Compare commits

...

161 Commits

Author SHA1 Message Date
Matthias Clasen d4dfbc1def gtk-demo: Add filters to the zoom demo 2023-02-07 19:45:07 -05:00
Matthias Clasen fb73acc885 gtk-demo: Rewrite the zoom demo slightly
Use a texture directly instead of a paintable.
This will be used in the following commit to
introduce filters.
2023-02-07 19:45:07 -05:00
Matthias Clasen acad0e8893 gsk: Use filters from texture nodes 2023-02-07 19:45:07 -05:00
Matthias Clasen d869aec29f gsk: Add filters to texture nodes
Allow specifying the min and mag filters when
creating texture nodes.

Fixes: #5563
Fixes: #3524
2023-02-07 19:44:16 -05:00
Matthias Clasen aae99a8704 gsk: Pass filters down from visit_texture_node
For now, we always pass GL_LINEAR.
2023-02-07 19:39:46 -05:00
Matthias Clasen 19ba03d0a6 gsk: Generate mipmaps when requested
If the min_filter requires it, call
glGenerateMipmap for our textures.
2023-02-07 19:39:46 -05:00
Matthias Clasen ac59d553ce gsk: Don't limit filters too much
GL does not allow mipmapping for mag filters,
but it doesn't have a problem with it for min
filters.
2023-02-07 19:39:46 -05:00
Matthias Clasen 9991d6834d Merge branch 'stop-testing-pixbuf-formats' into 'main'
Drop pixbuf format tests

See merge request GNOME/gtk!5486
2023-02-07 18:48:39 +00:00
Matthias Clasen ddf8c4dd1a Drop pixbuf format tests
We have our own loaders for the formats we
always want to support, so we don't need to
check for what gdk-pixbuf supports.
2023-02-07 07:54:22 -05:00
Matthias Clasen 970072ef65 Merge branch 'file-dialog-fixes' into 'main'
filedialog: Robustness fixes

See merge request GNOME/gtk!5485
2023-02-07 12:42:09 +00:00
Matthias Clasen f8321029fc filedialog: Robustness fixes
This code was not working well.
2023-02-06 23:16:17 +01:00
Matthias Clasen f83cab01ec filechooserportal: Fix an oversight 2023-02-06 20:28:35 +01:00
Sabri Ünal 8a74770ec1 Update Turkish translation 2023-02-06 09:19:35 +00:00
Matthias Clasen 39c503c108 Merge branch 'matthiasc/for-main' into 'main'
CONTRIBUTING: Updates

See merge request GNOME/gtk!5483
2023-02-06 06:53:14 +00:00
Matthias Clasen fc32b8242b CONTRIBUTING: Updates
Mention matrix instead of irc, and ask
for display/graphics as essential info
in issues.
2023-02-06 07:35:11 +01:00
Piotr Drąg 7c2b4eb0e7 Update Polish translation 2023-02-05 15:22:00 +01:00
Matthias Clasen d8b0aea6b7 Merge branch 'rename-openuri-portal' into 'main'
Use a Gtk prefix for dbus-generated code

Closes #5572

See merge request GNOME/gtk!5482
2023-02-05 08:27:09 +00:00
Matthias Clasen 190d8ef8ff Use a Gtk prefix for dbus-generated code
Copying this file from GIO without renaming it
was not the greatest idea in retrospect.

Fixes: #5572
2023-02-05 09:09:22 +01:00
Cheng-Chia Tseng 15e9194b59 Update Chinese (Taiwan) translation 2023-02-04 16:28:15 +00:00
Matthias Clasen 0257da6cc0 Post-release version bump 2023-02-04 17:01:51 +01:00
Matthias Clasen 907f878c9f make-release: Explicily enable introspection 2023-02-04 16:31:55 +01:00
Matthias Clasen b2071cdeb5 4.9.3 2023-02-04 16:16:54 +01:00
Matthias Clasen 1a292bf8ab Merge branch 'wip/carlosg/scroll-fix' into 'main'
gdk/x11: Reset all scroll valuators on enter

Closes #4160

See merge request GNOME/gtk!5479
2023-02-04 13:14:02 +00:00
Matthias Clasen 7e07d63a6c Merge branch 'ebassi/stack-at-context' into 'main'
a11y: Clear the GtkATContext in a single step

See merge request GNOME/gtk!5477
2023-02-04 12:37:20 +00:00
Carlos Garnacho 824e983372 gdk/x11: Reset all scroll valuators on enter
We no longer need to make much distinction between multiple logical
devices, plus it breaks esp. with the Xwayland input device distribution.
Just iterate across all devices and reset their scroll valuators.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4160
2023-02-04 13:13:19 +01:00
Matthias Clasen 9e5417c6c7 Merge branch 'wip/carlosg/wayland-device-refactor' into 'main'
Refactor some wayland code

See merge request GNOME/gtk!5473
2023-02-04 07:48:33 +00:00
Matthias Clasen e94dae8536 Merge branch 'rgba-free-checked' into 'main'
gtktextview: Avoid calling gdk_rgba_free for NULL values

See merge request GNOME/gtk!5474
2023-02-04 07:48:24 +00:00
Matthias Clasen 0dd163254d Merge branch 'ebassi/accessible-editable' into 'main'
a11y: Simplify GtkAccessible implementation for editables

See merge request GNOME/gtk!5475
2023-02-04 07:47:36 +00:00
Emmanuele Bassi 341ecab41a a11y: Clear the GtkATContext in a single step
There's no need to unrealize the GtkATContext inside dispose() and then
drop its reference inside finalize().
2023-02-03 17:11:22 +01:00
Marco Trevisan (Treviño) 9eac7ed8b9 gtktextview: Avoid calling gdk_rgba_free for NULL values
Related to glib#2908
2023-02-03 16:41:56 +01:00
Carlos Garnacho 4005eb8fe8 gdk/wayland: Rename gdkkeys-wayland.c file
Since it contains the GdkKeymap implementation, give it a more
obvious name.
2023-02-03 16:15:34 +01:00
Carlos Garnacho 1d4ceac2c5 gdk/wayland: "Split" GdkWaylandDevice implementation out
This is a bit spaghetti right now, since seats and devices were
heavily entangled there are a number of crossed private API calls that
should ideally not be there.

Let this be a first step, so more bits may move from the seat
implementation to devices.
2023-02-03 16:15:34 +01:00
Carlos Garnacho a5246a6856 gdk/wayland: Split GdkDevicePad wayland implementation
This now lives in its own C file.
2023-02-03 16:08:07 +01:00
Lukáš Tyrychtr 11d235d165 a11y: Simplify GtkAccessible implementation for editables
This commit implements the idea brought up in #5032, and provides a
simple function for GtkEditable implementations using a delegate object.
The accessible state is proxied from the outher GtkEditable to the
delegate.
2023-02-03 16:08:06 +01:00
Carlos Garnacho af00beb772 gdk/wayland: Move struct declarations to header
These will be used from outside the main file, after we are
done splitting it.
2023-02-03 16:00:01 +01:00
Carlos Garnacho e5cd9354d5 gdk/wayland: Move GdkWaylandDevice data to private struct
Before splitting this object, avoid leaking details in its struct.
2023-02-03 15:58:11 +01:00
Carlos Garnacho 6426ab7466 gdk/wayland: Rename gdkdevice-wayland.c to gdkseat-wayland.c
This file, event though a clump of input-y objects, has more of
seats than anything else. Rename it so that we can start splitting
these objects out of it.
2023-02-03 15:58:11 +01:00
Matthias Clasen b710df6f45 Merge branch 'file-chooser-context-menu' into 'main'
filechooser: Fix context menus

Closes #5554

See merge request GNOME/gtk!5472
2023-02-03 13:39:21 +00:00
Matthias Clasen 50998b0ee9 Merge branch 'drag-icon-robustness' into 'main'
dragicon: Handle files without info

See merge request GNOME/gtk!5460
2023-02-03 13:19:26 +00:00
Matthias Clasen 92c2c68c7b filechooser: Fix context menus
We only want to show the file list context menu
when we are over the file list.

Fixes: #5554
2023-02-03 14:17:34 +01:00
Matthias Clasen c2f5b64b5d Merge branch 'ebassi/public-accessible' into 'main'
Make GtkAccessible public

Closes #4240

See merge request GNOME/gtk!5470
2023-02-03 11:31:06 +00:00
Matthias Clasen 460bf6d8b9 inspector: Show if accessibles aren't realized
This prevents confusion and makes it clear
what is going on.
2023-02-03 11:49:17 +01:00
Emmanuele Bassi a0dff87c86 a11y: Documentation and code style fixes 2023-02-03 11:49:17 +01:00
Emmanuele Bassi 3015b9f120 a11y: Fix get_bounds() implementation
Don't allocate graphene_rect_t, and fix the size retrieval.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 01549e3c91 Take the widget transform into account when computing the bounds for a11y 2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr bc48bfc2b6 a11y: Use a DOM-like API for iterating accessible objects
The `get_child_at_index()` API model comes from AT-SPI, and it's not an
efficient design, especially when coupled with large widgets.

Replace `get_child_at_index()` with `get_first_accessible_child()` and
`get_next_accessible_sibling()`.

That allows efficiently retrieving all the children, simplifies the
implementation of GtkAccessible in GtkWidget and closely resembeles the
GtkWidget API.

Getting the last child and previous sibling for iterating backwards is
not a part of the interface at the moment, but they can be added at a
later date.

Note that this change required tracking the next stack page in
GtkStackPage.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 6100258ba2 a11y: Rename GtkAccessible.get_parent
Avoid a collision when the type implementing the GtkAccessible interface
already has a `get_parent()` method—like GtkWidget.
2023-02-03 11:49:17 +01:00
Emmanuele Bassi e083bd7920 Apply trivial review suggestions 2023-02-03 11:49:17 +01:00
Emmanuele Bassi e915546b44 Add versioned symbol annotations 2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr b6cfe35940 Style fixes
Documentation and coding style updates.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 4cd9fd9b15 stack: Use a pointer array for children
Reduce our dependency on linked lists; pointer arrays are better at
cache locality.

Additionally, we can avoid quadratic behaviors when finding a child at a
given index.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 6f8cab0e9d Style fix 2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 6eb9161906 Improve documentation 2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr d13695f586 a11y: Implement new GtkAccessible vfuncs in GtkStack
Implement the virtual a11y children for GtkStack.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 749919c551 Update API docs 2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 58980e0b4a Make GtkAccessible public
Out of tree classes need to be able to implement the GtkAccessible
interface, in order to implement custom accessible objects.

Fixes: #4240
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 5813a5cace a11y: Add bounds rectangle to GtkAccessible
Make the bounds calculation part of the accessible interface.

Bounds are used by ATs like Orca to implement features like Flat Review:

https://help.gnome.org/users/orca/stable/howto_flat_review.html.en

Or to determine the area of a non-presentational widget.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr f88b777fe5 widget: Implement new GtkAccessible vfuncs 2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr a80af681b8 a11y: Skip non-presentable objects
Don't get confused with non-presentable objects when iterating the list
of children.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 94695bb276 a11y: Use GtkAccessible for tree traversal
Remove the widget tree dependence from GtkAtSpiContext.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr be36113826 a11y: Implement the new GtkAccessible vfuncs
Implement the gtk_accessible functions and begin removing the old widget
based tree calls.
2023-02-03 11:49:17 +01:00
Lukáš Tyrychtr 5dfbaa53fc a11y: Add DOM-like API to GtkAccessible
Add get_parent and get_child_at_index to GtkAccessible so we can
decouple the a11y tree from the widget tree.
2023-02-03 11:49:17 +01:00
Matthias Clasen a13ddcb67b Merge branch 'filechooser-sidebar' into 'main'
placessidebar: Make all rows ellipsize

Closes #4710

See merge request GNOME/gtk!5471
2023-02-03 09:41:21 +00:00
Carlos Garnacho d228bae365 Merge branch 'drag-button-issue' into 'main'
Fix button mask calculation for Wayland

Closes #5561

See merge request GNOME/gtk!5468
2023-02-03 09:28:01 +00:00
Matthias Clasen 463f12a3bb placessidebar: Make all rows ellipsize
Otherwise, we end up with a single long row
pushing the content of all the other rows
off to the left, which is much worse than
ellipsizing.

Fixes: #4710
2023-02-03 10:00:03 +01:00
Matthias Clasen 3f87b130ba NEWS: Updates 2023-02-03 09:26:50 +01:00
Benjamin Otte c17049c6d1 Merge branch 'wip/otte/gl-is-current' into 'main'
gdk: Add private GLContext::is_current() check

Closes #5392

See merge request GNOME/gtk!5463
2023-02-02 21:56:32 +00:00
Arjan Molenaar f000baf0d6 wayland: Fix button mask for button 2 and 3
Wayland and GTK order mouse button 2 and 3 differently.

Fixes #5561.
2023-02-02 21:48:58 +01:00
Arjan Molenaar aef4c50155 Allow all mouse buttons to be used for the drawingarea demo
So we can test if the drag gesture works with all mouse buttons.
2023-02-02 21:29:45 +01:00
Matthias Clasen 2a1e4b8621 Merge branch 'matthiasc/for-main' into 'main'
Matthiasc/for main

See merge request GNOME/gtk!5467
2023-02-02 17:36:44 +00:00
Matthias Clasen cabd18fba0 textbtree: Fix a compiler warning 2023-02-02 17:15:28 +01:00
Matthias Clasen 1da4782262 gsk: Fix a compiler warning 2023-02-02 17:15:28 +01:00
Matthias Clasen 8911ed5d9b Merge branch 'monitor-description' into 'main'
Add GdkMonitor::description

See merge request GNOME/gtk!5466
2023-02-02 14:12:23 +00:00
Matthias Clasen 294b659dc1 Merge branch 'wip/carlosg/deprecations' into 'main'
Some deprecations and cleanups

See merge request GNOME/gtk!5465
2023-02-02 14:11:58 +00:00
Carlos Garnacho 7ad74ad6c3 gdk/wayland: Deprecate GdkDisplay windowing-specific for startup IDs
This is currently just used as a convenience storage of the startup ID
between the GtkApplication and the GtkWindow (after it's ready to notify
on it).

This could be untangled in the GTK layers so there is no involvement
from GDK in keeping the startup ID around, in the mean time just deprecate
these gdk_wayland* API calls.
2023-02-02 12:50:59 +01:00
Carlos Garnacho bb777507ce gtkmodelbutton: Avoid gtk_gesture_set_sequence_state()
It is not necessary for this widget to know about the specific
sequence that is interacting.
2023-02-02 12:50:59 +01:00
Carlos Garnacho 1e1d79d4f7 gtktextview: Avoid gtk_gesture_set_sequence_state()
Use gtk_gesture_set_state() as this widget does not need specific
knowledge on the sequence being used for interaction.
2023-02-02 12:50:59 +01:00
Carlos Garnacho a254a4529f gtkscrolledwindow: Clean up input handling a bit
These pieces were added in commit 8d2f81cca4, but are no longer
necessary since there's no capture_button_press special behavior
toggle.

This can be simplified again.
2023-02-02 12:50:59 +01:00
Matthias Clasen e7bd691532 inspector: Show monitor descriptions 2023-02-02 12:32:28 +01:00
Matthias Clasen 4e62350232 wayland: Set up monitor descriptions
We get this information in the xdg_output protocol.
2023-02-02 12:32:28 +01:00
Matthias Clasen 2c883a70e2 Add GdkMonitor::description
This is the right string to when showing
monitors in the UI.
2023-02-02 12:32:28 +01:00
Matthias Clasen 3dfeb2fd37 monitor: Document connector names better 2023-02-02 12:32:28 +01:00
Carlos Garnacho 3ba3e8286f gtkwindowhandle: Refactor click handling a bit
Do not get a GdkEvent first and foremost, and only do that in the
parts where the GdkEvent is absolutely necessary (i.e. popping up
the WM menu for the window).
2023-02-02 11:21:22 +01:00
Carlos Garnacho fbf4817ef5 gtkgesture: Deprecate gtk_gesture_set_sequence_state()
We can abstract widgets about the specific ongoing sequences that
are triggering a GtkGesture. This used to be more necessary in
GTK3 world where complex widgets might have required handling
different events in different areas, but in GTK4 world that would
be done with multiple widgets.

This is no longer necessary to carry forward.
2023-02-02 11:21:22 +01:00
Carlos Garnacho db43e0669f gtkscrolledwindow: Avoid gtk_gesture_set_sequence_state()
This widget does not require special knowledge about the ongoing
event sequences, just make it use gtk_gesture_set_state() generically.
2023-02-02 11:21:22 +01:00
Carlos Garnacho 386c77b13d gtkwindowhandle: Avoid gtk_gesture_set_sequence_state()
It does not require special knowledge about the ongoing event
sequences, and it can instead trust the event controller. Make
it use gtk_gesture_set_state() generically.
2023-02-02 11:21:21 +01:00
Matthias Clasen e6998dffe8 Merge branch 'small-gltexture-cleanup' into 'main'
gltexture: Small refactoring

See merge request GNOME/gtk!5464
2023-02-02 09:16:09 +00:00
Matthias Clasen 12057c8a30 gltexture: Small refactoring
We do this in two places, so factor out
the dropping of GL resources into a helper.
2023-02-02 10:01:36 +01:00
Matthias Clasen b7c422cb98 ci: Stop running the asan build every time
It fails because of address sanitizer crashes,
and takes a long time. It is not that useful
in this shape.
2023-02-02 09:07:10 +01:00
Matthias Clasen 1c76f6586b Update po/POTFILES.in
Deprecations affect this file.
2023-02-02 09:05:31 +01:00
Matthias Clasen d43968f7b6 Fix a deprecation warning 2023-02-02 09:03:26 +01:00
Matthias Clasen 26650787e1 main: Compiler warnin gfixes 2023-02-02 08:44:53 +01:00
Matthias Clasen b4ef072188 icontheme: Compiler warning fixes 2023-02-02 08:44:28 +01:00
Matthias Clasen 3858c5282c Deprecate GtkAssistant
It is a dialog-like toplevel, and libadwaita has
replacement parts (like AdwCarousel).
2023-02-02 08:39:25 +01:00
Matthias Clasen 1ff8dad8ec Deprecate GtkLockButton
This is a very specialized widget, and should really just
live with the applications where it is used.
2023-02-02 08:39:25 +01:00
Matthias Clasen d8cb11ec4a Deprecate GtkStatusbar
The design patterns using statusbar are no longer popular,
and it is pretty easy to make a statusbar yourself with boxes
and labels, if you need one. The only thing special about
GtkStatusbar was its window resize handle, but that has
been gone for a long time.
2023-02-02 08:39:24 +01:00
Matthias Clasen 8796950651 Deprecate more startup-notification API 2023-02-02 08:30:32 +01:00
Benjamin Otte c6cef6db52 gdk: Add private GLContext::is_current() check
... and use this check in gdk_gl_context_make_current() and
gdk_gl_context_get_current() to make sure the context really is still
current.

The context no longer being current can happen when external GL
implementations make their own contexts current in the same threads GDK
contexts are used in.
And that can happen for example by WebKit.

Theoretically, this should also allow external EGL code to run in X11
applications when GDK chooses to use GLX, but I didn't try it.

Fixes #5392
2023-02-02 04:23:51 +01:00
Benjamin Otte fdea27c04d win32: Remove unused variable 2023-02-02 04:23:51 +01:00
Fran Dieguez a52f9d6def Update Galician translation 2023-02-01 19:12:29 +00:00
Benjamin Otte ee272646c9 Merge branch 'fix-gltexture-confusion' into 'main'
gltexture: Use the right context

See merge request GNOME/gtk!5461
2023-02-01 18:47:28 +00:00
Matthias Clasen 6655177a0b Cosmetics 2023-02-01 18:38:22 +01:00
Daniel Mustieles cb78f0d10a Update Spanish translation 2023-02-01 15:28:00 +00:00
Matthias Clasen 1cb621633c gltexture: Use the right context
When checking characteristics of the context
for downloading, we were using self->context,
even though we are using a possibly different
context for downloading.

Pass the right context along and use it.
2023-02-01 11:32:07 +01:00
Kukuh Syafaat ce25efeee7 Update Indonesian translation 2023-02-01 03:14:46 +00:00
Matthias Clasen 375b554924 Merge branch 'fix-gst-sync' into 'main'
gst: Fix synchronization

See merge request GNOME/gtk!5459
2023-01-31 12:28:27 +00:00
Matthias Clasen 69eed999bb gst: Rename a field for clarity
gst_gdk_context is clearer than gst_app_context. Maybe
2023-01-30 15:01:31 -05:00
Matthias Clasen cab5f2bd8d Merge branch 'file-chooser-dnd-crash' into 'main'
filechooserwidget: Fix file chooser crash when dropping empty file list

See merge request GNOME/gtk!5456
2023-01-30 19:28:24 +00:00
Fina Wilke 35e3c22832 filechooserwidget: Fix file chooser crash when dropping empty file list 2023-01-30 19:28:24 +00:00
Matthias Clasen 92612c2265 filetransfer: Be more careful around files
File may not have paths, and we should handle
that without incident. While we are at it, add
some logging so GDK_DEBUG=dnd gives us enough
output to see what is going on.
2023-01-30 14:03:13 -05:00
Matthias Clasen 4e1b46a7ec dragicon: Handle files without info
g_file_query_info can (and does) fail,
occasionally. Handle it.
2023-01-30 14:03:13 -05:00
Matthias Clasen 55f7f7d0ee gst: Fix synchronization
It does not make sense to sync and wait in the
same context, that is just a no-op. The intention
of this code clearly was to sync in the gst
context, and wait in the gdk one.

That also matches what the gtk sink implementation
in gstreamer does.
2023-01-30 12:04:49 -05:00
Matthias Clasen 442cd4a369 Merge branch 'password-entry-unrealize' into 'main'
passwordentry: Fix an asymmetry

Closes #5285

See merge request GNOME/gtk!5457
2023-01-30 12:29:33 +00:00
Matthias Clasen 53af41e2fa passwordentry: Fix an asymmetry
When connecting a signal in realize,
we should disconnect in unrealize.

Fixes: #5285
2023-01-29 22:39:28 -05:00
Matthias Clasen c43e1f3d0a gsk: Quiet a compiler warning 2023-01-28 21:13:10 -05:00
Jürgen Benvenuti 32e855ad61 Update German translation 2023-01-28 19:59:19 +00:00
Benjamin Otte 034a8a5501 Merge branch 'tooltip-size-simplification' into 'main'
tooltip: Don't play games with max-width-chars

Closes #4470 and #5521

See merge request GNOME/gtk!5455
2023-01-28 18:26:00 +00:00
Matthias Clasen 1e9dbf2df0 tooltip: Prevent too-wide tooltip windows
Set the label to expand, so it actually fills
the width that we allocated for it, instead
of shrinking back to the minimum width for
its height.

Fixes: #5521
2023-01-28 13:07:26 -05:00
Matthias Clasen dce21f06dd tooltip: Don't play games with max-width-chars
Setting max-width-chars to the number of characters
in the string works ok only as long as the average
char width we get from Pango matches reality. Sadly
that seems not always the case, and this code was
causing short Chinese tooltips to always be broken
into two lines.

Fixes: #4470
2023-01-28 13:06:30 -05:00
Piotr Drąg 56c1c4152f Update POTFILES.in 2023-01-28 14:05:01 +01:00
Matthias Clasen a9d2fa296e Merge branch 'position-as-double' into 'main'
Boyscouting: fix position type in `gtk_drag_source_drag_begin()`

See merge request GNOME/gtk!5437
2023-01-28 03:24:19 +00:00
Carlos Garnacho 5bccb106c2 Merge branch 'work/zzag/activation-token-dbus' into 'main'
wayland: Fix handling of activation-token in org.freedesktop.Application requests

See merge request GNOME/gtk!5151
2023-01-28 00:44:25 +00:00
Yuri Chornoivan 45086487f1 Update Ukrainian translation 2023-01-27 19:23:39 +00:00
Vlad Zahorodnii 65f03121a4 wayland: Fix handling of activation-token in org.freedesktop.Application requests
At the moment, GTK applications search for "desktop-startup-id" in the
platform data on Wayland , but desktop environments such as plasma set
"activation-token" property instead as indicated in the spec:

    activation-token: This should be a string of the same value as would
    be stored in the XDG_ACTIVATION_TOKEN environment variable, as specified
    by the XDG Activation protocol for Wayland.

https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#dbus
2023-01-27 19:20:53 +00:00
Carlos Garnacho 09769193d7 Merge branch 'wip/carlosg/broadway-fix' into 'main'
gdk/broadway: Add deprecation guards around gdk_display_put_event()

See merge request GNOME/gtk!5450
2023-01-27 19:20:28 +00:00
Carlos Garnacho 7f8acf960b gdk/broadway: Add deprecation guards around gdk_display_put_event()
This went missing.
2023-01-27 19:59:36 +01:00
Matthias Clasen ee0e026237 Merge branch 'fix_5551' into 'main'
object_tree.c: One gtk_list_item_get_child call is redundant

Closes #5551

See merge request GNOME/gtk!5449
2023-01-27 16:22:17 +00:00
Matthias Clasen 6bfd581a72 Merge branch 'wip/sophie-h/scrolled-window-propagate-event' into 'main'
scrolledWindow: Propagate event for no scrolling

See merge request GNOME/gtk!5447
2023-01-27 14:54:33 +00:00
Lukáš Tyrychtr 7b6f254e64 object_tree.c: One gtk_list_item_get_child call is redundant
Fixes #5551
2023-01-27 15:43:33 +01:00
Hugo Carvalho 47955cfe62 Update Portuguese translation 2023-01-27 14:26:32 +00:00
Sophie Herold e62ca17f88 scrolledWindow: Propagate event for no scrolling 2023-01-26 20:12:10 +01:00
Matthias Clasen c24ba58acb Merge branch 'broadway-modal-hint' into 'main'
[GTK4] gdk/broadway: Implements modal hint for Broadway surface

See merge request GNOME/gtk!4428
2023-01-26 02:44:54 +00:00
Matthias Clasen 30987168fb Merge branch 'fix_5543' into 'main'
GtkCssProvider: fix element type in docs

Closes #5543

See merge request GNOME/gtk!5441
2023-01-25 13:08:07 +00:00
Lukáš Tyrychtr 93a875bf20 Actually, the annotation is not needed in this case 2023-01-25 11:46:53 +01:00
Yosef Or Boczko aac3bf581a Update Hebrew translation 2023-01-25 08:15:09 +00:00
Matthias Clasen 869f07521c Merge branch 'macos-fix-popups' into 'main'
macos: Fix popup event handling

Closes #5528

See merge request GNOME/gtk!5436
2023-01-24 16:37:23 +00:00
Matthias Clasen 7e392a1186 Merge branch 'wip/abono/gtk-switch-state-off' into 'main'
gtkswitch: Allow to set state FALSE while keeping active TRUE

See merge request GNOME/gtk!5442
2023-01-24 16:08:57 +00:00
Alessandro Bono 53d87e42a5 gtkswitch: Decouple set_state with set_active.
Allow the user to set a state that doesn't reflect the active property.
2023-01-24 14:55:16 +01:00
Arjan Molenaar 6757a1b409 macos: Propagate events for child surfaces
Before, popup windows did not respond to mouse clicks.
This change fixes that.

Fixes #5528.
2023-01-24 09:07:33 +01:00
Maxim Zakharov 115738dd2f remove unused variable 2023-01-24 11:41:27 +11:00
Matthias Clasen 5caa66ffb7 Merge branch 'macos-native-dnd' into 'main'
macos: DnD Drag support

Closes #3423

See merge request GNOME/gtk!5416
2023-01-23 22:01:30 +00:00
Emmanuele Bassi 7df73c4fd2 Use wording from a suggestion 2023-01-23 11:50:28 +00:00
Lukáš Tyrychtr 1ea5a08c8f GtkCssProvider: fix element type in docs
The method takes an array of char, which actually is UTF-8, so make the docs say so.
Fixes #5543
2023-01-23 12:12:00 +01:00
Matthias Clasen 9c669cbe90 Merge branch 'matthiasc/for-main' into 'main'
iconhelper: Handle GtkSymbolicPaintable

See merge request GNOME/gtk!5440
2023-01-22 18:36:11 +00:00
Matthias Clasen 1a5184bc85 iconhelper: Handle GtkSymbolicPaintable
If we are given a GtkSymbolicPaintable,
treat it as symbolic.
2023-01-22 13:18:18 -05:00
Arjan Molenaar d6ef39b9a2 macos: remove dead code 2023-01-21 15:22:13 +01:00
Arjan Molenaar 52f6acd398 macos: Send dragging events directly to the display
Instead of adding events to the application event queue, dispatch
them directly to the right display. We know this when the event is
to be dispatched.

This is the same as used for the `sendEvent` method in `GdkMacosWindow`.

To achieve this I factored out the generic NSEvent to GdkEvent translation.
We can send an event directly, when we receive it in the GdkMacosWindow
directly from the OS.
2023-01-21 14:54:12 +01:00
Arjan Molenaar 136c1ccd2c macos: Update event source doc
Update the documentation with the interaction pattern we
need to support DnD.
2023-01-17 16:37:21 +01:00
Arjan Molenaar 16e23b3f9e macos: align functions in gdkmacosdrag-private.h 2023-01-17 16:12:57 +01:00
Arjan Molenaar 628aeda7ee macos: Provide the right drag action
We should use the drag action/operation provided by the
drag handlers, not rely on our internal bookkeeping.
2023-01-16 23:21:35 +01:00
Arjan Molenaar 2669dc269b macos: Default kCFRunLoopAllActivities
It's actually a mask, but we'll keep it in to
avoid compiler warnings.
2023-01-16 20:28:38 +01:00
Arjan Molenaar 1bc63eeadb macos: Queue events during drag
By passing the events during a (midal-ish) drag operation to the main loop,
we're able to keep up with what's happening. This allows the internal
drag state (GtkDragSource) to be updated and be done when the drag is
done.
2023-01-16 14:47:49 +01:00
Arjan Molenaar 1d8a23e97b macos: Provide fallback pasteboard for gtype Dnd
The Drag data should pass through the macos pasteboard system.
We need to provide some pasteboard type. Let's make it a "URL",
which is a pretty generic type anyway.
2023-01-15 10:03:47 +01:00
Arjan Molenaar 422b4b6561 macos: No need to drag handle events
This is handled by the DraggingSource object.
2023-01-15 10:03:47 +01:00
Arjan Molenaar 27ee8b23fd macos: No need to grab a seat
The macOS DnD logic will take over anyway.
2023-01-15 10:03:47 +01:00
Arjan Molenaar b9847795a7 macos: Support dragging from GdkMacosWindow
The handling is done similar to drag targets.
Note that dragging is a modal action on macos: no events
are sent to the main window. This could cause trouble when
we finish the drag, and not finish the gesture in GTK.
2023-01-15 10:01:56 +01:00
Arjan Molenaar 757d1916ae Fix dx, dy position in gtk_drag_source_drag_begin
Coordinates are double. This change avoid an unneeded cast.
2023-01-15 09:52:43 +01:00
Arjan Molenaar 420be8fb0f macos: run glib idle functions when in nested run loop
It looks like DnD starts a nested run loop. We still have to run our
GLib handlers, so animations work.
2023-01-13 20:03:55 +01:00
Christian Hergert 9c3629653f macos: abstract pasteboard for use in clipboard and drag
This will allow us to share a single NSPasteboardItem and data provider
implementation for both GdkClipboard and GdkDrag.
2023-01-13 20:03:55 +01:00
Christian Hergert eb5cf831b1 macos: refactor pasteboard components into separate module
This will make it easier to reuse from drag integration so that we don't
require clipboards for everything.

We will need to subclass the pasteboard provider twice, however, both
for clipboard and dragging.
2023-01-13 20:03:55 +01:00
Maxim Zakharov 2290c2bb23 gdk/broadway: Implements modal hint for Broadway surface
Ensures modal window is raised above parent; does return focus to
parent window when transient child window is closed.

That solves problems with overlapped modal window and focus loss in
complex multi window UI.
2022-05-17 15:18:30 +10:00
142 changed files with 14585 additions and 13235 deletions
+1
View File
@@ -364,6 +364,7 @@ asan-build:
tags: [ asan ]
stage: analysis
needs: []
when: manual
variables:
script:
- export PATH="$HOME/.local/bin:$PATH"
+2 -1
View File
@@ -21,7 +21,7 @@ many things that we value:
Please, do not use the issue tracker for support questions. If you have
questions on how to use GTK effectively, you can use:
- the `#gtk` IRC channel on irc.gnome.org
- the `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org)
- the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
You can also look at the GTK tag on [Stack
@@ -44,6 +44,7 @@ If you're reporting a bug make sure to list:
0. which version of GTK are you using?
0. which operating system are you using?
0. what display and graphics driver are you using?
0. the necessary steps to reproduce the issue
0. the expected outcome
0. a description of the behavior; screenshots are also welcome
+71 -1
View File
@@ -1,6 +1,76 @@
Overview of Changes in 4.9.3, xx-xx-xxxx
Overview of Changes in 4.9.4, xx-xx-xxxx
========================================
Overview of Changes in 4.9.3, 04-02-2023
========================================
* Add GtkUriLauncher, as replacement for gtk_show_uri
* Add GdkMonitor::description
* Fix problems with tooltip sizing
* Deprecations:
- GtkStatusbar
- GtkAssistant
- GtkLockButton
- gtk_gesture_set_sequence_state
* GtkColumnView:
- Only create widgets for visible columns
* GtkFileDialog:
- Drop shortcut folders API
* GtkCalendar:
- Make marked days work again
* GtkSwitch:
- Make state and active independently settable
* GtkFileChooser:
- Fix a crash with DND
- Fix excessively wide sidebar
- Make context menus work again
* Accessibility:
- Make GtkAccessible public, so it can be implemented outside GTK
- Support accessible implementation for editables
* CSS:
- Fix randomly stopping CSS animations
* GL:
- Fix synchronization with GStreamer
- Fix problems with 3rd party GL in the same thread
* Wayland:
- Fix startup notification with xdg_activation
* Broadway:
- Implement modal windows
* macOS:
- Make DND work
* Build:
- Require graphene 1.10
- Require gobject-introspection 1.72
* Translation updates
Catalan
Galician
German
Hebrew
Indonesian
Portuguese
Russian
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.9.2, 26-12-2022
========================================
+2
View File
@@ -2,6 +2,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
typedef GtkApplication DemoApplication;
typedef GtkApplicationClass DemoApplicationClass;
+2
View File
@@ -7,6 +7,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *progress_bar = NULL;
static gboolean
+4
View File
@@ -37,6 +37,8 @@ remove_timeout (gpointer data)
g_source_remove (id);
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static gboolean
pop_status (gpointer data)
{
@@ -57,6 +59,8 @@ status_message (GtkStatusbar *status,
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
}
G_GNUC_END_IGNORE_DEPRECATIONS
static void
help_activate (GSimpleAction *action,
GVariant *parameter,
+61 -24
View File
@@ -3,7 +3,9 @@
enum
{
PROP_PAINTABLE = 1,
PROP_TEXTURE = 1,
PROP_MIN_FILTER,
PROP_MAG_FILTER,
PROP_SCALE
};
@@ -11,8 +13,10 @@ struct _Demo3Widget
{
GtkWidget parent_instance;
GdkPaintable *paintable;
GdkTexture *texture;
float scale;
GskScalingFilter min_filter;
GskScalingFilter mag_filter;
GtkWidget *menu;
};
@@ -28,6 +32,8 @@ static void
demo3_widget_init (Demo3Widget *self)
{
self->scale = 1.f;
self->min_filter = GSK_SCALING_FILTER_NEAREST;
self->mag_filter = GSK_SCALING_FILTER_NEAREST;
gtk_widget_init_template (GTK_WIDGET (self));
}
@@ -36,7 +42,7 @@ demo3_widget_dispose (GObject *object)
{
Demo3Widget *self = DEMO3_WIDGET (object);
g_clear_object (&self->paintable);
g_clear_object (&self->texture);
gtk_widget_dispose_template (GTK_WIDGET (self), DEMO3_TYPE_WIDGET);
@@ -50,12 +56,13 @@ demo3_widget_snapshot (GtkWidget *widget,
Demo3Widget *self = DEMO3_WIDGET (widget);
int x, y, width, height;
double w, h;
GskRenderNode *node;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
w = self->scale * gdk_paintable_get_intrinsic_width (self->paintable);
h = self->scale * gdk_paintable_get_intrinsic_height (self->paintable);
w = self->scale * gdk_texture_get_width (self->texture);
h = self->scale * gdk_texture_get_height (self->texture);
x = MAX (0, (width - ceil (w)) / 2);
y = MAX (0, (height - ceil (h)) / 2);
@@ -63,7 +70,12 @@ demo3_widget_snapshot (GtkWidget *widget,
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
gdk_paintable_snapshot (self->paintable, snapshot, w, h);
node = gsk_texture_node_new_with_filters (self->texture,
&GRAPHENE_RECT_INIT (0, 0, w, h),
self->min_filter,
self->mag_filter);
gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
gtk_snapshot_restore (snapshot);
gtk_snapshot_pop (snapshot);
}
@@ -81,9 +93,9 @@ demo3_widget_measure (GtkWidget *widget,
int size;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
size = gdk_paintable_get_intrinsic_width (self->paintable);
size = gdk_texture_get_width (self->texture);
else
size = gdk_paintable_get_intrinsic_height (self->paintable);
size = gdk_texture_get_height (self->texture);
*minimum = *natural = self->scale * size;
}
@@ -113,9 +125,9 @@ demo3_widget_set_property (GObject *object,
switch (prop_id)
{
case PROP_PAINTABLE:
g_clear_object (&self->paintable);
self->paintable = g_value_dup_object (value);
case PROP_TEXTURE:
g_clear_object (&self->texture);
self->texture = g_value_dup_object (value);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
@@ -124,6 +136,16 @@ demo3_widget_set_property (GObject *object,
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
case PROP_MIN_FILTER:
self->min_filter = g_value_get_enum (value);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
case PROP_MAG_FILTER:
self->mag_filter = g_value_get_enum (value);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -140,14 +162,22 @@ demo3_widget_get_property (GObject *object,
switch (prop_id)
{
case PROP_PAINTABLE:
g_value_set_object (value, self->paintable);
case PROP_TEXTURE:
g_value_set_object (value, self->texture);
break;
case PROP_SCALE:
g_value_set_float (value, self->scale);
break;
case PROP_MIN_FILTER:
g_value_set_enum (value, self->min_filter);
break;
case PROP_MAG_FILTER:
g_value_set_enum (value, self->mag_filter);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -205,16 +235,26 @@ demo3_widget_class_init (Demo3WidgetClass *class)
widget_class->measure = demo3_widget_measure;
widget_class->size_allocate = demo3_widget_size_allocate;
g_object_class_install_property (object_class, PROP_PAINTABLE,
g_param_spec_object ("paintable", "Paintable", "Paintable",
GDK_TYPE_PAINTABLE,
g_object_class_install_property (object_class, PROP_TEXTURE,
g_param_spec_object ("texture", NULL, NULL,
GDK_TYPE_TEXTURE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_SCALE,
g_param_spec_float ("scale", "Scale", "Scale",
g_param_spec_float ("scale", NULL, NULL,
0.0, 10.0, 1.0,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_MIN_FILTER,
g_param_spec_enum ("min-filter", NULL, NULL,
GSK_TYPE_SCALING_FILTER, GSK_SCALING_FILTER_LINEAR,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_MAG_FILTER,
g_param_spec_enum ("mag-filter", NULL, NULL,
GSK_TYPE_SCALING_FILTER, GSK_SCALING_FILTER_LINEAR,
G_PARAM_READWRITE));
/* These are the actions that we are using in the menu */
gtk_widget_class_install_action (widget_class, "zoom.in", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "zoom.out", NULL, zoom_cb);
@@ -229,16 +269,13 @@ GtkWidget *
demo3_widget_new (const char *resource)
{
Demo3Widget *self;
GdkPixbuf *pixbuf;
GdkPaintable *paintable;
GdkTexture *texture;
pixbuf = gdk_pixbuf_new_from_resource (resource, NULL);
paintable = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
texture = gdk_texture_new_from_resource (resource);
self = g_object_new (DEMO3_TYPE_WIDGET, "paintable", paintable, NULL);
self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
g_object_unref (pixbuf);
g_object_unref (paintable);
g_object_unref (texture);
return GTK_WIDGET (self);
}
+1 -1
View File
@@ -362,7 +362,7 @@ do_drawingarea (GtkWidget *do_widget)
G_CALLBACK (scribble_resize), NULL);
drag = gtk_gesture_drag_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), 0);
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
+13 -1
View File
@@ -22,9 +22,11 @@ do_menu (GtkWidget *do_widget)
if (!window)
{
GtkWidget *box;
GtkWidget *box2;
GtkWidget *sw;
GtkWidget *widget;
GtkWidget *scale;
GtkWidget *dropdown;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Menu");
@@ -43,10 +45,20 @@ do_menu (GtkWidget *do_widget)
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_append (GTK_BOX (box), box2);
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
gtk_range_set_value (GTK_RANGE (scale), 1.0);
gtk_box_append (GTK_BOX (box), scale);
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_box_append (GTK_BOX (box2), dropdown);
g_object_bind_property (dropdown, "selected", widget, "min-filter", G_BINDING_DEFAULT);
g_object_bind_property (dropdown, "selected", widget, "mag-filter", G_BINDING_DEFAULT);
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
widget, "scale",
G_BINDING_BIDIRECTIONAL);
+2
View File
@@ -6,6 +6,8 @@
#include "demo_conf.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *main_window;
static GFile *filename = NULL;
static GtkPageSetup *page_setup = NULL;
+4
View File
@@ -2252,11 +2252,13 @@ activate (GApplication *app)
for (i = 0; i < G_N_ELEMENTS (accels); i++)
gtk_application_set_accels_for_action (GTK_APPLICATION (app), accels[i].action_and_target, accels[i].accelerators);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
widget = (GtkWidget *)gtk_builder_get_object (builder, "statusbar");
gtk_statusbar_push (GTK_STATUSBAR (widget), 0, "All systems are operating normally.");
action = G_ACTION (g_property_action_new ("statusbar", widget, "visible"));
g_action_map_add_action (G_ACTION_MAP (window), action);
g_object_unref (G_OBJECT (action));
G_GNUC_END_IGNORE_DEPRECATIONS
widget = (GtkWidget *)gtk_builder_get_object (builder, "toolbar");
action = G_ACTION (g_property_action_new ("toolbar", widget, "visible"));
@@ -2430,6 +2432,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
widget = (GtkWidget *)gtk_builder_get_object (builder, "record_button");
g_object_set_data (G_OBJECT (window), "record_button", widget);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
widget = (GtkWidget *)gtk_builder_get_object (builder, "lockbox");
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "lockbutton");
g_object_set_data (G_OBJECT (window), "lockbutton", widget2);
@@ -2447,6 +2450,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
G_BINDING_SYNC_CREATE);
gtk_lock_button_set_permission (GTK_LOCK_BUTTON (widget2), permission);
g_object_unref (permission);
G_GNUC_END_IGNORE_DEPRECATIONS
widget = (GtkWidget *)gtk_builder_get_object (builder, "iconview1");
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "increase_button");
+10
View File
@@ -109,3 +109,13 @@ Other libraries, such as libadwaita, may provide replacements as well.
## gtk_show_uri is being replaced
Instead of gtk_show_uri(), you should use GtkUriLauncher or GtkFileLauncher.
## GtkStatusbar is going away
This is an oldfashioned widget that does not do all that much anymore, since
it no longer has a resize handle for the window.
## GtkLockButton is going away
This is an very specialized widget that should better live with the application
where it is used.
+1 -1
View File
@@ -37,7 +37,7 @@ main (int argc,
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
+8
View File
@@ -213,6 +213,7 @@ typedef enum {
BROADWAY_REQUEST_RELEASE_TEXTURE,
BROADWAY_REQUEST_SET_NODES,
BROADWAY_REQUEST_ROUNDTRIP,
BROADWAY_REQUEST_SET_MODAL_HINT,
} BroadwayRequestType;
typedef struct {
@@ -293,6 +294,12 @@ typedef struct {
guint32 show_keyboard;
} BroadwayRequestSetShowKeyboard;
typedef struct {
BroadwayRequestBase base;
guint32 id;
gboolean modal_hint;
} BroadwayRequestSetModalHint;
typedef union {
BroadwayRequestBase base;
BroadwayRequestNewSurface new_surface;
@@ -312,6 +319,7 @@ typedef union {
BroadwayRequestUploadTexture upload_texture;
BroadwayRequestReleaseTexture release_texture;
BroadwayRequestSetNodes set_nodes;
BroadwayRequestSetModalHint set_modal_hint;
} BroadwayRequest;
typedef enum {
+36
View File
@@ -124,6 +124,7 @@ struct BroadwaySurface {
gboolean visible;
gint32 transient_for;
guint32 texture;
gboolean modal_hint;
BroadwayNode *nodes;
GHashTable *node_lookup;
};
@@ -421,6 +422,14 @@ update_event_state (BroadwayServer *server,
{
surface->x = message->configure_notify.x;
surface->y = message->configure_notify.y;
if (server->focused_surface_id != message->configure_notify.id &&
server->pointer_grab_surface_id == -1 && surface->modal_hint)
{
broadway_server_surface_raise (server, message->configure_notify.id);
broadway_server_focus_surface (server, message->configure_notify.id);
broadway_server_flush (server);
}
}
break;
case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
@@ -1568,6 +1577,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
int id)
{
BroadwaySurface *surface;
gint32 transient_for = -1;
if (server->mouse_in_surface_id == id)
{
@@ -1585,11 +1595,24 @@ broadway_server_destroy_surface (BroadwayServer *server,
surface = broadway_server_lookup_surface (server, id);
if (surface != NULL)
{
if (server->focused_surface_id == id)
transient_for = surface->transient_for;
server->surfaces = g_list_remove (server->surfaces, surface);
g_hash_table_remove (server->surface_id_hash,
GINT_TO_POINTER (id));
broadway_surface_free (server, surface);
}
if (transient_for != -1)
{
surface = broadway_server_lookup_surface (server, transient_for);
if (surface != NULL)
{
broadway_server_focus_surface (server, transient_for);
broadway_server_flush (server);
}
}
}
gboolean
@@ -1710,6 +1733,19 @@ broadway_server_surface_set_transient_for (BroadwayServer *server,
}
}
void
broadway_server_surface_set_modal_hint (BroadwayServer *server,
int id, gboolean modal_hint)
{
BroadwaySurface *surface;
surface = broadway_server_lookup_surface (server, id);
if (surface == NULL)
return;
surface->modal_hint = modal_hint;
}
gboolean
broadway_server_has_client (BroadwayServer *server)
{
+3
View File
@@ -130,6 +130,9 @@ gboolean broadway_server_surface_move_resize (BroadwayServer *
int height);
void broadway_server_focus_surface (BroadwayServer *server,
int new_focused_surface);
void broadway_server_surface_set_modal_hint (BroadwayServer *server,
int id,
gboolean modal_hint);
#endif /* __BROADWAY_SERVER__ */
+5
View File
@@ -380,6 +380,11 @@ client_handle_request (BroadwayClient *client,
case BROADWAY_REQUEST_SET_SHOW_KEYBOARD:
broadway_server_set_show_keyboard (server, request->set_show_keyboard.show_keyboard);
break;
case BROADWAY_REQUEST_SET_MODAL_HINT:
broadway_server_surface_set_modal_hint (server,
request->set_modal_hint.id,
request->set_modal_hint.modal_hint);
break;
default:
g_warning ("Unknown request of type %d", request->base.type);
}
+12
View File
@@ -561,6 +561,18 @@ _gdk_broadway_server_surface_set_transient_for (GdkBroadwayServer *server,
BROADWAY_REQUEST_SET_TRANSIENT_FOR);
}
void
_gdk_broadway_server_surface_set_modal_hint (GdkBroadwayServer *server,
int id, gboolean modal_hint)
{
BroadwayRequestSetModalHint msg;
msg.id = id;
msg.modal_hint = modal_hint;
gdk_broadway_server_send_message (server, msg,
BROADWAY_REQUEST_SET_MODAL_HINT);
}
static int
open_shared_memory (void)
{
+3
View File
@@ -78,5 +78,8 @@ gboolean _gdk_broadway_server_surface_move_resize (GdkBroadwaySe
int y,
int width,
int height);
void _gdk_broadway_server_surface_set_modal_hint (GdkBroadwayServer *server,
int id,
gboolean modal_hint);
#endif /* __GDK_BROADWAY_SERVER__ */
+25
View File
@@ -82,6 +82,27 @@ gdk_event_source_check (GSource *source)
return retval;
}
static void
handle_focus_change (GdkEvent *event)
{
GdkEvent *focus_event;
gboolean focus_in = (gdk_event_get_event_type (event) == GDK_ENTER_NOTIFY);
if (gdk_crossing_event_get_detail (event) == GDK_NOTIFY_INFERIOR)
return;
if (!gdk_crossing_event_get_focus (event) )
return;
focus_event = gdk_focus_event_new (gdk_event_get_surface (event),
gdk_event_get_device (event),
focus_in);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gdk_display_put_event (gdk_event_get_display (event), focus_event);
G_GNUC_END_IGNORE_DEPRECATIONS
gdk_event_unref (focus_event);
}
void
_gdk_broadway_events_got_input (GdkDisplay *display,
BroadwayInputMsg *message)
@@ -110,6 +131,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
handle_focus_change (event);
}
break;
case BROADWAY_EVENT_LEAVE:
@@ -126,6 +149,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
message->crossing.mode,
GDK_NOTIFY_ANCESTOR);
handle_focus_change (event);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
+21
View File
@@ -709,6 +709,21 @@ gdk_broadway_surface_set_transient_for (GdkSurface *surface,
_gdk_broadway_server_surface_set_transient_for (display->server, impl->id, impl->transient_for);
}
static void
gdk_broadway_surface_set_modal_hint (GdkSurface *surface,
gboolean modal)
{
GdkBroadwayDisplay *display;
GdkBroadwaySurface *impl;
impl = GDK_BROADWAY_SURFACE (surface);
impl->modal_hint = modal;
display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
_gdk_broadway_server_surface_set_modal_hint (display->server, impl->id, impl->modal_hint);
}
static void
gdk_broadway_surface_get_geometry (GdkSurface *surface,
int *x,
@@ -1433,6 +1448,8 @@ gdk_broadway_toplevel_set_property (GObject *object,
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
gdk_broadway_surface_set_modal_hint (surface, g_value_get_boolean (value));
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
@@ -1479,6 +1496,10 @@ gdk_broadway_toplevel_get_property (GObject *object,
g_value_set_object (value, surface->transient_for);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
g_value_set_boolean (value, surface->modal_hint);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
g_value_set_pointer (value, NULL);
break;
+1
View File
@@ -54,6 +54,7 @@ struct _GdkBroadwaySurface
gboolean dirty;
gboolean last_synced;
gboolean modal_hint;
GdkGeometry geometry_hints;
GdkSurfaceHints geometry_hints_mask;
+45 -5
View File
@@ -26,6 +26,7 @@
#include "gdkcontentformats.h"
#include "gdkcontentserializer.h"
#include "gdkcontentdeserializer.h"
#include "gdkdebugprivate.h"
#include <gio/gio.h>
@@ -213,6 +214,8 @@ file_transfer_portal_register_files (const char **files,
afd->len = g_strv_length ((char **)files);
afd->start = 0;
GDK_DEBUG (DND, "file transfer portal: registering %d files", afd->len);
g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add (&options, "{sv}", "writable", g_variant_new_boolean (writable));
g_variant_builder_add (&options, "{sv}", "autostop", g_variant_new_boolean (TRUE));
@@ -348,9 +351,8 @@ portal_ready (GObject *object,
static void
portal_file_serializer (GdkContentSerializer *serializer)
{
GFile *file;
const GValue *value;
GPtrArray *files;
const GValue *value;
files = g_ptr_array_new_with_free_func (g_free);
@@ -358,9 +360,24 @@ portal_file_serializer (GdkContentSerializer *serializer)
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
GFile *file;
file = g_value_get_object (gdk_content_serializer_get_value (serializer));
if (file)
g_ptr_array_add (files, g_file_get_path (file));
if (file && g_file_peek_path (file))
{
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
g_ptr_array_add (files, g_file_get_path (file));
}
#ifdef G_ENABLE_DEBUG
else if (GDK_DEBUG_CHECK (DND))
{
char *uri = g_file_get_uri (file);
gdk_debug_message ("file transfer portal: %s has no path, dropping\n", uri);
g_free (uri);
}
#endif
g_ptr_array_add (files, NULL);
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
@@ -368,7 +385,21 @@ portal_file_serializer (GdkContentSerializer *serializer)
GSList *l;
for (l = g_value_get_boxed (value); l; l = l->next)
g_ptr_array_add (files, g_file_get_path (l->data));
{
GFile *file = l->data;
if (file && g_file_peek_path (file))
{
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
g_ptr_array_add (files, g_file_get_path (file));
}
else
{
char *uri = g_file_get_uri (file);
gdk_debug_message ("file transfer portal: %s has no path, dropping", uri);
g_free (uri);
}
}
g_ptr_array_add (files, NULL);
}
@@ -395,6 +426,15 @@ portal_finish (GObject *object,
return;
}
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (DND))
{
char *s = g_strjoinv (", ", files);
gdk_debug_message ("file transfer portal: Receiving files: %s", s);
g_free (s);
}
#endif
value = gdk_content_deserializer_get_value (deserializer);
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
+3 -1
View File
@@ -1149,7 +1149,7 @@ _gdk_display_get_next_serial (GdkDisplay *display)
* [method@Gtk.Window.set_auto_startup_notification]
* is called to disable that feature.
*
* Deprecated: 4.10. Using gdk_toplevel_set_startup_id() is sufficient.
* Deprecated: 4.10: Using [method@Gdk.Toplevel.set_startup_id] is sufficient
*/
void
gdk_display_notify_startup_complete (GdkDisplay *display,
@@ -1168,6 +1168,8 @@ gdk_display_notify_startup_complete (GdkDisplay *display,
* if no ID has been defined.
*
* Returns: (nullable): the startup notification ID for @display
*
* Deprecated: 4.10
*/
const char *
gdk_display_get_startup_notification_id (GdkDisplay *display)
+1 -1
View File
@@ -86,7 +86,7 @@ GdkClipboard * gdk_display_get_primary_clipboard (GdkDisplay
GDK_DEPRECATED_IN_4_10_FOR(gdk_toplevel_set_startup_id)
void gdk_display_notify_startup_complete (GdkDisplay *display,
const char *startup_id);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
const char * gdk_display_get_startup_notification_id (GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
+29 -2
View File
@@ -501,6 +501,18 @@ gdk_gl_context_real_is_shared (GdkGLContext *self,
return TRUE;
}
static gboolean
gdk_gl_context_real_is_current (GdkGLContext *self)
{
#ifdef HAVE_EGL
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
return priv->egl_context == eglGetCurrentContext ();
#else
return TRUE;
#endif
}
static gboolean
gdk_gl_context_real_clear_current (GdkGLContext *context)
{
@@ -670,6 +682,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
klass->is_shared = gdk_gl_context_real_is_shared;
klass->make_current = gdk_gl_context_real_make_current;
klass->clear_current = gdk_gl_context_real_clear_current;
klass->is_current = gdk_gl_context_real_is_current;
klass->get_default_framebuffer = gdk_gl_context_real_get_default_framebuffer;
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
@@ -1551,6 +1564,12 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->extensions_checked = TRUE;
}
static gboolean
gdk_gl_context_check_is_current (GdkGLContext *context)
{
return GDK_GL_CONTEXT_GET_CLASS (context)->is_current (context);
}
/**
* gdk_gl_context_make_current:
* @context: a `GdkGLContext`
@@ -1569,7 +1588,7 @@ gdk_gl_context_make_current (GdkGLContext *context)
masked_context = mask_context (context, surfaceless);
current = g_private_get (&thread_current_context);
if (current == masked_context)
if (current == masked_context && gdk_gl_context_check_is_current (context))
return;
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
@@ -1740,10 +1759,18 @@ GdkGLContext *
gdk_gl_context_get_current (void)
{
MaskedContext *current;
GdkGLContext *context;
current = g_private_get (&thread_current_context);
context = unmask_context (current);
return unmask_context (current);
if (context && !gdk_gl_context_check_is_current (context))
{
g_private_replace (&thread_current_context, NULL);
context = NULL;
}
return context;
}
gboolean
+1
View File
@@ -83,6 +83,7 @@ struct _GdkGLContextClass
gboolean (* make_current) (GdkGLContext *context,
gboolean surfaceless);
gboolean (* clear_current) (GdkGLContext *context);
gboolean (* is_current) (GdkGLContext *context);
cairo_region_t * (* get_damage) (GdkGLContext *context);
gboolean (* is_shared) (GdkGLContext *self,
+26 -24
View File
@@ -53,10 +53,8 @@ struct _GdkGLTextureClass {
G_DEFINE_TYPE (GdkGLTexture, gdk_gl_texture, GDK_TYPE_TEXTURE)
static void
gdk_gl_texture_dispose (GObject *object)
drop_gl_resources (GdkGLTexture *self)
{
GdkGLTexture *self = GDK_GL_TEXTURE (object);
if (self->destroy)
{
self->destroy (self->data);
@@ -66,17 +64,29 @@ gdk_gl_texture_dispose (GObject *object)
g_clear_object (&self->context);
self->id = 0;
}
static void
gdk_gl_texture_dispose (GObject *object)
{
GdkGLTexture *self = GDK_GL_TEXTURE (object);
drop_gl_resources (self);
g_clear_object (&self->saved);
G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object);
}
typedef void (* GLFunc) (GdkGLTexture *self,
GdkGLContext *context,
gpointer data);
typedef struct _InvokeData
{
GdkGLTexture *self;
volatile int spinlock;
GFunc func;
GLFunc func;
gpointer data;
} InvokeData;
@@ -91,7 +101,7 @@ gdk_gl_texture_invoke_callback (gpointer data)
gdk_gl_context_make_current (context);
glBindTexture (GL_TEXTURE_2D, invoke->self->id);
invoke->func (invoke->self, invoke->data);
invoke->func (invoke->self, context, invoke->data);
g_atomic_int_set (&invoke->spinlock, 1);
@@ -100,7 +110,7 @@ gdk_gl_texture_invoke_callback (gpointer data)
static void
gdk_gl_texture_run (GdkGLTexture *self,
GFunc func,
GLFunc func,
gpointer data)
{
InvokeData invoke = { self, 0, func, data };
@@ -145,19 +155,19 @@ gdk_gl_texture_find_format (gboolean use_es,
}
static inline void
gdk_gl_texture_do_download (gpointer texture_,
gpointer download_)
gdk_gl_texture_do_download (GdkGLTexture *self,
GdkGLContext *context,
gpointer download_)
{
GdkTexture *texture = GDK_TEXTURE (self);
gsize expected_stride;
GdkGLTexture *self = texture_;
GdkTexture *texture = texture_;
Download *download = download_;
GLenum gl_internal_format, gl_format, gl_type;
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
if (download->stride == expected_stride &&
!gdk_gl_context_get_use_es (self->context) &&
!gdk_gl_context_get_use_es (context) &&
gdk_memory_format_gl_format (download->format, TRUE, &gl_internal_format, &gl_format, &gl_type))
{
glGetTexImage (GL_TEXTURE_2D,
@@ -175,11 +185,11 @@ gdk_gl_texture_do_download (gpointer texture_,
glGenFramebuffers (1, &fbo);
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
if (gdk_gl_context_check_version (self->context, 4, 3, 3, 1))
if (gdk_gl_context_check_version (context, 4, 3, 3, 1))
{
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 (self->context), gl_read_format, gl_read_type, &actual_format))
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), gl_read_format, gl_read_type, &actual_format))
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
}
else
@@ -193,7 +203,7 @@ gdk_gl_texture_do_download (gpointer texture_,
(download->stride == expected_stride))
{
glReadPixels (0, 0,
texture->width, texture->height,
texture->width, texture->height,
gl_read_format,
gl_read_type,
download->data);
@@ -204,7 +214,7 @@ gdk_gl_texture_do_download (gpointer texture_,
guchar *pixels = g_malloc_n (texture->width * actual_bpp, texture->height);
glReadPixels (0, 0,
texture->width, texture->height,
texture->width, texture->height,
gl_read_format,
gl_read_type,
pixels);
@@ -297,15 +307,7 @@ gdk_gl_texture_release (GdkGLTexture *self)
self->saved = GDK_TEXTURE (gdk_memory_texture_from_texture (texture,
gdk_texture_get_format (texture)));
if (self->destroy)
{
self->destroy (self->data);
self->destroy = NULL;
self->data = NULL;
}
g_clear_object (&self->context);
self->id = 0;
drop_gl_resources (self);
}
static void
+52
View File
@@ -39,6 +39,7 @@
enum {
PROP_0,
PROP_DESCRIPTION,
PROP_DISPLAY,
PROP_MANUFACTURER,
PROP_MODEL,
@@ -81,6 +82,10 @@ gdk_monitor_get_property (GObject *object,
switch (prop_id)
{
case PROP_DESCRIPTION:
g_value_set_string (value, monitor->description);
break;
case PROP_DISPLAY:
g_value_set_object (value, monitor->display);
break;
@@ -154,6 +159,7 @@ gdk_monitor_finalize (GObject *object)
{
GdkMonitor *monitor = GDK_MONITOR (object);
g_free (monitor->description);
g_free (monitor->connector);
g_free (monitor->manufacturer);
g_free (monitor->model);
@@ -170,6 +176,18 @@ gdk_monitor_class_init (GdkMonitorClass *class)
object_class->get_property = gdk_monitor_get_property;
object_class->set_property = gdk_monitor_set_property;
/**
* GdkMonitor:description: (attributes org.gtk.Property.get=gdk_monitor_get_description)
*
* A short description of the monitor, meant for display to the user.
*
* Since: 4.10
*/
props[PROP_DESCRIPTION] =
g_param_spec_string ("description", NULL, NULL,
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkMonitor:display: (attributes org.gtk.Property.get=gdk_monitor_get_display)
*
@@ -377,6 +395,10 @@ gdk_monitor_get_height_mm (GdkMonitor *monitor)
*
* Gets the name of the monitor's connector, if available.
*
* These are strings such as "eDP-1", or "HDMI-2". They depend
* on software and hardware configuration, and should not be
* relied on as stable identifiers of a specific monitor.
*
* Returns: (transfer none) (nullable): the name of the connector
*/
const char *
@@ -619,3 +641,33 @@ gdk_monitor_is_valid (GdkMonitor *monitor)
return monitor->valid;
}
/**
* gdk_monitor_get_description: (attributes org.gtk.Method.get_property=description)
* @monitor: a `GdkMonitor`
*
* Gets a string describing the monitor, if available.
*
* This can be used to identify a monitor in the UI.
*
* Returns: (transfer none) (nullable): the monitor description
*
* Since: 4.10
*/
const char *
gdk_monitor_get_description (GdkMonitor *monitor)
{
g_return_val_if_fail (GDK_IS_MONITOR (monitor), NULL);
return monitor->description;
}
void
gdk_monitor_set_description (GdkMonitor *monitor,
const char *description)
{
g_free (monitor->description);
monitor->description = g_strdup (description);
g_object_notify_by_pspec (G_OBJECT (monitor), props[PROP_DESCRIPTION]);
}
+2
View File
@@ -86,6 +86,8 @@ GDK_AVAILABLE_IN_ALL
GdkSubpixelLayout gdk_monitor_get_subpixel_layout (GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
gboolean gdk_monitor_is_valid (GdkMonitor *monitor);
GDK_AVAILABLE_IN_4_10
const char * gdk_monitor_get_description (GdkMonitor *monitor);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkMonitor, g_object_unref)
+3
View File
@@ -37,6 +37,7 @@ struct _GdkMonitor {
char *manufacturer;
char *model;
char *connector;
char *description;
GdkRectangle geometry;
int width_mm;
int height_mm;
@@ -70,6 +71,8 @@ void gdk_monitor_set_refresh_rate (GdkMonitor *monitor,
void gdk_monitor_set_subpixel_layout (GdkMonitor *monitor,
GdkSubpixelLayout subpixel);
void gdk_monitor_invalidate (GdkMonitor *monitor);
void gdk_monitor_set_description (GdkMonitor *monitor,
const char *description);
G_END_DECLS
+60 -4
View File
@@ -27,10 +27,12 @@
#import "GdkMacosView.h"
#import "GdkMacosWindow.h"
#include "gdkmacosclipboard-private.h"
#include "gdkmacosdisplay-private.h"
#include "gdkmacosdrag-private.h"
#include "gdkmacosdrop-private.h"
#include "gdkmacoseventsource-private.h"
#include "gdkmacosmonitor-private.h"
#include "gdkmacospasteboard-private.h"
#include "gdkmacossurface-private.h"
#include "gdkmacospopupsurface-private.h"
#include "gdkmacostoplevelsurface-private.h"
@@ -144,7 +146,7 @@ typedef NSString *CALayerContentsGravity;
*
* TODO: Can we improve grab breaking to fix this?
*/
_gdk_macos_display_send_button_event ([self gdkDisplay], event);
_gdk_macos_display_send_event ([self gdkDisplay], event);
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
@@ -246,7 +248,7 @@ typedef NSString *CALayerContentsGravity;
[view release];
/* TODO: We might want to make this more extensible at some point */
_gdk_macos_clipboard_register_drag_types (self);
_gdk_macos_pasteboard_register_drag_types (self);
return self;
}
@@ -668,7 +670,61 @@ typedef NSString *CALayerContentsGravity;
}
// NSDraggingSource protocol
// ...
- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
{
NSInteger sequence_number = [session draggingSequenceNumber];
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
GdkModifierType state = _gdk_macos_display_get_current_keyboard_modifiers (GDK_MACOS_DISPLAY (display));
_gdk_macos_drag_set_actions (GDK_MACOS_DRAG (drag), state);
return _gdk_macos_drag_operation (GDK_MACOS_DRAG (drag));
}
- (void)draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint
{
NSInteger sequence_number = [session draggingSequenceNumber];
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
int x, y;
_gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display), screenPoint.x, screenPoint.y, &x, &y);
_gdk_macos_drag_set_start_position (GDK_MACOS_DRAG (drag), x, y);
_gdk_macos_drag_surface_move (GDK_MACOS_DRAG (drag), x, y);
}
- (void)draggingSession:(NSDraggingSession *)session movedToPoint:(NSPoint)screenPoint
{
NSInteger sequence_number = [session draggingSequenceNumber];
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (gdk_surface)));
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
int x, y;
_gdk_macos_display_send_event (display, [NSApp currentEvent]);
_gdk_macos_display_from_display_coords (display, screenPoint.x, screenPoint.y, &x, &y);
_gdk_macos_drag_surface_move (GDK_MACOS_DRAG (drag), x, y);
}
- (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation
{
NSInteger sequence_number = [session draggingSequenceNumber];
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (gdk_surface)));
GdkDrag *drag = _gdk_macos_display_find_drag (display, sequence_number);
_gdk_macos_display_send_event (display, [NSApp currentEvent]);
gdk_drag_set_selected_action (drag, _gdk_macos_drag_ns_operation_to_action (operation));
if (gdk_drag_get_selected_action (drag) != 0)
g_signal_emit_by_name (drag, "drop-performed");
else
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
_gdk_macos_display_set_drag (display, [session draggingSequenceNumber], NULL);
}
// end
-(void)setStyleMask:(NSWindowStyleMask)styleMask
+1 -1
View File
@@ -32,7 +32,7 @@
#define GDK_IS_MACOS_WINDOW(obj) ([obj isKindOfClass:[GdkMacosWindow class]])
@interface GdkMacosWindow : NSWindow {
@interface GdkMacosWindow : NSWindow <NSDraggingSource, NSDraggingDestination> {
GdkMacosSurface *gdk_surface;
BOOL inMove;
+1 -24
View File
@@ -24,6 +24,7 @@
#include "gdkclipboardprivate.h"
#include "gdkmacosdisplay-private.h"
#include "gdkmacospasteboard-private.h"
G_BEGIN_DECLS
@@ -41,30 +42,6 @@ NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char
NSPasteboardType *alternate);
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
void _gdk_macos_pasteboard_read_async (GObject *object,
NSPasteboard *pasteboard,
GdkContentFormats *formats,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
GAsyncResult *result,
const char **out_mime_type,
GError **error);
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
{
GCancellable *cancellable;
GdkClipboard *clipboard;
char **mimeTypes;
}
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
-(NSArray<NSPasteboardType> *)types;
@end
G_END_DECLS
+15 -488
View File
@@ -22,6 +22,7 @@
#include <glib/gi18n.h>
#include "gdkmacosclipboard-private.h"
#include "gdkmacospasteboard-private.h"
#include "gdkmacosutils-private.h"
#include "gdkprivate.h"
@@ -32,163 +33,8 @@ struct _GdkMacosClipboard
NSInteger last_change_count;
};
typedef struct
{
GMemoryOutputStream *stream;
NSPasteboardItem *item;
NSPasteboardType type;
GMainContext *main_context;
guint done : 1;
} WriteRequest;
enum {
TYPE_STRING,
TYPE_PBOARD,
TYPE_URL,
TYPE_FILE_URL,
TYPE_COLOR,
TYPE_TIFF,
TYPE_PNG,
TYPE_LAST
};
#define PTYPE(k) (get_pasteboard_type(TYPE_##k))
static NSPasteboardType pasteboard_types[TYPE_LAST];
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
static NSPasteboardType
get_pasteboard_type (int type)
{
static gsize initialized = FALSE;
g_assert (type >= 0);
g_assert (type < TYPE_LAST);
if (g_once_init_enter (&initialized))
{
pasteboard_types[TYPE_PNG] = NSPasteboardTypePNG;
pasteboard_types[TYPE_STRING] = NSPasteboardTypeString;
pasteboard_types[TYPE_TIFF] = NSPasteboardTypeTIFF;
pasteboard_types[TYPE_COLOR] = NSPasteboardTypeColor;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
pasteboard_types[TYPE_PBOARD] = NSStringPboardType;
G_GNUC_END_IGNORE_DEPRECATIONS
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
pasteboard_types[TYPE_URL] = NSPasteboardTypeURL;
pasteboard_types[TYPE_FILE_URL] = NSPasteboardTypeFileURL;
#else
pasteboard_types[TYPE_URL] = [[NSString alloc] initWithUTF8String:"public.url"];
pasteboard_types[TYPE_FILE_URL] = [[NSString alloc] initWithUTF8String:"public.file-url"];
#endif
g_once_init_leave (&initialized, TRUE);
}
return pasteboard_types[type];
}
static void
write_request_free (WriteRequest *wr)
{
g_clear_pointer (&wr->main_context, g_main_context_unref);
g_clear_object (&wr->stream);
[wr->item release];
g_slice_free (WriteRequest, wr);
}
const char *
_gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
if ([type isEqualToString:PTYPE(STRING)] ||
[type isEqualToString:PTYPE(PBOARD)])
return g_intern_string ("text/plain;charset=utf-8");
else if ([type isEqualToString:PTYPE(URL)] ||
[type isEqualToString:PTYPE(FILE_URL)])
return g_intern_string ("text/uri-list");
else if ([type isEqualToString:PTYPE(COLOR)])
return g_intern_string ("application/x-color");
else if ([type isEqualToString:PTYPE(TIFF)])
return g_intern_string ("image/tiff");
else if ([type isEqualToString:PTYPE(PNG)])
return g_intern_string ("image/png");
G_GNUC_END_IGNORE_DEPRECATIONS;
return NULL;
}
NSPasteboardType
_gdk_macos_clipboard_to_ns_type (const char *mime_type,
NSPasteboardType *alternate)
{
if (alternate)
*alternate = NULL;
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
{
return PTYPE(STRING);
}
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
{
if (alternate)
*alternate = PTYPE(URL);
return PTYPE(FILE_URL);
}
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
{
return PTYPE(COLOR);
}
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
{
return PTYPE(TIFF);
}
else if (g_strcmp0 (mime_type, "image/png") == 0)
{
return PTYPE(PNG);
}
return nil;
}
static void
populate_content_formats (GdkContentFormatsBuilder *builder,
NSPasteboardType type)
{
const char *mime_type;
g_return_if_fail (builder != NULL);
g_return_if_fail (type != NULL);
mime_type = _gdk_macos_clipboard_from_ns_type (type);
if (mime_type != NULL)
gdk_content_formats_builder_add_mime_type (builder, mime_type);
}
static GdkContentFormats *
load_offer_formats (NSPasteboard *pasteboard)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkContentFormatsBuilder *builder;
GdkContentFormats *formats;
builder = gdk_content_formats_builder_new ();
for (NSPasteboardType type in [pasteboard types])
populate_content_formats (builder, type);
formats = gdk_content_formats_builder_free_to_formats (builder);
GDK_END_MACOS_ALLOC_POOL;
return g_steal_pointer (&formats);
}
static void
_gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
{
@@ -199,22 +45,13 @@ _gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
change_count = [self->pasteboard changeCount];
formats = load_offer_formats (self->pasteboard);
formats = _gdk_macos_pasteboard_load_formats (self->pasteboard);
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
gdk_content_formats_unref (formats);
self->last_change_count = change_count;
}
static GInputStream *
create_stream_from_nsdata (NSData *data)
{
const guint8 *bytes = [data bytes];
gsize len = [data length];
return g_memory_input_stream_new_from_data (g_memdup2 (bytes, len), len, g_free);
}
static void
_gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
GdkContentFormats *formats,
@@ -245,34 +82,26 @@ static void
_gdk_macos_clipboard_send_to_pasteboard (GdkMacosClipboard *self,
GdkContentProvider *content)
{
GdkMacosPasteboardItem *item;
NSArray<NSPasteboardItem *> *items;
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
g_assert (GDK_IS_CONTENT_PROVIDER (content));
if (self->pasteboard == NULL)
return;
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosClipboardDataProvider *dataProvider;
GdkContentFormats *serializable;
NSPasteboardItem *item;
const char * const *mime_types;
gsize n_mime_types;
g_return_if_fail (GDK_IS_MACOS_CLIPBOARD (self));
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (content));
serializable = gdk_content_provider_ref_storable_formats (content);
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
dataProvider = [[GdkMacosClipboardDataProvider alloc] initClipboard:GDK_CLIPBOARD (self)
mimetypes:mime_types];
item = [[NSPasteboardItem alloc] init];
[item setDataProvider:dataProvider forTypes:[dataProvider types]];
item = [[GdkMacosPasteboardItem alloc] initForClipboard:GDK_CLIPBOARD (self) withContentProvider:content];
items = [NSArray arrayWithObject:item];
[self->pasteboard clearContents];
if ([self->pasteboard writeObjects:[NSArray arrayWithObject:item]] == NO)
g_warning ("Failed to write object to pasteboard");
if ([self->pasteboard writeObjects:items] == NO)
g_warning ("Failed to send clipboard to pasteboard");
self->last_change_count = [self->pasteboard changeCount];
g_clear_pointer (&serializable, gdk_content_formats_unref);
GDK_END_MACOS_ALLOC_POOL;
}
@@ -365,305 +194,3 @@ _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self)
if ([self->pasteboard changeCount] != self->last_change_count)
_gdk_macos_clipboard_load_contents (self);
}
@implementation GdkMacosClipboardDataProvider
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
{
[super init];
self->mimeTypes = g_strdupv ((char **)mime_types);
self->clipboard = g_object_ref (gdkClipboard);
return self;
}
-(void)dealloc
{
g_cancellable_cancel (self->cancellable);
g_clear_pointer (&self->mimeTypes, g_strfreev);
g_clear_object (&self->clipboard);
g_clear_object (&self->cancellable);
[super dealloc];
}
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
{
g_clear_object (&self->clipboard);
}
-(NSArray<NSPasteboardType> *)types
{
NSMutableArray *ret = [[NSMutableArray alloc] init];
for (guint i = 0; self->mimeTypes[i]; i++)
{
const char *mime_type = self->mimeTypes[i];
NSPasteboardType type;
NSPasteboardType alternate = nil;
if ((type = _gdk_macos_clipboard_to_ns_type (mime_type, &alternate)))
{
[ret addObject:type];
if (alternate)
[ret addObject:alternate];
}
}
return g_steal_pointer (&ret);
}
static void
on_data_ready_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkClipboard *clipboard = (GdkClipboard *)object;
WriteRequest *wr = user_data;
GError *error = NULL;
NSData *data = nil;
g_assert (GDK_IS_CLIPBOARD (clipboard));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (wr != NULL);
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
if (gdk_clipboard_write_finish (clipboard, result, &error))
{
gsize size;
gpointer bytes;
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
size = g_memory_output_stream_get_data_size (wr->stream);
bytes = g_memory_output_stream_steal_data (wr->stream);
data = [[NSData alloc] initWithBytesNoCopy:bytes
length:size
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
}
else
{
g_warning ("Failed to serialize clipboard contents: %s",
error->message);
g_clear_error (&error);
}
[wr->item setData:data forType:wr->type];
wr->done = TRUE;
GDK_END_MACOS_ALLOC_POOL;
}
-(void) pasteboard:(NSPasteboard *)pasteboard
item:(NSPasteboardItem *)item
provideDataForType:(NSPasteboardType)type
{
const char *mime_type = _gdk_macos_clipboard_from_ns_type (type);
GMainContext *main_context = g_main_context_default ();
WriteRequest *wr;
if (self->clipboard == NULL || mime_type == NULL)
{
[item setData:[NSData data] forType:type];
return;
}
wr = g_slice_new0 (WriteRequest);
wr->item = [item retain];
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
wr->type = type;
wr->main_context = g_main_context_ref (main_context);
wr->done = FALSE;
gdk_clipboard_write_async (self->clipboard,
mime_type,
G_OUTPUT_STREAM (wr->stream),
G_PRIORITY_DEFAULT,
self->cancellable,
on_data_ready_cb,
wr);
/* We're forced to provide data synchronously via this API
* so we must block on the main loop. Using another main loop
* than the default tends to get us locked up here, so that is
* what we'll do for now.
*/
while (!wr->done)
g_main_context_iteration (wr->main_context, TRUE);
write_request_free (wr);
}
void
_gdk_macos_clipboard_register_drag_types (NSWindow *window)
{
[window registerForDraggedTypes:[NSArray arrayWithObjects:PTYPE(STRING),
PTYPE(PBOARD),
PTYPE(URL),
PTYPE(FILE_URL),
PTYPE(COLOR),
PTYPE(TIFF),
PTYPE(PNG),
nil]];
}
@end
GdkContentFormats *
_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
{
return load_offer_formats (pasteboard);
}
void
_gdk_macos_pasteboard_read_async (GObject *object,
NSPasteboard *pasteboard,
GdkContentFormats *formats,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkContentFormats *offer_formats = NULL;
const char *mime_type;
GInputStream *stream = NULL;
GTask *task = NULL;
g_assert (G_IS_OBJECT (object));
g_assert (pasteboard != NULL);
g_assert (formats != NULL);
task = g_task_new (object, cancellable, callback, user_data);
g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
g_task_set_priority (task, io_priority);
offer_formats = load_offer_formats (pasteboard);
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
if (mime_type == NULL)
{
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"%s",
_("No compatible transfer format found"));
goto cleanup;
}
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
{
NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
if (nsstr != NULL)
{
const char *str = [nsstr UTF8String];
stream = g_memory_input_stream_new_from_data (g_strdup (str),
strlen (str) + 1,
g_free);
}
}
else if (strcmp (mime_type, "text/uri-list") == 0)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
{
GString *str = g_string_new (NULL);
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
gsize n_files = [files count];
char *data;
guint len;
for (gsize i = 0; i < n_files; ++i)
{
NSString* uriString = [files objectAtIndex:i];
uriString = [@"file://" stringByAppendingString:uriString];
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
g_string_append_printf (str,
"%s\r\n",
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
}
len = str->len;
data = g_string_free (str, FALSE);
stream = g_memory_input_stream_new_from_data (data, len, g_free);
}
G_GNUC_END_IGNORE_DEPRECATIONS;
}
else if (strcmp (mime_type, "application/x-color") == 0)
{
NSColorSpace *colorspace;
NSColor *nscolor;
guint16 color[4];
colorspace = [NSColorSpace genericRGBColorSpace];
nscolor = [[NSColor colorFromPasteboard:pasteboard]
colorUsingColorSpace:colorspace];
color[0] = 0xffff * [nscolor redComponent];
color[1] = 0xffff * [nscolor greenComponent];
color[2] = 0xffff * [nscolor blueComponent];
color[3] = 0xffff * [nscolor alphaComponent];
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
sizeof color,
g_free);
}
else if (strcmp (mime_type, "image/tiff") == 0)
{
NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
stream = create_stream_from_nsdata (data);
}
else if (strcmp (mime_type, "image/png") == 0)
{
NSData *data = [pasteboard dataForType:PTYPE(PNG)];
stream = create_stream_from_nsdata (data);
}
if (stream != NULL)
{
g_task_set_task_data (task, g_strdup (mime_type), g_free);
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
}
else
{
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Failed to decode contents with mime-type of '%s'"),
mime_type);
}
cleanup:
g_clear_object (&task);
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
GDK_END_MACOS_ALLOC_POOL;
}
GInputStream *
_gdk_macos_pasteboard_read_finish (GObject *object,
GAsyncResult *result,
const char **out_mime_type,
GError **error)
{
GTask *task = (GTask *)result;
g_assert (G_IS_OBJECT (object));
g_assert (G_IS_TASK (task));
if (out_mime_type != NULL)
*out_mime_type = g_strdup (g_task_get_task_data (task));
return g_task_propagate_pointer (task, error);
}
+2 -1
View File
@@ -155,12 +155,13 @@ void _gdk_macos_display_surface_became_key (GdkMacosDisp
GdkMacosSurface *surface);
void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self);
const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self);
void _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
void _gdk_macos_display_send_event (GdkMacosDisplay *self,
NSEvent *nsevent);
void _gdk_macos_display_warp_pointer (GdkMacosDisplay *self,
int x,
int y);
NSEvent *_gdk_macos_display_get_nsevent (GdkEvent *event);
NSEvent *_gdk_macos_display_get_last_nsevent (void);
GdkDrag *_gdk_macos_display_find_drag (GdkMacosDisplay *self,
NSInteger sequence_number);
GdkDrop *_gdk_macos_display_find_drop (GdkMacosDisplay *self,
+85 -74
View File
@@ -723,6 +723,85 @@ fill_scroll_event (GdkMacosDisplay *self,
return g_steal_pointer (&ret);
}
static GdkEvent *
fill_event (GdkMacosDisplay *self,
GdkMacosWindow *window,
NSEvent *nsevent,
int x,
int y)
{
GdkMacosSurface *surface = [window gdkSurface];
NSEventType event_type = [nsevent type];
GdkEvent *ret = NULL;
switch ((int)event_type)
{
case NSEventTypeLeftMouseDown:
case NSEventTypeRightMouseDown:
case NSEventTypeOtherMouseDown:
case NSEventTypeLeftMouseUp:
case NSEventTypeRightMouseUp:
case NSEventTypeOtherMouseUp:
ret = fill_button_event (self, surface, nsevent, x, y);
break;
case NSEventTypeLeftMouseDragged:
case NSEventTypeRightMouseDragged:
case NSEventTypeOtherMouseDragged:
case NSEventTypeMouseMoved:
ret = fill_motion_event (self, surface, nsevent, x, y);
break;
case NSEventTypeMagnify:
case NSEventTypeRotate:
ret = fill_pinch_event (self, surface, nsevent, x, y);
break;
case NSEventTypeMouseExited:
case NSEventTypeMouseEntered:
{
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
GdkDevice *pointer = gdk_seat_get_pointer (seat);
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer);
if ([(GdkMacosWindow *)window isInManualResizeOrMove])
{
ret = GDK_MACOS_EVENT_DROP;
}
else if (grab == NULL || grab->owner_events)
{
if (event_type == NSEventTypeMouseExited)
[[NSCursor arrowCursor] set];
ret = synthesize_crossing_event (self, surface, nsevent, x, y);
}
}
break;
case NSEventTypeKeyDown:
case NSEventTypeKeyUp:
case NSEventTypeFlagsChanged: {
GdkEventType type = _gdk_macos_keymap_get_event_type (nsevent);
if (type)
ret = fill_key_event (self, surface, nsevent, type);
break;
}
case NSEventTypeScrollWheel:
ret = fill_scroll_event (self, surface, nsevent, x, y);
break;
default:
break;
}
return ret;
}
static gboolean
is_mouse_button_press_event (NSEventType type)
{
@@ -1025,16 +1104,12 @@ find_surface_for_ns_event (GdkMacosDisplay *self,
GdkMacosBaseView *view;
GdkSurface *surface;
NSPoint point;
int x_tmp;
int y_tmp;
g_assert (GDK_IS_MACOS_DISPLAY (self));
g_assert (nsevent != NULL);
g_assert (x != NULL);
g_assert (y != NULL);
_gdk_macos_display_from_display_coords (self, point.x, point.y, &x_tmp, &y_tmp);
switch ((int)[nsevent type])
{
case NSEventTypeLeftMouseDown:
@@ -1083,7 +1158,6 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
GdkMacosWindow *window;
NSEventType event_type;
NSWindow *event_window;
GdkEvent *ret = NULL;
int x;
int y;
@@ -1191,79 +1265,15 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
_gdk_macos_display_clear_sorting (self);
}
}
switch ((int)event_type)
{
case NSEventTypeLeftMouseDown:
case NSEventTypeRightMouseDown:
case NSEventTypeOtherMouseDown:
case NSEventTypeLeftMouseUp:
case NSEventTypeRightMouseUp:
case NSEventTypeOtherMouseUp:
ret = fill_button_event (self, surface, nsevent, x, y);
break;
case NSEventTypeLeftMouseDragged:
case NSEventTypeRightMouseDragged:
case NSEventTypeOtherMouseDragged:
case NSEventTypeMouseMoved:
ret = fill_motion_event (self, surface, nsevent, x, y);
break;
case NSEventTypeMagnify:
case NSEventTypeRotate:
ret = fill_pinch_event (self, surface, nsevent, x, y);
break;
case NSEventTypeMouseExited:
case NSEventTypeMouseEntered:
{
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
GdkDevice *pointer = gdk_seat_get_pointer (seat);
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer);
if ([(GdkMacosWindow *)window isInManualResizeOrMove])
{
ret = GDK_MACOS_EVENT_DROP;
}
else if (grab == NULL)
{
if (event_type == NSEventTypeMouseExited)
[[NSCursor arrowCursor] set];
ret = synthesize_crossing_event (self, surface, nsevent, x, y);
}
}
break;
case NSEventTypeKeyDown:
case NSEventTypeKeyUp:
case NSEventTypeFlagsChanged: {
GdkEventType type = _gdk_macos_keymap_get_event_type (nsevent);
if (type)
ret = fill_key_event (self, surface, nsevent, type);
break;
}
case NSEventTypeScrollWheel:
ret = fill_scroll_event (self, surface, nsevent, x, y);
break;
default:
break;
}
return ret;
return fill_event (self, window, nsevent, x, y);
}
void
_gdk_macos_display_send_button_event (GdkMacosDisplay *self,
NSEvent *nsevent)
_gdk_macos_display_send_event (GdkMacosDisplay *self,
NSEvent *nsevent)
{
GdkMacosSurface *surface;
GdkMacosWindow *window;
GdkEvent *event;
int x;
int y;
@@ -1272,7 +1282,8 @@ _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
g_return_if_fail (nsevent != NULL);
if ((surface = find_surface_for_ns_event (self, nsevent, &x, &y)) &&
(event = fill_button_event (self, surface, nsevent, x, y)))
(window = (GdkMacosWindow *)_gdk_macos_surface_get_native (surface)) &&
(event = fill_event (self, window, nsevent, x, y)))
_gdk_windowing_got_event (GDK_DISPLAY (self),
_gdk_event_queue_append (GDK_DISPLAY (self), event),
event,
+10
View File
@@ -1024,6 +1024,16 @@ _gdk_macos_display_get_nsevent (GdkEvent *event)
return NULL;
}
NSEvent *
_gdk_macos_display_get_last_nsevent ()
{
const GdkToNSEventMap *map = g_queue_peek_tail (&event_map);
if (map)
return map->nsevent;
return NULL;
}
GdkDrag *
_gdk_macos_display_find_drag (GdkMacosDisplay *self,
NSInteger sequence_number)
+16 -3
View File
@@ -41,7 +41,6 @@ struct _GdkMacosDrag
GdkDrag parent_instance;
GdkMacosDragSurface *drag_surface;
GdkSeat *drag_seat;
GdkCursor *cursor;
int hot_x;
@@ -62,8 +61,22 @@ struct _GdkMacosDragClass
GdkDragClass parent_class;
};
GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
gboolean _gdk_macos_drag_begin (GdkMacosDrag *self);
GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
gboolean _gdk_macos_drag_begin (GdkMacosDrag *self,
GdkContentProvider *content,
GdkMacosWindow *window);
NSDragOperation _gdk_macos_drag_operation (GdkMacosDrag *self);
GdkDragAction _gdk_macos_drag_ns_operation_to_action
(NSDragOperation operation);
void _gdk_macos_drag_surface_move (GdkMacosDrag *self,
int x_root,
int y_root);
void _gdk_macos_drag_set_start_position (GdkMacosDrag *self,
int start_x,
int start_y);
void _gdk_macos_drag_set_actions (GdkMacosDrag *self,
GdkModifierType mods);
G_END_DECLS
+106 -271
View File
@@ -25,6 +25,7 @@
#include "gdkmacoscursor-private.h"
#include "gdkmacosdisplay-private.h"
#include "gdkmacosdragsurface-private.h"
#include "gdkmacospasteboard-private.h"
#include "gdk/gdkdeviceprivate.h"
#include "gdk/gdkeventsprivate.h"
@@ -187,47 +188,6 @@ gdk_macos_drag_set_cursor (GdkDrag *drag,
[nscursor set];
}
static gboolean
drag_grab (GdkMacosDrag *self)
{
GdkSeat *seat;
g_assert (GDK_IS_MACOS_DRAG (self));
seat = gdk_device_get_seat (gdk_drag_get_device (GDK_DRAG (self)));
if (gdk_seat_grab (seat,
GDK_SURFACE (self->drag_surface),
GDK_SEAT_CAPABILITY_ALL_POINTING,
FALSE,
self->cursor,
NULL,
NULL,
NULL) != GDK_GRAB_SUCCESS)
return FALSE;
g_set_object (&self->drag_seat, seat);
return TRUE;
}
static void
drag_ungrab (GdkMacosDrag *self)
{
GdkDisplay *display;
g_assert (GDK_IS_MACOS_DRAG (self));
if (self->drag_seat)
{
gdk_seat_ungrab (self->drag_seat);
g_clear_object (&self->drag_seat);
}
display = gdk_drag_get_display (GDK_DRAG (self));
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), GDK_CURRENT_TIME);
}
static void
gdk_macos_drag_cancel (GdkDrag *drag,
GdkDragCancelReason reason)
@@ -240,7 +200,6 @@ gdk_macos_drag_cancel (GdkDrag *drag,
return;
self->cancelled = TRUE;
drag_ungrab (self);
gdk_drag_drop_done (drag, FALSE);
}
@@ -253,7 +212,6 @@ gdk_macos_drag_drop_performed (GdkDrag *drag,
g_assert (GDK_IS_MACOS_DRAG (self));
g_object_ref (self);
drag_ungrab (self);
g_signal_emit_by_name (drag, "dnd-finished");
gdk_drag_drop_done (drag, TRUE);
g_object_unref (self);
@@ -316,225 +274,6 @@ gdk_drag_get_current_actions (GdkModifierType state,
}
}
static void
gdk_drag_update (GdkDrag *drag,
double x_root,
double y_root,
GdkModifierType mods,
guint32 evtime)
{
GdkMacosDrag *self = (GdkMacosDrag *)drag;
GdkDragAction suggested_action;
GdkDragAction possible_actions;
g_assert (GDK_IS_MACOS_DRAG (self));
self->last_x = x_root;
self->last_y = y_root;
gdk_drag_get_current_actions (mods,
GDK_BUTTON_PRIMARY,
gdk_drag_get_actions (drag),
&suggested_action,
&possible_actions);
if (GDK_IS_MACOS_SURFACE (self->drag_surface))
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
x_root - self->hot_x,
y_root - self->hot_y);
if (!self->did_update)
{
self->start_x = self->last_x;
self->start_y = self->last_y;
self->did_update = TRUE;
}
gdk_drag_set_actions (drag, possible_actions);
}
static gboolean
gdk_dnd_handle_motion_event (GdkDrag *drag,
GdkEvent *event)
{
double x, y;
int x_root, y_root;
g_assert (GDK_IS_MACOS_DRAG (drag));
g_assert (event != NULL);
/* Ignore motion while doing zoomback */
if (GDK_MACOS_DRAG (drag)->cancelled)
return FALSE;
gdk_event_get_position (event, &x, &y);
x_root = event->surface->x + x;
y_root = event->surface->y + y;
gdk_drag_update (drag, x_root, y_root,
gdk_event_get_modifier_state (event),
gdk_event_get_time (event));
return TRUE;
}
static gboolean
gdk_dnd_handle_grab_broken_event (GdkDrag *drag,
GdkEvent *event)
{
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
gboolean is_implicit = gdk_grab_broken_event_get_implicit (event);
GdkSurface *grab_surface = gdk_grab_broken_event_get_grab_surface (event);
/* Don't cancel if we break the implicit grab from the initial button_press. */
if (is_implicit || grab_surface == (GdkSurface *)self->drag_surface)
return FALSE;
if (gdk_event_get_device (event) != gdk_drag_get_device (drag))
return FALSE;
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_ERROR);
return TRUE;
}
static gboolean
gdk_dnd_handle_button_event (GdkDrag *drag,
GdkEvent *event)
{
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
g_assert (GDK_IS_MACOS_DRAG (self));
g_assert (event != NULL);
#if 0
/* FIXME: Check the button matches */
if (event->button != self->button)
return FALSE;
#endif
if (gdk_drag_get_selected_action (drag) != 0)
g_signal_emit_by_name (drag, "drop-performed");
else
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
return TRUE;
}
static gboolean
gdk_dnd_handle_key_event (GdkDrag *drag,
GdkEvent *event)
{
GdkMacosDrag *self = GDK_MACOS_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)
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_macos_device_query_state (pointer, NULL, NULL, NULL, NULL, &state);
if (dx != 0 || dy != 0)
{
GdkDisplay *display = gdk_event_get_display ((GdkEvent *)event);
self->last_x += dx;
self->last_y += dy;
_gdk_macos_display_warp_pointer (GDK_MACOS_DISPLAY (display),
self->last_x,
self->last_y);
}
gdk_drag_update (drag,
self->last_x, self->last_y,
state,
gdk_event_get_time (event));
return TRUE;
}
static gboolean
gdk_macos_drag_handle_event (GdkDrag *drag,
GdkEvent *event)
{
g_assert (GDK_IS_MACOS_DRAG (drag));
g_assert (event != NULL);
switch ((guint) event->event_type)
{
case GDK_MOTION_NOTIFY:
return gdk_dnd_handle_motion_event (drag, event);
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);
default:
return FALSE;
}
}
static void
gdk_macos_drag_finalize (GObject *object)
{
@@ -542,11 +281,6 @@ gdk_macos_drag_finalize (GObject *object)
GdkMacosDragSurface *drag_surface = g_steal_pointer (&self->drag_surface);
g_clear_object (&self->cursor);
if (self->drag_seat)
{
gdk_seat_ungrab (self->drag_seat);
g_clear_object (&self->drag_seat);
}
G_OBJECT_CLASS (gdk_macos_drag_parent_class)->finalize (object);
@@ -608,7 +342,6 @@ gdk_macos_drag_class_init (GdkMacosDragClass *klass)
drag_class->set_cursor = gdk_macos_drag_set_cursor;
drag_class->cancel = gdk_macos_drag_cancel;
drag_class->drop_performed = gdk_macos_drag_drop_performed;
drag_class->handle_event = gdk_macos_drag_handle_event;
properties [PROP_DRAG_SURFACE] =
g_param_spec_object ("drag-surface", NULL, NULL,
@@ -624,11 +357,113 @@ gdk_macos_drag_init (GdkMacosDrag *self)
}
gboolean
_gdk_macos_drag_begin (GdkMacosDrag *self)
_gdk_macos_drag_begin (GdkMacosDrag *self,
GdkContentProvider *content,
GdkMacosWindow *window)
{
NSArray<NSDraggingItem *> *items;
NSDraggingSession *session;
NSPasteboardItem *item;
NSEvent *nsevent;
g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), FALSE);
g_return_val_if_fail (GDK_IS_MACOS_WINDOW (window), FALSE);
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self->drag_surface));
GDK_BEGIN_MACOS_ALLOC_POOL;
return drag_grab (self);
item = [[GdkMacosPasteboardItem alloc] initForDrag:GDK_DRAG (self) withContentProvider:content];
items = [NSArray arrayWithObject:item];
nsevent = _gdk_macos_display_get_last_nsevent ();
session = [[window contentView] beginDraggingSessionWithItems:items
event:nsevent
source:window];
GDK_END_MACOS_ALLOC_POOL;
_gdk_macos_display_set_drag (GDK_MACOS_DISPLAY (gdk_drag_get_display (GDK_DRAG (self))),
[session draggingSequenceNumber],
GDK_DRAG (self));
return TRUE;
}
NSDragOperation
_gdk_macos_drag_operation (GdkMacosDrag *self)
{
NSDragOperation operation = NSDragOperationNone;
GdkDragAction actions;
g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), NSDragOperationNone);
actions = gdk_drag_get_actions (GDK_DRAG (self));
if (actions & GDK_ACTION_LINK)
operation |= NSDragOperationLink;
if (actions & GDK_ACTION_MOVE)
operation |= NSDragOperationMove;
if (actions & GDK_ACTION_COPY)
operation |= NSDragOperationCopy;
return operation;
}
GdkDragAction
_gdk_macos_drag_ns_operation_to_action (NSDragOperation operation)
{
if (operation & NSDragOperationCopy)
return GDK_ACTION_COPY;
if (operation & NSDragOperationMove)
return GDK_ACTION_MOVE;
if (operation & NSDragOperationLink)
return GDK_ACTION_LINK;
return 0;
}
void
_gdk_macos_drag_surface_move (GdkMacosDrag *self,
int x_root,
int y_root)
{
g_return_if_fail (GDK_IS_MACOS_DRAG (self));
self->last_x = x_root;
self->last_y = y_root;
if (GDK_IS_MACOS_SURFACE (self->drag_surface))
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
x_root - self->hot_x,
y_root - self->hot_y);
}
void
_gdk_macos_drag_set_start_position (GdkMacosDrag *self,
int start_x,
int start_y)
{
g_return_if_fail (GDK_IS_MACOS_DRAG (self));
self->start_x = start_x;
self->start_y = start_y;
}
void
_gdk_macos_drag_set_actions (GdkMacosDrag *self,
GdkModifierType mods)
{
GdkDragAction suggested_action;
GdkDragAction possible_actions;
g_assert (GDK_IS_MACOS_DRAG (self));
gdk_drag_get_current_actions (mods,
GDK_BUTTON_PRIMARY,
gdk_drag_get_actions (GDK_DRAG (self)),
&suggested_action,
&possible_actions);
gdk_drag_set_selected_action (GDK_DRAG (self), suggested_action);
gdk_drag_set_actions (GDK_DRAG (self), possible_actions);
}
+42 -26
View File
@@ -37,11 +37,15 @@
/*
* This file implementations integration between the GLib main loop and
* the native system of the Core Foundation run loop and Cocoa event
* handling. There are basically two different cases that we need to
* handle: either the GLib main loop is in control (the application
* has called gtk_main(), or is otherwise iterating the main loop), or
* CFRunLoop is in control (we are in a modal operation such as window
* resizing or drag-and-drop.)
* handling. There are basically three different cases that we need to
* handle:
*
* - the GLib main loop is in control. The application has called
* gtk_main(), or is otherwise iterating the main loop.
* - CFRunLoop is in control. We are in a modal operation such as window
* resizing.
* - CFRunLoop is running a nested loop. This happens when a drag-and-drop
* operation has been initiated.
*
* When the GLib main loop is in control we integrate in native event
* handling in two ways: first we add a GSource that handles checking
@@ -57,14 +61,23 @@
* stages of the GLib main loop (prepare, check, dispatch), and make the
* appropriate calls into GLib.
*
* Both cases share a single problem: the OS X APIs dont allow us to
* When initiating a drag operation, a nested CFRunLoop is executed.
* The nested run loop is started when fetching a native event in our GLib
* main loop. The application does not receive any events until the nested loop
* is finished. We work around this by forwarding the
* events that trigger the callbacks of the NSDraggingSource protocol.
* The "run loop observer" is executing the GLib main loop stages as long as we're
* in the nested run loop, as if CFRunLoop were in control.
* See also GdkMacosWindow.
*
* All cases share a single problem: the macOS APIs dont allow us to
* wait simultaneously for file descriptors and for events. So when we
* need to do a blocking wait that includes file descriptor activity, we
* push the actual work of calling select() to a helper thread (the
* "select thread") and wait for native events in the main thread.
*
* The main known limitation of this code is that if a callback is triggered
* via the OS X run loop while we are "polling" (in either case described
* via the macOS run loop while we are "polling" (in either case described
* above), iteration of the GLib main loop is not possible from within
* that callback. If the programmer tries to do so explicitly, then they
* will get a warning from GLib "main loop already active in another thread".
@@ -640,6 +653,23 @@ _gdk_macos_event_source_get_pending (void)
return event;
}
static void
_gdk_macos_event_source_queue_event (NSEvent *event)
{
/* Just used to wake us up; if an event and a FD arrived at the same
* time; could have come from a previous iteration in some cases,
* but the spurious wake up is harmless if a little inefficient.
*/
if (!event ||
([event type] == NSEventTypeApplicationDefined &&
[event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP))
return;
if (!current_events)
current_events = g_queue_new ();
g_queue_push_head (current_events, [event retain]);
}
static gboolean
gdk_macos_event_source_prepare (GSource *source,
int *timeout)
@@ -782,23 +812,7 @@ poll_func (GPollFD *ufds,
if (last_ufds == ufds && n_ready < 0)
n_ready = select_thread_collect_poll (ufds, nfds);
if (event &&
[event type] == NSEventTypeApplicationDefined &&
[event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP)
{
/* Just used to wake us up; if an event and a FD arrived at the same
* time; could have come from a previous iteration in some cases,
* but the spurious wake up is harmless if a little inefficient.
*/
event = NULL;
}
if (event)
{
if (!current_events)
current_events = g_queue_new ();
g_queue_push_head (current_events, [event retain]);
}
_gdk_macos_event_source_queue_event (event);
return n_ready;
}
@@ -1018,7 +1032,10 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
break;
}
if (getting_events > 0) /* Activity we triggered */
/* DnD starts a nested runloop, or so it seems.
If we have such a loop, we still want to run
our idle handlers. */
if (getting_events > 0 && current_loop_level < 2)
return;
switch (activity)
@@ -1042,7 +1059,6 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
run_loop_exit ();
break;
case kCFRunLoopAllActivities:
/* TODO: Do most of the above? */
default:
break;
}
+9
View File
@@ -548,6 +548,14 @@ gdk_macos_gl_context_clear_current (GdkGLContext *context)
return TRUE;
}
static gboolean
gdk_macos_gl_context_is_current (GdkGLContext *context)
{
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
return self->cgl_context == CGLGetCurrentContext ();
}
static gboolean
gdk_macos_gl_context_make_current (GdkGLContext *context,
gboolean surfaceless)
@@ -639,6 +647,7 @@ gdk_macos_gl_context_class_init (GdkMacosGLContextClass *klass)
gl_class->get_damage = gdk_macos_gl_context_get_damage;
gl_class->clear_current = gdk_macos_gl_context_clear_current;
gl_class->is_current = gdk_macos_gl_context_is_current;
gl_class->make_current = gdk_macos_gl_context_make_current;
gl_class->realize = gdk_macos_gl_context_real_realize;
gl_class->get_default_framebuffer = gdk_macos_gl_context_get_default_framebuffer;
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright © 2021 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef __GDK_MACOS_PASTEBOARD_PRIVATE_H__
#define __GDK_MACOS_PASTEBOARD_PRIVATE_H__
#include <AppKit/AppKit.h>
#include <gio/gio.h>
#include "gdkclipboardprivate.h"
G_BEGIN_DECLS
@interface GdkMacosPasteboardItemDataProvider : NSObject <NSPasteboardItemDataProvider>
{
GdkContentProvider *_contentProvider;
GdkClipboard *_clipboard;
GdkDrag *_drag;
}
-(id)initForClipboard:(GdkClipboard *)clipboard withContentProvider:(GdkContentProvider *)contentProvider;
-(id)initForDrag:(GdkDrag *)drag withContentProvider:(GdkContentProvider *)contentProvider;
@end
@interface GdkMacosPasteboardItem : NSPasteboardItem
{
GdkContentProvider *_contentProvider;
GdkClipboard *_clipboard;
GdkDrag *_drag;
NSRect _draggingFrame;
}
-(id)initForClipboard:(GdkClipboard *)clipboard withContentProvider:(GdkContentProvider *)contentProvider;
-(id)initForDrag:(GdkDrag *)drag withContentProvider:(GdkContentProvider *)contentProvider;
@end
NSPasteboardType _gdk_macos_pasteboard_to_ns_type (const char *mime_type,
NSPasteboardType *alternate);
const char *_gdk_macos_pasteboard_from_ns_type (NSPasteboardType type);
GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
void _gdk_macos_pasteboard_register_drag_types (NSWindow *window);
void _gdk_macos_pasteboard_read_async (GObject *object,
NSPasteboard *pasteboard,
GdkContentFormats *formats,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
GAsyncResult *result,
const char **out_mime_type,
GError **error);
G_END_DECLS
#endif /* __GDK_MACOS_PASTEBOARD_PRIVATE_H__ */
+602
View File
@@ -0,0 +1,602 @@
/*
* Copyright © 2021 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#include <glib/gi18n.h>
#include "gdkdragprivate.h"
#include "gdkmacospasteboard-private.h"
#include "gdkmacosutils-private.h"
enum {
TYPE_STRING,
TYPE_PBOARD,
TYPE_URL,
TYPE_FILE_URL,
TYPE_COLOR,
TYPE_TIFF,
TYPE_PNG,
TYPE_LAST
};
#define PTYPE(k) (get_pasteboard_type(TYPE_##k))
static NSPasteboardType pasteboard_types[TYPE_LAST];
static NSPasteboardType
get_pasteboard_type (int type)
{
static gsize initialized = FALSE;
g_assert (type >= 0);
g_assert (type < TYPE_LAST);
if (g_once_init_enter (&initialized))
{
pasteboard_types[TYPE_PNG] = NSPasteboardTypePNG;
pasteboard_types[TYPE_STRING] = NSPasteboardTypeString;
pasteboard_types[TYPE_TIFF] = NSPasteboardTypeTIFF;
pasteboard_types[TYPE_COLOR] = NSPasteboardTypeColor;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
pasteboard_types[TYPE_PBOARD] = NSStringPboardType;
G_GNUC_END_IGNORE_DEPRECATIONS
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
pasteboard_types[TYPE_URL] = NSPasteboardTypeURL;
pasteboard_types[TYPE_FILE_URL] = NSPasteboardTypeFileURL;
#else
pasteboard_types[TYPE_URL] = [[NSString alloc] initWithUTF8String:"public.url"];
pasteboard_types[TYPE_FILE_URL] = [[NSString alloc] initWithUTF8String:"public.file-url"];
#endif
g_once_init_leave (&initialized, TRUE);
}
return pasteboard_types[type];
}
const char *
_gdk_macos_pasteboard_from_ns_type (NSPasteboardType type)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
if ([type isEqualToString:PTYPE(STRING)] ||
[type isEqualToString:PTYPE(PBOARD)])
return g_intern_string ("text/plain;charset=utf-8");
else if ([type isEqualToString:PTYPE(URL)] ||
[type isEqualToString:PTYPE(FILE_URL)])
return g_intern_string ("text/uri-list");
else if ([type isEqualToString:PTYPE(COLOR)])
return g_intern_string ("application/x-color");
else if ([type isEqualToString:PTYPE(TIFF)])
return g_intern_string ("image/tiff");
else if ([type isEqualToString:PTYPE(PNG)])
return g_intern_string ("image/png");
G_GNUC_END_IGNORE_DEPRECATIONS;
return NULL;
}
NSPasteboardType
_gdk_macos_pasteboard_to_ns_type (const char *mime_type,
NSPasteboardType *alternate)
{
if (alternate)
*alternate = NULL;
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
{
return PTYPE(STRING);
}
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
{
if (alternate)
*alternate = PTYPE(URL);
return PTYPE(FILE_URL);
}
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
{
return PTYPE(COLOR);
}
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
{
return PTYPE(TIFF);
}
else if (g_strcmp0 (mime_type, "image/png") == 0)
{
return PTYPE(PNG);
}
return nil;
}
static void
populate_content_formats (GdkContentFormatsBuilder *builder,
NSPasteboardType type)
{
const char *mime_type;
g_assert (builder != NULL);
g_assert (type != NULL);
if ((mime_type = _gdk_macos_pasteboard_from_ns_type (type)))
gdk_content_formats_builder_add_mime_type (builder, mime_type);
}
static GdkContentFormats *
load_offer_formats (NSPasteboard *pasteboard)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkContentFormatsBuilder *builder;
GdkContentFormats *formats;
builder = gdk_content_formats_builder_new ();
for (NSPasteboardType type in [pasteboard types])
populate_content_formats (builder, type);
formats = gdk_content_formats_builder_free_to_formats (builder);
GDK_END_MACOS_ALLOC_POOL;
return g_steal_pointer (&formats);
}
GdkContentFormats *
_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
{
return load_offer_formats (pasteboard);
}
static GInputStream *
create_stream_from_nsdata (NSData *data)
{
const guint8 *bytes = [data bytes];
gsize len = [data length];
return g_memory_input_stream_new_from_data (g_memdup2 (bytes, len), len, g_free);
}
void
_gdk_macos_pasteboard_read_async (GObject *object,
NSPasteboard *pasteboard,
GdkContentFormats *formats,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkContentFormats *offer_formats = NULL;
const char *mime_type;
GInputStream *stream = NULL;
GTask *task = NULL;
g_assert (G_IS_OBJECT (object));
g_assert (pasteboard != NULL);
g_assert (formats != NULL);
task = g_task_new (object, cancellable, callback, user_data);
g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
g_task_set_priority (task, io_priority);
offer_formats = load_offer_formats (pasteboard);
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
if (mime_type == NULL)
{
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"%s",
_("No compatible transfer format found"));
goto cleanup;
}
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
{
NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
if (nsstr != NULL)
{
const char *str = [nsstr UTF8String];
stream = g_memory_input_stream_new_from_data (g_strdup (str),
strlen (str) + 1,
g_free);
}
}
else if (strcmp (mime_type, "text/uri-list") == 0)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
{
GString *str = g_string_new (NULL);
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
gsize n_files = [files count];
char *data;
guint len;
for (gsize i = 0; i < n_files; ++i)
{
NSString* uriString = [files objectAtIndex:i];
uriString = [@"file://" stringByAppendingString:uriString];
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
g_string_append_printf (str,
"%s\r\n",
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
}
len = str->len;
data = g_string_free (str, FALSE);
stream = g_memory_input_stream_new_from_data (data, len, g_free);
}
G_GNUC_END_IGNORE_DEPRECATIONS;
}
else if (strcmp (mime_type, "application/x-color") == 0)
{
NSColorSpace *colorspace;
NSColor *nscolor;
guint16 color[4];
colorspace = [NSColorSpace genericRGBColorSpace];
nscolor = [[NSColor colorFromPasteboard:pasteboard]
colorUsingColorSpace:colorspace];
color[0] = 0xffff * [nscolor redComponent];
color[1] = 0xffff * [nscolor greenComponent];
color[2] = 0xffff * [nscolor blueComponent];
color[3] = 0xffff * [nscolor alphaComponent];
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
sizeof color,
g_free);
}
else if (strcmp (mime_type, "image/tiff") == 0)
{
NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
stream = create_stream_from_nsdata (data);
}
else if (strcmp (mime_type, "image/png") == 0)
{
NSData *data = [pasteboard dataForType:PTYPE(PNG)];
stream = create_stream_from_nsdata (data);
}
if (stream != NULL)
{
g_task_set_task_data (task, g_strdup (mime_type), g_free);
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
}
else
{
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Failed to decode contents with mime-type of '%s'"),
mime_type);
}
cleanup:
g_clear_object (&task);
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
GDK_END_MACOS_ALLOC_POOL;
}
GInputStream *
_gdk_macos_pasteboard_read_finish (GObject *object,
GAsyncResult *result,
const char **out_mime_type,
GError **error)
{
GTask *task = (GTask *)result;
g_assert (G_IS_OBJECT (object));
g_assert (G_IS_TASK (task));
if (out_mime_type != NULL)
*out_mime_type = g_strdup (g_task_get_task_data (task));
return g_task_propagate_pointer (task, error);
}
void
_gdk_macos_pasteboard_register_drag_types (NSWindow *window)
{
[window registerForDraggedTypes:[NSArray arrayWithObjects:PTYPE(STRING),
PTYPE(PBOARD),
PTYPE(URL),
PTYPE(FILE_URL),
PTYPE(COLOR),
PTYPE(TIFF),
PTYPE(PNG),
nil]];
}
@implementation GdkMacosPasteboardItemDataProvider
-(id)initForClipboard:(GdkClipboard*)clipboard withContentProvider:(GdkContentProvider*)contentProvider
{
[super init];
g_set_object (&self->_clipboard, clipboard);
g_set_object (&self->_contentProvider, contentProvider);
return self;
}
-(id)initForDrag:(GdkDrag*)drag withContentProvider:(GdkContentProvider*)contentProvider
{
[super init];
g_set_object (&self->_drag, drag);
g_set_object (&self->_contentProvider, contentProvider);
return self;
}
-(void)dealloc
{
g_clear_object (&self->_contentProvider);
g_clear_object (&self->_clipboard);
g_clear_object (&self->_drag);
[super dealloc];
}
-(NSArray<NSPasteboardType> *)types
{
NSMutableArray *ret = [[NSMutableArray alloc] init];
GdkContentFormats *serializable;
const char * const *mime_types;
gsize n_mime_types;
serializable = gdk_content_provider_ref_storable_formats (self->_contentProvider);
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
for (gsize i = 0; i < n_mime_types; i++)
{
const char *mime_type = mime_types[i];
NSPasteboardType type;
NSPasteboardType alternate = nil;
if ((type = _gdk_macos_pasteboard_to_ns_type (mime_type, &alternate)))
{
[ret addObject:type];
if (alternate)
[ret addObject:alternate];
}
}
gdk_content_formats_unref (serializable);
/* Default to an url type (think gobject://internal)
* to support internal, GType-based DnD.
*/
if (n_mime_types == 0)
{
GdkContentFormats *formats;
gsize n_gtypes;
formats = gdk_content_provider_ref_formats (self->_contentProvider);
gdk_content_formats_get_gtypes (formats, &n_gtypes);
if (n_gtypes)
[ret addObject:NSPasteboardTypeURL];
gdk_content_formats_unref (formats);
}
return g_steal_pointer (&ret);
}
typedef struct
{
GMemoryOutputStream *stream;
NSPasteboardItem *item;
NSPasteboardType type;
GMainContext *main_context;
guint done : 1;
} WriteRequest;
static void
write_request_free (WriteRequest *wr)
{
g_clear_pointer (&wr->main_context, g_main_context_unref);
g_clear_object (&wr->stream);
[wr->item release];
g_slice_free (WriteRequest, wr);
}
static void
on_data_ready_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
WriteRequest *wr = user_data;
GError *error = NULL;
NSData *data = nil;
gboolean ret;
g_assert (G_IS_OBJECT (object));
g_assert (GDK_IS_CLIPBOARD (object) || GDK_IS_DRAG (object));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (wr != NULL);
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
if (GDK_IS_CLIPBOARD (object))
ret = gdk_clipboard_write_finish (GDK_CLIPBOARD (object), result, &error);
else if (GDK_IS_DRAG (object))
ret = gdk_drag_write_finish (GDK_DRAG (object), result, &error);
else
g_return_if_reached ();
if (ret)
{
gsize size;
gpointer bytes;
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
size = g_memory_output_stream_get_data_size (wr->stream);
bytes = g_memory_output_stream_steal_data (wr->stream);
data = [[NSData alloc] initWithBytesNoCopy:bytes
length:size
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
}
else
{
g_warning ("Failed to serialize pasteboard contents: %s",
error->message);
g_clear_error (&error);
}
[wr->item setData:data forType:wr->type];
wr->done = TRUE;
GDK_END_MACOS_ALLOC_POOL;
}
-(void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSPasteboardType)type
{
const char *mime_type = _gdk_macos_pasteboard_from_ns_type (type);
GMainContext *main_context = g_main_context_default ();
WriteRequest *wr;
if (self->_contentProvider == NULL || mime_type == NULL)
{
[item setData:[NSData data] forType:type];
return;
}
wr = g_slice_new0 (WriteRequest);
wr->item = [item retain];
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
wr->type = type;
wr->main_context = g_main_context_ref (main_context);
wr->done = FALSE;
if (GDK_IS_CLIPBOARD (self->_clipboard))
gdk_clipboard_write_async (self->_clipboard,
mime_type,
G_OUTPUT_STREAM (wr->stream),
G_PRIORITY_DEFAULT,
NULL,
on_data_ready_cb,
wr);
else if (GDK_IS_DRAG (self->_drag))
gdk_drag_write_async (self->_drag,
mime_type,
G_OUTPUT_STREAM (wr->stream),
G_PRIORITY_DEFAULT,
NULL,
on_data_ready_cb,
wr);
else
g_return_if_reached ();
/* We're forced to provide data synchronously via this API
* so we must block on the main loop. Using another main loop
* than the default tends to get us locked up here, so that is
* what we'll do for now.
*/
while (!wr->done)
g_main_context_iteration (wr->main_context, TRUE);
write_request_free (wr);
}
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
{
g_clear_object (&self->_clipboard);
g_clear_object (&self->_drag);
g_clear_object (&self->_contentProvider);
}
@end
@implementation GdkMacosPasteboardItem
-(id)initForClipboard:(GdkClipboard*)clipboard withContentProvider:(GdkContentProvider*)contentProvider
{
GdkMacosPasteboardItemDataProvider *dataProvider;
dataProvider = [[GdkMacosPasteboardItemDataProvider alloc] initForClipboard:clipboard withContentProvider:contentProvider];
[super init];
g_set_object (&self->_clipboard, clipboard);
g_set_object (&self->_contentProvider, contentProvider);
[self setDataProvider:dataProvider forTypes:[dataProvider types]];
[dataProvider release];
return self;
}
-(id)initForDrag:(GdkDrag*)drag withContentProvider:(GdkContentProvider*)contentProvider
{
GdkMacosPasteboardItemDataProvider *dataProvider;
dataProvider = [[GdkMacosPasteboardItemDataProvider alloc] initForDrag:drag withContentProvider:contentProvider];
[super init];
g_set_object (&self->_drag, drag);
g_set_object (&self->_contentProvider, contentProvider);
[self setDataProvider:dataProvider forTypes:[dataProvider types]];
[dataProvider release];
return self;
}
-(void)dealloc
{
g_clear_object (&self->_contentProvider);
g_clear_object (&self->_clipboard);
g_clear_object (&self->_drag);
[super dealloc];
}
-(NSRect)draggingFrame
{
return self->_draggingFrame;
}
-(void)setDraggingFrame:(NSRect)draggingFrame;
{
self->_draggingFrame = draggingFrame;
}
-(id)item
{
return self;
}
-(NSArray* (^) (void))imageComponentsProvider
{
return nil;
}
@end
+1 -1
View File
@@ -446,7 +446,7 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
gdk_drag_get_selected_action (GDK_DRAG (drag)));
gdk_drag_set_cursor (GDK_DRAG (drag), cursor);
if (!_gdk_macos_drag_begin (drag))
if (!_gdk_macos_drag_begin (drag, content, self->window))
{
g_object_unref (drag);
return NULL;
+1
View File
@@ -19,6 +19,7 @@ gdk_macos_sources = files([
'gdkmacoseventsource.c',
'gdkmacoskeymap.c',
'gdkmacosmonitor.c',
'gdkmacospasteboard.c',
'gdkmacospopupsurface.c',
'gdkmacosseat.c',
'gdkmacossurface.c',
+250
View File
@@ -2,6 +2,236 @@
#define __GDK_DEVICE_WAYLAND_PRIVATE_H__
#include "gdkwaylanddevice.h"
#include "gdkwaylandseat.h"
#include <gdk/gdkdeviceprivate.h>
#include <gdk/gdkkeysprivate.h>
#include <xkbcommon/xkbcommon.h>
struct _GdkWaylandDevice
{
GdkDevice parent_instance;
};
struct _GdkWaylandDeviceClass
{
GdkDeviceClass parent_class;
};
typedef struct _GdkWaylandTouchData GdkWaylandTouchData;
typedef struct _GdkWaylandPointerFrameData GdkWaylandPointerFrameData;
typedef struct _GdkWaylandPointerData GdkWaylandPointerData;
typedef struct _GdkWaylandTabletPadGroupData GdkWaylandTabletPadGroupData;
typedef struct _GdkWaylandTabletPadData GdkWaylandTabletPadData;
typedef struct _GdkWaylandTabletData GdkWaylandTabletData;
typedef struct _GdkWaylandTabletToolData GdkWaylandTabletToolData;
struct _GdkWaylandTouchData
{
uint32_t id;
double x;
double y;
GdkSurface *surface;
uint32_t touch_down_serial;
guint initial_touch : 1;
};
struct _GdkWaylandPointerFrameData
{
GdkEvent *event;
/* Specific to the scroll event */
double delta_x, delta_y;
int32_t value120_x, value120_y;
gint8 is_scroll_stop;
enum wl_pointer_axis_source source;
};
struct _GdkWaylandPointerData {
GdkSurface *focus;
double surface_x, surface_y;
GdkModifierType button_modifiers;
uint32_t time;
uint32_t enter_serial;
uint32_t press_serial;
GdkSurface *grab_surface;
uint32_t grab_time;
struct wl_surface *pointer_surface;
guint cursor_is_default: 1;
GdkCursor *cursor;
guint cursor_timeout_id;
guint cursor_image_index;
guint cursor_image_delay;
guint touchpad_event_sequence;
guint current_output_scale;
GSList *pointer_surface_outputs;
/* Accumulated event data for a pointer frame */
GdkWaylandPointerFrameData frame;
};
struct _GdkWaylandTabletPadGroupData
{
GdkWaylandTabletPadData *pad;
struct zwp_tablet_pad_group_v2 *wp_tablet_pad_group;
GList *rings;
GList *strips;
GList *buttons;
guint mode_switch_serial;
guint n_modes;
guint current_mode;
struct {
guint source;
gboolean is_stop;
double value;
} axis_tmp_info;
};
struct _GdkWaylandTabletPadData
{
GdkSeat *seat;
struct zwp_tablet_pad_v2 *wp_tablet_pad;
GdkDevice *device;
GdkWaylandTabletData *current_tablet;
guint enter_serial;
uint32_t n_buttons;
char *path;
GList *rings;
GList *strips;
GList *mode_groups;
};
struct _GdkWaylandTabletToolData
{
GdkSeat *seat;
struct zwp_tablet_tool_v2 *wp_tablet_tool;
GdkAxisFlags axes;
GdkDeviceToolType type;
guint64 hardware_serial;
guint64 hardware_id_wacom;
GdkDeviceTool *tool;
GdkWaylandTabletData *current_tablet;
};
struct _GdkWaylandTabletData
{
struct zwp_tablet_v2 *wp_tablet;
char *name;
char *path;
uint32_t vid;
uint32_t pid;
GdkDevice *logical_device;
GdkDevice *stylus_device;
GdkSeat *seat;
GdkWaylandPointerData pointer_info;
GList *pads;
GdkWaylandTabletToolData *current_tool;
int axis_indices[GDK_AXIS_LAST];
double axes[GDK_AXIS_LAST];
};
struct _GdkWaylandSeat
{
GdkSeat parent_instance;
guint32 id;
struct wl_seat *wl_seat;
struct wl_pointer *wl_pointer;
struct wl_keyboard *wl_keyboard;
struct wl_touch *wl_touch;
struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe;
struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch;
struct zwp_pointer_gesture_hold_v1 *wp_pointer_gesture_hold;
struct zwp_tablet_seat_v2 *wp_tablet_seat;
GdkDisplay *display;
GdkDevice *logical_pointer;
GdkDevice *logical_keyboard;
GdkDevice *pointer;
GdkDevice *wheel_scrolling;
GdkDevice *finger_scrolling;
GdkDevice *continuous_scrolling;
GdkDevice *keyboard;
GdkDevice *logical_touch;
GdkDevice *touch;
GdkCursor *cursor;
GdkKeymap *keymap;
GHashTable *touches;
GList *tablets;
GList *tablet_tools;
GList *tablet_pads;
GdkWaylandPointerData pointer_info;
GdkWaylandPointerData touch_info;
GdkModifierType key_modifiers;
GdkSurface *keyboard_focus;
GdkSurface *grab_surface;
uint32_t grab_time;
gboolean have_server_repeat;
uint32_t server_repeat_rate;
uint32_t server_repeat_delay;
struct wl_data_offer *pending_offer;
GdkContentFormatsBuilder *pending_builder;
GdkDragAction pending_source_actions;
GdkDragAction pending_action;
struct wl_callback *repeat_callback;
guint32 repeat_timer;
guint32 repeat_key;
guint32 repeat_count;
gint64 repeat_deadline;
uint32_t keyboard_time;
uint32_t keyboard_key_serial;
GdkClipboard *clipboard;
GdkClipboard *primary_clipboard;
struct wl_data_device *data_device;
GdkDrag *drag;
GdkDrop *drop;
/* Some tracking on gesture events */
guint gesture_n_fingers;
double gesture_scale;
GdkCursor *grab_cursor;
};
#define GDK_TYPE_WAYLAND_DEVICE_PAD (gdk_wayland_device_pad_get_type ())
GType gdk_wayland_device_pad_get_type (void);
void gdk_wayland_seat_stop_cursor_animation (GdkWaylandSeat *seat,
GdkWaylandPointerData *pointer);
GdkWaylandPointerData * gdk_wayland_device_get_pointer (GdkWaylandDevice *wayland_device);
void gdk_wayland_device_set_pointer (GdkWaylandDevice *wayland_device,
GdkWaylandPointerData *pointer);
GdkWaylandTouchData * gdk_wayland_device_get_emulating_touch (GdkWaylandDevice *wayland_device);
void gdk_wayland_device_set_emulating_touch (GdkWaylandDevice *wayland_device,
GdkWaylandTouchData *touch);
void gdk_wayland_device_query_state (GdkDevice *device,
GdkSurface *surface,
@@ -14,4 +244,24 @@ void gdk_wayland_device_pad_set_feedback (GdkDevice *device,
guint feature_idx,
const char *label);
GdkWaylandTabletPadData * gdk_wayland_seat_find_pad (GdkWaylandSeat *seat,
GdkDevice *device);
GdkWaylandTabletData * gdk_wayland_seat_find_tablet (GdkWaylandSeat *seat,
GdkDevice *device);
GdkWaylandTouchData * gdk_wayland_seat_get_touch (GdkWaylandSeat *seat,
uint32_t id);
void gdk_wayland_device_maybe_emit_grab_crossing (GdkDevice *device,
GdkSurface *window,
guint32 time);
GdkSurface * gdk_wayland_device_maybe_emit_ungrab_crossing (GdkDevice *device,
guint32 time_);
gboolean gdk_wayland_device_update_surface_cursor (GdkDevice *device);
GdkModifierType gdk_wayland_device_get_modifiers (GdkDevice *device);
#endif
File diff suppressed because it is too large Load Diff
+266
View File
@@ -0,0 +1,266 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkwaylanddevice.h"
#include "gdkdevice-wayland-private.h"
#include "tablet-unstable-v2-client-protocol.h"
#include <gdk/gdkdevicepadprivate.h>
typedef struct _GdkWaylandDevicePad GdkWaylandDevicePad;
typedef struct _GdkWaylandDevicePadClass GdkWaylandDevicePadClass;
struct _GdkWaylandDevicePad
{
GdkWaylandDevice parent_instance;
};
struct _GdkWaylandDevicePadClass
{
GdkWaylandDeviceClass parent_class;
};
static void gdk_wayland_device_pad_iface_init (GdkDevicePadInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GdkWaylandDevicePad, gdk_wayland_device_pad,
GDK_TYPE_WAYLAND_DEVICE,
G_IMPLEMENT_INTERFACE (GDK_TYPE_DEVICE_PAD,
gdk_wayland_device_pad_iface_init))
static int
gdk_wayland_device_pad_get_n_groups (GdkDevicePad *pad)
{
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
GdkWaylandTabletPadData *data;
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
GDK_DEVICE (pad));
#ifdef G_DISABLE_ASSERT
if (data == NULL)
return 0;
#else
g_assert (data != NULL);
#endif
return g_list_length (data->mode_groups);
}
static int
gdk_wayland_device_pad_get_group_n_modes (GdkDevicePad *pad,
int n_group)
{
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
GdkWaylandTabletPadGroupData *group;
GdkWaylandTabletPadData *data;
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
GDK_DEVICE (pad));
#ifdef G_DISABLE_ASSERT
if (data == NULL)
return 0;
#else
g_assert (data != NULL);
#endif
group = g_list_nth_data (data->mode_groups, n_group);
if (!group)
return -1;
return group->n_modes;
}
static int
gdk_wayland_device_pad_get_n_features (GdkDevicePad *pad,
GdkDevicePadFeature feature)
{
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
GdkWaylandTabletPadData *data;
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
GDK_DEVICE (pad));
g_assert (data != NULL);
switch (feature)
{
case GDK_DEVICE_PAD_FEATURE_BUTTON:
return data->n_buttons;
case GDK_DEVICE_PAD_FEATURE_RING:
return g_list_length (data->rings);
case GDK_DEVICE_PAD_FEATURE_STRIP:
return g_list_length (data->strips);
default:
return -1;
}
}
static int
gdk_wayland_device_pad_get_feature_group (GdkDevicePad *pad,
GdkDevicePadFeature feature,
int idx)
{
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
GdkWaylandTabletPadGroupData *group;
GdkWaylandTabletPadData *data;
GList *l;
int i;
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
GDK_DEVICE (pad));
#ifdef G_DISABLE_ASSERT
if (data == NULL)
return -1;
#else
g_assert (data != NULL);
#endif
for (l = data->mode_groups, i = 0; l; l = l->next, i++)
{
group = l->data;
switch (feature)
{
case GDK_DEVICE_PAD_FEATURE_BUTTON:
if (g_list_find (group->buttons, GINT_TO_POINTER (idx)))
return i;
break;
case GDK_DEVICE_PAD_FEATURE_RING:
{
gpointer ring;
ring = g_list_nth_data (data->rings, idx);
if (ring && g_list_find (group->rings, ring))
return i;
break;
}
case GDK_DEVICE_PAD_FEATURE_STRIP:
{
gpointer strip;
strip = g_list_nth_data (data->strips, idx);
if (strip && g_list_find (group->strips, strip))
return i;
break;
}
default:
break;
}
}
return -1;
}
static void
gdk_wayland_device_pad_iface_init (GdkDevicePadInterface *iface)
{
iface->get_n_groups = gdk_wayland_device_pad_get_n_groups;
iface->get_group_n_modes = gdk_wayland_device_pad_get_group_n_modes;
iface->get_n_features = gdk_wayland_device_pad_get_n_features;
iface->get_feature_group = gdk_wayland_device_pad_get_feature_group;
}
static void
gdk_wayland_device_pad_class_init (GdkWaylandDevicePadClass *klass)
{
}
static void
gdk_wayland_device_pad_init (GdkWaylandDevicePad *pad)
{
}
static GdkWaylandTabletPadGroupData *
tablet_pad_lookup_button_group (GdkWaylandTabletPadData *pad,
uint32_t button)
{
GdkWaylandTabletPadGroupData *group;
GList *l;
for (l = pad->mode_groups; l; l = l->next)
{
group = l->data;
if (g_list_find (group->buttons, GUINT_TO_POINTER (button)))
return group;
}
return NULL;
}
/*<private>
* gdk_wayland_device_pad_set_feedback:
* @device: (type GdkWaylandDevice): a %GDK_SOURCE_TABLET_PAD device
* @feature: Feature to set the feedback label for
* @feature_idx: 0-indexed index of the feature to set the feedback label for
* @label: Feedback label
*
* Sets the feedback label for the given feature/index.
*
* This may be used by the compositor to provide user feedback
* of the actions available/performed.
*/
void
gdk_wayland_device_pad_set_feedback (GdkDevice *device,
GdkDevicePadFeature feature,
guint feature_idx,
const char *label)
{
GdkWaylandTabletPadData *pad;
GdkWaylandTabletPadGroupData *group;
GdkSeat *seat;
seat = gdk_device_get_seat (device);
pad = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat), device);
if (!pad)
return;
if (feature == GDK_DEVICE_PAD_FEATURE_BUTTON)
{
group = tablet_pad_lookup_button_group (pad, feature_idx);
if (!group)
return;
zwp_tablet_pad_v2_set_feedback (pad->wp_tablet_pad, feature_idx, label,
group->mode_switch_serial);
}
else if (feature == GDK_DEVICE_PAD_FEATURE_RING)
{
struct zwp_tablet_pad_ring_v2 *wp_pad_ring;
wp_pad_ring = g_list_nth_data (pad->rings, feature_idx);
if (!wp_pad_ring)
return;
group = zwp_tablet_pad_ring_v2_get_user_data (wp_pad_ring);
zwp_tablet_pad_ring_v2_set_feedback (wp_pad_ring, label,
group->mode_switch_serial);
}
else if (feature == GDK_DEVICE_PAD_FEATURE_STRIP)
{
struct zwp_tablet_pad_strip_v2 *wp_pad_strip;
wp_pad_strip = g_list_nth_data (pad->strips, feature_idx);
if (!wp_pad_strip)
return;
group = zwp_tablet_pad_strip_v2_get_user_data (wp_pad_strip);
zwp_tablet_pad_strip_v2_set_feedback (wp_pad_strip, label,
group->mode_switch_serial);
}
}
+13 -3
View File
@@ -832,6 +832,8 @@ gdk_wayland_display_get_next_serial (GdkDisplay *display)
* if no ID has been defined.
*
* Returns: (nullable): the startup notification ID for @display
*
* Deprecated: 4.10.
*/
const char *
gdk_wayland_display_get_startup_notification_id (GdkDisplay *display)
@@ -853,6 +855,8 @@ gdk_wayland_display_get_startup_notification_id (GdkDisplay *display)
* The startup ID is also what is used to signal that the startup is
* complete (for example, when opening a window or when calling
* [method@Gdk.Display.notify_startup_complete]).
*
* Deprecated: 4.10. Use [method@Gdk.Toplevel.set_startup_id]
*/
void
gdk_wayland_display_set_startup_notification_id (GdkDisplay *display,
@@ -981,7 +985,9 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
display_class->queue_events = _gdk_wayland_display_queue_events;
display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context;
display_class->get_next_serial = gdk_wayland_display_get_next_serial;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
display_class->get_startup_notification_id = gdk_wayland_display_get_startup_notification_id;
G_GNUC_END_IGNORE_DEPRECATIONS
display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete;
display_class->create_surface = _gdk_wayland_display_create_surface;
display_class->get_keymap = _gdk_wayland_display_get_keymap;
@@ -2326,6 +2332,7 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
monitor->x, monitor->y,
monitor->width, monitor->height });
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
gdk_monitor_set_description (GDK_MONITOR (monitor), monitor->description);
monitor->wl_output_done = FALSE;
monitor->xdg_output_done = FALSE;
@@ -2382,7 +2389,7 @@ xdg_output_handle_name (void *data,
{
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
GDK_DEBUG (MISC, "handle name xdg-output %d", monitor->id);
GDK_DEBUG (MISC, "handle name xdg-output %d: %s", monitor->id, name);
monitor->name = g_strdup (name);
}
@@ -2392,8 +2399,11 @@ xdg_output_handle_description (void *data,
struct zxdg_output_v1 *xdg_output,
const char *description)
{
GDK_DEBUG (MISC, "handle description xdg-output %d",
((GdkWaylandMonitor *)data)->id);
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
GDK_DEBUG (MISC, "handle description xdg-output %d: %s", monitor->id, description);
monitor->description = g_strdup (description);
}
static const struct zxdg_output_v1_listener xdg_output_listener = {
+1
View File
@@ -46,6 +46,7 @@ gdk_wayland_monitor_finalize (GObject *object)
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)object;
g_free (monitor->name);
g_free (monitor->description);
g_clear_pointer (&monitor->xdg_output, zxdg_output_v1_destroy);
+1
View File
@@ -38,6 +38,7 @@ struct _GdkWaylandMonitor {
int32_t width;
int32_t height;
char *name;
char *description;
gboolean wl_output_done;
gboolean xdg_output_done;
};
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -53,9 +53,9 @@ GDK_AVAILABLE_IN_ALL
void gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
const char *name,
int size);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
const char * gdk_wayland_display_get_startup_notification_id (GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10_FOR(gdk_toplevel_set_startup_id)
void gdk_wayland_display_set_startup_notification_id (GdkDisplay *display,
const char *startup_id);
+3 -1
View File
@@ -6,15 +6,17 @@ gdk_wayland_sources = files([
'gdkclipboard-wayland.c',
'gdkcursor-wayland.c',
'gdkdevice-wayland.c',
'gdkdevicepad-wayland.c',
'gdkdisplay-wayland.c',
'gdkdrag-wayland.c',
'gdkdragsurface-wayland.c',
'gdkdrop-wayland.c',
'gdkeventsource.c',
'gdkglcontext-wayland.c',
'gdkkeys-wayland.c',
'gdkkeymap-wayland.c',
'gdkmonitor-wayland.c',
'gdkprimary-wayland.c',
'gdkseat-wayland.c',
'gdksurface-wayland.c',
'gdktoplevel-wayland.c',
'gdkpopup-wayland.c',
+9
View File
@@ -631,6 +631,14 @@ gdk_win32_gl_context_wgl_clear_current (GdkGLContext *context)
return wglMakeCurrent (NULL, NULL);
}
static gboolean
gdk_win32_gl_context_wgl_is_current (GdkGLContext *context)
{
GdkWin32GLContextWGL *self = GDK_WIN32_GL_CONTEXT_WGL (context);
return self->wgl_context == wglGetCurrentContext ();
}
static gboolean
gdk_win32_gl_context_wgl_make_current (GdkGLContext *context,
gboolean surfaceless)
@@ -682,6 +690,7 @@ gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
context_class->realize = gdk_win32_gl_context_wgl_realize;
context_class->make_current = gdk_win32_gl_context_wgl_make_current;
context_class->clear_current = gdk_win32_gl_context_wgl_clear_current;
context_class->is_current = gdk_win32_gl_context_wgl_is_current;
draw_context_class->begin_frame = gdk_win32_gl_context_wgl_begin_frame;
draw_context_class->end_frame = gdk_win32_gl_context_wgl_end_frame;
-1
View File
@@ -740,7 +740,6 @@ GPtrArray *
_gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
{
EnumMonitorData data;
int i;
data.display = win32_display;
data.monitors = get_monitor_devices (win32_display);
+3 -12
View File
@@ -2066,19 +2066,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
xev->detail != XINotifyInferior && xev->mode != XINotifyPassiveUngrab &&
GDK_IS_TOPLEVEL (surface))
{
if (gdk_x11_device_xi2_get_device_type ((GdkX11DeviceXI2 *) device) != GDK_X11_DEVICE_TYPE_LOGICAL)
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
else
{
GList *physical_devices, *l;
GList *l;
physical_devices = gdk_device_list_physical_devices (source_device);
for (l = physical_devices; l; l = l->next)
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (l->data));
g_list_free (physical_devices);
}
for (l = device_manager->devices; l; l = l->next)
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (l->data));
}
event = gdk_crossing_event_new (ev->evtype == XI_Enter
+9 -1
View File
@@ -2074,8 +2074,10 @@ gdk_x11_display_make_default (GdkDisplay *display)
display_x11->startup_notification_id = NULL;
startup_id = gdk_get_startup_notification_id ();
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
if (startup_id)
gdk_x11_display_set_startup_notification_id (display, startup_id);
G_GNUC_END_IGNORE_DEPRECATIONS
}
static void
@@ -2303,6 +2305,8 @@ gdk_x11_display_get_user_time (GdkDisplay *display)
* Gets the startup notification ID for a display.
*
* Returns: the startup notification ID for @display
*
* Deprecated: 4.10
*/
const char *
gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
@@ -2329,7 +2333,9 @@ gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
* The startup ID is also what is used to signal that the startup is
* complete (for example, when opening a window or when calling
* gdk_display_notify_startup_complete()).
**/
*
* Deprecated: 4.10: Using [method@Gdk.Toplevel.set_startup_id] is sufficient
*/
void
gdk_x11_display_set_startup_notification_id (GdkDisplay *display,
const char *startup_id)
@@ -3042,7 +3048,9 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
display_class->get_app_launch_context = _gdk_x11_display_get_app_launch_context;
display_class->get_next_serial = gdk_x11_display_get_next_serial;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
display_class->get_startup_notification_id = gdk_x11_display_get_startup_notification_id;
G_GNUC_END_IGNORE_DEPRECATIONS
display_class->notify_startup_complete = gdk_x11_display_notify_startup_complete;
display_class->create_surface = _gdk_x11_display_create_surface;
display_class->get_keymap = gdk_x11_display_get_keymap;
+9
View File
@@ -210,6 +210,14 @@ gdk_x11_gl_context_glx_clear_current (GdkGLContext *context)
return TRUE;
}
static gboolean
gdk_x11_gl_context_glx_is_current (GdkGLContext *context)
{
GdkX11GLContextGLX *self = GDK_X11_GL_CONTEXT_GLX (context);
return self->glx_context == glXGetCurrentContext ();
}
static gboolean
gdk_x11_gl_context_glx_make_current (GdkGLContext *context,
gboolean surfaceless)
@@ -685,6 +693,7 @@ gdk_x11_gl_context_glx_class_init (GdkX11GLContextGLXClass *klass)
context_class->realize = gdk_x11_gl_context_glx_realize;
context_class->make_current = gdk_x11_gl_context_glx_make_current;
context_class->clear_current = gdk_x11_gl_context_glx_clear_current;
context_class->is_current = gdk_x11_gl_context_glx_is_current;
context_class->get_damage = gdk_x11_gl_context_glx_get_damage;
draw_context_class->end_frame = gdk_x11_gl_context_glx_end_frame;
+2 -2
View File
@@ -80,9 +80,9 @@ Cursor gdk_x11_display_get_xcursor (GdkDisplay *display,
GDK_AVAILABLE_IN_ALL
guint32 gdk_x11_display_get_user_time (GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
const char * gdk_x11_display_get_startup_notification_id (GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gdk_x11_display_set_startup_notification_id (GdkDisplay *display,
const char *startup_id);
GDK_AVAILABLE_IN_ALL
+5 -3
View File
@@ -956,7 +956,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
guint default_framebuffer)
{
G_GNUC_UNUSED guint count = 0;
graphene_rect_t scissor_test;
graphene_rect_t scissor_test = GRAPHENE_RECT_INIT (0, 0, 0, 0);
gboolean has_scissor = scissor != NULL;
gboolean scissor_state = -1;
guint program = 0;
@@ -1439,8 +1439,7 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (!GDK_IS_GL_TEXTURE (texture));
g_assert (min_filter == GL_LINEAR || min_filter == GL_NEAREST);
g_assert (mag_filter == GL_LINEAR || min_filter == GL_NEAREST);
g_assert (mag_filter == GL_LINEAR || mag_filter == GL_NEAREST);
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
@@ -1464,6 +1463,9 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
gsk_gl_command_queue_do_upload_texture (self, texture);
if (min_filter == GL_LINEAR_MIPMAP_LINEAR)
glGenerateMipmap (GL_TEXTURE_2D);
/* Restore previous texture state if any */
if (self->attachments->textures[0].id > 0)
glBindTexture (self->attachments->textures[0].target,
+12 -4
View File
@@ -3443,9 +3443,13 @@ gsk_gl_render_job_visit_gl_shader_node (GskGLRenderJob *job,
static void
gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
GdkTexture *texture,
int min_filter,
int mag_filter,
GskGLRenderOffscreen *offscreen)
{
if (gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
if (min_filter == GL_LINEAR &&
mag_filter == GL_LINEAR &&
gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
texture->width,
texture->height) &&
!GDK_IS_GL_TEXTURE (texture))
@@ -3458,7 +3462,7 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
}
else
{
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, GL_LINEAR, GL_LINEAR);
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, min_filter, mag_filter);
init_full_texture_region (offscreen);
}
}
@@ -3468,6 +3472,10 @@ gsk_gl_render_job_visit_texture_node (GskGLRenderJob *job,
const GskRenderNode *node)
{
GdkTexture *texture = gsk_texture_node_get_texture (node);
int min_filters[] = { GL_LINEAR, GL_NEAREST, GL_LINEAR_MIPMAP_LINEAR };
int mag_filters[] = { GL_LINEAR, GL_NEAREST, GL_LINEAR };
int min_filter = min_filters[gsk_texture_node_get_min_filter (node)];
int mag_filter = mag_filters[gsk_texture_node_get_mag_filter (node)];
int max_texture_size = job->command_queue->max_texture_size;
if G_LIKELY (texture->width <= max_texture_size &&
@@ -3475,7 +3483,7 @@ gsk_gl_render_job_visit_texture_node (GskGLRenderJob *job,
{
GskGLRenderOffscreen offscreen = {0};
gsk_gl_render_job_upload_texture (job, texture, &offscreen);
gsk_gl_render_job_upload_texture (job, texture, min_filter, mag_filter, &offscreen);
g_assert (offscreen.texture_id);
g_assert (offscreen.was_offscreen == FALSE);
@@ -3808,7 +3816,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
offscreen->force_offscreen == FALSE)
{
GdkTexture *texture = gsk_texture_node_get_texture (node);
gsk_gl_render_job_upload_texture (job, texture, offscreen);
gsk_gl_render_job_upload_texture (job, texture, GL_LINEAR, GL_LINEAR, offscreen);
g_assert (offscreen->was_offscreen == FALSE);
return TRUE;
}
+10
View File
@@ -214,8 +214,18 @@ GType gsk_texture_node_get_type (void) G_GNUC_CO
GDK_AVAILABLE_IN_ALL
GskRenderNode * gsk_texture_node_new (GdkTexture *texture,
const graphene_rect_t *bounds);
GDK_AVAILABLE_IN_4_10
GskRenderNode * gsk_texture_node_new_with_filters (GdkTexture *texture,
const graphene_rect_t *bounds,
GskScalingFilter min_filter,
GskScalingFilter mag_filter);
GDK_AVAILABLE_IN_ALL
GdkTexture * gsk_texture_node_get_texture (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_10
GskScalingFilter gsk_texture_node_get_min_filter (const GskRenderNode *node);
GDK_AVAILABLE_IN_4_10
GskScalingFilter gsk_texture_node_get_mag_filter (const GskRenderNode *node);
GDK_AVAILABLE_IN_ALL
GType gsk_linear_gradient_node_get_type (void) G_GNUC_CONST;
+90 -1
View File
@@ -1471,6 +1471,9 @@ struct _GskTextureNode
GskRenderNode render_node;
GdkTexture *texture;
GskScalingFilter min_filter;
GskScalingFilter mag_filter;
};
static void
@@ -1492,6 +1495,11 @@ gsk_texture_node_draw (GskRenderNode *node,
cairo_surface_t *surface;
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
cairo_filter_t filters[] = {
CAIRO_FILTER_BILINEAR,
CAIRO_FILTER_NEAREST,
CAIRO_FILTER_GOOD,
};
surface = gdk_texture_download_surface (self->texture);
pattern = cairo_pattern_create_for_surface (surface);
@@ -1504,6 +1512,10 @@ gsk_texture_node_draw (GskRenderNode *node,
-node->bounds.origin.x,
-node->bounds.origin.y);
cairo_pattern_set_matrix (pattern, &matrix);
if (gdk_texture_get_width (self->texture) > node->bounds.size.width)
cairo_pattern_set_filter (pattern, filters[self->min_filter]);
else
cairo_pattern_set_filter (pattern, filters[self->mag_filter]);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
@@ -1522,7 +1534,9 @@ gsk_texture_node_diff (GskRenderNode *node1,
GskTextureNode *self2 = (GskTextureNode *) node2;
if (graphene_rect_equal (&node1->bounds, &node2->bounds) &&
self1->texture == self2->texture)
self1->texture == self2->texture &&
self1->min_filter ==self2->min_filter &&
self1->mag_filter ==self2->mag_filter)
return;
gsk_render_node_diff_impossible (node1, node2, region);
@@ -1544,6 +1558,38 @@ gsk_texture_node_get_texture (const GskRenderNode *node)
return self->texture;
}
/**
* gsk_texture_node_get_min_filter:
* @node: (type GskTextureNode): a `GskRenderNode` of type %GSK_TEXTURE_NODE
*
* Retrieves the filter to apply when scaling the texture down.
*
* Since: 4.10
*/
GskScalingFilter
gsk_texture_node_get_min_filter (const GskRenderNode *node)
{
const GskTextureNode *self = (const GskTextureNode *) node;
return self->min_filter;
}
/**
* gsk_texture_node_get_mag_filter:
* @node: (type GskTextureNode): a `GskRenderNode` of type %GSK_TEXTURE_NODE
*
* Retrieves the filter to apply when scaling the texture up.
*
* Since: 4.10
*/
GskScalingFilter
gsk_texture_node_get_mag_filter (const GskRenderNode *node)
{
const GskTextureNode *self = (const GskTextureNode *) node;
return self->mag_filter;
}
/**
* gsk_texture_node_new:
* @texture: the `GdkTexture`
@@ -1569,6 +1615,49 @@ gsk_texture_node_new (GdkTexture *texture,
node->offscreen_for_opacity = FALSE;
self->texture = g_object_ref (texture);
self->min_filter = GSK_SCALING_FILTER_LINEAR;
self->mag_filter = GSK_SCALING_FILTER_LINEAR;
graphene_rect_init_from_rect (&node->bounds, bounds);
node->prefers_high_depth = gdk_memory_format_prefers_high_depth (gdk_texture_get_format (texture));
return node;
}
/**
* gsk_texture_node_new_with_filters:
* @texture: the `GdkTexture`
* @bounds: the rectangle to render the texture into
* @min_filter: filter to apply when scaling down
* @mag_filter: filter to apply when scaling up
*
* Creates a `GskRenderNode` that will render the given
* @texture into the area given by @bounds, using the
* given filters when required.
*
* Returns: (transfer full) (type GskTextureNode): A new `GskRenderNode`
*
* Since: 4.10
*/
GskRenderNode *
gsk_texture_node_new_with_filters (GdkTexture *texture,
const graphene_rect_t *bounds,
GskScalingFilter min_filter,
GskScalingFilter mag_filter)
{
GskTextureNode *self;
GskRenderNode *node;
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
g_return_val_if_fail (bounds != NULL, NULL);
self = gsk_render_node_alloc (GSK_TEXTURE_NODE);
node = (GskRenderNode *) self;
node->offscreen_for_opacity = FALSE;
self->texture = g_object_ref (texture);
self->min_filter = min_filter;
self->mag_filter = mag_filter;
graphene_rect_init_from_rect (&node->bounds, bounds);
node->prefers_high_depth = gdk_memory_format_prefers_high_depth (gdk_texture_get_format (texture));
+88 -272
View File
@@ -82,6 +82,10 @@
* hold the TAB_PANEL role and be the target of the CONTROLS
* relation with their corresponding tabs (in the stack
* switcher or notebook).
*
* These are the exceptions implemented by GTK itself, but note that application
* developers can customize the accessibility tree by implementing the
* [iface@Gtk.Accessible] interface in any way they choose.
*/
struct _GtkAtSpiContext
@@ -329,32 +333,43 @@ collect_relations (GtkAtSpiContext *self,
/* }}} */
/* {{{ Accessible implementation */
static int
get_index_in_parent (GtkWidget *widget)
get_index_in (GtkAccessible *parent,
GtkAccessible *child)
{
GtkWidget *parent = gtk_widget_get_parent (widget);
GtkWidget *child;
int idx;
GtkAccessible *candidate;
guint res;
if (parent == NULL)
return -1;
idx = 0;
for (child = gtk_widget_get_first_child (parent);
child;
child = gtk_widget_get_next_sibling (child))
res = 0;
for (candidate = gtk_accessible_get_first_accessible_child (parent);
candidate != NULL;
candidate = gtk_accessible_get_next_accessible_sibling (candidate))
{
if (child == widget)
return idx;
if (candidate == child)
return res;
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
if (!gtk_accessible_should_present (candidate))
continue;
idx++;
res++;
}
return -1;
}
static int
get_index_in_parent (GtkAccessible *accessible)
{
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
if (parent != NULL)
return get_index_in (parent, accessible);
return -1;
}
static int
get_index_in_toplevels (GtkWidget *widget)
{
@@ -387,61 +402,21 @@ get_parent_context_ref (GtkAccessible *accessible)
{
GVariant *res = NULL;
if (GTK_IS_WIDGET (accessible))
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
if (parent == NULL)
{
GtkWidget *widget = GTK_WIDGET (accessible);
GtkWidget *parent = gtk_widget_get_parent (widget);
GtkATContext *context = gtk_accessible_get_at_context (accessible);
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
if (parent == NULL)
{
GtkATContext *context = gtk_accessible_get_at_context (accessible);
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
res = gtk_at_spi_root_to_ref (self->root);
}
else if (GTK_IS_STACK (parent))
{
GtkStackPage *page =
gtk_stack_get_page (GTK_STACK (parent), widget);
GtkATContext *parent_context =
gtk_accessible_get_at_context (GTK_ACCESSIBLE (page));
if (parent_context != NULL)
{
gtk_at_context_realize (parent_context);
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
}
}
else
{
GtkATContext *parent_context =
gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent));
if (parent_context != NULL)
{
/* XXX: This realize() is needed otherwise opening a GtkPopover will
* emit a warning when getting the context's reference
*/
gtk_at_context_realize (parent_context);
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
}
}
res = gtk_at_spi_root_to_ref (self->root);
}
else if (GTK_IS_STACK_PAGE (accessible))
else
{
GtkWidget *parent =
gtk_widget_get_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible)));
GtkATContext *parent_context =
gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent));
GtkATContext *parent_context = gtk_accessible_get_at_context (parent);
gtk_at_context_realize (parent_context);
if (parent_context != NULL)
{
gtk_at_context_realize (parent_context);
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
}
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
}
if (res == NULL)
@@ -522,49 +497,30 @@ handle_accessible_method (GDBusConnection *connection,
{
GtkATContext *context = NULL;
GtkAccessible *accessible;
int idx, real_idx = 0;
int idx, presentable_idx;
g_variant_get (parameters, "(i)", &idx);
accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
if (GTK_IS_STACK_PAGE (accessible))
{
if (idx == 0)
{
GtkWidget *child;
GtkAccessible *child;
presentable_idx = 0;
for (child = gtk_accessible_get_first_accessible_child (accessible);
child != NULL;
child = gtk_accessible_get_next_accessible_sibling (child))
{
if (!gtk_accessible_should_present (child))
continue;
if (presentable_idx == idx)
break;
presentable_idx++;
child = gtk_stack_page_get_child (GTK_STACK_PAGE (accessible));
if (gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
}
}
else if (GTK_IS_WIDGET (accessible))
if (child)
{
GtkWidget *widget = GTK_WIDGET (accessible);
GtkWidget *child;
real_idx = 0;
for (child = gtk_widget_get_first_child (widget);
child;
child = gtk_widget_get_next_sibling (child))
{
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
continue;
if (real_idx == idx)
break;
real_idx += 1;
}
if (child)
{
if (GTK_IS_STACK (accessible))
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (gtk_stack_get_page (GTK_STACK (accessible), child)));
else
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
}
context = gtk_accessible_get_at_context (child);
}
if (context == NULL)
@@ -588,45 +544,24 @@ handle_accessible_method (GDBusConnection *connection,
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(so)"));
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
if (GTK_IS_WIDGET (accessible))
{
GtkWidget *widget = GTK_WIDGET (accessible);
GtkWidget *child;
for (child = gtk_widget_get_first_child (widget);
child;
child = gtk_widget_get_next_sibling (child))
{
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
continue;
GtkAccessible *child;
for (child = gtk_accessible_get_first_accessible_child (accessible);
child != NULL;
child = gtk_accessible_get_next_accessible_sibling (child))
{
if (!gtk_accessible_should_present (child))
continue;
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
GtkATContext *context = gtk_accessible_get_at_context (child);
/* Realize the child ATContext in order to get its ref */
gtk_at_context_realize (context);
/* Realize the child ATContext in order to get its ref */
gtk_at_context_realize (context);
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
if (ref != NULL)
g_variant_builder_add (&builder, "@(so)", ref);
}
}
else if (GTK_IS_STACK_PAGE (accessible))
{
GtkWidget *child = gtk_stack_page_get_child (GTK_STACK_PAGE (accessible));
if (gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
{
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
/* Realize the child ATContext in order to get its ref */
gtk_at_context_realize (context);
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
if (ref != NULL)
g_variant_builder_add (&builder, "@(so)", ref);
}
if (ref != NULL)
g_variant_builder_add (&builder, "@(so)", ref);
}
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder));
@@ -915,7 +850,7 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN)
{
GtkWidget *parent;
GtkAccessible *parent;
GtkATContext *context;
GtkAccessibleChildChange change;
@@ -932,14 +867,9 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
}
else
{
if (GTK_IS_WIDGET (accessible))
parent = gtk_widget_get_parent (GTK_WIDGET (accessible));
else if (GTK_IS_STACK_PAGE (accessible))
parent = gtk_widget_get_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible)));
else
g_assert_not_reached ();
parent = gtk_accessible_get_accessible_parent (accessible);
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent));
context = gtk_accessible_get_at_context (parent);
gtk_at_context_child_changed (context, change, accessible);
}
}
@@ -1168,29 +1098,9 @@ gtk_at_spi_context_bounds_change (GtkATContext *ctx)
{
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (ctx);
GtkAccessible *accessible = gtk_at_context_get_accessible (ctx);
GtkWidget *widget;
GtkWidget *parent;
double x, y;
int width, height;
if (!GTK_IS_WIDGET (accessible))
return;
widget = GTK_WIDGET (accessible);
if (!gtk_widget_get_realized (widget))
return;
parent = gtk_widget_get_parent (widget);
if (parent)
gtk_widget_translate_coordinates (widget, parent, 0., 0., &x, &y);
else
x = y = 0.;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
emit_bounds_changed (self, (int)x, (int)y, width, height);
int x, y, width, height;
if (gtk_accessible_get_bounds (accessible, &x, &y, &width, &height))
emit_bounds_changed (self, x, y, width, height);
}
static void
@@ -1201,99 +1111,17 @@ gtk_at_spi_context_child_change (GtkATContext *ctx,
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (ctx);
GtkAccessible *accessible = gtk_at_context_get_accessible (ctx);
GtkATContext *child_context = gtk_accessible_get_at_context (child);
GtkWidget *parent_widget;
GtkWidget *child_widget;
int idx = 0;
if (!GTK_IS_WIDGET (accessible))
return;
if (child_context == NULL)
return;
/* handle the stack page special case */
if (GTK_IS_WIDGET (child) &&
GTK_IS_STACK (gtk_widget_get_parent (GTK_WIDGET (child))))
{
GtkWidget *stack;
GtkStackPage *page;
GListModel *pages;
GtkAccessible *parent = gtk_accessible_get_accessible_parent (child);
int idx = 0;
stack = gtk_widget_get_parent (GTK_WIDGET (child));
page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (child));
pages = G_LIST_MODEL (gtk_stack_get_pages (GTK_STACK (stack)));
idx = 0;
for (guint i = 0; i < g_list_model_get_n_items (pages); i++)
{
GtkStackPage *item = g_list_model_get_item (pages, i);
g_object_unref (item);
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (item)))
continue;
if (item == page)
break;
idx++;
}
g_object_unref (pages);
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED)
{
emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (stack))),
GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))),
idx,
GTK_ACCESSIBLE_CHILD_STATE_ADDED);
emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))),
GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (child)),
0,
GTK_ACCESSIBLE_CHILD_STATE_ADDED);
}
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_REMOVED)
{
emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))),
GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (child)),
0,
GTK_ACCESSIBLE_CHILD_STATE_REMOVED);
emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (stack))),
GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))),
idx,
GTK_ACCESSIBLE_CHILD_STATE_REMOVED);
}
return;
}
parent_widget = GTK_WIDGET (accessible);
if (GTK_IS_STACK_PAGE (child))
child_widget = gtk_stack_page_get_child (GTK_STACK_PAGE (child));
else
child_widget = GTK_WIDGET (child);
if (gtk_widget_get_parent (child_widget) != parent_widget)
{
idx = 0;
}
else
{
for (GtkWidget *iter = gtk_widget_get_first_child (parent_widget);
iter != NULL;
iter = gtk_widget_get_next_sibling (iter))
{
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (iter)))
continue;
if (iter == child_widget)
break;
idx += 1;
}
}
if (parent == NULL)
idx = -1;
else if (parent == accessible)
idx = get_index_in (accessible, child);
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED)
emit_children_changed (self,
@@ -1858,12 +1686,8 @@ gtk_at_spi_context_get_index_in_parent (GtkAtSpiContext *self)
if (GTK_IS_ROOT (accessible))
idx = get_index_in_toplevels (GTK_WIDGET (accessible));
else if (GTK_IS_STACK_PAGE (accessible))
idx = get_index_in_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible)));
else if (GTK_IS_STACK (gtk_widget_get_parent (GTK_WIDGET (accessible))))
idx = 1;
else
idx = get_index_in_parent (GTK_WIDGET (accessible));
idx = get_index_in_parent (accessible);
return idx;
}
@@ -1874,26 +1698,18 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self)
g_return_val_if_fail (GTK_IS_AT_SPI_CONTEXT (self), -1);
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
int n_children = -1;
int n_children = 0;
if (GTK_IS_WIDGET (accessible))
GtkAccessible *child = NULL;
for (child = gtk_accessible_get_first_accessible_child (accessible);
child != NULL;
child = gtk_accessible_get_next_accessible_sibling (child))
{
GtkWidget *child;
if (!gtk_accessible_should_present (child))
continue;
n_children = 0;
for (child = gtk_widget_get_first_child (GTK_WIDGET (accessible));
child;
child = gtk_widget_get_next_sibling (child))
{
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
continue;
n_children++;
}
}
else if (GTK_IS_STACK_PAGE (accessible))
{
n_children = 1;
n_children++;
}
return n_children;
@@ -88,6 +88,8 @@
#include "gtkstack.h"
#include "gtktypebuiltins.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
typedef struct _GtkAssistantPageClass GtkAssistantPageClass;
struct _GtkAssistantPage
@@ -103,81 +103,81 @@ GDK_AVAILABLE_IN_ALL
GType gtk_assistant_page_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GType gtk_assistant_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GtkWidget *gtk_assistant_new (void);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_next_page (GtkAssistant *assistant);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_previous_page (GtkAssistant *assistant);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
int gtk_assistant_get_current_page (GtkAssistant *assistant);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_set_current_page (GtkAssistant *assistant,
int page_num);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
int gtk_assistant_get_n_pages (GtkAssistant *assistant);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GtkWidget *gtk_assistant_get_nth_page (GtkAssistant *assistant,
int page_num);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
int gtk_assistant_prepend_page (GtkAssistant *assistant,
GtkWidget *page);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
int gtk_assistant_append_page (GtkAssistant *assistant,
GtkWidget *page);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
int gtk_assistant_insert_page (GtkAssistant *assistant,
GtkWidget *page,
int position);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_remove_page (GtkAssistant *assistant,
int page_num);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_set_forward_page_func (GtkAssistant *assistant,
GtkAssistantPageFunc page_func,
gpointer data,
GDestroyNotify destroy);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_set_page_type (GtkAssistant *assistant,
GtkWidget *page,
GtkAssistantPageType type);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GtkAssistantPageType gtk_assistant_get_page_type (GtkAssistant *assistant,
GtkWidget *page);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_set_page_title (GtkAssistant *assistant,
GtkWidget *page,
const char *title);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
const char * gtk_assistant_get_page_title (GtkAssistant *assistant,
GtkWidget *page);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_set_page_complete (GtkAssistant *assistant,
GtkWidget *page,
gboolean complete);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
gboolean gtk_assistant_get_page_complete (GtkAssistant *assistant,
GtkWidget *page);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_add_action_widget (GtkAssistant *assistant,
GtkWidget *child);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_remove_action_widget (GtkAssistant *assistant,
GtkWidget *child);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_update_buttons_state (GtkAssistant *assistant);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_assistant_commit (GtkAssistant *assistant);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GtkAssistantPage * gtk_assistant_get_page (GtkAssistant *assistant,
GtkWidget *child);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GtkWidget * gtk_assistant_page_get_child (GtkAssistantPage *page);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GListModel * gtk_assistant_get_pages (GtkAssistant *assistant);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkAssistant, g_object_unref)
@@ -28,6 +28,8 @@
#include "gtkstack.h"
#include "gtkprivate.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/**
* GtkLockButton:
*
@@ -32,11 +32,11 @@ typedef struct _GtkLockButton GtkLockButton;
GDK_AVAILABLE_IN_ALL
GType gtk_lock_button_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GtkWidget *gtk_lock_button_new (GPermission *permission);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GPermission *gtk_lock_button_get_permission (GtkLockButton *button);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_lock_button_set_permission (GtkLockButton *button,
GPermission *permission);
@@ -36,6 +36,8 @@
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/**
* GtkStatusbar:
*
@@ -42,23 +42,23 @@ typedef struct _GtkStatusbar GtkStatusbar;
GDK_AVAILABLE_IN_ALL
GType gtk_statusbar_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
GtkWidget* gtk_statusbar_new (void);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
guint gtk_statusbar_get_context_id (GtkStatusbar *statusbar,
const char *context_description);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
guint gtk_statusbar_push (GtkStatusbar *statusbar,
guint context_id,
const char *text);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_statusbar_pop (GtkStatusbar *statusbar,
guint context_id);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_statusbar_remove (GtkStatusbar *statusbar,
guint context_id,
guint message_id);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
void gtk_statusbar_remove_all (GtkStatusbar *statusbar,
guint context_id);
+6
View File
@@ -3,6 +3,7 @@ gtk_deprecated_sources = [
'deprecated/gtkappchooserbutton.c',
'deprecated/gtkappchooserdialog.c',
'deprecated/gtkappchooserwidget.c',
'deprecated/gtkassistant.c',
'deprecated/gtkcellarea.c',
'deprecated/gtkcellareabox.c',
'deprecated/gtkcellareacontext.c',
@@ -31,8 +32,10 @@ gtk_deprecated_sources = [
'deprecated/gtkiconview.c',
'deprecated/gtkinfobar.c',
'deprecated/gtkliststore.c',
'deprecated/gtklockbutton.c',
'deprecated/gtkrender.c',
'deprecated/gtkshow.c',
'deprecated/gtkstatusbar.c',
'deprecated/gtkstylecontext.c',
'deprecated/gtktreedatalist.c',
'deprecated/gtktreednd.c',
@@ -53,6 +56,7 @@ gtk_deprecated_headers = [
'deprecated/gtkappchooserbutton.h',
'deprecated/gtkappchooserdialog.h',
'deprecated/gtkappchooserwidget.h',
'deprecated/gtkassistant.h',
'deprecated/gtkcellarea.h',
'deprecated/gtkcellareabox.h',
'deprecated/gtkcellareacontext.h',
@@ -87,9 +91,11 @@ gtk_deprecated_headers = [
'deprecated/gtkiconview.h',
'deprecated/gtkinfobar.h',
'deprecated/gtkliststore.h',
'deprecated/gtklockbutton.h',
'deprecated/gtkmessagedialog.h',
'deprecated/gtkrender.h',
'deprecated/gtkshow.h',
'deprecated/gtkstatusbar.h',
'deprecated/gtkstylecontext.h',
'deprecated/gtktreednd.h',
'deprecated/gtktreemodel.h',
-52
View File
@@ -1,52 +0,0 @@
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright 2017 Red Hat, Inc.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __G_OPEN_URI_PORTAL_H__
#include "gtkwindow.h"
#include <glib.h>
#include <gio/gio.h>
G_BEGIN_DECLS
gboolean g_openuri_portal_is_available (void);
void g_openuri_portal_open_async (GFile *file,
gboolean open_folder,
GtkWindow *window,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean g_openuri_portal_open_finish (GAsyncResult *result,
GError **error);
void g_openuri_portal_open_uri_async (const char *uri,
GtkWindow *window,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean g_openuri_portal_open_uri_finish (GAsyncResult *result,
GError **error);
G_END_DECLS
#endif
+3 -3
View File
@@ -46,7 +46,7 @@
#include <gtk/gtkapplication.h>
#include <gtk/gtkapplicationwindow.h>
#include <gtk/gtkaspectframe.h>
#include <gtk/gtkassistant.h>
#include <gtk/deprecated/gtkassistant.h>
#include <gtk/gtkatcontext.h>
#include <gtk/gtkbinlayout.h>
#include <gtk/gtkbitset.h>
@@ -177,7 +177,7 @@
#include <gtk/gtklistitemfactory.h>
#include <gtk/deprecated/gtkliststore.h>
#include <gtk/gtklistview.h>
#include <gtk/gtklockbutton.h>
#include <gtk/deprecated/gtklockbutton.h>
#include <gtk/gtkmain.h>
#include <gtk/gtkmaplistmodel.h>
#include <gtk/gtkmediacontrols.h>
@@ -252,7 +252,7 @@
#include <gtk/gtkspinner.h>
#include <gtk/gtkstack.h>
#include <gtk/gtkstackswitcher.h>
#include <gtk/gtkstatusbar.h>
#include <gtk/deprecated/gtkstatusbar.h>
#include <gtk/gtkstringfilter.h>
#include <gtk/gtkstringlist.h>
#include <gtk/gtkstringsorter.h>
+114 -13
View File
@@ -37,6 +37,14 @@
* a way that should be reflected by assistive technologies. For instance,
* if a `GtkWidget` visibility changes, the %GTK_ACCESSIBLE_STATE_HIDDEN
* state will also change to reflect the [property@Gtk.Widget:visible] property.
*
* Every accessible implementation is part of a tree of accessible objects.
* Normally, this tree corresponds to the widget tree, but can be customized
* by reimplementing the [vfunc@Gtk.Accessible.get_accessible_parent],
* [vfunc@Gtk.Accessible.get_first_accessible_child] and
* [vfunc@Gtk.Accessible.get_next_accessible_sibling] virtual functions.
* Note that you can not create a top-level accessible object as of now,
* which means that you must always have a parent accessible object.
*/
#include "config.h"
@@ -74,7 +82,7 @@ gtk_accessible_default_init (GtkAccessibleInterface *iface)
g_object_interface_install_property (iface, pspec);
}
/*< private >
/**
* gtk_accessible_get_at_context:
* @self: a `GtkAccessible`
*
@@ -91,12 +99,68 @@ gtk_accessible_get_at_context (GtkAccessible *self)
}
/**
* gtk_accessible_get_accessible_role: (attributes org.gtk.Method.get_property=accessible-role)
* gtk_accessible_get_accessible_parent:
* @self: a `GtkAccessible`
*
* Retrieves the `GtkAccessibleRole` for the given `GtkAccessible`.
* Retrieves the accessible accessible for an accessible object
*
* Returns: a `GtkAccessibleRole`
* This function returns `NULL` for top level widgets
*
* Returns: (transfer none) (nullable): the accessible parent
*
* Since: 4.10
*/
GtkAccessible *
gtk_accessible_get_accessible_parent (GtkAccessible *self)
{
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), NULL);
return GTK_ACCESSIBLE_GET_IFACE (self)->get_accessible_parent (self);
}
/**
* gtk_accessible_get_first_accessible_child:
* @self: an accessible object
*
* Retrieves the first accessible child of an accessible object.
*
* Returns: (transfer none) (nullable): the first accessible child
*
* since: 4.10
*/
GtkAccessible *
gtk_accessible_get_first_accessible_child (GtkAccessible *self)
{
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), NULL);
return GTK_ACCESSIBLE_GET_IFACE (self)->get_first_accessible_child (self);
}
/**
* gtk_accessible_get_next_accessible_sibling:
* @self: an accessible object
*
* Retrieves the next accessible sibling of an accessible object
*
* Returns: (transfer none) (nullable): the next accessible sibling
*
* since: 4.10
*/
GtkAccessible *
gtk_accessible_get_next_accessible_sibling (GtkAccessible *self)
{
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), NULL);
return GTK_ACCESSIBLE_GET_IFACE (self)->get_next_accessible_sibling (self);
}
/**
* gtk_accessible_get_accessible_role:
* @self: an accessible object
*
* Retrieves the accessible role of an accessible object.
*
* Returns: the accessible role
*/
GtkAccessibleRole
gtk_accessible_get_accessible_role (GtkAccessible *self)
@@ -127,6 +191,7 @@ gtk_accessible_get_accessible_role (GtkAccessible *self)
* state change must be communicated to assistive technologies.
*
* Example:
*
* ```c
* value = GTK_ACCESSIBLE_TRISTATE_MIXED;
* gtk_accessible_update_state (GTK_ACCESSIBLE (check_button),
@@ -659,10 +724,10 @@ gtk_accessible_role_to_name (GtkAccessibleRole role,
/*< private >
* gtk_accessible_role_is_range_subclass:
* @role: a `GtkAccessibleRole`
*
*
* Checks if @role is considered to be a subclass of %GTK_ACCESSIBLE_ROLE_RANGE
* according to the WAI-ARIA specification.
*
*
* Returns: whether the @role is range-like
*/
gboolean
@@ -683,7 +748,7 @@ gtk_accessible_role_is_range_subclass (GtkAccessibleRole role)
return FALSE;
}
/*<private>
/*< private >
* gtk_accessible_platform_changed:
* @self: a `GtkAccessible`
* @change: the platform state change to report
@@ -712,7 +777,7 @@ gtk_accessible_platform_changed (GtkAccessible *self,
/* propagate changes up from ignored widgets */
if (gtk_accessible_get_accessible_role (self) == GTK_ACCESSIBLE_ROLE_NONE)
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (gtk_widget_get_parent (GTK_WIDGET (self))));
context = gtk_accessible_get_at_context (gtk_accessible_get_accessible_parent (self));
if (context == NULL)
return;
@@ -721,7 +786,7 @@ gtk_accessible_platform_changed (GtkAccessible *self,
gtk_at_context_update (context);
}
/*<private>
/**
* gtk_accessible_get_platform_state:
* @self: a `GtkAccessible`
* @state: platform state to query
@@ -735,15 +800,19 @@ gtk_accessible_platform_changed (GtkAccessible *self,
* child widget, as is the case for `GtkText` wrappers.
*
* Returns: the value of @state for the accessible
*
* Since: 4.10
*/
gboolean
gtk_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), FALSE);
return GTK_ACCESSIBLE_GET_IFACE (self)->get_platform_state (self, state);
}
/*<private>
/*< private >
* gtk_accessible_bounds_changed:
* @self: a `GtkAccessible`
*
@@ -752,7 +821,7 @@ gtk_accessible_get_platform_state (GtkAccessible *self,
* changed.
*
* Note that the bounds are not included in this API.
* AT backends should use widget API to obtain them.
* AT backends should use [method@Gtk.Accessible.get_bounds] to get them.
*/
void
gtk_accessible_bounds_changed (GtkAccessible *self)
@@ -770,7 +839,39 @@ gtk_accessible_bounds_changed (GtkAccessible *self)
gtk_at_context_bounds_changed (context);
}
/*<private>
/**
* gtk_accessible_get_bounds:
* @self: a `GtkAccessible`
* @x: (out): the x coordinate of the top left corner of the accessible
* @y: (out): the y coordinate of the top left corner of the widget
* @width: (out): the width of the accessible object
* @height: (out): the height of the accessible object
*
* Queries the coordinates and dimensions of this accessible
*
* This functionality can be overridden by `GtkAccessible`
* implementations, e.g. to get the bounds from an ignored
* child widget.
*
* Returns: true if the bounds are valid, and false otherwise
*
* Since: 4.10
*/
gboolean
gtk_accessible_get_bounds (GtkAccessible *self,
int *x,
int *y,
int *width,
int *height)
{
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), FALSE);
g_return_val_if_fail (x != NULL && y != NULL, FALSE);
g_return_val_if_fail (width != NULL && height != NULL, FALSE);
return GTK_ACCESSIBLE_GET_IFACE (self)->get_bounds (self, x, y, width, height);
}
/*< private >
* gtk_accessible_should_present:
* @self: a `GtkAccessible`
*
@@ -829,7 +930,7 @@ gtk_accessible_update_children (GtkAccessible *self,
/* propagate changes up from ignored widgets */
if (gtk_accessible_get_accessible_role (self) == GTK_ACCESSIBLE_ROLE_NONE)
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (gtk_widget_get_parent (GTK_WIDGET (self))));
context = gtk_accessible_get_at_context (gtk_accessible_get_accessible_parent (self));
if (context == NULL)
return;
+184 -43
View File
@@ -32,58 +32,199 @@ G_BEGIN_DECLS
#define GTK_TYPE_ACCESSIBLE (gtk_accessible_get_type())
GDK_AVAILABLE_IN_ALL
GDK_AVAILABLE_IN_4_10
G_DECLARE_INTERFACE (GtkAccessible, gtk_accessible, GTK, ACCESSIBLE, GObject)
GDK_AVAILABLE_IN_ALL
GtkAccessibleRole gtk_accessible_get_accessible_role (GtkAccessible *self);
/**
* GtkAccessiblePlatformState:
* @GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE: whether the accessible can be focused
* @GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED: whether the accessible has focus
* @GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE: whether the accessible is active
*
* The various platform states which can be queried
* using [method@Gtk.Accessible.get_platform_state].
*
* Since: 4.10
*/
typedef enum {
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE
} GtkAccessiblePlatformState;
/**
* GtkAccessibleInterface:
* @get_at_context: retrieve the platform-specific accessibility context
* for the accessible implementation
* @get_platform_state: retrieve the accessible state
*
* The common interface for accessible objects.
*
* Since: 4.10
*/
struct _GtkAccessibleInterface
{
GTypeInterface g_iface;
/**
* GtkAccessibleInterface::get_at_context:
* @self: an accessible object
*
* Retrieves the platform-specific accessibility context for the
* accessible implementation.
*
* Returns: (transfer none) (nullable): the accessibility context
*
* Since: 4.10
*/
GtkATContext * (* get_at_context) (GtkAccessible *self);
/**
* GtkAccessibleInterface::get_platform_state:
* @self: an accessible object
* @state: the state to query
*
* Checks if the given @state applies to the accessible object.
*
* Returns: true if the @state is set, and false otherwise
*
* Since: 4.10
*/
gboolean (* get_platform_state) (GtkAccessible *self,
GtkAccessiblePlatformState state);
/**
* GtkAccessibleInterface::get_accessible_parent:
* @self: an accessible object
*
* Retrieves the accessible parent of an accessible object.
*
* This virtual function should return `NULL` for top level objects.
*
* Returns: (nullable) (transfer none): the accessible parent
*
* Since: 4.10
*/
GtkAccessible * (* get_accessible_parent) (GtkAccessible *self);
/**
* GtkaccessibleInterface::get_first_accessible_child:
* @self: an accessible object
*
* Retrieves the first accessible child of an accessible object.
*
* Returns: (transfer none) (nullable): an accessible object
*
* Since: 4.10
*/
GtkAccessible * (* get_first_accessible_child) (GtkAccessible *self);
/**
* GtkaccessibleInterface::get_next_accessible_sibling:
* @self: an accessible object
*
* Retrieves the next accessible sibling of an accessible object.
*
* Returns: (transfer none) (nullable): an accessible object
*
* Since: 4.10
*/
GtkAccessible * (* get_next_accessible_sibling) (GtkAccessible *self);
/**
* GtkAccessibleInterface::get_bounds:
* @self: an accessible object
* @x: (out): the horizontal coordinate of a rectangle
* @y: (out): the vertical coordinate of a rectangle
* @width: (out): the width of a rectangle
* @height: (out): the height of a rectangle
*
* Retrieves the dimensions and position of an accessible object in its
* parent's coordinate space, if those values can be determined.
*
* For top level accessible objects, the X and Y coordinates are always
* going to be set to zero.
*
* Returns: true if the values are value, and false otherwise
*/
gboolean (* get_bounds) (GtkAccessible *self,
int *x,
int *y,
int *width,
int *height);
};
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_state (GtkAccessible *self,
GtkAccessibleState first_state,
...);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_property (GtkAccessible *self,
GtkAccessibleProperty first_property,
...);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_relation (GtkAccessible *self,
GtkAccessibleRelation first_relation,
...);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_state_value (GtkAccessible *self,
int n_states,
GtkAccessibleState states[],
const GValue values[]);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_property_value (GtkAccessible *self,
int n_properties,
GtkAccessibleProperty properties[],
const GValue values[]);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_relation_value (GtkAccessible *self,
int n_relations,
GtkAccessibleRelation relations[],
const GValue values[]);
GtkATContext * gtk_accessible_get_at_context (GtkAccessible *self);
GDK_AVAILABLE_IN_4_10
gboolean gtk_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state);
GDK_AVAILABLE_IN_4_10
GtkAccessible * gtk_accessible_get_accessible_parent (GtkAccessible *self);
GDK_AVAILABLE_IN_4_10
GtkAccessible * gtk_accessible_get_first_accessible_child (GtkAccessible *self);
GDK_AVAILABLE_IN_4_10
GtkAccessible * gtk_accessible_get_next_accessible_sibling (GtkAccessible *self);
GDK_AVAILABLE_IN_4_10
gboolean gtk_accessible_get_bounds (GtkAccessible *self,
int *x,
int *y,
int *width,
int *height);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_reset_state (GtkAccessible *self,
GtkAccessibleState state);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_reset_property (GtkAccessible *self,
GtkAccessibleProperty property);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_reset_relation (GtkAccessible *self,
GtkAccessibleRelation relation);
GtkAccessibleRole gtk_accessible_get_accessible_role (GtkAccessible *self);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_state_init_value (GtkAccessibleState state,
GValue *value);
void gtk_accessible_update_state (GtkAccessible *self,
GtkAccessibleState first_state,
...);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_property_init_value (GtkAccessibleProperty property,
GValue *value);
void gtk_accessible_update_property (GtkAccessible *self,
GtkAccessibleProperty first_property,
...);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_relation_init_value (GtkAccessibleRelation relation,
GValue *value);
void gtk_accessible_update_relation (GtkAccessible *self,
GtkAccessibleRelation first_relation,
...);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_state_value (GtkAccessible *self,
int n_states,
GtkAccessibleState states[],
const GValue values[]);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_property_value (GtkAccessible *self,
int n_properties,
GtkAccessibleProperty properties[],
const GValue values[]);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_relation_value (GtkAccessible *self,
int n_relations,
GtkAccessibleRelation relations[],
const GValue values[]);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_reset_state (GtkAccessible *self,
GtkAccessibleState state);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_reset_property (GtkAccessible *self,
GtkAccessibleProperty property);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_reset_relation (GtkAccessible *self,
GtkAccessibleRelation relation);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_state_init_value (GtkAccessibleState state,
GValue *value);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_property_init_value (GtkAccessibleProperty property,
GValue *value);
GDK_AVAILABLE_IN_ALL
void gtk_accessible_relation_init_value (GtkAccessibleRelation relation,
GValue *value);
G_END_DECLS
+30 -17
View File
@@ -21,21 +21,36 @@
#pragma once
#include "gtkaccessible.h"
#include "gtkatcontextprivate.h"
G_BEGIN_DECLS
struct _GtkAccessibleInterface
{
GTypeInterface g_iface;
/* < private >
* GtkAccessiblePlatformChange:
* @GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSABLE: whether the accessible has changed
* its focusable state
* @GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSED: whether the accessible has changed its
* focused state
* @GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE: whether the accessible has changed its
* active state
*
* Represents the various platform changes which can occur and are communicated
* using [method@Gtk.Accessible.platform_changed].
*/
typedef enum {
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSABLE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSED = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE,
} GtkAccessiblePlatformChange;
GtkATContext * (* get_at_context) (GtkAccessible *self);
typedef enum {
GTK_ACCESSIBLE_CHILD_STATE_ADDED,
GTK_ACCESSIBLE_CHILD_STATE_REMOVED
} GtkAccessibleChildState;
gboolean (* get_platform_state) (GtkAccessible *self,
GtkAccessiblePlatformState state);
};
GtkATContext * gtk_accessible_get_at_context (GtkAccessible *self);
typedef enum {
GTK_ACCESSIBLE_CHILD_CHANGE_ADDED = 1 << GTK_ACCESSIBLE_CHILD_STATE_ADDED,
GTK_ACCESSIBLE_CHILD_CHANGE_REMOVED = 1 << GTK_ACCESSIBLE_CHILD_STATE_REMOVED
} GtkAccessibleChildChange;
const char * gtk_accessible_role_to_name (GtkAccessibleRole role,
const char *domain);
@@ -44,15 +59,13 @@ gboolean gtk_accessible_role_is_range_subclass (GtkAccessibleRole role);
gboolean gtk_accessible_should_present (GtkAccessible *self);
void gtk_accessible_platform_changed (GtkAccessible *self,
GtkAccessiblePlatformChange change);
gboolean gtk_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state);
void gtk_accessible_bounds_changed (GtkAccessible *self);
void gtk_accessible_update_children (GtkAccessible *self,
GtkAccessible *child,
GtkAccessibleChildState state);
void gtk_accessible_bounds_changed (GtkAccessible *self);
void gtk_accessible_platform_changed (GtkAccessible *self,
GtkAccessiblePlatformChange change);
G_END_DECLS
+5 -1
View File
@@ -104,9 +104,13 @@ gtk_application_impl_wayland_before_emit (GtkApplicationImpl *impl,
{
const char *startup_notification_id = NULL;
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
g_variant_lookup (platform_data, "activation-token", "&s", &startup_notification_id);
if (!startup_notification_id)
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gdk_wayland_display_set_startup_notification_id (gdk_display_get_default (), startup_notification_id);
G_GNUC_END_IGNORE_DEPRECATIONS
}
static guint
+2
View File
@@ -87,7 +87,9 @@ gtk_application_impl_x11_before_emit (GtkApplicationImpl *impl,
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gdk_x11_display_set_startup_notification_id (gdk_display_get_default (), startup_notification_id);
G_GNUC_END_IGNORE_DEPRECATIONS
}
static void
+8 -2
View File
@@ -321,10 +321,16 @@ gtk_application_add_platform_data (GApplication *application,
{
const char *startup_id;
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
startup_id = gdk_display_get_startup_notification_id (display);
G_GNUC_END_IGNORE_DEPRECATIONS
if (startup_id && g_utf8_validate (startup_id, -1, NULL))
g_variant_builder_add (builder, "{sv}", "desktop-startup-id",
g_variant_new_string (startup_id));
{
g_variant_builder_add (builder, "{sv}", "activation-token",
g_variant_new_string (startup_id));
g_variant_builder_add (builder, "{sv}", "desktop-startup-id",
g_variant_new_string (startup_id));
}
}
}
+1 -22
View File
@@ -22,6 +22,7 @@
#include "gtkatcontext.h"
#include "gtkaccessibleprivate.h"
#include "gtkaccessibleattributesetprivate.h"
G_BEGIN_DECLS
@@ -80,28 +81,6 @@ typedef enum {
GTK_ACCESSIBLE_STATE_CHANGE_SELECTED = 1 << GTK_ACCESSIBLE_STATE_SELECTED
} GtkAccessibleStateChange;
typedef enum {
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE
} GtkAccessiblePlatformState;
typedef enum {
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSABLE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSED = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE,
} GtkAccessiblePlatformChange;
typedef enum {
GTK_ACCESSIBLE_CHILD_STATE_ADDED,
GTK_ACCESSIBLE_CHILD_STATE_REMOVED
} GtkAccessibleChildState;
typedef enum {
GTK_ACCESSIBLE_CHILD_CHANGE_ADDED = 1 << GTK_ACCESSIBLE_CHILD_STATE_ADDED,
GTK_ACCESSIBLE_CHILD_CHANGE_REMOVED = 1 << GTK_ACCESSIBLE_CHILD_STATE_REMOVED
} GtkAccessibleChildChange;
struct _GtkATContext
{
GObject parent_instance;
+2 -4
View File
@@ -1086,10 +1086,8 @@ gtk_css_provider_load_internal (GtkCssProvider *self,
/**
* gtk_css_provider_load_from_data:
* @css_provider: a `GtkCssProvider`
* @data: (array length=length) (element-type guint8): CSS data loaded in memory
* @length: the length of @data in bytes, or -1 for NUL terminated strings. If
* @length is not -1, the code will assume it is not NUL terminated and will
* potentially do a copy.
* @data: CSS data to be parsed
* @length: the length of @data in bytes, or -1 for NUL terminated strings
*
* Loads @data into @css_provider.
*
+3
View File
@@ -555,6 +555,9 @@ gtk_drag_icon_create_widget_for_value (const GValue *value)
GtkWidget *image;
info = g_file_query_info (G_FILE (g_value_get_object (value)), "standard::icon", 0, NULL, NULL);
if (!info)
return NULL;
image = gtk_image_new_from_gicon (g_file_info_get_icon (info));
gtk_widget_add_css_class (image, "large-icons");
g_object_unref (info);
+1 -1
View File
@@ -569,7 +569,7 @@ gtk_drag_source_drag_begin (GtkDragSource *source)
GtkNative *native;
GdkSurface *surface;
double px, py;
int dx, dy;
double dx, dy;
GdkContentProvider *content = NULL;
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
+53 -2
View File
@@ -19,7 +19,7 @@
* 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/.
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
/**
@@ -485,7 +485,7 @@ gtk_editable_insert_text (GtkEditable *editable,
if (length < 0)
length = strlen (text);
GTK_EDITABLE_GET_IFACE (editable)->do_insert_text (editable, text, length, position);
}
@@ -1181,3 +1181,54 @@ gtk_editable_delegate_get_property (GObject *object,
return TRUE;
}
/**
* gtk_editable_delegate_get_accessible_platform_state:
* @editable: a `GtkEditable` implementation
* @state: what kind of accessible state to retrieve
*
* Retrieves the accessible platform state from the editable delegate.
*
* This is an helper function to retrieve the accessible state for
* `GtkEditable` interface implementations using a delegate pattern.
*
* You should call this function in your editable widget implementation
* of the [vfunc@Gtk.Accessible.get_platform_state] virtual function, for
* instance:
*
* ```c
* static void
* accessible_interface_init (GtkAccessibleInterface *iface)
* {
* iface->get_platform_state = your_editable_get_accessible_platform_state;
* }
*
* static gboolean
* your_editable_get_accessible_platform_state (GtkAccessible *accessible,
* GtkAccessiblePlatformState state)
* {
* return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (accessible), state);
* }
* ```
*
* Since: 4.10
*/
gboolean
gtk_editable_delegate_get_accessible_platform_state (GtkEditable *editable,
GtkAccessiblePlatformState state)
{
GtkWidget *delegate = GTK_WIDGET (gtk_editable_get_delegate (editable));
switch (state)
{
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
return gtk_widget_get_focusable (delegate);
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (delegate);
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
return FALSE;
}
}
+4 -1
View File
@@ -30,9 +30,9 @@
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkaccessible.h>
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
#define GTK_TYPE_EDITABLE (gtk_editable_get_type ())
@@ -194,6 +194,9 @@ gboolean gtk_editable_delegate_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
GDK_AVAILABLE_IN_4_10
gboolean gtk_editable_delegate_get_accessible_platform_state (GtkEditable *editable,
GtkAccessiblePlatformState state);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEditable, g_object_unref)
+1 -14
View File
@@ -339,20 +339,7 @@ static gboolean
gtk_entry_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
GtkEntry *entry = GTK_ENTRY (self);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
switch (state)
{
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
return gtk_widget_get_focusable (GTK_WIDGET (priv->text));
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (GTK_WIDGET (priv->text));
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}
return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (self), state);
}
static void
+1 -1
View File
@@ -207,7 +207,7 @@ send_close (FilechooserPortalData *data)
message = g_dbus_message_new_method_call (PORTAL_BUS_NAME,
PORTAL_OBJECT_PATH,
PORTAL_FILECHOOSER_INTERFACE,
PORTAL_REQUEST_INTERFACE,
"Close");
g_dbus_message_set_body (message,
g_variant_new ("(o)", data->portal_handle));
+17 -9
View File
@@ -96,7 +96,7 @@
#include "gtkexpression.h"
#ifndef G_OS_WIN32
#include "gopenuriportal.h"
#include "gtkopenuriportal.h"
#endif
#include <cairo-gobject.h>
@@ -1566,6 +1566,9 @@ file_list_drag_drop_cb (GtkDropTarget *dest,
files = g_value_get_boxed (value);
if (files == NULL)
return TRUE;
data = g_new0 (FileListDragData, 1);
data->impl = g_object_ref (impl);
data->files = g_slist_copy_deep (files, (GCopyFunc) g_object_ref, NULL);
@@ -7219,16 +7222,21 @@ popup_menu (GtkWidget *widget,
}
static void
file_chooser_widget_clicked (GtkEventController *controller,
int n_press,
double x,
double y,
gpointer user_data)
file_chooser_widget_clicked (GtkEventController *controller,
int n_press,
double x,
double y,
GtkFileChooserWidget *impl)
{
GtkWidget *widget = user_data;
GtkWidget *widget = GTK_WIDGET (impl);
GtkWidget *child;
gtk_gesture_set_state (GTK_GESTURE (controller), GTK_EVENT_SEQUENCE_CLAIMED);
popup_menu (widget, x, y);
child = gtk_widget_pick (widget, x, y, 0);
if (gtk_widget_is_ancestor (child, impl->browse_files_stack))
{
gtk_gesture_set_state (GTK_GESTURE (controller), GTK_EVENT_SEQUENCE_CLAIMED);
popup_menu (widget, x, y);
}
}
static void
+3 -3
View File
@@ -694,7 +694,7 @@ gtk_file_dialog_set_initial_file (GtkFileDialog *self,
GFile *folder;
GFileInfo *info;
if (g_file_equal (self->initial_file, file))
if (self->initial_file && g_file_equal (self->initial_file, file))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INITIAL_FILE]);
@@ -707,7 +707,7 @@ gtk_file_dialog_set_initial_file (GtkFileDialog *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INITIAL_FOLDER]);
info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME, 0, NULL, NULL);
if (g_file_info_get_edit_name (info) != NULL)
if (info && g_file_info_get_edit_name (info) != NULL)
{
if (g_set_str (&self->initial_name, g_file_info_get_edit_name (info)))
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INITIAL_NAME]);
@@ -724,7 +724,7 @@ gtk_file_dialog_set_initial_file (GtkFileDialog *self,
g_free (name);
g_free (relative);
}
g_object_unref (info);
g_clear_object (&info);
g_object_unref (folder);
}
else
+6 -6
View File
@@ -22,7 +22,7 @@
#include "gtkfilelauncher.h"
#include "gtkdialogerror.h"
#include "gopenuriportal.h"
#include "gtkopenuriportal.h"
#include "deprecated/gtkshow.h"
#include <glib/gi18n-lib.h>
@@ -219,7 +219,7 @@ open_done (GObject *source,
GTask *task = G_TASK (data);
GError *error = NULL;
if (!g_openuri_portal_open_finish (result, &error))
if (!gtk_openuri_portal_open_finish (result, &error))
g_task_return_error (task, error);
else
g_task_return_boolean (task, TRUE);
@@ -367,9 +367,9 @@ gtk_file_launcher_launch (GtkFileLauncher *self,
}
#ifndef G_OS_WIN32
if (g_openuri_portal_is_available ())
if (gtk_openuri_portal_is_available ())
{
g_openuri_portal_open_async (self->file, FALSE, parent, cancellable, open_done, task);
gtk_openuri_portal_open_async (self->file, FALSE, parent, cancellable, open_done, task);
}
else
#endif
@@ -461,9 +461,9 @@ gtk_file_launcher_open_containing_folder (GtkFileLauncher *self,
}
#ifndef G_OS_WIN32
if (g_openuri_portal_is_available ())
if (gtk_openuri_portal_is_available ())
{
g_openuri_portal_open_async (self->file, TRUE, parent, cancellable, open_done, task);
gtk_openuri_portal_open_async (self->file, TRUE, parent, cancellable, open_done, task);
}
else
#endif
+48 -4
View File
@@ -69,7 +69,7 @@
*
* Within a widget, gestures can be grouped through [method@Gtk.Gesture.group].
* Grouped gestures synchronize the state of sequences, so calling
* [method@Gtk.Gesture.set_sequence_state] on one will effectively propagate
* [method@Gtk.Gesture.set_state] on one will effectively propagate
* the state throughout the group.
*
* By default, all sequences start out in the %GTK_EVENT_SEQUENCE_NONE state,
@@ -99,7 +99,7 @@
* again.
*
* Sequence states can't be changed freely.
* See [method@Gtk.Gesture.set_sequence_state] to know about the possible
* See [method@Gtk.Gesture.set_state] to know about the possible
* lifetimes of a `GdkEventSequence`.
*
* ## Touchpad gestures
@@ -519,7 +519,9 @@ _gtk_gesture_update_point (GtkGesture *gesture,
else
state = gtk_gesture_get_group_state (gesture, sequence);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_gesture_set_sequence_state (gesture, sequence, state);
G_GNUC_END_IGNORE_DEPRECATIONS
}
return TRUE;
@@ -1017,6 +1019,8 @@ gtk_gesture_get_sequence_state (GtkGesture *gesture,
*
* Returns: %TRUE if @sequence is handled by @gesture,
* and the state is changed successfully
*
* Deprecated: 4.10. Use [method@Gtk.Gesture.set_state]
*/
gboolean
gtk_gesture_set_sequence_state (GtkGesture *gesture,
@@ -1069,8 +1073,46 @@ gtk_gesture_set_sequence_state (GtkGesture *gesture,
* Sets the state of all sequences that @gesture is currently
* interacting with.
*
* See [method@Gtk.Gesture.set_sequence_state] for more details
* on sequence states.
* Sequences start in state %GTK_EVENT_SEQUENCE_NONE, and whenever
* they change state, they can never go back to that state. Likewise,
* sequences in state %GTK_EVENT_SEQUENCE_DENIED cannot turn back to
* a not denied state. With these rules, the lifetime of an event
* sequence is constrained to the next four:
*
* * None
* * None Denied
* * None Claimed
* * None Claimed Denied
*
* Note: Due to event handling ordering, it may be unsafe to set the
* state on another gesture within a [signal@Gtk.Gesture::begin] signal
* handler, as the callback might be executed before the other gesture
* knows about the sequence. A safe way to perform this could be:
*
* ```c
* static void
* first_gesture_begin_cb (GtkGesture *first_gesture,
* GdkEventSequence *sequence,
* gpointer user_data)
* {
* gtk_gesture_set_state (first_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
* gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
* }
*
* static void
* second_gesture_begin_cb (GtkGesture *second_gesture,
* GdkEventSequence *sequence,
* gpointer user_data)
* {
* if (gtk_gesture_get_sequence_state (first_gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
* gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
* }
* ```
*
* If both gestures are in the same group, just set the state on
* the gesture emitting the event, the sequence will be already
* be initialized to the group's global state when the second
* gesture processes the event.
*
* Returns: %TRUE if the state of at least one sequence
* was changed successfully
@@ -1090,8 +1132,10 @@ gtk_gesture_set_state (GtkGesture *gesture,
priv = gtk_gesture_get_instance_private (gesture);
sequences = g_hash_table_get_keys (priv->points);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
for (l = sequences; l; l = l->next)
handled |= gtk_gesture_set_sequence_state (gesture, l->data, state);
G_GNUC_END_IGNORE_DEPRECATIONS
g_list_free (sequences);
+1 -1
View File
@@ -51,7 +51,7 @@ GDK_AVAILABLE_IN_ALL
GtkEventSequenceState
gtk_gesture_get_sequence_state (GtkGesture *gesture,
GdkEventSequence *sequence);
GDK_AVAILABLE_IN_ALL
GDK_DEPRECATED_IN_4_10
gboolean gtk_gesture_set_sequence_state (GtkGesture *gesture,
GdkEventSequence *sequence,
GtkEventSequenceState state);
+2 -1
View File
@@ -33,6 +33,7 @@
#include "gtksnapshot.h"
#include "gtkwidgetprivate.h"
#include "gdk/gdkprofilerprivate.h"
#include "gtksymbolicpaintable.h"
struct _GtkIconHelper
{
@@ -123,7 +124,7 @@ gtk_icon_helper_load_paintable (GtkIconHelper *self,
{
case GTK_IMAGE_PAINTABLE:
paintable = g_object_ref (gtk_image_definition_get_paintable (self->def));
symbolic = FALSE;
symbolic = GTK_IS_SYMBOLIC_PAINTABLE (paintable);
break;
case GTK_IMAGE_ICON_NAME:
+1 -1
View File
@@ -3046,7 +3046,7 @@ theme_lookup_icon (IconTheme *theme,
IconThemeDirSize *min_dir_size;
IconThemeFile *min_file;
int min_difference;
IconCacheFlag min_suffix;
IconCacheFlag min_suffix = ICON_CACHE_FLAG_PNG_SUFFIX;
int i;
min_difference = G_MAXINT;
+1 -4
View File
@@ -1441,13 +1441,10 @@ gesture_pressed (GtkGestureClick *gesture,
double y,
GtkWidget *widget)
{
GdkEventSequence *sequence;
if (gtk_widget_get_focus_on_click (widget) && !gtk_widget_has_focus (widget))
gtk_widget_grab_focus (widget);
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
gtk_gesture_set_sequence_state (GTK_GESTURE (gesture), sequence, GTK_EVENT_SEQUENCE_CLAIMED);
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static void
+33 -33
View File
@@ -26,7 +26,7 @@
#include <string.h>
#include <glib/gstdio.h>
#include "gopenuriportal.h"
#include "gtkopenuriportal.h"
#include "xdp-dbus.h"
#include "gtkwindowprivate.h"
#include "gtkprivate.h"
@@ -43,7 +43,7 @@
#endif
static GXdpOpenURI *openuri;
static GtkXdpOpenURI *openuri;
static gboolean
init_openuri_portal (void)
@@ -57,10 +57,10 @@ init_openuri_portal (void)
if (connection != NULL)
{
openuri = gxdp_open_uri_proxy_new_sync (connection, 0,
PORTAL_BUS_NAME,
PORTAL_OBJECT_PATH,
NULL, &error);
openuri = gtk_xdp_open_uri_proxy_new_sync (connection, 0,
PORTAL_BUS_NAME,
PORTAL_OBJECT_PATH,
NULL, &error);
if (openuri == NULL)
{
g_warning ("Cannot create OpenURI portal proxy: %s", error->message);
@@ -83,7 +83,7 @@ init_openuri_portal (void)
}
gboolean
g_openuri_portal_is_available (void)
gtk_openuri_portal_is_available (void)
{
return init_openuri_portal ();
}
@@ -169,7 +169,7 @@ open_call_done (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GXdpOpenURI *portal = GXDP_OPEN_URI (source);
GtkXdpOpenURI *portal = GTK_XDP_OPEN_URI (source);
GTask *task = user_data;
OpenUriData *data = g_task_get_task_data (task);
GError *error = NULL;
@@ -179,13 +179,13 @@ open_call_done (GObject *source,
switch (data->call)
{
case OPEN_FILE:
res = gxdp_open_uri_call_open_file_finish (portal, &path, NULL, result, &error);
res = gtk_xdp_open_uri_call_open_file_finish (portal, &path, NULL, result, &error);
break;
case OPEN_FOLDER:
res = gxdp_open_uri_call_open_directory_finish (portal, &path, NULL, result, &error);
res = gtk_xdp_open_uri_call_open_directory_finish (portal, &path, NULL, result, &error);
break;
case OPEN_URI:
res = gxdp_open_uri_call_open_uri_finish (portal, &path, result, &error);
res = gtk_xdp_open_uri_call_open_uri_finish (portal, &path, result, &error);
break;
default:
g_assert_not_reached ();
@@ -341,7 +341,7 @@ open_uri (OpenUriData *data,
if (open_folder)
{
data->call = OPEN_FOLDER;
gxdp_open_uri_call_open_directory (openuri,
gtk_xdp_open_uri_call_open_directory (openuri,
parent_window ? parent_window : "",
g_variant_new ("h", fd_id),
opts,
@@ -353,7 +353,7 @@ open_uri (OpenUriData *data,
else
{
data->call = OPEN_FILE;
gxdp_open_uri_call_open_file (openuri,
gtk_xdp_open_uri_call_open_file (openuri,
parent_window ? parent_window : "",
g_variant_new ("h", fd_id),
opts,
@@ -373,7 +373,7 @@ open_uri (OpenUriData *data,
uri = g_file_get_uri (file);
data->call = OPEN_URI;
gxdp_open_uri_call_open_uri (openuri,
gtk_xdp_open_uri_call_open_uri (openuri,
parent_window ? parent_window : "",
uri ? uri : data->uri,
opts,
@@ -441,12 +441,12 @@ window_handle_exported (GtkWindow *window,
}
void
g_openuri_portal_open_async (GFile *file,
gboolean open_folder,
GtkWindow *parent,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
gtk_openuri_portal_open_async (GFile *file,
gboolean open_folder,
GtkWindow *parent,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
OpenUriData *data;
@@ -465,27 +465,27 @@ g_openuri_portal_open_async (GFile *file,
data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
data->task = g_task_new (parent, cancellable, callback, user_data);
g_task_set_check_cancellable (data->task, FALSE);
g_task_set_source_tag (data->task, g_openuri_portal_open_async);
g_task_set_source_tag (data->task, gtk_openuri_portal_open_async);
if (!parent || !gtk_window_export_handle (parent, window_handle_exported, data))
window_handle_exported (parent, NULL, data);
}
gboolean
g_openuri_portal_open_finish (GAsyncResult *result,
GError **error)
gtk_openuri_portal_open_finish (GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == g_openuri_portal_open_async, FALSE);
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_openuri_portal_open_async, FALSE);
return g_task_propagate_boolean (G_TASK (result), error);
}
void
g_openuri_portal_open_uri_async (const char *uri,
GtkWindow *parent,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
gtk_openuri_portal_open_uri_async (const char *uri,
GtkWindow *parent,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
OpenUriData *data;
@@ -503,17 +503,17 @@ g_openuri_portal_open_uri_async (const char *uri,
data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
data->task = g_task_new (parent, cancellable, callback, user_data);
g_task_set_check_cancellable (data->task, FALSE);
g_task_set_source_tag (data->task, g_openuri_portal_open_uri_async);
g_task_set_source_tag (data->task, gtk_openuri_portal_open_uri_async);
if (!parent || !gtk_window_export_handle (parent, window_handle_exported, data))
window_handle_exported (parent, NULL, data);
}
gboolean
g_openuri_portal_open_uri_finish (GAsyncResult *result,
GError **error)
gtk_openuri_portal_open_uri_finish (GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == g_openuri_portal_open_uri_async, FALSE);
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_openuri_portal_open_uri_async, FALSE);
return g_task_propagate_boolean (G_TASK (result), error);
}

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