Compare commits

..

552 Commits

Author SHA1 Message Date
Nelson Benítez León bab2bf2596 widget-factory: add example on styling tooltip window
by using new api:
  gtk_tooltip_set_css_class()
  GtkWidget signals 'tooltip-show' and 'tooltip-hide'

Part of #5925
2023-07-09 17:07:09 -04:00
Nelson Benítez León 11b4e4a467 GtkWidget: add new signals 'tooltip-show' and 'tooltip-hide'
which are emitted when a tooltip window is about to be shown
on a widget, and when a tooltip window stopped being shown
on a widget.

These signals provide two convenient moments for where to style
our tooltip window in case we want to do so by adding a css
class to it.

The existant signal 'query-tooltip' could not be used for that
as it's triggered on motion events and we cannot distinguish
from that when the tooltip window gets shown or hidden.

Part of issue #5925
2023-07-09 17:07:09 -04:00
Nelson Benítez León 1cae0cd54c GtkToolTip: new API to add css classes to GtkTooltipWindow
we add a simple API to allow styling GtkTooltip's window
by setting a css class on it:

void gtk_tooltip_set_css_class (GtkTooltip *tooltip,
                                const char *css_class);

By passing NULL it will remove any previously set css class
by this function.

Issue #5925
2023-07-09 17:07:09 -04:00
Matthias Clasen 1f3db35271 Merge branch 'dboles/image-notify-storage-type' into 'main'
Image—Notify when :storage-type changes from EMPTY

See merge request GNOME/gtk!6170
2023-07-07 01:15:56 +00:00
Emmanuele Bassi 18cce46ed2 Merge branch 'wip/corey/listitemleak' into 'main'
gtklistitemmanager: Stop leaking item

Closes #5940

See merge request GNOME/gtk!6171
2023-07-06 23:57:16 +00:00
Corey Berla e78148bae5 gtklistitemmanager: Stop leaking item
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5940
2023-07-06 16:24:29 -07:00
Daniel Boles 41237509ad Image—Notify when :storage-type changes from EMPTY
PROP_STORAGE_TYPE was only notified if it was changing *to* EMPTY, in
gtk_image_clear_internal(). We did not notify when it changes *from*
EMPTY to something non-empty. We should as not doing so is confusing,
e.g. if a user wants to bind :storage-type to :visible if non-empty,
which I just did! So, in functions that apply an ImageType, now notify.

Also do so in gtk_image_set_from_definition, declared in imageprivate.h,
even though none of the function there are currently used anywhere.
(Should they be removed?)
2023-07-06 23:08:20 +01:00
Yosef Or Boczko 576e8a2090 Update Hebrew translation 2023-07-06 09:38:02 +00:00
Matthias Clasen d0f77c1db4 Merge branch 'wip/carlosg/switch-stylus-buttons' into 'main'
gdk/wayland: Switch behavior of BTN_STYLUS/STYLUS2 as middle/right click

Closes #5935

See merge request GNOME/gtk!6168
2023-07-05 23:38:38 +00:00
Carlos Garnacho e28ff79bec gdk/wayland: Switch behavior of BTN_STYLUS/STYLUS2 as middle/right click
This mapping of stylus evdev input event codes into GDK button numbers
makes gdk/wayland inconsistent with gdk/x11, so depending on the backend
the same button middle-click pastes or right-click pops up menus.

Make the wayland backend consistent with X11, so that a GNOME wayland
session gets these buttons consistently mapped across all kinds of
clients.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5935
2023-07-05 16:54:54 +02:00
Daniel Boles dccf6b55bd GdkTexture: Don't mention private new_from_surface
The stuff about Cairo Surfaces is in gdktextureprivate.h, & so end users
will not be able to use them; we shouldn't confuse by implying they can.
2023-07-05 12:07:33 +01:00
Daniel Boles d5ea376e7b docs/list-widget: links, DirList, correct Sections
* Add links to various symbols.
* Mention DirectoryList in the "ready-made choices available" section.
* Don't say that GridView can display headers: it makes no attempt to.
2023-07-05 12:02:08 +01:00
Matthias Clasen 40707a6af0 Merge branch 'ebassi/issue-5934' into 'main'
Lower the Python requirement

Closes #5934

See merge request GNOME/gtk!6167
2023-07-05 10:57:45 +00:00
Emmanuele Bassi 9b71c9dfc6 Do not use bleeding edge Python
The match operator was added in Python 3.10, which is a bit too new for
some downstreams.

While at it, let's fix the flake8 errors and warnings.

Fixes: #5934
2023-07-05 10:19:18 +01:00
Emmanuele Bassi 64308317f8 Add flake8 configuration file
Ignore long lines; most of our Python scripts generate code or other
types of files, which makes long lines a necessity.

We should validate all our Python script in our CI as well.
2023-07-05 10:12:20 +01:00
Daniel Boles f920723eae AlertDialog: Remove spurious/unmatched backtick 2023-07-04 22:42:50 +01:00
Daniel Boles c581f4c96f ListBase: Fix a typo 2023-07-04 19:44:56 +01:00
Matthias Clasen 4998c90b10 Merge branch 'update-uac-script-format' into 'main'
tools/generate-uac-manifest.py: Fix formatting (unify with copy in GLib)

See merge request GNOME/gtk!6164
2023-07-03 23:37:36 +00:00
Benjamin Otte 412b23a146 Merge branch 'wip/otte/for-main' into 'main'
gsk: Catch values < 0 before bad things happen

See merge request GNOME/gtk!6165
2023-07-03 20:40:30 +00:00
Benjamin Otte c179013790 testsuite: Add a test for mask out of bounds effects
Inverted alpha masks have an effect on the source, even if the mask
doesn't cover the source at all - or worse, is completely clipped out.

The GL renderer handles this fine, but Cairo and Vulkan had
optimizations that got this wrong.
2023-07-03 22:02:44 +02:00
Benjamin Otte c6eb7fd483 gsk: Fix luminance in Cairo and GL renderer
In particular, fix the combination of luminance and alpha. We want to do
  mask = luminance * alpha
and for inverted
  mask = (1.0 - luminance) * alpha
so add a test that makes sure we do that and then fix the code and
existing tests to conform to it.
2023-07-03 22:02:44 +02:00
Benjamin Otte 7c58370673 rendernode: Work around a Cairo bug
When color-matrix modifying a clear surface, the surface would remain
clear according to Cairo.

That's very unfortunate when we prepare a mask for inverted-alpha
masking.
2023-07-03 22:02:44 +02:00
Benjamin Otte 84737a5159 build: Include the right things
If we build our own targets, we need to include those.

This is only relevant when adding new shaders because meson will
complain that the (unused) sources don't exist as it tries to include
those.
And that will make the build.ninja file not be generated which would
have build those shaders and would have allowed to copy them into the
sources.

Note that this makes builds with glslc not care about all the shader
files being included with the sources, but we have CI to check that.
2023-07-03 22:02:44 +02:00
Benjamin Otte 48804c81f3 rendernode: Mask nodes with different modes are different
So treat them as such.

Fixes the node editor not updating when I edit the mask mode.
2023-07-03 22:02:44 +02:00
Benjamin Otte c79ec355af gsk: Catch values < 0 before bad things happen
In particular, catch radius values being < 0 by return_if_fail()ing in
the rendernode creation code, and by erroring out in the rendernode
parser.

I try too much dumb stuff in the node editor.
2023-07-03 22:02:44 +02:00
Benjamin Otte ce5d74d7df glcontext: Fix typo in Apple extension name 2023-07-03 22:02:44 +02:00
Matthias Clasen 5bcc943ec3 Post-release version bump 2023-07-03 14:56:49 -04:00
Matthias Clasen f5d68bb586 4.11.4 2023-07-03 14:12:53 -04:00
Chun-wei Fan 6d1537647c tools/generate-uac-manifest.py: Fix formatting
As this script is now also used in GLib, unify the formatting between
GLib and GTK. Make the formatting of the script conformant to the
Black[1] tool, as GLib requires, and add a copyright header to this
script.

[1]: https://black.readthedocs.io/en/stable/, see also
$(glibsrcroot)/.gitlab-ci/run-bash.sh
2023-07-03 12:50:55 +08:00
Matthias Clasen ae2c10996a Merge branch 'fix_atcontext_refleaks' into 'main'
a11y: Fix some GtkATContext reference leaks

See merge request GNOME/gtk!6160
2023-07-01 18:06:19 +00:00
Barnabás Pőcze 81e9de3778 a11y: Fix some GtkATContext reference leaks
`gtk_accessible_get_at_context()` is transfer-full, so the returned
reference needs to be dropped. This was missing in a couple places.
2023-07-01 16:40:11 +02:00
Chun-wei Fan 42a704fefb Merge branch 'gdk-win32-input-fixes' into 'main'
GdkWin32 input fixes

Closes #5877

See merge request GNOME/gtk!6131
2023-06-30 04:33:08 +00:00
Matthias Clasen e57eaf16b4 Merge branch 'wip/chergert/map-as-sectionmodel' into 'main'
maplistmodel: implement GtkSectionModel

See merge request GNOME/gtk!6154
2023-06-30 01:50:07 +00:00
Matthias Clasen 9aabb0e98d Add section model tests for GtkMapListModel 2023-06-29 21:30:11 -04:00
Matthias Clasen 9590a5f45e maplistmodel: Handle the ::sections-changed signal
Wrapper section models need to listen to and pass
on the ::sections-changed signal from the underlying
model.
2023-06-29 21:29:11 -04:00
Daniel Boles 7bee50c4f6 Image: Fix missing closing backtick 2023-06-29 14:33:29 +01:00
Matthias Clasen bad2324318 Merge branch 'dboles/gtk-demo_dnd_dark' into 'main'
gtk-demo/dnd: Fix, generalise detecting dark theme

See merge request GNOME/gtk!6157
2023-06-29 10:26:41 +00:00
Matthias Clasen dd15accb79 Merge branch 'matthiasc/for-main' into 'main'
build: Try harder to work with nongnu ld

See merge request GNOME/gtk!6159
2023-06-28 23:31:41 +00:00
Matthias Clasen 1d1f35576a build: Try harder to work with nongnu ld
Only try to be fast with gnu ld.
2023-06-28 16:54:34 -04:00
Daniel Boles 15458b5af3 gtk-demo/dnd: Fix, generalise detecting dark theme
Our default theme is now Default, not Adwaita, & HighContrastInverse was
renamed to Default-hc. So these checks did not work anymore. Rather than
hard-coding the new names, & possibly running into the same issue again,
we can just look for the convention of appending -dark to the theme name
and/or the Settings:prefer-dark-theme prop. The latter, we can & likely
SHOULD also apply to all themes - not just ours as before. We also check
for the :dark suffix as that means the theme variant - & before checking
GtkSettings check the GTK_THEME env var, just as GtkSettings itself does
2023-06-28 14:40:06 +01:00
Matthias Clasen 5ffe9a68ed Merge branch 'matthiasc/for-main' into 'main'
build: Move objcopy checks to one place

Closes #5672

See merge request GNOME/gtk!6156
2023-06-28 12:06:49 +00:00
Matthias Clasen f341bd563b build: Look for ld.bfd
The objcopy+ld approach to fast resource building
relies on behavior that is specific to the binutils
linker, and does not work with the llvm one.

Therefore, check for ld.bfd. We still fall back
to trying with just ld, since I'm not 100% sure
if binutils unconditionally installs ld.bfd.

Fixes: #5672
2023-06-28 07:12:07 -04:00
Matthias Clasen 70edacc68d build: Move objcopy checks to one place
We were doing the same thing in three places.
Move it to the toplevel meson.build, so we
can change it in one place.
2023-06-28 07:11:51 -04:00
Matthias Clasen 091176ae48 Updates 2023-06-28 06:47:32 -04:00
Matthias Clasen d9cfb94a80 Merge branch 'fix_dropdown_set_expression' into 'main'
GtkDropDown: Force redisplay of the drop-down items after expression change

See merge request GNOME/gtk!6145
2023-06-28 09:57:04 +00:00
Lukáš Tyrychtr 3c7ca28f1f dropdown: Handle expression changes
The expression is used by the default factory, so we
need to track whether we are using the default factory
and recreate it if the expression changes.
2023-06-28 08:18:01 +02:00
Matthias Clasen 25e518326c Merge branch 'matthiasc/for-main' into 'main'
Plug a memory leak in gsk_render_node_serialize

See merge request GNOME/gtk!6155
2023-06-28 02:42:47 +00:00
Matthias Clasen a853307fb7 ci: Ignore more leaks in dependencies
libxkbcommon shows up quite a bit in leak sanitizer
reports. Ignore it.
2023-06-27 22:08:22 -04:00
Matthias Clasen 0ae541671d gsk: Plug a memory leak in mask node fallback
We were forgetting to free the mask pattern.
Found by asan.
2023-06-27 21:54:15 -04:00
Matthias Clasen ef0d6c7290 gsk: Plug a memory leak in the gl renderer
Found by asan.
2023-06-27 21:52:08 -04:00
Matthias Clasen 2217509701 Plug a memory leak in gsk tests
Pointed out by asan.
2023-06-27 21:48:12 -04:00
Matthias Clasen 16e46a73f3 Plug a memory leak in gsk_render_node_serialize
This was introduced in 0d6a6a5997 with named
textures.
2023-06-27 21:43:17 -04:00
Christian Hergert 32a3690a3c maplistmodel: implement GtkSectionModel
This just wraps the underlying GListModel if it is a GtkSectionModel.
2023-06-27 18:08:20 -07:00
Benjamin Otte 526771751f Merge branch 'dboles/issue5922-DropTarget-reject-enter-critical' into 'main'
DropTarget: Fix critical if `reject()` drop before `::enter`

Closes #5922

See merge request GNOME/gtk!6152
2023-06-27 21:30:03 +00:00
Daniel Boles dfa6591675 DropTarget: Fix critical if reject drop pre-enter
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5922

The docs of `Gtk.DropTarget::accept` say this:
> If the decision whether the drop will be accepted or rejected depends
> on the data, [`::accept`] should return `TRUE`, [`:preload`] should be
> set and the value should be inspected via the `::notify:value` signal,
> calling `gtk_drop_target_reject()` if required.

But this pattern causes a CRITICAL, given these steps:
* Create a `DragSource` and `DropTarget`
* Keep the default `::accept` handler and set `:preload` to `TRUE`
* Connect to `notify::value` and therein call `DropTarget.reject()`
* CRITICAL at `DropTarget.enter()`→`Drop.get_actions()` on NULL instance

We should let the documented case work without a CRITICAL or worse, null
deref. And per @otte on the bug, we should bail earlier before `::enter`
& setting `GTK_STATE_FLAG_DROP_ACTIVE`; neither should occur if rejected

This fixes that, by checking after `start_drop()` when notifications are
thawed, whether any handler has `reject()`ed & set our `drop` to `NULL`.
2023-06-27 21:37:32 +01:00
Daniel Boles 6252517aac DropTarget: Fix if block indented 1 step too far 2023-06-27 21:37:20 +01:00
Matthias Clasen 51e440fa03 Merge branch 'fix-asan-ifunc' into 'main'
Fix fp16 with asan

See merge request GNOME/gtk!6153
2023-06-27 19:55:28 +00:00
Matthias Clasen d82fb6f20a Fix fp16 with asan
The IFUNC resolvers that we are using here get
run early, before asan had a chance to set up its
plumbing, and therefore things go badly if they
are compiled with asan. Turning it off makes things
work again.

The gcc bug tracking this problem:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110442

Thanks to Jakub Jelinek and Florian Weimer for
analyzing this and recommending the workaround.
2023-06-27 15:17:56 -04:00
Matthias Clasen 44de6a6cbe Merge branch 'wip/sadiq/fix-use-after-free' into 'main'
gldriver: Fix a possible use-after-free

See merge request GNOME/gtk!6151
2023-06-27 18:46:28 +00:00
Mohammed Sadiq 64e27cd87d gldriver: Fix a possible use-after-free
g_hash_table_insert() frees the given key if it already exists
in the hashtable.  But since we use the same pointer in the
following line, it will result in use-after-free.

So instead, insert the key only if it doesn't exist.
2023-06-27 22:45:07 +05:30
Benjamin Otte 60e75f8a2a Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Generate vertex array headers from shaders

See merge request GNOME/gtk!6149
2023-06-27 16:20:29 +00:00
Matthias Clasen 57eda94dde Merge branch 'matthiasc/for-main' into 'main'
gtk4-builder-tool: Fix naming

See merge request GNOME/gtk!6150
2023-06-27 11:24:08 +00:00
Matthias Clasen 723fb6c8be gtk4-builder-tool: Fix naming
We install the tool as gtk4-builder-tool, so that
is what it should call itself.

String change.
2023-06-27 07:09:04 -04:00
Benjamin Otte 6c85ed1ba1 vulkan: Generate vertex array headers from shaders
The script is pretty dumb but it does its job.
2023-06-27 07:11:48 +02:00
Benjamin Otte 2e58274f23 vulkan: Rename crossfade => cross-fade
Preparation for the future.
2023-06-27 06:46:57 +02:00
Benjamin Otte 4ade0afe03 vulkan: Rename blendmode to blend-mode
Preparation for future changes, nothing to see here.
2023-06-27 06:46:57 +02:00
Benjamin Otte 93fb45c689 Merge branch 'wip/otte/vulkan-for-main' into 'main'
vulkan: Add a pipeline cache

See merge request GNOME/gtk!6148
2023-06-26 18:52:48 +00:00
Benjamin Otte 684a015c98 vulkan: Add a pipeline cache
Make the display handle the cache, because we only need one.

We store the cache in
  $CACHE_DIR/gtk-4.0/vulkan-pipeline-cache/$UUID.$VERSION
so we regenerate caches for each different device (different UUID) and
each different driver version.

We also keep track of the etag of the cache file, so if 2 different
applications update the cache, we can detect that.
Vulkan allows merging caches, so the 2nd app reloads the new cache file
and merges it into its cache before saving.
2023-06-26 20:28:11 +02:00
Matthias Clasen f7fcd2e425 Merge branch 'main' into 'main'
Add settable search match mode in dropdown

See merge request GNOME/gtk!6146
2023-06-26 18:18:14 +00:00
Matthias Clasen c6c637fe21 Merge branch 'matthiasc/for-main' into 'main'
buildertool: Make render an alias for screenshot

See merge request GNOME/gtk!6147
2023-06-26 15:38:32 +00:00
Matthias Clasen 33fc4d6495 buildertool: Make render an alias for screenshot
Its a more neutral name and will align better with
other tools.
2023-06-26 10:58:35 -04:00
al_SeveR 33ff927522 Add settable search match mode in dropdown 2023-06-26 14:14:39 +00:00
Leônidas Araújo 2d39cdbff8 Update Brazilian Portuguese translation
(cherry picked from commit 98a2aae5ac)
2023-06-26 13:08:53 +00:00
Daniel Boles 8d675810e8 GtkText: Link to descendents/monospace CSS nodes
Change the descendent classes from `monospace`-without-links to links.
Add `monospace` around the names of CSS nodes and classes for clarity.
2023-06-26 13:05:39 +01:00
Matthias Clasen 8b25481c26 widget-factory: Set a11y labels on scale buttons
Just to check that this works now.
2023-06-25 22:28:23 -04:00
Ekaterine Papava 5fdf96f496 Update Georgian translation 2023-06-25 13:39:03 +00:00
Matthias Clasen b61991a023 Merge branch 'gtkstack_fix_pages_param_check' into 'main'
stack: fix pages list bounds check

See merge request GNOME/gtk!6141
2023-06-24 12:08:18 +00:00
G.Willems 91d302a201 stack: fix pages list bounds check
Fix integer underflow when children->len is 0.
Add missing bounds check in select_item()
2023-06-24 03:05:37 +02:00
Matthias Clasen 35a1a62d50 Merge branch 'ebassi/builder-docs' into 'main'
docs: Clean up section on UI definitions

See merge request GNOME/gtk!6139
2023-06-23 23:45:05 +00:00
Matthias Clasen ac7a4cb94c Merge branch 'wip/chergert/gdatetime-from-gtkbuilder' into 'main'
builder: add support for parsing GDateTime

See merge request GNOME/gtk!6140
2023-06-23 23:43:28 +00:00
Christian Hergert bacd7ef92f builder: add support for parsing GDateTime
This will parse a <property/> containing the ISO 8601 format for a date
for use in GDateTime properties. For example:

  <property name="sampled-at">2023-06-23T00:00:00.00</property>
2023-06-23 14:11:37 -07:00
Emmanuele Bassi 980dc44f4a docs: Clean up section on UI definitions
The current documentation is narrative, but it lacks examples and proper
formatting, which makes it harder to read and visually scan.

Let's split off paragraphs and sections, so they can be easily linkend,
and add a few examples for each description.
2023-06-23 14:31:57 +01:00
Daniel Boles 2d648f84a9 docs/ref/gtk/running: Mention GDK_DEBUG=no-portals
It was omitted from !5336
2023-06-23 14:24:47 +01:00
Daniel Boles aef0943f61 FileDialog: Fix typos of "inital" to "initial" 2023-06-23 13:50:53 +01:00
Matthias Clasen 3e146171cb Merge branch 'dboles/FileDialog_initial-folder_from_initial-file' into 'main'
Fix FileDialog: initial-file doesnʼt set initial-folder

See merge request GNOME/gtk!6137
2023-06-23 01:14:15 +00:00
Matthias Clasen 24bbaceaa4 Merge branch 'always-more-a11y-fixes' into 'main'
scalebutton: Use the group role

See merge request GNOME/gtk!6138
2023-06-23 01:06:57 +00:00
Matthias Clasen 318cf132e9 a11y: Extend the nested button hack to volume buttons 2023-06-22 18:37:10 -04:00
Matthias Clasen 8bbc143ed1 scalebutton: Use the group role
This is needed for accessible labels to work.
2023-06-22 18:36:39 -04:00
Daniel Boles 220d130c0f FileDialog: initial-file didnʼt set initial-folder
We always set :initial-folder to NULL and then notified about that,
instead of setting it to the folder of the :initial-file as we say.
2023-06-22 22:33:14 +01:00
Jordi Mas e28a32a7c7 Update Catalan translation 2023-06-22 21:00:28 +02:00
Matthias Clasen 88f8b77d77 Merge branch 'matthiasc/for-main' into 'main'
docs: Mention GtkAccessibleRange

See merge request GNOME/gtk!6136
2023-06-22 02:40:08 +00:00
Matthias Clasen 1066374909 docs: Mention GtkAccessibleRange
In the accessibility docs about custom widgets,
mention GtkAccessibleRange as the best way to
implement custom range widgets.
2023-06-21 22:15:59 -04:00
Matthias Clasen 34a2595dfb Merge branch 'more-a11y-fixes' into 'main'
widget: Don't let abstract role slip through

See merge request GNOME/gtk!6135
2023-06-22 00:47:03 +00:00
Matthias Clasen 76fcd5cf25 Add another a11y test
This one catches the lingering 'widget' role
that only happens when widgets are realized
and rooted.
2023-06-21 19:55:46 -04:00
Matthias Clasen 32e6ed4eca a11y: Use group role for color and font buttons
This is needed since generic does not allow naming.
2023-06-21 19:55:46 -04:00
Matthias Clasen 2983c0be70 widget: Don't let abstract role slip through
When there isn't an accessible role set on the
instance or in class_init, we want to default
to 'generic'. There was one place where we
failed to do so.
2023-06-21 16:18:33 -04:00
Matthias Clasen e0bf6585de Cosmetics: typo fix 2023-06-21 16:18:33 -04:00
Daniel Boles c045b0be4c Settings: prop typo => "No description available."
Fix the typo so that we'll actually get documentation for
gtk-entry-select-on-focus.
2023-06-21 20:48:17 +01:00
Matthias Clasen d8c094944a Merge branch 'more-a11y-fixes' into 'main'
a11y: Don't forget to space-separate computed names

See merge request GNOME/gtk!6134
2023-06-21 18:52:35 +00:00
Matthias Clasen 510bf86268 Add another a11y test
Test that roles come out right for custom widgets.
2023-06-21 14:24:52 -04:00
Matthias Clasen f3bea027a0 Dropdown: Explicitly set a role
For some reason I haven't been able to track down,
the listitemwidget comes up wit the abstract widget
role otherwise.
2023-06-21 14:17:52 -04:00
Matthias Clasen bce3b6f34a aboutdialog: Fix roles one more time
We are more picky about generic, so use group.
2023-06-21 13:47:59 -04:00
Matthias Clasen 01274dfbb9 shortcutswindow: Fix up roles and labels again 2023-06-21 13:18:58 -04:00
Matthias Clasen 533a2cf9ec a11y: Don't forget to space-separate computed names
This was overlooked in one place.
2023-06-21 13:18:07 -04:00
Luca Bacci 43af0ee514 Define this_module with (void) argument
Fixes a compiler warning about K&R (old-style) function definition
2023-06-21 16:18:40 +02:00
Luca Bacci 3912d6aba9 GdkWin32: Fix keyboard state for WinPointer input
The dwKeyStates field of the POINTER_INFO structure
is always set to 0, no matter what. Use GetKeyState
instead.

Forward-port of !4327 to GTK4
2023-06-21 16:18:01 +02:00
Luca Bacci 871685e271 GdkWin32: Use double coordinates for mouse events
Mouse coordinates reported by the system are still integers,
but go sub-pixel when dividing by the window scale factor.
2023-06-21 16:07:55 +02:00
Luca Bacci 5e9daa9728 GdkWin32: Unscaled coordinates in current_root_x, current_root_y
Also modify gdk_win32_surface_do_move_resize_drag() to take
unscaled root coordinates.

Fixes #5877
2023-06-21 16:01:42 +02:00
Luca Bacci 412bc1713a GdkWin32: Keep track of the last cursor position in move / resize contexts
...and avoid doing any work if the position hasn't changed.
2023-06-21 15:31:48 +02:00
Matthias Clasen 5dbc5bbf22 Merge branch 'wip/antoniof/my-mistake' into 'main'
Fix my a mistake

See merge request GNOME/gtk!6130
2023-06-21 12:01:00 +00:00
António Fernandes 79c999cf76 columnviewrowwidget: Reset roles on teardown
This was added to the wrong file in e245883f91

Fix the mistake.
2023-06-21 12:23:39 +01:00
Matthias Clasen e375bc8838 Merge branch 'wip/antoniof/columnviewrow-accessible-label' into 'main'
columnviewrow: Add accessible-label and -description

Closes #5903

See merge request GNOME/gtk!6129
2023-06-21 10:22:41 +00:00
Matthias Clasen 79505f940b Merge branch 'always-more-a11y-fixes' into 'main'
range: Don't use an abstract role

See merge request GNOME/gtk!6127
2023-06-21 10:07:57 +00:00
Matthias Clasen 0f087deb2a Merge branch 'bump-glib' into 'main'
Bump GLib requirement to 2.76.0

See merge request GNOME/gtk!6128
2023-06-21 10:07:40 +00:00
António Fernandes e245883f91 columnviewrow: Add accessible-label and -description
Echoing the same changes introduced for GtkListItem by these commits:
* df8d28f5fe
* f2b682dd9c

Resolves https://gitlab.gnome.org/GNOME/gtk/-/issues/5903
2023-06-21 10:27:39 +01:00
Chun-wei Fan 4e9bd13892 Visual Studio: Remove workarounds for <= glib-2.74.x
We now need glib-2.76.0 or later, which removes our needs for the workarounds
that we need to build the media backends against GLib-2.74.x or earlier, so
clean up things a bit.
2023-06-21 12:29:38 +08:00
Chun-wei Fan 65e9b8fe66 glib.wrap: Use 2.76.0
We are now using APIs that were introduced in 2.75.x, so let's use glib-2.76.0
here for our glib subproject.

Update the build and gobject-introspection items accordingly
2023-06-21 12:27:41 +08:00
Matthias Clasen e9f870fee6 Make generic really the default role
If nothing else has been set for the instance
or the class, return GTK_ACCESSIBLE_ROLE_GENERIC.
2023-06-20 22:02:37 -04:00
Matthias Clasen e5e5966934 frame: Use the group role 2023-06-20 21:58:55 -04:00
Matthias Clasen 5c407365e3 ci: Use the current build options for flatpaks
These were changed a while ago.
2023-06-20 20:49:29 -04:00
Matthias Clasen 7e251d81c2 a11y: Fix the stack switcher selection implementation
This was listening for signals on the wrong object.
2023-06-20 20:49:29 -04:00
Matthias Clasen 92d1d52c59 NEWS: updates 2023-06-20 20:49:29 -04:00
Matthias Clasen ef436e4dce range: Don't use an abstract role
This snuck through, because the range wasn't
setting any role at all, it just ends up using
the initial, abstract role of widget.
2023-06-20 20:49:29 -04:00
Benjamin Otte 1a07e336bf Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Fix a bunch of validation-layer complaints

See merge request GNOME/gtk!6126
2023-06-20 18:38:41 +00:00
Benjamin Otte 169355f771 vulkan: Rebuild the precompiled shaders
We forgot that with all the changes.
2023-06-20 20:17:06 +02:00
Benjamin Otte 299c6a3d6f vulkan: Take offscreen fromat from context
We want to create offscreens in compatible formats, and in particular we
want to ideally use the same format as rendering would use.
2023-06-20 20:15:12 +02:00
Benjamin Otte 17698bfd2e vulkan: Use 3 descriptor sets, not 3 bindings
It turns out variable length is only supported for the last binding in
a set, not for every binding.
So we need to create one set for each of our arrays.

[ VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004 ] Object 0: handle = 0x33a9f10, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xd3f353a | vkCreateDescriptorSetLayout(): pBindings[0] has VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT but 0 is the largest value of all the bindings. The Vulkan spec states: If an element of pBindingFlags includes VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, then all other elements of VkDescriptorSetLayoutCreateInfo::pBindings must have a smaller value of binding (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004)
2023-06-20 20:15:12 +02:00
Benjamin Otte 377592cb62 vulkan: Use the right flags
Somebody (me) had flipped the 2 flags in commit ba28971a18:

[ VUID-vkCmdCopyBufferToImage-srcBuffer-00174 ] Object 0: handle = 0x3cfaac0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x430000000043, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0xe1b276a1 | Invalid usage flag for VkBuffer 0x430000000043[] used by vkCmdCopyBufferToImage. In this case, VkBuffer should have VK_BUFFER_USAGE_TRANSFER_SRC_BIT set during creation. The Vulkan spec states: srcBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdCopyBufferToImage-srcBuffer-00174)
2023-06-20 20:15:12 +02:00
Benjamin Otte 015cebc046 vulkan: Set descriptorBindingStorageBufferUpdateAfterBind
It's necessary now that we use storage buffers for gradients:

[ VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008 ] Object 0: handle = 0x1e72d70, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x943cc552 | vkCreateDescriptorSetLayout(): pBindings[0] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT for VK_DESCRIPTOR_TYPE_STORAGE_BUFFER since descriptorBindingStorageBufferUpdateAfterBind is not enabled. The Vulkan spec states: If VkPhysicalDeviceDescriptorIndexingFeatures::descriptorBindingStorageBufferUpdateAfterBind is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER must not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008)
2023-06-20 20:15:12 +02:00
Benjamin Otte 0a5e5023a8 vulkan: Remove unused declaration from shader 2023-06-20 20:15:12 +02:00
Matthias Clasen a9b8ad6181 Merge branch 'always-more-a11y-fixes' into 'main'
Add a comment about accessible naming

See merge request GNOME/gtk!6125
2023-06-20 17:13:51 +00:00
Matthias Clasen 7331683c01 a11y: Improve name computation
We only want to settle on subtree content
if it provides nonempty text. Otherwise,
the tooltip should still win.

This was clarified in the current Editor Draft
of the accessible name computation spec.
2023-06-20 12:34:51 -04:00
Matthias Clasen cca6a66518 a11y: Fix tests
The change to make hidden follow mappedness
means that we now need to arrange for our
test cases to be mapped.
2023-06-20 12:33:02 -04:00
Matthias Clasen 891462e5af Add some more a11y tests
Check that the hidden state is as it should be.
2023-06-20 11:05:22 -04:00
Matthias Clasen 95cd6fe206 menubutton: Remove all the labelled-by relations
This was a bit much, and should not be necessary anymore,
now that our name computation handles nested buttons.
2023-06-20 10:58:18 -04:00
Matthias Clasen 63534fd9eb widget: Fix accessible hidden state
Make this track the widgets' mapped state
instead of visible. Also, set hidden to FALSE
initially, since the accessible name computation
checks for hidden==FALSE.
2023-06-20 10:40:12 -04:00
Matthias Clasen e836e3380e Add a comment about accessible naming
Put a note on why there are a few differences
to ARIA.
2023-06-20 06:54:59 -04:00
Matthias Clasen f693beab57 NEWS: Updates 2023-06-20 06:54:40 -04:00
Matthias Clasen 2d2df42a94 Merge branch 'listitem-a11y' into 'main'
listitem: Add accessible-label and -description

See merge request GNOME/gtk!6123
2023-06-20 09:55:58 +00:00
Matthias Clasen fb0a4fa457 a11y: Stop recommending tab list labels
There is no good way to set an explicit label
on the tab list of a GtkNotebook, so showing
a blue overlay on it is annoying more than
helpful.

This is another little deviation from the ARIA
authoring guidelines.
2023-06-19 22:20:05 -04:00
Matthias Clasen be0003c108 a11y: Stop recommending against listitem labels
Due to the way listviews are set up, there is not
much of an alternative to setting labels on the
listitems, so don't recommend against doing it.

This is a little deviation from the ARIA authoring
guidelines.
2023-06-19 22:20:05 -04:00
Matthias Clasen eb1e24a5bf gizmo: Stop using abstract roles
This was overlooked.
2023-06-19 22:20:05 -04:00
Matthias Clasen a3e98558d3 gtk-demo: Some a11y improvements
Add missing labels to the applauncher demo
and the clocks demo.
2023-06-19 22:19:54 -04:00
Matthias Clasen f2b682dd9c listitemwidget: Clean up in teardown 2023-06-19 21:50:45 -04:00
Matthias Clasen b826ef4f4d Merge branch 'a11y-work' into 'main'
A11y role changes

See merge request GNOME/gtk!6101
2023-06-20 01:23:13 +00:00
Matthias Clasen a2fdeb99e0 gtk-demo: Improve a11y for applauncher
Use the new listitem properties to make
orca read the selected item in the applauncher
demo.
2023-06-19 21:21:55 -04:00
Matthias Clasen df8d28f5fe listitem: Add accessible-label and -description
Add properties to GtkListItem to set the accessible
label and description of the listitem widget. This
is important, since orca will read these if the
listitem widget ends up with the focus.
2023-06-19 21:21:55 -04:00
Matthias Clasen 838c51cc92 a11y: Add the ARIA ontology
Add a helper function to find out which roles are
superclasses of each other.

This isn't used yet (apart from the existing use for
ranges), but it might be in the future.
2023-06-19 18:38:58 -04:00
Matthias Clasen 315ded687c Docs: update 2023-06-19 18:38:58 -04:00
Matthias Clasen 6855346269 a11y: Treat widget and window as abstract roles
We no longer use these, so we can enforce
that they are abstract.
2023-06-19 18:38:58 -04:00
Matthias Clasen c2d6f900d9 window: Use application as accessible role
ARIA deems the window role to be abstract,
so lets use the application role instead.

Update affected tests.
2023-06-19 18:38:58 -04:00
Matthias Clasen 85c2d5f14e Add the application role
ARIA has this role. We left it out initially, but
it is an ok fit for toplevel windows, and better
than window, since that is meant to be abstract.
2023-06-19 18:38:58 -04:00
Matthias Clasen b3eb912cf3 Use generic as default accessible role
The ARIA specs want widget to be abstract role.
We should respect that and use 'generic' instead.
2023-06-19 18:38:58 -04:00
Matthias Clasen 81d9205369 widget: Warn for abstract accessible roles
These should not be used for widgets, so warn if
they are passed to gtk_widget_set_accessible_role()
or gtk_widget_class_set_accessible_role().
2023-06-19 18:38:32 -04:00
Matthias Clasen 152a335cee Add gtk_accessible_role_is_abstract
Move this code from the a11y overlay in the inspector.
It will be used more widely, going forward.
2023-06-19 18:30:41 -04:00
Matthias Clasen b84650c2a3 Add another a11y test 2023-06-19 18:30:41 -04:00
Matthias Clasen 722bea2943 Merge branch 'a11y-defeat' into 'main'
Give up on warning ATs into submission

See merge request GNOME/gtk!6121
2023-06-19 21:06:13 +00:00
Matthias Clasen 6c337b949d Merge branch 'fix-issue-5899' into 'main'
GtkFileChooserWidget: Fix condition on visit action

Closes #5899

See merge request GNOME/gtk!6103
2023-06-19 20:52:15 +00:00
Matthias Clasen db97a35dc7 a11y: Remove the unrealized warning
This warning triggers quite a lot when opening
a window while orca is running, which clearly
shows that what it warns about happens in
practice. But fixing it is reentry hell, and
not a battle I'm up for today.
2023-06-19 16:41:39 -04:00
Matthias Clasen c2fda63b0d Give up on warning ATs into submission
Its been more than a decade since Wayland
has not supported screen coordinates. Clearly
spamming every apps stderr with warnings is
never going to make ATs stop asking for screen
coordinates.

Just give up. Go home
2023-06-19 16:41:20 -04:00
Benjamin Otte 5da64e9e34 Merge branch 'unaligned-access' into 'main'
gtk: Align key_size up to key_align

Closes #5907

See merge request GNOME/gtk!6120
2023-06-19 20:26:18 +00:00
Matt Turner 3f360aa883 gtk: Align key_size up to key_align
Avoids unaligned accesses when e.g. the key_size is 12 and key_align is
8. We need to round the key size up to 16 to ensure that all keys are
appropriately aligned.

This manifested as a failure in the `gtk:gtk / sorter` unit test on
sparc.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5907
2023-06-19 15:55:09 -04:00
Matt Turner a444045386 gtk: Pass G_ALIGNOF (...) to gtk_sort_keys_new
The sizeof and G_ALIGNOF are often, but not always, identical.
2023-06-19 15:54:51 -04:00
Daniel Boles 584a807ed6 Widget: Also mention get_height in get_alloc depʼn
The deprecation notice seems to have been copied from
get_allocated_width(), but for get_allocation() height is also relevant.
2023-06-19 20:29:23 +01:00
Matthias Clasen 72e5697804 Merge branch 'redo-a11y-name-computation' into 'main'
Reimplement a11y name computation

See merge request GNOME/gtk!6119
2023-06-19 17:49:22 +00:00
Matthias Clasen 93aff8a129 Add more name computation tests
Test the fallback for range values.

This was not working at all before
the previous commit.
2023-06-19 12:40:33 -04:00
Matthias Clasen c3cfaab479 a11y: Fix name computation for ranges
There were two problems here:

First, the code was checking for the abstract
range role, instead of its subclasses.

Second, the code was calling a string value
getter on a number value. Oops.
2023-06-19 12:40:32 -04:00
Matthias Clasen 663e3d0811 Add tests for accessible name computation 2023-06-19 12:38:51 -04:00
Matthias Clasen 2dc35ec0c1 a11y: Quietly allow realizing unrooted at context
We can't set the display if we don't have a root,
but the default display is more than good enough
for the tests which otherwise would need to do
quite a bit more setup work to make their test
widgets rooted.
2023-06-19 12:38:51 -04:00
Matthias Clasen a791f235e6 a11y: Only allow get_name/description when realized
These functions rely on self->accessible_role
being set, and that is only the case for realized
contexts.

In practice, this is not a problem. Contexts are
realized before ATs can get their names or descriptions,
and the inspector realizes contexts too, nowadays.

The only place where this caused a hickup is the
testsuite.
2023-06-19 12:38:51 -04:00
Matthias Clasen 7df9cc1b47 label: Stop overriding accessible label
There's no need to, the accessible name computation
picks the content up where it is allowed (and not
overridden by explicit attributes).
2023-06-19 12:38:51 -04:00
Matthias Clasen 4449344fad a11y: Reimplement name computation
Reimplement the name computation to follow the spec
(https://www.w3.org/TR/accname-1.2) more closely.

Also, unify the functions for name and description,
since their only difference is which property/relation
they use.
2023-06-19 12:38:51 -04:00
Matthias Clasen e1c9f50d26 a11y: Cosmetics
No need to have two code paths doing the same.
2023-06-19 12:38:51 -04:00
Matthias Clasen 1f029229dc Merge branch 'a11y-inspector-tweaks' into 'main'
Move the a11y naming data into gtk proper

See merge request GNOME/gtk!6118
2023-06-19 16:21:31 +00:00
Matthias Clasen a80dd28e35 a11y: Move naming data to gtkatcontext.c
This is in preparation for using this information
in the name computation.
2023-06-19 11:17:47 -04:00
Matthias Clasen 16077fbdac inspector: Tweak the a11y overlay
Shorten the warnings, and lower some of the
errors to 'not recommended' (where the authoring
guidelines say 'do not label', but aria doesn't
prohibit labels outright).
2023-06-19 11:17:47 -04:00
Matthias Clasen 1906bb5263 a11y: Update the name-prohibited list
ARIA has the time role in this as well.

It does not matter in practice since we don't
have a widget with this role, but lets match
the specs.
2023-06-19 11:17:47 -04:00
Matthias Clasen a8b907a33c a11y: Cover the printer option widget case too
This is another case of nested control, in this
case it goes two levels deep. Since we already
have this hack, lets use it for all the cases.
This avoids some more complicated workaround.
2023-06-19 11:17:47 -04:00
Matthias Clasen f2a2e97004 docs: Add guidance on container roles
Provide some guidance on whether group or generic
is a more suitable role for containers.
2023-06-19 11:17:47 -04:00
Matthias Clasen a86923de94 a11y: Change the role for many containers
The group role that we've used before has some
implications of semantic grouping, whereas these
containers are mainly about layout, so use the
generic role instead.

This should not affect the translation to AT-SPI
at all.

The affected containers are: box, grid, centerbox,
scrolledwindow, viewport, windowhandle, aspectframe.

The role of GtkTreeExpander has been changed to
button instead, since it acts as a button.
2023-06-19 11:15:48 -04:00
Matthias Clasen 4412f25c9f a11y: Treat none and presentation the same
ARIA says these roles are aliases, so treat them
the same.
2023-06-19 11:15:48 -04:00
Benjamin Otte c40588886b Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Add support for different image formats

See merge request GNOME/gtk!6117
2023-06-19 14:30:50 +00:00
Benjamin Otte 4045a0edd1 vulkan: Check for descriptor indexing extension
By checking if the extension is supported and avoiding devices when it
isn't, we avoid critical warnings later.
2023-06-19 15:08:00 +02:00
Benjamin Otte 636591c080 vulkan: Refactor function
Instead of checking for one specific extension, instead pass the
extension to check for by name.

This way we can reuse it for different extensions.
2023-06-19 15:08:00 +02:00
Benjamin Otte aa6c670f15 vulkan: Add support for high bit depth 2023-06-19 15:08:00 +02:00
Benjamin Otte 746d0d8fde vulkan: Don't create unnecessary render passes
Pass the render pass to the pipeline creation function instead of
creating an extra one just for pipeline creation.
2023-06-19 15:08:00 +02:00
Benjamin Otte 35b09c727a vulkan: Put the framebuffer in the renderpass
... instead of having fancy caching.

That caching is complicated and it's not necessary.
2023-06-19 15:08:00 +02:00
Benjamin Otte c35f491795 vulkan: Store the VkFormat in GskVulkanImage
... and use that info when creating renderpasses.
2023-06-19 15:08:00 +02:00
Benjamin Otte 5b64ca7e0a vulkan: Pick high depth texture for high depth nodes
If a node has a higher depth, pick the RGBA format that has that depth
as the texture format we're renderig to with render_texture().

Support for adapting the swapchain is not part of this.
2023-06-19 15:08:00 +02:00
Benjamin Otte d61737ac7a vulkan: Add format fallback
When a GdkMemoryFormat isn't supported, pick close formats that have a
higher chance of being supported.
Make sure this works recursively and the whole loop always ends up at
R8G8B8A8_UNORM because that one is mandatory.

Roughly, follow these rules:
1. Drop the unpremultiplied
2. Expand channels to include all of RGBA
3. pick swizzle that is RGBA
4. pick next largest depth
5. pick R8G8B8A8_UNORM
2023-06-19 15:08:00 +02:00
Benjamin Otte ba28971a18 vulkan: Allow mapping images as "read" and/or "write"
This way, we unify the code paths for memory access to textures.

We also technically gain the ability to modify images, though I have no
use case for this.
2023-06-19 15:08:00 +02:00
Benjamin Otte 7b4846bc25 vulkan: Pass format to offscreen creation function
That way, the offscreen can create images of different types.

Its not used in this commit, but will come in handy when we want to
support high bit depth.
2023-06-19 15:08:00 +02:00
Benjamin Otte eb3ccfb404 vulkan: Remove gsk_vulkan_image_new_for_framebuffer()
Use gsk_vulkan_image_new_for_offscreen() instead, it does the same thing
pretty much.
2023-06-19 15:08:00 +02:00
Benjamin Otte e4c37ceb34 vulkan: Allow uploading in different formats
This requires quite some code because Vulkan may not support all the
formats and then we need to detect that and fallback properly.
2023-06-19 15:08:00 +02:00
Benjamin Otte dae1e2b117 vulkan: Create the view in vulkan_image_new()
All callers want it created anyway.

Plus, we can consolidate things in future commits.
2023-06-19 15:08:00 +02:00
Benjamin Otte 49c2366121 testsuite: Unify skipping memorytexture test
... and make it handle more cases of failure, in particular OpenGL and
Vulkan being unsupported by the system.
2023-06-19 15:08:00 +02:00
Emmanuele Bassi 76efe45552 Merge branch 'more-a11y-tweaks' into 'main'
A11y improvements

See merge request GNOME/gtk!6116
2023-06-19 12:53:10 +00:00
Matthias Clasen 1489c764cb docs: Expand role docs
Clarify that presentation and none
can be used interchangeably.
2023-06-19 08:28:54 -04:00
Matthias Clasen d5a6d09348 dropdown: Use presentation instead of none 2023-06-19 08:28:54 -04:00
Benjamin Otte ae89f6e6c0 testsuite: Add a vulkan method to memorytexure test
This uses the newly added NULL-surface renderer.
2023-06-19 14:13:03 +02:00
Benjamin Otte 63edecd857 vulkan: Make gsk_renderer_realize() work with NULL surface
Pretty much copy what GL does and just use the default display to create
GPU-related resources without the need for a display.

This also adds gdk_display_create_vulkan_context() but I've
kept it private because the Vulkan API is generally considered in flux,
in particular with our pending attempts to redo how renderers work.
2023-06-19 14:13:03 +02:00
Benjamin Otte 515e1642a4 vulkan: Actually reset the buffer size
Fixes a bug introduced in d1135f9e3c.

Luckily the buffer was large enough that all my testing didn't catch it
because it took a few minutes to overflow.
2023-06-19 14:13:03 +02:00
Benjamin Otte 177ee89b99 vulkan: Renaming fix
This rename was a long time ago...
2023-06-19 14:13:03 +02:00
Matthias Clasen 94f5d2db0d modelbutton: Set a11y shortcuts 2023-06-19 08:09:49 -04:00
Matthias Clasen d562c86638 printdialog: Some a11y improvements
Add proper roles and labels in some places.
2023-06-19 08:09:49 -04:00
Matthias Clasen 64ff528fe1 printdialog: Give the page range entry a label
This is mainly to pacify the a11y checker.
2023-06-19 08:09:49 -04:00
Matthias Clasen 5993a2a16e notebook: Make sure tabs are labelled 2023-06-19 08:09:49 -04:00
Matthias Clasen ff20b3f303 windowcontrols: Cosmetics 2023-06-19 08:09:49 -04:00
Matthias Clasen 05ea3470e5 dropdown: Avoid accessibility warnings
The image here is just presentational.
2023-06-19 08:09:49 -04:00
Matthias Clasen 28e1f288c3 infobar: Improve a11y labelling
Treat the close button the same way we treat
the window close button, wrt. to accessibility.
2023-06-19 08:09:48 -04:00
Matthias Clasen 8d9a59f698 gtk-demo: Miscellaneous a11y improvements 2023-06-19 08:09:48 -04:00
Emmanuele Bassi 60a170db88 Merge branch 'a11y-remove-value-opt' into 'main'
a11y: Remove an overzealous optimisation

Closes #5886

See merge request GNOME/gtk!6115
2023-06-19 11:46:19 +00:00
Matthias Clasen 32550fd6fc a11y: Remove an overzealous optimisation
The result of calling update_property needs
to be that the property is marked as set
afterward, even if the value we pass happens
to match the default value.

After this change, scrollbars have value-now
show up as zero in the accessiblity page of
the inspector, even when that matches the lower
bound.

Test included.

Fixes: #5886
2023-06-19 07:22:32 -04:00
Matthias Clasen 12fb249dc6 Merge branch 'a11y-nest-button-redux' into 'main'
Revert "dropdown: Shuffle accessible roles around"

See merge request GNOME/gtk!6111
2023-06-18 15:42:06 +00:00
Matthias Clasen c3904e8a27 Merge branch 'main' into 'main'
Revert "Use gsk_matrix_transform_point3d consistently"

Closes #5902

See merge request GNOME/gtk!6112
2023-06-18 13:19:07 +00:00
Benjamin Otte 799fd4f4a3 Merge branch 'wip/otte/for-main' into 'main'
memoryformat: Add gdk_memory_format_get_depth()

See merge request GNOME/gtk!6110
2023-06-18 13:14:57 +00:00
Benjamin Otte 090cd2238a gdk: Replace prefers_high_depth with depth
Now that we track depth, we can also pass it into the GDK frame code.

For now it's just passed along, code acts the same as with
prefers_high_depth.
2023-06-18 14:28:39 +02:00
Benjamin Otte 8b8dfcdfb4 rendernode: Change to gsk_render_node_get_preferred_depth()
Instead of just tracking preferred_high_depth(), track the actual depth
we'd like to have.
2023-06-18 14:26:18 +02:00
Benjamin Otte 9015ed1c43 memoryformat: Add gdk_memory_format_get_depth()
Replace gdk_memory_format_prefers_high_depth with the more generic
gdk_memory_format_get_depth() that returns the depth of the individual
channels.

Also make the GL renderer use that to pick the generic F16 format
instead of immediately going for F32 when uploading textures.
2023-06-18 14:26:18 +02:00
Benjamin Otte 1a6d60b7d7 inspector: Handle a11y being disabled 2023-06-18 14:26:18 +02:00
Yiğit Burak 603d9e091c Revert "Use gsk_matrix_transform_point3d consistently"
Revert commit 440d56a4
2023-06-18 15:14:23 +03:00
Matthias Clasen 743b27571d a11y: Special-case nested buttons
Special-case nested buttons in our name computation,
since it is hard to reconcile all the a11y attributes
being on the wrapper, but the focus ending up on the
button inside.

This is a pragmatic approach that works. The only
downside is that the wrapper and the button end up
with the same name+description, but at least orca
seems to only read the focus elements' ones.
2023-06-18 08:12:31 -04:00
Matthias Clasen 30c38951b9 Revert "colordialogbutton: Shuffle accessible roles around"
This reverts commit 343b9d246f.

Unfortunately, this makes it so that the focus ends up on
the 'generic' accessible, not the one with the label, and
orca remains quiet.
2023-06-18 07:35:52 -04:00
Matthias Clasen 11d7052a40 Revert "dropdown: Shuffle accessible roles around"
This reverts commit 5ec0b07baf.

Unfortunately, this makes it so that the focus ends up on
the 'generic' accessible, not the one with the label, and
orca remains quiet.
2023-06-18 07:34:50 -04:00
Matthias Clasen 48d719e58e Merge branch 'matthiasc/for-main' into 'main'
testsuite: Add some more a11y tests

See merge request GNOME/gtk!6109
2023-06-18 03:03:33 +00:00
Matthias Clasen 5ec0b07baf dropdown: Shuffle accessible roles around
Make the internal toggle button generic, so that
the a11y checker doesn't complain about it not
having a label. And mark the icons in the popup
as presentational.
2023-06-17 22:40:17 -04:00
Matthias Clasen 343b9d246f colordialogbutton: Shuffle accessible roles around
Make the color button itself take the button role,
and make the internal toggle button just be generic.

This solves the problem that labelled-by relations
that are set up in ui files via mnemonics point at
the toplevel, not the toggle button.
2023-06-17 22:40:17 -04:00
Matthias Clasen de622c592d gtk-demo: a11y improvements
Make the clipboard demo come up clean in the
a11y checker.
2023-06-17 22:39:56 -04:00
Matthias Clasen c2735f98b4 testsuite: Add some more a11y tests
Test that overriding roles works, both
via g_object_new, and via ui files.
2023-06-17 22:00:55 -04:00
Matthias Clasen 7669198d2c Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Fix a crash

Closes #4522

See merge request GNOME/gtk!6108
2023-06-18 01:47:50 +00:00
Emmanuele Bassi 6bf4ad866f Apply suggestions from review 2023-06-17 21:26:53 -04:00
Matthias Clasen d705a7effa video: Make the overlay clickable
And add missing accessible labels at the same time.

Fixes: #4522
2023-06-17 19:30:08 -04:00
Matthias Clasen 407304f2ed inspector: Cosmetic fixes
Align the values on the a11y page to the right.
2023-06-17 19:30:08 -04:00
Matthias Clasen 21fa1d67ce mediacontrols: Add accessible labels 2023-06-17 19:29:53 -04:00
Matthias Clasen a9f8ec71a4 gtk-demo: Misc a11y improvements 2023-06-17 19:29:53 -04:00
Matthias Clasen caa8fb4fac gtk-demo: Fix a crash
This was broken in 6b2c088a29.
2023-06-17 17:56:41 -04:00
Matthias Clasen d59fc3da3c Merge branch 'matthiasc/for-main' into 'main'
colordialogbutton: Sync color

See merge request GNOME/gtk!6107
2023-06-17 21:20:10 +00:00
Matthias Clasen cbdcf64e4d inspector: Limit the width of a11y page
Ellipsize labels that can contain long
content to prevent a super-wide window.
2023-06-17 16:50:36 -04:00
Matthias Clasen e251e7583f gtk-demo: Misc a11y fixes
Add some missing labels.
2023-06-17 16:50:36 -04:00
Matthias Clasen 158a3d4f04 inspector: Realize AT ontexts
Otherwise we don't get change notification...
2023-06-17 14:50:01 -04:00
Matthias Clasen efeff41501 a11y: Set has-popup consistently
Set the has-popup property when a widget
has a context menu.
2023-06-17 12:18:34 -04:00
Matthias Clasen 80c4d4f51d colordialogbutton: Sync color
Make sure the color of the swatch and the button
are initially in sync. As a side-effect, this
ensures that the swatch has its accessible label
computed at the outset.
2023-06-17 11:52:37 -04:00
Matthias Clasen 115f60796f gtk-demo: Cosmetics 2023-06-17 11:52:37 -04:00
Matthias Clasen 7e62bdbf26 Merge branch 'matthiasc/for-main' into 'main'
Don't use "Tab list" as an accessible label

Closes #4839

See merge request GNOME/gtk!6106
2023-06-17 15:44:21 +00:00
Luca Bacci 16bdaa11ce GtkFileChooserWidget: Use GTK_INVALID_LIST_POSITION
...instead of G_MAXUINT
2023-06-17 15:51:22 +02:00
Luca Bacci 46afb4a9a4 GtkFileChooserWidget: Fix condition on visit action
Fixes #5899
2023-06-17 15:50:50 +02:00
Matthias Clasen 775e8dc43d Don't use "Tab list" as an accessible label
It does not add any extra information.

Fixes: #4839
2023-06-17 08:46:41 -04:00
Benjamin Otte cc603bf657 Merge branch 'dropdown-sections' into 'main'
dropdown: Add section support

See merge request GNOME/gtk!6102
2023-06-17 06:41:30 +00:00
Matthias Clasen 0652e05e0b gtk-demo: Add an example for dropdown sections
Make one of the dropdowns in the Selections
demo have sections.
2023-06-16 21:13:26 -04:00
Matthias Clasen 1347d23658 dropdown: Add section support
Add a header-factory property and pass it through
to the listview in the popup.
2023-06-16 21:13:26 -04:00
Matthias Clasen 3cf349eb6e Merge branch 'fix-c4013' into 'main'
gtkprintoperation-win32.c: Fix build

See merge request GNOME/gtk!6099
2023-06-16 16:38:22 +00:00
Matthias Clasen 53503e3f19 Merge branch 'a11y-computed-name' into 'main'
atcontext: Update name computation

See merge request GNOME/gtk!6088
2023-06-16 16:30:51 +00:00
Daniel Boles 8106dc0f46 reference/gtk/coordinates: Fix typos of “widget’s” 2023-06-15 17:40:08 +01:00
Matthias Clasen 8dec07b6c4 Merge branch 'better_gtkstacksidebar' into 'main'
GtkStackSidebar: Explicitly mark the sidebar items as labeled by the labels

See merge request GNOME/gtk!6100
2023-06-15 12:54:20 +00:00
Lukáš Tyrychtr 29cf15a444 GtkStackSidebar: Explicitly mark the sidebar items as labeled by the labels
That improves the reading of the GtkStackSidebar widget considerably.
Previously, Orca would not read the items at all, now it does.
2023-06-15 14:29:31 +02:00
Chun-wei Fan abe5eda0f0 gtkprintoperation-win32.c: Fix build
Include the needed headers so that we don't break the build with C4013
warnings, which are treated as errors if msvc_recommended_pragmas.h is
found during build configuration.
2023-06-15 18:50:10 +08:00
Benjamin Otte fa98e2baf3 Merge branch 'listitem' into 'main'
signallistitemfactory: finish prototype change

See merge request GNOME/gtk!6098
2023-06-15 10:10:55 +00:00
Matthias Clasen e5eba26eac Merge branch 'no_random_screen_coords' into 'main'
gtkatspicomponent: Don't return unitialized stack data as screen positions of widgets

See merge request GNOME/gtk!6097
2023-06-15 10:02:19 +00:00
Marc-André Lureau 611439aad7 signallistitemfactory: finish prototype change
Complete the API change from commit be1729b316 ("signallistitemfactory:
Update signal prototype").

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2023-06-15 09:52:34 +02:00
Lukáš Tyrychtr cb3045bf38 gtkatspicomponent: Don't return unitialized stack data as screen positions of widgets
We can not compute the correct value, but that does not mean we should return
basically random values from an unitialized stack space.

Rather than that behavior, return zeros concistently.
2023-06-15 09:06:30 +02:00
Benjamin Otte 447d1fab62 Merge branch 'wip/otte/vulkan-for-main' into 'main'
vulkan: Move some code

See merge request GNOME/gtk!6096
2023-06-14 06:01:47 +00:00
Benjamin Otte 9836389fde vulkan: Repurpose debug flags for image uploads
Now that we don't use the old environment variables anymore to force
staging buffer/image uploads, we don't need them.

However, we do autodetect the fast path for avoiding a staging buffer
now, and we might want to be able to turn that off for testing.

So add GSK_DEBUG=staging that does exactly that.
2023-06-14 03:34:07 +02:00
Benjamin Otte 7f26f5a160 vulkan: Remove gsk_vulkan_image_new_from_data()
This is unused now that all the code uses map/unmap.

The only thing that map/unmap doesn't do that the old code did, was use
a staging image instead as alternative to a staging buffer for image
uploads.

However, that code is not necessary for anything, so I'm sure we can do
without.
2023-06-14 03:34:07 +02:00
Benjamin Otte 6a009b7182 vulkan: Add upload fastpath
If the memory heap that the GPU uses allows CPU access
(which is the case on basically every integrated GPU, including phones),
we can avoid a staging buffer and write directly into the image memory.

Check for this case and do that automatically.

Unfortunately we need to change the image format we use from
VK_IMAGE_TILING_OPTIMAL to VK_IMAGE_TILING_LINEAR, I haven't found a way
around that yet.
2023-06-14 03:34:07 +02:00
Benjamin Otte 17dd100f43 vulkan: Add gsk_vulkan_memory_can_map()
.. nd use it to assert memory is mappable when mapping it.
2023-06-14 03:34:07 +02:00
Benjamin Otte 49c2c2da1a vulkan: Use map/unmap for fallback images 2023-06-14 03:34:07 +02:00
Benjamin Otte f88b1cef21 vulkan: Render fallback into vulkan memory
Use the new map/unmap image upload method for Cairo node drawing:
1. map() the memory
2. create an image surface or that memory
3. draw to that image surface
4. success

There's no longer a need for Cairo to allocate image memory.
2023-06-14 03:34:07 +02:00
Benjamin Otte c27e412ff1 vulkan: Use new upload method for texture uploads
gsk_vulkan_image_new_from_texture() now uses the direct copy via
gdk_texture_downloader_download_into().
2023-06-14 03:34:07 +02:00
Benjamin Otte 0c72f19cb1 vulkan: Add a new way to upload data into images
As an alternative to gsk_vulkan_image_new_from_data() that
takes a given data and creates an image from it, add a 3 step process:
  gsk_vulkan_image_new_for_upload()
  gsk_vulkan_image_map_memory()
  /* put data into memory */
  gsk_vulkan_image_unmap_memory()

The benefit of this approach is that it potentially avoids a copy;
instead of creating a buffer to pass and writing the data into it before
then memcpy()ing it into the image, the data can be written straight
into image memory.

So far, only the staging buffer upload is implemented.

There are also no users, those come in the next commit(s).
2023-06-14 03:34:07 +02:00
Benjamin Otte cb4e92946b vulkan: Move some code
Add gsk_vulkan_image_new_from_texture() and use it.

Also rewrite the actual code from using Cairo surfaces to using
GdkTextureDownloader.
2023-06-14 03:34:07 +02:00
Benjamin Otte e7c86f4608 vulkan: Constify upload function 2023-06-14 03:34:07 +02:00
Matthias Clasen 4d026857dc Merge branch 'wip/carlosg/pad-detection' into 'main'
gdk/wayland: Create pad devices on enter

See merge request GNOME/gtk!6094
2023-06-14 00:10:32 +00:00
Carlos Garnacho c523c68cef gdk: Include pads in GDK_SEAT_CAPABILITY_ALL
The GDK_SEAT_CAPABILITY_TABLET_PAD stood awkwardly out of the
ALL value. Even though it's not a keyboard, its focus has more
resemblance to it, so it should be part of this group together
with keyboards.
2023-06-14 01:42:53 +02:00
Carlos Garnacho 9f4320a4ac gdk/wayland: Create pad devices on enter
We were creating the pad device on wp_tablet_pad.done, but
at that time we do not know what tablet it is associated with,
thus we cannot get appropriate vid/pid/name properties for it.

To get that, we need to wait for the pad to enter a surface,
at that time we do know what tablet it is associated with, so
we can get better information about the device.

There are pads that may plausibly "change" tablet between
one .enter event and the next (e.g. Wacom Express Key Remote),
but this situation is highly unlikely. The pad devices created
are thus persistent until that situation happens.
2023-06-14 01:42:53 +02:00
Matthias Clasen 8f6cc19fdb Merge branch 'mcatanzaro/gtk-show-uri-deprecated-for' into 'main'
Change recommended replacement for gtk_show_uri()

See merge request GNOME/gtk!6093
2023-06-13 18:28:32 +00:00
Matthias Clasen 9831632fbd a11y docs: Some updates
Clarify what UI properties go into the name computation,
and mention the inspector tools for accessiblity.
2023-06-13 14:12:16 -04:00
Michael Catanzaro bef1c69254 Change recommended replacement for gtk_show_uri()
Problem is GtkFileLauncher is unable to handle all the types of URIs
that are supported by gtk_show_uri(), e.g. help: URIs. GtkUriLauncher
avoids this problem.

Another problem is that GtkUriLauncher is just generally a better choice
for launching URIs, since you don't have to create a GFile in order to
use it. Porting code is slightly simpler.

The documentation still mentions both GtkFileLauncher and GtkUriLauncher
as options, but most people will use whatever the compiler recommends
when it prints the deprecation warning.
2023-06-13 13:03:04 -05:00
Carlos Garnacho f381cdef5b Merge branch 'window-clear-resize_cursor-on' into 'main'
window: Clear resize_cursor on leave notify events

See merge request GNOME/gtk!6090
2023-06-13 11:39:04 +00:00
Michel Dänzer f8fd04402e window: Clear resize_cursor on leave notify events
When the pointer leaves the window surface, gtk_window_capture_motion
will not be called anymore, so priv->resize_cursor may remain non-NULL
indefinitely without this.

If update_cursor is later called (via gtk_window_maybe_update_cursor) on
a virtual enter notify event (e.g. because the pointer entered a
descendant surface), it would previously re-set the window surface
cursor to priv->resize_cursor, which could result in the wrong cursor
shape being shown for descendant surfaces.

This affected mutter-x11-frames, see
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1557.

One could also say that if the pointer leaves the window surface, it's
trivially not over any window edge.
2023-06-13 12:01:29 +02:00
Matthias Clasen e5f570045e Merge branch 'matthiasc/for-main' into 'main'
Matthiasc/for main

See merge request GNOME/gtk!6091
2023-06-12 19:18:49 +00:00
Matthias Clasen 4bee0e2454 ci: Collect artifacts from the asan build 2023-06-12 14:54:28 -04:00
Matthias Clasen fb6ce30fb4 listitemmanager: Quiet a compiler warning 2023-06-12 14:54:21 -04:00
Matthias Clasen 11108ed048 Merge branch 'a11y-overlay' into 'main'
inspector: Add an a11y overlay

Closes #5883

See merge request GNOME/gtk!6085
2023-06-12 17:56:26 +00:00
Matthias Clasen deac44962a Fix a crash in gtk-demo
Fixes #5889
2023-06-12 12:12:49 -04:00
Daniel Boles 0f6219c9ca docs/reference/gtk/running: Incl GDK_DEBUG=portals
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5871
2023-06-12 16:29:52 +01:00
Luca Bacci cf980cdefb Merge branch 'focus-modal-windows' into 'main'
win32: Focus modal windows when clicking on unfocused parent

See merge request GNOME/gtk!6051
2023-06-12 13:55:45 +00:00
Luca Bacci 51265e2367 Merge branch 'center-dialogs' into 'main'
win32: Center newly created transient windows

Closes #5407

See merge request GNOME/gtk!6050
2023-06-12 13:53:00 +00:00
Daniel Rusek f1484df60a Update Czech translation 2023-06-12 13:14:31 +00:00
Matthias Clasen 92a8cf3f29 inspector: Add an a11y overlay
Add an overlay that shows a11y issues.

For now, this checks for:
 - abstract roles being used
 - elements without labels
 - required attributes
 - required context
2023-06-12 07:31:49 -04:00
Alice Mikhaylenko 5a877c8d43 menubutton: Horizontally expand child
Set hexpand on the outer box so we don't propagate that expand.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5883
2023-06-12 07:31:49 -04:00
Alice Mikhaylenko 1ffaf486af menubutton: Normalize label layout
- Remove unnecessary halign=center and hexpand=0 dance
- Set hexpand=false on the outer box so we don't propagate hexpand
2023-06-12 07:31:49 -04:00
Matthias Clasen 9c3e514d3f Merge branch 'misc-a11y-fixes' into 'main'
Various a11y improvements

See merge request GNOME/gtk!6089
2023-06-12 01:48:04 +00:00
Matthias Clasen 1b829c7d01 gtk4-demo: Some a11y improvements
Add some labels in the pickers demo.
2023-06-11 20:29:25 -04:00
Matthias Clasen 0f39069be1 filechooser: Some accessibility improvements 2023-06-11 20:29:25 -04:00
Matthias Clasen bc27b54367 togglebutton: Set a11y properties on realize
The pressed property is required, so we need to
make sure that it is set.
2023-06-11 20:29:25 -04:00
Matthias Clasen 9e784f47c9 fontchooser: Add one more accessible property 2023-06-11 20:29:25 -04:00
Matthias Clasen ade66c84ed aboutdialog: Set some accessible properties 2023-06-11 20:29:25 -04:00
Matthias Clasen 57c34fca96 menubutton: Set accessible relations
In the case where we create the popover, mark it
as labelled by the button.
2023-06-11 20:29:25 -04:00
Matthias Clasen 10e91f6281 shortcutswindow: Add some accessible properties 2023-06-11 20:29:25 -04:00
Matthias Clasen aada893352 passwordentry: Change an accessible role
The caps-lock icon is really an alert. Maybe
this is in vain, since orca ignores these images.
2023-06-11 20:29:25 -04:00
Matthias Clasen 79847f20c4 atcontext: Change the way we handle fallback
The tooltip text should only be considered after
all other means are exhausted. but it can be used
for both the name and the description.

See https://www.w3.org/TR/accname-1.2/
2023-06-11 20:27:31 -04:00
Matthias Clasen 22548785b0 atcontext: Update name computation
Implement this sentence from the "Accessible Name
and Description Computation 1.2" spec:

    If the root node's role prohibits naming,
    return the empty string ("").

See https://www.w3.org/TR/accname-1.2/
2023-06-11 20:27:22 -04:00
Matthias Clasen 2349f13f45 Merge branch 'wip/alice/menu-button' into 'main'
menubutton: Horizontally expand child

Closes #5883

See merge request GNOME/gtk!6084
2023-06-11 15:14:02 +00:00
Matthias Clasen 084b4361b6 Merge branch 'master' into 'main'
Reset chars_changed_stamp in _gtk_text_btree_unref

Closes #5544

See merge request GNOME/gtk!6087
2023-06-11 11:12:52 +00:00
Daniel Boles d0ebd42e3e Popover: If can't get widget rect, zero output ptr
cherry-pick of commit a6d40b610b

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/893#note_1766079
2023-06-11 11:46:36 +01:00
Bart Jacobs a4330aae38 Reset chars_changed_stamp in _gtk_text_btree_unref
This causes an "Invalid text buffer iterator" warning to be produced if a TextIter is used after the TextBuffer is disposed.
2023-06-11 08:57:41 +00:00
Benjamin Otte a02fc2d290 Merge branch 'wip/otte/for-main' into 'main'
mediafile: Load extension at startup with GTK_MEDIA

See merge request GNOME/gtk!6086
2023-06-11 02:19:13 +00:00
Benjamin Otte 9df935591c vulkan: Handle new nodes being added correctly
When nodes are added, nothing was warning us that we need to bump
N_RENDER_NODES.

Make sure that that's no longer necessary by refactoring the code to
remove the define.
2023-06-11 03:54:50 +02:00
Benjamin Otte 1f8045ddbe vulkan: Do intersection check for every node
This is more expensive, but it finds more cases, and in particular it
catches corner cases like empty nodes or fully clipped nodes that might
otherwise make the kernel throw signals in our direction.
2023-06-11 03:54:50 +02:00
Benjamin Otte 82ba8c848b vulkan: Handle empty rects in intersects_rect()
Apart from the none case, this was already handled, so we just check if
the rect is empty now.
2023-06-11 03:15:08 +02:00
Benjamin Otte cf48f83709 mediafile: Load extension at startup with GTK_MEDIA
When the GTK_MEDIA env var is set, check at startup that it works, not
only when the first MediaFile is instantiated.

This has the fortunate side effect that it prints help output for
GTK_MEDIA=help at startup, too.
2023-06-11 03:14:55 +02:00
Matthias Clasen 9d79982677 Merge branch 'fontchooser-a11y' into 'main'
button: Improve accessible setup

See merge request GNOME/gtk!6081
2023-06-10 20:29:45 +00:00
Alice Mikhaylenko 27599d688e menubutton: Horizontally expand child
Set hexpand on the outer box so we don't propagate that expand.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5883
2023-06-11 00:02:15 +04:00
Alice Mikhaylenko c0d8716366 menubutton: Normalize label layout
- Remove unnecessary halign=center and hexpand=0 dance
- Set hexpand=false on the outer box so we don't propagate hexpand
2023-06-11 00:01:19 +04:00
Benjamin Otte 3681144768 Merge branch 'wip/otte/for-main' into 'main'
testsuite: Add another test to the listitemmanager

See merge request GNOME/gtk!6083
2023-06-10 18:51:05 +00:00
Benjamin Otte c2fef6f6fd listitemmanager: All sections without widgets are unmatched
We were failing to mark sections when both the start and end of the
untracked area fell on a section boundary.

Fixes testsuite failure in
https://gitlab.gnome.org/GNOME/gtk/-/jobs/2878290
2023-06-10 20:25:20 +02:00
Benjamin Otte f06cfa2967 testsuite: Print update after changes, not before
This way, we don't do an empty print at the start and don't miss a print
at the end.
2023-06-10 20:25:20 +02:00
Benjamin Otte 2cbee7cf86 testsuite: Check that removing listitem trackers works properly
We remove them at the end, so just to be sure, check again.

(Guess if I added this check because removing failed.)
2023-06-10 20:25:20 +02:00
Benjamin Otte f5cdd6fa32 testsuite: Add another test to the listitemmanager
Ensure the itemmanager doesn't lose any widgets by ensuring that the
tiles with widgets do account for all children of the list widget.
2023-06-10 20:25:20 +02:00
Matthias Clasen c49c971f47 colorchooser: Improve accessibility
Set up missing accessible relations, labels and roles.
2023-06-10 13:59:32 -04:00
Matthias Clasen 4746e0bdc4 Merge branch 'matthiasc/for-main' into 'main'
inspector: Fix an oversight

See merge request GNOME/gtk!6082
2023-06-10 16:15:20 +00:00
Matthias Clasen f20ef5a0fc fontchooser: Improve accessibility
Set up missing accessible relations, labels and roles.
2023-06-10 11:29:12 -04:00
Matthias Clasen cf30a4f304 button: Improve accessible setup
With the current approach, we get duplicate labels
in the accessible name: _Cancel Cancel. Change things
around to always set the labelled-by accessible relation
if we have a label, and not the label accessible property.
2023-06-10 11:29:12 -04:00
Matthias Clasen ca189cb5f5 inspector: Fix an oversight
There is no margin property, so don't set it.
2023-06-10 11:09:50 -04:00
Matthias Clasen 5e07710f5a Merge branch 'textview-ctrl-backspace' into 'main'
textview: Improve word navigation

Closes #737

See merge request GNOME/gtk!6080
2023-06-10 13:33:10 +00:00
Matthias Clasen 46bb5837e2 textview: Improve word navigation
Both Ctrl-Left and Ctrl-Backspace were failing
to step over a non-word at the beginning of
the line. Fix this to match GtkEntry behavior.

Fixes: #737
2023-06-10 09:05:34 -04:00
Matthias Clasen 1888f1e422 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Change sidebar tab behavior

Closes #3543

See merge request GNOME/gtk!6079
2023-06-10 11:03:02 +00:00
Matthias Clasen e606313ad1 gtk-demo: Change sidebar tab behavior
Change the sidebar to use the 'item' tab
behavior.

Fixes: #3543
2023-06-10 00:02:29 -04:00
Matthias Clasen b69bfe3799 testsuite: More memleak fixes 2023-06-09 23:23:32 -04:00
Matthias Clasen 5d07c71dd2 builder: Cosmetics 2023-06-09 23:23:32 -04:00
Matthias Clasen 8155b08de8 Merge branch 'matthiasc/for-main' into 'main'
inspector: Cosmetics

See merge request GNOME/gtk!6078
2023-06-10 03:17:14 +00:00
Matthias Clasen 0790f24773 gtk: Plug a memory leak 2023-06-09 22:40:38 -04:00
Matthias Clasen 5f02631812 gsk: Fully free mask nodes
We were forgetting to chain up in finalize.  Oops
2023-06-09 22:40:38 -04:00
Matthias Clasen c8133ecb50 gsk: Plug a memory leak 2023-06-09 22:40:38 -04:00
Matthias Clasen b439398d09 testsuite: Plug some memory leaks 2023-06-09 22:40:38 -04:00
Matthias Clasen fcb9048043 inspector: Show computed values in a11y tab
Show the name and description in the a11y tab.
These are not direct property values, but computed
according to ARIA rules.
2023-06-09 21:05:17 -04:00
Matthias Clasen 5816e2fe51 inspector: Cosmetics
Don't use technobabble like "fps overlay" in the UI.
2023-06-09 20:10:56 -04:00
Matthias Clasen 298fed6d94 Merge branch 'filechooser-sort-directories-first' into 'main'
FileChooser: Sort directories before files by default

See merge request GNOME/gtk!4284
2023-06-09 19:10:58 +00:00
Matthias Clasen 0557b29f5b Merge branch 'matthiasc/for-main' into 'main'
Avoid deprecation warnings from GTK_ALIGN_BASELINE_FILL

Closes #5875

See merge request GNOME/gtk!6077
2023-06-09 14:18:51 +00:00
Matthias Clasen 4c65bdf707 Fix some typos in gtk.supp
Actually ignore the media module leak.
2023-06-09 08:28:36 -04:00
Matthias Clasen 351d747909 print: Drop one use of private api
We added public api for the foreground color
for just this case, so use it.
2023-06-09 08:23:09 -04:00
Matthias Clasen 53af7208e6 gdk: Fix an oversight in GdkContentFormats
When clearing a builder, reset the counts to 0.

Otherwise valgrind spots uninitialized memory
use in our testsuite.
2023-06-09 08:17:34 -04:00
Matthias Clasen c67f3c5038 Avoid deprecation warnings from GTK_ALIGN_BASELINE_FILL
We have to be careful to only use GDK_ALIGN_BASELINE_FILL when
permitted by GDK_VERSION_MAX_ALLOWED because gtkenums.h is a
public header.

Fixes: #5875
I don't think we can avoid conditional compilation here, because the old definition is going to cause deprecated declaration warnings unless you define an old GDK_VERSION_MIN_REQUIRED.
2023-06-09 08:17:34 -04:00
Daniel Boles 1bee1cd180 DrawingArea: Document Widget.get_color, !StyleCont
StyleContext is deprecated. To just get foreground colour we now have a
method on Widget, so use that in this example, instead of StyleContext.
2023-06-09 13:02:40 +01:00
Piotr Drąg e77a17b227 Update POTFILES.in and POTFILES.skip 2023-06-09 13:22:17 +02:00
Benjamin Otte d8b4249ee9 Merge branch 'wip/otte/for-main' into 'main'
testsuite: Set GIO_USE_VFS=local everywhere

See merge request GNOME/gtk!6076
2023-06-09 00:47:26 +00:00
Matthias Clasen da47d9cc3d Merge branch 'print-subdir' into 'main'
Move printing code to its own directory

See merge request GNOME/gtk!6067
2023-06-09 00:32:45 +00:00
Benjamin Otte 53bebd2ed1 testsuite: Set GIO_USE_VFS=local everywhere
And do so centrally, not randomly in individual tests.

(Hopefully) fixes spurious test failures in CI.

Related: #5867
2023-06-09 02:29:24 +02:00
Benjamin Otte ca9f0abdd8 Merge branch 'wip/otte/for-main' into 'main'
testsuite: Make memorytexture tests random

See merge request GNOME/gtk!6075
2023-06-08 23:54:07 +00:00
Matthias Clasen 8497f97dec print: Reimplement collate preview
Redo this with widgets instead of cairo drawing.
The new private widget is called GtkPageThumbnail.
2023-06-08 19:51:28 -04:00
Matthias Clasen f22788a3a8 print: Drop some private api use 2023-06-08 19:51:28 -04:00
Matthias Clasen a30e0fad1f Move resources too 2023-06-08 19:51:28 -04:00
Benjamin Otte f033b6c2c6 testsuite: Don't always loop in memorytexture tests
When running the tests, only run the random (and potentially large) size
download test once instead of 10 times.

There's no real benefit in doing that, both because it's unlikely to
fail only in the 2nd or 9th run and because the sizes are picked
randomly.

This also speeds up the test massively as the download test was
dominating the runtime.
2023-06-09 01:12:32 +02:00
Benjamin Otte 45656ba426 testsuite: Make memorytexture tests random
Instead of picking a few numbers in advance and running them through the
test gauntlet every time, pick the random numbers at runtime.

This both increases the test coverage in that it ultimately tests more
combinations across many runs and it reduces the runtime of individual
runs because every tun only runs the download tests twice (with 1px and
the random size) instead of 5 times.

And that speedup benefits the CI, where the asan runs would cause this
test to timeout sometimes.
2023-06-09 01:12:32 +02:00
Benjamin Otte 83efe2b66c Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Fancy gradients

See merge request GNOME/gtk!6073
2023-06-08 21:57:07 +00:00
dgsasha 84840f1f2e win32: Center newly created transient windows
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5407
2023-06-08 16:42:27 -04:00
Benjamin Otte 2883f4b7a2 vulkan: Antialiasing for linear gradients
Shaders are complicated now...
2023-06-08 22:16:18 +02:00
Benjamin Otte 0a0f0d9e7e testsuite: Add a test for repeating gradients
Make sure scaling the image also scales the color stop lookup.
2023-06-08 22:16:18 +02:00
Benjamin Otte e3cc3f7841 vulkan: Make gradient shader use buffers
This allows putting any number of color stops into the buffer, so
fallbacks with too many stops are no longer necessary.
2023-06-08 21:53:06 +02:00
Benjamin Otte d1135f9e3c vulkan: Add support for storage buffers
And add a default storage buffer that is used for per-frame temporary
data.

So far nothing is using this code, this is just infrastructure.
2023-06-08 21:53:06 +02:00
Benjamin Otte 2d89dfea29 vulkan: Switch GLSL version to 450
We need more modern features soon.
2023-06-08 21:53:06 +02:00
Benjamin Otte 89f20c2fb6 vulkan: Only update descriptor sets with contents
If one of the descriptor sets doesn't have any items, don't include it
in the sets passed to vkUpdateDescriptorSets().

This has no effect right now, because we either have both images and
samplers or neither, but it will become relevant once we also support
buffers.
2023-06-08 21:53:06 +02:00
Matthias Clasen c019eb9eea print: Some more include cleanup 2023-06-07 15:35:12 -04:00
Matthias Clasen 216e415186 Update POTFILES.in
The moving the printing sources needs to
be reflected here.
2023-06-07 14:41:46 -04:00
Matthias Clasen 28fb91e85e Merge branch 'matthiasc/for-main' into 'main'
Fix a compiler warning

See merge request GNOME/gtk!6070
2023-06-07 15:11:29 +00:00
Matthias Clasen 7f3d4fa66e ci: Mark asan as must-pass
The asan test run seems to pass pretty
reliably now, so lets keep it that way.
2023-06-07 10:54:48 -04:00
Matthias Clasen 0505c8fac9 Fix a compiler warning
Compilers these days are very picky about
their NULLs.
2023-06-07 10:39:24 -04:00
Benjamin Otte ccb7c9057a Merge branch 'wip/otte/for-main' into 'main'
gtk-demo: Remove random numbers

See merge request GNOME/gtk!6069
2023-06-07 14:21:32 +00:00
Benjamin Otte ac6f18da12 gtk-demo: make the sidebar request proper width
- 25 chars sounds about right for the texts we use
- don't use min width so we allow shrinking the widget (large text or
  small mobile devices)
- ellipsize the text instead of clipping it.
2023-06-07 16:00:44 +02:00
Benjamin Otte 0d7069452b gtk-demo: Remove random numbers
There were 3 different random numbers set to determine the sidebar width
and all of them were wrong. Remove them.

Instead, propagate the natural width of the listitems.
2023-06-07 16:00:44 +02:00
Matthias Clasen 5aa62b6273 Fix a compiler warning
Compilers these days are very picky about
their NULLs.
2023-06-07 07:41:30 -04:00
Matthias Clasen 41d03c68f8 Make introspection build 2023-06-07 07:41:16 -04:00
Matthias Clasen 30ff352960 print: Maintain compatibility
gtkunixprint.h is a public header, that needs
to keep being installed in the same location.
2023-06-07 07:16:26 -04:00
Matthias Clasen 2adc017048 print: Start sorting apart includes
Use gtk/gtk.h in the print sources, so that it
becomes apparent where we are using private apis.
2023-06-07 00:18:14 -04:00
Matthias Clasen d1aae4bffa print: Move all the remaining sources
Move the unix- and Windows-specific print
sources to the gtk/print subdirectory.
2023-06-07 00:06:33 -04:00
Matthias Clasen 434a747d42 print: Move frontend sources
Move the cross-platform printing sources
to the gtk/print subdirectory.
2023-06-06 23:21:19 -04:00
Matthias Clasen 50cf1c08dd print: Install headers in a subdir
This is a first step towards isolating the printing
code within gtk.
2023-06-06 23:16:09 -04:00
Matthias Clasen caaeaedf1f Merge branch 'matthiasc/for-main' into 'main'
Drop gtkunixprint-autocleanups.h

See merge request GNOME/gtk!6066
2023-06-07 03:14:17 +00:00
Matthias Clasen 19362522e0 print: Rename private headers
Rename private print-related headers to follow our
naming conventions:
gtkprintutils.h -> gtkprintutilsprivate.h
gtkprinteroption.h -> gtkprinteroptionprivate.h
gtkprinteroptionset.h => gtkprinteroptionsetprivate.h
gtkprinteroptionwidget.h -> gtkprinteroptionwidgetprivate.h
2023-06-06 22:32:18 -04:00
Matthias Clasen 50c3ea064b Drop gtkunixprint-autocleanups.h
Move these definitions where they belong
and git rid of an auxiliary header we don't
need anymore.
2023-06-06 22:18:12 -04:00
Matthias Clasen 84e345adac Merge branch 'matthiasc/for-main' into 'main'
ci: More asan test runs

See merge request GNOME/gtk!6064
2023-06-06 11:17:32 +00:00
Marco Trevisan d2638f0955 Merge branch 'wip/otte/fix-glx' into 'main'
glx: Ignore all errors

See merge request GNOME/gtk!6065
2023-06-06 10:56:55 +00:00
Benjamin Otte e580dcf18d glx: Fake an X request to make GLX hack work
Sometimes, GLX can decide to use the previous request serial when faking
XErrors via __glXSendError() (look through the Mesa sources to enjoy).
This can cause the error trap we just installed to not feel responsible
for the error. And that makes GDK decide to immediately abort the
application.
That is not what we or GLX want.

So we use a no-op X Request to bump the request number so that when GLX
does its shenanigans, it uses a serial that our error trap will catch.

Fixes a crash in mutter's CI which apparently manages to drive GLX
without an X server.
2023-06-06 05:20:34 +02:00
Benjamin Otte 14e44f36bf glx: Move error trap even further out
This way we only create one error trap for all attempts to create a
context instead of up to 3.
2023-06-06 05:20:34 +02:00
Benjamin Otte 1e60ad1430 glx: Ignore all errors
In error cases, glXCreateContextAttribsARB() will always return NULL so
it is enough to run the loop until the first non-NULL context is
returned.

And at that point, we can just look at the return value and ignore all
errors.
2023-06-06 05:20:34 +02:00
Matthias Clasen 2c67d9f7cf ci: Build less for asan
The asan build is all about running the tests
with asan, so lets not waste time building
demos and examples.
2023-06-05 22:05:16 -04:00
Matthias Clasen 4bcaeab4dc ci: More asan test runs 2023-06-05 21:47:36 -04:00
Matthias Clasen 97a4cc301a Merge branch 'matthiasc/for-main' into 'main'
Revert "ci: More verbose output from asan"

See merge request GNOME/gtk!6063
2023-06-06 01:37:47 +00:00
Matthias Clasen baaa748248 ci: Disable headless tests under asan
Our use of LD_PRELOAD for these tests does not
sit right with asan, so just skip them in this
case.
2023-06-05 21:15:31 -04:00
Matthias Clasen cf69fecc87 ci: Tweak asan options
Allow the allocator to return NULL, so our
g_try_malloc tests don't fail.
2023-06-05 21:09:51 -04:00
Matthias Clasen 29ad2c1247 ci: Turn off LeakSanitizer
When it is enabled, almost every report from asan is
"LeakSanitizer has encountered a fatal error."
So try without.
2023-06-05 20:56:53 -04:00
Matthias Clasen 1450789052 ci: Reenable asan builds
This is an attempts to catch sporadic ci failures.
2023-06-05 20:55:00 -04:00
Matthias Clasen 51f4ad55cf wayland: Free seat globals in dispose
This matches what we do for the display globals.
2023-06-05 20:50:09 -04:00
Matthias Clasen 94d65f6ef1 gdk: Dispose seats when a display is closed
We dispose the display itself. It does not make
sense to hold onto seat resources beyond that point.
2023-06-05 20:50:09 -04:00
Matthias Clasen c3f446a95a wayland: Don't leak all globals 2023-06-05 20:50:09 -04:00
Matthias Clasen ad8e5c3a39 wayland: Drop an unused field
Nobody is using the wl_input_device field.
2023-06-05 20:50:09 -04:00
Matthias Clasen 6b26a4f9be Revert "ci: More verbose output from asan"
This reverts commit 4f65c121b7.
2023-06-05 14:52:15 -04:00
Matthias Clasen 40f215ea46 Post-release version bump 2023-06-05 07:39:28 -04:00
Matthias Clasen 55dd5f4780 4.11.3 2023-06-05 07:26:41 -04:00
Matthias Clasen 1e878d3928 Merge branch 'search-entry-allocation' into 'main'
text: Make the placeholder non-intrusive

See merge request GNOME/gtk!6060
2023-06-05 10:17:46 +00:00
Benjamin Otte 66c57a8f4e Merge branch 'wip/otte/for-main' into 'main'
testsuite: Adapt color-matrix testcase

See merge request GNOME/gtk!6018
2023-06-05 04:07:27 +00:00
Benjamin Otte ee22f8f52f stringsorter: Handle NULL strings
NULL is a valid string GValue, so we need to handle it.
The utf8 normalizing and collating functions do not, so we better catch
it early.
2023-06-05 05:33:07 +02:00
Benjamin Otte 9070c457d6 testsuite: Make clipped-repeat test work universally
Cover the rounded corners so that they cause no visible difference in
the end result.
2023-06-05 05:33:07 +02:00
Benjamin Otte bba324ce30 rendernode: Scale repeat offscreens properly
Respect the matrix in use at time of encountering a repeat node so that
the offscreen uses roughly the same device pixel density as the target.

Fixes the handling of the clipped-repeat test.
2023-06-05 05:33:07 +02:00
Benjamin Otte c322ab34c7 rendernode: Use cairo_set_device_offset()
Simplifies the code.
2023-06-05 05:33:07 +02:00
Benjamin Otte 8c5e046574 testsuite: Adapt color-matrix testcase
Make it use an alpha value that is well defined, ie 0.4 instead of 0.5.

0.4 * 255 = 102
0.5 * 255 = 127.5

This avoids rounding issues where some math may cause the resulting
alpha value to be 127, and some other math ends up with 128.
2023-06-05 05:33:07 +02:00
Benjamin Otte 8860a2a688 testsuite: fix memleak
Also use the actual diff command we found instead of searching for it
again.
2023-06-05 05:33:07 +02:00
Matthias Clasen 5ca40c3660 Merge branch 'matthiasc/for-main' into 'main'
gl: Free all tracked buffers

See merge request GNOME/gtk!6061
2023-06-05 03:03:01 +00:00
Matthias Clasen a9f9fb2022 gl: Free all tracked buffers
This was overlooked when the number of tracked
buffers was bumped from 2 to 4 in 46e3454eb7.
2023-06-04 22:17:56 -04:00
Matthias Clasen a8a49d270b searchentry: Improve size allocation
We want to always reserve space for the clear icon,
but let the text widget use that space when the icon
isn't shown. A plain box layout can't do that, so
do our own size allocation.
2023-06-04 21:50:35 -04:00
Matthias Clasen 419c431f29 text: Make the placeholder non-intrusive
We never want to let the placeholder cause
the widget to grow, so set its max-width-chars
to a small value to make it ellipsize.
2023-06-04 21:47:11 -04:00
Benjamin Otte fd5d15004e Merge branch 'wip/otte/vulkan' into 'main'
Vulkan hacking going overboard

See merge request GNOME/gtk!5992
2023-06-04 18:21:21 +00:00
Benjamin Otte 5409f0b350 vulkan: Create multiple render objects
Sometimes the GPU is still busy when the next frame starts (like when
no-vsync benchmarking), so we need to keep all those resources alone and
create new ones.
That's what the render object is for, so we just create another one.

However, when we create too many, we'll starve the CPU. So we'll limit
it. Currently, that limit is at 4, but I've never reached it (I've also
not starved the GPU yet), so that number may want to be set lower/higher
in the future.

Note that this is different from the number of outstanding buffers, as
those are not busy on the GPU but on the compositor, and as such a
buffer may have not finished rendering but have been returend from the
compositor (very busy GPU) or have finished rendering but not been
returned from the compositor (very idle GPU).
2023-06-04 19:42:01 +02:00
Benjamin Otte f1b1aacc34 vulkan: Stop differentiating rounded from cicular corners
Our shaders can handle both, so don'ttry to tell them apart anymore.

Removes a lot of unnecessary fallbacks.
2023-06-04 19:42:01 +02:00
Benjamin Otte e7201968d6 vulkan: Cleanup: Initialize constants at the top 2023-06-04 19:42:01 +02:00
Benjamin Otte 67f2ad817e vulkan: Add support for texture-scale nodes 2023-06-04 19:42:01 +02:00
Benjamin Otte f420c143e0 vulkan: Split textures and samplers
The idea here is that we can do more complex combinations and use that
to support texture-scale nodes or use fancy texture formats (suc as
YUV).

I'm not sure this is actually necessary, but for now it gives more
flexibility.
2023-06-04 19:42:01 +02:00
Benjamin Otte 1cf6dfab2f vulkan: Add a hackish way to handle empty children
For blend and crossfade nodes, one of the children may exist and
influence the rendering, while the other does not.

Previously, we would skip the node, which would cause the required
rendering to not happen. We now send a valid texture id for the
invalid offscreen, thereby actually rendering the required parts.

Fixes the blend-invisible-child compare test

Current state for compare tests:
Ok:                 397
Expected Fail:      0
Fail:               26
Unexpected Pass:    0
Skipped:            2
Timeout:            0
2023-06-04 19:42:01 +02:00
Benjamin Otte 330a8b1cdb vulkan: Convert blend shader
Same work as crossfade shader pretty much.
2023-06-04 19:42:01 +02:00
Benjamin Otte 8d19db6732 vulkan: Update the cross-fade shader
This also fixes it rendering weird things when the bounds of start and
end node don't match.
2023-06-04 19:42:01 +02:00
Benjamin Otte 0f1b039306 vulkan: Implement bindless texture rendering
Instead of having a descriptor set per operation, we just have one
descriptor set and bind all our images into it.

Then the shaders get to use an index into the large texture array
instead.

Getting this to work - because it's a Vulkan extension that needs to be
manually enabled, even though it's officially part of Vulkan 1.2 - is
insane.
2023-06-04 19:42:01 +02:00
Benjamin Otte b791aa0301 vulkan: Clip using scissors
If we have a rectangular clip without transforms, we can use
scissoring. This works particularly well because it allows intersecting
rounded rectangles with regular rectangles in all cases:
Use the scissor rect for the rectangle and the normal clipping code for
the rounded rectangle.
2023-06-04 19:42:01 +02:00
Benjamin Otte 7fd94c1828 vulkan: Make scissoring an explicit operation
The idea is to use it for clip nodes when they are integer-aligned.

To do that, we need to track the scissor rect in the parse state, so we
do that, too.

Also move the viewport offset out of the projection matrix, as it is
part of the transform between clip and scissor, so it needs to live in
the offset.
2023-06-04 19:42:01 +02:00
Benjamin Otte dd4c1167b2 vulkan: Remove unneeded struct member
We can use gsk_vulkan_pipeline_get_vertex_stride() whenever we need that
value.
2023-06-04 19:42:01 +02:00
Benjamin Otte d411912396 vulkan: Bind vertex buffers only once
We can index into the same buffer from every pipeline due to the aligned
buffer writes (see previous commit).

So we do that.
2023-06-04 19:42:01 +02:00
Benjamin Otte 0e93ad8671 vulkan: Align vertex data
We align the data to a multiple of vertex stride, that way we use more
memory, but we could compute an offset into the vertex buffer without
changing the offset.
2023-06-04 19:42:01 +02:00
Benjamin Otte d98991a0ad vulkan: Set offsets when counting
We can set the vertex offset while counting the data, this gets rid of
the need of passing all the counting machinery into the actual data
collection code.
2023-06-04 19:42:01 +02:00
Benjamin Otte 1f7dcc1286 vulkan: Simplify switch statement
All branches do the same thing now, so pull them all into the same
branch.
2023-06-04 19:42:01 +02:00
Benjamin Otte 328cdf7b2a vulkan: Simplify collect_vertex_data()
We don't have any size arguments to it, so don't use them.
2023-06-04 19:42:01 +02:00
Benjamin Otte 79a227bc64 vulkan: Remove a function from pipeline impls
That function is available already in the structs we feed to Vulkan.

Store it from there and reuse it.
2023-06-04 19:42:01 +02:00
Benjamin Otte 0fee26252c vulkan: Don't draw fully clipped nodes
... if they are container nodes. Other nodes will get culled by the
vertex shader.
2023-06-04 19:42:01 +02:00
Benjamin Otte d48b6b9ad5 vulkan: Add optimization for transforms
When attempting a complex transform, check if the clip can be ignored
and do that if possible.

That way we don't cause fallbacks when transforming the clip is too
complex.
2023-06-04 19:42:01 +02:00
Benjamin Otte d4618ea8a6 vulkan: Don't crash with overly large nodes
... when these nodes are used as children of a complex transform nodes
and we lose the clip.
2023-06-04 19:42:01 +02:00
Benjamin Otte a73530f952 vulkan: Update texture shader to do AA 2023-06-04 19:42:01 +02:00
Benjamin Otte 3e620a8fe5 vulkan: Split generic code off
No need to duplicate code in shaders when it can be shared.
2023-06-04 19:42:01 +02:00
Benjamin Otte 6d8c8199d9 vulkan: Use rounded rect APIs to improve clips
There are a bunch of intersection APIs available these days.
Let's use them.
2023-06-04 19:42:01 +02:00
Benjamin Otte 968ceb71d5 gsk: Add (private) gsk_rounded_rect_intersection()
The idea is that for a rectangle intersection, each corner of the
result is either entirely part of one original rectangle or it is
an intersection point.

By detecting those 2 cases and treating them differently, we can
simplify the code to compare rounded rectangles.
2023-06-04 19:42:01 +02:00
Benjamin Otte 7f5504bea4 vulkan: Set the initial clip rect
Instead of rendering unclipped, set the clip region to the extents of
the current clip region.
2023-06-04 19:42:01 +02:00
Benjamin Otte 4b2b239550 vulkan: Only draw one rect
Instead of emitting the render commands once per rectangle of the clip
region, just emit them once with the region's extents.

This is generally faster because it emits fewer commands to the GPU,
even though it may touch significantly more pixels.

For a proper method, we'd need to record the commands per clip rectangle
instead of emitting all of them all the time.
2023-06-04 19:42:01 +02:00
Benjamin Otte 23c10d434c vulkan: Use CLAMP_TO_EDGE in sampler
We don't want to clamp to the border, that causes fade-outs at the
edges.
2023-06-04 19:42:01 +02:00
Benjamin Otte 87c9503293 vulkan: Rewrite AA shaders to respect scale
The border and color shaders - the ones that do AA - now multiply their
coordinates by the scale factor, which gives them better rounding
capabilities.

This in particular improves the case where they are used in fractional
scaling situations, where the scale is defined at the root element.
2023-06-04 19:42:01 +02:00
Benjamin Otte 76634cb68b vulkan: Don't allocate no descriptor sets
If we don't need them, exit early.

Shuts up the validation layers when running simple denos without
textures.
2023-06-04 19:42:01 +02:00
Benjamin Otte 52eefdb7d9 vulkan: Only use a single pipeline layout
There's no need to use 3 different ones when they are compatible.
2023-06-04 19:42:01 +02:00
Benjamin Otte ea9f0a3372 vulkan: Don't cull vertices
We end up with the backside, when we scale(-1) and we still want it to
be visible, just flipped.
2023-06-04 19:42:01 +02:00
Benjamin Otte 8561ff37c4 vulkan: Use scale factor for offscreens and fallbacks
Previously, we just used the defaultscale factor, but now that we're
having it available in push constants, we can read it back for creating
offscreens and rendering fallbacks.

So do that.
2023-06-04 19:42:01 +02:00
Benjamin Otte a09580b9ef vulkan: Split scale from matrix
Now, the scale is no longer part of the matrix. This allows shaders to
transform points by the scale which increases accuracy for antialiasing.
2023-06-04 19:42:01 +02:00
Benjamin Otte 0511227379 vulkan: Keep the modelview as a GskTransform
This allows doing more optimized math on it.
2023-06-04 19:42:01 +02:00
Benjamin Otte 4183ce0b52 vulkan: Split modelview and projection
This is adding extra work, but the benefits should become visible
in future commits.
2023-06-04 19:42:01 +02:00
Benjamin Otte 57222cc64c vulkan: Add scale to push constants
This way, it can be pushed to the shaders
2023-06-04 19:42:01 +02:00
Benjamin Otte b3c1284382 vulkan: Move scale into the state object 2023-06-04 19:42:01 +02:00
Benjamin Otte b02e054592 vulkan: Add offset to the Vulkan clip checks
This was forgotten when tracking the offset was added, so code was
actually selecting the wrong shaders.
2023-06-04 19:42:01 +02:00
Benjamin Otte 870ee06d1f vulkan: Move offset into the state object 2023-06-04 19:42:01 +02:00
Benjamin Otte 8d586be693 vulkan: Add a new GskVulkanParseState
It's a 1:1 replacement for GskVulkanPushConstants, just without the
indirection through a different file.

GskVulkanPushConstants as a struct is gone now.
The file still exists to handle the push_constants operation.
2023-06-04 19:42:01 +02:00
Benjamin Otte 94ab11b999 vulkan: Don't store push constants in RenderOp
Instead, only store the values that are needed.
2023-06-04 19:42:01 +02:00
Benjamin Otte 9b1dcd3872 vulkan: Split out gsk_vulkan_render_pass_append_push_constants()
Simplifies the code and makes future refactoring easier
2023-06-04 19:42:01 +02:00
Benjamin Otte c37171f4d6 vulkan: Pass values to push directly
Don't require a GskVulkanPushConstants there.
2023-06-04 19:42:01 +02:00
Benjamin Otte c479f93372 vulkan: Add a static assert
We don't want to make the push constants larger than what the spec
guarantees. And that is 128 bytes, see value for
maxPushConstantsSize in table 55 of
https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#limits-minmax
2023-06-04 19:42:01 +02:00
Benjamin Otte 186e056c56 vulkan: Handle clip properly for offscreens
This was broken in the last commit.
2023-06-04 19:42:01 +02:00
Benjamin Otte d8b9c3ae96 vulkan: Track offset in the renderpass
This avoids emitting lots of push constant updates as most of the
transforms we have are simple translations to adjust drawing for the
next widget.
2023-06-04 19:42:01 +02:00
Benjamin Otte 5de6f12e88 vulkan: Pass scale to offscreens
Create offscreens with enough pixels for the given scale and ensure
the scale is passed on.

This improves text rendering on offscreens quite a bit.
2023-06-04 19:42:01 +02:00
Benjamin Otte 5422c12577 vulkan: Clean up scale handling
1. Use a graphene_vec2_t
2. Ensure it's always positive
3. Don't break with fallback

The scale value is nothing more than an indication of how many pixels to
assume per unit of a node.
2023-06-04 19:42:01 +02:00
Benjamin Otte bb145b9bc1 vulkan: Fix typo 2023-06-04 19:42:01 +02:00
Benjamin Otte a55fda0b49 vulkan: Don't store unused matrices
We can compute it when needed, so do that.
2023-06-04 19:42:01 +02:00
Benjamin Otte 5b93a32f90 vulkan: Remove unneeded argument
The initial matrix can be computed as needed, so we don't need to
precompute it.
2023-06-04 19:42:01 +02:00
Benjamin Otte 495ee1be3d vulkan: Don't explode without vertex data
If no buffer has any vertex data (read: if nothing gets drawn), don't
try to allocate a 0 bytes buffer.
2023-06-04 19:42:01 +02:00
Benjamin Otte 7f1bd1f047 vulkan: Handle empty child bounds in repeat node
Also add test to the testsuite for it.
2023-06-04 19:42:01 +02:00
Benjamin Otte da147dca92 vulkan: Fix repeat nodes 2023-06-04 19:42:01 +02:00
Benjamin Otte 8ba5ff98aa vulkan: Don't transform the viewport rect
We don't want to render the offscreen trnsformed, we want to render it
as-is.

We lose the correct scale factor, but that requires some separate work,
so for now it gets a bit blurry on hidpi.
2023-06-04 19:42:01 +02:00
Benjamin Otte 34f4493c36 vulkan: Make quarks global variables
I don't want to ensure there's a RenderPass available everywhere and
recreate the quarks in each, I just want to use them.
2023-06-04 19:42:01 +02:00
Benjamin Otte 314923d4b5 vulkan: Split out a function
We can now create offscreens explicitly.
2023-06-04 19:42:00 +02:00
Benjamin Otte d2f45dae96 vulkan: offscreens are used as color attachments
... so set the corresponding flag.

Also name the function "new_for_offscreen()" because thats what this
function is about, "texture" is ambiguous.
2023-06-04 19:42:00 +02:00
Benjamin Otte 0e31cf9542 vulkan: compute new modelview directly
no need to go through a GskTransform
2023-06-04 19:42:00 +02:00
Benjamin Otte af901a10e3 vulkan: Make border shader handle fractional widths
We were rounding widths properly, make sure we always round up.
2023-06-04 19:42:00 +02:00
Benjamin Otte 3d1a607367 vulkan: Don't round corners when growing rounded rect
If the corner is set to 0, keep it there.
2023-06-04 19:42:00 +02:00
Benjamin Otte 1be21a33d9 vulkan: Rewrite rounded rectangle to use SDF distance
We can use this to properly compute distance in scaled situations.
We also now compute coverage with (imperfect) antialiasing.
2023-06-04 19:42:00 +02:00
Benjamin Otte 64bcdb713c vulkan: Start rework on shaders to allow antialiased drawing
This introduces the rect object and adds a rect_distance() and
rect_coverage() function.

_distance() returns the signed distance tp the rectangle.
_coverage() returns the coverage of a pixel centered at that position.

Note that the pixel size is computed using dFdx/dFdy.
2023-06-04 19:42:00 +02:00
Benjamin Otte 4a868736f9 vulkan: Render whole texture
When the node bounds were a non-integer size, the texture would get
ceil()ed pixels, but various viewport or scissor computations might
floor() instead, leaving the right/bottom row of pixels untouched.
Make sure those functions ceil(), too.
2023-06-04 19:42:00 +02:00
Benjamin Otte cfeaa0ac72 renderer: return_if_fail() if the given texture size is 0
All renderers SEGV currently when that happens.
2023-06-04 19:42:00 +02:00
Matthias Clasen b44ef07e22 Merge branch 'matthiasc/for-main' into 'main'
wayland: Don't leak cursor structs

See merge request GNOME/gtk!6058
2023-06-04 17:35:04 +00:00
Ekaterine Papava 7f119b5ad2 Update Georgian translation 2023-06-04 14:45:45 +00:00
Matthias Clasen d427933c61 testsuite: Improve test coverage 2023-06-04 09:04:25 -04:00
Matthias Clasen 85bafbdff0 wayland: Don't leak cursor structs
Found by gcc's -fanalyzer.
2023-06-04 07:58:24 -04:00
Matthias Clasen 7ae7356284 NEWS: Cosmetics 2023-06-04 07:58:24 -04:00
Matthias Clasen 444d5fa500 Merge branch 'drop-x11-dnd-keynav' into 'main'
x11: Stop using passive grabs

See merge request GNOME/gtk!6055
2023-06-03 19:38:24 +00:00
Matthias Clasen c380d17621 Revert "gdk/x11: Also grab keyboard during XDnD grabs"
This reverts commit ae94417f80.
2023-06-03 12:25:25 -04:00
Matthias Clasen 686d18dfc2 x11: Stop using passive grabs
The keynav that this implements is half-broken under
xwayland anyway, and it confused and complicates things
on the compositor side.
2023-06-03 12:25:25 -04:00
Benjamin Otte 0a1702ae99 Merge branch 'wip/otte/fix-glx' into 'main'
glx: Trap errors inside loop

Closes #5857

See merge request GNOME/gtk!6056
2023-06-03 16:19:09 +00:00
Benjamin Otte 0016fea36b glx: Trap errors inside loop
Instead of trapping errors for the whole loop trying to create GL
contexts, trap them once per GL context.

Apparently GLX does throw an error when a too high version is requested
and doesn't just return NULL and then that error lingers when we try
lower versions.

Fixes #5857
2023-06-03 18:03:56 +02:00
Matthias Clasen 7ef46293aa Merge branch 'wip/antoniof/boxlayout-baseline-optional' into 'main'
boxlayout: Don't always reserve height for baseline alignment

Closes #5863

See merge request GNOME/gtk!6053
2023-06-03 11:01:40 +00:00
António Fernandes 6b59c138b2 boxlayout: Don't always reserve height for baseline alignment
Otherwise an horizontal box may have a larger minumum height than
any of its children even though non of them is baseline-aligned.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5863
2023-06-02 20:18:56 +01:00
dgsasha b7e3a231b4 win32: Focus modal windows when clicking on unfocused parent 2023-06-02 12:33:03 -04:00
Matthias Clasen c8c895d160 Merge branch 'trap-bad-rr-errors' into 'main'
x11: Trap XRandr errors when getting outputs during init and update

See merge request GNOME/gtk!6046
2023-06-02 11:31:45 +00:00
Luca Bacci acbd7f212e Merge branch 'for-main' into 'main'
GdkWin32 Cleanup

See merge request GNOME/gtk!5714
2023-06-02 09:34:48 +00:00
Marco Trevisan (Treviño) f2a2889153 x11: Trap XRandr errors when getting outputs during init and update
We may try to update the XRR outputs and Crtcs when they're changing in
the server, and so we may get BadRROutput that we're currently not
handling properly.

As per this, use traps and check whether we got errors, and if we did
let's ignore the current output.

It's not required to call init_randr13() again because if we got errors
it's very likely that there's a change coming that will be notified at
next iteration during which we'll repeat the init actions.
2023-06-02 00:30:14 +02:00
Matthias Clasen a4ae215309 Merge branch 'sumibi-yakitori/fix-glcontext-macos' into 'main'
macOS: Fix problems with OpenGL context creation on macOS

Closes #5811

See merge request GNOME/gtk!6044
2023-06-01 20:58:22 +00:00
Daniel Boles fa16ba12cf Window: Copy caveats from :*visible to the setters 2023-06-01 20:31:22 +01:00
Daniel Boles ec2421b187 Window: Fix wrong case in property attribute which
rendered the literal text `org.gtk.MEthod.set_property	focus-visible`.
2023-06-01 20:26:57 +01:00
sumibi-yakitori 1fce2b1e06 Fix an issue where min_version was not being used as the minimum version required by GTK 2023-06-01 23:05:44 +09:00
Matthias Clasen 38bf843de8 Merge branch 'wip/alice/muxer-fix' into 'main'
actionmuxer: Correctly notify actions after reparenting

Closes #5861

See merge request GNOME/gtk!6043
2023-06-01 10:54:33 +00:00
sumibi-yakitori 7b8a5235d4 Fix a bug in error checking conditions. This avoids unintentional Legacy of the created OpenGL context 2023-06-01 16:46:24 +09:00
sumibi-yakitori 3c9b3ead6f The GL version reported by epoxy seems to depend on the current GL context, so the GL context to create should be the one determined by gdk_gl_context_get_matching_version 2023-06-01 16:43:57 +09:00
Alice Mikhaylenko 1549ec5f9b actionmuxer: Correctly notify actions after reparenting
When registering an observer, we send a notification and for that we need
to query the action's state and param type. When setting up a muxer parent,
same thing happens, except the action is queried on the parent instead.

This means that the muxer will notify observers about the parent's actions,
but not about its own.

Add a test to verify it works.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5861
2023-06-01 06:39:44 +04:00
Matthias Clasen 4339e8e464 Merge branch 'matthiasc/for-main' into 'main'
gsk: Support straight alpha textures

See merge request GNOME/gtk!6041
2023-05-31 19:14:07 +00:00
Matthias Clasen 39f4d5ccf7 gltexturebuilder: Update the docs
We do handle unpremultiplied alpha correctly (albeit
non-optimally) now.
2023-05-31 14:39:07 -04:00
Matthias Clasen 957fa87fce gsk: Support straight alpha textures
This is not the optimal way of doing it: we're
reuploading the texture with client-side conversion.
But it fits nicely into our current handling of mipmaps.

We can do better once we use shaders for colorspace
conversions.
2023-05-31 14:37:33 -04:00
Matthias Clasen e8bdd46d8d Merge branch 'a11y-crash' into 'main'
label: Fix crashes when executing a11y actions

See merge request GNOME/gtk!6034
2023-05-31 12:27:49 +00:00
Erik Schilling d03b27b441 label: Fix crashes when executing a11y actions 2023-05-31 12:27:48 +00:00
Matthias Clasen f4cbe26af3 Merge branch 'more-texture-tests' into 'main'
testsuite: Add more download tests

See merge request GNOME/gtk!6038
2023-05-31 12:01:31 +00:00
Luca Bacci 24af4b48cc GdkWin32: Remove unused functions 2023-05-31 12:15:57 +02:00
Luca Bacci 1c8caf745f GdkWin32: Remove declarations of unused types from gdkprivate-win32.h 2023-05-31 12:15:57 +02:00
Luca Bacci 395d80f131 GdkWin32: Remove declarations of unexisting functions from gdkprivate-win32.h 2023-05-31 12:15:57 +02:00
Luca Bacci 74229572e7 GdkWin32: Remove defines for old MinGW headers 2023-05-31 12:15:57 +02:00
Luca Bacci cbb3d3f177 GdkWin32: Remove _gdk_display_hdc global variable 2023-05-31 12:15:57 +02:00
Luca Bacci 8861d0eb53 GdkWin32: Turn a few functions to static
When used only in the source file they're defined in.
Also remove the corresponding declarations from
gdkrivate-win32.h.
2023-05-31 12:15:57 +02:00
Luca Bacci a23bc894e9 GdkWin32: Remove unused debug functions
* _gdk_win32_print_paletteentries
 * _gdk_win32_print_system_palette
 * _gdk_win32_print_hpalette
 * _gdk_win32_drag_protocol_to_string
 * _gdk_win32_data_to_string
 * _gdk_win32_gdkrectangle_to_string
 * _gdk_win32_cairo_region_to_string
 * _gdk_win32_surface_description
2023-05-31 12:15:57 +02:00
Luca Bacci 156e25b6aa Update manifest XML for the GTK DLL 2023-05-31 12:15:49 +02:00
Matthias Clasen 96f6787a3e testsuite: Add more download tests
Add some odd-sized texture sizes to the
download tests, to trigger alignment issues
in the various upload code paths. And add
a size that is bigger than the max-texture-size
we force in one of our test setups.

To compensate, reduce the number of
runs per size from 20 to 10.
2023-05-30 23:01:20 -04:00
Matthias Clasen cc665f29ea testsuite: Plug a memory leak 2023-05-30 22:37:03 -04:00
Matthias Clasen 8d2047c824 testsuite: Use proper alignment when uploading to GL 2023-05-30 22:36:41 -04:00
Matthias Clasen a79da8b655 Improve test coverage for GdkGLTexture 2023-05-30 22:36:10 -04:00
Matthias Clasen f29c7e76f5 gltexture: Use proper alignment for downloads 2023-05-30 22:35:45 -04:00
Matthias Clasen 29867e7ae1 NEWS: Updates 2023-05-30 20:21:13 -04:00
Matthias Clasen 876b439d4a Merge branch 'matthiasc/conversion-tests' into 'main'
Texture format work

See merge request GNOME/gtk!6035
2023-05-31 00:13:51 +00:00
Matthias Clasen 4f6d7c69a1 gltexturebuilder: Document format expectations
Provide some details about storage and alpha handling.
2023-05-30 19:46:13 -04:00
Matthias Clasen 2bf2635635 testsuite: Exclude some formats on GLES
GLES < 3.2 has some problems with 16-bit formats,
so exclude these from our download tests.
2023-05-30 19:46:13 -04:00
Matthias Clasen 67ed09f5ae testsuite: Add tests for native GL textures
Create GL textures in gray and GA formats
and check that we can download from them
successfully.
2023-05-30 19:46:13 -04:00
Matthias Clasen 1c72f46eed gltexture: Rewrite downloading code
For non-gles, make it handle unpremultiplied formats,
and everything else, by downloading the texture in its
preferred format and, in most cases, doing a
gdk_memory_convert afterwards.

For gles, keep using glReadPixels, but handle cases
where the gl read format doesn't match the texture
format by doing the necessary swizzling before calling
gdk_memory_convert.
2023-05-30 15:57:18 -04:00
Matthias Clasen f5e7a1d4cc Merge branch 'fix-selection-input-stream-leak' into 'main'
gtkselectioninputstream-x11: Do not leak the stream and double-free the EOF bytes marker

Closes #4892

See merge request GNOME/gtk!6037
2023-05-30 19:10:49 +00:00
Matthias Clasen 0f61c52593 gdk: Simplify gdk_memory_format_gl_format
Make the callers of this function check for
straight alpha themselves, and only do the
version compatibility check here. This makes
the function usable in contexts where straight
alpha is acceptable.
2023-05-30 14:49:45 -04:00
Matthias Clasen a4bae6a62d gsk: Use matching memory format
memory_format_gl_format returns the new memory
format if it made a change, we should not drop
that on the floor.
2023-05-30 14:41:01 -04:00
Sophie Herold d141ac5adf gdk: Add gray/alpha memory formats to testsuite 2023-05-30 14:41:01 -04:00
Sophie Herold 894a4bda85 gdk: Support gray/alpha in PNG loader 2023-05-30 14:41:01 -04:00
Sophie Herold 2b88505ca4 gdk: Support gray/alpha in TIFF loader
Use PHOTOMETRIC_MINISBLACK for grayscale image
2023-05-30 14:41:01 -04:00
Sophie Herold ef8c835762 gsk: Support swizzle for gray and alpha formats
Swizzling is needed to display one channel memory formats
as gray etc.
2023-05-30 14:41:01 -04:00
Sophie Herold 50115d70c6 gdk: Add grayscale and alpha memory formats 2023-05-30 14:41:01 -04:00
Luca Bacci 1a058a41c9 Do not keep HINSTANCE variables around
Use &__ImageBase for the GTK DLL and GetModuleHandle (NULL)
for the application module. Then remove DllMain as it's not
necessary anymore.

References:

 [1] Accessing the current module's HINSTANCE from a static library:
     https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483
2023-05-30 19:31:54 +02:00
Marco Trevisan (Treviño) be4f6ff3da gdkselectioninputstream-x11: Explicitly handle stream ownership in signal
The display xevent signal connection takes the ownership of the stream
until we get a valid event, so it should manage the stream lifetime.

So make this clearer, by automatically removing the stream reference
when we disconnect from the xevent signal handler.
2023-05-30 17:59:19 +02:00
Marco Trevisan (Treviño) 4fcf899852 gdkselectioninputstream-x11: Make it clearer how we manage the stream ownership
It gets unreffed during gdk_x11_selection_input_stream_complete, so use
APIs that make this clearer.
2023-05-30 17:54:29 +02:00
Marco Trevisan (Treviño) 371e860184 gtkselectioninputstream-x11: Do not add an extra reference to the returned stream
We create a new stream during gdk_x11_selection_input_stream_new_async()
then such stream is referenced when passed to the task via
g_task_return_pointer(), so there's no need to reference it again before
returning it, or we'd end up leaking.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4892
2023-05-30 17:50:56 +02:00
Marco Trevisan (Treviño) bce1e0bfdd gtkselectioninputstream-x11: Do not add unreffed bytes to the chunks queue
This should never happen, but we may exit the loop because of count value
with an unreffed bytes pointer being added back to the chunks queue.
2023-05-30 17:43:57 +02:00
Marco Trevisan (Treviño) 468d2cb7f2 gtkselectioninputstream-x11: Do not add EOF marker twice to the chunks queue
We were adding the same EOF marker two times back to the chunks queue,
one implicitly, and the other time could happen when exiting the loop.
2023-05-30 17:42:59 +02:00
Jordi Mas b520a5ceda Update Catalan translation 2023-05-30 06:41:10 +02:00
Matthias Clasen e6bc82cff5 Merge branch 'fix_gtkstack_crash' into 'main'
GtkStack: Fix a potential crash in gtk_stack_get_first_accessible_child

See merge request GNOME/gtk!6031
2023-05-29 23:38:05 +00:00
Matthias Clasen d021aa7bd2 Merge branch 'macos-fixes' into 'main'
For main

See merge request GNOME/gtk!6032
2023-05-29 23:37:22 +00:00
Benjamin Otte 3dc3d03a08 testsuite: Add conversion tests
Ensure we can convert from any format to any other format.
2023-05-30 00:42:10 +02:00
Benjamin Otte 788bd575d6 testsuite: Disable certain texture download tests
The GL renderers like to premultiply content that isn't, and due to the
data loss with alpha == 0 (transparent white, transparent black and
transparent anything are all represented by (0, 0, 0, 0) when
premultiplied) these values cannot be converted back.
2023-05-30 00:42:10 +02:00
Benjamin Otte 94a2dc4c47 testsuite: Update memorytexture test for TextureDownloader
There is no longer a need to use gdk_texture_download() and force
conversion to ARGB8 format. We can download the pixels in the original
format again.

That way we avoid testing the conversion code and avoid having to deal
with differences in representable colors.

However, some formats do do conversions, so we allow pixel comparisons
to be accurate (requires 16bit comparison accuracy) or inaccurate (we
only care about 8bit).
Note that for the default RGBA formats, this is identical and means they
need to be bit-exact the same, no matter what.
But the higher bit depth formats may be more different - floating point
can even have different values with high accuracy (the float mantissa is
23 bit, we only care about 16).
2023-05-30 00:42:10 +02:00
Benjamin Otte 169a7f83e6 testsuite: Imitate gdk_memory_convert() correctly
The formula use to compute pixel values from GdkRGBA floats was slightly
adapted some time ago, copy that adaptation
2023-05-30 00:39:46 +02:00
Luca Bacci 703494c7fa testsuite: rename 'wait' function to 'timed_loop'
When compiling for macOS, CLang errors out because a non-static
wait function is declared in sys/wait.h.
2023-05-29 16:43:28 +02:00
Luca Bacci d642072603 Check for NULL groups in gtk_action_muxer_get_group ()
The groups hash table is initialized lazily when inserting
the first GActionGroup (gtk_action_muxer_insert ()). Do as
all surrounding code does and check for NULL before using
groups.

This avoids triggering a warning
2023-05-29 16:43:28 +02:00
Lukáš Tyrychtr ab7a4f64cb GtkStack: Fix a potential crash in gtk_stack_get_first_accessible_child
This one can occur when the stack has no pages.
2023-05-29 15:14:51 +02:00
Jami Kettunen cfef21501c FileChooser: Sort directories before files by default
This imho is what most people[1][2] would expect to be the default in
modern times; considering this also cannot be "easily" configured
outside of the cli utilities gsettings or dconf it should just be the
default.

[1] https://superuser.com/questions/843615/gtk-3-14-file-chooser-folders-first
[2] https://askubuntu.com/questions/789505/can-i-choose-to-not-sort-directories-before-files-on-file-open-dialogs
2021-12-25 15:16:11 +02:00
503 changed files with 15164 additions and 8510 deletions
+2
View File
@@ -0,0 +1,2 @@
[flake8]
ignore = E501
+15 -5
View File
@@ -222,7 +222,7 @@ macos:
-Dcpp_std=c++11
-Dpixman:tests=disabled
-Dlibjpeg-turbo:simd=disabled
-Ddemos=false
-Dbuild-demos=false
-Dbuild-tests=false
-Dbuild-examples=false
-Dbuild-testsuite=false
@@ -385,17 +385,27 @@ asan-build:
tags: [ asan ]
stage: analysis
needs: []
when: manual
variables:
script:
- export PATH="$HOME/.local/bin:$PATH"
- CC=clang meson setup --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled -Df16c=disabled _build
- CC=clang meson setup
--buildtype=debugoptimized
-Db_sanitize=address
-Db_lundef=false
-Dbuild-demos=false
-Dbuild-tests=false
-Dbuild-examples=false
-Dintrospection=disabled
-Df16c=disabled
_build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build x11
artifacts:
when: always
paths:
- _build/meson-logs
allow_failure: true
- "${CI_PROJECT_DIR}/_build/meson-logs"
reference:
image: $FEDORA_IMAGE
+2 -2
View File
@@ -23,8 +23,8 @@ flatpak build ${builddir} meson \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Ddemos=true \
-Dprofile=devel \
-Dbuild-demos=true \
-Ddemo-profile=devel \
_flatpak_build
flatpak build ${builddir} ninja -C _flatpak_build install
+1 -1
View File
@@ -9,7 +9,7 @@ backend=$2
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:verbosity=1:log_threads=1
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
export G_SLICE=always-malloc
case "${backend}" in
+121 -4
View File
@@ -1,4 +1,93 @@
Overview of Changes in 4.11.3, xx-xx-xxxx
Overview of Changes in 4.11.5, xx-xx-xxxx
=========================================
Overview of Changes in 4.11.4, 03-07-2023
=========================================
* GtkFileChooser:
- Default to sorting folders first
- Fix a crash when visiting recent files
* GtkTextView:
- Fix corner cases in word navigation
* GtkMenuButton:
- Normalize label layout
* GtkDropDown:
- Add support for sections
* GtkVideo:
- Make the overlay icon clickable
* GtkWindow:
- Clear the resize cursors to avoid artifacts
* GtkFileDialog:
- Always set initial-folder
* GtkDropDown:
- Update on expression changes
* GtkMapListModel:
- Implement GtkSectionModel
* Accessibility:
- Improvements all over the place: GtkButton, GtkPasswordEntry,
GtkFontChooserDialog, GtkColorChooserDialog, GtkShortcutsWindow,
GtkMenuButton, GtkAboutDialog, GtkFileChooserDialog, GtkStackSidebar,
GtkStackSwitcher, GtkMediaControls, GtkColorDialogButton, GtkDropDown,
GtkInfoBar, GtkNotebook, GtkPrintUnixDialog, GtkModelButton
- Make name computation follow the ARIA spec more closely
- Adapt name computation for the common 'nested button' scenario
- Change many containers to use `generic` instead of `group`
- Use `generic` as the default role
- Use `application` instead of `window` for windows
- Add properties for accessible names of not directly exposed
widgets in GtkListView, GtkGridView and GtkColumnView
* DND:
- Fix criticals when drops are rejected
* X11:
- Fix regressions in GLX setup
* Windows:
- Center newly created transient windows
* Vulkan:
- Add antialising for gradients
- Do less work on clipped away nodes
- Redo image uploading
- Support different image depths and formats
- Add a pipeline cache
* Demos:
- gtk4-demo: Improve window sizing
- gtk4-demo: Improve focus behavior
- gtk4-demo: Add many missing a11y properties
* Tools:
- gtk4-builder-tool: Make render an alias screenshot
* Inspector:
- Show more information in the a11y tab
- Add an accessibility overlay with warnings and recommendations
- Limit the width of the a11y tab
* Build:
- Require GLib 2.76
- Make asan builds work again
- Fix the build if ld is not ld.bdf
* Translation updates:
Brazilian Portuguese
Catalan
Czech
Georgian
Overview of Changes in 4.11.3, 05-06-2023
=========================================
* GtkGridView:
@@ -8,6 +97,9 @@ Overview of Changes in 4.11.3, xx-xx-xxxx
* GtkListView:
- Don't leak the factories
* GtkColumnView:
- Support displaying sections
* GtkNotebook:
- Make the pages model implement GtkSelectionModel
@@ -17,18 +109,41 @@ Overview of Changes in 4.11.3, xx-xx-xxxx
* GtkPopoverMenu:
- Avoid unnecessary left padding
* Css:
* GtkSearchEntry:
- Improve size allocation for the clear icon
* GtkBoxLayout:
- Fix a regression from recent baseline work
* CSS:
- Add new binding-friendly css provider apis
* Theme:
- Show focus in the shortcuts window
* Tests:
- Improve test coverage
* GDK:
- Support grayscale and alpha texture formats for loading
and saving to png and tiff, and in GL
- Fix some regressions in GL context initialization
* GSK:
- Support grayscale and alpha texture formats in the GL renderer
- Support straight alpha textures in the GL renderer
- Many improvements to the experimental Vulkan renderer
* Wayland:
- Make exporting surface handles more flexible
* X11:
- Trap XRandr errors
- Stop using passive grabs during DND
* Windows:
- Many cleanups and simplifications
* Tests:
- Improve test coverage
* Build:
- Some build options have been renamed:
demos -> build-demos
@@ -48,7 +163,9 @@ Overview of Changes in 4.11.3, xx-xx-xxxx
* Translation updates:
Basque
Catalan
Georgian
Russian
Turkish
Overview of Changes in 4.11.2, 09-05-2023
+4
View File
@@ -162,6 +162,10 @@ create_page4 (GtkWidget *assistant)
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), progress_bar, GTK_ASSISTANT_PAGE_PROGRESS);
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), progress_bar, "Applying changes");
gtk_accessible_update_property (GTK_ACCESSIBLE (progress_bar),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Applying changes",
-1);
/* This prevents the assistant window from being
* closed while we're "busy" applying changes.
*/
+50 -5
View File
@@ -4,6 +4,9 @@
<object class="GtkWindow" id="window">
<property name="resizable">1</property>
<property name="title">Clipboard</property>
<accessibility>
<relation name="described-by">label</relation>
</accessibility>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
@@ -13,7 +16,7 @@
<property name="margin-bottom">12</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="label">
<property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the current clipboard contents. You can also drag the data to the bottom.</property>
<property name="wrap">1</property>
<property name="max-width-chars">40</property>
@@ -24,6 +27,9 @@
<property name="spacing">12</property>
<child>
<object class="GtkDropDown" id="source_chooser">
<accessibility>
<property name="label">Source Type</property>
</accessibility>
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
@@ -54,6 +60,9 @@
<property name="name">Text</property>
<property name="child">
<object class="GtkEntry" id="source_text">
<accessibility>
<property name="label">Text Drag Source</property>
</accessibility>
<property name="valign">center</property>
<signal name="notify::text" handler="text_changed_cb" object="copy_button"/>
<property name="text">Copy this!</property>
@@ -66,6 +75,9 @@
<property name="name">Color</property>
<property name="child">
<object class="GtkColorDialogButton" id="source_color">
<accessibility>
<property name="label">Color Drag Source</property>
</accessibility>
<property name="dialog">
<object class="GtkColorDialog">
</object>
@@ -87,14 +99,17 @@
</style>
<child>
<object class="GtkToggleButton" id="image_rose">
<accessibility>
<property name="label">Photo Drag Source</property>
</accessibility>
<property name="active">1</property>
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">Portland Rose Photo</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
@@ -105,6 +120,9 @@
</child>
<child>
<object class="GtkToggleButton" id="image_floppy">
<accessibility>
<property name="label">Icon Drag Source</property>
</accessibility>
<property name="group">image_rose</property>
<child>
<object class="GtkDragSource">
@@ -113,6 +131,9 @@
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">Floppy Buddy Icon</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
@@ -123,6 +144,9 @@
</child>
<child>
<object class="GtkToggleButton" id="image_logo">
<accessibility>
<property name="label">SVG Drag Source</property>
</accessibility>
<property name="group">image_floppy</property>
<child>
<object class="GtkDragSource">
@@ -131,6 +155,9 @@
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">gtk-demo logo</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
@@ -148,6 +175,9 @@
<property name="name">File</property>
<property name="child">
<object class="GtkButton" id="source_file">
<accessibility>
<property name="label">File Drag Source</property>
</accessibility>
<child>
<object class="GtkDragSource">
<property name="propagation-phase">capture</property>
@@ -172,6 +202,9 @@
<property name="name">Folder</property>
<property name="child">
<object class="GtkButton" id="source_folder">
<accessibility>
<property name="label">Folder Drag Source</property>
</accessibility>
<child>
<object class="GtkDragSource">
<property name="propagation-phase">capture</property>
@@ -225,7 +258,7 @@
</object>
</child>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="paste_label">
<property name="xalign">0</property>
<binding name="label">
<lookup name="visible-child-name" type="GtkStack">
@@ -252,6 +285,9 @@
<property name="name">Text</property>
<property name="child">
<object class="GtkLabel">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="xalign">0</property>
@@ -265,6 +301,9 @@
<property name="name">Image</property>
<property name="child">
<object class="GtkImage">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<style>
@@ -283,6 +322,9 @@
<property name="valign">center</property>
<child>
<object class="GtkColorSwatch">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="accessible-role">img</property>
<property name="can-focus">0</property>
<property name="selectable">0</property>
@@ -298,6 +340,9 @@
<property name="name">File</property>
<property name="child">
<object class="GtkLabel">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="xalign">0</property>
+2
View File
@@ -387,6 +387,8 @@ demo3_widget_class_init (Demo3WidgetClass *class)
gtk_widget_class_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
gtk_widget_class_bind_template_child (widget_class, Demo3Widget, menu);
gtk_widget_class_bind_template_callback (widget_class, pressed_cb);
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_IMG);
}
GtkWidget *
+6
View File
@@ -19,8 +19,14 @@
</item>
</menu>
<template class="Demo3Widget">
<accessibility>
<property name="label">Demo image</property>
</accessibility>
<child>
<object class="GtkPopoverMenu" id="menu">
<accessibility>
<property name="label">Context menu</property>
</accessibility>
<property name="has-arrow">0</property>
<property name="menu-model">model</property>
</object>
+19 -7
View File
@@ -162,27 +162,39 @@ click_done (GtkGesture *gesture)
gtk_widget_insert_after (item, canvas, last_child);
}
/* GtkSettings treats `GTK_THEME=foo:dark` as theme name `foo`, variant `dark`,
* and our embedded CSS files let `foo-dark` work as an alias for `foo:dark`. */
static gboolean
has_dark_suffix (const char *theme)
{
return g_str_has_suffix (theme, ":dark") ||
g_str_has_suffix (theme, "-dark");
}
/* So we can make a good guess whether the current theme is dark by checking for
* either: it is suffixed `[:-]dark`, or Settings:…prefer-dark-theme is TRUE. */
static gboolean
theme_is_dark (void)
{
const char *env_theme;
GtkSettings *settings;
char *theme;
gboolean prefer_dark;
gboolean dark;
/* Like GtkSettings, 1st see if theme is overridden by environment variable */
env_theme = g_getenv ("GTK_THEME");
if (env_theme != NULL)
return has_dark_suffix (env_theme);
/* If not, test Settings:…theme-name in the same way OR :…prefer-dark-theme */
settings = gtk_settings_get_default ();
g_object_get (settings,
"gtk-theme-name", &theme,
"gtk-application-prefer-dark-theme", &prefer_dark,
NULL);
if ((strcmp (theme, "Adwaita") == 0 && prefer_dark) || strcmp (theme, "HighContrastInverse") == 0)
dark = TRUE;
else
dark = FALSE;
dark = prefer_dark || has_dark_suffix (theme);
g_free (theme);
return dark;
}
+17 -5
View File
@@ -334,11 +334,17 @@ do_drawingarea (GtkWidget *do_widget)
gtk_widget_set_vexpand (frame, TRUE);
gtk_box_append (GTK_BOX (vbox), frame);
da = gtk_drawing_area_new ();
da = g_object_new (GTK_TYPE_DRAWING_AREA,
"accessible-role", GTK_ACCESSIBLE_ROLE_IMG,
NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
gtk_accessible_update_relation (GTK_ACCESSIBLE (da),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), groups_draw, NULL, NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
/*
* Create the scribble area
@@ -352,11 +358,17 @@ do_drawingarea (GtkWidget *do_widget)
gtk_widget_set_vexpand (frame, TRUE);
gtk_box_append (GTK_BOX (vbox), frame);
da = gtk_drawing_area_new ();
da = g_object_new (GTK_TYPE_DRAWING_AREA,
"accessible-role", GTK_ACCESSIBLE_ROLE_IMG,
NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
gtk_accessible_update_relation (GTK_ACCESSIBLE (da),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), scribble_draw, NULL, NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
g_signal_connect (da, "resize",
G_CALLBACK (scribble_resize), NULL);
@@ -372,7 +384,7 @@ do_drawingarea (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
+7
View File
@@ -95,6 +95,13 @@ do_entry_completion (GtkWidget *do_widget)
entry = gtk_entry_new ();
gtk_box_append (GTK_BOX (vbox), entry);
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE, GTK_ACCESSIBLE_AUTOCOMPLETE_LIST,
-1);
/* Create the completion object */
completion = gtk_entry_completion_new ();
+4
View File
@@ -43,6 +43,10 @@ do_entry_undo (GtkWidget *do_widget)
entry = gtk_entry_new ();
gtk_editable_set_enable_undo (GTK_EDITABLE (entry), TRUE);
gtk_box_append (GTK_BOX (vbox), entry);
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
}
if (!gtk_widget_get_visible (window))
+15
View File
@@ -22,11 +22,15 @@ validate_more_details (GtkEntry *entry,
{
gtk_widget_set_tooltip_text (GTK_WIDGET (entry), "Must have details first");
gtk_widget_add_css_class (GTK_WIDGET (entry), "error");
gtk_accessible_update_state (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_STATE_INVALID, GTK_ACCESSIBLE_INVALID_TRUE,
-1);
}
else
{
gtk_widget_set_tooltip_text (GTK_WIDGET (entry), "");
gtk_widget_remove_css_class (GTK_WIDGET (entry), "error");
gtk_accessible_reset_state (GTK_ACCESSIBLE (entry), GTK_ACCESSIBLE_STATE_INVALID);
}
}
@@ -44,10 +48,18 @@ mode_switch_state_set (GtkSwitch *sw,
{
gtk_widget_set_visible (label, FALSE);
gtk_switch_set_state (sw, state);
gtk_accessible_reset_relation (GTK_ACCESSIBLE (sw), GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE);
gtk_accessible_reset_state (GTK_ACCESSIBLE (sw), GTK_ACCESSIBLE_STATE_INVALID);
}
else
{
gtk_widget_set_visible (label, TRUE);
gtk_accessible_update_relation (GTK_ACCESSIBLE (sw),
GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, label,
-1);
gtk_accessible_update_state (GTK_ACCESSIBLE (sw),
GTK_ACCESSIBLE_STATE_INVALID, GTK_ACCESSIBLE_INVALID_TRUE,
-1);
}
return TRUE;
@@ -73,6 +85,9 @@ level_scale_value_changed (GtkRange *range,
{
gtk_switch_set_state (GTK_SWITCH (sw), FALSE);
}
gtk_accessible_reset_relation (GTK_ACCESSIBLE (sw), GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE);
gtk_accessible_reset_state (GTK_ACCESSIBLE (sw), GTK_ACCESSIBLE_STATE_INVALID);
}
GtkWidget *
+44 -5
View File
@@ -59,6 +59,9 @@
<property name="spacing">6</property>
<child>
<object class="GtkFontDialogButton" id="font">
<accessibility>
<property name="label">Font</property>
</accessibility>
<property name="dialog">
<object class="GtkFontDialog">
</object>
@@ -73,7 +76,7 @@
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="size_label">
<property name="label">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -89,6 +92,9 @@
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">size_adjustment</property>
<accessibility>
<relation name="labelled-by">size_label</relation>
</accessibility>
<layout>
<property name="column">1</property>
<property name="row">0</property>
@@ -101,6 +107,9 @@
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<accessibility>
<relation name="labelled-by">size_label</relation>
</accessibility>
<signal name="activate" handler="basic_entry_activated"
object="size_adjustment" swapped="false"/>
<layout>
@@ -110,7 +119,7 @@
</object>
</child>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="letterspacing_label">
<property name="label">Letterspacing</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -126,6 +135,9 @@
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">letterspacing_adjustment</property>
<accessibility>
<relation name="labelled-by">letterspacing_label</relation>
</accessibility>
<layout>
<property name="column">1</property>
<property name="row">1</property>
@@ -138,6 +150,9 @@
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<accessibility>
<relation name="labelled-by">letterspacing_label</relation>
</accessibility>
<signal name="activate" handler="basic_entry_activated"
object="letterspacing_adjustment" swapped="false"/>
<layout>
@@ -147,7 +162,7 @@
</object>
</child>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="line_height_label">
<property name="label">Line Height</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -163,6 +178,9 @@
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">line_height_adjustment</property>
<accessibility>
<relation name="labelled-by">line_height_label</relation>
</accessibility>
<layout>
<property name="column">1</property>
<property name="row">2</property>
@@ -175,6 +193,9 @@
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<accessibility>
<relation name="labelled-by">line_height_label</relation>
</accessibility>
<signal name="activate" handler="basic_entry_activated"
object="line_height_adjustment" swapped="false"/>
<layout>
@@ -184,7 +205,7 @@
</object>
</child>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="foreground_label">
<property name="label">Foreground</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -202,6 +223,9 @@
</property>
<property name="valign">baseline</property>
<property name="rgba">black</property>
<accessibility>
<relation name="labelled-by">foreground_label</relation>
</accessibility>
<signal name="notify::rgba" handler="color_set_cb"/>
<layout>
<property name="column">1</property>
@@ -210,7 +234,7 @@
</object>
</child>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="background_label">
<property name="label">Background</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -228,6 +252,9 @@
</property>
<property name="valign">baseline</property>
<property name="rgba">white</property>
<accessibility>
<relation name="labelled-by">background_label</relation>
</accessibility>
<signal name="notify::rgba" handler="color_set_cb"/>
<layout>
<property name="column">1</property>
@@ -240,6 +267,9 @@
<property name="icon-name">object-flip-vertical-symbolic</property>
<property name="halign">start</property>
<property name="valign">center</property>
<accessibility>
<property name="label">Swap colors</property>
</accessibility>
<style>
<class name="circular"/>
</style>
@@ -341,6 +371,9 @@
<property name="yalign">0</property>
<property name="valign">start</property>
<property name="selectable">1</property>
<accessibility>
<property name="label">Font example</property>
</accessibility>
</object>
</property>
</object>
@@ -350,6 +383,9 @@
<property name="name">entry</property>
<property name="child">
<object class="GtkTextView" id="entry">
<accessibility>
<property name="label">Example text</property>
</accessibility>
<property name="buffer">
<object class="GtkTextBuffer">
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
@@ -446,6 +482,9 @@
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<accessibility>
<property name="label">Edit text</property>
</accessibility>
<signal name="clicked" handler="font_features_toggle_edit"/>
</object>
</child>
+1 -1
View File
@@ -306,7 +306,7 @@ retry:
texture = gdk_texture_new_for_pixbuf (pixbuf2);
gtk_picture_set_paintable (GTK_PICTURE (image), GDK_PAINTABLE (texture));
g_object_unref (pixbuf2);
g_object_unref (pixbuf2);
g_object_unref (texture);
}
static gboolean fading = FALSE;
+17 -2
View File
@@ -39,7 +39,7 @@
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="text_label">
<property name="margin-start">10</property>
<property name="label">Text</property>
<property name="xalign">1</property>
@@ -57,10 +57,13 @@
<layout>
<property name="column">2</property>
</layout>
<accessibility>
<relation name="labelled-by">text_label</relation>
</accessibility>
</object>
</child>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="font_label">
<property name="margin-start">10</property>
<property name="label">Font</property>
<property name="xalign">1</property>
@@ -75,6 +78,9 @@
</child>
<child>
<object class="GtkFontDialogButton" id="font_button">
<accessibility>
<relation name="labelled-by">font_label</relation>
</accessibility>
<property name="dialog">
<object class="GtkFontDialog">
</object>
@@ -186,6 +192,9 @@
<property name="icon-name">list-add-symbolic</property>
<property name="halign">center</property>
<property name="valign">center</property>
<accessibility>
<property name="label">Zoom in</property>
</accessibility>
<style>
<class name="circular"/>
</style>
@@ -211,6 +220,9 @@
<property name="icon-name">list-remove-symbolic</property>
<property name="halign">center</property>
<property name="valign">center</property>
<accessibility>
<property name="label">Zoom out</property>
</accessibility>
<style>
<class name="circular"/>
</style>
@@ -251,6 +263,9 @@
<property name="vexpand">1</property>
<child>
<object class="GtkPicture" id="image">
<accessibility>
<property name="label">Font rendering example</property>
</accessibility>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="can-shrink">0</property>
+13 -2
View File
@@ -18,6 +18,7 @@ do_headerbar (GtkWidget *do_widget)
GtkWidget *header;
GtkWidget *button;
GtkWidget *box;
GtkWidget *content;
if (!window)
{
@@ -37,16 +38,26 @@ do_headerbar (GtkWidget *do_widget)
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_add_css_class (box, "linked");
button = gtk_button_new_from_icon_name ("go-previous-symbolic");
gtk_widget_set_tooltip_text (button, "Back");
gtk_box_append (GTK_BOX (box), button);
button = gtk_button_new_from_icon_name ("go-next-symbolic");
gtk_widget_set_tooltip_text (button, "Forward");
gtk_box_append (GTK_BOX (box), button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), box);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), gtk_switch_new ());
button = gtk_switch_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Change something",
-1);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_child (GTK_WINDOW (window), gtk_text_view_new ());
content = gtk_text_view_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (content),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Content",
-1);
gtk_window_set_child (GTK_WINDOW (window), content);
}
if (!gtk_widget_get_visible (window))
+6
View File
@@ -164,12 +164,18 @@ do_image_scaling (GtkWidget *do_widget)
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
gtk_widget_set_tooltip_text (scale, "Zoom");
gtk_accessible_update_property (GTK_ACCESSIBLE (scale),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Zoom",
-1);
gtk_range_set_value (GTK_RANGE (scale), 0.);
gtk_widget_set_hexpand (scale, TRUE);
gtk_box_append (GTK_BOX (box2), scale);
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
gtk_widget_set_tooltip_text (dropdown, "Filter");
gtk_accessible_update_property (GTK_ACCESSIBLE (dropdown),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Filter",
-1);
gtk_box_append (GTK_BOX (box2), dropdown);
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
+11 -4
View File
@@ -49,6 +49,7 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">switch</property>
</object>
</child>
<child>
@@ -73,6 +74,7 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">check</property>
</object>
</child>
<child>
@@ -110,6 +112,7 @@
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="opacity">0</property>
<property name="accessible-role">status</property>
</object>
</child>
</object>
@@ -150,10 +153,11 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">scale</property>
</object>
</child>
<child>
<object class="GtkScale">
<object class="GtkScale" id="scale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">0</property>
@@ -185,10 +189,11 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">spin</property>
</object>
</child>
<child>
<object class="GtkSpinButton">
<object class="GtkSpinButton" id="spin">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="adjustment">
@@ -217,10 +222,11 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">dropdown</property>
</object>
</child>
<child>
<object class="GtkDropDown">
<object class="GtkDropDown" id="dropdown">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="model">
@@ -252,10 +258,11 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">entry</property>
</object>
</child>
<child>
<object class="GtkEntry">
<object class="GtkEntry" id="entry">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="placeholder-text">Type here…</property>
+5
View File
@@ -52,6 +52,10 @@ setup_listitem_cb (GtkListItemFactory *factory,
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
image = gtk_image_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_PROPERTY_LABEL,
"App icon",
-1);
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_box_append (GTK_BOX (box), image);
label = gtk_label_new ("");
@@ -79,6 +83,7 @@ bind_listitem_cb (GtkListItemFactory *factory,
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
gtk_label_set_label (GTK_LABEL (label), g_app_info_get_display_name (app_info));
gtk_list_item_set_accessible_label (list_item, g_app_info_get_display_name (app_info));
}
/* In more complex code, we would also need functions to unbind and teardown
+6
View File
@@ -431,6 +431,9 @@ setup_listitem_cb (GtkListItemFactory *factory,
picture = gtk_picture_new ();
gtk_expression_bind (expression, picture, "paintable", picture);
gtk_box_append (GTK_BOX (box), picture);
gtk_accessible_update_relation (GTK_ACCESSIBLE (picture),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, location_label, NULL,
-1);
/* And finally, everything comes together.
@@ -487,6 +490,9 @@ do_listview_clocks (GtkWidget *do_widget)
model = GTK_SELECTION_MODEL (gtk_no_selection_new (create_clocks_model ()));
gridview = gtk_grid_view_new (model, factory);
gtk_accessible_update_property (GTK_ACCESSIBLE (gridview),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Clocks",
-1);
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
+55 -6
View File
@@ -368,6 +368,38 @@ match_func (MatchObject *obj,
g_free (tmp2);
}
static void
setup_header (GtkSignalListItemFactory *factory,
GObject *list_item,
gpointer data)
{
GtkListHeader *self = GTK_LIST_HEADER (list_item);
GtkWidget *child;
child = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (child), 0);
gtk_label_set_use_markup (GTK_LABEL (child), TRUE);
gtk_widget_set_margin_top (child, 10);
gtk_widget_set_margin_bottom (child, 10);
gtk_list_header_set_child (self, child);
}
static void
bind_header (GtkSignalListItemFactory *factory,
GObject *list_item,
gpointer data)
{
GtkListHeader *self = GTK_LIST_HEADER (list_item);
GtkWidget *child = gtk_list_header_get_child (self);
GObject *item = gtk_list_header_get_item (self);
if (strstr (gtk_string_object_get_string (GTK_STRING_OBJECT (item)), "hour"))
gtk_label_set_label (GTK_LABEL (child), "<big><b>Hours</b></big>");
else
gtk_label_set_label (GTK_LABEL (child), "<big><b>Minutes</b></big>");
}
GtkWidget *
do_listview_selections (GtkWidget *do_widget)
{
@@ -377,10 +409,12 @@ do_listview_selections (GtkWidget *do_widget)
GtkExpression *expression;
GtkListItemFactory *factory;
const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
const char * const many_times[] = {
const char * const minutes[] = {
"1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
"25 minutes", "30 minutes", "35 minutes", "40 minutes", "45 minutes", "50 minutes",
"55 minutes", "1 hour", "2 hours", "3 hours", "5 hours", "6 hours", "7 hours",
"55 minutes", NULL
};
const char * const hours[] = { "1 hour", "2 hours", "3 hours", "5 hours", "6 hours", "7 hours",
"8 hours", "9 hours", "10 hours", "11 hours", "12 hours", NULL
};
const char * const device_titles[] = { "Digital Output", "Headphones", "Digital Output", "Analog Output", NULL };
@@ -395,6 +429,10 @@ do_listview_selections (GtkWidget *do_widget)
if (!window)
{
GtkStringList *minutes_model, *hours_model;
GListStore *store;
GtkFlattenListModel *flat;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
@@ -422,14 +460,25 @@ do_listview_selections (GtkWidget *do_widget)
gtk_box_append (GTK_BOX (box), button);
/* A dropdown using an expression to obtain strings */
button = drop_down_new_from_strings (many_times, NULL, NULL);
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
minutes_model = gtk_string_list_new (minutes);
hours_model = gtk_string_list_new (hours);
store = g_list_store_new (G_TYPE_LIST_MODEL);
g_list_store_append (store, minutes_model);
g_list_store_append (store, hours_model);
g_object_unref (minutes_model);
g_object_unref (hours_model);
flat = gtk_flatten_list_model_new (G_LIST_MODEL (store));
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
0, NULL,
(GCallback)get_title,
NULL, NULL);
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
gtk_expression_unref (expression);
button = gtk_drop_down_new (G_LIST_MODEL (flat), expression);
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_header), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_header), NULL);
gtk_drop_down_set_header_factory (GTK_DROP_DOWN (button), factory);
g_object_unref (factory);
gtk_box_append (GTK_BOX (box), button);
button = gtk_drop_down_new (NULL, NULL);
+2
View File
@@ -10,6 +10,8 @@
<property name="child">
<object class="GtkInscription">
<property name="hexpand">1</property>
<property name="nat-chars">25</property>
<property name="text-overflow">ellipsize-end</property>
<binding name="text">
<lookup name="title" type="GtkDemo">
<lookup name="item">expander</lookup>
+38 -24
View File
@@ -18,7 +18,6 @@
#include <string.h>
#include "config.h"
#include <gtk/gtk.h>
#include <glib/gstdio.h>
@@ -268,9 +267,9 @@ activate_run (GSimpleAction *action,
}
static GtkWidget *
display_image (const char *format,
const char *resource,
char **label)
display_image (const char *format,
const char *resource,
GtkWidget *label)
{
GtkWidget *sw, *image;
@@ -280,13 +279,17 @@ display_image (const char *format,
sw = gtk_scrolled_window_new ();
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), image);
gtk_accessible_update_relation (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
return sw;
}
static GtkWidget *
display_images (const char *format,
const char *resource_dir,
char **label)
display_images (const char *format,
const char *resource_dir,
GtkWidget *label)
{
char **resources;
GtkWidget *grid;
@@ -311,13 +314,15 @@ display_images (const char *format,
{
char *resource_name;
GtkWidget *box;
GtkWidget *image_label;
resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);
widget = display_image (NULL, resource_name, NULL);
image_label = gtk_label_new (resources[i]);
widget = display_image (NULL, resource_name, image_label);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_append (GTK_BOX (box), widget);
gtk_box_append (GTK_BOX (box), gtk_label_new (resources[i]));
gtk_box_append (GTK_BOX (box), image_label);
gtk_flow_box_insert (GTK_FLOW_BOX (grid), box, -1);
g_free (resource_name);
@@ -325,15 +330,19 @@ display_images (const char *format,
g_strfreev (resources);
*label = g_strdup ("Images");
gtk_label_set_label (GTK_LABEL (label), "Images");
gtk_accessible_update_relation (GTK_ACCESSIBLE (grid),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
return sw;
}
static GtkWidget *
display_text (const char *format,
const char *resource,
char **label)
display_text (const char *format,
const char *resource,
GtkWidget *label)
{
GtkTextBuffer *buffer;
GtkWidget *textview, *sw;
@@ -368,6 +377,10 @@ display_text (const char *format,
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
gtk_accessible_update_relation (GTK_ACCESSIBLE (textview),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
sw = gtk_scrolled_window_new ();
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
@@ -378,15 +391,19 @@ display_text (const char *format,
}
static GtkWidget *
display_video (const char *format,
const char *resource,
char **label)
display_video (const char *format,
const char *resource,
GtkWidget *label)
{
GtkWidget *video;
video = gtk_video_new_for_resource (resource);
gtk_video_set_loop (GTK_VIDEO (video), TRUE);
gtk_accessible_update_relation (GTK_ACCESSIBLE (video),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
return video;
}
@@ -408,9 +425,9 @@ display_nothing (const char *resource)
static struct {
const char *extension;
const char *format;
GtkWidget * (* display_func) (const char *format,
const char *resource,
char **label);
GtkWidget * (* display_func) (const char *format,
const char *resource,
GtkWidget *label);
} display_funcs[] = {
{ ".gif", NULL, display_image },
{ ".jpg", NULL, display_image },
@@ -433,7 +450,6 @@ add_data_tab (const char *demoname)
char **resources;
GtkWidget *widget, *label;
guint i, j;
char *label_string;
resource_dir = g_strconcat ("/", demoname, NULL);
resources = g_resources_enumerate_children (resource_dir, 0, NULL);
@@ -453,23 +469,21 @@ add_data_tab (const char *demoname)
break;
}
label_string = NULL;
label = gtk_label_new (resources[i]);
if (j < G_N_ELEMENTS (display_funcs))
widget = display_funcs[j].display_func (display_funcs[j].format,
resource_name,
&label_string);
label);
else
widget = display_nothing (resource_name);
label = gtk_label_new (label_string ? label_string : resources[i]);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
g_object_set (gtk_notebook_get_page (GTK_NOTEBOOK (notebook), widget),
"tab-expand", FALSE,
NULL);
g_free (resource_name);
g_free (label_string);
}
g_strfreev (resources);
+6 -3
View File
@@ -57,14 +57,17 @@
<object class="GtkBox">
<child>
<object class="GtkBox">
<property name="width-request">220</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar" id="searchbar">
<accessibility>
<relation name="labelled-by">search-entry</relation>
</accessibility>
<property name="key-capture-widget">window</property>
<child>
<object class="GtkSearchEntry" id="search-entry">
<accessibility>
<property name="label" translatable="yes">Search</property>
<relation name="controls">listview</relation>
</accessibility>
</object>
@@ -76,15 +79,15 @@
<style>
<class name="sidebar"/>
</style>
<property name="width-request">120</property>
<property name="hscrollbar-policy">never</property>
<property name="min-content-width">150</property>
<property name="propagate-natural-width">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkListView" id="listview">
<style>
<class name="navigation-sidebar"/>
</style>
<property name="tab-behavior">item</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/ui/main-listitem.ui</property>
+1 -11
View File
@@ -158,17 +158,7 @@ demos_h = custom_target('gtk4 demo header',
command: [ find_program('geninclude.py'), '@OUTPUT@', '@INPUT@' ],
)
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
if can_use_objcopy_for_resources
# Create the resource blob
gtkdemo_gresource = custom_target('gtkdemo.gresource',
input : 'demo.gresource.xml',
+6
View File
@@ -68,6 +68,9 @@ do_password_entry (GtkWidget *do_widget)
"placeholder-text", "Password",
"activates-default", TRUE,
NULL);
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Password",
-1);
g_signal_connect (entry, "notify::text", G_CALLBACK (update_button), NULL);
gtk_box_append (GTK_BOX (box), entry);
@@ -77,6 +80,9 @@ do_password_entry (GtkWidget *do_widget)
"placeholder-text", "Confirm",
"activates-default", TRUE,
NULL);
gtk_accessible_update_property (GTK_ACCESSIBLE (entry2),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Confirm",
-1);
g_signal_connect (entry2, "notify::text", G_CALLBACK (update_button), NULL);
gtk_box_append (GTK_BOX (box), entry2);
+9 -1
View File
@@ -189,6 +189,7 @@ do_pickers (GtkWidget *do_widget)
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
picker = gtk_color_dialog_button_new (gtk_color_dialog_new ());
gtk_label_set_mnemonic_widget (GTK_LABEL (label), picker);
gtk_grid_attach (GTK_GRID (table), picker, 1, 0, 1, 1);
label = gtk_label_new ("Font:");
@@ -198,6 +199,7 @@ do_pickers (GtkWidget *do_widget)
gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
picker = gtk_font_dialog_button_new (gtk_font_dialog_new ());
gtk_label_set_mnemonic_widget (GTK_LABEL (label), picker);
gtk_grid_attach (GTK_GRID (table), picker, 1, 1, 1, 1);
label = gtk_label_new ("File:");
@@ -208,6 +210,9 @@ do_pickers (GtkWidget *do_widget)
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
button = gtk_button_new_from_icon_name ("document-open-symbolic");
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Select File",
-1);
label = gtk_label_new ("None");
@@ -223,6 +228,9 @@ do_pickers (GtkWidget *do_widget)
gtk_box_append (GTK_BOX (picker), button);
app_picker = gtk_button_new_from_icon_name ("emblem-system-symbolic");
gtk_widget_set_halign (app_picker, GTK_ALIGN_END);
gtk_accessible_update_property (GTK_ACCESSIBLE (app_picker),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Open File",
-1);
gtk_widget_set_sensitive (app_picker, FALSE);
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
gtk_box_append (GTK_BOX (picker), app_picker);
@@ -241,7 +249,7 @@ do_pickers (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
+16
View File
@@ -150,20 +150,36 @@ do_video_player (GtkWidget *do_widget)
button = gtk_button_new ();
image = gtk_image_new_from_resource ("/cursors/images/gtk_logo_cursor.png");
gtk_accessible_update_relation (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, button, NULL,
-1);
gtk_image_set_pixel_size (GTK_IMAGE (image), 24);
gtk_button_set_child (GTK_BUTTON (button), image);
g_signal_connect (button, "clicked", G_CALLBACK (logo_clicked_cb), video);
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "GTK Logo",
-1);
gtk_header_bar_pack_start (GTK_HEADER_BAR (title), button);
button = gtk_button_new ();
image = gtk_image_new_from_resource ("/video-player/bbb.png");
gtk_accessible_update_relation (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, button, NULL,
-1);
gtk_image_set_pixel_size (GTK_IMAGE (image), 24);
gtk_button_set_child (GTK_BUTTON (button), image);
g_signal_connect (button, "clicked", G_CALLBACK (bbb_clicked_cb), video);
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Big Buck Bunny",
-1);
gtk_header_bar_pack_start (GTK_HEADER_BAR (title), button);
fullscreen_button = gtk_button_new_from_icon_name ("view-fullscreen-symbolic");
g_signal_connect (fullscreen_button, "clicked", G_CALLBACK (fullscreen_clicked_cb), NULL);
gtk_accessible_update_property (GTK_ACCESSIBLE (fullscreen_button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Fullscreen",
-1);
gtk_header_bar_pack_end (GTK_HEADER_BAR (title), fullscreen_button);
controller = gtk_shortcut_controller_new ();
+1 -11
View File
@@ -1,16 +1,6 @@
# demos/widget-factory
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
if can_use_objcopy_for_resources
# Create the resource blob
widgetfactory_gresource = custom_target('widgetfactory.gresource',
input : 'widget-factory.gresource.xml',
+31
View File
@@ -153,6 +153,35 @@ get_busy (GSimpleAction *action,
gtk_widget_set_sensitive (window, FALSE);
}
static void
search_button_tooltip_show (GtkWidget *self,
GtkTooltip *tooltip)
{
static int style = 0;
if (style == 0)
{
gtk_tooltip_set_css_class (tooltip, "red-tooltip");
style++;
}
else if (style == 1)
{
gtk_tooltip_set_css_class (tooltip, "yellow-tooltip");
style++;
}
else
{
style = 0;
}
}
static void
search_button_tooltip_hide (GtkWidget *self,
GtkTooltip *tooltip)
{
gtk_tooltip_set_css_class (tooltip, NULL);
}
static int current_page = 0;
static gboolean
on_page (int i)
@@ -2221,6 +2250,8 @@ activate (GApplication *app)
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
gtk_builder_cscope_add_callback (scope, transition_speed_changed);
gtk_builder_cscope_add_callback (scope, reset_icon_size);
gtk_builder_cscope_add_callback (scope, search_button_tooltip_show);
gtk_builder_cscope_add_callback (scope, search_button_tooltip_hide);
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
if (!gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", &error))
+9
View File
@@ -6,3 +6,12 @@
.toolbar {
-gtk-icon-style: symbolic;
}
.red-tooltip {
background-color: red;
}
.yellow-tooltip {
background-color: yellow;
color: black;
}
+11 -1
View File
@@ -257,7 +257,9 @@
</object>
<object class="GtkTextBuffer" id="textbuffer1">
<property name="tag-table">tags</property>
<property name="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<property name="text">Search button above will display its tooltip in an alternating red, yellow and default style.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nullam fringilla, est ut feugiat ultrices, elit lacus ultricies nibh, id commodo tortor nisi id elit.
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
Morbi vel elit erat. Maecenas dignissim, dui et pharetra rutrum, tellus lectus rutrum mi, a convallis libero nisi quis tellus.
@@ -1572,6 +1574,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="valign">3</property>
<child>
<object class="GtkVolumeButton">
<accessibility>
<property name="label" translatable="1">Volume</property>
</accessibility>
<property name="orientation">1</property>
<property name="valign">3</property>
<property name="value">.5</property>
@@ -1584,6 +1589,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</child>
<child>
<object class="GtkScaleButton" id="mic-button">
<accessibility>
<property name="label" translatable="1">Microphone gain</property>
</accessibility>
<property name="has-tooltip">1</property>
<property name="icons">microphone-sensitivity-muted-symbolic
microphone-sensitivity-high-symbolic
@@ -1915,6 +1923,8 @@ microphone-sensitivity-medium-symbolic</property>
<property name="icon-name">edit-find</property>
<property name="action-name">win.search</property>
<property name="tooltip-text" translatable="1">Search for it</property>
<signal name="tooltip-show" handler="search_button_tooltip_show"/>
<signal name="tooltip-hide" handler="search_button_tooltip_hide"/>
</object>
</child>
<child>
+6 -6
View File
@@ -23,7 +23,7 @@ When it comes to rendering, GTK follows the CSS box model as far as practical.
The CSS stylesheet that is in use determines the sizes (and appearance) of the
margin, border and padding areas for each widget. The size of the content area
is determined by GTKs layout algorithm using each widgets [vfunc@Gtk.Widget.measure]
is determined by GTKs layout algorithm using each widgets [vfunc@Gtk.Widget.measure]
and [vfunc@Gtk.Widget.size_allocate] vfuncs.
You can learn more about the CSS box model by reading the
@@ -37,11 +37,11 @@ To learn more about where GTK CSS differs from CSS on the web, see the
The content area in the CSS box model is the region that the widget considers its own.
The origin of the widgets coordinate system is the top left corner of the content area,
and its size is the widgets size. The size can be queried with [method@Gtk.Widget.get_width]
The origin of the widgets coordinate system is the top left corner of the content area,
and its size is the widgets size. The size can be queried with [method@Gtk.Widget.get_width]
and [method@Gtk.Widget.get_height]. GTK allows general 3D transformations to position
widgets (although most of the time, the transformation will be a simple 2D translation).
The transform to go from one widgets coordinate system to another one can be obtained
The transform to go from one widgets coordinate system to another one can be obtained
with [method@Gtk.Widget.compute_transform].
In addition to a size, widgets can optionally have a **_baseline_** to position text on.
@@ -55,8 +55,8 @@ or [method@Gtk.Widget.compute_bounds]. These methods can fail (either because th
don't share a common ancestor, or because of a singular transformation), and callers need
to handle this eventuality.
Another area that is occasionally relevant are the widgets **_bounds_**, which is the area
that a widgets rendering is typically confined to (technically, widgets can draw outside
Another area that is occasionally relevant are the widgets **_bounds_**, which is the area
that a widgets rendering is typically confined to (technically, widgets can draw outside
of this area, unless clipping is enforced via the [property@Gtk.Widget:overflow] property).
In CSS terms, the bounds of a widget correspond to the border area.
+10 -5
View File
@@ -16,6 +16,7 @@ SYNOPSIS
| **gtk4-builder-tool** enumerate [OPTIONS...] <FILE>
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
| **gtk4-builder-tool** render [OPTIONS...] <FILE>
| **gtk4-builder-tool** screenshot [OPTIONS...] <FILE>
DESCRIPTION
@@ -69,12 +70,11 @@ file to use.
Load style information from the given CSS file.
Screenshot
^^^^^^^^^^
Render
^^^^^^
The ``screenshot`` command saves a rendering of the UI definition file
as a png image or node file. The name of the file to write can be specified as
a second FILE argument.
The ``render`` command saves a rendering of the UI definition file as a png image
or node file. The name of the file to write can be specified as a second FILE argument.
This command accepts options to specify the ID of the toplevel object and a CSS
file to use.
@@ -96,6 +96,11 @@ file to use.
Overwrite an existing file.
Screenshot
^^^^^^^^^^
The ``screenshot`` command is an alias for ``render``.
Simplification
^^^^^^^^^^^^^^
+6
View File
@@ -208,6 +208,12 @@ A number of options affect behavior instead of logging:
`nograbs`
: Turn off all pointer and keyboard grabs
`portals`
: Force the use of [portals](https://docs.flatpak.org/en/latest/portals.html)
`no-portals`
: Disable use of [portals](https://docs.flatpak.org/en/latest/portals.html)
`gl-disable`
: Disable OpenGL support
+31 -13
View File
@@ -31,7 +31,7 @@ described by a set of *attributes*.
Roles define the taxonomy and semantics of a UI control to any assistive
technology application; for instance, a button will have a role of
`GTK_ACCESSIBLE_ROLE_BUTTON`; an entry will have a role of
`GTK_ACCESSIBLE_ROLE_TEXTBOX`; a toggle button will have a role of
`GTK_ACCESSIBLE_ROLE_TEXTBOX`; a check button will have a role of
`GTK_ACCESSIBLE_ROLE_CHECKBOX`; etc.
Each role is part of the widget's instance, and **cannot** be changed over
@@ -46,6 +46,7 @@ Each role name is part of the #GtkAccessibleRole enumeration.
| Role name | Description | Related GTK widget |
|-----------|-------------|--------------------|
| `APPLICATION` | An application window | [class@Gtk.Window] |
| `BUTTON` | A control that performs an action when pressed | [class@Gtk.Button], [class@Gtk.LinkButton], [class@Gtk.Expander] |
| `CHECKBOX` | A control that has three possible value: `true`, `false`, or `undefined` | [class@Gtk.CheckButton] |
| `COMBOBOX` | A control that can be expanded to show a list of possible values to select | [class@Gtk.ComboBox] |
@@ -78,7 +79,6 @@ Each role name is part of the #GtkAccessibleRole enumeration.
| `TAB_PANEL` | A page in a notebook or stack | [class@Gtk.Stack] |
| `TEXT_BOX` | A type of input that allows free-form text as its value. | [class@Gtk.Entry], [class@Gtk.PasswordEntry], [class@Gtk.TextView] |
| `TREE_GRID` | A treeview-like columned list | [class@Gtk.ColumnView] |
| `WINDOW` | An application window | [class@Gtk.Window] |
| `...` | … |
See the [WAI-ARIA](https://www.w3.org/WAI/PF/aria/appendices#quickref) list
@@ -204,19 +204,27 @@ you should ensure that:
readable and localised action performed when pressed; for instance "Copy",
"Paste", "Add layer", or "Remove"
GTK will try to fill in some information by using ancillary UI control
properties, for instance the accessible label will be taken from the label or
placeholder text used by the UI control, or from its tooltip, if the
`GTK_ACCESSIBLE_PROPERTY_LABEL` property or the `GTK_ACCESSIBLE_RELATION_LABELLED_BY`
relation are unset. Nevertheless, it is good practice and project hygiene
to explicitly specify the accessible properties, just like it's good practice
to specify tooltips and style classes.
GTK will try to fill in some information by using ancillary UI control properties,
for instance the accessible name will be taken from the label used by the UI control,
or from its tooltip, if the `GTK_ACCESSIBLE_PROPERTY_LABEL` property or the
`GTK_ACCESSIBLE_RELATION_LABELLED_BY` relation are unset. Similary for the accessible
description. Nevertheless, it is good practice and project hygiene to explicitly specify
the accessible properties, just like it's good practice to specify tooltips and style classes.
Application developers using GTK **should** ensure that their UI controls
are accessible as part of the development process. When using `GtkBuilder`
templates and UI definition files, GTK provides a validation tool that
verifies that each UI element has a valid role and properties; this tool can
be used as part of the application's test suite to avoid regressions.
are accessible as part of the development process. The GTK Inspector shows
the accessible attributes of each widget, and also provides an overlay that
can highlight accessibility issues.
It is possible to set accessible attributes in UI files as well:
```xml
<object class="GtkButton" id="button1">
<accessibility>
<property name="label">Download</property>
<relation name="labelled-by">label1</relation>
/accessibility>
</object>
```
## Implementations
@@ -259,6 +267,13 @@ turn automatically any widget into a `GtkButton`; but if your widget behaves
like a button, using the %GTK_ACCESSIBLE_ROLE_BUTTON will allow any
assistive technology to handle it like they would a `GtkButton`.
For widgets that act as containers of other widgets, you should use
%GTK_ACCESSIBLE_ROLE_GROUP if the grouping of the children is semantic
in nature; for instance, the children of a [class@Gtk.HeaderBar] are
grouped together on the header of a window. For generic containers that
only impose a layout on their children, you should use
%GTK_ACCESSIBLE_ROLE_GENERIC instead.
### Attributes can both hide and enhance
Accessible attributes can be used to override the content of a UI element,
@@ -367,3 +382,6 @@ To allow changing the value via accessible technologies, you can export
actions. Since the accessibility interfaces only support actions
without parameters, you should provide actions such as `increase-value`
and `decrease-value`.
Since GTK 4.10, the best way to suppose changing the value is by implementing
the [iface@Gtk.AccessibleRange] interface.
+10 -6
View File
@@ -30,12 +30,12 @@ Views display data from a **_model_**. Models implement the [`iface@Gio.ListMode
interface and can be provided in a variety of ways:
* List model implementations for many specific types of data already exist, for
example `GtkDirectoryList` or `GtkStringList`.
example [`class@Gtk.DirectoryList`] or [`class@Gtk.StringList`].
* There are generic list model implementations like`GListStore` that allow building
* There are generic list model implementations like [`class@Gio.ListStore`] that allow building
lists of arbitrary objects.
* Wrapping list models like `GtkFilterListModel` or `GtkSortListModel`
* Wrapping list models like [`class@Gtk.FilterListModel`] or [`class@Gtk.SortListModel`]
modify, adapt or combine other models.
* Last but not least, developers are encouraged to create their own `GListModel`
@@ -133,8 +133,8 @@ tradeoffs of those and experiment with them.
GTK offers a wide variety of wrapping models which change or supplement an
existing model (or models) in some way. But when it comes to storing your
actual data, there are only a few ready-made choices available: [`class@Gio.ListStore`]
and [`class@Gtk.StringList`].
actual data, there are only a few ready-made choices available:
[`class@Gio.ListStore`], [`class@Gtk.StringList`], and [`class@Gtk.DirectoryList`].
`GListStore` is backed by a balanced tree and has performance characteristics
that are expected for that data structure. It works reasonably well for dataset
@@ -147,6 +147,10 @@ that are expected for that data structure. `GtkStringList` is a good fit for any
place where you would otherwise use `char*[]` and works best if the dataset
is not very dynamic.
`GtkDirectoryList` is a list model that wraps [`method@Gio.File.enumerate_children_async`].
It presents a `GListModel` and fills it asynchronously with the [`iface@Gio.File`]s
returned from that function.
If these models don't fit your use case or scalability requirements, you
should make a custom `GListModel` implementation. It is a small interface and
not very hard to implement.
@@ -199,7 +203,7 @@ the `.data-table` style class.
## Sections
List models can optionally group their items into **_sections_**, by implementing
the `GtkSectionModel` interface. Both `GtkListView` and `GtkGridView` can
the `GtkSectionModel` interface. `GtkListView` can
display headers for sections, by installing a separate **_header factory_**.
Many GTK list models support section inherently, or they pass through the
+1 -1
View File
@@ -34,7 +34,7 @@ gdk_broadway_cairo_context_dispose (GObject *object)
static void
gdk_broadway_cairo_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkBroadwayCairoContext *self = GDK_BROADWAY_CAIRO_CONTEXT (draw_context);
+1 -1
View File
@@ -34,7 +34,7 @@ gdk_broadway_draw_context_dispose (GObject *object)
static void
gdk_broadway_draw_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkBroadwayDrawContext *self = GDK_BROADWAY_DRAW_CONTEXT (draw_context);
+3
View File
@@ -645,6 +645,9 @@ gdk_content_formats_builder_clear (GdkContentFormatsBuilder *builder)
{
g_clear_pointer (&builder->gtypes, g_slist_free);
g_clear_pointer (&builder->mime_types, g_slist_free);
builder->n_gtypes = 0;
builder->n_mime_types = 0;
}
/**
+47
View File
@@ -36,6 +36,7 @@
#include "gdkglcontextprivate.h"
#include "gdkmonitorprivate.h"
#include "gdkrectangle.h"
#include "gdkvulkancontext.h"
#ifdef HAVE_EGL
#include <epoxy/egl.h>
@@ -383,6 +384,9 @@ gdk_display_dispose (GObject *object)
#endif
g_clear_error (&priv->gl_error);
for (GList *l = display->seats; l; l = l->next)
g_object_run_dispose (G_OBJECT (l->data));
G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
}
@@ -1213,6 +1217,49 @@ gdk_display_get_keymap (GdkDisplay *display)
return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
}
/*<private>
* gdk_display_create_vulkan_context:
* @self: a `GdkDisplay`
* @error: return location for an error
*
* Creates a new `GdkVulkanContext` for use with @display.
*
* The context can not be used to draw to surfaces, it can only be
* used for custom rendering or compute.
*
* If the creation of the `GdkVulkanContext` failed, @error will be set.
*
* Returns: (transfer full): the newly created `GdkVulkanContext`, or
* %NULL on error
*/
GdkVulkanContext *
gdk_display_create_vulkan_context (GdkDisplay *self,
GError **error)
{
g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (gdk_display_get_debug_flags (self) & GDK_DEBUG_VULKAN_DISABLE)
{
g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
_("Vulkan support disabled via GDK_DEBUG"));
return NULL;
}
if (GDK_DISPLAY_GET_CLASS (self)->vk_extension_name == NULL)
{
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
"The %s backend has no Vulkan support.", G_OBJECT_TYPE_NAME (self));
return FALSE;
}
return g_initable_new (GDK_DISPLAY_GET_CLASS (self)->vk_context_type,
NULL,
error,
"display", self,
NULL);
}
static void
gdk_display_init_gl (GdkDisplay *self)
{
+7
View File
@@ -100,6 +100,10 @@ struct _GdkDisplay
VkDevice vk_device;
VkQueue vk_queue;
uint32_t vk_queue_family_index;
VkPipelineCache vk_pipeline_cache;
gsize vk_pipeline_cache_size;
char *vk_pipeline_cache_etag;
guint vk_save_pipeline_cache_source;
guint vulkan_refcount;
#endif /* GDK_RENDERING_VULKAN */
@@ -202,6 +206,9 @@ gulong _gdk_display_get_next_serial (GdkDisplay *display
void _gdk_display_pause_events (GdkDisplay *display);
void _gdk_display_unpause_events (GdkDisplay *display);
GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
GError **error);
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
gboolean gdk_display_init_egl (GdkDisplay *display,
+11 -10
View File
@@ -311,19 +311,20 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
g_return_if_fail (priv->surface != NULL);
g_return_if_fail (region != NULL);
gdk_draw_context_begin_frame_full (context, FALSE, region);
gdk_draw_context_begin_frame_full (context, GDK_MEMORY_U8, region);
}
/*
* @prefers_high_depth: %TRUE to request a higher bit depth
* @depth: best depth to render in
*
* If high depth is preferred, GDK will see about providing a rendering target
* that supports higher bit depth than 8 bits per channel. Typically this means
* a target supporting 16bit floating point pixels, but that is not guaranteed.
* If the given depth is not `GDK_MEMORY_U8`, GDK will see about providing a
* rendering target that supports a higher bit depth than 8 bits per channel.
* Typically this means a target supporting 16bit floating point pixels, but
* that is not guaranteed.
*
* This is only a request and if the GDK backend does not support HDR rendering
* or does not consider it worthwhile, it may choose to not honor the request.
* It may also choose to provide high depth even if it was not requested.
* It may also choose to provide a differnet depth even if it was not requested.
* Typically the steps undertaken by a backend are:
* 1. Check if high depth is supported by this drawing backend.
* 2. Check if the compositor supports high depth.
@@ -333,12 +334,12 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
* In either of those cases, the context will usually choose to not honor the request.
*
* The rendering code must be able to deal with content in any bit depth, no matter
* the preference. The prefers_high_depth argument is only a hint and GDK is free
* the preference. The depth argument is only a hint and GDK is free
* to choose.
*/
void
gdk_draw_context_begin_frame_full (GdkDrawContext *context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
const cairo_region_t *region)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
@@ -365,12 +366,12 @@ gdk_draw_context_begin_frame_full (GdkDrawContext *context,
}
if (gdk_display_get_debug_flags (priv->display) & GDK_DEBUG_HIGH_DEPTH)
prefers_high_depth = TRUE;
depth = GDK_MEMORY_FLOAT32;
priv->frame_region = cairo_region_copy (region);
priv->surface->paint_context = g_object_ref (context);
GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context, prefers_high_depth, priv->frame_region);
GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context, depth, priv->frame_region);
cairo_region_intersect_rectangle (priv->frame_region,
&(cairo_rectangle_int_t) {
+4 -2
View File
@@ -22,6 +22,8 @@
#include "gdkdrawcontext.h"
#include "gdkmemoryformatprivate.h"
G_BEGIN_DECLS
#define GDK_DRAW_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAW_CONTEXT, GdkDrawContextClass))
@@ -40,7 +42,7 @@ struct _GdkDrawContextClass
GObjectClass parent_class;
void (* begin_frame) (GdkDrawContext *context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *update_area);
void (* end_frame) (GdkDrawContext *context,
cairo_region_t *painted);
@@ -50,7 +52,7 @@ struct _GdkDrawContextClass
void gdk_draw_context_surface_resized (GdkDrawContext *context);
void gdk_draw_context_begin_frame_full (GdkDrawContext *context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
const cairo_region_t *region);
G_END_DECLS
+24
View File
@@ -30,6 +30,8 @@
#include <glib.h>
#include <gdk/version/gdkversionmacros.h>
G_BEGIN_DECLS
/**
@@ -306,6 +308,20 @@ typedef enum
* the alpha value. Since: 4.6
* @GDK_MEMORY_R32G32B32A32_FLOAT: 4 float values; for red, green, blue and
* alpha. Since: 4.6
* @GDK_MEMORY_G8A8_PREMULTIPLIED: 2 bytes; for grayscale, alpha. The color
* values are premultiplied with the alpha value. Since: 4.12
* @GDK_MEMORY_G8A8: 2 bytes; for grayscale, alpha. Since: 4.12
* @GDK_MEMORY_G8: One byte; for grayscale. The data is opaque.
* Since: 4.12
* @GDK_MEMORY_G16A16_PREMULTIPLIED: 2 guint16 values; for grayscale, alpha.
* The color values are premultiplied with the alpha value. Since: 4.12
* @GDK_MEMORY_G16A16: 2 guint16 values; for grayscale, alpha. Since: 4.12
* @GDK_MEMORY_G16: One guint16 value; for grayscale. The data is opaque.
* Since: 4.12
* @GDK_MEMORY_A8: One byte; for alpha.
* Since: 4.12
* @GDK_MEMORY_A16: One guint16 value; for alpha.
* Since: 4.12
* @GDK_MEMORY_N_FORMATS: The number of formats. This value will change as
* more formats get added, so do not rely on its concrete integer.
*
@@ -340,6 +356,14 @@ typedef enum {
GDK_MEMORY_R32G32B32_FLOAT,
GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
GDK_MEMORY_R32G32B32A32_FLOAT,
GDK_MEMORY_G8A8_PREMULTIPLIED GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_G8A8 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_G8 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_G16A16_PREMULTIPLIED GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_G16A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_G16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A8 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_N_FORMATS
} GdkMemoryFormat;
+5 -9
View File
@@ -173,12 +173,8 @@ static GPrivate thread_current_context = G_PRIVATE_INIT (unref_unmasked);
static void
gdk_gl_context_clear_old_updated_area (GdkGLContext *context)
{
int i;
for (i = 0; i < 2; i++)
{
g_clear_pointer (&context->old_updated_area[i], cairo_region_destroy);
}
for (unsigned int i = 0; i < GDK_GL_MAX_TRACKED_BUFFERS; i++)
g_clear_pointer (&context->old_updated_area[i], cairo_region_destroy);
}
static void
@@ -585,7 +581,7 @@ gdk_gl_context_get_scale (GdkGLContext *self)
static void
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
@@ -601,7 +597,7 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
#ifdef HAVE_EGL
if (priv->egl_context)
gdk_surface_ensure_egl_surface (surface, prefers_high_depth);
gdk_surface_ensure_egl_surface (surface, depth != GDK_MEMORY_U8);
#endif
damage = GDK_GL_CONTEXT_GET_CLASS (context)->get_damage (context);
@@ -1556,7 +1552,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_sync = gdk_gl_context_check_version (context, "3.2", "3.0") ||
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GK_APPLE_sync");
epoxy_has_gl_extension ("GL_APPLE_sync");
#ifdef G_ENABLE_DEBUG
{
+139 -23
View File
@@ -138,6 +138,7 @@ static gboolean
gdk_gl_texture_find_format (gboolean use_es,
guint gl_major,
guint gl_minor,
GdkMemoryAlpha alpha,
GLint gl_format,
GLint gl_type,
GdkMemoryFormat *out_format)
@@ -147,8 +148,12 @@ gdk_gl_texture_find_format (gboolean use_es,
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
{
GLenum q_internal_format, q_format, q_type;
GLint q_swizzle[4];
if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type))
if (gdk_memory_format_alpha (format) != alpha)
continue;
if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type, &q_swizzle))
continue;
if (q_format != gl_format || q_type != gl_type)
@@ -167,31 +172,57 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
gpointer download_)
{
GdkTexture *texture = GDK_TEXTURE (self);
GdkMemoryFormat format;
gsize expected_stride;
Download *download = download_;
GLenum gl_internal_format, gl_format, gl_type;
GLint gl_swizzle[4];
int major, minor;
unsigned int internal_texture_format, dummy;
format = gdk_texture_get_format (texture),
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
gdk_gl_context_get_version (context, &major, &minor);
gdk_memory_format_gl_format (gdk_texture_get_format (texture),
FALSE,
major, minor,
&internal_texture_format,
&dummy, &dummy);
if (download->stride == expected_stride &&
!gdk_gl_context_get_use_es (context) &&
gdk_memory_format_gl_format (download->format, FALSE, major, minor, &gl_internal_format, &gl_format, &gl_type) &&
gl_internal_format == internal_texture_format)
if (!gdk_gl_context_get_use_es (context) &&
gdk_memory_format_gl_format (format,
FALSE,
major, minor,
&gl_internal_format,
&gl_format, &gl_type, &gl_swizzle))
{
glGetTexImage (GL_TEXTURE_2D,
0,
gl_format,
gl_type,
download->data);
if (download->stride == expected_stride &&
download->format == format)
{
glGetTexImage (GL_TEXTURE_2D,
0,
gl_format,
gl_type,
download->data);
}
else
{
gsize stride = texture->width * gdk_memory_format_bytes_per_pixel (format);
guchar *pixels = g_malloc_n (stride, texture->height);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glGetTexImage (GL_TEXTURE_2D,
0,
gl_format,
gl_type,
pixels);
gdk_memory_convert (download->data,
download->stride,
download->format,
pixels,
stride,
format,
texture->width,
texture->height);
g_free (pixels);
}
}
else
{
@@ -204,17 +235,26 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
if (gdk_gl_context_check_version (context, "4.3", "3.1"))
{
gdk_gl_context_get_version (context, &major, &minor);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), major, minor, gl_read_format, gl_read_type, &actual_format))
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
if (!gdk_gl_texture_find_format (TRUE, major, minor, gdk_memory_format_alpha (format), gl_read_format, gl_read_type, &actual_format))
{
gl_read_format = GL_RGBA;
gl_read_type = GL_UNSIGNED_BYTE;
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_PREMULTIPLIED)
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
else
actual_format = GDK_MEMORY_R8G8B8A8;
}
}
else
{
gl_read_format = GL_RGBA;
gl_read_type = GL_UNSIGNED_BYTE;
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_PREMULTIPLIED)
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
else
actual_format = GDK_MEMORY_R8G8B8A8;
}
if (download->format == actual_format &&
@@ -229,19 +269,95 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
else
{
gsize actual_bpp = gdk_memory_format_bytes_per_pixel (actual_format);
guchar *pixels = g_malloc_n (texture->width * actual_bpp, texture->height);
gsize stride = actual_bpp * texture->width;
guchar *pixels = g_malloc_n (stride, texture->height);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glReadPixels (0, 0,
texture->width, texture->height,
gl_read_format,
gl_read_type,
pixels);
/* Fix up gles inadequacies */
if (gl_read_format == GL_RGBA &&
gl_read_type == GL_UNSIGNED_BYTE &&
(format == GDK_MEMORY_G8A8 ||
format == GDK_MEMORY_G8A8_PREMULTIPLIED ||
format == GDK_MEMORY_G8 ||
format == GDK_MEMORY_A8))
{
for (unsigned int y = 0; y < texture->height; y++)
{
for (unsigned int x = 0; x < texture->width; x++)
{
guchar *data = &pixels[y * stride + x * actual_bpp];
if (format == GDK_MEMORY_G8A8 ||
format == GDK_MEMORY_G8A8_PREMULTIPLIED)
{
data[3] = data[1];
data[1] = data[0];
data[2] = data[0];
}
else if (format == GDK_MEMORY_G8)
{
data[1] = data[0];
data[2] = data[0];
data[3] = 0xff;
}
else if (format == GDK_MEMORY_A8)
{
data[3] = data[0];
data[0] = 0;
data[1] = 0;
data[2] = 0;
}
}
}
}
if (gl_read_format == GL_RGBA &&
gl_read_type == GL_UNSIGNED_SHORT &&
(format == GDK_MEMORY_G16A16 ||
format == GDK_MEMORY_G16A16_PREMULTIPLIED ||
format == GDK_MEMORY_G16 ||
format == GDK_MEMORY_A16))
{
for (unsigned int y = 0; y < texture->height; y++)
{
for (unsigned int x = 0; x < texture->width; x++)
{
guint16 *data = (guint16 *) &pixels[y * stride + x * actual_bpp];
if (format == GDK_MEMORY_G16A16 ||
format == GDK_MEMORY_G16A16_PREMULTIPLIED)
{
data[3] = data[1];
data[1] = data[0];
data[2] = data[0];
}
else if (format == GDK_MEMORY_G16)
{
data[1] = data[0];
data[2] = data[0];
data[3] = 0xffff;
}
else if (format == GDK_MEMORY_A16)
{
data[3] = data[0];
data[0] = 0;
data[1] = 0;
data[2] = 0;
}
}
}
}
gdk_memory_convert (download->data,
download->stride,
download->format,
pixels,
texture->width * actual_bpp,
stride,
actual_format,
texture->width,
texture->height);
+8
View File
@@ -644,10 +644,18 @@ gdk_gl_texture_builder_get_format (GdkGLTextureBuilder *self)
* The format is the preferred format the texture data should be downloaded to. The
* format must be supported by the GL version of [property@Gdk.GLTextureBuilder:context].
*
* GDK's texture download code assumes that the format corresponds to the storage
* parameters of the GL texture in an obvious way. For example, a format of
* `GDK_MEMORY_R16G16B16A16_PREMULTIPLIED` is expected to be stored as `GL_RGBA16`
* texture, and `GDK_MEMORY_G8A8` is expected to be stored as `GL_RG8` texture.
*
* Setting the right format is particularly useful when using high bit depth textures
* to preserve the bit depth, to set the correct value for unpremultiplied textures
* and to make sure opaque textures are treated as such.
*
* Non-RGBA textures need to have swizzling parameters set up properly to be usable
* in GSK's shaders.
*
* Since: 4.12
*/
void
+205 -57
View File
@@ -60,6 +60,36 @@ name ## _from_float (guchar *dest_data, \
} \
}
#define TYPED_GRAY_FUNCS(name, T, G, A, bpp, scale) \
static void \
name ## _to_float (float *dest, \
const guchar *src_data, \
gsize n) \
{ \
for (gsize i = 0; i < n; i++) \
{ \
T *src = (T *) (src_data + i * bpp); \
if (G >= 0) dest[0] = (float) src[G] / scale; else dest[0] = 1.0; \
dest[1] = dest[2] = dest[0]; \
if (A >= 0) dest[3] = (float) src[A] / scale; else dest[3] = 1.0; \
dest += 4; \
} \
} \
\
static void \
name ## _from_float (guchar *dest_data, \
const float *src, \
gsize n) \
{ \
for (gsize i = 0; i < n; i++) \
{ \
T *dest = (T *) (dest_data + i * bpp); \
if (G >= 0) dest[G] = CLAMP ((src[0] + src[1] + src[2]) * scale / 3.f + 0.5, 0, scale); \
if (A >= 0) dest[A] = CLAMP (src[3] * scale + 0.5, 0, scale); \
src += 4; \
} \
}
TYPED_FUNCS (b8g8r8a8_premultiplied, guchar, 2, 1, 0, 3, 4, 255)
TYPED_FUNCS (a8r8g8b8_premultiplied, guchar, 1, 2, 3, 0, 4, 255)
TYPED_FUNCS (r8g8b8a8_premultiplied, guchar, 0, 1, 2, 3, 4, 255)
@@ -72,6 +102,15 @@ TYPED_FUNCS (b8g8r8, guchar, 2, 1, 0, -1, 3, 255)
TYPED_FUNCS (r16g16b16, guint16, 0, 1, 2, -1, 6, 65535)
TYPED_FUNCS (r16g16b16a16, guint16, 0, 1, 2, 3, 8, 65535)
TYPED_GRAY_FUNCS (g8a8_premultiplied, guchar, 0, 1, 2, 255)
TYPED_GRAY_FUNCS (g8a8, guchar, 0, 1, 2, 255)
TYPED_GRAY_FUNCS (g8, guchar, 0, -1, 1, 255)
TYPED_GRAY_FUNCS (a8, guchar, -1, 0, 1, 255)
TYPED_GRAY_FUNCS (g16a16_premultiplied, guint16, 0, 1, 4, 65535)
TYPED_GRAY_FUNCS (g16a16, guint16, 0, 1, 4, 65535)
TYPED_GRAY_FUNCS (g16, guint16, 0, -1, 2, 65535)
TYPED_GRAY_FUNCS (a16, guint16, -1, 0, 2, 65535)
static void
r16g16b16_float_to_float (float *dest,
const guchar *src_data,
@@ -219,7 +258,7 @@ struct _GdkMemoryFormatDescription
GdkMemoryAlpha alpha;
gsize bytes_per_pixel;
gsize alignment;
gboolean prefers_high_depth;
GdkMemoryDepth depth;
struct {
guint gl_major;
guint gl_minor;
@@ -230,6 +269,7 @@ struct _GdkMemoryFormatDescription
guint internal_format;
guint format;
guint type;
GLint swizzle[4];
} gl;
/* no premultiplication going on here */
void (* to_float) (float *, const guchar*, gsize);
@@ -249,9 +289,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
4,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
b8g8r8a8_premultiplied_to_float,
b8g8r8a8_premultiplied_from_float,
},
@@ -259,9 +299,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
4,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
a8r8g8b8_premultiplied_to_float,
a8r8g8b8_premultiplied_from_float,
},
@@ -269,9 +309,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
4,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, 0, 0 },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r8g8b8a8_premultiplied_to_float,
r8g8b8a8_premultiplied_from_float,
},
@@ -279,9 +319,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
b8g8r8a8_to_float,
b8g8r8a8_from_float,
},
@@ -289,9 +329,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
{ GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
a8r8g8b8_to_float,
a8r8g8b8_from_float,
},
@@ -299,9 +339,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, 0, 0 },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r8g8b8a8_to_float,
r8g8b8a8_from_float,
},
@@ -309,9 +349,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
a8b8g8r8_to_float,
a8b8g8r8_from_float,
},
@@ -319,9 +359,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_OPAQUE,
3,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, 0, 0 },
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE },
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
r8g8b8_to_float,
r8g8b8_from_float,
},
@@ -329,9 +369,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_OPAQUE,
3,
G_ALIGNOF (guchar),
FALSE,
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE },
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
b8g8r8_to_float,
b8g8r8_from_float,
},
@@ -339,9 +379,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_OPAQUE,
6,
G_ALIGNOF (guint16),
TRUE,
GDK_MEMORY_U16,
{ 0, 0, 3, 0 },
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT },
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
r16g16b16_to_float,
r16g16b16_from_float,
},
@@ -349,9 +389,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
8,
G_ALIGNOF (guint16),
TRUE,
GDK_MEMORY_U16,
{ 0, 0, 3, 0 },
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r16g16b16a16_to_float,
r16g16b16a16_from_float,
},
@@ -359,9 +399,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_STRAIGHT,
8,
G_ALIGNOF (guint16),
TRUE,
GDK_MEMORY_U16,
{ 0, 0, 3, 0 },
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r16g16b16a16_to_float,
r16g16b16a16_from_float,
},
@@ -369,9 +409,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_OPAQUE,
6,
G_ALIGNOF (guint16),
TRUE,
GDK_MEMORY_FLOAT16,
{ 0, 0, 3, 0 },
{ GL_RGB16F, GL_RGB, GL_HALF_FLOAT },
{ GL_RGB16F, GL_RGB, GL_HALF_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
r16g16b16_float_to_float,
r16g16b16_float_from_float,
},
@@ -379,9 +419,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
8,
G_ALIGNOF (guint16),
TRUE,
GDK_MEMORY_FLOAT16,
{ 0, 0, 3, 0 },
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r16g16b16a16_float_to_float,
r16g16b16a16_float_from_float,
},
@@ -389,9 +429,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_STRAIGHT,
8,
G_ALIGNOF (guint16),
TRUE,
GDK_MEMORY_FLOAT16,
{ 0, 0, 3, 0 },
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r16g16b16a16_float_to_float,
r16g16b16a16_float_from_float,
},
@@ -399,9 +439,9 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_OPAQUE,
12,
G_ALIGNOF (float),
TRUE,
GDK_MEMORY_FLOAT32,
{ 0, 0, 3, 0 },
{ GL_RGB32F, GL_RGB, GL_FLOAT },
{ GL_RGB32F, GL_RGB, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
r32g32b32_float_to_float,
r32g32b32_float_from_float,
},
@@ -411,7 +451,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
G_ALIGNOF (float),
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
{ GL_RGBA32F, GL_RGBA, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r32g32b32a32_float_to_float,
r32g32b32a32_float_from_float,
},
@@ -419,11 +459,91 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
GDK_MEMORY_ALPHA_STRAIGHT,
16,
G_ALIGNOF (float),
TRUE,
GDK_MEMORY_FLOAT32,
{ 0, 0, 3, 0 },
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
{ GL_RGBA32F, GL_RGBA, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r32g32b32a32_float_to_float,
r32g32b32a32_float_from_float,
},
[GDK_MEMORY_G8A8_PREMULTIPLIED] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
2,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, 3, 0 },
{ GL_RG8, GL_RG, GL_UNSIGNED_BYTE, { GL_RED, GL_RED, GL_RED, GL_GREEN } },
g8a8_premultiplied_to_float,
g8a8_premultiplied_from_float,
},
[GDK_MEMORY_G8A8] = {
GDK_MEMORY_ALPHA_STRAIGHT,
2,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, 3, 0 },
{ GL_RG8, GL_RG, GL_UNSIGNED_BYTE, { GL_RED, GL_RED, GL_RED, GL_GREEN } },
g8a8_to_float,
g8a8_from_float,
},
[GDK_MEMORY_G8] = {
GDK_MEMORY_ALPHA_OPAQUE,
1,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, 3, 0 },
{ GL_R8, GL_RED, GL_UNSIGNED_BYTE, { GL_RED, GL_RED, GL_RED, GL_ONE } },
g8_to_float,
g8_from_float,
},
[GDK_MEMORY_G16A16_PREMULTIPLIED] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
4,
G_ALIGNOF (guint16),
GDK_MEMORY_U16,
{ 0, 0, 3, 0 },
{ GL_RG16, GL_RG, GL_UNSIGNED_SHORT, { GL_RED, GL_RED, GL_RED, GL_GREEN } },
g16a16_premultiplied_to_float,
g16a16_premultiplied_from_float,
},
[GDK_MEMORY_G16A16] = {
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guint16),
GDK_MEMORY_U16,
{ 0, 0, 3, 0 },
{ GL_RG16, GL_RG, GL_UNSIGNED_SHORT, { GL_RED, GL_RED, GL_RED, GL_GREEN } },
g16a16_to_float,
g16a16_from_float,
},
[GDK_MEMORY_G16] = {
GDK_MEMORY_ALPHA_OPAQUE,
2,
G_ALIGNOF (guint16),
GDK_MEMORY_U16,
{ 0, 0, 3, 0 },
{ GL_R16, GL_RED, GL_UNSIGNED_SHORT, { GL_RED, GL_RED, GL_RED, GL_ONE } },
g16_to_float,
g16_from_float,
},
[GDK_MEMORY_A8] = {
GDK_MEMORY_ALPHA_STRAIGHT,
1,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, 3, 0 },
{ GL_R8, GL_RED, GL_UNSIGNED_BYTE, { GL_ONE, GL_ONE, GL_ONE, GL_RED } },
a8_to_float,
a8_from_float,
},
[GDK_MEMORY_A16] = {
GDK_MEMORY_ALPHA_STRAIGHT,
2,
G_ALIGNOF (guint16),
GDK_MEMORY_U16,
{ 0, 0, 3, 0 },
{ GL_R16, GL_RED, GL_UNSIGNED_SHORT, { GL_ONE, GL_ONE, GL_ONE, GL_RED } },
a16_to_float,
a16_from_float,
}
};
@@ -446,23 +566,57 @@ gdk_memory_format_alignment (GdkMemoryFormat format)
}
/*<private>
* gdk_memory_format_prefers_high_depth:
* gdk_memory_format_get_depth:
* @format: a memory format
*
* Checks if the given format benefits from being rendered
* in bit depths higher than 8bits per pixel. See
* gsk_render_node_prefers_high_depth() for more information
* on this.
* Usually this is the case when
* gdk_memory_format_bytes_per_pixel() is larger than 4.
* Gets the depth of the individual channels of the format.
* See gsk_render_node_prefers_high_depth() for more
* information on this.
*
* Returns: %TRUE if the format benefits from being
* composited in hgiher bit depths.
* Usually renderers want to use higher depth for render
* targets to match these formats.
*
* Returns: The depth of this format
**/
gboolean
gdk_memory_format_prefers_high_depth (GdkMemoryFormat format)
GdkMemoryDepth
gdk_memory_format_get_depth (GdkMemoryFormat format)
{
return memory_formats[format].prefers_high_depth;
return memory_formats[format].depth;
}
/*<private>
* gdk_memory_depth_merge:
* @depth1: the first depth
* @depth2: the second depth
*
* Returns a depth that can accomodate both given depths
* without any loss of precision.
*
* Returns: The merged depth
**/
GdkMemoryDepth
gdk_memory_depth_merge (GdkMemoryDepth depth1,
GdkMemoryDepth depth2)
{
switch (depth1)
{
case GDK_MEMORY_U8:
return depth2;
case GDK_MEMORY_FLOAT32:
return GDK_MEMORY_FLOAT32;
case GDK_MEMORY_U16:
case GDK_MEMORY_FLOAT16:
if (depth2 == depth1 || depth2 == GDK_MEMORY_U8)
return depth1;
else
return GDK_MEMORY_FLOAT32;
default:
g_assert_not_reached ();
return GDK_MEMORY_U8;
}
}
gboolean
@@ -472,14 +626,13 @@ gdk_memory_format_gl_format (GdkMemoryFormat format,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type)
guint *out_type,
GLint (*out_swizzle)[4])
{
*out_internal_format = memory_formats[format].gl.internal_format;
*out_format = memory_formats[format].gl.format;
*out_type = memory_formats[format].gl.type;
if (memory_formats[format].alpha == GDK_MEMORY_ALPHA_STRAIGHT)
return FALSE;
memcpy (out_swizzle, &memory_formats[format].gl.swizzle, sizeof(GLint) * 4);
if (gles)
{
@@ -600,11 +753,6 @@ gdk_memory_convert (guchar *dest_data,
for (y = 0; y < height; y++)
{
src_desc->to_float (tmp, src_data, width);
/* Note: Converting from a premultiplied format to an opaque format is defined
* to yield the same result as compositing over black, which works out to
* using the premultiplied values, and just dropping alpha.
*/
if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT)
unpremultiply (tmp, width);
else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
+14 -2
View File
@@ -21,6 +21,8 @@
#include "gdkenums.h"
#include <epoxy/gl.h>
G_BEGIN_DECLS
typedef enum {
@@ -29,17 +31,27 @@ typedef enum {
GDK_MEMORY_ALPHA_OPAQUE
} GdkMemoryAlpha;
typedef enum {
GDK_MEMORY_U8,
GDK_MEMORY_U16,
GDK_MEMORY_FLOAT16,
GDK_MEMORY_FLOAT32
} GdkMemoryDepth;
gsize gdk_memory_format_alignment (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryAlpha gdk_memory_format_alpha (GdkMemoryFormat format) G_GNUC_CONST;
gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format) G_GNUC_CONST;
gboolean gdk_memory_format_prefers_high_depth(GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryDepth gdk_memory_format_get_depth (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth depth1,
GdkMemoryDepth depth2) G_GNUC_CONST;
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type);
guint *out_type,
GLint (*out_gizzle)[4]);
void gdk_memory_convert (guchar *dest_data,
gsize dest_stride,
+1 -1
View File
@@ -55,7 +55,7 @@ typedef enum {
GDK_SEAT_CAPABILITY_KEYBOARD = 1 << 3,
GDK_SEAT_CAPABILITY_TABLET_PAD = 1 << 4,
GDK_SEAT_CAPABILITY_ALL_POINTING = (GDK_SEAT_CAPABILITY_POINTER | GDK_SEAT_CAPABILITY_TOUCH | GDK_SEAT_CAPABILITY_TABLET_STYLUS),
GDK_SEAT_CAPABILITY_ALL = (GDK_SEAT_CAPABILITY_ALL_POINTING | GDK_SEAT_CAPABILITY_KEYBOARD)
GDK_SEAT_CAPABILITY_ALL = (GDK_SEAT_CAPABILITY_ALL_POINTING | GDK_SEAT_CAPABILITY_KEYBOARD | GDK_SEAT_CAPABILITY_TABLET_PAD)
} GdkSeatCapabilities;
struct _GdkSeat
+2 -1
View File
@@ -25,7 +25,8 @@
* multiple frames, and will be used for a long time.
*
* There are various ways to create `GdkTexture` objects from a
* [class@GdkPixbuf.Pixbuf], or a Cairo surface, or other pixel data.
* [class@GdkPixbuf.Pixbuf], or from bytes stored in memory, a file, or a
* [struct@Gio.Resource].
*
* The ownership of the pixel data is transferred to the `GdkTexture`
* instance; you can only make a copy of it, via [method@Gdk.Texture.download].
+361 -25
View File
@@ -47,7 +47,12 @@ typedef struct _GdkVulkanContextPrivate GdkVulkanContextPrivate;
struct _GdkVulkanContextPrivate {
#ifdef GDK_RENDERING_VULKAN
VkSurfaceKHR surface;
VkSurfaceFormatKHR image_format;
struct {
VkSurfaceFormatKHR vk_format;
GdkMemoryFormat gdk_format;
} formats[4];
GdkMemoryDepth current_format;
GdkMemoryFormat offscreen_formats[4];
VkSwapchainKHR swapchain;
VkSemaphore draw_semaphore;
@@ -429,8 +434,8 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
.minImageCount = CLAMP (4,
capabilities.minImageCount,
capabilities.maxImageCount ? capabilities.maxImageCount : G_MAXUINT32),
.imageFormat = priv->image_format.format,
.imageColorSpace = priv->image_format.colorSpace,
.imageFormat = priv->formats[priv->current_format].vk_format.format,
.imageColorSpace = priv->formats[priv->current_format].vk_format.colorSpace,
.imageExtent = capabilities.currentExtent,
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
@@ -499,19 +504,20 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
}
static gboolean
device_supports_incremental_present (VkPhysicalDevice device)
physical_device_supports_extension (VkPhysicalDevice device,
const char *extension_name)
{
VkExtensionProperties *extensions;
uint32_t n_device_extensions;
vkEnumerateDeviceExtensionProperties (device, NULL, &n_device_extensions, NULL);
GDK_VK_CHECK (vkEnumerateDeviceExtensionProperties, device, NULL, &n_device_extensions, NULL);
extensions = g_newa (VkExtensionProperties, n_device_extensions);
vkEnumerateDeviceExtensionProperties (device, NULL, &n_device_extensions, extensions);
GDK_VK_CHECK (vkEnumerateDeviceExtensionProperties, device, NULL, &n_device_extensions, extensions);
for (uint32_t i = 0; i < n_device_extensions; i++)
{
if (g_str_equal (extensions[i].extensionName, VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME))
if (g_str_equal (extensions[i].extensionName, extension_name))
return TRUE;
}
@@ -520,13 +526,27 @@ device_supports_incremental_present (VkPhysicalDevice device)
static void
gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
guint i;
if (depth != priv->current_format)
{
if (priv->formats[depth].gdk_format != priv->formats[priv->current_format].gdk_format)
{
GError *error = NULL;
if (!gdk_vulkan_context_check_swapchain (context, &error))
{
g_warning ("%s", error->message);
g_error_free (error);
return;
}
}
priv->current_format = depth;
}
for (i = 0; i < priv->n_images; i++)
{
cairo_region_union (priv->regions[i], region);
@@ -665,6 +685,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (initable);
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
VkResult res;
VkBool32 supported;
uint32_t i;
@@ -673,6 +694,22 @@ gdk_vulkan_context_real_init (GInitable *initable,
if (!priv->vulkan_ref)
return FALSE;
priv->offscreen_formats[GDK_MEMORY_U8] = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_U16] = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_FLOAT16] = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_FLOAT32] = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (surface == NULL)
{
for (i = 0; i < G_N_ELEMENTS (priv->formats); i++)
{
priv->formats[i].vk_format.format = VK_FORMAT_B8G8R8A8_UNORM;
priv->formats[i].vk_format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
priv->formats[i].gdk_format = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
}
return TRUE;
}
res = GDK_VULKAN_CONTEXT_GET_CLASS (context)->create_surface (context, &priv->surface);
if (res != VK_SUCCESS)
{
@@ -707,17 +744,74 @@ gdk_vulkan_context_real_init (GInitable *initable,
&n_formats, formats);
for (i = 0; i < n_formats; i++)
{
if (formats[i].format == VK_FORMAT_B8G8R8A8_UNORM)
break;
if (formats[i].colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
continue;
switch ((int) formats[i].format)
{
case VK_FORMAT_B8G8R8A8_UNORM:
if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED)
{
priv->formats[GDK_MEMORY_U8].vk_format = formats[i];
priv->formats[GDK_MEMORY_U8].gdk_format = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_U8] = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
};
break;
case VK_FORMAT_R8G8B8A8_UNORM:
if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED)
{
priv->formats[GDK_MEMORY_U8].vk_format = formats[i];
priv->formats[GDK_MEMORY_U8].gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
break;
case VK_FORMAT_R16G16B16A16_UNORM:
priv->formats[GDK_MEMORY_U16].vk_format = formats[i];
priv->formats[GDK_MEMORY_U16].gdk_format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
break;
case VK_FORMAT_R16G16B16A16_SFLOAT:
priv->formats[GDK_MEMORY_FLOAT16].vk_format = formats[i];
priv->formats[GDK_MEMORY_FLOAT16].gdk_format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
break;
case VK_FORMAT_R32G32B32A32_SFLOAT:
priv->formats[GDK_MEMORY_FLOAT32].vk_format = formats[i];
priv->formats[GDK_MEMORY_FLOAT32].gdk_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
break;
default:
break;
}
}
if (i == n_formats)
if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED)
{
g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
"No supported image format found.");
goto out_surface;
}
priv->image_format = formats[i];
priv->has_present_region = device_supports_incremental_present (display->vk_physical_device);
/* Ensure all the formats exist:
* - If a format was found, keep that one.
* - FLOAT32 chooses the best format we have.
* - FLOAT16 and U16 pick the format FLOAT32 uses
*/
if (priv->formats[GDK_MEMORY_FLOAT32].vk_format.format == VK_FORMAT_UNDEFINED)
{
if (priv->formats[GDK_MEMORY_FLOAT16].vk_format.format != VK_FORMAT_UNDEFINED)
priv->formats[GDK_MEMORY_FLOAT32] = priv->formats[GDK_MEMORY_FLOAT16];
else if (priv->formats[GDK_MEMORY_U16].vk_format.format != VK_FORMAT_UNDEFINED)
priv->formats[GDK_MEMORY_FLOAT32] = priv->formats[GDK_MEMORY_U16];
else
priv->formats[GDK_MEMORY_FLOAT32] = priv->formats[GDK_MEMORY_U8];
}
if (priv->formats[GDK_MEMORY_FLOAT16].vk_format.format == VK_FORMAT_UNDEFINED)
priv->formats[GDK_MEMORY_FLOAT16] = priv->formats[GDK_MEMORY_FLOAT32];
if (priv->formats[GDK_MEMORY_U16].vk_format.format == VK_FORMAT_UNDEFINED)
priv->formats[GDK_MEMORY_U16] = priv->formats[GDK_MEMORY_FLOAT32];
priv->has_present_region = physical_device_supports_extension (display->vk_physical_device,
VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
if (!gdk_vulkan_context_check_swapchain (context, error))
goto out_surface;
@@ -740,6 +834,15 @@ out_surface:
return FALSE;
}
GdkMemoryFormat
gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth)
{
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
return priv->offscreen_formats[depth];
}
static void
gdk_vulkan_context_initable_init (GInitableIface *iface)
{
@@ -828,6 +931,216 @@ gdk_vulkan_context_get_queue_family_index (GdkVulkanContext *context)
return gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context))->vk_queue_family_index;
}
static char *
gdk_vulkan_get_pipeline_cache_dirname (void)
{
return g_build_filename (g_get_user_cache_dir (), "gtk-4.0", "vulkan-pipeline-cache", NULL);
}
static GFile *
gdk_vulkan_get_pipeline_cache_file (GdkDisplay *display)
{
VkPhysicalDeviceProperties props;
char *dirname, *basename, *path;
GFile *result;
vkGetPhysicalDeviceProperties (display->vk_physical_device, &props);
dirname = gdk_vulkan_get_pipeline_cache_dirname ();
basename = g_strdup_printf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x"
"-%02x%02x%02x%02x%02x%02x.%u",
props.pipelineCacheUUID[0], props.pipelineCacheUUID[1],
props.pipelineCacheUUID[2], props.pipelineCacheUUID[3],
props.pipelineCacheUUID[4], props.pipelineCacheUUID[5],
props.pipelineCacheUUID[6], props.pipelineCacheUUID[7],
props.pipelineCacheUUID[8], props.pipelineCacheUUID[9],
props.pipelineCacheUUID[10], props.pipelineCacheUUID[11],
props.pipelineCacheUUID[12], props.pipelineCacheUUID[13],
props.pipelineCacheUUID[14], props.pipelineCacheUUID[15],
props.driverVersion);
path = g_build_filename (dirname, basename, NULL);
result = g_file_new_for_path (path);
g_free (path);
g_free (basename);
g_free (dirname);
return result;
}
static VkPipelineCache
gdk_display_load_pipeline_cache (GdkDisplay *display)
{
GError *error = NULL;
VkPipelineCache result;
GFile *cache_file;
char *etag, *data;
gsize size;
cache_file = gdk_vulkan_get_pipeline_cache_file (display);
if (!g_file_load_contents (cache_file, NULL, &data, &size, &etag, &error))
{
GDK_DEBUG (VULKAN, "failed to load Vulkan pipeline cache file '%s': %s\n",
g_file_peek_path (cache_file), error->message);
g_object_unref (cache_file);
g_clear_error (&error);
return VK_NULL_HANDLE;
}
if (GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
&(VkPipelineCacheCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
.initialDataSize = size,
.pInitialData = data,
},
NULL,
&result) != VK_SUCCESS)
result = VK_NULL_HANDLE;
g_free (data);
g_free (display->vk_pipeline_cache_etag);
display->vk_pipeline_cache_etag = etag;
display->vk_pipeline_cache_size = size;
return result;
}
static gboolean
gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
{
GError *error = NULL;
VkDevice device;
VkPipelineCache cache;
GFile *file;
char *path;
size_t size;
char *data, *etag;
device = display->vk_device;
cache = display->vk_pipeline_cache;
GDK_VK_CHECK (vkGetPipelineCacheData, device, cache, &size, NULL);
if (size == 0)
return TRUE;
if (size == display->vk_pipeline_cache_size)
{
GDK_DEBUG (VULKAN, "pipeline cache size (%zu bytes) unchanged, skipping save", size);
return TRUE;
}
data = g_malloc (size);
if (GDK_VK_CHECK (vkGetPipelineCacheData, device, cache, &size, data) != VK_SUCCESS)
{
g_free (data);
return FALSE;
}
path = gdk_vulkan_get_pipeline_cache_dirname ();
if (g_mkdir_with_parents (path, 0755) != 0)
{
g_warning_once ("Failed to create pipeline cache directory");
g_free (path);
return FALSE;
}
g_free (path);
file = gdk_vulkan_get_pipeline_cache_file (display);
GDK_DEBUG (VULKAN, "Saving pipeline cache to %s", g_file_peek_path (file));
if (!g_file_replace_contents (file,
data,
size,
display->vk_pipeline_cache_etag,
FALSE,
0,
&etag,
NULL,
&error))
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WRONG_ETAG))
{
VkPipelineCache new_cache;
GDK_DEBUG (VULKAN, "Pipeline cache file modified, merging into current");
new_cache = gdk_display_load_pipeline_cache (display);
if (new_cache)
{
GDK_VK_CHECK (vkMergePipelineCaches, device, cache, 1, &new_cache);
vkDestroyPipelineCache (device, new_cache, NULL);
}
else
{
g_clear_pointer (&display->vk_pipeline_cache_etag, g_free);
}
g_clear_error (&error);
g_object_unref (file);
/* try again */
return gdk_vulkan_save_pipeline_cache (display);
}
g_warning ("Failed to save pipeline cache: %s", error->message);
g_clear_error (&error);
g_object_unref (file);
return FALSE;
}
g_object_unref (file);
g_free (display->vk_pipeline_cache_etag);
display->vk_pipeline_cache_etag = etag;
return TRUE;
}
static gboolean
gdk_vulkan_save_pipeline_cache_cb (gpointer data)
{
GdkDisplay *display = data;
gdk_vulkan_save_pipeline_cache (display);
display->vk_save_pipeline_cache_source = 0;
return G_SOURCE_REMOVE;
}
void
gdk_vulkan_context_pipeline_cache_updated (GdkVulkanContext *self)
{
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self));
g_clear_handle_id (&display->vk_save_pipeline_cache_source, g_source_remove);
display->vk_save_pipeline_cache_source = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE - 10,
10, /* random choice that is not now */
gdk_vulkan_save_pipeline_cache_cb,
display,
NULL);
}
static void
gdk_display_create_pipeline_cache (GdkDisplay *display)
{
display->vk_pipeline_cache = gdk_display_load_pipeline_cache (display);
GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
&(VkPipelineCacheCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
},
NULL,
&display->vk_pipeline_cache);
}
VkPipelineCache
gdk_vulkan_context_get_pipeline_cache (GdkVulkanContext *self)
{
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (self), NULL);
return gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self))->vk_pipeline_cache;
}
/**
* gdk_vulkan_context_get_image_format:
* @context: a `GdkVulkanContext`
@@ -843,7 +1156,7 @@ gdk_vulkan_context_get_image_format (GdkVulkanContext *context)
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), VK_FORMAT_UNDEFINED);
return priv->image_format.format;
return priv->formats[priv->current_format].vk_format.format;
}
/**
@@ -1039,6 +1352,10 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
for (i = first; i < last; i++)
{
uint32_t n_queue_props;
if (!physical_device_supports_extension (devices[i], VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME))
continue;
vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, NULL);
VkQueueFamilyProperties *queue_props = g_newa (VkQueueFamilyProperties, n_queue_props);
vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, queue_props);
@@ -1049,30 +1366,36 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
GPtrArray *device_extensions;
gboolean has_incremental_present;
has_incremental_present = device_supports_incremental_present (devices[i]);
has_incremental_present = physical_device_supports_extension (devices[i],
VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
device_extensions = g_ptr_array_new ();
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SWAPCHAIN_EXTENSION_NAME);
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
g_ptr_array_add (device_extensions, (gpointer) VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
if (has_incremental_present)
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
GDK_DISPLAY_DEBUG (display, VULKAN, "Using Vulkan device %u, queue %u", i, j);
if (GDK_VK_CHECK (vkCreateDevice, devices[i],
&(VkDeviceCreateInfo) {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
NULL,
0,
1,
&(VkDeviceQueueCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &(VkDeviceQueueCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.queueFamilyIndex = j,
.queueCount = 1,
.pQueuePriorities = (float []) { 1.0f },
},
0,
NULL,
device_extensions->len,
(const char * const *) device_extensions->pdata
.enabledExtensionCount = device_extensions->len,
.ppEnabledExtensionNames = (const char * const *) device_extensions->pdata,
.pNext = &(VkPhysicalDeviceDescriptorIndexingFeatures) {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
.descriptorBindingPartiallyBound = VK_TRUE,
.descriptorBindingVariableDescriptorCount = VK_TRUE,
.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE,
.descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE,
}
},
NULL,
&display->vk_device) != VK_SUCCESS)
@@ -1144,6 +1467,7 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
used_extensions = g_ptr_array_new ();
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_SURFACE_EXTENSION_NAME);
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
g_ptr_array_add (used_extensions, (gpointer) GDK_DISPLAY_GET_CLASS (display)->vk_extension_name);
for (i = 0; i < n_extensions; i++)
@@ -1215,7 +1539,7 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
.enabledLayerCount = used_layers->len,
.ppEnabledLayerNames = (const char * const *) used_layers->pdata,
.enabledExtensionCount = used_extensions->len,
.ppEnabledExtensionNames = (const char * const *) used_extensions->pdata
.ppEnabledExtensionNames = (const char * const *) used_extensions->pdata,
},
NULL,
&display->vk_instance);
@@ -1267,6 +1591,8 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
return FALSE;
}
gdk_display_create_pipeline_cache (display);
return TRUE;
}
@@ -1295,6 +1621,16 @@ gdk_display_unref_vulkan (GdkDisplay *display)
if (display->vulkan_refcount > 0)
return;
if (display->vk_save_pipeline_cache_source)
{
gdk_vulkan_save_pipeline_cache_cb (display);
g_assert (display->vk_save_pipeline_cache_source == 0);
}
vkDestroyPipelineCache (display->vk_device, display->vk_pipeline_cache, NULL);
display->vk_device = VK_NULL_HANDLE;
g_clear_pointer (&display->vk_pipeline_cache_etag, g_free);
display->vk_pipeline_cache_size = 0;
vkDestroyDevice (display->vk_device, NULL);
display->vk_device = VK_NULL_HANDLE;
if (display->vk_debug_callback != VK_NULL_HANDLE)
+9 -3
View File
@@ -69,9 +69,15 @@ gdk_vulkan_handle_result (VkResult res,
#define GDK_VK_CHECK(func, ...) gdk_vulkan_handle_result (func (__VA_ARGS__), G_STRINGIFY (func))
gboolean gdk_display_ref_vulkan (GdkDisplay *display,
GError **error);
void gdk_display_unref_vulkan (GdkDisplay *display);
gboolean gdk_display_ref_vulkan (GdkDisplay *display,
GError **error);
void gdk_display_unref_vulkan (GdkDisplay *display);
VkPipelineCache gdk_vulkan_context_get_pipeline_cache (GdkVulkanContext *self);
void gdk_vulkan_context_pipeline_cache_updated (GdkVulkanContext *self);
GdkMemoryFormat gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth);
#else /* !GDK_RENDERING_VULKAN */
+49 -6
View File
@@ -183,8 +183,7 @@ gdk_load_png (GBytes *bytes,
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb (png);
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
if (color_type == PNG_COLOR_TYPE_GRAY)
png_set_expand_gray_1_2_4_to_8 (png);
if (png_get_valid (png, info, PNG_INFO_tRNS))
@@ -193,10 +192,6 @@ gdk_load_png (GBytes *bytes,
if (depth < 8)
png_set_packing (png);
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb (png);
if (interlace != PNG_INTERLACE_NONE)
png_set_interlace_handling (png);
@@ -239,6 +234,26 @@ gdk_load_png (GBytes *bytes,
format = GDK_MEMORY_R16G16B16;
}
break;
case PNG_COLOR_TYPE_GRAY:
if (depth == 8)
{
format = GDK_MEMORY_G8;
}
else if (depth == 16)
{
format = GDK_MEMORY_G16;
}
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
if (depth == 8)
{
format = GDK_MEMORY_G8A8;
}
else if (depth == 16)
{
format = GDK_MEMORY_G16A16;
}
break;
default:
png_destroy_read_struct (&png, &info, NULL);
g_set_error (error,
@@ -349,6 +364,34 @@ gdk_save_png (GdkTexture *texture)
depth = 16;
break;
case GDK_MEMORY_G8:
format = GDK_MEMORY_G8;
png_format = PNG_COLOR_TYPE_GRAY;
depth = 8;
break;
case GDK_MEMORY_G8A8_PREMULTIPLIED:
case GDK_MEMORY_G8A8:
case GDK_MEMORY_A8:
format = GDK_MEMORY_G8A8;
png_format = PNG_COLOR_TYPE_GRAY_ALPHA;
depth = 8;
break;
case GDK_MEMORY_G16:
format = GDK_MEMORY_G16;
png_format = PNG_COLOR_TYPE_GRAY;
depth = 16;
break;
case GDK_MEMORY_G16A16_PREMULTIPLIED:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_A16:
format = GDK_MEMORY_G16A16;
png_format = PNG_COLOR_TYPE_GRAY_ALPHA;
depth = 16;
break;
case GDK_MEMORY_N_FORMATS:
default:
g_assert_not_reached ();
+32 -22
View File
@@ -229,27 +229,36 @@ struct _FormatData {
guint16 samples_per_pixel;
guint16 sample_format;
guint16 alpha_samples;
guint16 photometric;
};
static const FormatData format_data[] = {
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA },
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA },
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA },
[GDK_MEMORY_B8G8R8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
[GDK_MEMORY_A8R8G8B8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
[GDK_MEMORY_R8G8B8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
[GDK_MEMORY_A8B8G8R8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0 },
[GDK_MEMORY_B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0 },
[GDK_MEMORY_R16G16B16] = { GDK_MEMORY_R16G16B16, 16, 3, SAMPLEFORMAT_UINT, 0 },
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA },
[GDK_MEMORY_R16G16B16A16] = { GDK_MEMORY_R16G16B16A16, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA },
[GDK_MEMORY_R16G16B16_FLOAT] = { GDK_MEMORY_R16G16B16_FLOAT, 16, 3, SAMPLEFORMAT_IEEEFP, 0 },
[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA },
[GDK_MEMORY_R16G16B16A16_FLOAT] = { GDK_MEMORY_R16G16B16A16_FLOAT, 16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_UNASSALPHA },
[GDK_MEMORY_R32G32B32_FLOAT] = { GDK_MEMORY_R32G32B32_FLOAT, 32, 3, SAMPLEFORMAT_IEEEFP, 0 },
[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = { GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED, 32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA },
[GDK_MEMORY_R32G32B32A32_FLOAT] = { GDK_MEMORY_R32G32B32A32_FLOAT, 32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_UNASSALPHA },
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_B8G8R8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8R8G8B8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8B8G8R8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16] = { GDK_MEMORY_R16G16B16, 16, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16A16] = { GDK_MEMORY_R16G16B16A16, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16_FLOAT] = { GDK_MEMORY_R16G16B16_FLOAT, 16, 3, SAMPLEFORMAT_IEEEFP, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16A16_FLOAT] = { GDK_MEMORY_R16G16B16A16_FLOAT, 16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R32G32B32_FLOAT] = { GDK_MEMORY_R32G32B32_FLOAT, 32, 3, SAMPLEFORMAT_IEEEFP, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = { GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED, 32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R32G32B32A32_FLOAT] = { GDK_MEMORY_R32G32B32A32_FLOAT, 32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_G8A8_PREMULTIPLIED] = { GDK_MEMORY_G8A8_PREMULTIPLIED, 8, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_G8A8] = { GDK_MEMORY_G8A8, 8, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_G8] = { GDK_MEMORY_G8, 8, 1, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_G16A16_PREMULTIPLIED] = { GDK_MEMORY_G16A16_PREMULTIPLIED, 16, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_G16A16] = { GDK_MEMORY_G16A16, 16, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_G16] = { GDK_MEMORY_G16, 16, 1, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_A8] = { GDK_MEMORY_G8A8, 8, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_A16] = { GDK_MEMORY_G16A16, 16, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
};
/* if this fails, somebody forgot to add formats above */
@@ -289,7 +298,7 @@ gdk_save_tiff (GdkTexture *texture)
if (fdata->alpha_samples)
TIFFSetField (tif, TIFFTAG_EXTRASAMPLES, 1, &fdata->alpha_samples);
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, fdata->photometric);
TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
gdk_texture_downloader_init (&downloader, texture);
@@ -397,7 +406,7 @@ gdk_load_tiff (GBytes *input_bytes,
TIFFGetFieldDefaulted (tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetFieldDefaulted (tif, TIFFTAG_IMAGELENGTH, &height);
if (samples_per_pixel == 4)
if (samples_per_pixel == 2 || samples_per_pixel == 4)
{
guint16 extra;
guint16 *extra_types;
@@ -426,14 +435,15 @@ gdk_load_tiff (GBytes *input_bytes,
if (format_data[format].sample_format == sample_format &&
format_data[format].bits_per_sample == bits_per_sample &&
format_data[format].samples_per_pixel == samples_per_pixel &&
format_data[format].alpha_samples == alpha_samples)
format_data[format].alpha_samples == alpha_samples &&
format_data[format].photometric == photometric)
{
break;
}
}
if (format == G_N_ELEMENTS(format_data) ||
photometric != PHOTOMETRIC_RGB ||
(photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_MINISBLACK) ||
planarconfig != PLANARCONFIG_CONTIG ||
TIFFIsTiled (tif) ||
orientation != ORIENTATION_TOPLEFT)
+1 -1
View File
@@ -190,7 +190,7 @@ copy_surface_data (GdkMacosBuffer *from,
static void
_gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
+4 -4
View File
@@ -344,14 +344,14 @@ create_pixel_format (GdkGLVersion *version,
if (gdk_gl_version_get_major (version) >= 4)
{
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core;
if (CGLChoosePixelFormat (attrs, &format, &n_format))
if (CHECK (error, CGLChoosePixelFormat (attrs, &format, &n_format)))
return g_steal_pointer (&format);
}
if (gdk_gl_version_greater_equal (version, &GDK_GL_MIN_GL_VERSION))
{
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core;
if (CGLChoosePixelFormat (attrs, &format, &n_format))
if (CHECK (error, CGLChoosePixelFormat (attrs, &format, &n_format)))
return g_steal_pointer (&format);
}
@@ -396,7 +396,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
FALSE,
&version);
&min_version);
display = gdk_gl_context_get_display (context);
shared = gdk_display_get_gl_context (display);
@@ -480,7 +480,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
static void
gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
+12 -14
View File
@@ -207,7 +207,7 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
{
char *path;
XcursorImages *images;
struct cursor *cursor;
struct wl_cursor *cursor;
struct cursor_image *image;
int i, nbytes;
unsigned int load_size;
@@ -240,17 +240,16 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
return NULL;
}
cursor->cursor.images =
malloc(images->nimage * sizeof cursor->cursor.images[0]);
if (!cursor->cursor.images) {
cursor->images =
malloc(images->nimage * sizeof cursor->images[0]);
if (!cursor->images) {
free(cursor);
xcursor_images_destroy (images);
return NULL;
}
cursor->cursor.name = strdup(name);
cursor->cursor.size = load_size;
cursor->total_delay = 0;
cursor->name = strdup(name);
cursor->size = load_size;
for (i = 0; i < images->nimage; i++) {
image = malloc(sizeof *image);
@@ -291,14 +290,13 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
}
}
}
cursor->total_delay += image->image.delay;
cursor->cursor.images[i] = (struct wl_cursor_image *) image;
cursor->images[i] = (struct wl_cursor_image *) image;
}
cursor->cursor.image_count = i;
cursor->image_count = i;
if (cursor->cursor.image_count == 0) {
free(cursor->cursor.name);
free(cursor->cursor.images);
if (cursor->image_count == 0) {
free(cursor->name);
free(cursor->images);
free(cursor);
xcursor_images_destroy (images);
return NULL;
@@ -306,7 +304,7 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
xcursor_images_destroy (images);
return &cursor->cursor;
return cursor;
}
static void
+1 -1
View File
@@ -145,7 +145,7 @@ gdk_wayland_cairo_context_create_surface (GdkWaylandCairoContext *self)
static void
gdk_wayland_cairo_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkWaylandCairoContext *self = GDK_WAYLAND_CAIRO_CONTEXT (draw_context);
+31 -7
View File
@@ -698,7 +698,36 @@ gdk_wayland_display_dispose (GObject *object)
g_list_free_full (display_wayland->on_has_globals_closures, g_free);
g_clear_pointer (&display_wayland->cursor_theme, wl_cursor_theme_destroy);
g_clear_pointer (&display_wayland->compositor, wl_compositor_destroy);
g_clear_pointer (&display_wayland->xdg_wm_base, xdg_wm_base_destroy);
g_clear_pointer (&display_wayland->zxdg_shell_v6, zxdg_shell_v6_destroy);
g_clear_pointer (&display_wayland->gtk_shell, gtk_shell1_destroy);
g_clear_pointer (&display_wayland->data_device_manager, wl_data_device_manager_destroy);
g_clear_pointer (&display_wayland->subcompositor, wl_subcompositor_destroy);
g_clear_pointer (&display_wayland->pointer_gestures, zwp_pointer_gestures_v1_destroy);
g_clear_pointer (&display_wayland->primary_selection_manager, zwp_primary_selection_device_manager_v1_destroy);
g_clear_pointer (&display_wayland->tablet_manager, zwp_tablet_manager_v2_destroy);
g_clear_pointer (&display_wayland->xdg_exporter, zxdg_exporter_v1_destroy);
g_clear_pointer (&display_wayland->xdg_exporter_v2, zxdg_exporter_v2_destroy);
g_clear_pointer (&display_wayland->xdg_importer, zxdg_importer_v1_destroy);
g_clear_pointer (&display_wayland->xdg_importer_v2, zxdg_importer_v2_destroy);
g_clear_pointer (&display_wayland->keyboard_shortcuts_inhibit, zwp_keyboard_shortcuts_inhibit_manager_v1_destroy);
g_clear_pointer (&display_wayland->server_decoration_manager, org_kde_kwin_server_decoration_manager_destroy);
g_clear_pointer (&display_wayland->xdg_output_manager, zxdg_output_manager_v1_destroy);
g_clear_pointer (&display_wayland->idle_inhibit_manager, zwp_idle_inhibit_manager_v1_destroy);
g_clear_pointer (&display_wayland->xdg_activation, xdg_activation_v1_destroy);
g_clear_pointer (&display_wayland->fractional_scale, wp_fractional_scale_manager_v1_destroy);
g_clear_pointer (&display_wayland->viewporter, wp_viewporter_destroy);
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);
g_list_store_remove_all (display_wayland->monitors);
G_OBJECT_CLASS (gdk_wayland_display_parent_class)->dispose (object);
g_clear_pointer (&display_wayland->wl_display, wl_display_disconnect);
}
static void
@@ -708,22 +737,17 @@ gdk_wayland_display_finalize (GObject *object)
_gdk_wayland_display_finalize_cursors (display_wayland);
g_object_unref (display_wayland->monitors);
g_free (display_wayland->startup_notification_id);
g_free (display_wayland->cursor_theme_name);
xkb_context_unref (display_wayland->xkb_context);
g_clear_pointer (&display_wayland->cursor_theme, wl_cursor_theme_destroy);
g_list_store_remove_all (display_wayland->monitors);
g_object_unref (display_wayland->monitors);
if (display_wayland->settings)
g_hash_table_destroy (display_wayland->settings);
g_clear_object (&display_wayland->settings_portal);
wl_display_disconnect (display_wayland->wl_display);
G_OBJECT_CLASS (gdk_wayland_display_parent_class)->finalize (object);
}
-1
View File
@@ -98,7 +98,6 @@ struct _GdkWaylandDisplay
struct xdg_wm_base *xdg_wm_base;
struct zxdg_shell_v6 *zxdg_shell_v6;
struct gtk_shell1 *gtk_shell;
struct wl_input_device *input_device;
struct wl_data_device_manager *data_device_manager;
struct wl_subcompositor *subcompositor;
struct zwp_pointer_gestures_v1 *pointer_gestures;
+2 -2
View File
@@ -48,12 +48,12 @@ G_DEFINE_TYPE (GdkWaylandGLContext, gdk_wayland_gl_context, GDK_TYPE_GL_CONTEXT)
static void
gdk_wayland_gl_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
gdk_wayland_surface_ensure_wl_egl_window (gdk_draw_context_get_surface (draw_context));
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->begin_frame (draw_context, prefers_high_depth, region);
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->begin_frame (draw_context, depth, region);
}
static void
+63 -21
View File
@@ -2143,10 +2143,13 @@ _gdk_wayland_seat_remove_tablet_pad (GdkWaylandSeat *seat,
{
seat->tablet_pads = g_list_remove (seat->tablet_pads, pad);
gdk_seat_device_removed (GDK_SEAT (seat), pad->device);
_gdk_device_set_associated_device (pad->device, NULL);
if (pad->device)
{
gdk_seat_device_removed (GDK_SEAT (seat), pad->device);
_gdk_device_set_associated_device (pad->device, NULL);
g_object_unref (pad->device);
}
g_object_unref (pad->device);
g_free (pad);
}
@@ -3061,9 +3064,9 @@ tablet_tool_handle_button (void *data,
tablet->pointer_info.press_serial = serial;
if (button == BTN_STYLUS)
n_button = GDK_BUTTON_SECONDARY;
else if (button == BTN_STYLUS2)
n_button = GDK_BUTTON_MIDDLE;
else if (button == BTN_STYLUS2)
n_button = GDK_BUTTON_SECONDARY;
else if (button == BTN_STYLUS3)
n_button = 8; /* Back */
else
@@ -3535,21 +3538,10 @@ static void
tablet_pad_handle_done (void *data,
struct zwp_tablet_pad_v2 *wp_tablet_pad)
{
GdkWaylandTabletPadData *pad = data;
G_GNUC_UNUSED GdkWaylandTabletPadData *pad = data;
GDK_SEAT_DEBUG (pad->seat, EVENTS,
"tablet pad handle done, pad = %p", wp_tablet_pad);
pad->device =
g_object_new (GDK_TYPE_WAYLAND_DEVICE_PAD,
"name", "Pad device",
"source", GDK_SOURCE_TABLET_PAD,
"display", gdk_seat_get_display (pad->seat),
"seat", pad->seat,
NULL);
_gdk_device_set_associated_device (pad->device, GDK_WAYLAND_SEAT (pad->seat)->logical_keyboard);
gdk_seat_device_added (GDK_SEAT (pad->seat), pad->device);
}
static void
@@ -3606,9 +3598,44 @@ tablet_pad_handle_enter (void *data,
"tablet pad handle enter, pad = %p, tablet = %p surface = %p",
wp_tablet_pad, wp_tablet, surface);
if (pad->device && pad->current_tablet != tablet)
{
gdk_seat_device_removed (GDK_SEAT (pad->seat), pad->device);
_gdk_device_set_associated_device (pad->device, NULL);
g_clear_object (&pad->device);
}
/* Relate pad and tablet */
tablet->pads = g_list_prepend (tablet->pads, pad);
pad->current_tablet = tablet;
if (!pad->device)
{
gchar *name, *vid, *pid;
name = g_strdup_printf ("%s Pad %d",
tablet->name,
g_list_index (tablet->pads, pad) + 1);
vid = g_strdup_printf ("%.4x", tablet->vid);
pid = g_strdup_printf ("%.4x", tablet->pid);
pad->device =
g_object_new (GDK_TYPE_WAYLAND_DEVICE_PAD,
"name", name,
"vendor-id", vid,
"product-id", pid,
"source", GDK_SOURCE_TABLET_PAD,
"display", gdk_seat_get_display (pad->seat),
"seat", pad->seat,
NULL);
_gdk_device_set_associated_device (pad->device, GDK_WAYLAND_SEAT (pad->seat)->logical_keyboard);
gdk_seat_device_added (GDK_SEAT (pad->seat), pad->device);
g_free (name);
g_free (vid);
g_free (pid);
}
}
static void
@@ -3624,10 +3651,7 @@ tablet_pad_handle_leave (void *data,
wp_tablet_pad, surface);
if (pad->current_tablet)
{
pad->current_tablet->pads = g_list_remove (pad->current_tablet->pads, pad);
pad->current_tablet = NULL;
}
pad->current_tablet->pads = g_list_remove (pad->current_tablet->pads, pad);
}
static void
@@ -3875,6 +3899,23 @@ gdk_wayland_pointer_data_finalize (GdkWaylandPointerData *pointer)
g_slist_free (pointer->pointer_surface_outputs);
}
static void
gdk_wayland_seat_dispose (GObject *object)
{
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (object);
g_clear_pointer (&seat->wl_seat, wl_seat_destroy);
g_clear_pointer (&seat->wl_pointer, wl_pointer_destroy);
g_clear_pointer (&seat->wl_keyboard, wl_keyboard_destroy);
g_clear_pointer (&seat->wl_touch, wl_touch_destroy);
g_clear_pointer (&seat->wp_pointer_gesture_swipe, zwp_pointer_gesture_swipe_v1_destroy);
g_clear_pointer (&seat->wp_pointer_gesture_pinch, zwp_pointer_gesture_pinch_v1_destroy);
g_clear_pointer (&seat->wp_pointer_gesture_hold, zwp_pointer_gesture_hold_v1_destroy);
g_clear_pointer (&seat->wp_tablet_seat, zwp_tablet_seat_v2_destroy);
G_OBJECT_CLASS (gdk_wayland_seat_parent_class)->dispose (object);
}
static void
gdk_wayland_seat_finalize (GObject *object)
{
@@ -4189,6 +4230,7 @@ gdk_wayland_seat_class_init (GdkWaylandSeatClass *klass)
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
object_class->finalize = gdk_wayland_seat_finalize;
object_class->dispose = gdk_wayland_seat_dispose;
seat_class->get_capabilities = gdk_wayland_seat_get_capabilities;
seat_class->grab = gdk_wayland_seat_grab;
+1 -1
View File
@@ -53,7 +53,7 @@ create_cairo_surface_for_surface (GdkSurface *surface,
static void
gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkWin32CairoContext *self = GDK_WIN32_CAIRO_CONTEXT (draw_context);
+3 -3
View File
@@ -1436,7 +1436,7 @@ register_clipboard_notification ()
wclass.lpszClassName = "GdkClipboardNotification";
wclass.lpfnWndProc = _clipboard_window_procedure;
wclass.hInstance = _gdk_dll_hinstance;
wclass.hInstance = this_module ();
wclass.cbWndExtra = sizeof (GdkWin32ClipboardThread *);
klass = RegisterClass (&wclass);
@@ -1446,7 +1446,7 @@ register_clipboard_notification ()
clipboard_thread_data->clipboard_window = CreateWindow (MAKEINTRESOURCE (klass),
NULL, WS_POPUP,
0, 0, 0, 0, NULL, NULL,
_gdk_dll_hinstance, NULL);
this_module (), NULL);
if (clipboard_thread_data->clipboard_window == NULL)
goto failed;
@@ -1471,7 +1471,7 @@ register_clipboard_notification ()
failed:
g_critical ("Failed to install clipboard viewer");
UnregisterClass (MAKEINTRESOURCE (klass), _gdk_dll_hinstance);
UnregisterClass (MAKEINTRESOURCE (klass), this_module ());
return FALSE;
}
+7 -30
View File
@@ -417,13 +417,12 @@ hcursor_from_x_cursor (int i,
#undef SET_BIT
#undef RESET_BIT
rv = CreateCursor (_gdk_app_hmodule, cursors[i].hotx, cursors[i].hoty,
rv = CreateCursor (NULL, cursors[i].hotx, cursors[i].hoty,
w, h, and_plane, xor_plane);
}
else
{
rv = CreateCursor (_gdk_app_hmodule, 0, 0,
w, h, and_plane, xor_plane);
rv = CreateCursor (NULL, 0, 0, w, h, and_plane, xor_plane);
}
if (rv == NULL)
@@ -466,7 +465,7 @@ win32_cursor_create_win32hcursor (GdkWin32Display *display,
break;
case GDK_WIN32_CURSOR_LOAD_FROM_RESOURCE_THIS:
result = gdk_win32_hcursor_new (display,
LoadImageA (_gdk_app_hmodule,
LoadImageA (GetModuleHandle (NULL),
(const char *) cursor->resource_name,
IMAGE_CURSOR,
cursor->width,
@@ -476,7 +475,7 @@ win32_cursor_create_win32hcursor (GdkWin32Display *display,
break;
case GDK_WIN32_CURSOR_LOAD_FROM_RESOURCE_GTK:
result = gdk_win32_hcursor_new (display,
LoadImageA (_gdk_dll_hinstance,
LoadImageA (this_module (),
(const char *) cursor->resource_name,
IMAGE_CURSOR,
cursor->width,
@@ -858,9 +857,7 @@ create_blank_win32hcursor (GdkWin32Display *display)
xor_plane = g_malloc ((w/8) * h);
memset (xor_plane, 0, (w/8) * h);
rv = CreateCursor (_gdk_app_hmodule, 0, 0,
w, h, and_plane, xor_plane);
rv = CreateCursor (NULL, 0, 0, w, h, and_plane, xor_plane);
if (rv == NULL)
WIN32_API_FAILED ("CreateCursor");
@@ -871,6 +868,7 @@ static GdkWin32HCursor *
gdk_win32hcursor_create_for_name (GdkWin32Display *display,
const char *name)
{
const HINSTANCE hinstance = GetModuleHandle (NULL);
GdkWin32HCursor *win32hcursor = NULL;
/* Blank cursor case */
@@ -885,7 +883,7 @@ gdk_win32hcursor_create_for_name (GdkWin32Display *display,
/* Allow to load named cursor resources linked into the executable.
* Cursors obtained with LoadCursor() cannot be destroyed.
*/
return gdk_win32_hcursor_new (display, LoadCursor (_gdk_app_hmodule, name), FALSE);
return gdk_win32_hcursor_new (display, LoadCursor (hinstance, name), FALSE);
}
static HICON
@@ -1452,27 +1450,6 @@ pixbuf_to_hicon (GdkPixbuf *pixbuf,
return icon;
}
HICON
_gdk_win32_texture_to_hicon (GdkTexture *texture)
{
cairo_surface_t *surface;
GdkPixbuf *pixbuf;
int width, height;
HICON icon;
surface = gdk_texture_download_surface (texture);
width = cairo_image_surface_get_width (surface);
height = cairo_image_surface_get_height (surface);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
icon = pixbuf_to_hicon (pixbuf, TRUE, 0, 0);
g_object_unref (pixbuf);
return icon;
}
/**
* gdk_win32_display_get_win32hcursor:
* @display: (type GdkWin32Display): a `GdkDisplay`
+3 -3
View File
@@ -481,7 +481,7 @@ register_display_change_notification (GdkDisplay *display)
wclass.lpszClassName = "GdkDisplayChange";
wclass.lpfnWndProc = display_change_window_procedure;
wclass.hInstance = _gdk_app_hmodule;
wclass.hInstance = this_module ();
wclass.style = CS_OWNDC;
klass = RegisterClass (&wclass);
@@ -490,10 +490,10 @@ register_display_change_notification (GdkDisplay *display)
display_win32->hwnd = CreateWindow (MAKEINTRESOURCE (klass),
NULL, WS_POPUP,
0, 0, 0, 0, NULL, NULL,
_gdk_app_hmodule, NULL);
this_module (), NULL);
if (!display_win32->hwnd)
{
UnregisterClass (MAKEINTRESOURCE (klass), _gdk_app_hmodule);
UnregisterClass (MAKEINTRESOURCE (klass), this_module ());
}
}
}
+24 -17
View File
@@ -139,7 +139,6 @@ static GSourceFuncs event_funcs = {
static GdkSurface *mouse_window = NULL;
static GdkSurface *mouse_window_ignored_leave = NULL;
static int current_x, current_y;
static int current_root_x, current_root_y;
static UINT got_gdk_events_message;
@@ -413,8 +412,7 @@ set_up_low_level_keyboard_hook (void)
hook_handle = SetWindowsHookEx (WH_KEYBOARD_LL,
(HOOKPROC) low_level_keyboard_proc,
_gdk_dll_hinstance,
0);
this_module (), 0);
if (hook_handle != NULL)
keyboard_hook = hook_handle;
@@ -1523,14 +1521,15 @@ generate_button_event (GdkEventType type,
GdkEvent *event;
GdkDeviceManagerWin32 *device_manager;
GdkWin32Surface *impl = GDK_WIN32_SURFACE (window);
double x, y;
if (_gdk_input_ignore_core > 0)
return;
device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager);
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer,
_gdk_device_manager->system_pointer);
@@ -1542,10 +1541,10 @@ generate_button_event (GdkEventType type,
_gdk_win32_get_next_tick (msg->time),
build_pointer_event_state (msg),
button,
current_x,
current_y,
x,
y,
NULL);
_gdk_win32_append_event (event);
}
@@ -2351,19 +2350,19 @@ gdk_event_translate (MSG *msg,
* sends WM_MOUSEMOVE messages after a new window is shown under
* the mouse, even if the mouse hasn't moved. This disturbs gtk.
*/
if (msg->pt.x / impl->surface_scale == current_root_x &&
msg->pt.y / impl->surface_scale == current_root_y)
if (msg->pt.x == current_root_x &&
msg->pt.y == current_root_y)
break;
current_root_x = msg->pt.x / impl->surface_scale;
current_root_y = msg->pt.y / impl->surface_scale;
current_root_x = msg->pt.x;
current_root_y = msg->pt.y;
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
gdk_win32_surface_do_move_resize_drag (window, msg->pt.x, msg->pt.y);
else if (_gdk_input_ignore_core == 0)
{
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
double x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
double y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer,
_gdk_device_manager->system_pointer);
@@ -2373,8 +2372,8 @@ gdk_event_translate (MSG *msg,
NULL,
_gdk_win32_get_next_tick (msg->time),
build_pointer_event_state (msg),
current_x,
current_y,
x,
y,
NULL);
_gdk_win32_append_event (event);
@@ -2735,6 +2734,10 @@ gdk_event_translate (MSG *msg,
if (GDK_IS_DRAG_SURFACE (window) ||
_gdk_modal_blocked (window))
{
/* Focus the modal window */
GdkSurface *modal_window = _gdk_modal_current ();
if (modal_window != NULL)
SetFocus (GDK_SURFACE_HWND (modal_window));
*ret_valp = MA_NOACTIVATE;
return_val = TRUE;
}
@@ -2745,6 +2748,10 @@ gdk_event_translate (MSG *msg,
if (GDK_IS_DRAG_SURFACE (window) ||
_gdk_modal_blocked (window))
{
/* Focus the modal window */
GdkSurface *modal_window = _gdk_modal_current ();
if (modal_window != NULL)
SetFocus (GDK_SURFACE_HWND (modal_window));
*ret_valp = PA_NOACTIVATE;
return_val = TRUE;
}
+2 -2
View File
@@ -109,12 +109,12 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
static void
gdk_win32_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *update_area)
{
gdk_win32_surface_handle_queued_move_resize (draw_context);
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->begin_frame (draw_context, prefers_high_depth, update_area);
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->begin_frame (draw_context, depth, update_area);
}
static void
+5 -5
View File
@@ -118,12 +118,12 @@ gdk_win32_gl_context_wgl_end_frame (GdkDrawContext *draw_context,
static void
gdk_win32_gl_context_wgl_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *update_area)
{
gdk_win32_surface_handle_queued_move_resize (draw_context);
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_wgl_parent_class)->begin_frame (draw_context, prefers_high_depth, update_area);
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_wgl_parent_class)->begin_frame (draw_context, depth, update_area);
}
static int
@@ -261,7 +261,7 @@ create_dummy_gl_window (void)
wclass.lpszClassName = "GdkGLDummyWindow";
wclass.lpfnWndProc = DefWindowProc;
wclass.hInstance = _gdk_app_hmodule;
wclass.hInstance = this_module ();
wclass.style = CS_OWNDC;
klass = RegisterClass (&wclass);
@@ -270,10 +270,10 @@ create_dummy_gl_window (void)
hwnd = CreateWindow (MAKEINTRESOURCE (klass),
NULL, WS_POPUP,
0, 0, 0, 0, NULL, NULL,
_gdk_app_hmodule, NULL);
this_module (), NULL);
if (!hwnd)
{
UnregisterClass (MAKEINTRESOURCE (klass), _gdk_app_hmodule);
UnregisterClass (MAKEINTRESOURCE (klass), this_module ());
}
}
-4
View File
@@ -30,10 +30,6 @@
GdkDisplay *_gdk_display = NULL;
GdkDeviceManagerWin32 *_gdk_device_manager = NULL;
HDC _gdk_display_hdc;
HINSTANCE _gdk_dll_hinstance;
HINSTANCE _gdk_app_hmodule;
int _gdk_input_ignore_core;
HKL _gdk_input_locale;
+5 -4
View File
@@ -271,9 +271,10 @@ winpointer_make_event (GdkDeviceWinpointer *device,
y /= impl->surface_scale;
state = 0;
if (info->dwKeyStates & POINTER_MOD_CTRL)
/* Note that info->dwKeyStates is not reliable, use GetKeyState() */
if (GetKeyState (VK_CONTROL) < 0)
state |= GDK_CONTROL_MASK;
if (info->dwKeyStates & POINTER_MOD_SHIFT)
if (GetKeyState (VK_SHIFT) < 0)
state |= GDK_SHIFT_MASK;
if (GetKeyState (VK_MENU) < 0)
state |= GDK_ALT_MASK;
@@ -1003,7 +1004,7 @@ winpointer_notif_window_create (void)
wndclassex.cbSize = sizeof (wndclassex);
wndclassex.lpszClassName = L"GdkWin32WinpointerNotificationsWindowClass";
wndclassex.lpfnWndProc = winpointer_notifications_window_procedure;
wndclassex.hInstance = _gdk_dll_hinstance;
wndclassex.hInstance = this_module ();
if ((notifications_window_class = RegisterClassExW (&wndclassex)) == 0)
{
@@ -1018,7 +1019,7 @@ winpointer_notif_window_create (void)
0, 0, 0, 0,
HWND_MESSAGE,
NULL,
_gdk_dll_hinstance,
this_module (),
NULL)))
{
WIN32_API_FAILED ("CreateWindowExW");
-13
View File
@@ -576,19 +576,6 @@ gdk_mod_mask_to_mod_bits (GdkModifierType mod_mask)
return result;
}
/* keypad decimal mark depends on active keyboard layout
* return current decimal mark as unicode character
*/
guint32
_gdk_win32_keymap_get_decimal_mark (GdkWin32Keymap *keymap)
{
guint32 c = MapVirtualKeyW (VK_DECIMAL, MAPVK_VK_TO_CHAR);
if (!c)
c = (guint32) '.';
return c;
}
static void
update_keymap (GdkWin32Keymap *keymap)
{
+56 -190
View File
@@ -45,9 +45,6 @@
#include <wintab.h>
#include <imm.h>
/* for CFSTR_SHELLIDLIST */
#include <shlobj.h>
static gboolean gdk_synchronize = FALSE;
/* Whether GDK initialized COM */
@@ -66,8 +63,6 @@ _gdk_win32_surfaceing_init (void)
if (gdk_synchronize)
GdiSetBatchLimit (1);
_gdk_app_hmodule = GetModuleHandle (NULL);
_gdk_display_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
_gdk_input_locale = GetKeyboardLayout (0);
_gdk_win32_keymap_set_active_layout (win32_keymap, _gdk_input_locale);
@@ -187,135 +182,6 @@ static_printf (const char *format,
return retval;
}
void
_gdk_win32_print_paletteentries (const PALETTEENTRY *pep,
const int nentries)
{
char buf[20];
int i;
for (i = 0; i < nentries; i++)
g_print (" %3d %02x: %02x %02x %02x%s\n",
i, i,
pep[i].peRed, pep[i].peGreen, pep[i].peBlue,
(pep[i].peFlags == 0 ? "" :
(pep[i].peFlags == PC_EXPLICIT ? " PC_EXPLICIT" :
(pep[i].peFlags == PC_NOCOLLAPSE ? " PC_NOCOLLAPSE" :
(pep[i].peFlags == PC_RESERVED ? " PC_RESERVED" :
(g_sprintf (buf, " %d", pep[i].peFlags), buf))))));
}
void
_gdk_win32_print_system_palette (void)
{
PALETTEENTRY *pe;
int k;
k = GetSystemPaletteEntries (_gdk_display_hdc, 0, 0, NULL);
pe = g_new (PALETTEENTRY, k);
k = GetSystemPaletteEntries (_gdk_display_hdc, 0, k, pe);
if (!k)
g_print ("GetSystemPaletteEntries failed: %s\n",
g_win32_error_message (GetLastError ()));
else
{
g_print ("System palette: %d entries\n", k);
_gdk_win32_print_paletteentries (pe, k);
}
g_free (pe);
}
static int
palette_size (HPALETTE hpal)
{
WORD npal = 0;
if (!GetObject (hpal, sizeof (npal), &npal))
WIN32_GDI_FAILED ("GetObject (HPALETTE)");
return npal;
}
void
_gdk_win32_print_hpalette (HPALETTE hpal)
{
PALETTEENTRY *pe;
int n, npal;
npal = palette_size (hpal);
pe = g_new (PALETTEENTRY, npal);
n = GetPaletteEntries (hpal, 0, npal, pe);
if (!n)
g_print ("HPALETTE %p: GetPaletteEntries failed: %s\n",
hpal, g_win32_error_message (GetLastError ()));
else
{
g_print ("HPALETTE %p: %d (%d) entries\n", hpal, n, npal);
_gdk_win32_print_paletteentries (pe, n);
}
g_free (pe);
}
void
_gdk_win32_print_dc (HDC hdc)
{
HGDIOBJ obj;
LOGBRUSH logbrush;
EXTLOGPEN extlogpen;
HRGN hrgn;
RECT rect;
int flag;
g_print ("%p:\n", hdc);
obj = GetCurrentObject (hdc, OBJ_BRUSH);
GetObject (obj, sizeof (LOGBRUSH), &logbrush);
g_print ("brush: %s color=%06lx hatch=%p\n",
_gdk_win32_lbstyle_to_string (logbrush.lbStyle),
logbrush.lbColor, (gpointer) logbrush.lbHatch);
obj = GetCurrentObject (hdc, OBJ_PEN);
GetObject (obj, sizeof (EXTLOGPEN), &extlogpen);
g_print ("pen: %s %s %s %s w=%d %s\n",
_gdk_win32_pstype_to_string (extlogpen.elpPenStyle),
_gdk_win32_psstyle_to_string (extlogpen.elpPenStyle),
_gdk_win32_psendcap_to_string (extlogpen.elpPenStyle),
_gdk_win32_psjoin_to_string (extlogpen.elpPenStyle),
(int) extlogpen.elpWidth,
_gdk_win32_lbstyle_to_string (extlogpen.elpBrushStyle));
g_print ("rop2: %s textcolor=%06lx\n",
_gdk_win32_rop2_to_string (GetROP2 (hdc)),
GetTextColor (hdc));
hrgn = CreateRectRgn (0, 0, 0, 0);
if ((flag = GetClipRgn (hdc, hrgn)) == -1)
WIN32_API_FAILED ("GetClipRgn");
else if (flag == 0)
g_print ("no clip region\n");
else if (flag == 1)
{
GetRgnBox (hrgn, &rect);
g_print ("clip region: %p bbox: %s\n",
hrgn, _gdk_win32_rect_to_string (&rect));
}
DeleteObject (hrgn);
}
char *
_gdk_win32_drag_protocol_to_string (GdkDragProtocol protocol)
{
switch (protocol)
{
#define CASE(x) case GDK_DRAG_PROTO_##x: return #x
CASE (NONE);
CASE (WIN32_DROPFILES);
CASE (OLE2);
#undef CASE
default: return static_printf ("illegal_%d", protocol);
}
/* NOTREACHED */
return NULL;
}
char *
_gdk_win32_surface_state_to_string (GdkToplevelState state)
{
@@ -478,7 +344,7 @@ _gdk_win32_drag_action_to_string (GdkDragAction actions)
return static_printf ("%s", buf);
}
char *
static char *
_gdk_win32_rop2_to_string (int rop2)
{
switch (rop2)
@@ -507,7 +373,7 @@ _gdk_win32_rop2_to_string (int rop2)
return NULL;
}
char *
static char *
_gdk_win32_lbstyle_to_string (UINT brush_style)
{
switch (brush_style)
@@ -526,7 +392,7 @@ _gdk_win32_lbstyle_to_string (UINT brush_style)
return NULL;
}
char *
static char *
_gdk_win32_pstype_to_string (DWORD pen_style)
{
switch (pen_style & PS_TYPE_MASK)
@@ -539,7 +405,7 @@ _gdk_win32_pstype_to_string (DWORD pen_style)
return NULL;
}
char *
static char *
_gdk_win32_psstyle_to_string (DWORD pen_style)
{
switch (pen_style & PS_STYLE_MASK)
@@ -561,7 +427,7 @@ _gdk_win32_psstyle_to_string (DWORD pen_style)
return NULL;
}
char *
static char *
_gdk_win32_psendcap_to_string (DWORD pen_style)
{
switch (pen_style & PS_ENDCAP_MASK)
@@ -577,7 +443,7 @@ _gdk_win32_psendcap_to_string (DWORD pen_style)
return NULL;
}
char *
static char *
_gdk_win32_psjoin_to_string (DWORD pen_style)
{
switch (pen_style & PS_JOIN_MASK)
@@ -593,6 +459,56 @@ _gdk_win32_psjoin_to_string (DWORD pen_style)
return NULL;
}
void
_gdk_win32_print_dc (HDC hdc)
{
HGDIOBJ obj;
LOGBRUSH logbrush;
EXTLOGPEN extlogpen;
HRGN hrgn;
RECT rect;
int flag;
g_print ("%p:\n", hdc);
obj = GetCurrentObject (hdc, OBJ_BRUSH);
GetObject (obj, sizeof (LOGBRUSH), &logbrush);
g_print ("brush: %s color=%06lx hatch=%p\n",
_gdk_win32_lbstyle_to_string (logbrush.lbStyle),
logbrush.lbColor, (gpointer) logbrush.lbHatch);
obj = GetCurrentObject (hdc, OBJ_PEN);
GetObject (obj, sizeof (EXTLOGPEN), &extlogpen);
g_print ("pen: %s %s %s %s w=%d %s\n",
_gdk_win32_pstype_to_string (extlogpen.elpPenStyle),
_gdk_win32_psstyle_to_string (extlogpen.elpPenStyle),
_gdk_win32_psendcap_to_string (extlogpen.elpPenStyle),
_gdk_win32_psjoin_to_string (extlogpen.elpPenStyle),
(int) extlogpen.elpWidth,
_gdk_win32_lbstyle_to_string (extlogpen.elpBrushStyle));
g_print ("rop2: %s textcolor=%06lx\n",
_gdk_win32_rop2_to_string (GetROP2 (hdc)),
GetTextColor (hdc));
hrgn = CreateRectRgn (0, 0, 0, 0);
if ((flag = GetClipRgn (hdc, hrgn)) == -1)
WIN32_API_FAILED ("GetClipRgn");
else if (flag == 0)
g_print ("no clip region\n");
else if (flag == 1)
{
GetRgnBox (hrgn, &rect);
g_print ("clip region: %p bbox: %s\n",
hrgn, _gdk_win32_rect_to_string (&rect));
}
DeleteObject (hrgn);
}
char *
_gdk_win32_message_to_string (UINT msg)
{
@@ -893,26 +809,6 @@ _gdk_win32_cf_to_string (UINT format)
}
}
char *
_gdk_win32_data_to_string (const guchar *data,
int nbytes)
{
GString *s = g_string_new ("");
int i;
char *retval;
for (i = 0; i < nbytes; i++)
if (data[i] >=' ' && data[i] <= '~')
g_string_append_printf (s, "%c ", data[i]);
else
g_string_append_printf (s, "%02X ", data[i]);
retval = static_printf ("%s", s->str);
g_string_free (s, TRUE);
return retval;
}
char *
_gdk_win32_rect_to_string (const RECT *rect)
{
@@ -921,34 +817,4 @@ _gdk_win32_rect_to_string (const RECT *rect)
rect->left, rect->top);
}
char *
_gdk_win32_gdkrectangle_to_string (const GdkRectangle *rect)
{
return static_printf ("%dx%d@%+d%+d",
rect->width, rect->height,
rect->x, rect->y);
}
char *
_gdk_win32_cairo_region_to_string (const cairo_region_t *rgn)
{
cairo_rectangle_int_t extents;
cairo_region_get_extents (rgn, &extents);
return static_printf ("%dx%d@%+d%+d",
extents.width, extents.height,
extents.x, extents.y);
}
char *
_gdk_win32_surface_description (GdkSurface *d)
{
g_return_val_if_fail (GDK_IS_SURFACE (d), NULL);
return static_printf ("%s:%p:%dx%d",
G_OBJECT_TYPE_NAME (d),
GDK_SURFACE_HWND (d),
gdk_surface_get_width (GDK_SURFACE (d)),
gdk_surface_get_height (GDK_SURFACE (d)));
}
#endif /* G_ENABLE_DEBUG */
+10 -157
View File
@@ -15,15 +15,10 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#pragma once
#include "config.h"
#include <gdk/gdkcursorprivate.h>
#include <gdk/gdkdebugprivate.h>
#include <gdk/win32/gdksurface-win32.h>
@@ -32,10 +27,6 @@
#include <gdk/win32/gdkwin32keys.h>
#include <gdk/win32/gdkdevicemanager-win32.h>
#include <gdk/win32/gdkclipdrop-win32.h>
//#include <gdk/win32/gdkselection-win32.h>
#include "config.h"
/* Old debug macros */
@@ -54,62 +45,6 @@
#endif
/* Make up for some minor w32api or MSVC6 header lossage */
#ifndef PS_JOIN_MASK
#define PS_JOIN_MASK (PS_JOIN_BEVEL|PS_JOIN_MITER|PS_JOIN_ROUND)
#endif
#ifndef FS_VIETNAMESE
#define FS_VIETNAMESE 0x100
#endif
#ifndef WM_GETOBJECT
#define WM_GETOBJECT 0x3D
#endif
#ifndef WM_NCXBUTTONDOWN
#define WM_NCXBUTTONDOWN 0xAB
#endif
#ifndef WM_NCXBUTTONUP
#define WM_NCXBUTTONUP 0xAC
#endif
#ifndef WM_NCXBUTTONDBLCLK
#define WM_NCXBUTTONDBLCLK 0xAD
#endif
#ifndef WM_CHANGEUISTATE
#define WM_CHANGEUISTATE 0x127
#endif
#ifndef WM_UPDATEUISTATE
#define WM_UPDATEUISTATE 0x128
#endif
#ifndef WM_QUERYUISTATE
#define WM_QUERYUISTATE 0x129
#endif
#ifndef WM_XBUTTONDOWN
#define WM_XBUTTONDOWN 0x20B
#endif
#ifndef WM_XBUTTONUP
#define WM_XBUTTONUP 0x20C
#endif
#ifndef WM_XBUTTONDBLCLK
#define WM_XBUTTONDBLCLK 0x20D
#endif
#ifndef WM_NCMOUSEHOVER
#define WM_NCMOUSEHOVER 0x2A0
#endif
#ifndef WM_NCMOUSELEAVE
#define WM_NCMOUSELEAVE 0x2A2
#endif
#ifndef WM_APPCOMMAND
#define WM_APPCOMMAND 0x319
#endif
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x20E
#endif
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif
/* According to
* http://blog.airesoft.co.uk/2009/11/wm_messages/
* this is the actual internal name MS uses for this undocumented message.
@@ -122,11 +57,6 @@
#define WM_SYSMENU 0x313
#endif
#ifndef CF_DIBV5
#define CF_DIBV5 17
#endif
/* Define some combinations of GdkDebugFlags */
#define GDK_DEBUG_EVENTS_OR_INPUT (GDK_DEBUG_EVENTS|GDK_DEBUG_INPUT)
#define GDK_DEBUG_MISC_OR_EVENTS (GDK_DEBUG_MISC|GDK_DEBUG_EVENTS)
@@ -140,22 +70,6 @@ GdkWin32Screen *GDK_SURFACE_SCREEN(GObject *win);
*/
#define SWP_NOZORDER_SPECIFIED HWND_TOP
typedef struct _GdkWin32SingleFont GdkWin32SingleFont;
struct _GdkWin32SingleFont
{
HFONT hfont;
UINT charset;
UINT codepage;
FONTSIGNATURE fs;
};
typedef enum {
GDK_WIN32_PE_STATIC,
GDK_WIN32_PE_AVAILABLE,
GDK_WIN32_PE_INUSE
} GdkWin32PalEntryState;
typedef enum
{
GDK_DRAG_PROTO_NONE = 0,
@@ -163,51 +77,23 @@ typedef enum
GDK_DRAG_PROTO_OLE2,
} GdkDragProtocol;
GType _gdk_gc_win32_get_type (void);
gulong _gdk_win32_get_next_tick (gulong suggested_tick);
BOOL _gdk_win32_get_cursor_pos (LPPOINT lpPoint);
void _gdk_surface_init_position (GdkSurface *window);
void _gdk_surface_move_resize_child (GdkSurface *window,
int x,
int y,
int width,
int height);
gboolean _gdk_win32_surface_enable_transparency (GdkSurface *window);
/* GdkSurfaceImpl methods */
void _gdk_win32_surface_scroll (GdkSurface *window,
int dx,
int dy);
void _gdk_win32_surface_move_region (GdkSurface *window,
const cairo_region_t *region,
int dx,
int dy);
void _gdk_win32_selection_init (void);
void _gdk_win32_dnd_exit (void);
void gdk_win32_handle_table_insert (HANDLE *handle,
gpointer data);
void gdk_win32_handle_table_remove (HANDLE handle);
HRGN _gdk_win32_cairo_region_to_hrgn (const cairo_region_t *region,
int x_origin,
int y_origin);
cairo_region_t *_gdk_win32_hrgn_to_region (HRGN hrgn,
guint scale);
void _gdk_win32_adjust_client_rect (GdkSurface *window,
RECT *RECT);
void _gdk_selection_property_delete (GdkSurface *);
void _gdk_push_modal_window (GdkSurface *window);
void _gdk_remove_modal_window (GdkSurface *window);
GdkSurface *_gdk_modal_current (void);
@@ -217,41 +103,22 @@ gboolean gdk_win32_ensure_com (void);
gboolean gdk_win32_ensure_ole (void);
#ifdef G_ENABLE_DEBUG
void _gdk_win32_print_paletteentries (const PALETTEENTRY *pep,
const int nentries);
void _gdk_win32_print_system_palette (void);
void _gdk_win32_print_hpalette (HPALETTE hpal);
void _gdk_win32_print_dc (HDC hdc);
char *_gdk_win32_drag_protocol_to_string (GdkDragProtocol protocol);
char *_gdk_win32_surface_state_to_string (GdkToplevelState state);
char *_gdk_win32_surface_style_to_string (LONG style);
char *_gdk_win32_surface_exstyle_to_string (LONG style);
char *_gdk_win32_surface_pos_bits_to_string (UINT flags);
char *_gdk_win32_drag_action_to_string (GdkDragAction actions);
char *_gdk_win32_surface_description (GdkSurface *d);
char *_gdk_win32_rop2_to_string (int rop2);
char *_gdk_win32_lbstyle_to_string (UINT brush_style);
char *_gdk_win32_pstype_to_string (DWORD pen_style);
char *_gdk_win32_psstyle_to_string (DWORD pen_style);
char *_gdk_win32_psendcap_to_string (DWORD pen_style);
char *_gdk_win32_psjoin_to_string (DWORD pen_style);
char *_gdk_win32_message_to_string (UINT msg);
char *_gdk_win32_key_to_string (LONG lParam);
char *_gdk_win32_cf_to_string (UINT format);
char *_gdk_win32_data_to_string (const guchar*data,
int nbytes);
char *_gdk_win32_rect_to_string (const RECT *rect);
char *_gdk_win32_gdkrectangle_to_string (const GdkRectangle *rect);
char *_gdk_win32_cairo_region_to_string (const cairo_region_t *box);
void _gdk_win32_print_event (GdkEvent *event);
#endif
char *_gdk_win32_last_error_string (void);
void _gdk_win32_api_failed (const char *where,
const char *api);
void _gdk_other_api_failed (const char *where,
@@ -284,10 +151,6 @@ extern GdkDisplay *_gdk_display;
extern GdkDeviceManagerWin32 *_gdk_device_manager;
extern HDC _gdk_display_hdc;
extern HINSTANCE _gdk_dll_hinstance;
extern HINSTANCE _gdk_app_hmodule;
extern int _gdk_input_ignore_core;
/* These are thread specific, but GDK/win32 works OK only when invoked
@@ -304,8 +167,6 @@ extern GdkWin32Clipdrop *_win32_clipdrop;
/* Used to identify the main thread */
extern GThread *_win32_main_thread;
void _gdk_win32_dnd_do_dragdrop (void);
typedef enum {
GDK_WIN32_MODAL_OP_NONE = 0x0,
GDK_WIN32_MODAL_OP_SIZE = 0x1 << 0,
@@ -324,16 +185,9 @@ extern HWND _modal_move_resize_window;
void _gdk_win32_begin_modal_call (GdkWin32ModalOpKind kind);
void _gdk_win32_end_modal_call (GdkWin32ModalOpKind kind);
/* Convert a pixbuf to an HICON (or HCURSOR). Supports alpha under
* Windows XP, thresholds alpha otherwise.
*/
HICON _gdk_win32_texture_to_hicon (GdkTexture *texture);
void _gdk_win32_display_init_cursors (GdkWin32Display *display);
void _gdk_win32_display_finalize_cursors (GdkWin32Display *display);
void _gdk_win32_display_update_cursors (GdkWin32Display *display);
GdkCursor *_gdk_win32_display_get_cursor_for_name (GdkDisplay *display, const char * cursor_name);
GdkCursor *gdk_win32_display_cursor_from_hcursor (GdkDisplay *display, HCURSOR hcursor);
typedef struct _Win32CursorTheme Win32CursorTheme;
@@ -367,9 +221,6 @@ Win32Cursor * win32_cursor_theme_get_cursor (Win32CursorTheme *theme,
void win32_cursor_theme_destroy (Win32CursorTheme *theme);
Win32CursorTheme *_gdk_win32_display_get_cursor_theme (GdkWin32Display *win32_display);
/* GdkDisplay member functions */
GList *_gdk_win32_display_list_devices (GdkDisplay *dpy);
gboolean _gdk_win32_display_has_pending (GdkDisplay *display);
void _gdk_win32_display_queue_events (GdkDisplay *display);
@@ -395,16 +246,11 @@ GdkDrag *_gdk_win32_surface_drag_begin (GdkSurface *window,
/* Stray GdkWin32Screen members */
gboolean _gdk_win32_get_setting (const char *name, GValue *value);
void _gdk_win32_screen_on_displaychange_event (GdkWin32Screen *screen);
GdkSurface *gdk_win32_screen_get_root_window (GdkWin32Screen *screen);
GdkSurface *gdk_win32_display_get_root_window (GdkDisplay *display);
/* Distributed display manager implementation */
GdkDisplay *_gdk_win32_display_open (const char *display_name);
void _gdk_win32_append_event (GdkEvent *event);
guint32 _gdk_win32_keymap_get_decimal_mark (GdkWin32Keymap *keymap);
void _gdk_win32_surface_handle_aerosnap (GdkSurface *window,
GdkWin32AeroSnapCombo combo);
@@ -449,8 +295,15 @@ gboolean _gdk_win32_check_processor (GdkWin32ProcessorCheckType check_type);
GdkPixbuf *gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
double *x_hot,
double *y_hot);
HICON gdk_win32_pixbuf_to_hicon_libgtk_only (GdkPixbuf *pixbuf);
void gdk_win32_set_modal_dialog_libgtk_only (HWND window);
gpointer gdk_win32_handle_table_lookup_ (HWND handle);
extern IMAGE_DOS_HEADER __ImageBase;
static inline HMODULE
this_module (void)
{
return (HMODULE) &__ImageBase;
}
+9 -1
View File
@@ -113,7 +113,15 @@ _gdk_win32_get_setting (const char *name,
}
else if (strcmp ("gtk-font-name", name) == 0)
{
char *font_name = _get_system_font_name (_gdk_display_hdc);
char *font_name = NULL;
HDC hdc = NULL;
if ((hdc = GetDC (HWND_DESKTOP)) != NULL)
{
font_name = _get_system_font_name (hdc);
ReleaseDC (HWND_DESKTOP, hdc);
hdc = NULL;
}
if (font_name)
{
+18 -10
View File
@@ -339,7 +339,7 @@ RegisterGdkClass (GType wtype)
wcl.lpfnWndProc = _gdk_win32_surface_procedure;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hInstance = _gdk_dll_hinstance;
wcl.hInstance = this_module ();
wcl.hIcon = 0;
wcl.hIconSm = 0;
@@ -356,7 +356,7 @@ RegisterGdkClass (GType wtype)
if (0 == hAppIcon && 0 == hAppIconSm)
{
// fallback : load icon from GTK DLL
if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
if (0 != GetModuleFileName (this_module (), sLoc, MAX_PATH))
{
ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
}
@@ -493,7 +493,7 @@ gdk_win32_surface_constructed (GObject *object)
CW_USEDEFAULT, CW_USEDEFAULT,
owner,
NULL,
_gdk_dll_hinstance,
this_module (),
surface);
if (impl->handle == NULL)
{
@@ -725,11 +725,7 @@ show_window_internal (GdkSurface *window,
if (center)
{
window_rect.left = 0;
window_rect.top = 0;
window_rect.right = window->width * surface->surface_scale;
window_rect.bottom = window->height * surface->surface_scale;
_gdk_win32_adjust_client_rect (window, &window_rect);
GetWindowRect (GDK_SURFACE_HWND (window), &window_rect);
x = center_on_rect.left + ((center_on_rect.right - center_on_rect.left) - (window_rect.right - window_rect.left)) / 2;
y = center_on_rect.top + ((center_on_rect.bottom - center_on_rect.top) - (window_rect.bottom - window_rect.top)) / 2;
@@ -2404,7 +2400,7 @@ RegisterGdkDumbClass ()
wcl.lpfnWndProc = DefWindowProcW;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hInstance = _gdk_dll_hinstance;
wcl.hInstance = this_module ();
wcl.hIcon = 0;
wcl.hIconSm = 0;
wcl.lpszMenuName = NULL;
@@ -2445,7 +2441,7 @@ ensure_snap_indicator_exists (GdkW32DragMoveResizeContext *context)
0, 0,
NULL,
NULL,
_gdk_dll_hinstance,
this_module (),
NULL);
context->shape_indicator = handle;
@@ -3539,6 +3535,8 @@ setup_drag_move_resize_context (GdkSurface *surface,
context->button = button;
context->start_root_x = root_x;
context->start_root_y = root_y;
context->current_root_x = root_x;
context->current_root_y = root_y;
context->timestamp = timestamp;
context->start_rect = rect;
@@ -3654,6 +3652,16 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
if (!_gdk_win32_get_window_rect (window, &rect))
return;
x /= impl->surface_scale;
y /= impl->surface_scale;
if (context->current_root_x == x &&
context->current_root_y == y)
return;
context->current_root_x = x;
context->current_root_y = y;
new_rect = context->start_rect;
diffx = (x - context->start_root_x) * impl->surface_scale;
diffy = (y - context->start_root_y) * impl->surface_scale;
+6
View File
@@ -137,6 +137,12 @@ struct _GdkW32DragMoveResizeContext
int start_root_x;
int start_root_y;
/* Last processed cursor position. Values are divided by the window
* scale.
*/
int current_root_x;
int current_root_y;
/* Initial window rectangle (position and size).
* The window is resized/moved relative to this (see start_root_*).
*/
+3 -5
View File
@@ -30,8 +30,6 @@
#include "gdkprivate-win32.h"
#include "gdkwin32misc.h"
extern HINSTANCE _gdk_dll_hinstance;
G_DEFINE_TYPE (GdkWin32VulkanContext, gdk_win32_vulkan_context, GDK_TYPE_VULKAN_CONTEXT)
static VkResult
@@ -47,7 +45,7 @@ gdk_win32_vulkan_context_create_surface (GdkVulkanContext *context,
info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
info.pNext = NULL;
info.flags = 0;
info.hinstance = _gdk_dll_hinstance;
info.hinstance = this_module ();
info.hwnd = GDK_SURFACE_HWND (window);
/* This is necessary so that Vulkan sees the Window.
@@ -68,12 +66,12 @@ gdk_win32_vulkan_context_create_surface (GdkVulkanContext *context,
static void
gdk_win32_vulkan_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *update_area)
{
gdk_win32_surface_handle_queued_move_resize (draw_context);
GDK_DRAW_CONTEXT_CLASS (gdk_win32_vulkan_context_parent_class)->begin_frame (draw_context, prefers_high_depth, update_area);
GDK_DRAW_CONTEXT_CLASS (gdk_win32_vulkan_context_parent_class)->begin_frame (draw_context, depth, update_area);
}
static void
+1 -1
View File
@@ -55,7 +55,7 @@ create_cairo_surface_for_surface (GdkSurface *surface)
static void
gdk_x11_cairo_context_begin_frame (GdkDrawContext *draw_context,
gboolean prefers_high_depth,
GdkMemoryDepth depth,
cairo_region_t *region)
{
GdkX11CairoContext *self = GDK_X11_CAIRO_CONTEXT (draw_context);
+1 -204
View File
@@ -134,35 +134,6 @@ struct _GdkX11DragClass
GdkDragClass parent_class;
};
typedef struct {
int keysym;
int modifiers;
} GrabKey;
static GrabKey grab_keys[] = {
{ XK_Escape, 0 },
{ XK_space, 0 },
{ XK_KP_Space, 0 },
{ XK_Return, 0 },
{ XK_KP_Enter, 0 },
{ XK_Up, 0 },
{ XK_Up, Mod1Mask },
{ XK_Down, 0 },
{ XK_Down, Mod1Mask },
{ XK_Left, 0 },
{ XK_Left, Mod1Mask },
{ XK_Right, 0 },
{ XK_Right, Mod1Mask },
{ XK_KP_Up, 0 },
{ XK_KP_Up, Mod1Mask },
{ XK_KP_Down, 0 },
{ XK_KP_Down, Mod1Mask },
{ XK_KP_Left, 0 },
{ XK_KP_Left, Mod1Mask },
{ XK_KP_Right, 0 },
{ XK_KP_Right, Mod1Mask }
};
/* Forward declarations */
static GdkSurfaceCache *gdk_surface_cache_ref (GdkSurfaceCache *cache);
@@ -1861,20 +1832,15 @@ drag_grab (GdkDrag *drag)
{
GdkX11Drag *x11_drag = GDK_X11_DRAG (drag);
GdkSeatCapabilities capabilities;
GdkDisplay *display;
Window root;
GdkSeat *seat;
int keycode, i;
GdkCursor *cursor;
if (!x11_drag->ipc_surface)
return FALSE;
display = gdk_drag_get_display (drag);
root = GDK_DISPLAY_XROOTWIN (display);
seat = gdk_device_get_seat (gdk_drag_get_device (drag));
capabilities = GDK_SEAT_CAPABILITY_ALL_POINTING | GDK_SEAT_CAPABILITY_KEYBOARD;
capabilities = GDK_SEAT_CAPABILITY_ALL_POINTING;
cursor = gdk_drag_get_cursor (drag, x11_drag->current_action);
g_set_object (&x11_drag->cursor, cursor);
@@ -1886,46 +1852,6 @@ drag_grab (GdkDrag *drag)
g_set_object (&x11_drag->grab_seat, seat);
gdk_x11_display_error_trap_push (display);
for (i = 0; i < G_N_ELEMENTS (grab_keys); ++i)
{
int deviceid = gdk_x11_device_get_id (gdk_seat_get_keyboard (seat));
unsigned char mask[XIMaskLen(XI_LASTEVENT)];
XIGrabModifiers mods;
XIEventMask evmask;
int num_mods;
keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (display),
grab_keys[i].keysym);
if (keycode == NoSymbol)
continue;
memset (mask, 0, sizeof (mask));
XISetMask (mask, XI_KeyPress);
XISetMask (mask, XI_KeyRelease);
evmask.deviceid = deviceid;
evmask.mask_len = sizeof (mask);
evmask.mask = mask;
num_mods = 1;
mods.modifiers = grab_keys[i].modifiers;
XIGrabKeycode (GDK_DISPLAY_XDISPLAY (display),
deviceid,
keycode,
root,
GrabModeAsync,
GrabModeAsync,
False,
&evmask,
num_mods,
&mods);
}
gdk_x11_display_error_trap_pop_ignored (display);
return TRUE;
}
@@ -1933,41 +1859,13 @@ static void
drag_ungrab (GdkDrag *drag)
{
GdkX11Drag *x11_drag = GDK_X11_DRAG (drag);
GdkDisplay *display;
GdkDevice *keyboard;
Window root;
int keycode, i;
if (!x11_drag->grab_seat)
return;
gdk_seat_ungrab (x11_drag->grab_seat);
display = gdk_drag_get_display (drag);
keyboard = gdk_seat_get_keyboard (x11_drag->grab_seat);
root = GDK_DISPLAY_XROOTWIN (display);
g_clear_object (&x11_drag->grab_seat);
for (i = 0; i < G_N_ELEMENTS (grab_keys); ++i)
{
XIGrabModifiers mods;
int num_mods;
keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (display),
grab_keys[i].keysym);
if (keycode == NoSymbol)
continue;
num_mods = 1;
mods.modifiers = grab_keys[i].modifiers;
XIUngrabKeycode (GDK_DISPLAY_XDISPLAY (display),
gdk_x11_device_get_id (keyboard),
keycode,
root,
num_mods,
&mods);
}
}
GdkDrag *
@@ -2191,103 +2089,6 @@ gdk_dnd_handle_motion_event (GdkDrag *drag,
return TRUE;
}
static gboolean
gdk_dnd_handle_key_event (GdkDrag *drag,
GdkEvent *event)
{
GdkX11Drag *x11_drag = GDK_X11_DRAG (drag);
GdkModifierType state;
GdkDevice *pointer;
GdkSeat *seat;
int dx, dy;
dx = dy = 0;
state = gdk_event_get_modifier_state (event);
seat = gdk_event_get_seat (event);
pointer = gdk_seat_get_pointer (seat);
if (event->event_type == GDK_KEY_PRESS)
{
guint keyval = gdk_key_event_get_keyval (event);
switch (keyval)
{
case GDK_KEY_Escape:
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_USER_CANCELLED);
return TRUE;
case GDK_KEY_space:
case GDK_KEY_Return:
case GDK_KEY_ISO_Enter:
case GDK_KEY_KP_Enter:
case GDK_KEY_KP_Space:
if ((gdk_drag_get_selected_action (drag) != 0) &&
(x11_drag->proxy_xid != None))
{
g_signal_emit_by_name (drag, "drop-performed");
}
else
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
return TRUE;
case GDK_KEY_Up:
case GDK_KEY_KP_Up:
dy = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
break;
case GDK_KEY_Down:
case GDK_KEY_KP_Down:
dy = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
break;
case GDK_KEY_Left:
case GDK_KEY_KP_Left:
dx = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
break;
case GDK_KEY_Right:
case GDK_KEY_KP_Right:
dx = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
break;
default:
break;
}
}
/* The state is not yet updated in the event, so we need
* to query it here. We could use XGetModifierMapping, but
* that would be overkill.
*/
gdk_x11_device_xi2_query_state (pointer, NULL, NULL, NULL, &state);
if (dx != 0 || dy != 0)
{
GdkDisplay *display;
Display *xdisplay;
GdkX11Screen *screen;
Window dest;
x11_drag->last_x += dx;
x11_drag->last_y += dy;
display = gdk_event_get_display ((GdkEvent *)event);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
screen = GDK_X11_DISPLAY (display)->screen;
dest = GDK_SCREEN_XROOTWIN (screen);
XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0,
round (x11_drag->last_x * screen->surface_scale),
round (x11_drag->last_y * screen->surface_scale));
}
gdk_drag_update (drag, x11_drag->last_x, x11_drag->last_y, state,
gdk_event_get_time (event));
return TRUE;
}
static gboolean
gdk_dnd_handle_grab_broken_event (GdkDrag *drag,
GdkEvent *event)
@@ -2354,10 +2155,6 @@ gdk_x11_drag_handle_event (GdkDrag *drag,
case GDK_BUTTON_RELEASE:
return gdk_dnd_handle_button_event (drag, event);
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
return gdk_dnd_handle_key_event (drag, event);
case GDK_GRAB_BROKEN:
return gdk_dnd_handle_grab_broken_event (drag, event);
+31 -22
View File
@@ -543,8 +543,6 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
if (share != NULL)
share_glx = GDK_X11_GL_CONTEXT_GLX (share);
gdk_x11_display_error_trap_push (display);
supported_versions = gdk_gl_versions_get_for_api (api);
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
{
@@ -568,19 +566,13 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
True,
context_attribs);
if (ctx)
if (ctx != NULL)
break;
}
if (ctx == NULL)
{
gdk_x11_display_error_trap_pop_ignored (display);
return 0;
}
if (gdk_x11_display_error_trap_pop (display))
{
glXDestroyContext (dpy, ctx);
GDK_DISPLAY_DEBUG (display, OPENGL, "Failed to create a GLX context");
return 0;
}
@@ -664,25 +656,42 @@ gdk_x11_gl_context_glx_realize (GdkGLContext *context,
if (share != NULL && gdk_gl_context_is_legacy (share))
legacy = TRUE;
gdk_x11_display_error_trap_push (display);
/* Increase XNextRequest because GLX may fake errors with the last request
* and we want the error trap to catch them */
XChangeWindowAttributes (GDK_DISPLAY_XDISPLAY (display),
GDK_X11_DISPLAY (display)->leader_window,
0,
(XSetWindowAttributes[1]) { 0, });
if (preferred_api == GDK_GL_API_GL)
{
if ((api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GL, legacy)) ||
(api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GLES, legacy)) ||
(api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GL, TRUE)))
return api;
api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GL, legacy);
if (api == 0)
api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GLES, legacy);
if (api == 0)
api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GL, TRUE);
}
else
{
if ((api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GLES, FALSE)) ||
(api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GL, legacy)) ||
(api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GL, TRUE)))
return api;
api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GLES, FALSE);
if (api == 0)
api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GL, legacy);
if (api == 0)
api = gdk_x11_context_create_glx_context (context, GDK_GL_API_GL, TRUE);
}
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
return 0;
gdk_x11_display_error_trap_pop_ignored (display);
if (api == 0)
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
}
return api;
}
#undef N_GLX_ATTRS
+19 -3
View File
@@ -685,8 +685,13 @@ init_randr13 (GdkX11Screen *x11_screen)
for (i = 0; i < resources->noutput; ++i)
{
RROutput output = resources->outputs[i];
XRROutputInfo *output_info =
XRRGetOutputInfo (x11_screen->xdisplay, resources, output);
XRROutputInfo *output_info;
gdk_x11_display_error_trap_push (display);
output_info = XRRGetOutputInfo (x11_screen->xdisplay, resources, output);
if (gdk_x11_display_error_trap_pop (display))
continue;
if (output_info->connection == RR_Disconnected)
{
@@ -697,13 +702,22 @@ init_randr13 (GdkX11Screen *x11_screen)
if (output_info->crtc)
{
GdkX11Monitor *monitor;
XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc);
XRRCrtcInfo *crtc;
char *name;
GdkRectangle geometry;
GdkRectangle newgeo;
int j;
int refresh_rate = 0;
gdk_x11_display_error_trap_push (display);
crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc);
if (gdk_x11_display_error_trap_pop (display))
{
XRRFreeOutputInfo (output_info);
continue;
}
for (j = 0; j < resources->nmode; j++)
{
XRRModeInfo *xmode = &resources->modes[j];
@@ -775,8 +789,10 @@ init_randr13 (GdkX11Screen *x11_screen)
}
x11_display->primary_monitor = 0;
gdk_x11_display_error_trap_push (display);
primary_output = XRRGetOutputPrimary (x11_screen->xdisplay,
x11_screen->xroot_window);
gdk_x11_display_error_trap_pop_ignored (display);
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (x11_display->monitors)); i++)
{
+12 -12
View File
@@ -89,7 +89,7 @@ gdk_x11_selection_input_stream_fill_buffer (GdkX11SelectionInputStream *stream,
if (size == 0)
{
/* EOF marker, put it back */
g_async_queue_push_front_unlocked (priv->chunks, bytes);
g_async_queue_push_front_unlocked (priv->chunks, g_steal_pointer (&bytes));
break;
}
else if (size > count)
@@ -107,7 +107,7 @@ gdk_x11_selection_input_stream_fill_buffer (GdkX11SelectionInputStream *stream,
memcpy (buffer, g_bytes_get_data (bytes, NULL), size);
}
g_bytes_unref (bytes);
g_bytes_unref (g_steal_pointer (&bytes));
result += size;
if (buffer)
buffer += size;
@@ -165,9 +165,7 @@ gdk_x11_selection_input_stream_complete (GdkX11SelectionInputStream *stream)
GDK_X11_DISPLAY (priv->display)->streams = g_slist_remove (GDK_X11_DISPLAY (priv->display)->streams, stream);
g_signal_handlers_disconnect_by_func (priv->display,
gdk_x11_selection_input_stream_xevent,
stream);
g_object_unref (stream);
g_steal_pointer (&stream));
}
static gssize
@@ -416,7 +414,7 @@ gdk_x11_selection_input_stream_xevent (GdkDisplay *display,
"%s:%s: got PropertyNotify erroring out of INCR",
priv->selection, priv->target);
/* error, should we signal one? */
gdk_x11_selection_input_stream_complete (stream);
g_clear_pointer (&stream, gdk_x11_selection_input_stream_complete);
}
else if (g_bytes_get_size (bytes) == 0 || type == None)
{
@@ -424,7 +422,7 @@ gdk_x11_selection_input_stream_xevent (GdkDisplay *display,
"%s:%s: got PropertyNotify ending INCR",
priv->selection, priv->target);
g_bytes_unref (bytes);
gdk_x11_selection_input_stream_complete (stream);
g_clear_pointer (&stream, gdk_x11_selection_input_stream_complete);
}
else
{
@@ -467,7 +465,7 @@ gdk_x11_selection_input_stream_xevent (GdkDisplay *display,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
_("Format %s not supported"), priv->target);
gdk_x11_selection_input_stream_complete (stream);
g_clear_pointer (&stream, gdk_x11_selection_input_stream_complete);
}
else
{
@@ -478,7 +476,7 @@ gdk_x11_selection_input_stream_xevent (GdkDisplay *display,
if (bytes == NULL)
{
gdk_x11_selection_input_stream_complete (stream);
g_clear_pointer (&stream, gdk_x11_selection_input_stream_complete);
}
else
{
@@ -500,7 +498,7 @@ gdk_x11_selection_input_stream_xevent (GdkDisplay *display,
g_bytes_get_size (bytes));
g_async_queue_push (priv->chunks, bytes);
gdk_x11_selection_input_stream_complete (stream);
g_clear_pointer (&stream, gdk_x11_selection_input_stream_complete);
}
}
@@ -541,7 +539,10 @@ gdk_x11_selection_input_stream_new_async (GdkDisplay *display,
priv->property = g_strdup_printf ("GDK_SELECTION_%p", stream);
priv->xproperty = gdk_x11_get_xatom_by_name_for_display (display, priv->property);
g_signal_connect (display, "xevent", G_CALLBACK (gdk_x11_selection_input_stream_xevent), stream);
g_signal_connect_data (display, "xevent",
G_CALLBACK (gdk_x11_selection_input_stream_xevent),
g_steal_pointer (&stream),
(GClosureNotify) g_object_unref, 0);
XConvertSelection (GDK_DISPLAY_XDISPLAY (display),
priv->xselection,
@@ -577,7 +578,6 @@ gdk_x11_selection_input_stream_new_finish (GAsyncResult *result,
*type = priv->type;
if (format)
*format = priv->format;
g_object_ref (stream);
}
return G_INPUT_STREAM (stream);
+4 -4
View File
@@ -165,7 +165,7 @@ void half_to_float4 (const guint16 h[4], float f[4]) __attribute__((ifunc ("reso
void float_to_half (const float *f, guint16 *h, int n) __attribute__((ifunc ("resolve_float_to_half")));
void half_to_float (const guint16 *h, float *f, int n) __attribute__((ifunc ("resolve_half_to_float")));
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_float_to_half4 (void)
{
__builtin_cpu_init ();
@@ -175,7 +175,7 @@ resolve_float_to_half4 (void)
return float_to_half4_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_half_to_float4 (void)
{
__builtin_cpu_init ();
@@ -185,7 +185,7 @@ resolve_half_to_float4 (void)
return half_to_float4_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_float_to_half (void)
{
__builtin_cpu_init ();
@@ -195,7 +195,7 @@ resolve_float_to_half (void)
return float_to_half_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_half_to_float (void)
{
__builtin_cpu_init ();
+73 -7
View File
@@ -1455,18 +1455,65 @@ memory_format_gl_format (GdkMemoryFormat data_format,
guint minor,
guint *gl_internalformat,
guint *gl_format,
guint *gl_type)
guint *gl_type,
GLint (*gl_swizzle)[4])
{
GdkMemoryDepth depth;
/* First, try the format itself */
if (gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type))
gl_type,
gl_swizzle) &&
gdk_memory_format_alpha (data_format) != GDK_MEMORY_ALPHA_STRAIGHT)
return data_format;
if (gdk_memory_format_prefers_high_depth (data_format))
depth = gdk_memory_format_get_depth (data_format);
/* Next, try the generic format for the given bit depth */
switch (depth)
{
case GDK_MEMORY_FLOAT16:
data_format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type,
gl_swizzle))
return data_format;
break;
case GDK_MEMORY_U16:
data_format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type,
gl_swizzle))
return data_format;
break;
case GDK_MEMORY_FLOAT32:
case GDK_MEMORY_U8:
break;
default:
g_assert_not_reached ();
break;
}
/* If the format is high depth, also try float32 */
if (depth != GDK_MEMORY_U8)
{
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format,
@@ -1475,10 +1522,12 @@ memory_format_gl_format (GdkMemoryFormat data_format,
minor,
gl_internalformat,
gl_format,
gl_type))
gl_type,
gl_swizzle))
return data_format;
}
/* If all else fails, pick the one format that's always supported */
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (!gdk_memory_format_gl_format (data_format,
use_es,
@@ -1486,7 +1535,8 @@ memory_format_gl_format (GdkMemoryFormat data_format,
minor,
gl_internalformat,
gl_format,
gl_type))
gl_type,
gl_swizzle))
{
g_assert_not_reached ();
}
@@ -1509,6 +1559,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
GLenum gl_internalformat;
GLenum gl_format;
GLenum gl_type;
GLint gl_swizzle[4];
gsize bpp;
gboolean use_es;
int major, minor;
@@ -1525,7 +1576,8 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
minor,
&gl_internalformat,
&gl_format,
&gl_type);
&gl_type,
&gl_swizzle);
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, data_format);
@@ -1560,6 +1612,18 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
/* Only apply swizzle if really needed, might not even be
* supported if default values are set
*/
if (gl_swizzle[0] != GL_RED || gl_swizzle[1] != GL_GREEN || gl_swizzle[2] != GL_BLUE)
{
/* Set each channel independently since GLES 3.0 doesn't support the iv method */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, gl_swizzle[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, gl_swizzle[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, gl_swizzle[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, gl_swizzle[3]);
}
g_bytes_unref (bytes);
}
@@ -1574,6 +1638,7 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
GLenum gl_internalformat;
GLenum gl_format;
GLenum gl_type;
GLint gl_swizzle[4];
gboolean use_es;
int texture_id;
int major, minor;
@@ -1618,7 +1683,8 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
minor,
&gl_internalformat,
&gl_format,
&gl_type);
&gl_type,
&gl_swizzle);
glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, NULL);
+11 -6
View File
@@ -686,17 +686,21 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
const GskTextureKey *key,
guint texture_id)
{
GskTextureKey *k;
g_assert (GSK_IS_GL_DRIVER (self));
g_assert (key != NULL);
g_assert (texture_id > 0);
g_assert (g_hash_table_contains (self->textures, GUINT_TO_POINTER (texture_id)));
k = g_memdup (key, sizeof *key);
if (!g_hash_table_contains (self->key_to_texture_id, key))
{
GskTextureKey *k;
g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
k = g_memdup (key, sizeof *key);
g_assert (!g_hash_table_contains (self->texture_id_to_key, GUINT_TO_POINTER (texture_id)));
g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
}
}
/**
@@ -761,7 +765,8 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
if (gdk_gl_context_is_shared (context, texture_context) &&
(!ensure_mipmap || gdk_gl_texture_has_mipmap (gl_texture)))
(!ensure_mipmap || gdk_gl_texture_has_mipmap (gl_texture)) &&
gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_STRAIGHT)
{
/* A GL texture from the same GL context is a simple task... */
return gdk_gl_texture_get_id (gl_texture);
+2 -2
View File
@@ -296,7 +296,7 @@ gsk_gl_renderer_render (GskRenderer *renderer,
viewport.size.height = gdk_surface_get_height (surface) * scale;
gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->context),
gsk_render_node_prefers_high_depth (root),
gsk_render_node_get_preferred_depth (root),
update_area);
gdk_gl_context_make_current (self->context);
@@ -373,7 +373,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
return texture;
}
if (gsk_render_node_prefers_high_depth (root) &&
if (gsk_render_node_get_preferred_depth (root) != GDK_MEMORY_U8 &&
gdk_gl_context_check_version (self->context, "3.0", "3.0"))
format = GL_RGBA32F;
else
+3 -1
View File
@@ -194,7 +194,7 @@ static inline int
get_target_format (GskGLRenderJob *job,
const GskRenderNode *node)
{
if (gsk_render_node_prefers_high_depth (node))
if (gsk_render_node_get_preferred_depth (node) != GDK_MEMORY_U8)
return job->target_format;
return GL_RGBA8;
@@ -803,6 +803,8 @@ gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
out_rect->origin.x -= job->offset_x;
out_rect->origin.y -= job->offset_y;
gsk_transform_unref (transform);
}
static inline void
+1
View File
@@ -204,6 +204,7 @@ gsk_gl_texture_library_dispose (GObject *object)
g_clear_pointer (&self->atlases, g_ptr_array_unref);
g_clear_object (&self->driver);
g_clear_pointer (&self->hash_table, g_hash_table_unref);
G_OBJECT_CLASS (gsk_gl_texture_library_parent_class)->dispose (object);
}
+8 -2
View File
@@ -13,6 +13,12 @@ void main() {
uniform int u_mode;
uniform sampler2D u_mask;
float
luminance (vec3 color)
{
return dot (vec3 (0.2126, 0.7152, 0.0722), color);
}
void main() {
vec4 source = GskTexture(u_source, vUv);
vec4 mask = GskTexture(u_mask, vUv);
@@ -23,9 +29,9 @@ void main() {
else if (u_mode == 1)
mask_value = 1.0 - mask.a;
else if (u_mode == 2)
mask_value = (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
mask_value = luminance (mask.rgb);
else if (u_mode == 3)
mask_value = 1.0 - (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
mask_value = mask.a - luminance (mask.rgb);
else
mask_value = 0.0;
+1 -2
View File
@@ -15,8 +15,7 @@ static const GdkDebugKey gsk_debug_keys[] = {
{ "geometry", GSK_DEBUG_GEOMETRY, "Show borders (when using cairo)" },
{ "full-redraw", GSK_DEBUG_FULL_REDRAW, "Force full redraws" },
{ "sync", GSK_DEBUG_SYNC, "Sync after each frame" },
{ "vulkan-staging-image", GSK_DEBUG_VULKAN_STAGING_IMAGE, "Use a staging image for Vulkan texture upload" },
{ "vulkan-staging-buffer", GSK_DEBUG_VULKAN_STAGING_BUFFER, "Use a staging buffer for Vulkan texture upload" }
{ "staging", GSK_DEBUG_STAGING, "Use a staging image for texture upload (Vulkan only)" },
};
static guint gsk_debug_flags;
+1 -2
View File
@@ -18,8 +18,7 @@ typedef enum {
GSK_DEBUG_GEOMETRY = 1 << 9,
GSK_DEBUG_FULL_REDRAW = 1 << 10,
GSK_DEBUG_SYNC = 1 << 11,
GSK_DEBUG_VULKAN_STAGING_IMAGE = 1 << 12,
GSK_DEBUG_VULKAN_STAGING_BUFFER = 1 << 13
GSK_DEBUG_STAGING = 1 << 12
} GskDebugFlags;
#define GSK_DEBUG_ANY ((1 << 13) - 1)
+2
View File
@@ -372,6 +372,8 @@ gsk_renderer_render_texture (GskRenderer *renderer,
gsk_render_node_get_bounds (root, &real_viewport);
viewport = &real_viewport;
}
g_return_val_if_fail (viewport->size.width > 0, NULL);
g_return_val_if_fail (viewport->size.height > 0, NULL);
texture = GSK_RENDERER_GET_CLASS (renderer)->render_texture (renderer, root, viewport);
+3 -3
View File
@@ -675,10 +675,10 @@ gsk_value_dup_render_node (const GValue *value)
return gsk_render_node_ref (value->data[0].v_pointer);
}
gboolean
gsk_render_node_prefers_high_depth (const GskRenderNode *node)
GdkMemoryDepth
gsk_render_node_get_preferred_depth (const GskRenderNode *node)
{
return node->prefers_high_depth;
return node->preferred_depth;
}
/* Whether we need an offscreen to handle opacity correctly for this node.
+106 -58
View File
@@ -1734,7 +1734,7 @@ gsk_texture_node_new (GdkTexture *texture,
self->texture = g_object_ref (texture);
graphene_rect_init_from_rect (&node->bounds, bounds);
node->prefers_high_depth = gdk_memory_format_prefers_high_depth (gdk_texture_get_format (texture));
node->preferred_depth = gdk_memory_format_get_depth (gdk_texture_get_format (texture));
return node;
}
@@ -1960,7 +1960,7 @@ gsk_texture_scale_node_new (GdkTexture *texture,
graphene_rect_init_from_rect (&node->bounds, bounds);
self->filter = filter;
node->prefers_high_depth = gdk_memory_format_prefers_high_depth (gdk_texture_get_format (texture));
node->preferred_depth = gdk_memory_format_get_depth (gdk_texture_get_format (texture));
return node;
}
@@ -2421,6 +2421,7 @@ gsk_inset_shadow_node_new (const GskRoundedRect *outline,
g_return_val_if_fail (outline != NULL, NULL);
g_return_val_if_fail (color != NULL, NULL);
g_return_val_if_fail (blur_radius >= 0, NULL);
self = gsk_render_node_alloc (GSK_INSET_SHADOW_NODE);
node = (GskRenderNode *) self;
@@ -2696,7 +2697,7 @@ gsk_outset_shadow_node_diff (GskRenderNode *node1,
static void
gsk_outset_shadow_node_class_init (gpointer g_class,
gpointer class_data)
gpointer class_data)
{
GskRenderNodeClass *node_class = g_class;
@@ -2734,6 +2735,7 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline,
g_return_val_if_fail (outline != NULL, NULL);
g_return_val_if_fail (color != NULL, NULL);
g_return_val_if_fail (blur_radius >= 0, NULL);
self = gsk_render_node_alloc (GSK_OUTSET_SHADOW_NODE);
node = (GskRenderNode *) self;
@@ -3193,14 +3195,16 @@ gsk_container_node_new (GskRenderNode **children,
self->children[0] = gsk_render_node_ref (children[0]);
graphene_rect_init_from_rect (&bounds, &(children[0]->bounds));
node->prefers_high_depth = gsk_render_node_prefers_high_depth (children[0]);
node->preferred_depth = gdk_memory_depth_merge (node->preferred_depth,
gsk_render_node_get_preferred_depth (children[0]));
for (guint i = 1; i < n_children; i++)
{
self->children[i] = gsk_render_node_ref (children[i]);
self->disjoint = self->disjoint && !graphene_rect_intersection (&bounds, &(children[i]->bounds), NULL);
graphene_rect_union (&bounds, &(children[i]->bounds), &bounds);
node->prefers_high_depth = node->prefers_high_depth || gsk_render_node_prefers_high_depth (children[i]);
node->preferred_depth = gdk_memory_depth_merge (node->preferred_depth,
gsk_render_node_get_preferred_depth (children[i]));
node->offscreen_for_opacity = node->offscreen_for_opacity || children[i]->offscreen_for_opacity;
}
@@ -3478,7 +3482,7 @@ gsk_transform_node_new (GskRenderNode *child,
&child->bounds,
&node->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -3630,7 +3634,7 @@ gsk_opacity_node_new (GskRenderNode *child,
graphene_rect_init_from_rect (&node->bounds, &child->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -3698,8 +3702,7 @@ gsk_color_matrix_node_finalize (GskRenderNode *node)
static void
apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset,
gboolean multiply_alpha)
const graphene_vec4_t *color_offset)
{
cairo_surface_t *surface, *image_surface;
guchar *data;
@@ -3737,13 +3740,6 @@ apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
graphene_matrix_transform_vec4 (color_matrix, &pixel, &pixel);
}
if (multiply_alpha)
graphene_vec4_init (&pixel,
graphene_vec4_get_x (&pixel),
graphene_vec4_get_y (&pixel),
graphene_vec4_get_z (&pixel),
alpha * graphene_vec4_get_w (&pixel));
graphene_vec4_add (&pixel, color_offset, &pixel);
alpha = graphene_vec4_get_w (&pixel);
@@ -3766,6 +3762,8 @@ apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
cairo_surface_mark_dirty (image_surface);
cairo_surface_unmap_image (surface, image_surface);
/* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */
cairo_surface_mark_dirty (surface);
}
static void
@@ -3787,7 +3785,7 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
pattern = cairo_pop_group (cr);
apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset, FALSE);
apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset);
cairo_set_source (cr, pattern);
cairo_paint (cr);
@@ -3868,7 +3866,7 @@ gsk_color_matrix_node_new (GskRenderNode *child,
graphene_rect_init_from_rect (&node->bounds, &child->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -3956,27 +3954,29 @@ gsk_repeat_node_draw (GskRenderNode *node,
cairo_pattern_t *pattern;
cairo_surface_t *surface;
cairo_t *surface_cr;
double scale_x, scale_y, width, height;
cairo_matrix_t matrix;
cairo_get_matrix (cr, &matrix);
width = ceil (self->child_bounds.size.width * (ABS (matrix.xx) + ABS (matrix.yx)));
height = ceil (self->child_bounds.size.height * (ABS (matrix.xy) + ABS (matrix.yy)));
surface = cairo_surface_create_similar (cairo_get_target (cr),
CAIRO_CONTENT_COLOR_ALPHA,
ceilf (self->child_bounds.size.width),
ceilf (self->child_bounds.size.height));
width, height);
cairo_surface_get_device_scale (surface, &scale_x, &scale_y);
scale_x *= width / self->child_bounds.size.width;
scale_y *= height / self->child_bounds.size.height;
cairo_surface_set_device_scale (surface, scale_x, scale_y);
cairo_surface_set_device_offset (surface,
- self->child_bounds.origin.x * scale_x,
- self->child_bounds.origin.y * scale_y);
surface_cr = cairo_create (surface);
cairo_translate (surface_cr,
- self->child_bounds.origin.x,
- self->child_bounds.origin.y);
gsk_render_node_draw (self->child, surface_cr);
cairo_destroy (surface_cr);
pattern = cairo_pattern_create_for_surface (surface);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
cairo_pattern_set_matrix (pattern,
&(cairo_matrix_t) {
.xx = 1.0,
.yy = 1.0,
.x0 = - self->child_bounds.origin.x,
.y0 = - self->child_bounds.origin.y
});
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
cairo_surface_destroy (surface);
@@ -4033,7 +4033,7 @@ gsk_repeat_node_new (const graphene_rect_t *bounds,
else
graphene_rect_init_from_rect (&self->child_bounds, &child->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -4181,7 +4181,7 @@ gsk_clip_node_new (GskRenderNode *child,
graphene_rect_intersection (&self->clip, &child->bounds, &node->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -4329,7 +4329,7 @@ gsk_rounded_clip_node_new (GskRenderNode *child,
graphene_rect_intersection (&self->clip.bounds, &child->bounds, &node->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -4571,7 +4571,7 @@ gsk_shadow_node_new (GskRenderNode *child,
gsk_shadow_node_get_bounds (self, &node->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -4781,7 +4781,8 @@ gsk_blend_node_new (GskRenderNode *bottom,
graphene_rect_union (&bottom->bounds, &top->bounds, &node->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (bottom) || gsk_render_node_prefers_high_depth (top);
node->preferred_depth = gdk_memory_depth_merge (gsk_render_node_get_preferred_depth (bottom),
gsk_render_node_get_preferred_depth (top));
return node;
}
@@ -4946,7 +4947,8 @@ gsk_cross_fade_node_new (GskRenderNode *start,
graphene_rect_union (&start->bounds, &end->bounds, &node->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (start) || gsk_render_node_prefers_high_depth (end);
node->preferred_depth = gdk_memory_depth_merge (gsk_render_node_get_preferred_depth (start),
gsk_render_node_get_preferred_depth (end));
return node;
}
@@ -5574,7 +5576,7 @@ gsk_blur_node_new (GskRenderNode *child,
- clip_radius,
- clip_radius);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -5636,9 +5638,56 @@ static void
gsk_mask_node_finalize (GskRenderNode *node)
{
GskMaskNode *self = (GskMaskNode *) node;
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_MASK_NODE));
gsk_render_node_unref (self->source);
gsk_render_node_unref (self->mask);
parent_class->finalize (node);
}
static void
apply_luminance_to_pattern (cairo_pattern_t *pattern,
gboolean invert_luminance)
{
cairo_surface_t *surface, *image_surface;
guchar *data;
gsize x, y, width, height, stride;
int red, green, blue, alpha, luminance;
guint32* pixel_data;
cairo_pattern_get_surface (pattern, &surface);
image_surface = cairo_surface_map_to_image (surface, NULL);
data = cairo_image_surface_get_data (image_surface);
width = cairo_image_surface_get_width (image_surface);
height = cairo_image_surface_get_height (image_surface);
stride = cairo_image_surface_get_stride (image_surface);
for (y = 0; y < height; y++)
{
pixel_data = (guint32 *) data;
for (x = 0; x < width; x++)
{
alpha = (pixel_data[x] >> 24) & 0xFF;
red = (pixel_data[x] >> 16) & 0xFF;
green = (pixel_data[x] >> 8) & 0xFF;
blue = (pixel_data[x] >> 0) & 0xFF;
luminance = 2126 * red + 7152 * green + 722 * blue;
if (invert_luminance)
luminance = 10000 * alpha - luminance;
luminance = (luminance + 5000) / 10000;
pixel_data[x] = luminance * 0x1010101;
}
data += stride;
}
cairo_surface_mark_dirty (image_surface);
cairo_surface_unmap_image (surface, image_surface);
/* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */
cairo_surface_mark_dirty (surface);
}
static void
@@ -5663,28 +5712,18 @@ gsk_mask_node_draw (GskRenderNode *node,
case GSK_MASK_MODE_ALPHA:
break;
case GSK_MASK_MODE_INVERTED_ALPHA:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, -1 });
graphene_vec4_init (&color_offset, 0, 0, 0, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, FALSE);
graphene_matrix_init_from_float (&color_matrix, (float[]){ 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
-1, -1, -1, -1 });
graphene_vec4_init (&color_offset, 1, 1, 1, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset);
break;
case GSK_MASK_MODE_LUMINANCE:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, 0.2126,
0, 1, 0, 0.7152,
0, 0, 1, 0.0722,
0, 0, 0, 0 });
graphene_vec4_init (&color_offset, 0, 0, 0, 0);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, TRUE);
apply_luminance_to_pattern (mask_pattern, FALSE);
break;
case GSK_MASK_MODE_INVERTED_LUMINANCE:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, -0.2126,
0, 1, 0, -0.7152,
0, 0, 1, -0.0722,
0, 0, 0, 0 });
graphene_vec4_init (&color_offset, 0, 0, 0, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, TRUE);
apply_luminance_to_pattern (mask_pattern, TRUE);
break;
default:
g_assert_not_reached ();
@@ -5694,6 +5733,8 @@ gsk_mask_node_draw (GskRenderNode *node,
cairo_clip (cr);
cairo_mask (cr, mask_pattern);
cairo_pattern_destroy (mask_pattern);
}
static void
@@ -5704,6 +5745,12 @@ gsk_mask_node_diff (GskRenderNode *node1,
GskMaskNode *self1 = (GskMaskNode *) node1;
GskMaskNode *self2 = (GskMaskNode *) node2;
if (self1->mask_mode != self2->mask_mode)
{
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
gsk_render_node_diff (self1->source, self2->source, region);
gsk_render_node_diff (self1->mask, self2->mask, region);
}
@@ -5754,7 +5801,7 @@ gsk_mask_node_new (GskRenderNode *source,
self->render_node.bounds = source->bounds;
self->render_node.prefers_high_depth = gsk_render_node_prefers_high_depth (source);
self->render_node.preferred_depth = gsk_render_node_get_preferred_depth (source);
return &self->render_node;
}
@@ -5920,7 +5967,7 @@ gsk_debug_node_new (GskRenderNode *child,
graphene_rect_init_from_rect (&node->bounds, &child->bounds);
node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
@@ -6103,7 +6150,8 @@ gsk_gl_shader_node_new (GskGLShader *shader,
for (guint i = 0; i < n_children; i++)
{
self->children[i] = gsk_render_node_ref (children[i]);
node->prefers_high_depth = node->prefers_high_depth || gsk_render_node_prefers_high_depth (children[i]);
node->preferred_depth = gdk_memory_depth_merge (node->preferred_depth,
gsk_render_node_get_preferred_depth (children[i]));
}
}
+45 -8
View File
@@ -453,6 +453,21 @@ parse_double (GtkCssParser *parser,
return gtk_css_parser_consume_number (parser, out_double);
}
static gboolean
parse_positive_double (GtkCssParser *parser,
Context *context,
gpointer out_double)
{
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_NUMBER)
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_INTEGER))
{
gtk_css_parser_error_syntax (parser, "Expected a positive number");
return FALSE;
}
return gtk_css_parser_consume_number (parser, out_double);
}
static gboolean
parse_point (GtkCssParser *parser,
Context *context,
@@ -1242,10 +1257,10 @@ parse_radial_gradient_node_internal (GtkCssParser *parser,
const Declaration declarations[] = {
{ "bounds", parse_rect, NULL, &bounds },
{ "center", parse_point, NULL, &center },
{ "hradius", parse_double, NULL, &hradius },
{ "vradius", parse_double, NULL, &vradius },
{ "start", parse_double, NULL, &start },
{ "end", parse_double, NULL, &end },
{ "hradius", parse_positive_double, NULL, &hradius },
{ "vradius", parse_positive_double, NULL, &vradius },
{ "start", parse_positive_double, NULL, &start },
{ "end", parse_positive_double, NULL, &end },
{ "stops", parse_stops, clear_stops, &stops },
};
GskRenderNode *result;
@@ -1335,7 +1350,7 @@ parse_inset_shadow_node (GtkCssParser *parser,
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_double, NULL, &blur }
{ "blur", parse_positive_double, NULL, &blur }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
@@ -1737,7 +1752,7 @@ parse_outset_shadow_node (GtkCssParser *parser,
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_double, NULL, &blur }
{ "blur", parse_positive_double, NULL, &blur }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
@@ -2017,7 +2032,7 @@ parse_blur_node (GtkCssParser *parser,
GskRenderNode *child = NULL;
double blur_radius = 1.0;
const Declaration declarations[] = {
{ "blur", parse_double, NULL, &blur_radius },
{ "blur", parse_positive_double, NULL, &blur_radius },
{ "child", parse_node, clear_node, &child },
};
GskRenderNode *result;
@@ -2477,6 +2492,15 @@ printer_init (Printer *self,
printer_init_duplicates_for_node (self, node);
}
static void
printer_clear (Printer *self)
{
if (self->str)
g_string_free (self->str, TRUE);
g_hash_table_unref (self->named_nodes);
g_hash_table_unref (self->named_textures);
}
#define IDENT_LEVEL 2 /* Spaces per level */
static void
_indent (Printer *self)
@@ -2892,6 +2916,14 @@ append_texture_param (Printer *p,
case GDK_MEMORY_R16G16B16:
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_G8A8_PREMULTIPLIED:
case GDK_MEMORY_G8A8:
case GDK_MEMORY_G8:
case GDK_MEMORY_G16A16_PREMULTIPLIED:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_G16:
case GDK_MEMORY_A8:
case GDK_MEMORY_A16:
bytes = gdk_texture_save_to_png_bytes (texture);
g_string_append (p->str, "url(\"data:image/png;base64,");
break;
@@ -3678,6 +3710,7 @@ GBytes *
gsk_render_node_serialize (GskRenderNode *node)
{
Printer p;
GBytes *res;
printer_init (&p, node);
@@ -3697,5 +3730,9 @@ gsk_render_node_serialize (GskRenderNode *node)
render_node_print (&p, node);
}
return g_string_free_to_bytes (p.str);
res = g_string_free_to_bytes (g_steal_pointer (&p.str));
printer_clear (&p);
return res;
}

Some files were not shown because too many files have changed in this diff Show More