Compare commits

..

512 Commits

Author SHA1 Message Date
Chun-wei Fan
bdbd8edc56 GDK/Win32: Re-enable libANGLE GLES to work
For libANGLE on Windows, it only supports GLES but not enough desktop GL,
even with the EGL_KHR_create_context extension, so check whether we are
using a libANGLE EGL implementation and enforce that we only allow the
GLES API set just before we realize the context, if that is the case.
2023-03-10 18:39:09 +08:00
Fabio Tomat
70fe37cf1b Update Friulian translation 2023-03-10 07:49:25 +00:00
Matthias Clasen
12858114a2 Merge branch 'more-size-allocation-fixes' into 'main'
widget: Skip popovers in allocation

See merge request GNOME/gtk!5615
2023-03-08 22:26:51 +00:00
Matthias Clasen
4f6133e00a Merge branch 'wip/chergert/fix-const-preserving-text-iter-order' into 'main'
textlinedisplaycache: fix const-preserving gtk_text_iter_order()

See merge request GNOME/gtk!5620
2023-03-08 22:06:04 +00:00
Matthias Clasen
9ca3a52bf0 Merge branch 'file_chooser_stuff' into 'main'
filechooser: two small changes

See merge request GNOME/gtk!5619
2023-03-08 21:57:13 +00:00
Christian Hergert
40d99839d6 textlinedisplaycache: fix const-preserving gtk_text_iter_order() 2023-03-08 13:00:08 -08:00
Barnabás Pőcze
111e8d2808 filechooser: Do not look up parents of directories
If the `GtkRecentInfo` represents a directory, simply use it, and
do not try to find its parent in `_gtk_file_chooser_extract_recent_folders()`.

For example, there is an entry in my recently-used database
from the Amberol music player about the folder I have opened
with it, but the folder is not listed on the "Recent" tab of
the file chooser widget, only its parent. After this change,
the directory itself is shown.
2023-03-08 20:46:17 +01:00
Barnabás Pőcze
9b0b3029a6 filechooser: Use gtk_recent_info_is_local() for filtering
There is already a function for determining if URI
has the "file" scheme, so use that.
2023-03-08 20:04:41 +01:00
Matthias Clasen
f743b95161 Merge branch 'ebassi/issue-5650' into 'main'
Filter recently used files in the file chooser

Closes #5650

See merge request GNOME/gtk!5618
2023-03-08 18:45:10 +00:00
Matthias Clasen
bdd35c1695 Merge branch 'fix-msvc-older-glib' into 'main'
modules/media: Fix Visual Studio builds with older GLib (<= 2.74.x)

See merge request GNOME/gtk!5605
2023-03-08 18:44:46 +00:00
Matthias Clasen
2f273ba76a widget: Skip popovers in allocation
Native widgets get allocated via their surface,
so can skip them here. This avoids criticals when
re-mapping a popover for the second time, as can
be seen e.g. in the 'Selections' demo in gtk4-demo.
2023-03-08 13:40:51 -05:00
Matthias Clasen
a2d14632de widget: Stop propagating alloc_needed beyond popovers
This should not be necessary, since popovers get
their new size from present_popup via the compositor.
2023-03-08 13:40:48 -05:00
Benjamin Otte
7a3e130efd widget: Remove goto usage in widget_allocate() 2023-03-08 13:40:37 -05:00
Benjamin Otte
c8d356a250 widget: Split out gtk_widget_ensure_allocate_on_children()
allocate() should not be calling into ensure_allocate(), they do a similar job.
In the end, the code does the same work, but it should be easier to follow now.
2023-03-08 13:40:31 -05:00
Matthias Clasen
ffb7177c2e widget: Simplify size allocation
Don't call ensure_allocate if we've just
done size_allocate. This makes criticals
from reshowing popovers go away.
2023-03-08 13:39:54 -05:00
Emmanuele Bassi
8b2202cd56 Filter recently used files in the file chooser
Since it's a file selection widget, we should only list recently used
files that point to a file.

Fixes: #5650
2023-03-08 18:08:24 +00:00
Matthias Clasen
14a5c78d80 Merge branch 'wip/carlosg/reuse-search-engine' into 'main'
gtkfilechooser: Keep GtkSearchEngine around for longer

See merge request GNOME/gtk!5617
2023-03-08 12:58:43 +00:00
Carlos Garnacho
5fd2a6c8f3 gtkfilechooser: Keep GtkSearchEngine around for longer
Currently the GtkSearchEngine is torn down every time the search
is stopped, which also means between typed characters. This
prevents any of the optimizations that the GtkSearchEngine can
do in the long run.

Let the GtkSearchEngine stay around for longer, and only be
disposed after search is cancelled, the filechooser moves
onto a different mode than search, or is otherwise unmapped/disposed.

While at it, remove an unused struct field.
2023-03-08 13:23:56 +01:00
Matthias Clasen
6cb6f4a50f Merge branch 'wip/carlosg/recursive-file-search' into 'main'
searchengine: Improve performance for recursive search

Closes #4133

See merge request GNOME/gtk!5611
2023-03-08 11:56:41 +00:00
Carlos Garnacho
7b909fb310 searchengine: Do not fight filechooser search mode sorting
Provide the hits in an order that is more easily consumed by the
filechooser, and less jarring when populating.
2023-03-08 11:33:10 +01:00
Carlos Garnacho
d12bea03d2 searchengine: Bail out on the first character
Again on massive filesystems, the very first character
is likely to bring a likewise massive amount of search
results that we need to maybe query info for, then create
icons and widgets for. While it's impressive we can do
that, it's also expensive and likely pointless, for the
first character.

Typing a second character is however very likely to
considerably reduce the amount of items to categorize and
show. So start actually searching from there.

Testing on a filesystem with 1434099 files indexed, trying 5
semi-random 1 character searches (n, h, t, i, o) returns on
average 168K items (min. 78771, max. 331471), trying 5
semi-random 2 character searches (no, he, th, in, on)
returns on average 34K items (min. 11133, max. 94961),
which is a more approachable set.

Doing this is enough that typing on a filechooser search
entry feels completely fluid.
2023-03-08 11:33:10 +01:00
Carlos Garnacho
deacc63d54 searchengine: Ensure some GFileInfo fields
The search provider should make it sure there are some
specific GFileInfo fields set. Fix the mimetype extraction
from the query, and use that to fill in the missing gaps
the best we can.
2023-03-08 11:33:10 +01:00
Carlos Garnacho
ead121a3c1 searchengine: Drop non-recursive search
Recursive search seems to be the hardcoded default, go with it.
2023-03-08 11:33:10 +01:00
Carlos Garnacho
de4725dbd5 searchengine: Populate filesystem model in an idle
When starting a search over a very populated filesystem, it
is possible that typing the first chars will return a too
high number of results. Even though iterating through the
cursor is in itself very fast, extracting the GIO information
from those many files at once is not going to be as fast.

In order to increase interactivity (i.e. not make things
possibly sluggish) iterate the cursor in an idle function
and add search results to the filechooser model little by little.

If the user keeps typing (as it is likely will happen), there
will be better chances to cancel and proceed to the next
query timely. If not, the results will be there soon enough.
2023-03-08 11:32:44 +01:00
Matthias Clasen
7f5504523f Merge branch 'check_null_gfile_location' into 'main'
filechooser: Fix memory leaks

See merge request GNOME/gtk!5610
2023-03-08 03:19:00 +00:00
Matthias Clasen
40b154bf28 Merge branch 'matthiasc/for-main' into 'main'
build: Handle introspection a bit better

See merge request GNOME/gtk!5614
2023-03-08 03:02:16 +00:00
Barnabás Pőcze
f0e4293b83 filechooser: Fix memory leaks
The returned strings from `file_chooser_get_location()` were never freed.
2023-03-08 03:59:10 +01:00
Matthias Clasen
87f820287a build: Handle introspection a bit better
Error out if introspection is requested,
but g-ir-scanner isn't found.

And if introspection isn't explicitly disabled
but is required for building the docs, build it.
2023-03-07 21:49:24 -05:00
Matthias Clasen
30586d75ac Merge branch 'matthiasc/for-main' into 'main'
filechooser: Handle pathless files

See merge request GNOME/gtk!5613
2023-03-08 02:31:19 +00:00
Matthias Clasen
7a1573a381 Merge branch 'expose_checkable_state' into 'main'
a11y: When an accessible has GTK_STATE_CHECKED, set its ATSPI_STATE_CHECKABLE as well

See merge request GNOME/gtk!5602
2023-03-08 02:07:39 +00:00
Matthias Clasen
bc42955a13 filechooser: Handle pathless files
g_file_get_path() can return NULL. Make our
getter for file locations handle that case.

Related: !5610
2023-03-07 20:54:31 -05:00
Matthias Clasen
cdc008763b Merge branch 'matthiasc/for-main' into 'main'
wayland: Don't crash during DND with Cairo renderer

See merge request GNOME/gtk!5612
2023-03-08 01:46:43 +00:00
Benjamin Otte
7fff188557 wayland: Don't crash during DND with Cairo renderer
Attaching buffers with offsets is forbidden now and nobody
checked the Cairo renderer.
2023-03-07 20:16:59 -05:00
Benjamin Otte
69238c1197 text: Don't crash when somebody drops NULL 2023-03-07 20:16:59 -05:00
Emmanuele Bassi
574380c744 Merge branch 'wroy-main-patch-03255' into 'main'
MSBuild: Fix gnome.compile_resources current source directory

See merge request GNOME/gtk!5609
2023-03-07 23:48:25 +00:00
Emmanuele Bassi
d1fc1adae7 Apply suggestion to use '/' over join_paths 2023-03-07 22:40:17 +00:00
Carlos Garnacho
64697ea95b searchengine: Improve performance for recursive search
As fancy as property paths are, recursive resolution of files
to a location increases the big O complexity enough that it's
not a great option on large homedirs with many indexed files.

Ensure the files are from the right location through a URI
prefix match, which does hits an index. This may dramatically
improve performance on large indexed trees.

Testing this query in an isolated testcase with a total
1434099 indexed files shows that it can run more than 1500 times
per second in this computer (an average of 15200 queries in
several 10 second runs), which presumably is a tad faster than
anyone can type.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4133
2023-03-07 23:18:46 +01:00
William Roy
aaeec84d75 Fix compile_resources present source directory
In certain scenarios, address the issue where gnome.compile_resources 
fails to transmit the present source directory. This is most notably 
visible with MSBuild.
2023-03-07 21:59:50 +00:00
Matthias Clasen
5822ba76d0 Merge branch 'unbreak-combobox' into 'main'
combobox: Avoid extra queue_resize()

Closes #5644

See merge request GNOME/gtk!5608
2023-03-07 19:10:51 +00:00
Ask Hjorth Larsen
a6ad8ebe0c Updated Danish translation 2023-03-07 20:02:40 +01:00
Ivan Molodetskikh
55faea1046 combobox: Avoid extra queue_resize()
width-request already ensures it's above the minimum width, so avoid an
extra queue_resize() when setting size request to (-1, -1).

This is the same way as GtkDropDown works. This also unbreaks
GtkComboBox after the recent allocation fix in
75a417e337.

Incidentally, this also makes GtkComboBox actually resize its popup as
intended (that was broken before).

I don't think this is ultimately the final fix, sometimes I still get
allocation warnings. But the proper fix will probably involve changing
some more allocation machinery around popovers. This is good enough for
now.
2023-03-07 09:55:30 -08:00
Matthias Clasen
21ee81823e Merge branch 'window-signals' into 'main'
window: Disconnect the ::compute-size handler

See merge request GNOME/gtk!5606
2023-03-07 13:15:21 +00:00
Matthias Clasen
9efd8ef201 window: Disconnect the ::compute-size handler
All the other signal handlers are connected in
realize and disconnected in unrealize, but the
::compute-size handler was forgotten.

This was notices in !5597.
2023-03-07 06:40:25 -05:00
Chun-wei Fan
432e8664e1 modules/media: Fix Visual Studio builds with older GLib
The current definitions of the g_io_module_*() symbols do not build on
Visual Studio when building against GLib earlier than 2.75.0 due to the
way how these symbols are decorated in the GLib headers, as Visual Studio
does not allow symbols that were previously marked with 'extern' (or so)
to be marked with anything that is symantically different later.

As a result, if we are using Visual Studio and glib-2.74.x or earlier,
override _GLIB_EXTERN as appropriate in the modules/media sources before
including the GIO headers.  This sadly, means that we need a
configure-time check as it would have been too late if we checked the
GLib version using G_VERSION_CHECK macro, as the GIO headers would have
been included already.

There are similar items in the print backends, but we will not attempt
to update these files as they are not meant to be built for Windows.
2023-03-07 15:36:42 +08:00
Matthias Clasen
6d2c5e51e0 Merge branch 'expose_landmark_role' into 'main'
a11y: Expose GTK_ACCESSIBLE_ROLE_LANDMARK to AtSPI2

See merge request GNOME/gtk!5601
2023-03-06 17:49:05 +00:00
Lukáš Tyrychtr
b669295fd8 a11y: When an accessible has GTK_STATE_CHECKED, set its ATSPI_STATE_CHECKABLE as well
This allows, for example, checkable list itemss.
2023-03-06 17:15:54 +01:00
Lukáš Tyrychtr
96e6332d28 a11y: Expose GTK_ACCESSIBLE_ROLE_LANDMARK to AtSPI2 2023-03-06 16:45:19 +01:00
Marek Černocký
59549d0665 Update Czech translation 2023-03-06 11:57:22 +00:00
Emmanuele Bassi
3e3158ce12 Merge branch 'wip/exalm/template' into 'main'
widget: Use the correct template in dispose_template()

See merge request GNOME/gtk!5600
2023-03-06 11:00:04 +00:00
Matthias Clasen
cfc2de4e3d Merge branch 'main' into 'main'
removed duplicate function call

See merge request GNOME/gtk!5545
2023-03-06 05:52:00 +00:00
Matthias Clasen
343852af7b Merge branch 'matthiasc/for-main' into 'main'
macos: Fix type func generation

See merge request GNOME/gtk!5596
2023-03-06 05:50:36 +00:00
Matthias Clasen
51902bbce8 Merge branch 'wip/fix-wl-destruct-order' into 'main'
wayland: Destroy xdg_surface after role

See merge request GNOME/gtk!5598
2023-03-06 05:08:44 +00:00
Alexander Mikhaylenko
9b3fb66bd4 widget: Use the correct template in dispose_template()
In derivable classes, the widget's class can be different from the one
dispose_template() was called for, which can lead to failing the
template != NULL check at best, undefined behavior at worst.

Since we already pass the correct GType into the function, just use that
instead.
2023-03-06 05:37:53 +04:00
Benjamin Otte
3ccf63b3c0 Merge branch 'wip/otte/for-main' into 'main'
inspector: Make really sure we don't inspect ourselves

See merge request GNOME/gtk!5599
2023-03-05 23:49:15 +00:00
Benjamin Otte
4655226907 inspector: Make really sure we don't inspect ourselves
The problem here is that new windows appear in the list before the
window's dispay gets set and we don't update the filter when the
display changes (would need watches support for the filtermodel).

So add this somewhat hacky method.
2023-03-06 00:13:53 +01:00
Jonas Ådahl
4500fa633b wayland: Destroy xdg_surface after role
The split-up of gdksurface-wayland.c introduced a protocol violation
when it didn't make sure xdg_surface was destroyed after the role
objects (xdg_popup / xdg_toplevel). Fix that.

Fixes: 2a463baed0 ("wayland: Rearrange the surface code")
2023-03-05 20:55:41 +01:00
Matthias Clasen
be11202538 macos: Fix type func generation
We were checking for gdk_quartz even though
the sysbols are now all called gdk_macos. Oops.
2023-03-05 10:17:52 -08:00
Benjamin Otte
0fa1e71ef0 Merge branch 'wip/otte/for-main' into 'main'
cssnode: Don't crash the inspector

See merge request GNOME/gtk!5595
2023-03-05 17:53:18 +00:00
Benjamin Otte
987b9cec3f testsuite: Add tests for the unknown enums
See commit 40e7a265a7
2023-03-05 18:35:02 +01:00
Benjamin Otte
a77beb39a1 testsuite: Add empty test for new node 2023-03-05 18:33:37 +01:00
Benjamin Otte
ac8e053ab6 cssnode: Don't crash the inspector
Don't misinform the observing listmodel that CSS nodes were removed that
weren't actually removed, but just moved. Otherwise the observer would
think it has run out of items when it really hasn't.
2023-03-05 18:33:37 +01:00
Matthias Clasen
986275239f Merge branch 'matthiasc/for-main' into 'main'
meson: Mention testsuite in summary

See merge request GNOME/gtk!5594
2023-03-05 16:51:23 +00:00
Matthias Clasen
2ee1273244 meson: Mention testsuite in summary
This was broken out from the 'tests' toggle,
so list it separately.
2023-03-05 08:10:12 -08:00
Matthias Clasen
248027a366 Merge branch 'expose_error_message_relation' into 'main'
a11y: Expose GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE to AtSPI2

See merge request GNOME/gtk!5588
2023-03-05 16:08:38 +00:00
Benjamin Otte
c823432eef Merge branch 'wip/otte/listview2' into 'main'
listview: GtkListTile

See merge request GNOME/gtk!5584
2023-03-05 15:53:43 +00:00
Matthias Clasen
98ac2de649 Merge branch 'matthiasc/for-main' into 'main'
ci: Disable the testsuite in flatpak builds

See merge request GNOME/gtk!5593
2023-03-05 15:46:13 +00:00
Matthias Clasen
1cee54009a ci: Disable the testsuite in flatpak builds
No need to build the testsuite when we are
just producing flatpaks.
2023-03-05 07:26:17 -08:00
Benjamin Otte
80b7c60150 listbase: Remove nonexisting function from header 2023-03-05 15:23:20 +00:00
Benjamin Otte
e8c5a771e5 gridview: Add a filler tile for empty space
That stupid space in the bottom right when n_items isn't a multiple of
n_columns needs its own tile, or we'll get errors about not finding a
tile.

So make one.
2023-03-05 15:23:20 +00:00
Benjamin Otte
882dcda53b columnview: Clear the sorter first thing in dispose
Otherwise, when removing the columns, each column will trigger a
sorter::changed signal emission.

And because sorters are often still connected to a sortlistmodel, we
can't skip that emission and need to do it.
But we only need to do it once.
2023-03-05 15:23:20 +00:00
Benjamin Otte
b488fae893 listview: Handle emptying of views
The previous check does not longer work.

When a model gets all items deleted, there will still be existing tiles
until the next time garbage collection is run.
So do that before checking if the list is empty.
2023-03-05 15:23:20 +00:00
Benjamin Otte
b962defc11 listview: Remove an unused member variable
It's only used in the allocate function, so make it a local varaible
there.
2023-03-05 15:23:20 +00:00
Benjamin Otte
9ee0696923 listview: Simplify a vfunc
Instead of making it 2 vfuncs for getting horizontal and vertical area,
make it one vfunc to get the area.

Also rewrite the implementations to use the tile's area instead of
trying to deduce things with fancy math.
2023-03-05 15:23:20 +00:00
Benjamin Otte
f3c53ae69d listview: Simplify allocation
With the Tile changes, a lot of stuff does no longer need to be
duplicated between listview and gridview. Move it to ListBase instead.
2023-03-05 15:23:20 +00:00
Benjamin Otte
8aea6fc1b5 gridview: Remove an unused member variable
It's only used during size_allocate(), so make it a local variable
there.
2023-03-05 15:23:20 +00:00
Benjamin Otte
d949afb80e listitemmanager: Add a split vfunc and use it
Instead of randomly changing tiles, the listitemmanager gains a split
vfunc that listview and gridview implement so they can keep their tile
areas intact. The listitemmanager will now conform to these rules:

1. Never delete a tile.
   This ensures that all areas stay intact.

2. Never change the n_items of a tile other than setting them to 0.
   This causes "empty" areas to appear, but listview/gridview can
   easily check for them by checking for tile->n_items == 0.
   gtk_list_tile_gc() will get rid of them.

3. Adding items always creates new tiles that are added with empty area.
   That way they don't interrupt any existing machinery until the next
   allocation.

4. Adding/removing widgets has no effect on areas
   This is useful in particular when scrolling where new widgets are
   moving between tiles. When the manager moves the widgets, it may
   split some areas, but will not remove any existing tiles, so the
   whole area stays intact and the list can deal with further scroll
   events before an allocation.

This improve the situation for #3334
2023-03-05 15:23:20 +00:00
Benjamin Otte
08c583b1b3 listview: Add gc'ing
This is in preparation for the following reorg of the listitemmanager,
it should not have any effect now.
2023-03-05 15:23:20 +00:00
Benjamin Otte
1c663cb340 listitemmanager: Remove unused functionality
Both ListView and GridView use GtkListTile now, so no need anymore for
custom machinery.
2023-03-05 15:23:20 +00:00
Benjamin Otte
776910d03d gridview: Redo tile management
Instead of the custom size property, use the new tile size.

Also introduce the ability to split tiles, so that gridview can split a
layout that would look like (question mark denoting cells without a
widget, which in this case would be a single tile)

█ █ █ ? ?
? ? ? ? ?
? ? ? ? ?
? ? ?

into 3 rectangular tiles like so:

█ █ █ A A
B B B B B
B B B B B
C C C

This of course also means we need to be able to merge those tiles again
when cells got added/deleted or the gridview was resized. For that job,
gtk_list_tile_gc() exists now, which removes tiles without items and
merges adjacent tiles without widgets.
2023-03-05 15:23:20 +00:00
Benjamin Otte
c82b2d86c0 listview: Get rid of ListRow and its height
Use the tiles' area instead.
2023-03-05 15:23:20 +00:00
Benjamin Otte
3ca4acdc1a list: Allow storing size in the ListTile
... and use it to handle ListView allocations.

Nothing spectacular, just proof of concept.

The code introduces the idea that every tile stores its area (others
would call it "allocation", but I avoided that because tiles aren't
widgets). This should allow moving lots of code into gtklistbase.c and
not require special handling inside ListView and GridView.

And that in turn hopefully makes it easier to add more features (like
sections and so on.)
2023-03-05 15:23:20 +00:00
Benjamin Otte
c705dba2ee list: Make GtkListTile more prominent
* Instead of using a gpointer to refer to it, use the GtkListTile type.

* Use gtk_list_tile_get_foo() instead of
  gtk_list_item_manager_get_tile_foo() naming.
2023-03-05 15:23:20 +00:00
Benjamin Otte
55ad241f43 list: Rename GtkListItemManagerItem => GtkListTile
That's a good description for what the job of those elements is:
They're a tile in the lists scrollable area.
2023-03-05 15:23:20 +00:00
Benjamin Otte
d3efd80b90 rendernodepaintable: Allow the node to be NULL
This can happen when creating paintables from GtkSnapshot when nothing
was drawn.
2023-03-05 15:23:20 +00:00
Jordi Mas
a899c0af6e Update Catalan translation 2023-03-05 09:44:49 +01:00
Matthias Clasen
f8fb30b555 Post-release version bump 2023-03-04 13:47:37 -08:00
Matthias Clasen
47aa0dcc7f 4.10.0 2023-03-04 08:28:12 -08:00
Emmanuele Bassi
32f0723bf0 Merge branch 'ebassi/file-info-attributes' into 'main'
Check for attributes being available before querying them

See merge request GNOME/gtk!5592
2023-03-04 16:04:04 +00:00
Matthias Clasen
90a3584c1d Merge branch 'wip/otte/dont-scale-or-it-breaks' into 'main'
Add a test for lots of texture scaling and fix the fallout

See merge request GNOME/gtk!5509
2023-03-04 15:57:49 +00:00
Emmanuele Bassi
891b6dc4a9 Check for attributes being available before querying them
GLib 2.75 started checking if a GFileInfo was created with the attribute
we're querying, instead of failing silently and leaving us in an
inconsistent state.

Turns out that GtkFileChooserWidget, GtkFileSystemModel, and GtkPathBar
trip the newly introduced check.
2023-03-04 15:28:53 +00:00
Emmanuele Bassi
c6ff7400a8 Merge branch 'wip/chergert/fix-action-activation-crash' into 'main'
inspector: be defensive against out parameters

See merge request GNOME/gtk!5591
2023-03-04 15:16:59 +00:00
Emmanuele Bassi
6620b7de92 Merge branch 'ebassi/stack-page-fix' into 'main'
a11y: Fix GtkStackPage first accessible child

See merge request GNOME/gtk!5590
2023-03-04 15:16:34 +00:00
Aleksandr Melman
d58071b4c1 Update Russian translation 2023-03-04 15:05:45 +00:00
Piotr Drąg
f38df62e2b Update Polish translation 2023-03-04 15:59:29 +01:00
Benjamin Otte
0581e38b09 testsuite: Add a test for stripes
The GL renderer was creating sripes for nodes that were scaled in
particular ways, probably due to rounding errors.

This testsuite focuses on one of those stripes to make sure they are
gone.
2023-03-04 02:50:38 +01:00
Emmanuele Bassi
74a00319dd a11y: Use weak references for GtkATContext cached accessibles
The accessible objects already own the GtkATContext, let's avoid a
reference cycle.
2023-03-03 22:07:09 +00:00
Matthias Clasen
611788fb53 stack: Don't recreate at contexts in dispose
This is the same protection we have in
GtkWidgetAccessible.
2023-03-03 22:07:09 +00:00
Emmanuele Bassi
500128d186 a11y: Plug reference leaks
The gtk_accessible_get_at_context() getter is now transfer full, which
means we need to drop the reference when getting the GtkATContext.
2023-03-03 22:07:09 +00:00
Christian Hergert
32cf104167 inspector: be defensive against out parameters
Set initial state to NULL so that we don't risk accessing an unset out
parameter.

Fixes a crash when activating certain actions.
2023-03-03 12:17:32 -08:00
Emmanuele Bassi
9b98426e71 a11y: Simplify bookkeeping while iterating accessible children 2023-03-03 18:02:22 +00:00
Emmanuele Bassi
9820d25cf9 a11y: Fix GtkStackPage first accessible child
The first accessible child is the child widget of the GtkStackPage, not
the first child of the widget.
2023-03-03 18:02:22 +00:00
Benjamin Otte
8bbf220fdf testsuite: Add a test for large scale nodes
This test fails if we naively create fullscale
intermediate offscreens. This was fixed in the
previous commits.

This tests the fixes in 22ba6b1f33 (for
cairo) and 3a0152b65f (for GL).
2023-03-03 11:33:57 -06:00
Matthias Clasen
3a0152b65f gl: Respect clip wehn drawing scale nodes
Use the same approach and only create an offscreen
that is big enough for the clipped part of the scaled
texture.

If the clipped part is still too large for a single
texture, we give up and just render the texture without
filters (using the regular texture rendering code path
which supports slicing).

The following commit will add the texture-scale-magnify-10000x
test which fails without this fix.
2023-03-03 11:32:08 -06:00
Benjamin Otte
22ba6b1f33 rendernode: Respect clip when drawing scale nodes
Scale nodes can use large scale factors and we don't want to create
insanely huge Cairo surfaces.

A subsequent commit will add the texture-scale-magnify-10000x
test which fails without this fix.
2023-03-03 11:31:31 -06:00
Benjamin Otte
718b5d5fe7 rendernode: Clarify some Cairo stuff
Split out a function to make it more obvious what's going on.
2023-03-03 11:24:46 -06:00
Benjamin Otte
88dd64551c rendernode: Don't do unnecessary stuff
Cairo surfaces are created transparent.

And even if they weren't, overdrawing with transparency wouldn't erase
what's in the surface because it's a no-op.

It would require CAIRO_OPERATOR_CLEAR or CAIRO_OPERATOR_SOURCE.
2023-03-03 11:24:46 -06:00
Benjamin Otte
98eac8ac83 Fixes for gdk_memory_texture_new_subtexture checks
There were several mistakes here.
2023-03-03 11:24:46 -06:00
Changwoo Ryu
dbb2cb22ca Update Korean translation 2023-03-03 15:36:03 +00:00
Lukáš Tyrychtr
71dbb5090e a11y: Expose GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE to AtSPI2
Also, update the AtSPI2 relations to match the 1.26 version of AtSPI2.
2023-03-03 15:15:59 +01:00
Matthias Clasen
4b46097748 Merge branch 'ebassi/accessible-transfer-full' into 'main'
Mark Accessible getters as transfer full

Closes #5615

See merge request GNOME/gtk!5586
2023-03-03 09:46:51 +00:00
Emmanuele Bassi
eb0f33d76b Mark Accessible getters as transfer full
GtkAccessible implementations in C can get away returning objects just
by shuffling pointers around, but higher level languages prefer using
full ownership transfer in virtual functions.

Fixes: #5615
2023-03-03 02:13:26 +00:00
Emmanuele Bassi
828f686fc9 Merge branch 'expose_details_relation' into 'main'
a11y: Expose GTK_ACCESSIBLE_RELATION_DETAILS to at-spi2

See merge request GNOME/gtk!5580
2023-03-03 01:55:48 +00:00
Emmanuele Bassi
681f8bed19 Merge branch 'fix_section_role' into 'main'
a11y: Fix mapping of GTK_ACCESSIBLE_ROLE_PRESENTATION

See merge request GNOME/gtk!5576
2023-03-03 01:54:51 +00:00
Matthias Clasen
5fe32a46a0 Merge branch 'ebassi/atcontext-dispose' into 'main'
a11y: Clear the accessible tree in GtkATContext

See merge request GNOME/gtk!5587
2023-03-03 01:54:38 +00:00
Emmanuele Bassi
e3548bb9ad Revert "stack: clear accessible parent when removing child"
This reverts commit 40d4441fd8.

The accessible parent of the child widget in a GtkStackPage is cleared
when the GtkATContext gets disposed, so we don't need to unset it
ourselves. This also avoids a temporary vivification of the GtkATContext
during dispose.
2023-03-03 01:39:24 +00:00
Emmanuele Bassi
61506648bf a11y: Clear the accessible tree in GtkATContext
We acquire a reference on the accessible objects, so we need to release
it when disposing the GtkATContext.
2023-03-03 01:38:27 +00:00
Balázs Úr
621b3b51ea Update Hungarian translation 2023-03-03 00:35:25 +00:00
Matthias Clasen
784ba8bf12 Merge branch 'matthiasc/for-main' into 'main'
impcontextsimple: Return from GTask

See merge request GNOME/gtk!5585
2023-03-03 00:19:38 +00:00
Matthias Clasen
d968659b43 impcontextsimple: Return from GTask
GLib complains about this now, so do it.
2023-03-02 16:18:45 -05:00
Emmanuele Bassi
48d3db8daa Merge branch 'leak-fix' into 'main'
gtkatspicontext: Fix a leak of a floating GVariant

See merge request GNOME/gtk!5583
2023-03-01 20:41:53 +00:00
Philip Withnall
ca702b4596 gtkatspicontext: Fix a leak of a floating GVariant
If the early return path in `emit_property_changed()` is taken, and
`value` is floating, it will be leaked. Fix that by sinking `value` on
entry to the function.

Spotted by asan:
```
Direct leak of 128 byte(s) in 2 object(s) allocated from:
    #0 0x7f44774ba6af in __interceptor_malloc (/lib64/libasan.so.8+0xba6af)
    #1 0x7f44764c941a in g_malloc ../../source/glib/glib/gmem.c:130
    #2 0x7f44764f6d8a in g_slice_alloc ../../source/glib/glib/gslice.c:252
    #3 0x7f447654655d in g_variant_alloc ../../source/glib/glib/gvariant-core.c:565
    #4 0x7f447654664c in g_variant_new_from_bytes ../../source/glib/glib/gvariant-core.c:608
    #5 0x7f4476536ed5 in g_variant_new_take_string ../../source/glib/glib/gvariant.c:1307
    #6 0x7f4475c75ada in gtk_at_spi_context_state_change ../../source/gtk4/gtk/a11y/gtkatspicontext.c:1112
    #7 0x7f44758ee194 in gtk_at_context_update ../../source/gtk4/gtk/gtkatcontext.c:694
    #8 0x7f44758dbfcf in gtk_accessible_update_property ../../source/gtk4/gtk/gtkaccessible.c:326
    #9 0x7f4475b5abe3 in gtk_widget_set_tooltip_text ../../source/gtk4/gtk/gtkwidget.c:9740
    #10 0x58439d in gs_updates_page_update_ui_state ../../source/gnome-software/src/gs-updates-page.c:302
    #11 0x5857dc in gs_updates_page_set_state ../../source/gnome-software/src/gs-updates-page.c:403
    #12 0x5879f1 in gs_updates_page_load ../../source/gnome-software/src/gs-updates-page.c:636
    #13 0x58822d in gs_updates_page_reload ../../source/gnome-software/src/gs-updates-page.c:678
    #14 0x50ff48 in gs_page_reload ../../source/gnome-software/src/gs-page.c:731
    #15 0x5491ce in gs_shell_reload_cb ../../source/gnome-software/src/gs-shell.c:830
    #16 0x7f4477363f54 in g_cclosure_marshal_VOID__VOID ../../source/glib/gobject/gmarshal.c:117
    #17 0x7f447735e0ad in g_closure_invoke ../../source/glib/gobject/gclosure.c:832
    #18 0x7f4477391f3f in signal_emit_unlocked_R ../../source/glib/gobject/gsignal.c:3802
    #19 0x7f4477390c13 in g_signal_emit_valist ../../source/glib/gobject/gsignal.c:3555
    #20 0x7f4477391324 in g_signal_emit ../../source/glib/gobject/gsignal.c:3612
    #21 0x7f447705b3c3 in gs_plugin_loader_reload_delay_cb ../../source/gnome-software/lib/gs-plugin-loader.c:1538
    #22 0x7f44764bd140 in g_timeout_dispatch ../../source/glib/glib/gmain.c:5054
    #23 0x7f44764b9eb1 in g_main_dispatch ../../source/glib/glib/gmain.c:3460
    #24 0x7f44764bb72c in g_main_context_dispatch ../../source/glib/glib/gmain.c:4200
    #25 0x7f44764bba15 in g_main_context_iterate ../../source/glib/glib/gmain.c:4276
    #26 0x7f44764bbbfa in g_main_context_iteration ../../source/glib/glib/gmain.c:4343
    #27 0x7f44769ef655 in g_application_run ../../source/glib/gio/gapplication.c:2589
    #28 0x4f2da5 in main ../../source/gnome-software/src/gs-main.c:49
    #29 0x7f4474e4a50f in __libc_start_call_main (/lib64/libc.so.6+0x2750f)
```

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2023-03-01 19:42:33 +00:00
Lukáš Tyrychtr
c91ba630a7 a11y: Expose GTK_ACCESSIBLE_RELATION_DETAILS to at-spi2
This particular relation was not exposed to at-spi2.
Exposing it required adding a missing at-spi2 relation variant, but it was introduced
in at-spi2-core 2.26, so that's likely safe as well.
2023-03-01 13:53:39 +01:00
Matthias Clasen
bc99ab38ce Merge branch 'matthiasc/for-main' into 'main'
inspector: Remove debug spew

See merge request GNOME/gtk!5579
2023-03-01 12:36:49 +00:00
Matthias Clasen
fe8c262351 inspector: Remove debug spew 2023-03-01 06:32:52 -05:00
Lukáš Tyrychtr
1b000b5586 a11y: Fix mapping of GTK_ACCESSIBLE_ROLE_PRESENTATION
It was, for some reason, mapped to ATSPI_ROLE_SECTION, and GTK_ACCESSIBLE_ROLE_SECTION was mapped to
ATSPI_ROLE_FILLER, so the mapping is reversed. So, reverse it and make it correct.
2023-03-01 11:07:09 +01:00
Benjamin Otte
1b4f240883 Merge branch 'wip/otte/default-size-docs' into 'main'
window: Clarify docs for default-size

See merge request GNOME/gtk!5569
2023-03-01 10:06:34 +00:00
Benjamin Otte
496f68376b window: Clarify docs for default-size 2023-03-01 10:06:32 +00:00
Matthias Clasen
f019ff5287 Merge branch 'textbuffer-foreground-property' into 'main'
textbuffer: Use correct foreground color property

See merge request GNOME/gtk!5574
2023-03-01 02:46:05 +00:00
Mat
c08e739996 textbuffer: Use correct foreground color property
The 'foreground-rgba' property should be used instead of 'foreground',
since the latter is not readable.
2023-03-01 04:14:19 +02:00
Emmanuele Bassi
8eb3c55709 Merge branch 'wip/chergert/fix-stack-page-leak' into 'main'
stack: clear accessible parent when removing child

Closes #5626

See merge request GNOME/gtk!5571
2023-02-28 23:24:57 +00:00
Christian Hergert
40d4441fd8 stack: clear accessible parent when removing child
Without this, the GtkStackPage may not reach a reference count of zero
and therefore will be leaked.

Fixes #5626
2023-02-28 15:08:20 -08:00
Benjamin Otte
471ebabd77 Merge branch 'gbsneto/filechooser-fixes' into 'main'
Fix GtkFileThumbnail thumbnail query

See merge request GNOME/gtk!5570
2023-02-28 18:04:40 +00:00
Georges Basile Stavracas Neto
d8b7c909ea filethumbnail: Set filechooser::queried after querying
Setting this attribute after querying, but before receiving the
results, can lead to inappropriate behaviour. This can be reproduced
by dragging the scrollbar very quickly in a large directory; after
going up and down a few times, some thumbnails will be wrong.

Without this branch, "wrong" means they'll show the completely wrong
icon or thumbnail, e.g. a folder icon in a video file. With previous
commit, "wrong" means they'll be empty even when there is a thumbnail
available.

The sequence of events that triggers this is as follows:

 1. GtkListItem receives a GFileInfo object and passes it to
    GtkFileThumbnail via expressions

 2. `get_thumbnail()` is called, doesn't find a thumbnail

 3. `filechooser::queried` is not set yet, so it is set to TRUE
      and we call `g_file_query_info_async()`

 4. **Before `thumbnail_queried_cb` is called**, a new GFileInfo
    is set, and we cancel the query initiated in the previous
    step

 5. We now have a GFileInfo with `filechooser::queried` set to
    TRUE, and no thumbnail!

This commit fixes that by only setting the `filechooser::queried`
attribute after the icon is queried. We need to set it in two
situations: when the query is successful, or when the error is
not G_IO_ERROR_CANCELLED. That's because the query was cancelled,
we didn't really perform it!
2023-02-28 14:18:30 -03:00
Georges Basile Stavracas Neto
158165f769 filethumbnail: Clear image on failure
Unset the image if we fail to find the appropriate icon, regardless
of the reason of the failure. Prevents the thumbnail to misrepresent
the GFileInfo it's supposed to represent.
2023-02-28 13:52:12 -03:00
Georges Basile Stavracas Neto
2d90031dab filethumbnail: Cosmetics
Remove an empty newline
2023-02-28 13:50:08 -03:00
Matthias Clasen
2a862c05a1 Merge branch 'matthiasc/for-main' into 'main'
inspector: Look for icon themes in system data dirs

See merge request GNOME/gtk!5567
2023-02-28 16:35:48 +00:00
Matthias Clasen
93b6c7863b Merge branch 'main' into 'main'
Update docs/reference/gtk/getting_started.md

See merge request GNOME/gtk!5558
2023-02-28 16:23:26 +00:00
Matthias Clasen
090f45a589 Merge branch 'wip/exalm/buildable' into 'main'
builderparser: Don't exit too early on nested custom tags

See merge request GNOME/gtk!5566
2023-02-28 16:21:19 +00:00
Alexander Mikhaylenko
ca737b1411 testsuite: Add a GtkBuildable custom tag test
Just test that it doesn't error out during parsing.
2023-02-28 17:51:38 +04:00
Matthias Clasen
b2af4006ba inspector: Look for icon themes in system data dirs
For some reason, these were not included, and they should.
2023-02-28 07:18:42 -05:00
Matthias Clasen
5d3942e5fa NEWS: Updates 2023-02-28 06:53:26 -05:00
Alexander Mikhaylenko
2bcc3cfb33 builderparser: Don't exit too early on nested custom tags
Currently nested custom tags work only as long as the element names differ
from the root one. If it's same, for example:

<condition type="any">
  <condition type="max-width">600</condition>
  <condition type="max-height">600</condition>
</condition>

then it will fail. Meanwhile the same tags wrapped into <conditions> would
work.

The problem is that custom tag parsing is considered finished as soon as we
encounter a closing tag with the same element name. So instead, track the
nesting level.
2023-02-28 14:46:14 +04:00
Matthias Clasen
a7a498e803 Merge branch 'alloc-needed-on-child-fix' into 'main'
widget: Reset alloc_needed_on_child before allocating children

See merge request GNOME/gtk!5564
2023-02-28 10:40:02 +00:00
Ivan Molodetskikh
75a417e337 widget: Reset alloc_needed_on_child before allocating children
Reset alloc_needed_on_child *before* allocating the children. This is
because some child's size_allocate() may call queue_allocate(), which
will bubble up alloc_needed_on_child. An example of this happening is
with GtkScrollable implementations, which are supposed to configure
their adjustments in size_allocate(), which will cause GtkScrollbar's
GtkRange to notice and queue_allocate() on itself.

If we reset alloc_needed_on_child after this happens, then our children
will have a lingering alloc_needed_on_child and will not receive an
allocation.

This commit fixes widgets occasionally losing an allocation when this
scenario happens.
2023-02-27 21:38:42 -08:00
Matthias Clasen
dbaaa59758 Merge branch 'fix-text-undo-disabling' into 'main'
text: Fix disabling of history

Closes #5622

See merge request GNOME/gtk!5565
2023-02-28 02:39:30 +00:00
Matthias Clasen
73ba043b02 text: Make editable API irreversible
Programmatic changes to the entry contents should
not become part of the undo history.

Sadly, the editable implementations are also used
in the code paths that we use for user-initiated changes,
so we have to be careful to only set them as
irreversible if we are not already in a user action.

Fixes: #5622
2023-02-27 19:43:11 -05:00
Matthias Clasen
61e4eadbce text: Fix disabling of history
Keep a separate boolean for enable-undo, and
disable the history if it is false, or the entry
is not using visible text, or isn't editable.

Related to: #5622
2023-02-27 19:17:08 -05:00
Matthias Clasen
0db2d0bc07 Merge branch 'expose_autocomplete' into 'main'
a11y: Expose GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE

See merge request GNOME/gtk!5563
2023-02-27 16:49:00 +00:00
Emmanuele Bassi
cd10e5dd1a Verbiage Change 2023-02-27 16:32:35 +00:00
Lukáš Tyrychtr
c57d6c5575 a11y: Expose GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE
Previously, it was not exposed at all, now it at least somewhat is.
2023-02-27 15:27:07 +01:00
Emmanuele Bassi
73057b267e Merge branch 'expose_has_popup' into 'main'
a11y: Expose GTK_ACCESSIBLE_PROPERTY_HAS_POPUP

See merge request GNOME/gtk!5562
2023-02-27 14:20:44 +00:00
Lukáš Tyrychtr
9d4bb77263 a11y: Expose GTK_ACCESSIBLE_PROPERTY_HAS_POPUP
This property was not exposed before, not it is.
2023-02-27 14:10:11 +01:00
Emmanuele Bassi
0d6cee9763 Merge branch 'expose_multi_selectable' into 'main'
a11y: Expose GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE to at-spi2

See merge request GNOME/gtk!5561
2023-02-27 12:41:11 +00:00
Lukáš Tyrychtr
b33bfe26fe a11y: Expose GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE to at-spi2
Previously, this property was not exposed to the a11y backend, now, it is.
2023-02-27 13:24:56 +01:00
Emmanuele Bassi
0cacaa08f5 Merge branch 'expose_required' into 'main'
a11y: Expose GTK_ACCESSIBLE_PROPERTY_REQUIRED to at-spi2

See merge request GNOME/gtk!5560
2023-02-27 11:30:59 +00:00
Lukáš Tyrychtr
cbf4a546b4 a11y: Expose GTK_ACCESSIBLE_PROPERTY_REQUIRED to at-spi2
Up until now, this property was silently not exposed to assistive technologies.
2023-02-27 12:17:58 +01:00
Emmanuele Bassi
03732c1d48 Merge branch 'fix_invalid_role_mapping' into 'main'
a11y: Map GTK_ACCESSIBLE_STATE_INVALID to ATSPI_STATE_INVALID_ENTRY

See merge request GNOME/gtk!5559
2023-02-27 11:02:40 +00:00
Lukáš Tyrychtr
568cf21486 a11y: Map GTK_ACCESSIBLE_STATE_INVALID to ATSPI_STATE_INVALID_ENTRY
Previously, it was mapped to ATSPI_STATE_INVALID. However, that state
is used for some internal errors, and not user errors, so use the correct
one for that purpose.
2023-02-27 11:40:46 +01:00
Bobby Neal
f11d647aa4 Update docs/reference/gtk/getting_started.md 2023-02-26 17:04:17 +00:00
Hugo Carvalho
49feaf465d Update Portuguese translation 2023-02-26 16:20:29 +00:00
Matthias Clasen
9b0afd8bff Merge branch 'pickers-demo-dnd' into 'main'
gtk4-demo: Accept file dnd in the pickers demo

See merge request GNOME/gtk!5556
2023-02-26 13:44:30 +00:00
Matthias Clasen
495ca72232 gtk4-demo: Accept file dnd in the pickers demo
Easy to add and expected of a file picker.
2023-02-26 08:28:38 -05:00
Alexander Shopov
e6f4464a3d Update Bulgarian translation 2023-02-26 08:48:06 +00:00
Anders Jonsson
cb0e4ee2be Update Swedish translation 2023-02-25 21:57:36 +00:00
Matthias Clasen
6f7b6ad61a Merge branch 'ebassi/button-no-check' into 'main'
Remove unused code in GtkButton

See merge request GNOME/gtk!5553
2023-02-25 13:41:52 +00:00
Emmanuele Bassi
1e599c9141 Remove unused code in GtkButton
GtkButton still has some code checking if the instance passed to
gtk_button_set_label() is a GtkCheckButton; GtkCheckButton is not a
GtkButton any more.
2023-02-24 14:38:39 +00:00
Yosef Or Boczko
4cf42eb19c Update Hebrew translation 2023-02-24 09:57:37 +00:00
Matthias Clasen
b0fc2f99ba Merge branch 'mcatanzaro/#5619' into 'main'
filesystemmodel: fix crash when file is removed

Closes #5619

See merge request GNOME/gtk!5550
2023-02-23 16:24:06 +00:00
Emmanuele Bassi
2b4dd182c1 Merge branch 'add_toggle_button_role' into 'main'
a11y: Introduce a dedicated role for toggle buttons

See merge request GNOME/gtk!5549
2023-02-23 15:22:16 +00:00
Michael Catanzaro
c141d0a70a filesystemmodel: fix crash when file is removed
In 32247bc50e node_get_for_file() was
changed to return GTK_INVALID_LIST_POSITION rather than 0 when the file
is untracked. Most call sites were updated accordingly, but this one was
missed.

Fixes #5619
2023-02-23 09:20:03 -06:00
Lukáš Tyrychtr
6fa8033c7c Use the correct role for GtkToggleButton 2023-02-23 15:02:29 +01:00
Lukáš Tyrychtr
de80f503e4 a11y: Introduce a dedicated role for toggle buttons
Up until now, toggle buttons were presented as regular push buttons.
That's the approach used by the ARIA specification, however, our platform
accessibility backend, at-spi2, can not represent accessibe states with values,
so we can not represent the design pattern precisely enough for screen readers.
If, in future, the a11y backends gain this capability, we might consider again
removing this role.
2023-02-23 14:22:20 +01:00
Matthias Clasen
41b67c4722 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Fix the shortcuts-window demo

See merge request GNOME/gtk!5548
2023-02-23 01:03:41 +00:00
Matthias Clasen
1eae87621d gtk-demo: Fix the shortcuts-window demo
Presenting the shortcutswindow got lost
in fb8e52f0c9. Oops.
2023-02-22 14:57:47 -05:00
Fran Dieguez
5f502601c8 Update Galician translation 2023-02-22 17:23:21 +00:00
Sabri Ünal
04d23c5cb9 Update Turkish translation 2023-02-22 11:41:36 +00:00
Philipp Kiemle
d9b6f814ad Update German translation 2023-02-22 10:34:50 +00:00
Matthias Clasen
871c46591a Merge branch 'improve_gtknotebook_a11y' into 'main'
GtkNotebook: Improve the labels of notebook pages for a11y

See merge request GNOME/gtk!5546
2023-02-21 16:48:28 +00:00
Lukáš Tyrychtr
d906b456a8 GtkNotebook: Improve the labels of notebook pages for a11y 2023-02-21 15:29:00 +01:00
Michael J. Baars
32bc7ce987 removed duplicate function call 2023-02-21 13:28:15 +01:00
Daniel
cad5771a66 Updated Spanish translation 2023-02-21 12:07:49 +01:00
Emmanuele Bassi
378f1421f0 Merge branch 'main' into 'main'
button: Remove nullable annotation for new_from_icon_name()

Closes #5606

See merge request GNOME/gtk!5544
2023-02-20 21:30:05 +00:00
Philipp Hörist
a209a73c69 button: Remove nullable annotation for new_from_icon_name()
This makes it more consistent with set_icon_name() which
does also not accept NULL.

Fixes #5606
2023-02-20 20:33:42 +01:00
Matthias Clasen
624458df9d Merge branch 'builder-tool-child-properties' into 'main'
gtk4-builder-tool: Prefer child properties

Closes #5609

See merge request GNOME/gtk!5543
2023-02-20 13:12:27 +00:00
Matthias Clasen
fbfbaa484d Merge branch 'matthiasc/for-main' into 'main'
filechooser: Fix paned limits

See merge request GNOME/gtk!5542
2023-02-20 13:04:33 +00:00
Matthias Clasen
3de10847b9 gtk4-builder-tool: Prefer child properties
Rewrite <child> elements to use child properties
where that is easily possible.

Fixes: #5609
2023-02-19 21:48:56 -05:00
Kukuh Syafaat
8be601da4f Update Indonesian translation 2023-02-20 01:20:48 +00:00
Matthias Clasen
07b9a6fb75 filechooser: Fix paned limits
The intention of the ui file was to not let
the paned shrink both children down to nothing,
but using <child> for the children effectively
overrides the setting of the shrink properties.
Fix that by using child properties instead of
<child>.
2023-02-19 19:12:30 -05:00
Matthias Clasen
5105d607de Merge branch 'builder-tool-template-parent' into 'main'
builder-tool: Try harder to find template parents

Closes #5232

See merge request GNOME/gtk!5541
2023-02-20 00:05:06 +00:00
Matthias Clasen
a9f03be588 builder-tool: Try harder to find template parents
This will make it work (in some cases) to add extra
libraries via LD_PRELOAD.

Based on work by Julian Sparber,
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/5084

Fixes: #5232
2023-02-19 18:17:34 -05:00
Asier Sarasua Garmendia
d67bdb96ad Update Basque translation 2023-02-19 20:44:24 +00:00
Yuri Chornoivan
c8f4535ed2 Update Ukrainian translation 2023-02-19 20:23:35 +00:00
Aurimas Černius
21cbf98942 Update Lithuanian translation 2023-02-19 19:06:03 +00:00
Emmanuele Bassi
300540f6b8 Merge branch 'texturescalenode-type-annotations' into 'main'
Fix self-`(type)` annotations for `TextureScaleNode` methods

See merge request GNOME/gtk!5539
2023-02-19 17:18:01 +00:00
Sebastian Dröge
323ba14dde Fix self-(type) annotations for TextureScaleNode methods 2023-02-19 19:00:34 +02:00
Matthias Clasen
aaee1ee5bd Merge branch 'fix_custom_accessible_hierarchy' into 'main'
Allow setting accessible parent and next sibling

See merge request GNOME/gtk!5517
2023-02-19 16:15:49 +00:00
Matthias Clasen
70a711882c Fix the build 2023-02-19 15:26:27 +00:00
Matthias Clasen
5717b95cad Miscellaneous formatting and documentation fixes 2023-02-19 15:09:25 +00:00
Matthias Clasen
1b0f324be5 Merge branch 'missing-since-markers' into 'main'
Add two missing `Since` markers

See merge request GNOME/gtk!5537
2023-02-19 14:56:51 +00:00
Sebastian Dröge
ca93512106 Add two missing Since markers 2023-02-19 11:18:15 +02:00
Ekaterine Papava
fbd4f06ee2 Update Georgian translation 2023-02-19 05:48:04 +00:00
Benjamin Otte
d553f6941d Merge branch 'wip/otte/for-main' into 'main'
listview: Measure children only, not self

See merge request GNOME/gtk!5535
2023-02-19 05:33:59 +00:00
Matthias Clasen
2173b7ccaa Merge branch 'matthiasc/for-main' into 'main'
Drop some unnecessary includes

See merge request GNOME/gtk!5536
2023-02-19 05:01:53 +00:00
Matthias Clasen
ca6642deed Drop some unnecessary includes 2023-02-18 23:42:04 -05:00
Benjamin Otte
be6a4722c0 listview: Measure children only, not self
The previous code would include CSS padding/margin/border in the
measurement and that is wrong.

Until commit a96c75ff02 this was not actually visible, but afterwards
listitems were allocated 16px too wide.

Test included
2023-02-19 05:41:29 +01:00
Matthias Clasen
3b3b63062d Revert "Merge branch 'inscription-single-line' into 'main'"
This reverts commit 7ec90abf24, reversing
changes made to ec49a912aa.

We did not have agreement on this after all.
2023-02-18 19:04:00 -05:00
Matthias Clasen
7ec90abf24 Merge branch 'inscription-single-line' into 'main'
inscription: Add single-line-mode property

Closes #5444

See merge request GNOME/gtk!5504
2023-02-18 23:34:17 +00:00
Matthias Clasen
ec49a912aa Merge branch 'wip/carlosg/dnd-x11-keys' into 'main'
gdk/x11: Also grab keyboard during XDnD grabs

Closes #5604

See merge request GNOME/gtk!5533
2023-02-18 22:20:30 +00:00
Carlos Garnacho
ae94417f80 gdk/x11: Also grab keyboard during XDnD grabs
The drag source must handle events and messaging, this also
includes keyboard handling for accessibility and cancellation.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5604
2023-02-18 23:02:22 +01:00
Matthias Clasen
24a6803958 Merge branch 'matthiasc/for-main' into 'main'
gtksearchentry: Apply header capitalization to the "Clear entry" tooltip

See merge request GNOME/gtk!5532
2023-02-18 21:10:16 +00:00
Automeris naranja
4073371416 gtksearchentry: Apply header capitalization to the "Clear entry" tooltip
HIG advises to use header capitalization in tooltip texts.

https://developer.gnome.org/hig/patterns/feedback/tooltips.html
2023-02-18 15:53:54 -05:00
Matthias Clasen
e5a391c0b9 Merge branch 'matthiasc/for-main' into 'main'
securememory: use function checks

Closes #5070

See merge request GNOME/gtk!5531
2023-02-18 17:21:15 +00:00
Matthias Clasen
6cb612ac15 gtk-demo: Fix build without sincos
We are getting into trouble here if
sincos isn't detected but still present
in headers. Avoid that.

Also fix the other copy of gtkgears.c.
2023-02-18 10:41:02 -05:00
Matthias Clasen
9f64202a60 meson: Consolidate function checks
Put all the function checks in one place.
Remove functions we don't actually use,
and add ones that we have #ifdefs for in
in the code. Also add enough includes to
make these checks actually work.

Fixes: #5070
2023-02-18 09:37:36 -05:00
Matthias Clasen
19c362f638 securememory: use function checks
Checking for getpagesize in meson.build is
useless if we don't check the resulting define
in the code. So do that.
2023-02-18 09:34:50 -05:00
Matthias Clasen
e51fa8b65b Merge branch 'matthiasc/for-main' into 'main'
printing: Avoid getrandom

See merge request GNOME/gtk!5530
2023-02-17 22:39:04 +00:00
Matthias Clasen
06d3bbafaf printing: Avoid getrandom
GLib has perfectly serviceable random number
apis, and this breaks the macOs build.
2023-02-17 17:20:44 -05:00
Matthias Clasen
da8a1f4683 Merge branch 'scalebutton-active-since-marker' into 'main'
Add missing `Since` marker to `GtkScaleButton:active`

See merge request GNOME/gtk!5529
2023-02-17 19:54:03 +00:00
Sebastian Dröge
ad7d9bc409 Add missing Since marker to GtkScaleButton:active 2023-02-17 19:41:55 +02:00
Emmanuele Bassi
94cde8d702 Merge branch 'ebassi/ci-update-v41' into 'main'
ci: Update image

See merge request GNOME/gtk!5528
2023-02-17 12:55:50 +00:00
Emmanuele Bassi
ec7b1f7208 ci: Add no-cache option to run-docker.sh script
Use `run-docker.sh build --no-cache` to discard the cached layers if you
need to rebuild the image without modifying the Dockerfile.
2023-02-17 12:24:09 +00:00
Emmanuele Bassi
864fbf89cd ci: Update image
Refresh the Fedora base (still at 37), and add the Python packaging
module for gi-docgen.
2023-02-17 12:24:09 +00:00
Emmanuele Bassi
b8e928d703 Merge branch 'matthiasc/for-main' into 'main'
mask: Fix glsl

See merge request GNOME/gtk!5527
2023-02-17 12:23:36 +00:00
Matthias Clasen
0b4d41698b mask: Fix glsl 2023-02-17 06:26:42 -05:00
Matthias Clasen
a9eca60b84 Merge branch 'wip/fix-mask-modes-regression' into 'main'
wayland/glcontext: Don't call wl_surface.offset on old objects

See merge request GNOME/gtk!5526
2023-02-17 11:25:06 +00:00
Jonas Ådahl
53c3f497f1 wayland: Clean up some dead code 2023-02-17 12:03:58 +01:00
Jonas Ådahl
3183a21347 wayland/glcontext: Don't call wl_surface.offset on old objects
The availability of wl_surface.offset depends on the compositor, so we
can't call it unconditionally. Add a version check to so we only call
offset if we know we won't raise a protocol error.

Fixes: 0eb791eaaa ("Make mask nodes more versatile")
2023-02-17 12:03:27 +01:00
Matthias Clasen
07f090f947 Merge branch 'test-invisible-text' into 'main'
Add a test for invisible text navigation

See merge request GNOME/gtk!5525
2023-02-17 03:01:42 +00:00
Matthias Clasen
ad111087cc Add a test for invisible text navigation
This shows that (at least some) things
work as expected.

See: #1811
2023-02-16 14:27:44 -05:00
Jürgen Benvenuti
5092581be8 Update German translation 2023-02-16 17:18:16 +00:00
Matthias Clasen
b261f7f533 Merge branch 'nielsdg/set-action-enabled-doc-ref' into 'main'
widget: mention action_set_enabled in install_action

See merge request GNOME/gtk!5524
2023-02-16 11:24:15 +00:00
Niels De Graef
779f9e5071 widget: mention action_set_enabled in install_action
When looking at `gtk_widget_class_install_action()`, it isn't
immediately obvious how actions can be enabled or disabled. Add a
reference to the `gtk_widget_action_set_enabled()` method so people have
a quick link to that.
2023-02-16 08:47:06 +01:00
Matthias Clasen
b07d9d1912 Merge branch 'alatiera/flatpak-ci' into 'main'
ci: Build and publish aarch64 flatpaks

Closes #5594

See merge request GNOME/gtk!5523
2023-02-15 19:54:32 +00:00
Jordan Petridis
7b4692bcb0 ci: Add a simple auto-retry policy 2023-02-15 21:38:24 +02:00
Jordan Petridis
f0a2b6f165 ci: Build and publish aarch64 flatpaks
Close GNOME/gtk#5594
2023-02-15 21:19:56 +02:00
Jordan Petridis
2dc6efd9ce ci: Switch from only/except to rules: keyword
It's more flexible and allows us to combine the flatpak jobs
2023-02-15 21:10:40 +02:00
Emmanuele Bassi
1f4adb60bb Merge branch 'fix-annotations' into 'main'
Fix a couple incorrect annotations for optional parameters

See merge request GNOME/gtk!5503
2023-02-15 16:27:11 +00:00
Lukáš Tyrychtr
f507dd4962 Allow updating the next accessible sibling for a GtkAccessible 2023-02-15 12:29:16 +01:00
Matthias Clasen
1bdb368e8b Merge branch 'more-mask-modes' into 'main'
rendernodeparser: Fix mask mode handling

See merge request GNOME/gtk!5522
2023-02-15 03:54:01 +00:00
Matthias Clasen
aec4bfcf3b gsk: Add a node parser test for mask modes 2023-02-14 21:47:54 -05:00
Matthias Clasen
7e18c2849b gsk: Add a render test for mask modes 2023-02-14 21:47:54 -05:00
Matthias Clasen
351abadee7 Make make not fallback match GL
We were not handling the inverted-luminance
case the same way, and it caused a test to
fail. Yay for tests.
2023-02-14 21:47:54 -05:00
Matthias Clasen
951db28f71 rendernodeparser: Fix mask mode handling
I had forgotten inverted-luminance, and also
to print an error.
2023-02-14 21:01:12 -05:00
Benjamin Otte
40e7a265a7 rendernodeparser: Print an error when failing to parse an enum 2023-02-14 21:01:12 -05:00
Matthias Clasen
9a539cec57 Merge branch 'mask-modes' into 'main'
Make mask nodes more versatile

See merge request GNOME/gtk!5521
2023-02-15 00:57:17 +00:00
Matthias Clasen
724cf6bd70 Merge branch 'wip/cdavis/menubutton-active' into 'main'
menubutton: Add `active` property and getter/setter

See merge request GNOME/gtk!5506
2023-02-15 00:44:17 +00:00
Matthias Clasen
5e4b43dcce Merge branch 'wip/otte/downloader' into 'main'
Add GdkTextureDownloader

See merge request GNOME/gtk!5515
2023-02-15 00:41:26 +00:00
Matthias Clasen
fa43282695 Merge branch 'wip/otte/disable-style-check' into 'main'
CI: Don't run style-check-diff by default

See merge request GNOME/gtk!5520
2023-02-15 00:36:53 +00:00
Benjamin Otte
662c251cd0 demo: Spice up the mask demo
Also use all the mask modes, weeeee!
2023-02-14 19:07:01 -05:00
Matthias Clasen
0d97d03fc1 Document mask node parser format 2023-02-14 19:07:01 -05:00
Matthias Clasen
cb0aaf0b2c Add more mask node tests 2023-02-14 19:07:01 -05:00
Matthias Clasen
0eb791eaaa Make mask nodes more versatile
Add a GskMaskMode enumeration and implement it
in the GL and cairo renderers.
2023-02-14 19:07:01 -05:00
Benjamin Otte
073c836f96 CI: Don't run style-check-diff by default
We don't use it most of the time and it's also confusing to new contributors who think it's important to fix it.

Keep it for manual runs, so that interested people can just click a button to see the results. It also makes it easy to turn back on later.
2023-02-14 23:53:02 +00:00
Matthias Clasen
0a0a03d913 Merge branch 'fix_4258' into 'main'
Don't tell the screen reader that a button is related to an image which has no useful label

Closes #4258

See merge request GNOME/gtk!4665
2023-02-14 23:50:18 +00:00
Lukáš Tyrychtr
d43724f5fc Don't tell the screen reader that a button is related to an image which has no useful label 2023-02-14 23:50:18 +00:00
Matthias Clasen
abf3cdb187 Merge branch 'cpdb' into 'main'
Update dependencies for CPDB print backend

Closes #5589

See merge request GNOME/gtk!5518
2023-02-14 23:48:43 +00:00
Benjamin Otte
cca5de3c7f memorytexture: Export less private API
It's not needed anymore with GdkTextureDownloader now.
2023-02-15 00:39:18 +01:00
Benjamin Otte
774696011d glrenderer: Use GdkTexureDownloader 2023-02-15 00:39:18 +01:00
Benjamin Otte
c9f54ca371 texture: Export gdk_texture_get_format()
The API docs outline why quite well.

This should make it possible to do saving of textures to image files
without any private API with the same featureset that GTK uses.

Also remove the gsktextureprivate.h include where
gdk_texture_get_format() was the only reason for it.
2023-02-15 00:39:18 +01:00
Benjamin Otte
ce0123ea58 docs: Link from gdk_texture_download() to GdkTextureDownloader 2023-02-15 00:39:18 +01:00
Benjamin Otte
b30af72125 tiff: Use GdkTexureDownloader when saving 2023-02-15 00:39:18 +01:00
Benjamin Otte
eb45b8083a png: Use GdkTexureDownloader when saving 2023-02-15 00:39:18 +01:00
Benjamin Otte
f05d801e28 jpeg: Use GdkTexureDownloader when saving 2023-02-15 00:39:18 +01:00
Benjamin Otte
4afec951c7 pixbuf: Use GdkTextureDownloader when downloading pixbufs 2023-02-15 00:39:18 +01:00
Benjamin Otte
51ed1442a2 gdk: Add GdkTextureDownloader
It's the new object that allows more control about accessing texture
data.
2023-02-15 00:39:18 +01:00
Benjamin Otte
01ff6c1c22 memorytexture: Use right size for GBytes
The GBytes were created with the wrong size.

Nobody seems to have looked at it.
2023-02-14 23:42:17 +01:00
Fran Dieguez
73f3ea9511 Update Galician translation 2023-02-14 20:04:07 +00:00
Emmanuele Bassi
f1311dc053 Merge branch 'gsk-render-node-type-abi-breakage' into 'main'
gsk: Move new 4.10 `GskRenderNodeType`s to the end instead of inserting them in the middle

See merge request GNOME/gtk!5519
2023-02-14 19:28:36 +00:00
Sebastian Dröge
a252aadadf gsk: Move new 4.10 GskRenderNodeTypes to the end instead of inserting them in the middle 2023-02-14 21:04:41 +02:00
tinytrebuchet
300670dad4 Update dependencies for CPDB print backend
Require cpdb-frontend 2.x for building CPDB print backend.
2023-02-14 23:39:13 +05:30
Matthias Clasen
44c95d3c96 Merge branch 'kjellahl/clang' into 'main'
gskglrenderjob: Fix compilation with clang

See merge request GNOME/gtk!5516
2023-02-14 14:18:29 +00:00
Lukáš Tyrychtr
d566771262 Preserve the correct a11y tree in GtkStack
Now, when we can, ensure that the GtkStackPage is the parent of its widget.
2023-02-14 14:44:20 +01:00
Lukáš Tyrychtr
5f72b51105 Allow setting accessible parent and sibling explicitly
This allows to maintain the correct a11y hierarchy even when it contains
objects which are only GtkAccessibles.
2023-02-14 14:43:57 +01:00
Hugo Carvalho
e0afd22c84 Update Portuguese translation 2023-02-14 11:39:50 +00:00
Kjell Ahlstedt
869ab1cd1b gskglrenderjob: Fix compilation with clang 2023-02-14 10:29:25 +01:00
Matthias Clasen
730593fab5 Merge branch 'texttag_textview_documentation' into 'main'
Update TextTag and TextView indent Documentation

See merge request GNOME/gtk!5507
2023-02-14 00:08:39 +00:00
Matthias Clasen
d0798c9526 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Fix hotspot handling in dnd

See merge request GNOME/gtk!5513
2023-02-14 00:03:55 +00:00
Matthias Clasen
e6dfb8732a gtk-demo: Fix hotspot handling in dnd
We were not remembering the pointer coordinates.
2023-02-13 18:39:45 -05:00
Aurimas Černius
453ef8c7e1 Update Lithuanian translation 2023-02-13 21:07:37 +00:00
Sabri Ünal
819595d1a9 Update Turkish translation 2023-02-13 18:08:05 +00:00
Andre Klapper
306276b689 Fix invalid markup in Belarusian UI translation 2023-02-13 18:32:03 +01:00
Emmanuele Bassi
bb15a7ef46 Merge branch 'faq-updates' into 'main'
faq: Some updates

See merge request GNOME/gtk!5512
2023-02-13 14:50:35 +00:00
Matthias Clasen
cd0fe13dae faq: Add a question about parallel UIs 2023-02-13 08:54:36 -05:00
Matthias Clasen
3dcea74e85 faq: Don't number questions
The numbering makes it unnecessarily hard to add
and remove questions, and does not really seem
necessary. Just use bullets.
2023-02-13 08:52:04 -05:00
Matthias Clasen
537c2f6c7a faq: Some updates
Miscellaneous tweaks and changes, after reading
the whole thing.
2023-02-13 08:52:03 -05:00
Matthias Clasen
72379f64e9 Merge branch 'fix-font-chooser-filter' into 'main'
Fix an assertion in GtkFontChooserWidget when setting a filter.

See merge request GNOME/gtk!5511
2023-02-13 12:41:48 +00:00
Akira TAGOH
4532c3020b Fix an assertion in GtkFontChooserWidget when setting a filter. 2023-02-13 12:49:02 +09:00
Kukuh Syafaat
b60bd8a73d Update Indonesian translation 2023-02-13 02:47:33 +00:00
Matthias Clasen
37f12e4bf9 Post-release version bump 2023-02-12 21:04:15 -05:00
Matthias Clasen
8967b2da01 4.9.4 2023-02-12 20:36:13 -05:00
Matthias Clasen
dfb019509d docs: Document new build options 2023-02-12 20:36:13 -05:00
Matthias Clasen
a770b429ec Merge branch 'fix-gst-gl-use' into 'main'
gstreamer: Fix gl context use

Closes #5586

See merge request GNOME/gtk!5508
2023-02-13 00:41:51 +00:00
Matthias Clasen
7430bd7780 gstreamer: Fix gl context use
We were not activating the context in which
we want to wait for the fence. This caused
a stream of critical warnings.

Fixes: #5586
2023-02-12 19:29:04 -05:00
Jacob Mealey
272a40a01a Update TextTag and TextView indent Documentation
Change the documentation for both to be in line with Pango documentation
specifically regarding hanging indentation.
2023-02-12 23:12:51 +00:00
Matthias Clasen
f121f607ae Merge branch 'search_entry_placeholder' into 'main'
gtksearchentry: Add getter/setter for placeholder text

See merge request GNOME/gtk!4312
2023-02-12 22:06:36 +00:00
Christopher Davis
ff45145eac menubutton: Add active property and getter/setter
GtkMenuButton currently does not provide a way to tell
if it's open programmatically. The existing methods,
`popup()` and `popdown()`, do not expose any state
to callers. If someone wanted to know whether or not
a menubutton was open, they needed the popover. Given
that GtkMenuButton can manage the popovers itself,
that's not always an option for app developers.

This commit adds the `active` property and associated
methods, where `gtk_menu_button_set_active ()` replaces
both `gtk_menu_popup ()` and `gtk_menu_popdown ()`.
This addition also mirrors changes in other places,
Such as `GtkWidget:visible` vs `show()`/`hide()`.
2023-02-12 16:47:59 -05:00
Matthias Clasen
83c5f5ff0f Apply 4 suggestion(s) to 2 file(s) 2023-02-13 06:47:06 +09:00
Alexandros Theodotou
87d21dc5c9 gtksearchentry: Add getter/setter for placeholder text 2023-02-13 06:46:31 +09:00
Matthias Clasen
cef7e6b741 Merge branch 'mark-deprecations' into 'main'
docs: Mark various deprecations

See merge request GNOME/gtk!5502
2023-02-12 21:44:00 +00:00
Yuri Chornoivan
84b5e94ffd Update Ukrainian translation 2023-02-12 17:56:09 +00:00
Matthias Clasen
679d510059 Merge branch 'template-child-dispose-order' into 'main'
gtk: Set widget template children to NULL before destroy unref

See merge request GNOME/gtk!4611
2023-02-12 16:36:52 +00:00
Marco Melorio
d2755e0385 inscription: Add single-line-mode property
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5444.
2023-02-12 17:35:56 +01:00
Matthias Clasen
0c2b437643 Merge branch 'main' into 'main'
Add note about widgets implementing the interface adding the `horizontal`/`vertical` CSS classes

See merge request GNOME/gtk!5391
2023-02-12 16:28:12 +00:00
madmurphy
0764cf0c9c Add note about widgets implementing the interface adding the horizontal/vertical CSS classes 2023-02-12 16:28:12 +00:00
Marco Melorio
2504215459 docs: Mark everything in GtkVolumeButton as deprecated 2023-02-12 17:20:11 +01:00
Marco Melorio
d45db3a961 docs: Mark everything in GtkStatusBar as deprecated 2023-02-12 17:20:11 +01:00
Matthias Clasen
557a1ed879 Merge branch 'no-more-lpr' into 'main'
printing: Drop the lpr backend

See merge request GNOME/gtk!5500
2023-02-12 15:29:27 +00:00
Matthias Clasen
c28b6a3ee6 Merge branch 'texture-atlas-crash' into 'main'
gl: Avoid a crash in the texture library

Closes #5175

See merge request GNOME/gtk!5501
2023-02-12 15:28:06 +00:00
Marco Melorio
b34c139028 docs: Mark everything in GtkLockButton as deprecated 2023-02-12 16:12:17 +01:00
Matthias Clasen
dd22e2aea9 printing: Drop the lpr backend
We want to consolidate and get to fewer print
backends (ideally only one), and the future is cpdb.
2023-02-12 10:10:06 -05:00
Marco Melorio
6e6f2f652c docs: Mark everything in GtkCellAreaContext as deprecated 2023-02-12 16:09:39 +01:00
Marco Melorio
3aac70f245 docs: Mark everything in GtkAssistant as deprecated 2023-02-12 16:09:25 +01:00
Matthias Clasen
7f3ea15d80 Update POTFILES.in 2023-02-12 10:09:22 -05:00
Matthias Clasen
d3dfdd214f gl: Avoid a crash in the texture library
entry->texture can be NULL, so check before
using it.

Fixes: #5175
2023-02-12 10:01:11 -05:00
Matthias Clasen
b6c3cf4eee gl: Maintain state when truncating
When we truncate the command queue because it
is too big, we were messing up our state accounting
and running into criticals as a consequence.

This can be reproduced by opening a well-populated
fishbowl demo in the inspectors recorder.

Fixes: #5188
2023-02-12 09:56:32 -05:00
Matthias Clasen
157ef1d395 Deprecate GtkVolumeButton
Too specialized.
2023-02-12 09:48:49 -05:00
Matthias Clasen
d0263f563a NEWS: Updates 2023-02-12 09:21:38 -05:00
Matthias Clasen
83b48bb25f Merge branch 'mask-nodes-rebased' into 'main'
gsk: Introduce mask nodes

See merge request GNOME/gtk!5497
2023-02-12 14:11:47 +00:00
Matthias Clasen
81e9eca256 Merge branch 'nacho/scalebutton-active' into 'main'
gtkscalebutton: add active property

See merge request GNOME/gtk!5492
2023-02-12 14:01:27 +00:00
Ignacio Casal Quinteiro
44c2d585b8 gtkscalebutton: add active property 2023-02-12 14:01:26 +00:00
Matthias Clasen
348803af7d Add a mask node demo 2023-02-12 08:35:25 -05:00
Matthias Clasen
c8bfea7aa1 Add a test for mask nodes 2023-02-12 08:35:25 -05:00
Matthias Clasen
8f47e885f0 Add gtk_snapshot_push_mask 2023-02-12 08:35:25 -05:00
Matthias Clasen
a9f50f1f7a gl: Support mask nodes
Add a shader for masking.
2023-02-12 08:35:25 -05:00
Matthias Clasen
0d58e5365d gsk: Introduce mask nodes
Add GskMaskNode, and support it in the render node
parser, in the inspector and in GtkSnapshot.

The rendering is just fallback for now.

Based on old work by Timm Bäder.
2023-02-12 08:35:25 -05:00
Ekaterine Papava
d00d4c4475 Update Georgian translation 2023-02-12 12:30:05 +00:00
Piotr Drąg
a6e7c38236 Update POTFILES.in 2023-02-12 13:20:48 +01:00
Matthias Clasen
eee7e59265 Merge branch 'fix_editable_label' into 'main'
Remove timeout when disposing GtkEditableLabel

Closes #5584

See merge request GNOME/gtk!5499
2023-02-12 02:55:45 +00:00
Matthias Clasen
c2cb1ffe9e Merge branch 'wip/wl-dispatch-helper' into 'main'
wayland: Add event queue dispatch helper

See merge request GNOME/gtk!5498
2023-02-12 01:01:29 +00:00
Alexandros Theodotou
d918a77d34 Remove timeout when disposing GtkEditableLabel
Fixes: #5584
2023-02-12 09:45:07 +09:00
Matthias Clasen
2285ef3824 Merge branch 'scaled-textures' into 'main'
Scaled textures

See merge request GNOME/gtk!5488
2023-02-11 22:16:43 +00:00
Jonas Ådahl
b2a2bf819d wayland/launch-context: Use dispatch helper
Otherwise we risk a busy loop if e.g. the pipe broke.
2023-02-11 23:14:53 +01:00
Jonas Ådahl
dd9433b50e wayland: Add event queue dispatch helper
Dispatch failing should always fatal; use a helper to centralize the
error handling everywhere.
2023-02-11 23:13:39 +01:00
Matthias Clasen
67c53e46f9 Add gtk_snapshot_append_scaled_texture
This is the snapshot api corresponding to
gsk_texture_scale_node_new.
2023-02-11 15:09:38 -05:00
Matthias Clasen
238e7ec351 Add a test for scaled textures 2023-02-11 15:09:38 -05:00
Matthias Clasen
d916659781 gl: Handle GskTextureScaleNodes 2023-02-11 15:09:38 -05:00
Matthias Clasen
82c02574f1 gl: Make texture slicing more flexible
Allow to specify the filtering to use for the slices,
and allow forcing the number of slices. This will be
used in the next commit.
2023-02-11 15:09:38 -05:00
Matthias Clasen
26e6d2106b gl: Pass filters down from visit_texture_node
For now, we always pass GL_LINEAR.
2023-02-11 15:09:38 -05:00
Matthias Clasen
625ffa2d96 gtk-demo: Add filtering to the zoom demo 2023-02-11 15:09:38 -05:00
Matthias Clasen
dd3eedd510 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-11 15:09:38 -05:00
Matthias Clasen
dc3a72cf38 nodeparser: Support texture-scale nodes 2023-02-11 15:09:38 -05:00
Matthias Clasen
b937c19dd4 gsk: Introduce GskTextureScaleNode 2023-02-11 15:09:38 -05:00
Matthias Clasen
04c3af537c Merge branch 'wip/handle-more-wl-dispatch-failures' into 'main'
wayland: Handle dispatch failing in a couple of more places

See merge request GNOME/gtk!5495
2023-02-11 19:56:45 +00:00
Matthias Clasen
cc43f5dcde gsk: Generate mipmaps when requested
If the min_filter requires it, call
glGenerateMipmap for our textures.
2023-02-11 09:29:03 -05:00
Matthias Clasen
c74d7afce5 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-11 09:29:03 -05:00
Matthias Clasen
52e18eb7fb Merge branch 'matthiasc/for-main' into 'main'
gdkevents.c: Fix up folding

See merge request GNOME/gtk!5496
2023-02-11 14:18:42 +00:00
Matthias Clasen
c0b5b4b8c1 gskrendernodeimpl.c: Use folding
Instead of homegrown markup.
2023-02-11 09:00:07 -05:00
Matthias Clasen
d497e721c9 gdkevents.c: Fix up folding
The modeline was lost at some point,
and superfluous spacing inserted.
2023-02-11 08:59:51 -05:00
Jonas Ådahl
a7fb9a6865 wayland: Handle dispatch failing in a couple of more places
Without doing this, we'll end up with risking GTK processes sitting
eating 100% CPU instead of just exit(1):ing.
2023-02-11 11:42:21 +01:00
Marek Kašík
2365d9be18 Merge branch 'cpdb' into 'main'
New CPDB print backend for GTK Print Dialog

See merge request GNOME/gtk!4930
2023-02-10 23:10:20 +00:00
tinytrebuchet
41b60bbd6c New CPDB print backend for GTK Print Dialog
The Common Print Dialog Backends (CPDB) concept has GUI-toolkit-independent
backends for each print technology (CUPS, Print to File, cloud printing
services, ...) and each print dialog (GTK, Qt, Chromium, ...) is supposed
to use this backend, so that changes in print technologies can be centrally
and quickly covered by changing the backends and everything new gets available
in all print dialogs.

This commit provides a GTK print dialog backend to add support for the CPDB
concept. It communicates with all installed CPDB backends and so gives support
for all these print technologies to the GTK print dialog.

To make use of CPDB the GTK print dialog is supposed to be installed with this
backend and the 'Print To File' backend, and not any others to prevent printer
duplication.
2023-02-11 01:13:48 +05:30
Emin Tufan Çetin
f0d3d011ea Update Turkish translation 2023-02-10 05:57:42 +00:00
Cameron White
0cb3555a65 Fix a couple incorrect annotations for optional parameters
The 'optional' annotation should be used in these cases rather than 'nullable'.
NULL can provided to ignore these output parameters, but the function is
not setting the output parameter to NULL.
2023-02-09 22:46:43 -05:00
Matthias Clasen
48e141a42c Merge branch 'avoid-criticals-tracker' into 'main'
searchengine: Avoid criticals when tracker init failed

See merge request GNOME/gtk!5489
2023-02-09 19:43:31 +00:00
Gaël Bonithon
6215b38e64 searchengine: Emit a simple warning when tracker init failed
Failure is allowed by nature of GInitable, and this avoids unnecessary
crashing of programs running with G_DEBUG=fatal-criticals.
2023-02-09 19:46:30 +01:00
Gaël Bonithon
41490f9624 searchengine: Add missing sanity check 2023-02-09 19:25:04 +01:00
Vasil Pupkin
45e6e9a7d1 Update Belarusian translation 2023-02-08 21:48:28 +00: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
Jason Francis
3fc7c97979 gtk: Set widget template children to NULL before destroy unref 2022-05-14 10:13:39 -04:00
359 changed files with 41233 additions and 36743 deletions

View File

@@ -26,25 +26,31 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v40"
FLATPAK_IMAGE: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v41"
.only-default:
only:
- branches
except:
- tags
workflow:
rules:
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
default:
retry:
max: 2
when:
- 'runner_system_failure'
- 'stuck_or_timeout_failure'
- 'scheduler_failure'
- 'api_failure'
interruptible: true
style-check-diff:
extends: .only-default
image: $FEDORA_IMAGE
stage: check
allow_failure: true
when: manual
script:
- .gitlab-ci/run-style-check-diff.sh
.build-fedora-default:
extends: .only-default
image: $FEDORA_IMAGE
artifacts:
when: always
@@ -160,7 +166,6 @@ fedora-mingw64:
- ninja -C _build
.mingw-defaults:
extends: .only-default
stage: build
tags:
- win32-ps
@@ -192,9 +197,8 @@ msys2-mingw64:
macos:
# Sadly, this fails regularly, and its failure is never enlightening
allow_failure: true
extends: .only-default
only:
- branches@GNOME/gtk
rules:
- if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
tags:
- macos
@@ -227,10 +231,9 @@ macos:
- "${CI_PROJECT_DIR}/_build/meson-logs"
vs2017-x64:
extends: .only-default
# TODO: Uncomment this when ready to merge.
#only:
# - branches@GNOME/gtk
# rules:
# - if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
tags:
- win32-ps
@@ -243,7 +246,7 @@ vs2017-x64:
- "${CI_PROJECT_DIR}/_build/meson-logs"
.flatpak-defaults:
image: $FLATPAK_IMAGE
image: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
stage: flatpak
allow_failure: true
tags:
@@ -253,65 +256,67 @@ vs2017-x64:
- "${APPID}-dev.flatpak"
- 'repo.tar'
expire_in: 1 day
rules:
# Only build Flatpak bundles automatically on main
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH != "main"
when: "manual"
script:
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
# Manual jobs, for branches and MRs
.flatpak-manual:
extends: .flatpak-defaults
when: manual
# Only build Flatpak bundles automatically on main
.flatpak-main:
extends: .flatpak-defaults
only:
- main
flatpak-manual:demo:
extends: .flatpak-manual
flatpak:demo:
extends: '.flatpak-defaults'
needs: []
variables:
APPID: org.gtk.Demo4
flatpak-main:demo:
extends: .flatpak-main
flatpak:demo:aarch64:
extends: '.flatpak-defaults'
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.Demo4
flatpak-manual:widget-factory:
extends: .flatpak-manual
flatpak:widget-factory:
extends: '.flatpak-defaults'
needs: []
variables:
APPID: org.gtk.WidgetFactory4
flatpak-main:widget-factory:
extends: .flatpak-main
flatpak:widget-factory:aarch64:
extends: '.flatpak-defaults'
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.WidgetFactory4
flatpak-manual:icon-browser:
extends: .flatpak-manual
flatpak:icon-browser:
extends: '.flatpak-defaults'
needs: []
variables:
APPID: org.gtk.IconBrowser4
flatpak-main:icon-browser:
extends: .flatpak-main
flatpak:icon-browser:aarch64:
extends: '.flatpak-defaults'
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.IconBrowser4
flatpak-manual:node-editor:
extends: .flatpak-manual
flatpak:node-editor:
extends: '.flatpak-defaults'
needs: []
variables:
APPID: org.gtk.gtk4.NodeEditor
flatpak-main:node-editor:
extends: .flatpak-main
flatpak:node-editor:aarch64:
extends: '.flatpak-defaults'
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.gtk4.NodeEditor
@@ -320,23 +325,35 @@ flatpak-main:node-editor:
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
nightly demo:
extends: '.publish_nightly'
dependencies: ['flatpak-main:demo']
needs: ['flatpak-main:demo']
needs: ['flatpak:demo']
nightly demo aarch64:
extends: '.publish_nightly'
needs: ['flatpak:demo:aarch64']
nightly factory:
extends: '.publish_nightly'
dependencies: ['flatpak-main:widget-factory']
needs: ['flatpak-main:widget-factory']
needs: ['flatpak:widget-factory']
nightly factory aarch64:
extends: '.publish_nightly'
needs: ['flatpak:widget-factory:aarch64']
nightly icon-browser:
extends: '.publish_nightly'
dependencies: ['flatpak-main:icon-browser']
needs: ['flatpak-main:icon-browser']
needs: ['flatpak:icon-browser']
nightly icon-browser aarch64:
extends: '.publish_nightly'
needs: ['flatpak:icon-browser:aarch64']
nightly node-editor:
extends: '.publish_nightly'
dependencies: ['flatpak-main:node-editor']
needs: ['flatpak-main:node-editor']
needs: ['flatpak:node-editor']
nightly node-editor aarch64:
extends: '.publish_nightly'
needs: ['flatpak:node-editor:aarch64']
static-scan:
image: $FEDORA_IMAGE
@@ -364,6 +381,7 @@ asan-build:
tags: [ asan ]
stage: analysis
needs: []
when: manual
variables:
script:
- export PATH="$HOME/.local/bin:$PATH"
@@ -418,9 +436,9 @@ reference:
publish-docs:
image: fedora:latest
stage: publish
interruptible: false
needs: ['reference']
script:
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
only:
refs:
- main
rules:
- if: $CI_COMMIT_REF_NAME == "main"

View File

@@ -82,6 +82,7 @@ RUN dnf -y install \
python3-gobject \
python3-jinja2 \
python3-markdown \
python3-packaging \
python3-pip \
python3-pygments \
python3-typogrify \

View File

@@ -20,6 +20,7 @@ flatpak build ${builddir} meson \
-Dx11-backend=true \
-Dwayland-backend=true \
-Dbuild-tests=false \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Ddemos=true \

View File

@@ -23,6 +23,7 @@ push=0
list=0
print_help=0
no_login=0
no_cache=0
while (($# > 0)); do
case "${1%%=*}" in
@@ -34,6 +35,7 @@ while (($# > 0)); do
--base|-b) read_arg base "$@" || shift;;
--version|-v) read_arg base_version "$@" || shift;;
--no-login) no_login=1;;
--no-cache) no_cache=1;;
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
esac
shift
@@ -103,11 +105,21 @@ TAG="${REGISTRY}/gnome/gtk/${base}:${base_version}"
if [ $build == 1 ]; then
echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
${CMD} build \
${format} \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
if [ $no_cache == 0 ]; then
${CMD} build \
${format} \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
else
${CMD} build \
${format} \
--no-cache \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
fi
exit $?
fi

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

166
NEWS
View File

@@ -1,6 +1,170 @@
Overview of Changes in 4.9.3, xx-xx-xxxx
Overview of Changes in 4.10.1, xx-xx-xxxx
=========================================
Overview of Changes in 4.10.0, 04-03-2023
=========================================
* GtkTextView
- Document hanging indentation
* GtkListView
- Fix a size allocation problem
* GtkFileChooser
- Fix paned behavior
- Fix a crash
* GtkText
- Fix various problems with undo
* Accessibility
- Make some getters transfer-full
- Allow setting accessible parents and siblings
- Add a role for toggle buttons
- Miscellaneous property fixes and improvements
* gtk
- Improve the handling resize-during-size-allocate
* gdk
- Introduce GdkTextureDownloader and use it
- Make gdk_texture_get_format public
* gsk
- Make mask nodes more versatile
- Improve the GL implementation for texture scale nodes
* X11
- Fix key handling during DND
* Tools
- gtk-builder-tool: Try harder to handle templates
- gtk-builder-tool: Prefer properties over <child>
* Translation updates
Basque
Belarusian
Bulgarian
Indonesian
Galician
Georgian
German
Hebrew
Lithuanian
Portuguese
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.9.4, 12-02-2023
========================================
* Printing:
- Add a CPDB backend
- Drop the lpr backend
* GtkFileDialog:
- Robustness fixes
* GtkScaleButton:
- Add an 'active' property
* GtkSearchEntry:
- Add placeholder text
* Fix conflicting type names between gtk and gio
* Gsk:
- Settable filtering for scaled textures
- Add mask nodes
- Some robustness and crash fixes
* Wayland:
- Handle dispatch failing in more places
* Deprecations:
- GtkVolumeButton
* Translation updates:
Belarusian
Chinese (Taiwan)
Georgian
Turkish
Ukrainian
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
========================================

View File

@@ -9,7 +9,7 @@ constraint_editor_sources = [
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
'constraint-editor.gresource.xml',
source_dir: '.',
source_dir: meson.current_source_dir(),
)
executable('gtk4-constraint-editor',

View File

@@ -2,6 +2,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
typedef GtkApplication DemoApplication;
typedef GtkApplicationClass DemoApplicationClass;

View File

@@ -7,6 +7,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *progress_bar = NULL;
static gboolean

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,

View File

@@ -215,6 +215,12 @@
<file>demo3widget.h</file>
<file>demo3widget.ui</file>
</gresource>
<gresource prefix="/mask">
<file>demo4widget.c</file>
<file>demo4widget.h</file>
<file>hsla.h</file>
<file>hsla.c</file>
</gresource>
<gresource prefix="/paintable_svg">
<file>svgpaintable.h</file>
<file>svgpaintable.c</file>
@@ -311,6 +317,7 @@
<file>list_store.c</file>
<file>main.c</file>
<file>markup.c</file>
<file>mask.c</file>
<file>menu.c</file>
<file>overlay.c</file>
<file>overlay_decorative.c</file>

View File

@@ -3,7 +3,8 @@
enum
{
PROP_PAINTABLE = 1,
PROP_TEXTURE = 1,
PROP_FILTER,
PROP_SCALE
};
@@ -11,8 +12,9 @@ struct _Demo3Widget
{
GtkWidget parent_instance;
GdkPaintable *paintable;
GdkTexture *texture;
float scale;
GskScalingFilter filter;
GtkWidget *menu;
};
@@ -28,6 +30,7 @@ static void
demo3_widget_init (Demo3Widget *self)
{
self->scale = 1.f;
self->filter = GSK_SCALING_FILTER_LINEAR;
gtk_widget_init_template (GTK_WIDGET (self));
}
@@ -36,7 +39,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 +53,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 +67,11 @@ 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_scale_node_new (self->texture,
&GRAPHENE_RECT_INIT (0, 0, w, h),
self->filter);
gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
gtk_snapshot_restore (snapshot);
gtk_snapshot_pop (snapshot);
}
@@ -81,9 +89,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 +121,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 +132,11 @@ demo3_widget_set_property (GObject *object,
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
case PROP_FILTER:
self->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 +153,18 @@ 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_FILTER:
g_value_set_enum (value, self->filter);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -205,16 +222,21 @@ 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_FILTER,
g_param_spec_enum ("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 +251,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);
}

View File

@@ -0,0 +1,226 @@
#include <math.h>
#include "demo4widget.h"
#include "hsla.h"
enum
{
PROP_0,
PROP_PROGRESS,
};
struct _Demo4Widget
{
GtkWidget parent_instance;
PangoLayout *layout;
GskColorStop stops[8];
gsize n_stops;
double progress;
guint tick;
};
struct _Demo4WidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (Demo4Widget, demo4_widget, GTK_TYPE_WIDGET)
static void
rotate_color (GdkRGBA *rgba)
{
GdkHSLA hsla;
_gdk_hsla_init_from_rgba (&hsla, rgba);
hsla.hue -= 1;
_gdk_rgba_init_from_hsla (rgba, &hsla);
}
static gboolean
rotate_colors (GtkWidget *widget,
GdkFrameClock *clock,
gpointer user_data)
{
Demo4Widget *self = DEMO4_WIDGET (widget);
for (unsigned int i = 0; i < self->n_stops; i++)
rotate_color (&self->stops[i].color);
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
demo4_widget_init (Demo4Widget *self)
{
PangoFontDescription *desc;
self->progress = 0.5;
self->n_stops = 8;
self->stops[0].offset = 0;
self->stops[0].color = (GdkRGBA) { 1, 0, 0, 1 };
for (unsigned int i = 1; i < self->n_stops; i++)
{
GdkHSLA hsla;
self->stops[i].offset = i / (double)(self->n_stops - 1);
_gdk_hsla_init_from_rgba (&hsla, &self->stops[i - 1].color);
hsla.hue += 360.0 / (double)(self->n_stops - 1);
_gdk_rgba_init_from_hsla (&self->stops[i].color, &hsla);
}
self->layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "123");
desc = pango_font_description_from_string ("Cantarell Bold 210");
pango_layout_set_font_description (self->layout, desc);
pango_font_description_free (desc);
self->tick = gtk_widget_add_tick_callback (GTK_WIDGET (self), rotate_colors, NULL, NULL);
}
static void
demo4_widget_dispose (GObject *object)
{
Demo4Widget *self = DEMO4_WIDGET (object);
g_clear_object (&self->layout);
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick);
G_OBJECT_CLASS (demo4_widget_parent_class)->dispose (object);
}
static void
demo4_widget_snapshot_content (GtkWidget *widget,
GtkSnapshot *snapshot,
GskMaskMode mode)
{
Demo4Widget *self = DEMO4_WIDGET (widget);
int width, height, layout_width, layout_height;
double scale;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_snapshot_push_mask (snapshot, mode);
pango_layout_get_pixel_size (self->layout, &layout_width, &layout_height);
scale = MIN ((double) width / layout_width, (double) height / layout_height);
gtk_snapshot_translate (snapshot,
&GRAPHENE_POINT_INIT ((width - scale * layout_width) / 2,
(height - scale * layout_height) / 2));
gtk_snapshot_scale (snapshot, scale, scale);
gtk_snapshot_append_layout (snapshot, self->layout, &(GdkRGBA) { 0, 0, 0, 1 });
gtk_snapshot_pop (snapshot);
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
self->stops,
self->n_stops);
gtk_snapshot_pop (snapshot);
}
static void
demo4_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
Demo4Widget *self = DEMO4_WIDGET (widget);
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_INVERTED_LUMINANCE);
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, 0),
(GskColorStop[2]) {
{ MAX (0.0, self->progress - 5.0 / width), { 1, 1, 1, 1 } },
{ MIN (1.0, self->progress + 5.0 / width), { 0, 0, 0, 1 } }
}, 2);
gtk_snapshot_pop (snapshot);
demo4_widget_snapshot_content (widget, snapshot, GSK_MASK_MODE_INVERTED_ALPHA);
gtk_snapshot_pop (snapshot);
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_LUMINANCE);
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, 0),
(GskColorStop[2]) {
{ MAX (0.0, self->progress - 5.0 / width), { 1, 1, 1, 1 } },
{ MIN (1.0, self->progress + 5.0 / width), { 0, 0, 0, 1 } }
}, 2);
gtk_snapshot_pop (snapshot);
demo4_widget_snapshot_content (widget, snapshot, GSK_MASK_MODE_ALPHA);
gtk_snapshot_pop (snapshot);
}
static void
demo4_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
Demo4Widget *self = DEMO4_WIDGET (object);
switch (prop_id)
{
case PROP_PROGRESS:
self->progress = g_value_get_double (value);
gtk_widget_queue_draw (GTK_WIDGET (object));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
demo4_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
Demo4Widget *self = DEMO4_WIDGET (object);
switch (prop_id)
{
case PROP_PROGRESS:
g_value_set_double (value, self->progress);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
demo4_widget_class_init (Demo4WidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = demo4_widget_dispose;
object_class->get_property = demo4_widget_get_property;
object_class->set_property = demo4_widget_set_property;
widget_class->snapshot = demo4_widget_snapshot;
g_object_class_install_property (object_class, PROP_PROGRESS,
g_param_spec_double ("progress", NULL, NULL,
0.0, 1.0, 0.5,
G_PARAM_READWRITE));
}
GtkWidget *
demo4_widget_new (void)
{
return g_object_new (DEMO4_TYPE_WIDGET, NULL);
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include <gtk/gtk.h>
#define DEMO4_TYPE_WIDGET (demo4_widget_get_type ())
G_DECLARE_FINAL_TYPE (Demo4Widget, demo4_widget, DEMO4, WIDGET, GtkWidget)
GtkWidget * demo4_widget_new (void);

View File

@@ -356,6 +356,10 @@ canvas_item_start_editing (CanvasItem *item)
}
typedef struct {
double x, y;
} Hotspot;
static GdkContentProvider *
prepare (GtkDragSource *source,
double x,
@@ -363,6 +367,7 @@ prepare (GtkDragSource *source,
{
GtkWidget *canvas;
GtkWidget *item;
Hotspot *hotspot;
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
@@ -373,6 +378,10 @@ prepare (GtkDragSource *source,
g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
hotspot = g_new (Hotspot, 1);
gtk_widget_translate_coordinates (canvas, item, x, y, &hotspot->x, &hotspot->y);
g_object_set_data_full (G_OBJECT (canvas), "hotspot", hotspot, g_free);
return gdk_content_provider_new_typed (GTK_TYPE_WIDGET, item);
}
@@ -383,12 +392,14 @@ drag_begin (GtkDragSource *source,
GtkWidget *canvas;
CanvasItem *item;
GdkPaintable *paintable;
Hotspot *hotspot;
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
item = CANVAS_ITEM (g_object_get_data (G_OBJECT (canvas), "dragged-item"));
hotspot = (Hotspot *) g_object_get_data (G_OBJECT (canvas), "hotspot");
paintable = canvas_item_get_drag_icon (item);
gtk_drag_source_set_icon (source, paintable, item->r, item->r);
gtk_drag_source_set_icon (source, paintable, hotspot->x, hotspot->y);
g_object_unref (paintable);
gtk_widget_set_opacity (GTK_WIDGET (item), 0.3);

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);

View File

@@ -48,14 +48,16 @@
#define VERTICES_PER_TOOTH 34
#define GEAR_VERTEX_STRIDE 6
#ifndef HAVE_SINCOS
static void
sincos (double x, double *_sin, double *_cos)
static inline void
_sincos (double x, double *_sin, double *_cos)
{
#ifdef HAVE_SINCOS
sincos (x, _sin, _cos);
#else
*_sin = sin (x);
*_cos = cos (x);
}
#endif
}
/**
* Struct describing the vertices in triangle strip
@@ -307,11 +309,11 @@ create_gear (GLfloat inner_radius,
struct point p[7];
/* Calculate needed sin/cos for various angles */
sincos(i * 2.0 * G_PI / teeth + da * 0, &s[0], &c[0]);
sincos(i * 2.0 * M_PI / teeth + da * 1, &s[1], &c[1]);
sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
_sincos(i * 2.0 * G_PI / teeth + da * 0, &s[0], &c[0]);
_sincos(i * 2.0 * M_PI / teeth + da * 1, &s[1], &c[1]);
_sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
_sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
_sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
GEAR_POINT(p[0], r2, 1);
GEAR_POINT(p[1], r2, 2);
@@ -520,7 +522,7 @@ void perspective(GLfloat *m, GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloa
identity(tmp);
deltaZ = zFar - zNear;
sincos(radians, &sine, &cosine);
_sincos(radians, &sine, &cosine);
if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
return;

146
demos/gtk-demo/hsla.c Normal file
View File

@@ -0,0 +1,146 @@
#include <gdk/gdk.h>
#include "hsla.h"
void
_gdk_hsla_init_from_rgba (GdkHSLA *hsla,
const GdkRGBA *rgba)
{
float min;
float max;
float red;
float green;
float blue;
float delta;
g_return_if_fail (hsla != NULL);
g_return_if_fail (rgba != NULL);
red = rgba->red;
green = rgba->green;
blue = rgba->blue;
if (red > green)
{
if (red > blue)
max = red;
else
max = blue;
if (green < blue)
min = green;
else
min = blue;
}
else
{
if (green > blue)
max = green;
else
max = blue;
if (red < blue)
min = red;
else
min = blue;
}
hsla->lightness = (max + min) / 2;
hsla->saturation = 0;
hsla->hue = 0;
hsla->alpha = rgba->alpha;
if (max != min)
{
if (hsla->lightness <= 0.5)
hsla->saturation = (max - min) / (max + min);
else
hsla->saturation = (max - min) / (2 - max - min);
delta = max -min;
if (red == max)
hsla->hue = (green - blue) / delta;
else if (green == max)
hsla->hue = 2 + (blue - red) / delta;
else if (blue == max)
hsla->hue = 4 + (red - green) / delta;
hsla->hue *= 60;
if (hsla->hue < 0.0)
hsla->hue += 360;
}
}
void
_gdk_rgba_init_from_hsla (GdkRGBA *rgba,
const GdkHSLA *hsla)
{
float hue;
float lightness;
float saturation;
float m1, m2;
lightness = hsla->lightness;
saturation = hsla->saturation;
if (lightness <= 0.5)
m2 = lightness * (1 + saturation);
else
m2 = lightness + saturation - lightness * saturation;
m1 = 2 * lightness - m2;
rgba->alpha = hsla->alpha;
if (saturation == 0)
{
rgba->red = lightness;
rgba->green = lightness;
rgba->blue = lightness;
}
else
{
hue = hsla->hue + 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
rgba->red = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->red = m2;
else if (hue < 240)
rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->red = m1;
hue = hsla->hue;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
rgba->green = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->green = m2;
else if (hue < 240)
rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->green = m1;
hue = hsla->hue - 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
rgba->blue = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->blue = m2;
else if (hue < 240)
rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->blue = m1;
}
}

15
demos/gtk-demo/hsla.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
typedef struct _GdkHSLA GdkHSLA;
struct _GdkHSLA {
float hue;
float saturation;
float lightness;
float alpha;
};
void _gdk_hsla_init_from_rgba (GdkHSLA *hsla,
const GdkRGBA *rgba);
void _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
const GdkHSLA *hsla);

53
demos/gtk-demo/mask.c Normal file
View File

@@ -0,0 +1,53 @@
/* Masking
*
* Demonstrates mask nodes.
*
* This demo uses a text node as mask for
* an animated linear gradient.
*/
#include <gtk/gtk.h>
#include "demo4widget.h"
GtkWidget *
do_mask (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *box;
GtkWidget *demo;
GtkWidget *scale;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Mask Nodes");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
demo = demo4_widget_new ();
gtk_widget_set_hexpand (demo, TRUE);
gtk_widget_set_vexpand (demo, TRUE);
gtk_box_append (GTK_BOX (box), demo);
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 1, 0.1);
gtk_range_set_value (GTK_RANGE (scale), 0.5);
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value", demo, "progress", 0);
gtk_box_append (GTK_BOX (box), scale);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

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,19 @@ 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, "filter", G_BINDING_DEFAULT);
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
widget, "scale",
G_BINDING_BIDIRECTIONAL);

View File

@@ -46,6 +46,7 @@ demos = files([
'links.c',
'listbox.c',
'listbox_controls.c',
'mask.c',
'menu.c',
'flowbox.c',
'list_store.c',
@@ -114,6 +115,7 @@ extra_demo_sources = files([
'gtkshadertoy.c',
'gtkshaderstack.c',
'gskshaderpaintable.c',
'hsla.c',
'puzzlepiece.c',
'bluroverlay.c',
'demoimage.c',
@@ -126,6 +128,7 @@ extra_demo_sources = files([
'four_point_transform.c',
'demo2widget.c',
'demo3widget.c',
'demo4widget.c',
'pixbufpaintable.c',
'script-names.c',
'unicode-names.c',
@@ -222,7 +225,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
else
gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
'demo.gresource.xml',
source_dir: '.',
source_dir: meson.current_source_dir()
)
endif

View File

@@ -13,20 +13,13 @@
static GtkWidget *app_picker;
static void
file_opened (GObject *source,
GAsyncResult *result,
void *data)
set_file (GFile *file,
gpointer data)
{
GFile *file;
GError *error = NULL;
char *name;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
gtk_widget_set_sensitive (app_picker, FALSE);
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
return;
@@ -40,6 +33,25 @@ file_opened (GObject *source,
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
}
static void
file_opened (GObject *source,
GAsyncResult *result,
void *data)
{
GFile *file;
GError *error = NULL;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
}
set_file (file, data);
}
static gboolean
abort_mission (gpointer data)
{
@@ -130,11 +142,28 @@ launch_uri (GtkButton *picker)
g_object_unref (launcher);
}
static gboolean
on_drop (GtkDropTarget *target,
const GValue *value,
double x,
double y,
gpointer data)
{
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
set_file (g_value_get_object (value), data);
return TRUE;
}
return FALSE;
}
GtkWidget *
do_pickers (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *table, *label, *picker, *button;
GtkDropTarget *drop_target;
if (!window)
{
@@ -179,7 +208,13 @@ do_pickers (GtkWidget *do_widget)
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
button = gtk_button_new_from_icon_name ("document-open-symbolic");
label = gtk_label_new ("None");
drop_target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY);
g_signal_connect (drop_target, "drop", G_CALLBACK (on_drop), label);
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (drop_target));
gtk_label_set_xalign (GTK_LABEL (label), 0.);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
gtk_widget_set_hexpand (label, TRUE);

View File

@@ -22,6 +22,7 @@ show_shortcuts (GtkWidget *window,
gtk_window_set_transient_for (GTK_WINDOW (overlay), GTK_WINDOW (window));
g_object_set (overlay, "view-name", view, NULL);
g_object_unref (builder);
gtk_window_present (GTK_WINDOW (overlay));
}
G_MODULE_EXPORT void

View File

@@ -8,7 +8,7 @@ iconbrowser_sources = [
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
'iconbrowser.gresource.xml',
source_dir: '.',
source_dir: meson.current_source_dir(),
)
executable('gtk4-icon-browser',

View File

@@ -7,7 +7,7 @@ node_editor_sources = [
node_editor_resources = gnome.compile_resources('node_editor_resources',
'node-editor.gresource.xml',
source_dir: '.',
source_dir: meson.current_source_dir(),
)
executable('gtk4-node-editor',

View File

@@ -178,6 +178,16 @@ Creates a node like `gsk_inset_shadow_node_new()` with the given properties.
Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
### mask
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| source | `<node>` | color { } | always |
| mode | `<blend-mode>` | alpha | non-default |
| mask | `<node>` | color { } | always |
Creates a node like `gsk_mask_node_new()` with the given properties.
### opacity
| property | syntax | default | printed |
@@ -297,6 +307,21 @@ The default texture is a 10x10 checkerboard with the top left and bottom right
representation for this texture is `url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABmJLR0QA/wD/AP+gvaeTAAAAKUlEQVQYlWP8z3DmPwMaYGQwYUQXY0IXwAUGUCGGoxkYGBiweXAoeAYAz44F3e3U1xUAAAAASUVORK5CYII=")
`.
### texture-scale
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| texture | `<url>` | *see below* | always |
| filter | `filter` | *see below* | non-default |
Creates a node like `gsk_texture_scale_node_new()` with the given properties.
The default texture is a 10x10 checkerboard, just like for texture.
The possible filter values are `linear`, `nearest` and `trilinear`, with
`linear` being the default.
### transform
| property | syntax | default | printed |

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;

View File

@@ -69,7 +69,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
else
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
'widget-factory.gresource.xml',
source_dir: '.',
source_dir: meson.current_source_dir(),
)
endif

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");

View File

@@ -239,14 +239,14 @@ control whether Vulkan should be used.
### `media-gstreamer` and `media-ffmpeg`
By default, GTK will try to build the gstreamer backend for
media playback support. These option can be used to explicitly
media playback support. These options can be used to explicitly
control which media backends should be built.
### `print-cups`
### `print-cups` and `print-cpdb`
By default, GTK will try to build various print backends
if their dependencies are found. This option can be used
to explicitly control whether the cups print backend should be built.
By default, GTK will try to build the cups and file print backends
if their dependencies are found. These options can be used to
explicitly control which print backends should be built.
### `cloudproviders`

View File

@@ -66,6 +66,10 @@ You can compile the program above with GCC using:
gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )
```
**Note**: If the above compilation does not work due to an error regarding `G_APPLICATION_DEFAULT_FLAGS`
this could be due to your OS providing an older version of GLib. For GLib versions older than 2.74 you
will need to replace `G_APPLICATION_DEFAULT_FLAGS` with `G_APPLICATION_FLAGS_NONE` in this example, and
others in this documentation.
For more information on how to compile a GTK application, please
refer to the [Compiling GTK Applications](compiling.html)
section in this reference.

View File

@@ -33,6 +33,11 @@ Validation
The ``validate`` command validates the given UI definition file and reports
errors to ``stderr``.
Note that there are limitations to the validation that can be done for templates,
since they are closely tied to the class_init function they are used in.
If your UI file uses types from third-party libraries, it may help to add those
libraries to the `LD_PRELOAD` environment variable.
``--deprecations``
Warn about uses of deprecated types in the UI definition file.

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 and GtkVolumeButton are going away
These are very specialized widgets that should better live with the application
where they are used.

View File

@@ -7,37 +7,50 @@ the question you have, this list is a good place to start.
## General Questions
1. How do I get started with GTK?
* How do I get started with GTK?
The GTK [website](https://www.gtk.org) offers some
[tutorials](https://www.gtk.org/documentation.php) and other documentation
(most of it about GTK 2.x and 3.x, but still somewhat applicable). This
reference manual also contains a introductory
This reference manual also contains a introductory
[Getting Started](#gtk-getting-started) part.
More documentation ranging from whitepapers to online books can be found at
the [GNOME developer's site](https://developer.gnome.org). After studying these
materials you should be well prepared to come back to this reference manual for details.
2. Where can I get help with GTK, submit a bug report, or make a feature request?
* Where can I get help with GTK, submit a bug report, or make a feature request?
See the [documentation](#gtk-resources) on this topic.
3. How do I port from one GTK version to another?
* How do I port from one GTK version to another?
See the [migration guide](#migrating). You may also find useful information in
the documentation for specific widgets and functions. If you have a question not
covered in the manual, feel free to ask, and please
Every major version of GTK comes with a [migration guide](#migrating). You may also
find useful information in the documentation for specific widgets and functions. If
you have a question not covered in the manual, feel free to ask, and please
[file a bug report](https://gitlab.gnome.org/GNOME/gtk/issues/new) against the
documentation.
4. How does memory management work in GTK? Should I free data returned from functions?
* Should I maintain parallel versions of my UI in GTK x and GTK y?
At the end of the day, that is up to you.
Our experience is that it is a lot of work, and usually not a good idea.
If you are not ready to make the jump to the next major version of GTK,
it is perfectly fine to stick with the stable release. We maintain them
for that reason.
* How does memory management work in GTK? Should I free data returned from functions?
See the documentation for `GObject` and `GInitiallyUnowned`. For `GObject` note
specifically `g_object_ref()` and `g_object_unref()`. `GInitiallyUnowned` is a
subclass of `GObject` so the same points apply, except that it has a "floating"
state (explained in its documentation).
In a widget tree, each container owns a reference to its children. The root
object (typically a `GtkWindow`) is owned by GTK. GTK will drop its reference
when you call [method@Gtk.Window.destroy].
For strings returned from functions, they will be declared "const" if they should
not be freed. Non-const strings should be freed with `g_free()`. Arrays follow the
same rule. If you find an undocumented exception to the rules, please
@@ -46,7 +59,7 @@ the question you have, this list is a good place to start.
The transfer annotations for gobject-introspection that are part of the
documentation can provide useful hints for memory handling semantics as well.
5. Why does my program leak memory, if I destroy a widget immediately
* Why does my program leak memory, if I destroy a widget immediately
after creating it?
If `GtkFoo` isn't a toplevel window, then
@@ -69,7 +82,7 @@ the question you have, this list is a good place to start.
the initial floating reference and you don't have to worry about reference
counting at all ... just remove the widget from the container to get rid of it.
6. How do I use GTK with threads?
* How do I use GTK with threads?
GTK requires that all GTK API calls are made from the same thread in which
the `GtkApplication` was created, or `gtk_init()` was called (the _main thread_).
@@ -79,7 +92,7 @@ the question you have, this list is a good place to start.
the results back to the main thread using `g_idle_add()` or `GAsyncQueue`. GIO
offers useful tools for such an approach such as `GTask`.
7. How do I internationalize a GTK program?
* How do I internationalize a GTK program?
Most people use [GNU gettext](https://www.gnu.org/software/gettext/),
already required in order to install GLib. On a UNIX or Linux system with
@@ -134,7 +147,7 @@ the question you have, this list is a good place to start.
#define _(x) dgettext (GETTEXT_PACKAGE, x)
8. How do I use non-ASCII characters in GTK programs ?
* How do I use non-ASCII characters in GTK programs ?
GTK uses [Unicode](http://www.unicode.org) (more exactly UTF-8) for all text.
UTF-8 encodes each Unicode codepoint as a sequence of one to six bytes and
@@ -217,7 +230,7 @@ the question you have, this list is a good place to start.
to call bind_textdomain_codeset() to ensure that translated strings
are returned in UTF-8 encoding.
9. How do I use GTK with C++?
* How do I use GTK with C++?
There are two ways to approach this. The GTK header files use the subset
of C that's also valid C++, so you can simply use the normal GTK API
@@ -242,19 +255,23 @@ the question you have, this list is a good place to start.
There are very few functions that require this cast, however.
10. How do I use GTK with other non-C languages?
* How do I use GTK with other non-C languages?
See the list of [language bindings](https://www.gtk.org/language-bindings.php)
on the GTK [website](https://www.gtk.org).
11. How do I load an image or animation from a file?
* How do I load an image or animation from a file?
To load an image file straight into a display widget, use
[ctor@Gtk.Image.new_from_file]. To load an image for another purpose, use
[ctor@Gdk.Texture.new_from_file]. To load a video from a file, use
[ctor@Gtk.MediaFile.new_for_file].
[ctor@Gtk.Picture.new_for_file] or [ctor@GTk.Picture.new_for_filename].
To load an image for another purpose, use [ctor@Gdk.Texture.new_from_file].
To load a video from a file, use [ctor@Gtk.MediaFile.new_for_file].
12. How do I draw text?
* How do I draw text?
If you just want to put text into your user interface somewhere, it is
usually easiest to just use one of ready-made widgets for this purpose,
such as [class@Gtk.Label].
To draw a piece of text onto a cairo surface, use a Pango layout and
[func@PangoCairo.show_layout].
@@ -272,7 +289,7 @@ the question you have, this list is a good place to start.
To draw a piece of text in a widget [vfunc@Gtk.Widget.snapshot] implementation,
use [method@Gtk.Snapshot.append_layout].
13. How do I measure the size of a piece of text?
* How do I measure the size of a piece of text?
To obtain the size of a piece of text, use a Pango layout and
[method@Pango.Layout.get_pixel_size], using code like the following:
@@ -287,7 +304,7 @@ the question you have, this list is a good place to start.
See also the [Layout Objects](https://developer.gnome.org/pango/stable/pango-Layout-Objects.html)
section of the [Pango documentation](https://developer.gnome.org/pango/stable/).
14. Why are types not registered if I use their `GTK_TYPE_BLAH` macro?
* Why are types not registered if I use their `GTK_TYPE_BLAH` macro?
The %GTK_TYPE_BLAH macros are defined as calls to gtk_blah_get_type(), and
the `_get_type()` functions are declared as %G_GNUC_CONST which allows the
@@ -298,14 +315,14 @@ the question you have, this list is a good place to start.
g_type_ensure (GTK_TYPE_BLAH);
15. How do I create a transparent toplevel window?
* How do I create a transparent toplevel window?
Any toplevel window can be transparent. It is just a matter of setting a
transparent background in the CSS style for it.
## Which widget should I use...
16. ...for lists and trees?
* ...for lists and trees?
This question has different answers, depending on the size of the dataset
and the required formatting flexibility.
@@ -321,7 +338,7 @@ the question you have, this list is a good place to start.
and widgetry inside the list, then you probably want to use a [class@Gtk.ListBox],
which uses regular widgets for display.
17. ...for multi-line text display or editing?
* ...for multi-line text display or editing?
See the [text widget overview](#TextWidget) -- you should use the
[class@Gtk.TextView] widget.
@@ -330,7 +347,7 @@ the question you have, this list is a good place to start.
of course. It can be made selectable with [method@Gtk.Label.set_selectable]. For a
single-line text entry, see [class@Gtk.Entry].
18. ...to display an image or animation?
* ...to display an image or animation?
GTK has two widgets that are dedicated to displaying images. [class@Gtk.Image], for
small, fixed-size icons and [class@Gtk.Picture] for content images.
@@ -346,17 +363,14 @@ the question you have, this list is a good place to start.
mediafile = gtk_media_file_new_for_filename ("example.webm");
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (mediafile));
19. ...for presenting a set of mutually-exclusive choices, where Windows
* ...for presenting a set of mutually-exclusive choices, where Windows
would use a combo box?
With GTK, a [class@Gtk.ComboBox] is the recommended widget to use for this use case.
If you need an editable text entry, use the [property@Gtk.ComboBox:has-entry] property.
A newer alternative is [class@Gtk.DropDown].
With GTK, a [class@Gtk.DropDown] is the recommended widget to use for this use case.
## Questions about GtkWidget
20. How do I change the color of a widget?
* How do I change the color of a widget?
The background color of a widget is determined by the CSS style that applies
to it. To change that, you can set style classes on the widget, and provide
@@ -364,7 +378,7 @@ the question you have, this list is a good place to start.
[method@Gtk.CssProvider.load_from_file] and its variants.
See [method@Gtk.StyleContext.add_provider].
21. How do I change the font of a widget?
* How do I change the font of a widget?
If you want to make the text of a label larger, you can use
gtk_label_set_markup():
@@ -388,14 +402,14 @@ the question you have, this list is a good place to start.
of this approach is that users can then override the font you have chosen.
See the `GtkStyleContext` documentation for more discussion.
22. How do I disable/ghost/desensitize a widget?
* How do I disable/ghost/desensitize a widget?
In GTK a disabled widget is termed _insensitive_.
See [method@Gtk.Widget.set_sensitive].
## GtkTextView questions
23. How do I get the contents of the entire text widget as a string?
* How do I get the contents of the entire text widget as a string?
See [method@Gtk.TextBuffer.get_bounds] and [method@Gtk.TextBuffer.get_text]
or [method@Gtk.TextIter.get_text].
@@ -410,14 +424,14 @@ the question you have, this list is a good place to start.
/* use text */
g_free (text);
24. How do I make a text widget display its complete contents in a specific font?
* How do I make a text widget display its complete contents in a specific font?
If you use [method@Gtk.TextBuffer.insert_with_tags] with appropriate tags to
select the font, the inserted text will have the desired appearance, but
text typed in by the user before or after the tagged block will appear in
the default style.
25. How do I make a text view scroll to the end of the buffer automatically ?
* How do I make a text view scroll to the end of the buffer automatically ?
A good way to keep a text buffer scrolled to the end is to place a
[mark](#GtkTextMark) at the end of the buffer, and give it right gravity.
@@ -432,21 +446,21 @@ the question you have, this list is a good place to start.
## GtkTreeView questions
26. How do I associate some data with a row in the tree?
* How do I associate some data with a row in the tree?
Remember that the [iface@Gtk.TreeModel] columns don't necessarily have to be
displayed. So you can put non-user-visible data in your model just
like any other data, and retrieve it with [method@Gtk.TreeModel.get].
See the [tree widget overview](#TreeWidget).
27. How do I put an image and some text in the same column?
* How do I put an image and some text in the same column?
You can pack more than one [class@Gtk.CellRenderer] into a single [class@Gtk.TreeViewColumn]
using [method@Gtk.TreeViewColumn.pack_start] or [method@Gtk.TreeViewColumn.pack_end].
So pack both a [class@Gtk.CellRendererPixbuf] and a [class@Gtk.CellRendererText] into the
column.
28. I can set data easily on my [class@Gtk.TreeStore] or [class@Gtk.ListStore] models using
* I can set data easily on my [class@Gtk.TreeStore] or [class@Gtk.ListStore] models using
[method@Gtk.ListStore.set] and [method@Gtk.TreeStore.set], but can't read it back?
Both the [class@Gtk.TreeStore] and the [class@Gtk.ListStore] implement the [iface@Gtk.TreeModel]
@@ -454,7 +468,7 @@ the question you have, this list is a good place to start.
implements. The easiest way to read a set of data back is to use
[method@Gtk.TreeModel.get].
29. How do I change the way that numbers are formatted by `GtkTreeView`?
* How do I change the way that numbers are formatted by `GtkTreeView`?
Use [method@Gtk.TreeView.insert_column_with_data_func] or
[method@Gtk.TreeViewColumn.set_cell_data_func] and do the conversion
@@ -528,19 +542,21 @@ the question you have, this list is a good place to start.
(gpointer)DOUBLE_COLUMN, NULL);
}
30. How do I hide the expander arrows in my tree view?
* How do I hide the expander arrows in my tree view?
Set the expander-column property of the tree view to a hidden column.
See [method@Gtk.TreeView.set_expander_column] and [method@Gtk.TreeViewColumn.set_visible].
## Using cairo with GTK
31. How do I use cairo to draw in GTK applications?
* How do I use cairo to draw in GTK applications?
Use [method@Gtk.Snapshot.append_cairo] in your [vfunc@Gtk.Widget.snapshot] vfunc
to obtain a cairo context and draw with that.
[class@Gtk.DrawingArea] is a ready-made widget for drawing with cairo.
32. Can I improve the performance of my application by using another backend
If you implement a custom widget, use [method@Gtk.Snapshot.append_cairo]
in your [vfunc@Gtk.Widget.snapshot] vfunc to obtain a cairo context and draw with that.
* Can I improve the performance of my application by using another backend
of cairo (such as GL)?
No. Most drawing in GTK is not done via cairo anymore (but instead
@@ -551,7 +567,7 @@ the question you have, this list is a good place to start.
If you are interested in using GL for your own drawing, see [class@Gtk.GLArea].
33. Can I use cairo to draw on a `GdkPixbuf`?
* Can I use cairo to draw on a `GdkPixbuf`?
No. The cairo image surface does not support the pixel format used by `GdkPixbuf`.

View File

@@ -1,6 +1,6 @@
app2_resources = gnome.compile_resources('exampleapp2_resources',
'exampleapp.gresource.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
executable('exampleapp2',
'exampleapp.c', 'exampleappwin.c', 'main.c', app2_resources,

View File

@@ -1,6 +1,6 @@
app3_resources = gnome.compile_resources('exampleapp3_resources',
'exampleapp.gresource.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
executable('exampleapp3',
'exampleapp.c', 'exampleappwin.c', 'main.c', app3_resources,

View File

@@ -1,6 +1,6 @@
app4_resources = gnome.compile_resources('exampleapp4_resources',
'exampleapp.gresource.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
executable('exampleapp4',
'exampleapp.c', 'exampleappwin.c', 'main.c', app4_resources,

View File

@@ -1,6 +1,6 @@
app5_resources = gnome.compile_resources('exampleapp5_resources',
'exampleapp.gresource.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
app5_schemas = gnome.compile_schemas()

View File

@@ -1,6 +1,6 @@
app6_resources = gnome.compile_resources('exampleapp6_resources',
'exampleapp.gresource.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
app6_schemas = gnome.compile_schemas()

View File

@@ -1,6 +1,6 @@
app7_resources = gnome.compile_resources('exampleapp7_resources',
'exampleapp.gresource.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
app7_schemas = gnome.compile_schemas()

View File

@@ -1,6 +1,6 @@
app8_resources = gnome.compile_resources('exampleapp8 resources',
'exampleapp.gresource.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
app8_schemas = gnome.compile_schemas()

View File

@@ -1,6 +1,6 @@
app9_resources = gnome.compile_resources('exampleapp9_resources',
'exampleapp.gresource.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
app9_schemas = gnome.compile_schemas()

View File

@@ -1,5 +1,5 @@
bp_resources = gnome.compile_resources('bloatpad_resources',
'bloatpad.gresources.xml',
source_dir: '.')
source_dir: meson.current_source_dir())
executable('bloatpad', 'bloatpad.c', bp_resources, dependencies: libgtk_dep, c_args: common_cflags)

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);

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 {

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)
{

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__ */

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);
}

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)
{

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__ */

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);
}

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;

View File

@@ -54,6 +54,7 @@ struct _GdkBroadwaySurface
gboolean dirty;
gboolean last_synced;
gboolean modal_hint;
GdkGeometry geometry_hints;
GdkSurfaceHints geometry_hints_mask;

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))
{

View File

@@ -69,6 +69,7 @@
#include <gdk/gdksnapshot.h>
#include <gdk/gdksurface.h>
#include <gdk/gdktexture.h>
#include <gdk/gdktexturedownloader.h>
#include <gdk/gdktoplevel.h>
#include <gdk/gdktoplevellayout.h>
#include <gdk/gdktoplevelsize.h>

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)

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

View File

@@ -1511,7 +1511,6 @@ gdk_button_event_get_button (GdkEvent *event)
}
/* }}} */
/* {{{ GdkKeyEvent */
/**
@@ -1972,7 +1971,6 @@ gdk_key_event_get_match (GdkEvent *event,
}
/* }}} */
/* {{{ GdkTouchEvent */
/**
@@ -2109,7 +2107,6 @@ gdk_touch_event_get_emulating_pointer (GdkEvent *event)
}
/* }}} */
/* {{{ GdkCrossingEvent */
/**
@@ -2253,7 +2250,6 @@ gdk_crossing_event_get_detail (GdkEvent *event)
}
/* }}} */
/* {{{ GdkDeleteEvent */
/**
@@ -2284,7 +2280,6 @@ gdk_delete_event_new (GdkSurface *surface)
}
/* }}} */
/* {{{ GdkFocusEvent */
/**
@@ -2341,7 +2336,6 @@ gdk_focus_event_get_in (GdkEvent *event)
}
/* }}} */
/* {{{ GdkScrollEvent */
/**
@@ -2600,7 +2594,6 @@ gdk_scroll_event_get_unit (GdkEvent *event)
}
/* }}} */
/* {{{ GdkTouchpadEvent */
/**
@@ -2859,7 +2852,6 @@ gdk_touchpad_event_get_pinch_scale (GdkEvent *event)
}
/* }}} */
/* {{{ GdkPadEvent */
/**
@@ -3033,7 +3025,6 @@ gdk_pad_event_get_group_mode (GdkEvent *event,
}
/* }}} */
/* {{{ GdkMotionEvent */
/**
@@ -3195,7 +3186,6 @@ gdk_event_get_history (GdkEvent *event,
}
/* }}} */
/* {{{ GdkProximityEvent */
/**
@@ -3258,7 +3248,6 @@ gdk_proximity_event_new (GdkEventType type,
}
/* }}} */
/* {{{ GdkDNDEvent */
/**
@@ -3364,7 +3353,6 @@ gdk_dnd_event_get_drop (GdkEvent *event)
}
/* }}} */
/* {{{ GdkGrabBrokenEvent */
/**
@@ -3442,3 +3430,5 @@ gdk_grab_broken_event_get_implicit (GdkEvent *event)
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */

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

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,

View File

@@ -24,7 +24,6 @@
#include "gdkglcontextprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdktextureprivate.h"
#include <epoxy/gl.h>
@@ -53,10 +52,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 +63,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 +100,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 +109,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 +154,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 +184,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 +202,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 +213,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 +306,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

View File

@@ -178,10 +178,10 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
GBytes *bytes;
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL);
g_return_val_if_fail (x >= 0 || x < GDK_TEXTURE (source)->width, NULL);
g_return_val_if_fail (y >= 0 || y < GDK_TEXTURE (source)->height, NULL);
g_return_val_if_fail (width > 0 || x + width <= GDK_TEXTURE (source)->width, NULL);
g_return_val_if_fail (height > 0 || y + height <= GDK_TEXTURE (source)->height, NULL);
g_return_val_if_fail (x >= 0 && x < GDK_TEXTURE (source)->width, NULL);
g_return_val_if_fail (y >= 0 && y < GDK_TEXTURE (source)->height, NULL);
g_return_val_if_fail (width > 0 && x + width <= GDK_TEXTURE (source)->width, NULL);
g_return_val_if_fail (height > 0 && y + height <= GDK_TEXTURE (source)->height, NULL);
texture = GDK_TEXTURE (source);
bpp = gdk_memory_format_bytes_per_pixel (texture->format);
@@ -222,7 +222,7 @@ gdk_memory_texture_from_texture (GdkTexture *texture,
data = g_malloc_n (stride, texture->height);
gdk_texture_do_download (texture, format, data, stride);
bytes = g_bytes_new_take (data, stride);
bytes = g_bytes_new_take (data, stride * texture->height);
result = gdk_memory_texture_new (texture->width,
texture->height,
format,
@@ -233,15 +233,11 @@ gdk_memory_texture_from_texture (GdkTexture *texture,
return GDK_MEMORY_TEXTURE (result);
}
const guchar *
gdk_memory_texture_get_data (GdkMemoryTexture *self)
GBytes *
gdk_memory_texture_get_bytes (GdkMemoryTexture *self,
gsize *out_stride)
{
return g_bytes_get_data (self->bytes, NULL);
}
gsize
gdk_memory_texture_get_stride (GdkMemoryTexture *self)
{
return self->stride;
*out_stride = self->stride;
return self->bytes;
}

View File

@@ -37,8 +37,8 @@ GdkTexture * gdk_memory_texture_new_subtexture (GdkMemoryTexture *
int width,
int height);
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
GBytes * gdk_memory_texture_get_bytes (GdkMemoryTexture *self,
gsize *out_stride);
G_END_DECLS

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]);
}

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)

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

View File

@@ -27,7 +27,7 @@
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdksurface.h"
#include "gdktextureprivate.h"
#include "gdktexturedownloaderprivate.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -218,9 +218,9 @@ gdk_pixbuf_get_from_surface (cairo_surface_t *surface,
static void
pixbuf_texture_unref_cb (guchar *pixels,
gpointer texture)
gpointer bytes)
{
g_object_unref (texture);
g_bytes_unref (bytes);
}
/**
@@ -238,22 +238,27 @@ pixbuf_texture_unref_cb (guchar *pixels,
GdkPixbuf *
gdk_pixbuf_get_from_texture (GdkTexture *texture)
{
GdkMemoryTexture *memtex;
GdkTextureDownloader downloader;
GBytes *bytes;
gsize stride;
gboolean alpha;
alpha = gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_OPAQUE;
memtex = gdk_memory_texture_from_texture (texture,
alpha ? GDK_MEMORY_GDK_PIXBUF_ALPHA
: GDK_MEMORY_GDK_PIXBUF_OPAQUE);
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader,
alpha ? GDK_MEMORY_GDK_PIXBUF_ALPHA
: GDK_MEMORY_GDK_PIXBUF_OPAQUE);
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
gdk_texture_downloader_finish (&downloader);
return gdk_pixbuf_new_from_data (gdk_memory_texture_get_data (memtex),
return gdk_pixbuf_new_from_data (g_bytes_get_data (bytes, NULL),
GDK_COLORSPACE_RGB,
alpha,
8,
gdk_texture_get_width (GDK_TEXTURE (memtex)),
gdk_texture_get_height (GDK_TEXTURE (memtex)),
gdk_memory_texture_get_stride (memtex),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
stride,
pixbuf_texture_unref_cb,
memtex);
bytes);
}

View File

@@ -722,6 +722,9 @@ gdk_texture_download_surface (GdkTexture *texture)
* cairo_image_surface_get_stride (surface));
* cairo_surface_mark_dirty (surface);
* ```
*
* For more flexible download capabilites, see
* [struct@Gdk.TextureDownloader].
*/
void
gdk_texture_download (GdkTexture *texture,
@@ -738,9 +741,29 @@ gdk_texture_download (GdkTexture *texture,
stride);
}
/**
* gdk_texture_get_format:
* @self: a GdkTexture
*
* Gets the memory format most closely associated with the data of
* the texture.
*
* Note that it may not be an exact match for texture data
* stored on the GPU or with compression.
*
* The format can give an indication about the bit depth and opacity
* of the texture and is useful to determine the best format for
* downloading the texture.
*
* Returns: the preferred format for the texture's data
*
* Since: 4.10
**/
GdkMemoryFormat
gdk_texture_get_format (GdkTexture *self)
{
g_return_val_if_fail (GDK_IS_TEXTURE (self), GDK_MEMORY_DEFAULT);
return self->format;
}

View File

@@ -24,6 +24,7 @@
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdkenums.h>
#include <gdk/gdktypes.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -82,6 +83,8 @@ GDK_AVAILABLE_IN_ALL
int gdk_texture_get_width (GdkTexture *texture) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
int gdk_texture_get_height (GdkTexture *texture) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_10
GdkMemoryFormat gdk_texture_get_format (GdkTexture *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
void gdk_texture_download (GdkTexture *texture,

268
gdk/gdktexturedownloader.c Normal file
View File

@@ -0,0 +1,268 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2023 Benjamin Otte
*
* 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/>.
*/
/**
* GdkTextureDownloader:
*
* The `GdkTextureDownloader` is used to download the contents of a
* [class@Gdk.Texture].
*
* It is intended to be created as a short-term object for a single download,
* but can be used for multipe downloads of different textures or with different
* settings.
*
* `GdkTextureDownloader` can be used to convert data between different formats.
* Create a `GdkTexture` for the existing format and then download it in a
* different format.
*
* Since: 4.10
*/
#include "config.h"
#include "gdktexturedownloaderprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdktextureprivate.h"
G_DEFINE_BOXED_TYPE (GdkTextureDownloader, gdk_texture_downloader,
gdk_texture_downloader_copy,
gdk_texture_downloader_free)
void
gdk_texture_downloader_init (GdkTextureDownloader *self,
GdkTexture *texture)
{
self->texture = g_object_ref (texture);
self->format = GDK_MEMORY_DEFAULT;
}
void
gdk_texture_downloader_finish (GdkTextureDownloader *self)
{
g_object_unref (self->texture);
}
/**
* gdk_texture_downloader_new:
* @texture: texture to download
*
* Creates a new texture downloader for @texture.
*
* Returns: A new texture downloader
*
* Since: 4.10
**/
GdkTextureDownloader *
gdk_texture_downloader_new (GdkTexture *texture)
{
GdkTextureDownloader *self;
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
self = g_slice_new (GdkTextureDownloader);
gdk_texture_downloader_init (self, texture);
return self;
}
/**
* gdk_texture_downloader_copy:
* @self: the downloader to copy
*
* Creates a copy of the downloader.
*
* This function is meant for language bindings.
*
* Returns: A copy of the downloader
*
* Since: 4.10
**/
GdkTextureDownloader *
gdk_texture_downloader_copy (const GdkTextureDownloader *self)
{
GdkTextureDownloader *copy;
g_return_val_if_fail (self != NULL, NULL);
copy = gdk_texture_downloader_new (self->texture);
gdk_texture_downloader_set_format (copy, self->format);
return copy;
}
/**
* gdk_texture_downloader_free:
* @self: texture downloader to free
*
* Frees the given downloader and all its associated resources.
*
* Since: 4.10
**/
void
gdk_texture_downloader_free (GdkTextureDownloader *self)
{
g_return_if_fail (self != NULL);
gdk_texture_downloader_finish (self);
g_slice_free (GdkTextureDownloader, self);
}
/**
* gdk_texture_downloader_set_texture:
* @self: a texture downloader
* @texture: the new texture to download
*
* Changes the texture the downloader will download.
*
* Since: 4.10
**/
void
gdk_texture_downloader_set_texture (GdkTextureDownloader *self,
GdkTexture *texture)
{
g_return_if_fail (self != NULL);
g_return_if_fail (GDK_IS_TEXTURE (texture));
g_set_object (&self->texture, texture);
}
/**
* gdk_texture_downloader_get_texture:
* @self: a texture downloader
*
* Gets the texture that the downloader will download.
*
* Returns: (transfer none): The texture to download
*
* Since: 4.10
**/
GdkTexture *
gdk_texture_downloader_get_texture (const GdkTextureDownloader *self)
{
g_return_val_if_fail (self != NULL, NULL);
return self->texture;
}
/**
* gdk_texture_downloader_set_format:
* @self: a texture downloader
* @format: the format to use
*
* Sets the format the downloader will download.
*
* By default, GDK_MEMORY_DEFAULT is set.
*
* Since: 4.10
*/
void
gdk_texture_downloader_set_format (GdkTextureDownloader *self,
GdkMemoryFormat format)
{
g_return_if_fail (self != NULL);
self->format = format;
}
/**
* gdk_texture_downloader_get_format:
* @self: a texture downloader
*
* Gets the format that the data will be downloaded in.
*
* Returns: The format of the download
*
* Since: 4.10
**/
GdkMemoryFormat
gdk_texture_downloader_get_format (const GdkTextureDownloader *self)
{
g_return_val_if_fail (self != NULL, GDK_MEMORY_DEFAULT);
return self->format;
}
/**
* gdk_texture_downloader_download_into:
* @self: a texture downloader
* @data: (array): pointer to enough memory to be filled with the
* downloaded data of the texture
* @stride: rowstride in bytes
*
* Downloads the @texture into local memory.
*
* Since: 4.10
**/
void
gdk_texture_downloader_download_into (const GdkTextureDownloader *self,
guchar *data,
gsize stride)
{
g_return_if_fail (self != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (stride >= gdk_texture_get_width (self->texture) * gdk_memory_format_bytes_per_pixel (self->format));
gdk_texture_do_download (self->texture, self->format, data, stride);
}
/**
* gdk_texture_downloader_download_bytes:
* @self: the downloader
* @out_stride: (out): The stride of the resulting data in bytes.
*
* Downloads the given texture pixels into a `GBytes`. The rowstride will
* be stored in the stride value.
*
* This function will abort if it tries to download a large texture and
* fails to allocate memory. If you think that may happen, you should
* handle memory allocation yourself and use
* gdk_texture_downloader_download_into() once allocation succeeded.
*
* Returns: The downloaded pixels.
*
* Since: 4.10
**/
GBytes *
gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self,
gsize *out_stride)
{
guchar *data;
gsize stride;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (out_stride != NULL, NULL);
if (GDK_IS_MEMORY_TEXTURE (self->texture) &&
gdk_texture_get_format (self->texture) == self->format)
{
GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (self->texture);
return g_bytes_ref (gdk_memory_texture_get_bytes (memtex, out_stride));
}
stride = self->texture->width * gdk_memory_format_bytes_per_pixel (self->format);
data = g_malloc_n (stride, self->texture->height);
gdk_texture_do_download (self->texture, self->format, data, stride);
*out_stride = stride;
return g_bytes_new_take (data, stride * self->texture->height);
}

View File

@@ -0,0 +1,69 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2023 Benjamin Otte
*
* 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/>.
*/
#ifndef __GTK_TEXTURE_DOWNLOADER_H__
#define __GTK_TEXTURE_DOWNLOADER_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdkenums.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_TEXTURE_DOWNLOADER (gdk_texture_downloader_get_type ())
GDK_AVAILABLE_IN_4_10
GType gdk_texture_downloader_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_10
GdkTextureDownloader * gdk_texture_downloader_new (GdkTexture *texture);
GDK_AVAILABLE_IN_4_10
GdkTextureDownloader * gdk_texture_downloader_copy (const GdkTextureDownloader *self);
GDK_AVAILABLE_IN_4_10
void gdk_texture_downloader_free (GdkTextureDownloader *self);
GDK_AVAILABLE_IN_4_10
void gdk_texture_downloader_set_texture (GdkTextureDownloader *self,
GdkTexture *texture);
GDK_AVAILABLE_IN_4_10
GdkTexture * gdk_texture_downloader_get_texture (const GdkTextureDownloader *self);
GDK_AVAILABLE_IN_4_10
void gdk_texture_downloader_set_format (GdkTextureDownloader *self,
GdkMemoryFormat format);
GDK_AVAILABLE_IN_4_10
GdkMemoryFormat gdk_texture_downloader_get_format (const GdkTextureDownloader *self);
GDK_AVAILABLE_IN_4_10
void gdk_texture_downloader_download_into (const GdkTextureDownloader *self,
guchar *data,
gsize stride);
GDK_AVAILABLE_IN_4_10
GBytes * gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self,
gsize *out_stride);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkTextureDownloader, gdk_texture_downloader_free)
G_END_DECLS
#endif /* __GTK_TEXTURE_DOWNLOADER_H__ */

View File

@@ -0,0 +1,41 @@
/* GTK - The GIMP Toolkit
*
* Copyright (C) 2023 Benjamin Otte
*
* 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 __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__
#define __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__
#include "gdktexturedownloader.h"
G_BEGIN_DECLS
struct _GdkTextureDownloader
{
/*< private >*/
GdkTexture *texture;
GdkMemoryFormat format;
};
void gdk_texture_downloader_init (GdkTextureDownloader *self,
GdkTexture *texture);
void gdk_texture_downloader_finish (GdkTextureDownloader *self);
G_END_DECLS
#endif /* __GTK_TEXTURE_DOWNLOADER_PRIVATE_H__ */

View File

@@ -43,7 +43,6 @@ void gdk_texture_do_download (GdkTexture
GdkMemoryFormat format,
guchar *data,
gsize stride);
GdkMemoryFormat gdk_texture_get_format (GdkTexture *self);
gboolean gdk_texture_set_render_data (GdkTexture *self,
gpointer key,
gpointer data,

View File

@@ -77,6 +77,7 @@ typedef struct _GdkContentFormats GdkContentFormats;
typedef struct _GdkContentProvider GdkContentProvider;
typedef struct _GdkCursor GdkCursor;
typedef struct _GdkTexture GdkTexture;
typedef struct _GdkTextureDownloader GdkTextureDownloader;
typedef struct _GdkDevice GdkDevice;
typedef struct _GdkDrag GdkDrag;
typedef struct _GdkDrop GdkDrop;

View File

@@ -23,7 +23,7 @@
#include <glib/gi18n-lib.h>
#include "gdktexture.h"
#include "gdkmemorytextureprivate.h"
#include "gdktexturedownloaderprivate.h"
#include "gdkprofilerprivate.h"
@@ -251,7 +251,8 @@ gdk_save_jpeg (GdkTexture *texture)
guchar *data = NULL;
gulong size = 0;
guchar *input = NULL;
GdkMemoryTexture *memtex = NULL;
GdkTextureDownloader downloader;
GBytes *texbytes;
const guchar *texdata;
gsize texstride;
guchar *row;
@@ -270,7 +271,7 @@ gdk_save_jpeg (GdkTexture *texture)
free (data);
g_free (input);
jpeg_destroy_compress (&info);
g_clear_object (&memtex);
g_clear_pointer (&texbytes, g_bytes_unref);
return NULL;
}
@@ -289,10 +290,11 @@ gdk_save_jpeg (GdkTexture *texture)
jpeg_mem_dest (&info, &data, &size);
memtex = gdk_memory_texture_from_texture (texture,
GDK_MEMORY_R8G8B8);
texdata = gdk_memory_texture_get_data (memtex);
texstride = gdk_memory_texture_get_stride (memtex);
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, GDK_MEMORY_R8G8B8);
texbytes = gdk_texture_downloader_download_bytes (&downloader, &texstride);
gdk_texture_downloader_finish (&downloader);
texdata = g_bytes_get_data (texbytes, NULL);
jpeg_start_compress (&info, TRUE);
@@ -304,7 +306,7 @@ gdk_save_jpeg (GdkTexture *texture)
jpeg_finish_compress (&info);
g_object_unref (memtex);
g_bytes_unref (texbytes);
g_free (input);
jpeg_destroy_compress (&info);

View File

@@ -21,10 +21,9 @@
#include <glib/gi18n-lib.h>
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkmemorytexture.h"
#include "gdkprofilerprivate.h"
#include "gdktexture.h"
#include "gdktextureprivate.h"
#include "gdktexturedownloaderprivate.h"
#include "gsk/gl/fp16private.h"
#include <png.h>
#include <stdio.h>
@@ -297,11 +296,12 @@ gdk_save_png (GdkTexture *texture)
png_info *info;
png_io io = { NULL, 0, 0 };
int width, height;
int y;
GdkMemoryFormat format;
GdkTextureDownloader downloader;
GBytes *bytes;
gsize stride;
const guchar *data;
int y;
GdkMemoryTexture *memtex;
GdkMemoryFormat format;
int png_format;
int depth;
@@ -370,11 +370,15 @@ gdk_save_png (GdkTexture *texture)
return NULL;
}
memtex = gdk_memory_texture_from_texture (texture, format);
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, format);
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
gdk_texture_downloader_finish (&downloader);
data = g_bytes_get_data (bytes, NULL);
if (sigsetjmp (png_jmpbuf (png), 1))
{
g_object_unref (memtex);
g_bytes_unref (bytes);
g_free (io.data);
png_destroy_read_struct (&png, &info, NULL);
return NULL;
@@ -394,8 +398,6 @@ gdk_save_png (GdkTexture *texture)
png_set_swap (png);
#endif
data = gdk_memory_texture_get_data (memtex);
stride = gdk_memory_texture_get_stride (memtex);
for (y = 0; y < height; y++)
png_write_row (png, data + y * stride);
@@ -403,7 +405,7 @@ gdk_save_png (GdkTexture *texture)
png_destroy_write_struct (&png, &info);
g_object_unref (memtex);
g_bytes_unref (bytes);
return g_bytes_new_take (io.data, io.size);
}

View File

@@ -21,10 +21,9 @@
#include <glib/gi18n-lib.h>
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkmemorytexture.h"
#include "gdkprofilerprivate.h"
#include "gdktexture.h"
#include "gdktextureprivate.h"
#include "gdktexturedownloaderprivate.h"
#include <tiffio.h>
@@ -260,11 +259,12 @@ GBytes *
gdk_save_tiff (GdkTexture *texture)
{
TIFF *tif;
int width, height, stride;
int width, height;
gsize stride;
const guchar *line;
const guchar *data;
GBytes *result = NULL;
GdkMemoryTexture *memtex;
GBytes *bytes, *result = NULL;
GdkTextureDownloader downloader;
GdkMemoryFormat format;
const FormatData *fdata = NULL;
@@ -292,9 +292,11 @@ gdk_save_tiff (GdkTexture *texture)
TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
memtex = gdk_memory_texture_from_texture (texture, fdata->format);
data = gdk_memory_texture_get_data (memtex);
stride = gdk_memory_texture_get_stride (memtex);
gdk_texture_downloader_init (&downloader, texture);
gdk_texture_downloader_set_format (&downloader, fdata->format);
bytes = gdk_texture_downloader_download_bytes (&downloader, &stride);
gdk_texture_downloader_finish (&downloader);
data = g_bytes_get_data (bytes, NULL);
line = (const guchar *)data;
for (int y = 0; y < height; y++)
@@ -302,7 +304,7 @@ gdk_save_tiff (GdkTexture *texture)
if (TIFFWriteScanline (tif, (void *)line, y, 0) == -1)
{
TIFFClose (tif);
g_object_unref (memtex);
g_bytes_unref (bytes);
return NULL;
}
@@ -314,7 +316,7 @@ gdk_save_tiff (GdkTexture *texture)
g_assert (result);
g_object_unref (memtex);
g_bytes_unref (bytes);
return result;
}

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

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;

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

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);
}

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,

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,

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)

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

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);
}

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;
}

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;

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__ */

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

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;

View File

@@ -19,6 +19,7 @@ gdk_macos_sources = files([
'gdkmacoseventsource.c',
'gdkmacoskeymap.c',
'gdkmacosmonitor.c',
'gdkmacospasteboard.c',
'gdkmacospopupsurface.c',
'gdkmacosseat.c',
'gdkmacossurface.c',

View File

@@ -43,6 +43,7 @@ gdk_public_sources = files([
'gdkseatdefault.c',
'gdksnapshot.c',
'gdktexture.c',
'gdktexturedownloader.c',
'gdkvulkancontext.c',
'gdksurface.c',
'gdkpopuplayout.c',
@@ -95,6 +96,7 @@ gdk_public_headers = files([
'gdkseat.h',
'gdksnapshot.h',
'gdktexture.h',
'gdktexturedownloader.h',
'gdktypes.h',
'gdkvulkancontext.h',
'gdksurface.h',
@@ -129,7 +131,7 @@ gdk_gresource_xml = configure_file(output: 'gdk.gresource.xml',
gdkresources = gnome.compile_resources('gdkresources',
gdk_gresource_xml,
source_dir: '.',
source_dir: meson.current_source_dir(),
c_name: '_gdk',
extra_args: '--manual-register',
)

View File

@@ -87,7 +87,7 @@ gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context
xdg_activation_token_v1_commit (token);
while (app_launch_data.token == NULL)
wl_display_dispatch_queue (display->wl_display, event_queue);
gdk_wayland_display_dispatch_queue (GDK_DISPLAY (display), event_queue);
xdg_activation_token_v1_destroy (token);
id = app_launch_data.token;

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

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);
}
}

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 = {
@@ -2684,3 +2694,17 @@ gdk_wayland_display_query_registry (GdkDisplay *display,
return FALSE;
}
void
gdk_wayland_display_dispatch_queue (GdkDisplay *display,
struct wl_event_queue *event_queue)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
if (wl_display_dispatch_queue (display_wayland->wl_display, event_queue) == -1)
{
g_message ("Error %d (%s) dispatching to Wayland display.",
errno, g_strerror (errno));
_exit (1);
}
}

View File

@@ -158,6 +158,9 @@ struct _GdkWaylandDisplayClass
gboolean gdk_wayland_display_prefers_ssd (GdkDisplay *display);
void gdk_wayland_display_dispatch_queue (GdkDisplay *display,
struct wl_event_queue *event_queue);
G_END_DECLS
#endif /* __GDK_WAYLAND_DISPLAY__ */

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