Compare commits

...

585 Commits

Author SHA1 Message Date
Luca Bacci 5b4d4b17ed WIP 2024-10-10 10:39:15 +02:00
Luca Bacci be2adb1838 Merge branch 'msys2-switch-to-ucrt64' into 'main'
MSYS2: Switch to UCRT64

See merge request GNOME/gtk!7812
2024-10-10 08:26:45 +00:00
Luca Bacci 0113fdc8d5 Merge branch 'gdk-win32-purge-globals' into 'main'
GDK/Win32: Drop most of the global variables

See merge request GNOME/gtk!7804
2024-10-10 08:26:30 +00:00
Matthias Clasen 53cbc64f41 Merge branch 'alatiera/sysprof-uri' into 'main'
gtkcssprovider: Only add the marker if the file is not null

See merge request GNOME/gtk!7807
2024-10-09 15:40:12 +00:00
Jordan Petridis 83387608ee gtkcssprovider: Use g_file_peek_path to get the uri for the sysprof marker
This avoids an extra allocation.

Additionally avoid calling it if file is already null.
2024-10-09 17:39:08 +03:00
Benjamin Otte a5b4d2b500 Merge branch 'typo-fix' into 'main'
Fix a typo

Closes #6984

See merge request GNOME/gtk!7816
2024-10-08 23:30:07 +00:00
ARAKHNID 1b83d87cf5 Fix a typo
Closes #6984
2024-10-08 13:41:04 -05:00
Emmanuele Bassi 6c2eb08b07 Merge branch 'wip/chergert/fix-a11y-default-attributes' into 'main'
gtk/accessibletext: handle NULL default values

Closes #7069

See merge request GNOME/gtk!7813
2024-10-08 18:10:26 +00:00
Christian Hergert ab1c85830c gtk/accessibletext: handle NULL default values
The default implementation for get_default_attributes() returns NULL for
both names and values yet the code which iterates them is assuming they
will never be NULL.

Since the interface implies that if the values are set, they will return
valid strings, make the default implementation do that.

Fixes: #7069
2024-10-08 10:41:19 -07:00
Luca Bacci d154decbb5 CI/MSYS2: Switch to UCRT64 2024-10-08 14:01:32 +02:00
Luca Bacci c7705f156a Rework test-msys2.sh a bit 2024-10-08 13:59:43 +02:00
Luca Bacci 20bdb0d7d5 Merge branch 'wgl-updates' into 'main'
WGL: Avoid using swap exchange on NVidia drivers

Closes #7019

See merge request GNOME/gtk!7776
2024-10-08 10:24:02 +00:00
Luca Bacci f840ae1337 WGL: Avoid using swap method exchange on NVidia drivers
It seems that NVidia sets PFD_SWAP_EXCHANGE / WGL_SWAP_EXCHANGE_ARB
on pixel formats but doesn't guarantee that the backbuffer age is
constantly 2. My guess is that they use swap exchange only to signal
usage of a flip present method.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/7019
2024-10-08 11:27:05 +02:00
Benjamin Otte 02feba87f2 Merge branch 'wip/otte/for-main' into 'main'
gpu: Remove warning

See merge request GNOME/gtk!7805
2024-10-07 10:20:37 +00:00
Benjamin Otte 220d7a3d5e picture: Queue a redraw when not resizing
When changing the code to do the resize only when the size changed, I
forgot to queue a draw when the size did not change.

Fixes: 5031f30f28
Related: !7786
2024-10-07 11:35:50 +02:00
Benjamin Otte 39686daa23 gpu: Remove warning
The warning gets triggered by rounding errors.

In particular when using fractional scales, the final tile may end up
not accurately matching the computed final value (in the example I was
debugging it was computing 1 vs 1.00000036 for the final tile index,
but that result computed a 0px wide tile size.
And for that tile size we hit that exit condition.
2024-10-07 11:31:34 +02:00
Chun-wei Fan b6269a3234 gdkevents-win32.c: Drop AeroSnap global variables
Put them into our GdkWin32Display under an appropriate sub-struct.
2024-10-07 14:37:40 +08:00
Chun-wei Fan 2879f6a99b gdkevents-win32.c: Drop event debug indent global variable
Tuck it as appropriate into our GdkWin32Display.
2024-10-07 14:37:40 +08:00
Chun-wei Fan 03a86b4667 GDK/Win32: Drop global variable on both shifts pressed 2024-10-07 14:37:39 +08:00
Chun-wei Fan 7eb96c39c5 GDK/Win32: Drop global variable tracking IME state
Tuck it into our GdkDisplay structure under an appropriate sub-struct.
2024-10-07 14:37:38 +08:00
Chun-wei Fan b4c5a7af69 GDK/Win32: Fold pen input global vars into GdkDeviceManagerWin32
This way, we just grab and set the values from there.
2024-10-07 14:37:38 +08:00
Chun-wei Fan d120aaf6ee GDK/Win32: Drop global variables from GdkKeys implementation
We get to create our GdkKey with a display as a property for free, so
just stuff the default keymap and keymap serial (to track IME state
changes and so) into our GdkWin32Display under an existing sub-struct
that is for holding these items.
2024-10-07 14:37:23 +08:00
Chun-wei Fan 004d787cb2 Gdk/Win32: Drop _gdk_display global variable
On Windows, we really only support a single GdkDisplay, so we can just
make the GdkDisplay that we obtain a property of our GdkDeviceManagerWin32
and GdkWin32Screen objects, and so we can just do away with the global
_gdk_display global variable.

This way, we can also drop the venerable gdkglobals-win32.c source file.
Yay!
2024-10-07 12:07:05 +08:00
Chun-wei Fan 7b554240f3 GDK/Win32: Drop modal surface-related global variables
Tuck them into GdkWin32Display as we track these operations.
2024-10-07 12:01:08 +08:00
Chun-wei Fan 7837f342e9 GdkDeviceManagerWin32: Drop global variables
Tuck the wintab global variables into the GdkDeviceManagerWin32
structure, and initialize and utilize items accordingly.
2024-10-07 12:01:07 +08:00
Chun-wei Fan 236139c78a gdkdisplay-win32.c: Drop debug_indent global variable
Instead, use [Set|Get]WindowLongPtr(), to store and retrieve that
value from the notification window HWND that we are using, as it
is where we are using that value.
2024-10-07 12:01:06 +08:00
Chun-wei Fan 789bb83b5a GDK/Win32: Drop surface tracking global variables
...including the list of modal surfaces and hashes of opened HWNDs for
various surfaces, and tuck them into GdkWin32Display.
2024-10-07 12:00:59 +08:00
Chun-wei Fan 0a65221721 GDK/Win32: Drop global variables in Direct Manipuation code
Tuck them into GdkWin32Display.
2024-10-07 11:56:21 +08:00
Chun-wei Fan b37947ff20 GDK/Win32: Drop global variables related to GdkDevice
Tuck the _win32_device_manager global variable into GdkWin32Display, and
drop the global variables that have to do with GdkDeviceManagerWin32.

Also improve how we query the WinPointer APIs from user32.dll, so that
we are sure that it is done once and only once.
2024-10-07 11:56:20 +08:00
Chun-wei Fan 0d4f827de8 GDK/Win32: Drop Clipdrop/DND global variables
Tuck the GdkWin32Clipdrop that we create in our GdkWin32Display, and
tuck the other associated global variables into GdkWin32ClipDrop and
GdkWin32Drag, as appropriate.

Also, since we are already registering "GDK_WORKER_THREAD_WAKEUP" as our
custom message to look for in our DND/clipboard ops, only register it
once, not twice, as it's not really necessary to do so since
RegisterWindowMessage() returns the same value for the same identifier
that is being used.,
2024-10-07 11:56:12 +08:00
Chun-wei Fan 1f52048e77 GDK/Win32: Drop global variable to track main thread
Instead, record the current thread in the GdkDisplay, under a structure
for DND items, which will hold other relevant Windows Clipbord/DND global
variables.

Add a new function in gdkdrag-win32.c to check whether the current
thread is (or is not) equivilant to the thread that is initiated when
the GdkDisplay is initialized (which also returns true if there is no
GdkDisplay that is associated with the GdkDrag in question).
2024-10-07 11:54:26 +08:00
Chun-wei Fan 7600d44995 GDK/Win32: Drop _gdk_ignore_input_core global variable
...and fold it into GdkWin32Display under pointer_device_items.
2024-10-07 11:50:21 +08:00
Chun-wei Fan 8bb806cd85 gdkmain-win32.c: Tuck global varianbles into local variables
...and use g_once_init_[enter|leave]() to mark that GDK did or did not
indeed successfully initialize COM and OLE2.
2024-10-07 11:39:04 +08:00
Chun-wei Fan 28aacf3db4 GDK/Win32: Drop input locale global variables
Rename gdkwin32id.c as gdkwin32misc.c.

Fold these items into GdkWin32Display, and also fold gdkproperty-win32.c
and gdkwin32langnoticiation.[c|h] into gdkwin32misc.c and gdkdisplay-win32.h as
appropriate.

This way, we get rid of few more global variables, and these items
should have been initialized (and registered with the system) when we
open a GdkWin32Display anyways.
2024-10-07 11:37:14 +08:00
Chun-wei Fan 95ad05181c gdksurface-win32.c: Drop a global variable
Use the gdk_win32_surface_parent_class that is given to us by
G_DEFINE_TYPE() instead of using a global variable to store up the
parent class of GdkWin32Surface.
2024-10-07 10:28:34 +08:00
Martin b4a54bb9cb Update Slovenian translation 2024-10-05 18:36:53 +00:00
Matthias Clasen 12dd5be649 Merge branch '3to4-separator' into 'main'
gtk4-builder-tool: Rewrite Gtk{H,V}Seperator

See merge request GNOME/gtk!7800
2024-10-05 14:52:30 +00:00
Guido Günther c86e45c432 gtk4-builder-tool: Rewrite Gtk{H,V}Seperator
One less UI element to worry about when migrating from GTK3.

Signed-off-by: Guido Günther <agx@sigxcpu.org>
2024-10-05 15:54:49 +02:00
Matthias Clasen 1ad5943cd8 Merge branch 'for-main' into 'main'
image tool: Better color state support

See merge request GNOME/gtk!7799
2024-10-05 13:38:07 +00:00
Matthias Clasen 34c69b2868 build: Don't use / in target names
It is unnecessary, and meson doesn't like it.
2024-10-05 08:55:50 -04:00
Matthias Clasen 28817b4bb2 image tool: Better color state support
Show cicp color states with their tuple.
2024-10-05 08:16:07 -04:00
Matthias Clasen b0acf2a7a8 Merge branch 'for-main' into 'main'
docs: Update GSK_GPU_DISABLE docs

See merge request GNOME/gtk!7798
2024-10-05 02:05:34 +00:00
Matthias Clasen 32d03a548e Drop some demos
The gtk4-icon-browser and gtk4-constraint-editor demos are basically
unmaintained, and not great showcases for GTK, so lets drop them.
2024-10-04 21:24:11 -04:00
Matthias Clasen fecadae80c docs: Update GSK_GPU_DISABLE docs
Add `repeat`.
2024-10-04 14:42:38 -04:00
Matthias Clasen 2d1367ccdc Merge branch 'wip/otte/this-looks-correct-but-is-it' into 'main'
listitemfactory: Don't rebind on position or selection changes

See merge request GNOME/gtk!7420
2024-10-04 18:32:08 +00:00
Matthias Clasen ac1c0d37c6 Merge branch 'gstreamer-no-gl' into 'main'
gstreamer: Fix gl context creation

See merge request GNOME/gtk!7796
2024-10-04 15:57:46 +00:00
Matthias Clasen ea6bcdbd3d gstreamer: Fix gl context creation
We may not have a surface (since realizing media streams is optional),
so use the display when creating a gl context.
2024-10-04 11:18:48 -04:00
Matthias Clasen fe83b06eaf Merge branch 'gbsneto/fix-a11y-nonwidget-recurse' into 'main'
atcontext: Only recurse parents for non-widget accessibles

Closes #7058

See merge request GNOME/gtk!7793
2024-10-04 13:19:07 +00:00
Matthias Clasen be5fd3d89f Merge branch 'gstreamer-no-gl' into 'main'
gstreamer: Make dmabufs work without GL

Closes #7048

See merge request GNOME/gtk!7787
2024-10-04 13:09:42 +00:00
Matthias Clasen bef38bd9c4 gstreamer: Tweak gl context handling
Just create the context when it is needed.
2024-10-04 08:21:58 -04:00
Georges Basile Stavracas Neto 06f08ea804 atcontext: Only recurse parents for non-widget accessibles
The original intent was to only realize parents recursively for
non-widget accessible objects. The implementation, however, always
try to realize parents. In the case of GtkStackPage, which is a
non-widget accessible with a widget accessible child, this breaks.

Only realize non-widget accessible parents recursively if the
current accessible is not a widget as well.

Closes https://gitlab.gnome.org/GNOME/gtk/-/issues/7058
Fixes 6074a18e3e
2024-10-04 09:19:57 -03:00
Matthias Clasen 79bb805a02 gstreamer: Simplify
Add a uses-gl property to our sink implementation, and use
it in the paintable code. This avoids juggling a second gl
context, with the risk of leaking it.
2024-10-04 07:49:07 -04:00
Matthias Clasen d70c005021 gstreamer: Improve caps handling
Separate out the caps for dmabuf, gl and memory and add them
when appropriate.
2024-10-04 07:44:20 -04:00
Matthias Clasen 9fc7d8e947 Restructure gtk_gst_paintable_video_renderer_create_video_sink
This code had too many early exits and was leaking GL contexts
and Gstreamer elements. Simplify.
2024-10-04 07:44:20 -04:00
Matthias Clasen b06ac9826c gstreamer: Use the default display if needed
Calling gtk_media_stream_realize is not mandatory, but we can
still try to make dmabufs happen. Tested by removing the realize
call from GtkVideo and using GDK_DISABLE=gl.
2024-10-04 07:44:20 -04:00
Matthias Clasen 94cacd79f9 gstreamer: Restructure gtk_gst_sink_propose_allocation
Split this clearly into two cases: dmabuf or gl memory.
2024-10-04 07:44:20 -04:00
Matthias Clasen 17d3631605 gstreamer: Make dmabufs work without GL
We only need a display to negotiate dmabuf formats. Pass that
directly, instead of getting the display of the GL context as
we did so far.

With this,

GSK_RENDERER=vulkan GL_DISABLE=gl gtk4-demo --run video_player

still uses dmabufs.

Related: #7048
2024-10-04 07:44:20 -04:00
Matthias Clasen 3b027cf466 Merge branch 'for-main' into 'main'
gpu: Add GSK_GPU_DISABLE=repeat

See merge request GNOME/gtk!7791
2024-10-04 00:48:58 +00:00
Matthias Clasen 5d4f2822d0 Fix testsuite setup
We no longer say GDK_DEBUG=gl-prefer-gl, we say GDK_DISABLE=gles-api.
2024-10-03 20:11:00 -04:00
Benjamin Otte 5a11ee7b9c gpu: Add GSK_GPU_DISABLE=repeat
This is useful for testing of repeat nodes - both performance
and conformance, and potentially even driver issues with GL_REPEAT.

We have code for manual repeating anyway, so adding a flag to force
always using it is easy.
2024-10-03 20:11:00 -04:00
Matthias Clasen 874410129e Merge branch 'fix-scrolled-window-criticals' into 'main'
scrolledwindow: Fix measuring non-overlay, always visible scrollbars

See merge request GNOME/gtk!7790
2024-10-03 17:52:16 +00:00
Sergey Bugaev 2cf1651235 scrolledwindow: Fix measuring non-overlay, always visible scrollbars
The last part of logic in gtk_scrolled_window_measure () that accounted
for scrollbars was handling the hscrollbar first, and vscrollbar second.
For each of them, it looked at the orientation we're being measured in,
and either added or MAX'ed scrollbar's size request into ours (or not,
depending on scrollbar policy and whether overlay scrolling is used).

In case of GTK_ORIENTATION_HORIZONTAL, this resulted in

    // MAX in hscrollbar width.
    minimum_req = MAX (minimum_req, min_scrollbar_width + sborder.left + sborder.right);
    // Add in vscrollbar width.
    minimum_req += min_scrollbar_width;

whereas for GTK_ORIENTATION_VERTICAL, it was

    // Add in hscrollbar height.
    minimum_req += min_scrollbar_height;
    // MAX in vscrollbar height.
    minimum_req = MAX (minimum_req, min_scrollbar_height + sborder.top + sborder.bottom);

The former is correct and the latter is wrong: we should be adding the
size requests of the scrollbars together, and MAX'ing them with the
content size request.

Fix this by refactoring the logic to first handle the MAX'ing, and then
the addition.

This fixes the following criticals:

Gtk-CRITICAL **: 17:26:51.406: Allocation height too small. Tried to allocate 15x31, but GtkScrollbar 0x2a00fac0 needs at least 15x46.

that were happening when all of:
- scrollbar policy was set to ALWAYS,
- overlay scrolling was disabled,
- the scrollable child was really small.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-10-03 19:04:15 +03:00
Matthias Clasen ad2221ce29 Merge branch 'fix-filechooser-crash' into 'main'
window: Fix crash when unexporting unrealized window

See merge request GNOME/gtk!7769
2024-10-03 15:53:44 +00:00
Sergey Bugaev 6dd0be2f06 printdialog: Call gtk_window_unexport_handle
We need to track the handle and properly unexport it.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-10-03 17:14:11 +03:00
Sergey Bugaev 2103ab99a5 window: Fix crash when unexporting unrealized window
It is possible that the window gets unrealized while a handle to its
surface is exported. This, naturally, invalidates the handle, so there
is nothing left to unexport. We should just note that and do nothing,
rather than crashing.

Fixes a crash when a portal-backed file dialog parented to a window is
closed after the window it was parented to.

Reported-by: Ivan Molodetskikh <yalterz@gmail.com>
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-10-03 17:14:11 +03:00
Sergey Bugaev d7ab7e9628 window: Fix a typo
Fortunately, it didn't impact string length.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-10-03 17:14:11 +03:00
Matthias Clasen 3d7ac47e5e Merge branch 'gbsneto/atspi-socket-realize' into 'main'
atcontext: Always realize non-widget accessibles

See merge request GNOME/gtk!7784
2024-10-03 09:46:40 +00:00
Chun-wei Fan c373e2c76b Merge branch 'gdk-win32-rename' into 'main'
GDK/Win32: Rename instances of "window" as in the GTK+-3.x-era GdkWindow as appropriate

See merge request GNOME/gtk!7738
2024-10-03 05:44:07 +00:00
Matthias Clasen ec3b27bb68 Merge branch 'for-main' into 'main'
Don't draw transparent fillers

See merge request GNOME/gtk!7788
2024-10-03 03:43:54 +00:00
Benjamin Otte 5b87dba1a3 Merge branch 'wip/otte/for-main' into 'main'
picture: Only queue_resize() if necessary

See merge request GNOME/gtk!7786
2024-10-03 01:10:53 +00:00
Matthias Clasen 12dcaf1e7a Don't draw transparent fillers
Repeat nodes take child bounds that let us achieve the desired
spacing without resorting to transparent fillers.
2024-10-02 21:05:21 -04:00
Benjamin Otte 5031f30f28 picture: Only queue_resize() if necessary
When setting a new paintable, we don't need to queue_resize() when it's
the same size as the old paintable.

This is especially useful when pictures are used in a listview or
gridview and different rows display images of the same size.
2024-10-03 02:56:12 +02:00
Matthias Clasen ad465e81aa Merge branch 'for-main' into 'main'
ci: Stop using catch

See merge request GNOME/gtk!7785
2024-10-03 00:41:40 +00:00
Matthias Clasen 39374c7209 gtk4-demo: Make demos standalone
Making the demo windows transient and modal makes gnome-shell
treat them like dialogs, which is not right.
2024-10-02 19:15:31 -04:00
Matthias Clasen 170a1cd941 ci: Stop using catch
It is useful to track down mysterious crashes in ci, but it causes
sporadic test failures, so disable it for now, until we have another
mysterious crash.
2024-10-02 19:15:31 -04:00
Georges Basile Stavracas Neto 6074a18e3e atcontext: Always realize non-widget accessibles
Upon joining the a11y tree. And do so recursively, as long as the parent
is also not a widget.

As for the explanation, please grab a mug of your favorite drink. It's
a little complicated.

GTK realizes AT contexts in 3 situations:

 1. When it's a toplevel, it's realized unconditionally
 2. When the widget is focused
 3. When the accessible is appended to a realized parent

Most importantly, GTK lazily realizes accessibles, and does not realize
child accessibles recursively.

Clearly, conditions 1 and 2 only ever happen for GtkWidgets, which are
accessible objects themselves. These two conditions will handle the vast
majority of cases of apps and platform libraries.

However, there are non-widget accessibles out there. GTK itself offers a
non-widget accessible implementation - GtkAtspiSocket - which is used by
WebKitGTK.

Now, let's look at WebKitGTK use case. It'll demonstrate the problem
nicely.

WebKitGTK creates the GtkAtspiSocket object *after* loading most of the
page. At this point, there are 2 possibilities:

 1. The web view widget is focused. In this case, the AT context of the
    web view is realized, and GTK will realize the GtkAtspiSocket when
    it is added to the a11y tree (condition 3 above).

 2. The web view widget is *not* focused. At some point the user focuses
    the web view, and GTK will realize the AT context of the web view.
    But remember, GTK does not realize child accessibles! That means
    GtkAtspiSocket won't be realized.

This example demonstrates a general problem with non-widget accessibles:
non-widget accessibles cannot trigger conditions 1 and 2, so they're
never realized. The only way they're realized in if they happen to be
added to an already realized accessible (condition 3).

To fix that, the following is proposed: always realize non-widget
accessibles, and also of their non-widget accessible parents. This is
not ideal, of course, as it might generate some D-Bus chattery, but GTK
does not have enough information to realize these objects at more
appropriate times.
2024-10-02 16:07:30 -03:00
Georges Basile Stavracas Neto 5d5b612630 atcontext: Factor out some code
Move the code that realizes an AT context if the parent is realized,
into to a separate function. This will make the next patch easier to
read.

No functional changes.
2024-10-02 14:51:33 -03:00
Matthias Clasen 5942252175 Merge branch 'scrolling-underline-demo' into 'main'
gtk4-demo: Add another scrolling case

See merge request GNOME/gtk!7781
2024-10-02 17:32:22 +00:00
Benjamin Otte 9a3898fe89 Merge branch 'wip/otte/for-main' into 'main'
dmabuf: Change a debug message

See merge request GNOME/gtk!7782
2024-10-02 12:36:02 +00:00
Benjamin Otte c6a3efaf70 dmabuf: Unify initialization debug messages
... and print if a format is advertised.

We now use the same style of message and use the term "advertise" for
formats that will be available via GdkDisplay::dmabuf-formats and
"supports" for formats the backend pretends it can handle but don't
want to advertise them.
2024-10-02 13:39:48 +02:00
Benjamin Otte 9870234294 dmabuf: Change a debug message
Instead of only printing the advertised dmabuf formats, print all
supported ones. This is now useful information because we will try to
use them when downloading.

Fixes me looking like I don't know what I'm talking about on IRC when
claiming that llvmpipe can't do dmabufs, because it only supports linear
ones and we didn't print those.
2024-10-02 13:39:48 +02:00
Matthias Clasen 64ecb972cf gtk4-demo: Add another scrolling case
Add a case for text with various underlines. In particular error
underlines, since these are more complicated and use repeat nodes
and offscreens.
2024-10-02 07:21:41 -04:00
Matthias Clasen ded6d400d7 gtk-demo: Make scrolling benchmark resizable
The small window does not really tax our renderer much. Make it
resizable, so we can test fullscreen scrolling.
2024-10-02 07:20:36 -04:00
Chun-wei Fan 979a37d3f7 GDK/Win32: Rename _gdk_win32_get_window_rect()
... to gdk_win32_get_surface_hwnd_rect(), so that things are a bit
clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 270e6165f4 GDK/Win32: Rename GtkShowWindow() to GtkShowSurfaceHWND()
Makes this function a bit clearer on what is being done.
2024-10-02 12:52:44 +08:00
Chun-wei Fan df51d474fc GDK/Win32: Rename "window" for event handling code
We want to make the distinction between GdkSurface's and native Windows
HWNDs clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 1e0ab6f249 gdkprivate-win32.h: Rename "window" as needed
We want to make the distinction between GdkSurface's and native Windows
HWNDs clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan deb4de6332 gdkvulkancontext-win32.c: Rename "window" as needed
We want to make the distinction between GdkSurface's and native Windows
HWNDs clear, and we don't want to confuse between GdkSurface's and
Vulkan surfaces.
2024-10-02 12:52:44 +08:00
Chun-wei Fan b4c7dd770c GDK/Win32: Rename "window" for DND/clipboard code
We want to make the distinction between GdkSurface's and native Windows
HWND clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 7488644176 gdkdisplay-win32.c: Rename "window" as appropriate
We want to make the distinction between GDK surfaces and the native
(underlying) Windows HWNDs clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 9ed7cecd42 GDK/Win32: Rename "window" in GdkDevice/GdkDeviceManager code
Make the distinction between GdkSurfaces and the underlying native
Windows HWND clearer in the code and in the comments.
2024-10-02 12:52:44 +08:00
Chun-wei Fan df36ab3f93 GDK/Win32: Rename "window" items in Cairo context code
Make the distinction between GDK surfaces and native Windows HWNDs
clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 7e4fdea71b GDK/Win32: Rename "window" in gdksurface-win32.* code
In order to help us in our refactoring, make the distinction between Gdk
surfaces and native Win32 HWND clearer in terms of the variables that we
used, and in the comments in the code.

Also, group forward function prototype declarations in one place, and
drop some unneeded items in gdkprivate-win32.h to fold them into
gdksurface-win32.c, as they are only used there.
2024-10-02 12:52:44 +08:00
Matthias Clasen ea8062e86a Merge branch 'for-main' into 'main'
gsk: Allow Vulkan software rendering as fallback

See merge request GNOME/gtk!7780
2024-10-02 01:31:05 +00:00
Matthias Clasen c4efe7709b Drop GDK_VULKAN_DEVICE support
We don't need our own mechanism for device selection; mesa has a
Vulkan layer that works perfectly fine for this purpose; just set
MESA_VK_DEVICE_SELECT.
2024-10-01 21:00:16 -04:00
Matthias Clasen fdea496883 gsk: Allow Vulkan software rendering as fallback
There is no reason to exclude lavapipe when we accept llvmpipe,
and lavapipe has the advantage that it supports dmabufs.
2024-10-01 20:57:49 -04:00
Matthias Clasen 60878e4186 Merge branch 'for-main' into 'main'
gsk: Prefer ngl over cairo

See merge request GNOME/gtk!7779
2024-10-02 00:45:13 +00:00
Matthias Clasen 02297138f3 gsk: Tweak renderer selection debug spew
Print a message for every get_renderer function that returns
FALSE, so the debug spew lets us get a clear picture of what
possibilities were tried.
2024-10-01 20:12:17 -04:00
Benjamin Otte 6603e02beb Merge branch 'wip/otte/for-main' into 'main'
Revert "tools: Drop support for the gl renderer"

See merge request GNOME/gtk!7778
2024-10-01 23:57:20 +00:00
Matthias Clasen bfb7573810 gsk: Prefer ngl over cairo
Now that the gl renderer is no longer in our fallback sequence, use
ngl instead. With current ngl, llvmpipe is still better than cairo.
2024-10-01 19:42:08 -04:00
Benjamin Otte 6847c3469d testsuite: Keep bounds for clip tests
The hope here is that it makes clip tests more reproducible because the
coordinates in device pixels are still the same as before.
2024-10-02 01:26:24 +02:00
Benjamin Otte 7a1e5b4418 compare-render: Add a KEEP_BOUNDS flag
If that flag is set, we keep the bounds of the original node when
rendering the modified node.

Gets around the replay test having to draw a transparent color node to
ensure the same bounds.
2024-10-02 01:26:24 +02:00
Benjamin Otte 76980e10a0 Revert "tools: Drop support for the gl renderer"
This reverts commit fd02afa2e4.

We don't want to remove the GL renderer from our tools yet, because we
use those tools for manual testing and having it available is useful.

In particular, reinstate the GL renderer for rendernode-tool benchmark.
2024-10-02 01:25:30 +02:00
Matthias Clasen 34f4a06691 Merge branch 'gl-renderer-memorytexture-test' into 'main'
Stop using a gl renderer in the memorytexture text

See merge request GNOME/gtk!7773
2024-10-01 21:29:29 +00:00
Matthias Clasen 2dea5ae958 Merge branch 'for-main' into 'main'
inspector: Plug a  memory leak

See merge request GNOME/gtk!7775
2024-10-01 15:52:05 +00:00
Matthias Clasen 5856716188 inspector: Plug a memory leak
Found by code inspection of all the places where we use texture
builders.
2024-10-01 08:59:52 -04:00
Matthias Clasen 1c4a0dae62 Merge branch 'gst-texture-builder-leak' into 'main'
gst: Don't leak texture builders

See merge request GNOME/gtk!7774
2024-10-01 12:20:48 +00:00
Matthias Clasen b7fba6298f gst: Don't leak texture builders
Found by code inspection. The leak was introduced in 4707784755.

Might help for #4184
2024-10-01 07:18:32 -04:00
Matthias Clasen 5ce196fe9f Rename memory texture tests from ngl to gl 2024-09-30 21:59:59 -04:00
Matthias Clasen c31c89c794 Drop gl renderer tests from memory texture test 2024-09-30 21:55:33 -04:00
Matthias Clasen 1eb8c3ea34 tests: Add ngl-released in memory texture test
This is parallel to the gl-released method, but for ngl.
2024-09-30 21:52:16 -04:00
Matthias Clasen b2414b1ecd Merge branch 'for-main' into 'main'
gtk4-demo: Drop the glshader demos

See merge request GNOME/gtk!7771
2024-10-01 01:47:09 +00:00
Matthias Clasen fd3dfaf2c3 Merge branch 'dmabuf-import-fixup' into 'main'
gl: Treat internal textures as special case

See merge request GNOME/gtk!7772
2024-10-01 01:46:44 +00:00
Benjamin Otte 43a6c8c5f5 gl: Treat internal textures as special case
Treat external as the normal case, and only try importing dmabufs
as non-external images if their format is on the internal formats
list.

Also add internal linear formats to the internal formats list.

This fixes an issue where AR24:0 dmabufs were imported as external
textures, causing some of the compare tests to fail.
2024-09-30 21:16:41 -04:00
Matthias Clasen 3789191853 docs: Stop mentioning the gl renderer
It is going away.
2024-09-30 19:24:42 -04:00
Matthias Clasen eb4fb2af0e gsk: Stop falling back to the gl renderer
The GL renderer is going away. For now, it is still possible
to use it explicitly, with GSK_RENDERER=gl.
2024-09-30 19:22:54 -04:00
Matthias Clasen fd02afa2e4 tools: Drop support for the gl renderer
The GL renderer is going away in 4.18.
2024-09-30 19:22:54 -04:00
Matthias Clasen 55bb77cffc tests: Use the ngl renderer in one more place 2024-09-30 19:22:54 -04:00
Matthias Clasen 119ba5844f testsuite: Drop glshader tests
And drop the gl renderer test here, but add ngl and Vulkan
equivalents.
2024-09-30 19:22:54 -04:00
Matthias Clasen 9b2b5ebb65 gsk: Stop supporting gl shaders
The GL shader code uses the GL renderer for compilation, and that
renderer is going away.
2024-09-30 19:22:54 -04:00
Matthias Clasen 1624455a32 gsk: Use the ngl renderer for serializing to png
This is a step towards dropping the GL renderer.
2024-09-30 18:58:33 -04:00
Matthias Clasen d483883f38 node-editor: Use NGL for exporting images
This is a step towards dropping the GL renderer.
2024-09-30 18:58:33 -04:00
Matthias Clasen 0dc0bea1d5 gtk4-demo: Drop the glshader demos
The GL renderer will be going away in 4.18, and with that, shader
nodes will stop working for good. It is time to start preparing
for that.
2024-09-30 18:58:33 -04:00
Matthias Clasen 55e31b972c Merge branch 'dmabuf-failable-download' into 'main'
Make gdk_dmabuf_downloader_download failable

See merge request GNOME/gtk!7720
2024-09-30 22:41:57 +00:00
Matthias Clasen 1013874de8 gpu: Drop get_dmabuf_formats
This vfunc is no longer needed.
2024-09-30 18:37:20 -04:00
Matthias Clasen c397460c11 Drop gdk_dmabuf_downloader_supports
It is not used anymore.
2024-09-30 18:37:20 -04:00
Matthias Clasen ff0045b8c9 dmabuftexture: Stop having a fixed downloader
Change things from picking a download method at creation time to
trying all methods at download time until one succeeds.
2024-09-30 18:37:20 -04:00
Matthias Clasen d0b409d349 Make gsk_gpu_frame_download_texture return status
Importing a dmabuf can fail, even if the format is supported
in princicple, In these cases, gsk_gpu_frame_download_texture
will return FALSE.
2024-09-30 18:37:20 -04:00
Matthias Clasen c0cb10262d Make gdk_dmabuf_download_mmap return status
Make this function return whether it was successful, and only emit
a debug message if we succeeded. In particular, make it return FALSE
if the dmabuf format is not linear.
2024-09-30 18:37:20 -04:00
Matthias Clasen 279a5f7825 Make gdk_dmabuf_downloader_download failable
This will enable us to try multiple downloaders in a row.
2024-09-30 18:37:20 -04:00
Matthias Clasen 6fa87d4f37 gsk renderer: Add a debug message
Add a debug message so we can see what downloaders are used
for dmabufs.
2024-09-30 18:37:20 -04:00
Matthias Clasen fe35daaf34 Merge branch 'wip/otte/dont-download-the-upload-of-the-download' into 'main'
gpu: Don't use copies for dmabuf downloads

Closes #7046

See merge request GNOME/gtk!7770
2024-09-30 22:30:58 +00:00
Benjamin Otte c3b836951a gl: ref the previous context
The current context might be the last reference to the context, which
would make it go away when the renderer calls make_current().

See commit 0fa2ae48d4 for a similar case.
2024-09-30 23:54:08 +02:00
Matthias Clasen ec10f1fe16 gsk: Don't lose context during download
When we use download in the middle of an upload operation (or the
other way around), we may end up making a different GL context
current. The downloader code is reponsible for reestablishing
the previous context when it is done. The old GL renderer was
doing that, NGL wasn't, until now.
2024-09-30 23:49:59 +02:00
Benjamin Otte ae741a06c0 gpu: Compare fourccs, not GdkMemoryFormat
For dmabufs, the format is not an exact description of the data, it only
gives the closest memory format for a given fourcc.
This of course means that multiple different fourccs may report the same
format.

So when deciding if we need to copy the image to get the right data to
download, we need to check if the fourcc is correct, not if the format
is.

Related: #7046
2024-09-30 22:14:38 +02:00
Benjamin Otte 754c9cb323 gpu: Don't use copies for dmabuf downloads
When we want to download a dmabuf, we want to download the actual
dmabuf.

If we just grab the cached image and use that, we might get the
(reuploaded) copy of the dmabuf. This happens when this renderer
doesn't support downloading this dmabuf but has used it before.

Worse, this is a reentrancy issue, where this renderer is trying to
render the dmabuf and has already scheduled the upload but the upload
has not finished. We will then download from an empty image, which is
very wrong.

The way to check that we have the actual dmabuf is a bit brittle, but it
should work.

Fixes #7046
2024-09-30 19:52:30 +02:00
Benjamin Otte a3683a080b Merge branch 'wip/otte/global-globals' into 'main'
ngl: Use a single buffer for globals

See merge request GNOME/gtk!7753
2024-09-30 17:09:52 +00:00
Matthias Clasen 0673d74986 Merge branch 'for-main' into 'main'
Cosmetics

See merge request GNOME/gtk!7768
2024-09-30 13:53:51 +00:00
Matthias Clasen 8c46df425e Merge branch 'default-cursor-xdg' into 'main'
wayland: Look for default cursor theme in XDG directories

See merge request GNOME/gtk!7766
2024-09-30 13:27:57 +00:00
Ilya Fedin ff78e1888b wayland: Look for default cursor theme in XDG directories
Currently it's looked up only in /usr/share what is a problem for non-FHS distros like NixOS
2024-09-30 15:50:11 +04:00
Matthias Clasen f2f219f304 Cosmetics
Make the debug message match the rest: FORMAT:MODIFIER.
2024-09-30 07:40:48 -04:00
Matthias Clasen bb46edcc21 dmabuf: Initizalize some memory
I've seen valgrind complain about external_only being uninitialized
after the call, when using llvmpipe. Better be safe than sorry, and
initialize these arrays.
2024-09-30 06:55:57 -04:00
Matthias Clasen 24173e3f93 Cosmetics
No point in having an early return since EGL_NO_IMAGE is what we
want to return anyway.
2024-09-30 06:50:20 -04:00
Anders Jonsson ec73bcb05b Update Swedish translation
(cherry picked from commit 82f08089f1)
2024-09-29 22:16:13 +00:00
Juliano de Souza Camargo 6c74c9c970 Update Brazilian Portuguese translation
(cherry picked from commit 1610ecbbac)
2024-09-29 16:30:00 +00:00
Matthias Clasen c9c35ae41d Merge branch 'for-main' into 'main'
testsuite: Don't assert more than guaranteed

See merge request GNOME/gtk!7763
2024-09-29 14:33:35 +00:00
Matthias Clasen 95cea06462 Revamp GDK_VULKAN_DEVICE slightly
Support a "help" value, as we do for other env vars.
2024-09-29 09:54:24 -04:00
Matthias Clasen d01ca53bde testsuite: Don't assert more than guaranteed
Compositors don't guarantee that there's any physical devices
around to correspond to the input capabilities.

This was found running the tests against mutter headless.
2024-09-29 09:30:56 -04:00
Matthias Clasen 3d3cafefc8 Merge branch 'clear-settings-portal' into 'main'
wayland: Clear settings_portal when going to fallback with no portal settings

See merge request GNOME/gtk!7756
2024-09-29 13:25:15 +00:00
Matthias Clasen 86cdb0ceb2 Merge branch '7040-improve-video-input-stream-error-message' into 'main'
gstmediafile: improve error message when there is an input stream.

Closes #7040

See merge request GNOME/gtk!7747
2024-09-29 13:22:28 +00:00
nee 0c97c86573 gstmediafile: improve error message when there is an input stream.
Previously it was unclear why passing an input stream would crash a video,
unless you went into the source and read it.

This adds a clarifying message that only file based media files are supported.
2024-09-29 13:41:17 +02:00
Benjamin Otte 10fa570195 Merge branch 'wip/otte/for-main' into 'main'
gpu: Consider scissor when intersecting with recangle

Closes #7044

See merge request GNOME/gtk!7762
2024-09-29 04:55:12 +00:00
Benjamin Otte e18c553457 gpu: Consider scissor when intersecting with recangle
The clip might be different from the scissor due to incompatible
intersections.

But the resulting intersection might be fully clipped, so we should
consider it.

Testsuite with longer explanation attached.

Fixes #7044
2024-09-29 06:29:47 +02:00
Matthias Clasen 187763d286 Merge branch 'for-main' into 'main'
wayland: Bring back the pointer viewporter

See merge request GNOME/gtk!7761
2024-09-29 00:21:36 +00:00
Fran Dieguez e6ae136de0 Update Galician translation
(cherry picked from commit 8360bfc772)
2024-09-28 21:50:23 +00:00
Matthias Clasen 81efb63073 emojichooser: insert before closing the popover
Doing otherwise risks that the focus is moved back to the entry,
causing everything to be selected, and then replaced by the Emoji
we insert. Which is not the desired effect!
2024-09-28 14:53:12 -04:00
Matthias Clasen cbadb1ed8e Merge branch 'pointer-viewporter-again' into 'main'
wayland: Bring back the pointer viewporter

See merge request GNOME/gtk!7760
2024-09-28 16:13:06 +00:00
Matthias Clasen 103e98f570 Merge branch 'default-cursor-size' into 'main'
wayland: Use the same default cursor size as gsettings schema

Closes #7043

See merge request GNOME/gtk!7754
2024-09-28 14:32:48 +00:00
Matthias Clasen 3768c751c5 wayland: Improve our cursor size selection
When picking a cursor image size for a given size, look for sizes
that do better when scaled by the viewporter:
- exact size
- twice the size
- closest larger size
- closest size
2024-09-28 10:26:42 -04:00
Matthias Clasen e42014573a wayland: Bring back the pointer viewporter
This was a thinko in 403da9a2d5. We have the cursor
image in device pixels, but we still need to apply the viewporter
to inform the compositor about the desired pointer size in
application pixels.
2024-09-28 10:01:04 -04:00
Ilya Fedin a9f1ff471b wayland: Use the same default cursor size as gsettings schema
Fixes: #7043
2024-09-28 16:50:05 +04:00
Ilya Fedin e26a1bbda9 wayland: Clear settings_portal when going to fallback with no portal settings
All other code paths with goto fallback clear it, this makes the behavior consistent with them
2024-09-28 16:41:13 +04:00
Matthias Clasen b2ae7a2448 Merge branch 'for-main' into 'main'
Cosmetics

See merge request GNOME/gtk!7751
2024-09-28 01:16:53 +00:00
Matthias Clasen cb682c759d Cosmetics
No newlines in g_warning.
2024-09-27 20:54:46 -04:00
Benjamin Otte b154c9caf4 ngL: Use a single buffer for globals
Instead of using glBuffer(Sub)Data() every time we set new globals, fill
a single buffer with all the globals and use glBindBufferRange() on that
buffer to set the current globals.
2024-09-28 02:25:40 +02:00
Matthias Clasen 523fca21e9 Merge branch 'wip/kabus/a11y-present-label' into 'main'
label: Don't set a11y label when role is presentation

See merge request GNOME/gtk!7750
2024-09-27 17:34:39 +00:00
Matthias Clasen 73ddde6eda Merge branch 'cursor-size-again' into 'main'
inspector: Tweak the cursor size control

See merge request GNOME/gtk!7749
2024-09-27 17:29:41 +00:00
Matthias Clasen 403da9a2d5 wayland: Redo cursor loading
Stop using a viewporter to scale cursors. Instead, just pass
the surface scale to the cursor loading code, and take the
buffer dimensions and hotspot that it returns, unchanged.

This avoids problems with cursor themes like Breeze, where
buffer dimensions are different from the nominal cursor size.

Make the cursor loading code take a floating point scale,
and return the closest sized cursor that it can find.
2024-09-27 12:37:25 -04:00
Khalid Abu Shawarib fb6f211869 label: Don't set a11y label when role is presentation
This resolves issue with labels of model buttons being set to
presentation a11y role but still have a11y label.

See: https://gitlab.gnome.org/GNOME/gtk/-/blob/b7e5a79468312706e7465caed2cd55badbee432d/gtk/gtkmodelbutton.c?page=2#L1539
2024-09-27 19:15:41 +03:00
Matthias Clasen c358606a46 inspector: Tweak the cursor size control
Useful for debugging our cursor loading code.
2024-09-27 12:11:31 -04:00
Matthias Clasen b7e5a79468 Merge branch 'listbox_tab_behavior' into 'main'
listbox: Introduce tab-behavior property

See merge request GNOME/gtk!7739
2024-09-27 11:42:14 +00:00
Benjamin Otte 06bcb0ee47 Merge branch 'wip/otte/ngl-downloader' into 'main'
Use NGL renderer for dmabuf downloads

See merge request GNOME/gtk!7741
2024-09-26 20:58:01 +00:00
Matthias Clasen 58ce0a39dc dmabuf: Use the ngl downloader
It works, now and is faster than the old GL downloader.

Playing the Barbie trailer @ 4k with hardware decoding but the Cairo
renderer on a 4k screen:

downloader  windowed  fullscreen
GL          12fps     19fps
NGL         16fps     29fps
Vulkan      16fps     29fps
no dmabufs  12fps     19fps
2024-09-26 22:06:18 +02:00
Benjamin Otte 6d3c333208 gpu: Actually ensure a downloadable dmabuf
For some formats, we could not download the dmabuf directly - in
particular YUV formats.
For those, do a copy on the GPU into the correct format.

While we're at it, also check the desired format and colorstate and if
they don't match, do the conversion on the GPU instead of using
gdk_memory_convert().
Reserve the CPU conversion for situations where the GPU doesn't support
the final format - like for example G8A8 (or often also RGB16).
2024-09-26 22:06:18 +02:00
Benjamin Otte 62c3923e5a gpu: Handle all colorstates in cache
Make gsk_gpu_cache_cache_texture_image() API safer by accepting all
color states as input and just not caching the images for colorstates we
don't care about.
2024-09-26 22:06:18 +02:00
Benjamin Otte 3be8b1d927 gpu: Check if the image is cached in right colorstate
This is most likely not a very likely check, but just to be sure, check
if the image exists in the cache in the desired colorstate already.
2024-09-26 22:06:18 +02:00
Benjamin Otte 27a61e221f gpu: Shuffle function arguments
Instead of passing down the depth and extracting format/srgb from it at
the end, extract format/srgb in the nodeprocessor and pass it down.

This allows creating offscreens for weirder formats in the future.
2024-09-26 22:06:18 +02:00
Benjamin Otte 52df3481d6 gpu: Add a gsk_gpu_download_into_op()
... and use it for the dmabuf downloader

Splits the download op into 2 separate ops: One for downloading textures
and one for downloading into preallocated memory.

The download into memory is the fallback for the texture downloading op,
so they need to share code.

But keeping them separate ensures that the different codepaths for
dmabuf download and render_texture() don't get mixed up in weird ways
that potentially call into each other.

By passing the emory down into the op we can also avoid an extra memcpy
which can lead to quite large speedups for big textures.
2024-09-26 22:06:17 +02:00
Benjamin Otte ccb993d87b gpu: Split out a function
I want to use it from elsewhere in future commits.
2024-09-26 22:06:17 +02:00
Benjamin Otte 5fdaa4a232 gl: Move function
We want to share the texture download function with the renderers, so
they can download textures without needing to wrap them in a
GdkGLTexture.

Move it into gdkglcontext.c for that purpose.
2024-09-26 22:06:17 +02:00
Benjamin Otte 8b166dff74 gltexture: Split out a function
No functional changes
2024-09-26 22:06:17 +02:00
Benjamin Otte f6b3f321a4 dmabuf: Refactor GPU renderer
We don't want to ever try fallback uploads in the dmabuf path. So
refactor gdk_frame_upload_texture() to have a flag that turns that off.
2024-09-26 22:06:17 +02:00
Benjamin Otte a314143a83 gpu: Pass color state to download op
Previously we were always implicitly using SRGB, which was correct more
or less by accident.
2024-09-26 22:06:17 +02:00
Benjamin Otte 6c7abf425a Merge branch 'wip/otte/for-main' into 'main'
testsuite: Remove leftover test.in files

See merge request GNOME/gtk!7744
2024-09-26 18:47:49 +00:00
Matthias Clasen b11e45762b Merge branch 'cursor-update-now' into 'main'
wayland: Make cursor changes effective immediately

Closes #6909

See merge request GNOME/gtk!7745
2024-09-26 18:07:28 +00:00
Benjamin Otte d041a681a5 Merge branch 'wip/otte/drop-gles2' into 'main'
Drop support for GLES 2 and GL < 3.3

See merge request GNOME/gtk!7743
2024-09-26 17:51:09 +00:00
Matthias Clasen d22d2f77a6 wayland: Make cursor changes effective immediately
When the cursor theme changes, update the cursors of our surfaces.

Fixes: #6909
2024-09-26 12:53:38 -04:00
Benjamin Otte 7458461d06 gl: Remove unpack-subimage checks
GLES 3.0 supports it unconditionally.
2024-09-26 18:41:13 +02:00
Benjamin Otte 283615936b gl: Remove check for half-float vertex data
All supported versions require it after we dropped support for GLES 2.
2024-09-26 18:41:13 +02:00
Benjamin Otte 2274bca95b gl: Require support for GLsync
It's supported by GL >= 3.2 and GLES >= 3.0 and we require both now.
2024-09-26 18:41:13 +02:00
Benjamin Otte f8b4deeac0 gdk: Drop support for GL < 3.3
The new renderers need features from GL 3.3 and GLSync is very required
these days, too.

Note that this is about GL proper, not GLES.
2024-09-26 18:41:13 +02:00
Benjamin Otte afa503c2e0 gl: Remove GLES 2 specific parts of format checks 2024-09-26 18:41:13 +02:00
Benjamin Otte 105f5f1137 gpu: Remove check for GLES 2
GLES 2 is no longer supported.
2024-09-26 18:41:13 +02:00
Benjamin Otte b83ad60a1f gdk: Drop support for GLES 2
We now require GLES 3.
2024-09-26 18:41:13 +02:00
Benjamin Otte 58b44ebc1c testsuite: Remove GLES 2 tests
We want to drop GLES 2 support.
2024-09-26 18:41:13 +02:00
Benjamin Otte b598f21506 testsuite: Remove leftover test.in files
We stopped supporting installed tests in 3121f88265 but forgot to remove
these files.
2024-09-26 16:35:47 +00:00
Matthias Clasen d3c166d511 Merge branch 'for-main' into 'main'
gtk-demo: Stop using g_time_zone_new

See merge request GNOME/gtk!7742
2024-09-26 15:35:06 +00:00
Matthias Clasen 76e93206f3 Stop using G_APPLICATION_FLAGS_NONE
It has been deprecated in favor of G_APPLICATION_DEFAULT_FLAGS.
2024-09-25 22:03:23 -04:00
Matthias Clasen ecfe47af73 docs: Drop a note about old GLib
We require GLib 2.76 now.
2024-09-25 22:00:38 -04:00
Matthias Clasen f20ca9067e gtk-demo: Stop using g_time_zone_new
It is deprecated in favor of g_time_zone_new_identifier.
2024-09-25 21:57:49 -04:00
Matthias Clasen 8f3cd4733c Merge branch 'for-main' into 'main'
Stop using g_memdup

See merge request GNOME/gtk!7740
2024-09-26 01:22:23 +00:00
Matthias Clasen 402ee9b39c Tweak the issue template
Ask for more relevant information.
2024-09-26 02:53:54 +02:00
Matthias Clasen becbf4e1f9 Update the README slightly 2024-09-26 02:53:54 +02:00
Matthias Clasen 67407d5dcf tools: Minor cleanup
No need to register all types here.
2024-09-26 02:53:54 +02:00
Matthias Clasen fcc0f243cf Stop using g_pattern_match_string
It has been deprecated in favor of g_pattern_spec_match_string.
2024-09-26 02:53:54 +02:00
Matthias Clasen 282dcfa9ac Apply review feedback, mostly formatting. 2024-09-25 11:21:52 +00:00
Matthias Clasen 8c04801f6a Stop using g_memdup
Its deprecated in favor of g_memdup2
2024-09-25 10:56:36 +02:00
Lukáš Tyrychtr abe2d1cb16 listbox: Introduce tab-behavior property
This is similar to the other tab-behavior properties, and allows
to control how the tabbing behaves in context of a GtkListBox.

It allows to make gnome-initial-setup#216 history, for example.
2024-09-25 10:07:43 +02:00
Benjamin Otte e407d22b1e Merge branch 'wip/otte/for-main' into 'main'
keynames: Use C types

See merge request GNOME/gtk!7737
2024-09-25 02:07:23 +00:00
Benjamin Otte 37cefde5b0 demo: Unmix argument names 2024-09-25 02:50:22 +02:00
Benjamin Otte 310a4a3bf6 gdk: Fix parameter names
Believe in your self!
2024-09-25 02:50:22 +02:00
Benjamin Otte e6896aa8dc gpu: Fix argument names 2024-09-25 02:50:22 +02:00
Benjamin Otte 36ce68a3ca textbuffer: includes go before G_BEGIN_DECLS 2024-09-25 02:50:22 +02:00
Benjamin Otte 797343da59 gtkpango: Fix argument names 2024-09-25 02:50:22 +02:00
Benjamin Otte bd3223d452 testsuite: Add missing headers 2024-09-25 02:50:22 +02:00
Benjamin Otte 87a1a17868 memoryformat: Rename parameter
It's meant to match the prototype.
2024-09-25 02:50:22 +02:00
Benjamin Otte 70f386bd68 keynames: Use C types
Then we don't need to include glib.h
2024-09-25 02:50:22 +02:00
Benjamin Otte 0af89088ba gdk: Include missing header 2024-09-25 02:50:22 +02:00
Benjamin Otte 7342317c31 gdk: Fix parameter names 2024-09-25 02:50:22 +02:00
Benjamin Otte 8d8bd4efba broadway: Fix argument name 2024-09-25 02:50:22 +02:00
Benjamin Otte 0ae3c8968e gdk: Add missing header 2024-09-25 02:50:22 +02:00
Benjamin Otte 5e3f13acd1 filetransferportal: Include missing header 2024-09-25 02:50:22 +02:00
Benjamin Otte 32cdf35583 broadway: Fix argument name 2024-09-25 02:50:22 +02:00
Benjamin Otte 2f670bdc59 demo: Fix typo 2024-09-25 02:50:22 +02:00
Benjamin Otte 8d5660b4ab demo: Fix argument name 2024-09-25 02:50:22 +02:00
Benjamin Otte 2a39f427e1 testsuite: include missing headers 2024-09-25 02:50:22 +02:00
Benjamin Otte ca86294325 tools: Include missing headers 2024-09-25 02:50:22 +02:00
Benjamin Otte 820ba1ef13 demo: Correct argument name 2024-09-25 02:50:22 +02:00
Benjamin Otte 9507130dbc demo: Unmix argument names 2024-09-25 02:50:22 +02:00
Benjamin Otte d2dede635b demo: include missing header 2024-09-25 02:50:22 +02:00
Benjamin Otte 5a7fc4054b memoryformat: Fix argument names in prototype 2024-09-25 02:50:22 +02:00
Benjamin Otte 7fe22845e3 Merge branch 'wip/otte/fix-ci' into 'main'
testsuite: Use RGBA8 reference images

See merge request GNOME/gtk!7735
2024-09-24 17:52:55 +00:00
Matthias Clasen 6c9a7cc708 Merge branch 'gtk-find' into 'main'
Add gtk_string_list_find method

See merge request GNOME/gtk!7733
2024-09-24 17:24:10 +00:00
Benjamin Otte feeca98270 testsuite: Use RGBA8 reference images
Due to a Mesa bug, RGBA16 images aren't properly handled sometimes and
can cause random failures.
In this case, generating the modified reference images for the tests
fails.

Fixes CI breakage.

Related: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11750
2024-09-24 13:57:09 +00:00
taozuhong 7c27241479 Add gtk_string_list_find method
This is a convenience API to find a given string's position.

Test included.
2024-09-24 15:44:04 +02:00
Matthias Clasen fb73040d70 Merge branch 'for-main' into 'main'
Fix tests for 4.17

See merge request GNOME/gtk!7736
2024-09-24 13:42:25 +00:00
Matthias Clasen bbe74abf51 Fix tests for 4.17 2024-09-24 14:23:31 +02:00
Matthias Clasen 34bd3fc854 Merge branch 'scale-focus-fix' into 'main'
theme: Fix scale sizing during .fine-tune

See merge request GNOME/gtk!7659
2024-09-24 11:54:21 +00:00
Benjamin Otte 940b5af2a8 Merge branch 'wip/otte/for-main' into 'main'
Revert "dmabuf: Use the ngl downloader"

See merge request GNOME/gtk!7734
2024-09-24 10:05:27 +00:00
Benjamin Otte 0929d77f7f Revert "Fix the ngl downloader"
This reverts commit c7dfb8cb55.
2024-09-24 11:29:59 +02:00
Benjamin Otte 617297ddd7 Revert "gpu: Make gsk_gpu_copy_image available"
This reverts commit 42d26720d6.
2024-09-24 11:29:59 +02:00
Benjamin Otte 67cec180ca Revert "gsk: Make downloaders work fully"
This reverts commit de74fa0836.
2024-09-24 11:29:59 +02:00
Benjamin Otte bab8f2f976 Revert "dmabuf: Use the ngl downloader"
This reverts commit 97e0f872a2.
2024-09-24 11:29:59 +02:00
Matthias Clasen 4801c3275e Merge branch 'wip/otte/win32-remove-sync' into 'main'
win32: Remove gdk_display_sync()

See merge request GNOME/gtk!7727
2024-09-24 07:03:53 +00:00
Matthias Clasen 39354b3b99 Merge branch 'wip/otte/x11-remove-sync' into 'main'
x11: Remove gdk_display_sync() call

See merge request GNOME/gtk!7728
2024-09-24 07:03:20 +00:00
Matthias Clasen 661e953558 Merge branch 'dmabuf-downloader-investigations' into 'main'
Fix the ngl downloader

See merge request GNOME/gtk!7731
2024-09-24 07:02:09 +00:00
Matthias Clasen 039b97ef9e Start 4.17 2024-09-24 08:42:21 +02:00
Matthias Clasen 630699fb68 Post-release version bump 2024-09-24 08:37:11 +02:00
Matthias Clasen 3f4a414b1d 4.16.2 2024-09-24 08:14:26 +02:00
Matthias Clasen 4569b1ab40 Merge branch '5917-stack-sidebar-object-ref' into 'main'
stack-sidebar: Hold reference to page

Closes #5917

See merge request GNOME/gtk!6144
2024-09-23 20:51:06 +00:00
Peter Bloomfield a484e8fc37 stack-sidebar: Hold reference to page 2024-09-23 20:51:05 +00:00
Matthias Clasen d51bf6d905 Merge branch 'fix-gl-texture-leak' into 'main'
gsk: Don't leak gl textures

Closes #7013

See merge request GNOME/gtk!7725
2024-09-23 20:50:30 +00:00
Matthias Clasen 358b0b4d13 Merge branch 'wip/state-driven-controller-changes' into 'main'
gtkwidget: Check for destroyed controllers while propagating state

Closes #6924

See merge request GNOME/gtk!7668
2024-09-23 20:45:01 +00:00
Matthias Clasen 97e0f872a2 dmabuf: Use the ngl downloader
It works, now.
2024-09-23 21:14:53 +02:00
Matthias Clasen de74fa0836 gsk: Make downloaders work fully
Use gsk_gpu_copy_image when necessary to get the image converted
into the right format before downloading it.
2024-09-23 21:14:19 +02:00
Matthias Clasen 42d26720d6 gpu: Make gsk_gpu_copy_image available
This was a static helper in gsknodeprocessor.c, but we want to
use it elsewhere, so make it available.
2024-09-23 21:14:19 +02:00
Matthias Clasen c7dfb8cb55 Fix the ngl downloader
The image is already associated with the original texture, the
one that the download op creates is purely to hand it to the
downloader, it should not be associated with the image.

This makes the ngl downloader work as well as the vulkan one
(ie rgba dmabufs work, yuv ones don't, since we don't convert
them).
2024-09-23 21:14:08 +02:00
Daniel 8648a67c10 Updated Spanish translation 2024-09-23 09:39:29 +02:00
Matthias Clasen f9b3ce95c2 Merge branch 'inspector-clipboard-criticals' into 'main'
inspector: Avoid criticals in the clipboard code

Closes #7026

See merge request GNOME/gtk!7730
2024-09-22 08:45:08 +00:00
Matthias Clasen c828813d78 Merge branch 'not-a-mimetype-no-no' into 'main'
wayland: Be more careful with mimetypes

See merge request GNOME/gtk!7729
2024-09-22 08:43:44 +00:00
Matthias Clasen 5935dc174f inspector: Avoid criticals in the clipboard code
We keep a pointer to the GdkDrop object without a reference, and
then it dies on us. Be more careful, and clean up the dnd section
when the we drop object goes away.

Fixes: #7026
2024-09-22 09:58:31 +02:00
Matthias Clasen b623b2acef wayland: Be more careful with mimetypes
Sometimes, jokers send us 'mimetypes' like DELETE or
org.webkitgtk.WebKit.custom-pasteboard-data, and gdk_intern_mime_type
will return NULL for such things. Handle that by just closing the fd.

Better than running into an assertion further down.
2024-09-22 09:25:44 +02:00
Yaron Shahrabani cc867eeccf Update Hebrew translation 2024-09-21 19:39:39 +00:00
Benjamin Otte 17bdb4c8fb Merge branch 'wip/otte/for-main' into 'main'
wayland: Don't call gdk_display_sync()

Closes #7022 and #7025

See merge request GNOME/gtk!7726
2024-09-21 17:01:19 +00:00
Benjamin Otte 236b6d1cd6 x11: Remove gdk_display_sync() call
This is unnecessary.
Worse, it is reentrant and can cause all sorts of avoc when processing
events halfway through initializing the Vulkan context.

It was introduced in commit e11a6a0e68 but back then GTK was barely
branched for GTK4 and Vulkan drivers were very new, and it looks like an
unnecessary workaround.

Testing did not seem to indicate any issues with just removing it, so
here it goes.

Related: #7022
2024-09-21 18:59:49 +02:00
Matthias Clasen 9ded3e64a2 Merge branch 'fix-rtl-centered-labels' into 'main'
Fix centered text in labels

Closes #6836

See merge request GNOME/gtk!7724
2024-09-21 16:39:42 +00:00
Benjamin Otte 6e714722c4 win32: Remove gdk_display_sync()
This is unnecessary.
Worse, it is reentrant and causes all sorts of avoc when processing
events halfway through initializing the context.

It only exists because in commit c4244ea1 the win32 Vulkan code was
copy/pasted from another backend.

Related: #7022
2024-09-21 18:19:26 +02:00
Benjamin Otte 60b1496091 wayland: Don't call gdk_display_sync()
It is not necessary.
Worse, it is reentrant and causes all sorts of avoc when processing
events halfway through initializing the context.

It only exists because in commit 3887548 the Wayland Vulkan code
was copy/pasted from X11.

Fixes #7022
Fixes #7025
2024-09-21 18:18:29 +02:00
Matthias Clasen dc1b2d4117 gsk: Don't leak gl textures
We need to fix all the textures we own. This broke in 65c8320a.

Fixes: #7013
2024-09-21 10:51:26 +02:00
Matthias Clasen e205f13495 Fix centered text in labels
When the text is rtl, pango will put the text at the right end of
its given width, causing the logical.x to be big, and in turn, our
computed position to be negative. If we don't allow that, centered
text will end up at the right side if it is rtl.

Fixes: #6836
2024-09-21 10:06:33 +02:00
Benjamin Otte 72718b7193 Merge branch 'wip/otte/critical-warning' into 'main'
vulkan: Demote g_critical() to g_warning()

See merge request GNOME/gtk!7723
2024-09-20 22:54:18 +00:00
Benjamin Otte db95e37e15 vulkan: Demote g_critical() to g_warning()
For VK_DEBUG_REPORT_WARNING_BIT_EXT we should always have used
g_warning().

For VK_DEBUG_REPORT_ERROR_BIT_EXT g_critical() is technically the right
choice, but Mesa has been using this flag for normal warnings, so until
that gets fixed, we don't want to throw criticals.

Related: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31292
Fixes: !7020
2024-09-20 23:02:15 +02:00
Juliano de Souza Camargo f9714cc054 Update Brazilian Portuguese translation 2024-09-20 00:03:31 +00:00
Ekaterine Papava 58c49ce6b0 Update Georgian translation 2024-09-19 23:03:39 +00:00
Florian Heiser 13364cea74 Update German translation 2024-09-19 08:25:48 +00:00
Andika Triwidada f6014bdc08 Update Indonesian translation 2024-09-19 01:05:51 +00:00
Hugo Carvalho 6070edfa61 Update Portuguese translation 2024-09-18 21:52:59 +00:00
Emin Tufan Çetin 0600357373 Update Turkish translation 2024-09-18 07:05:11 +00:00
Yuri Chornoivan 7873ebac2a Update Ukrainian translation 2024-09-18 06:39:12 +00:00
Luming Zh 8edd376ab8 Update Chinese (China) translation 2024-09-18 01:21:37 +00:00
Piotr Drąg 6f300557bf Update Polish translation 2024-09-17 18:44:48 +02:00
Martin bcda071d7d Update Slovenian translation 2024-09-17 15:22:00 +00:00
Jordi Mas i Hernandez 9df3a50c87 Update Catalan translation 2024-09-17 10:45:22 +00:00
Danial Behzadi 70d41583b3 Update Persian translation 2024-09-17 10:32:44 +00:00
Matthias Clasen a50df37d52 Merge branch 'iss-5072' into 'main'
gtk/print/gtkprintoperation{,-unix,-portal}.c: add CAIRO_HAS checks

Closes #5072

See merge request GNOME/gtk!7717
2024-09-17 10:05:18 +00:00
Matthias Clasen b7d07ae190 Merge branch 'dmabuf-init-refactor' into 'main'
Refactor dmabuf initialization

See merge request GNOME/gtk!7714
2024-09-17 09:56:25 +00:00
Thomas Devoogdt 3610ac0fd1 gsk/gskrendernodeparser.c: add CAIRO_HAS check
resolves #5072

Signed-off-by: Thomas Devoogdt <thomas@devoogdt.com>
2024-09-17 10:55:41 +02:00
Thomas Devoogdt 9f855eecb1 modules/printbackends/gtkprintbackendfile.c: add CAIRO_HAS checks
This is similar to the checks in tools/gtk-rendernode-tool-render.c.

resolves #5072

Signed-off-by: Thomas Devoogdt <thomas@devoogdt.com>
2024-09-17 10:55:40 +02:00
Thomas Devoogdt ffc8f34dfd gtk/print/gtkprintoperation{,-unix,-portal}.c: add CAIRO_HAS checks
This is similar to the checks in tools/gtk-rendernode-tool-render.c.

resolves #5072

Signed-off-by: Thomas Devoogdt <thomas@devoogdt.com>
2024-09-17 10:55:39 +02:00
Matthias Clasen 7acc1c0125 Make dmabuf initialization lazier
Only initialize the Vulkan or EGL parts where possible.

When dmabufs or dmabuf formats are actually used, we still
initialize fully by creating both a Vulkan and EGL downloader.

This shortens the time to first commit from 149ms to 108ms.
2024-09-17 09:46:01 +02:00
Matthias Clasen 6059eaf355 gdk: Reorganize dmabuf initialization
Change the xxx_get_downloader() functions to init_dmabuf_xxx(),
and make them initialize both xxx_dmabuf_formats and xxx_downloader.
2024-09-17 09:46:01 +02:00
Alexander Shopov 26971c48d4 Update Bulgarian translation 2024-09-17 07:42:50 +00:00
Matthias Clasen b42caef0ed Merge branch 'builder-tool-box-position' into 'main'
builder-tool: Handle pack-type, position, and center child in GtkBox

See merge request GNOME/gtk!7715
2024-09-17 05:42:46 +00:00
Elliott Sales de Andrade b3706daf90 builder-tool: Handle pack-type, position, and center child in GtkBox
This takes the `position` property and ensures children are sorted by
it, splits children by `pack-type` (also reversing the order of `end`
children), and handles children with `type="center"`.

If either a center child or end children exist, then the `GtkBox` is
converted to a `GtkCenterBox`, with `start-widget`/`end-widget` being a
nested `GtkBox` with the relevant children.

The splitting does cause some non-`object` children to sort differently
(hence the change to `office-runner.expected`.)
2024-09-16 05:12:54 -04:00
Matthias Clasen 24dc9dc653 Drop the dmabuf_downloaders array
Just use two individual fields, so we can track if we've already
created each one. This also matches the individual fields we have
for the dmabuf formats.

And change preference order of downloaders

Previously, our order was mmap > vulkan > egl.

But depending on the hw (discrete vs integrated gpu), mmap
can be catastrophically slower (on the order of 20ms vs 1.5s).

So, change the order to egl > vulkan > mmap.

Note that this currently has less effect than we'd like to,
since we don't let the downloaders claim linear formats.
2024-09-16 09:55:31 +02:00
Elliott Sales de Andrade 172dfb14c4 builder-tool: Convert node children after the node itself
Some nodes like `GtkBox` need to process removed-in-GTK4 attributes to
correctly convert their contents. If the node children are processed
first, then those attributes are removed prematurely.
2024-09-16 02:39:47 -04:00
Jordi Mas i Hernandez 3b43078b08 Update Catalan translation 2024-09-15 12:15:18 +00:00
Benjamin Otte f2e75529cb Merge branch 'wip/otte/for-main' into 'main'
vulkan: Actually return the preferred memory format

See merge request GNOME/gtk!7713
2024-09-15 08:19:53 +00:00
Benjamin Otte eed58b4051 gpu: Split out rect grid snapping function
We might want to use it outside of the nodeprocessor.

The function is now called gsk_rect_snap_to_grid().
2024-09-15 02:31:02 +02:00
Benjamin Otte 28a01ca954 gpu: Print some tex rects in verbose output
In the colorize and texture ops, print the tex rect. This is useful
because when adding new features with textures (like atlas usage), these
are the ops that I use for testing.
2024-09-15 02:31:02 +02:00
Benjamin Otte efd5395ecf rendernode-tool: Download in the texture's format
When downloading textures, download the in the actual format of the
texture. We don't want to benchmark conversion, we want to benchmark
renderers.
2024-09-15 02:31:02 +02:00
Benjamin Otte 376dbe9def memoryformat: Move fast path into the threaded path
We don't want to get slower in the fast path.
2024-09-15 02:31:02 +02:00
Benjamin Otte bba7979670 memoryformat: Add a fastpath for RGBA8 <=> BGRA8
Cairo is using BGRA8 but we want to use RGBA8 because it's the canonical
GL format.

So getting this fast sounds useful.
2024-09-15 02:31:02 +02:00
Benjamin Otte 01aafc6e65 memoryformat: Don't always convert to rec2100-linear and back
It turns out we lost the check to see if color states are equal when we
multithreaded things in !7657

Whoops.
2024-09-15 02:31:01 +02:00
Benjamin Otte fa86bfcb55 gpu: Use existing frame in render_texture()
Instead of recreating frames from scratch every time, use an existing one.

This ensures that renderers don't need to recreate GPU resources every
time (like buffers and everything else that frames manage). It also
speeds up occasional render_texture() calls in default renderers.

This speeds up in particular the Vulkan renderer.
2024-09-15 02:31:01 +02:00
Benjamin Otte c3d9f4a9ac gpu: Move a function
No functional changes.
2024-09-15 02:31:01 +02:00
Benjamin Otte d11ac3585d gpu: Clean up the frame after we're done waiting for it
This is useful because cleaning up will do the final copies of texture
data.

It also means we use less memory, as we're going to release images that
were used in ops.
2024-09-15 02:31:01 +02:00
Benjamin Otte 8f78a0f809 gpu: Add an internal is_clean() check
If no ops are recorded, then we don't need to wait for any ops to
finish.

Also fix the initial fence creation on Vulkan - we no longer need to
create it fixed because of the random cleanup() call at startup does no
longer happen.
2024-09-15 02:30:59 +02:00
Benjamin Otte 3286d9f1b5 vulkan: Actually return the preferred memory format
We were just exiting the loop, but not remembering the index.

Speeds up various memory operations, sometimes by quite a lot.
2024-09-15 00:07:47 +02:00
Matthias Clasen ee38c96ee3 Merge branch 'matthiasc/for-main' into 'main'
gsk: Add another profiler mark

See merge request GNOME/gtk!7712
2024-09-13 16:14:17 +00:00
Matthias Clasen e5705bd141 gsk: Add another profiler mark
This lets us compare the cost of realizing the new renderers vs
the old GL renderer.
2024-09-13 11:02:52 -04:00
Matthias Clasen 753d74d676 Post-release version bump 2024-09-13 10:34:06 -04:00
Matthias Clasen 670b4aabac 4.16.1 2024-09-13 10:11:36 -04:00
Matthias Clasen eba9316c12 Merge branch 'gtkcalendar-issue-6406' into 'main'
GtkCalendar: Avoid ending up with invalid dates

Closes #6406

See merge request GNOME/gtk!6851
2024-09-13 13:43:36 +00:00
Matthias Clasen 7f3835cc4f Merge branch 'phase-docs' into 'main'
docs: Fix typo and improve wording in drawing model docs

See merge request GNOME/gtk!7711
2024-09-12 16:21:51 +00:00
Matthias Clasen be89fa7919 Merge branch 'docs-typo' into 'main'
gtklistitem: Fix a minor typo in the docs

See merge request GNOME/gtk!7681
2024-09-12 13:58:04 +00:00
Philip Withnall 20d6938a90 docs: Fix typo and improve wording in drawing model docs
There was a typo ‘phases happens’, but also some spurious whitespace and
slightly odd-sounding use of ‘we’ so I changed it to be phrased
passively.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-09-12 14:06:39 +01:00
Matthias Clasen 6f4f4d0123 Merge branch 'gbsneto/atspiroot-flatpak-portal-session-bus' into 'main'
a11y: Use session bus to check Flatpak portal

See merge request GNOME/gtk!7709
2024-09-12 10:24:27 +00:00
Arjan Molenaar 250322deb0 Merge branch 'amolenaar/dnd-icon-on-top' into 'main'
macos: Keep DnD windows always on top

Closes #6809 and #6818

See merge request GNOME/gtk!7706
2024-09-12 09:25:05 +00:00
Matthias Clasen bdee95c32c Merge branch 'wip/otte/for-main' into 'main'
gpu: Don't crash when there's no ops

Closes #6992

See merge request GNOME/gtk!7710
2024-09-12 00:27:29 +00:00
Georges Basile Stavracas Neto 1ffd23dbab a11y: Use session bus to check Flatpak portal
The Flatpak portal (and so far all other portals) live in the session
bus, not in the a11y bus.

Use the session bus to get the Flatpak portal version. Avoid too many
synchronous D-Bus calls on startup by using g_once_init_* helpers.
2024-09-11 10:43:47 -03:00
Arjan Molenaar e92bd4d9ce macOS: drag surfaces should ignore all events
This fixes the Dnd demo.
2024-09-11 14:59:03 +02:00
Georges Basile Stavracas Neto 24841a8d5b a11y: Correct return type of D-Bus call
org.freedesktop.DBus.Properties.Get() returns "(v)" which then
must be unpacked into an uint32 ("u") variant.
2024-09-11 08:53:38 -03:00
Matthias Clasen c2dc459167 Merge branch 'label-docs-fix' into 'main'
gtkenums: Fix missing backtick in docs

See merge request GNOME/gtk!7683
2024-09-11 10:13:13 +00:00
Matthias Clasen d87ce14869 Merge branch 'vulkan-294' into 'main'
vulkan: Add another two error codes

See merge request GNOME/gtk!7708
2024-09-11 10:12:40 +00:00
Benjamin Otte e9735f0c35 gpu: Move GskGpuClip declaration into types header
Makes it possible to use it in multiple places.
2024-09-11 08:34:41 +02:00
Benjamin Otte d320373262 gpu: Clarify a function
It does functionally the same now, but it makes it mroe clear how it
works.

As a bonus, it will now trigger for -Wswitch-enum, too.
2024-09-11 08:33:22 +02:00
Arjan Molenaar a84fe6bde6 macos: Put DnD windows on status level
This will make sure the dragged window will stay visible.
2024-09-11 08:19:39 +02:00
Benjamin Otte a8748598b6 gpu: verbose-print if shaders are inside merged ops
This is useful when trying to get more ops merged for performance
reasons.
2024-09-11 08:17:58 +02:00
Benjamin Otte 748acaf654 gpu: Use a better character for debug print
Instead of 🞨 which isn't supported in many places, use ⬚.

⬚ also fits better with □ and ▢ for describing clip regions.
2024-09-11 08:17:58 +02:00
Benjamin Otte 1ff9d1545d Revert "vulkan: Set VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT"
This reverts commit ffae0010c4.

The commit doesn't work with the nvidia driver and it's not necessary to
use it, so drop it for now.

Fixes #6992
2024-09-11 08:17:43 +02:00
Benjamin Otte e35670a014 gpu: Don't crash when there's no ops
In the rare situation (read: I triggered it with obscure hacks) where no
ops are emitted, we could end up pointing into invalid memory and
crashing.

Don't do that.
2024-09-11 08:17:43 +02:00
Benjamin Otte 9690c87736 docs: Remove duplicated text 2024-09-11 08:17:43 +02:00
Philip Withnall a60d96a9ac gtkenums: Fix missing backtick in docs
Fixes the formatting for `GtkAlign`.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-09-11 00:35:47 +00:00
Matthias Clasen 0a9b501743 Merge branch 'plug-leak' into 'main'
filechooser: Plug a leak

See merge request GNOME/gtk!7705
2024-09-11 00:09:05 +00:00
Emmanuel Gil Peyrot 6dd55e381d vulkan: Fix error string
This one got added in 66ba1f76ba but didn’t end
the sentence with a dot, and didn’t have its enum name between parentheses so
that people can debug more easily which error code got generated.
2024-09-10 22:46:29 +00:00
Emmanuel Gil Peyrot abd8d40bf9 vulkan: Add another two error codes
Those two come from the VK_KHR_pipeline_binary extension and have been added in
Vulkan 1.3.294.
2024-09-10 22:45:41 +00:00
Matthias Clasen 348e938698 Merge branch 'matthiasc/for-main' into 'main'
print dialog: Fix initial selection

Closes #6996

See merge request GNOME/gtk!7704
2024-09-10 18:35:08 +00:00
Sergey Bugaev 4e0a909ca9 directorylist: Fix criticals if monitoring fails
g_file_monitor_directory () can fail.  We're ignoring the actual error
by passing NULL for the error argument, but we shouldn't be trying to
connect to a signal on the NULL value that gets returned on error.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-09-10 18:38:56 +03:00
Sergey Bugaev 8964f6f0cc filechooser: Plug a leak
gtk_file_chooser_get_current_folder () is transfer full, while
g_list_store_append () is transfer none.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-09-10 18:29:45 +03:00
Matthias Clasen b807b84e16 print dialog: Fix initial selection
This broke with recent fixes to GtkSingleSelection.

Fixes: #6996
2024-09-10 10:59:36 -04:00
Matthias Clasen 97a2c3a656 Merge branch 'wip/smcv/issue6995' into 'main'
gdkgltexture: Avoid use-after-free when switching GdkGLContext

Closes #6995

See merge request GNOME/gtk!7703
2024-09-10 11:23:30 +00:00
Bruce Cowan 5925c4c51f Update British English translation 2024-09-10 10:15:31 +00:00
Simon McVittie 0fa2ae48d4 gdkgltexture: Avoid use-after-free when switching GdkGLContext
`thread_current_context` might be holding the last reference to
`previous`, in which case `gdk_gl_context_make_current` on the new
context will free `previous`, leaving it a dangling pointer.
Avoid this by making sure to hold a reference.

Fixes: 41cd0c6f "gl: Fix initial EGL context creation on X11"
Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/6995
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-09-10 00:11:18 +01:00
Matthias Clasen 43303bf7e5 Merge branch 'matthiasc/for-main' into 'main'
Revert "css: Simplify theme loading"

Closes #6991

See merge request GNOME/gtk!7702
2024-09-09 12:35:57 +00:00
Anders Jonsson f26f491d58 Update Swedish translation 2024-09-09 11:22:40 +00:00
Matthias Clasen a9b46e8409 Revert "css: Simplify theme loading"
This reverts commit c033de9b83.

This change unintentionally broke use of relative paths in Adwaita.

Fixes: #6991
2024-09-09 06:51:34 -04:00
Daniel Mustieles b27e67999b Update Spanish translation 2024-09-09 09:26:15 +00:00
Balázs Úr 3177fd14f9 Update Hungarian translation 2024-09-09 06:26:41 +00:00
Benjamin Otte 9ba41ed6e8 Merge branch 'wip/otte/blur-and-blit' into 'main'
Fix blur for opaque textures

Closes #6980

See merge request GNOME/gtk!7697
2024-09-09 04:46:43 +00:00
Matthias Clasen 70f2e2e09c Merge branch 'matthiasc/for-main' into 'main'
docs: Sync docs for GDK_VULKAN_DISABLE

See merge request GNOME/gtk!7700
2024-09-09 03:53:50 +00:00
Benjamin Otte 56fc8f0077 gpu: Blur opaque textures correctly
Opaque textures don't clamp to transparent but instead to black.
We didn't consider this, so we were blurring their edges into blackness
not into transparency.

Fix this by adding the GSK_GPU_AS_IMAGE_SAMPLED_OUT_OF_BOUNDS flag
and respecting it in the implementation that uses it.

Test included.

Fixes #6980
2024-09-09 05:10:51 +02:00
Benjamin Otte 85abff343e ngl: Images are not blittable if they have a swizzle
Swizzling is not respected for blitting.
See commit 058252e895 for the same change in Vulkan.
Apparently that never made it to ngl.

The next commit will have a test for this.
2024-09-09 04:18:13 +02:00
Benjamin Otte 6cefdfeddd testsuite: Fix udmabuf creation
We were using the wrong format and color state when downloading the
data.

Tests not included in this commit, but a few commits later.
2024-09-09 04:18:13 +02:00
Matthias Clasen 75fa51ef6d Cosmetics
Fix a typo
2024-09-08 19:35:53 -04:00
Matthias Clasen 4181b4b142 docs: Sync docs for GDK_VULKAN_DISABLE
Add swapchain-maintenance, and remove some no longer used values.
2024-09-08 19:35:00 -04:00
Benjamin Otte 7b55d2cf1a Merge branch 'wip/otte/for-main' into 'main'
vulkan: Enable VK_EXT_swapchain_maintenance1 if available

See merge request GNOME/gtk!7696
2024-09-08 23:25:36 +00:00
Benjamin Otte 03230181ce gpu: Add GskGpuAsImageFlags
I've had a need for flags for the get_as_image() call but so far have
been able to work around it. But now it seems I might finally need it.

This just introduces the flags but doesn't add any.

Related: #6980
2024-09-09 01:25:03 +02:00
Benjamin Otte 5e4f692e63 tiff: Store RGBx images as 4 channels
Set the alpha channel to "undefined" in this case.

Gimp doesn't seem to like this when opening the image and insists to
doing something with it, that's a bit of a bummer.

But it allows GTK to load RGBx textures.
2024-09-09 01:25:03 +02:00
Matthias Clasen e9a046c439 Merge branch 'dead-hamza' into 'main'
imcontextsimple: Handle dead_hamza

See merge request GNOME/gtk!7699
2024-09-08 22:58:11 +00:00
Mohamed Akram 182de7c957 imcontextsimple: Handle dead_hamza 2024-09-09 00:02:29 +04:00
Aurimas Černius 6c939819a3 Update Lithuanian translation 2024-09-08 19:12:24 +00:00
Matthias Clasen 6288be286f Merge branch 'matthiasc/for-main' into 'main'
gsk: Small optimization

See merge request GNOME/gtk!7698
2024-09-08 17:29:27 +00:00
Matthias Clasen 76a13596aa gpu: Reduce per-glyph overhead
Pull the shader clip computation out of the loop in the common
case that the entire node is contained in the clip.
2024-09-08 12:57:31 -04:00
Matthias Clasen c18cd6050b gpu: Use gsk_gpu_colorize_op2
This reduces the cost of these calls significantly, and this is
the inner loop of the node processor.
2024-09-08 12:43:02 -04:00
Matthias Clasen 60f5d4c93e gpu: Add a variant of gsk_gpu_colorize_op
This variant takes the color_states, instead of computing it
anew from the ccs and the color state of the color. This will
be used to pull this work out of the loop in add_glyph_node.
2024-09-08 12:41:48 -04:00
Matthias Clasen 03840151ac gsk: Drop an unused variable
We're not using last_image for anything.
2024-09-08 11:48:43 -04:00
Matthias Clasen 2e44f3e2ff gsk: Get the text node color once
We don't need to do this in the loop.
2024-09-08 11:48:43 -04:00
Matthias Clasen 4f9fd5cf1d Add gsk_text_node_get_font_hint_style
Getting the hint style is one of the more expensive calls we do
when adding glyph nodes, so cache this information in the node.
2024-09-08 11:48:43 -04:00
Matthias Clasen 59f334622b rendernode: Inline gsk_render_node_get_node_type
This is the most-called function on render nodes.
2024-09-08 11:48:43 -04:00
Matthias Clasen c505a08e46 gsk: Small optimization
Avoid calling gsk_container_node_get_child in a loop.
2024-09-08 11:48:43 -04:00
Benjamin Otte ffae0010c4 vulkan: Set VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT
It seems Mesa doesn't support that yet, but having it doesn't hurt.

And it allows drivers to allocate less memory for the swapchains,
because we don't need all the 4 images we request in minImageCount.
But drivers tend to take that minimum image count as gospel, so we need
to use a higher number to not cause lag in corner cases.
2024-09-08 16:22:49 +02:00
Benjamin Otte 6c72a223f5 vulkan: Enable VK_EXT_swapchain_maintenance1 if available
This just adds the plumbing, usage will happen later.

For testing, GDK_VULKAN_DISABLE=swapchain-maintenance will turn it off.
2024-09-08 16:22:49 +02:00
Benjamin Otte 5a027594c3 vulkan: Add gdk_vulkan_context_has_feature()
A siimplification that will come in handy in the future.
2024-09-08 16:22:49 +02:00
Ask Hjorth Larsen ebc3600f78 Update Danish translation 2024-09-08 14:15:54 +00:00
Arjan Molenaar ae0cf9ff54 Merge branch 'amolenaar/focus-im-popups' into 'main'
macos: Fix popup window and keyboard input

Closes #6950 and #5049

See merge request GNOME/gtk!7653
2024-09-08 12:54:24 +00:00
Andi Chandler 08bf8b7464 Update British English translation 2024-09-08 12:26:07 +00:00
Hugo Carvalho 0201abca5e Update Portuguese translation 2024-09-08 10:38:11 +00:00
Asier Sarasua Garmendia d87b566c59 Update Basque translation 2024-09-08 08:03:53 +00:00
Ekaterine Papava 572b4140f9 Update Georgian translation 2024-09-08 03:58:29 +00:00
Matthias Clasen 6241471f3e Merge branch 'matthiasc/for-main' into 'main'
gpu: Print blur colors

See merge request GNOME/gtk!7695
2024-09-07 18:46:10 +00:00
Matthias Clasen 1ae9cdb4c9 gpu: Print blur colors
Relevant information when debugging shadows.
2024-09-07 12:34:04 -04:00
Daniel Rusek c1e1b54034 Update Czech translation 2024-09-07 15:52:31 +00:00
Matthias Clasen f654cb7d3b Merge branch 'docs-remove-gtk-attribute' into 'main'
docs: Remove custom org.gtk.Method and org.gtk.Property annotations

See merge request GNOME/gtk!7335
2024-09-07 14:39:19 +00:00
Alexander Shopov 85beb4fa20 Update Bulgarian translation 2024-09-07 12:50:50 +00:00
twlvnn kraftwerk a0e81996eb Update Bulgarian translation
(cherry picked from commit 090fcfe503)
2024-09-07 12:13:48 +00:00
Maximiliano Sandoval ec477ef71d docs: Document property annotations in README.md 2024-09-07 09:51:33 +02:00
Maximiliano Sandoval 3afc760644 docs: Manually remove property annotations
We remove the annotations that did not match the regex of the previous commits.
2024-09-07 09:51:33 +02:00
Maximiliano Sandoval ba32140671 docs: Remove all org.gtk.Method annotations
Removed via regex and grep.
2024-09-07 09:51:32 +02:00
Maximiliano Sandoval 91d36dd410 docs: Remove all org.gtk.Property annotations
Removed via regex and grep.

The following were intentionally not removed:

- GtkImage:file: (attributes org.gtk.Property.set=gtk_image_set_from_file)
- GtkImage:resource: (attributes org.gtk.Property.set=gtk_image_set_from_resource)

As they have no getter and (setter PROP) without a (getter PROP) crash
gobject-introspection. This is fixed by
https://gitlab.gnome.org/GNOME/gobject-introspection/-/commit/ad3118eb519d40131ae90f4cf9b55c991c30821b.
2024-09-07 09:51:32 +02:00
Maximiliano Sandoval 4fd1e32752 docs: Use correct property gir annotations
The annotations should only be set when the name of the setter or getter
for a property "GtkClassName:prop-name" is not gtk_class_name_g(s)et_property_name.
2024-09-07 09:51:26 +02:00
Matthias Clasen b538adf2c0 Post-release version bump 2024-09-06 23:07:08 -04:00
Matthias Clasen d16c9fbaca 4.16.0 2024-09-06 22:51:07 -04:00
Ahmed Baizid 9b6063c07c GtkCalendar: The focus cannot be moved to out of range dates
Out of range dates are in insensitive tabel cells.
2024-09-06 23:49:03 +01:00
Ahmed Baizid d1a4740894 GtkCalendar: move_focus() invalidates days
calendar_invalidate_day() calls are no more disseminated.
2024-09-06 23:49:03 +01:00
Ahmed Baizid 5186c4dc45 GtkCalendar: Not allowed with the mouse, not allowed with the keyboard
Month/year navigation with the keyboard checks if the corresponding
widget is sensitive or not.
2024-09-06 23:49:03 +01:00
Ahmed Baizid ca9664cdfd GtkCalendar: Disable navigation buttons for out of range months
`GtkCalendar`s span 0001-01/9999-12.
2024-09-06 23:49:03 +01:00
Ahmed Baizid 6c9edbf0da GtkCalendar: Out of range dates are neither displayed nor sensitive
`GDateTime`s span 0001-01-01/9999-12-31.
2024-09-06 23:49:03 +01:00
Ahmed Baizid b8d2b1d3ce GtkCalendar: Extract calendar_update_day_labels()
calendar_select_day_internal() is too big, doing so many things.
2024-09-06 23:49:03 +01:00
Matthias Clasen 0274294a6f Merge branch 'wip/otte/cpu-mipmap' into 'main'
gpu: Allow uploading of mipmap levels when tiling

See merge request GNOME/gtk!7657
2024-09-06 22:14:37 +00:00
Matthias Clasen 03b19d8861 docs: Recommend glycin for image loading
Best to send people elsewhere to avoid misunderstandings of our api.
2024-09-06 16:52:47 -04:00
Matthias Clasen 171612671f demo: Beef up the image scaling demo
Add buttons for loading the Portland Rose, and a nameless large
png. Make them load the texture in a thread, to demonstrate better
handling of large images.
2024-09-06 16:14:24 -04:00
Matthias Clasen d3db28b3f4 memory format: Add profiler marks
Add profiler marks to our long-running threaded operations.
To avoid spamming profiles too much, only report runs that take
at least 0.5 ms.
2024-09-06 16:14:24 -04:00
Benjamin Otte 896ea5b753 memoryformat: Add linear/nearest choice for mipmaping
linear will average all the pixels for the lod, nearest will just pick
one (using the same method as OpenGL/Vulkan, picking bottom right
center).

This doesn't really make linear/nearest filtering work as it should
(because it's still a form of mipmaps), but it has 2 advantages:

1. it gets closer to the desired effect

2. it is a lot faster

Because only 1 pixel is chosen from the original image, instead of
averaging all pixels, a lot less memory needs to be accessed, and
because memory access is the bottleneck for large images, the speedup is
almost linear with the number of pixels not accessed.
And that means that even for lot level 3, aka 1/8th scale, only 1/64 of
the pixels need to be accessed, and everything is 50x faster.

Switching gtk4-demo --run=image_scaling to linear/nearest makes all the
lag go away for me, even with a 64k x 64k image.
2024-09-06 15:47:35 -04:00
Benjamin Otte 5498b077fd memoryformat: Parallelize gdk_memory_mipmap() 2024-09-06 15:47:34 -04:00
Benjamin Otte 534a9b6ba0 memoryformat: Add fast path for mipmap
We have fast conversion functions, use those directly instead of calling
into gdk_memory_convert().

This is useful because as mentioned before, the main optimization here
is RGB8 => RGBA8 and we have a fastpath for that.
2024-09-06 15:47:34 -04:00
Benjamin Otte cea961f4f4 memoryformat: Take src_format and dest_format
Why do we need this? Because RGB images are provided in RGB format but
GPUs can't handle RGB, only RGBA, so we need to convert.

And we need to do that without allocating too much memory, because
allocating memory is slow. Which means in aprticular we need to do the
conversion after mipmapping, not before (like we were doing).
2024-09-06 15:47:34 -04:00
Benjamin Otte 848c6815d3 gpu: Allow uploading of mipmap levels when tiling
This allows uploading less memory but requires computing lod levels on
the CPU which is slow because it reads through all of the memory and so
far entirely not optimized.

However, it uses significantly less VRAM.

This is done by adding a gdk_memory_mipmap() function that does this
task.
The texture upload op now accepts a lod level and if that is >0 it uses
gdk_memory_mipmap() on the source texture.
2024-09-06 15:47:34 -04:00
Benjamin Otte 46559039f3 memoryformat: Parallelize gdk_memory_convert_color_state() 2024-09-06 15:47:34 -04:00
Benjamin Otte eb7a42bc13 memoryformat: Parallelize generic path of gdk_memory_convert() 2024-09-06 15:47:34 -04:00
Benjamin Otte ffe56fe6b3 memoryformat: Parallelize
Refactor code so that it uses g_parallel_task_run().
2024-09-06 15:47:34 -04:00
Benjamin Otte d4ba57fcc3 gdk: Add gdk_parallel_task_run()
This is just the API. Users will come later.

I considered putting it into gdkmemoryformat.c because it's likely gonna
be the only user and this one function is so little code, but it didn't
fit at all.
So now it's a new file.
2024-09-06 15:47:34 -04:00
Benjamin Otte a95c9ebc51 memoryformat: Split out a function
Allow querying the fast conversion functions outside of
gdk_memory_convert().
2024-09-06 15:47:34 -04:00
Benjamin Otte 9195c39756 build: Alphabetic order is hard 2024-09-06 15:47:34 -04:00
Mat e0ffeb8ded macos: simplify access to native widget. 2024-09-06 16:12:56 +00:00
Matthias Clasen d9bb434c1f Merge branch 'bad-relative-color' into 'main'
css: Avoid a crash with relative colors

Closes #6985

See merge request GNOME/gtk!7693
2024-09-06 15:05:27 +00:00
Juliano de Souza Camargo 866c83909c Update Brazilian Portuguese translation 2024-09-06 13:00:13 +00:00
Luca Bacci 4965b7b6fa Merge branch 'wgl-updates' into 'main'
WGL Updates

Closes #6975

See merge request GNOME/gtk!7692
2024-09-06 12:47:41 +00:00
Matthias Clasen 45f3e86457 css: Allocate less when searching themes
We trawl through a whole bunch of directories, but we can do it
without allocation quite so much.
2024-09-06 07:54:59 -04:00
Matthias Clasen c033de9b83 css: Simplify theme loading
There is no need to do a detour through a GFile here.
Just load the resource.
2024-09-06 07:54:37 -04:00
Matthias Clasen 3f7f9b705e css: Avoid a crash with relative colors
rgba(from @foo ...) would crash if @foo was not a named color.
Handle it as we do elsewhere, by returning NULL from resolve().

Test included.

Fixes: #6985
2024-09-06 07:54:37 -04:00
Matthias Clasen b6d19f4c8b Fix css tests
Disable css deprecation warnings for the style tests. We want to
be able to do tests with named colors here.
2024-09-06 07:54:37 -04:00
Andika Triwidada 3a2b8f94ec Update Indonesian translation 2024-09-06 04:13:55 +00:00
Matthias Clasen 3a5933a519 Merge branch 'mcatanzaro/#6983' into 'main'
popover: fix critical on pop down

Closes #6983

See merge request GNOME/gtk!7691
2024-09-06 00:14:09 +00:00
Matthias Clasen 4c295dc49c popover: Avoid unnecessary work
If the popover isn't visible, no need to do any extra
'cascade' work. This also helps to avoid running into
trouble during finalization when the parents are already
gone.
2024-09-05 15:27:55 -04:00
Emin Tufan Çetin 03ebb41262 Update Turkish translation 2024-09-05 18:02:12 +00:00
Yaron Shahrabani b0c3265561 Update Hebrew translation 2024-09-05 12:43:43 +00:00
Danial Behzadi 98943b28aa Update Persian translation 2024-09-05 12:16:59 +00:00
Vasil Pupkin c354c5a63d Update Belarusian translation 2024-09-05 10:03:35 +00:00
Tim Sabsch 2f8cb9b2d0 Update German translation 2024-09-04 18:21:04 +00:00
Luca Bacci 7559a87e8a WGL: Detect MESA D3D12 driver and request GDI compatibility
This way we get a non-opaque framebuffer / render target

Fixes #6975

References:
  [1] https://gitlab.gnome.org/GNOME/gtk/-/issues/6975
  [2] https://gitlab.freedesktop.org/mesa/mesa/-/issues/11828
2024-09-04 20:02:44 +02:00
Luca Bacci b2394691cc Inspector: Fix append_wgl_extension_row()
wglGetExtensionsStringARB takes an HDC argument even though it
checks extensions for the current context. This was done for future
extensibility. From [1]:

>    Should this function take an hdc? It seems like a good idea. At
>    some point MS may want to incorporate this into OpenGL32. If they
>    do this and and they want to support more than one ICD, then an HDC
>    would be needed.

Currently the HDC argument is unused, but still wglGetExtensionsStringARB()
is required to check if HDC is valid:

>    If <hdc> does not indicate a valid device context then the function
>    fails and the error ERROR_DC_NOT_FOUND is generated. If the function
>    fails, the return value is NULL. To get extended error information,
>    call GetLastError.

So wglGetExtensionsStringARB fails if we pass NULL. Here we can pass any
valid HDC, like for example the screen DC returned by GetDC(NULL), but
probably using wglGetCurrentDC() makes most sense.

Reference:
  [1] - https://registry.khronos.org/OpenGL/extensions/ARB/WGL_ARB_extensions_string.txt
2024-09-04 20:02:29 +02:00
Yuri Chornoivan 5a94004b59 Update Ukrainian translation 2024-09-04 16:46:15 +00:00
Michael Catanzaro 3bd609d77c popover: fix critical on pop down
It's expected that there may be no parent widget to grab focus.

This fixes 2299c02639.

Fixes #6983
2024-09-04 11:25:50 -05:00
Luca Bacci 84d2961a91 Inspector: Sync WGL extensions with GdkWin32GLContextWGL
Replace WGL_EXT_pixel_format with WGL_ARB_pixel_format and drop
WGL_ARB_MULTISAMPLE (unused).
2024-09-04 17:10:39 +02:00
Luca Bacci 3a9f26113f WGL: Fix attribs_remove_last() 2024-09-04 17:07:01 +02:00
Luca Bacci 6a240c36ac WGL: Swap core / compat in debug output 2024-09-04 17:04:58 +02:00
Luca Bacci aaf4261969 WGL: Include renderer string in debug output 2024-09-04 17:03:54 +02:00
Arjan Molenaar 0211299846 macos: Fix input source popup placement in popovers 2024-09-04 17:03:14 +02:00
Arjan Molenaar aca11d6879 macos: Only allow keyboard focus on toplevel windows
This avoids the focus to move to a popup or popover window.
The red/yellow/green buttons remain colored.
2024-09-04 17:03:14 +02:00
Luca Bacci 5dceb7f7d2 WGL: Make context current to get debug info
Otherwise we get NULL from glGetString()
2024-09-04 17:02:20 +02:00
Martin 3372b1a84b Update Slovenian translation 2024-09-04 14:26:58 +00:00
Luming Zh 75a4eca13a Update Chinese (China) translation 2024-09-04 13:21:40 +00:00
Jordi Mas i Hernandez 13f0ab881e Update Catalan translation 2024-09-04 12:40:06 +00:00
Fran Dieguez d4b45526b2 Update Galician translation 2024-09-04 06:34:09 +00:00
Fran Dieguez c06e1f4848 Update Galician translation 2024-09-04 06:11:36 +00:00
Matthias Clasen 6a4a52d110 Merge branch 'Enokilis-main-patch-44493' into 'main'
Typo in gtk/gtkcssprovider.c

See merge request GNOME/gtk!7688
2024-09-03 21:07:50 +00:00
Matthias Clasen ed6f5b8755 Merge branch 'stroke-autoptr' into 'main'
gsk: Add autoptr cleanup function for GskStroke

See merge request GNOME/gtk!7690
2024-09-03 17:15:10 +00:00
Philip Withnall e87b4dca71 gsk: Add autoptr cleanup function for GskStroke
It appeared to be missing, while other GSK types already have cleanup
functions defined.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-09-03 16:50:10 +01:00
Benjamin Otte 567c8b5ab3 Merge branch 'wip/smcv/debug-gsk-scaling-test' into 'main'
gsk/scaling test: Improve debuggability on failure

See merge request GNOME/gtk!7680
2024-09-03 15:30:32 +00:00
Benjamin Otte 7aeca0512c Merge branch 'wip/smcv/bug6977' into 'main'
scaling test: Fix intermittent failure with alpha = 0

Closes #6977

See merge request GNOME/gtk!7684
2024-09-03 15:27:20 +00:00
Matthias Clasen 5567934fc9 Merge branch 'wip/smcv/misc-realize' into 'main'
testsuite: If gsk_renderer_realize() fails, say why

See merge request GNOME/gtk!7686
2024-09-03 11:11:11 +00:00
Daniel Mustieles 63bece1fe7 Update Spanish translation 2024-09-03 09:25:56 +00:00
Simon McVittie ad3c285fc6 scaling test: Show the input and expected average after each failed test
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-09-03 10:19:16 +01:00
Simon McVittie 47c461b25b testsuite: Show pixel format of texture pixels that differ
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-09-03 10:05:32 +01:00
Simon McVittie 97f0aa7875 testsuite: Share memorytexture version of compare_textures()
Unlike the version in scaling.c, this one incorporates debugging code
to print the pixels that differ.

Signed-off-by: Simon McVittie <smcv@debian.org>
2024-09-03 10:05:32 +01:00
Simon McVittie 8e54460a48 testsuite: Extract common code from gdk/memorytexture and gsk/scaling
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-09-03 10:05:32 +01:00
Simon McVittie 4c4d260199 scaling test: Avoid dividing zero by zero
If all four of the random colours have alpha channel exactly 0.0,
then the computed premultiplied average will also be zero.
Normalize the expected colour to (0,0,0,0) rather than (NaN,NaN,NaN,0).

Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/6977
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-09-03 10:03:58 +01:00
Jürgen Benvenuti b18c6b5781 Update German translation 2024-09-03 05:06:47 +00:00
Enokilis d76e241558 Fixed typo that prevented theme update in the GTK4 demo. 2024-09-03 02:34:49 +00:00
Simon McVittie 13cbd9fcc7 testsuite: If gsk_renderer_realize() fails, say why
Showing the error message is usually more useful for debugging than
just saying that something failed.

Signed-off-by: Simon McVittie <smcv@debian.org>
2024-09-03 02:44:24 +01:00
Matthias Clasen 6e54589d9e Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Cosmetics

See merge request GNOME/gtk!7678
2024-09-02 22:16:01 +00:00
Fran Dieguez c781c0ff24 Update Galician translation 2024-09-02 17:23:04 +00:00
Philip Withnall 105ff3a25f gtklistitem: Fix a minor typo in the docs
Ye olde worlde typoe.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-09-02 16:47:47 +01:00
Benjamin Otte 0277e26152 Merge branch 'wip/otte/for-main' into 'main'
gpu: Use right GL context when exporting texture

See merge request GNOME/gtk!7679
2024-09-01 23:08:49 +00:00
Benjamin Otte 563cce5530 gsk: Use gsk_rect_init_offset() everywhere
... and make it use a graphene_point_t as argument, because that's what
the callers want.
2024-09-02 00:22:37 +02:00
Benjamin Otte b0e4be7fda rendernode: Colors should not influence depth decisions
Depth of a rendernode should be determined by the textures used and the
compositing colorstate requirements.
Colors influence the colorstate choice, so they indirectly influence the
depth, but they should not influence the depth directly.

Otherwise a single color in a border being rec2100-pq would make us
switch to 16bit float.

Also remove gdk_color_get_depth(), because it was only used here and
because again: Colors should not influence depth decisions.
2024-09-02 00:22:37 +02:00
Benjamin Otte e29701a203 gl: Handle GDK_MEMORY_NONE depth
In rare circumstances a rendernode can be MEMORY_NONE and we don't want
to render it as a float texture then.
2024-09-02 00:22:37 +02:00
Benjamin Otte 6a1cd87480 gpu: Use builder for memory texture 2024-09-01 22:49:34 +02:00
Benjamin Otte 3db858b45f window: Remove unused code 2024-09-01 22:49:34 +02:00
Benjamin Otte 49ee69f316 gpu: Use right GL context when exporting texture
We want to use the display's context on the resulting texture,
but we do not want to use it for the stufff we need to do while
exporting - most importantly the GLsync.

Fixes #6976
2024-09-01 22:49:34 +02:00
Aurimas Černius b43e0a3423 Update Lithuanian translation 2024-09-01 20:16:16 +00:00
Arjan Molenaar 8054099d0e Merge branch 'amolenaar/macos-maximize-and-transparency' into 'main'
macos: Fix maximizing windows

See merge request GNOME/gtk!7650
2024-09-01 19:22:38 +00:00
Matthias Clasen a8e49cc21f gtk-demo: Cosmetics
Don't print out when the user just canceled the print dialog,
in the fill and stroke demo.
2024-09-01 10:33:27 -04:00
Matthias Clasen 5f1ec18550 Merge branch 'popover-menu-resize' into 'main'
MenuSectionBox: Increase priority of separator sync function

Closes #5166

See merge request GNOME/gtk!6699
2024-09-01 14:04:07 +00:00
Matthias Clasen 6b5c5714e5 Merge branch 'gdksurface-broadway-fix' into 'main'
gdk: Add missed compute_size and request_layout vfunc to GdkBroadwaySurface

Closes #4527

See merge request GNOME/gtk!4277
2024-09-01 13:48:22 +00:00
Maxim Zakharov 9a8e5b07ae gdk: Add missed compute_size and request_layout vfunc to GdkBroadwaySurface 2024-09-01 13:48:22 +00:00
Matthias Clasen 3f4cf65686 Merge branch 'fix_model_button_states' into 'main'
a11y: Set expanded states properly when switching to a submenu

See merge request GNOME/gtk!7305
2024-09-01 11:59:47 +00:00
Lukáš Tyrychtr 345eca1efe a11y: Set expanded states properly when switching to a submenu 2024-09-01 11:59:47 +00:00
Matthias Clasen 166afbf8e8 Merge branch 'ebassi/a11y-event-listeners' into 'main'
a11y: Add missing value free function

See merge request GNOME/gtk!7677
2024-09-01 11:20:56 +00:00
Matthias Clasen 9120d1c834 Merge branch 'proper_focus_during_popover_cascaded_popdown' into 'main'
a11y: Ensure the focus lands on the correct element during cascaded popover popdown

See merge request GNOME/gtk!7318
2024-08-31 23:09:04 +00:00
Matthias Clasen 083f9e7723 Merge branch 'numeric-spinbutton-no-emoji' into 'main'
spinbutton: No emoji for numeric input

See merge request GNOME/gtk!7676
2024-08-31 23:04:56 +00:00
Emmanuele Bassi a0cfc6c404 a11y: Turn criticals into debugging messages
It seems we can get spurious de-registrations, so let's avoid spamming
the logs, and also avoid crashes from applications whose maintainer
decided to turn all critical warnings into assertions.
2024-08-31 23:41:21 +01:00
Matthias Clasen edc50c85ef spinbutton: No emoji for numeric input
Continuing from cfc871f031, when a spin button is in numeric mode,
set the no-emoji input hint, since Emoji aren't useful in numeric
input.
2024-08-31 18:23:49 -04:00
Matthias Clasen 4794bc3db6 Remove duplicate semicolon 2024-08-31 22:16:25 +00:00
Lukáš Tyrychtr 2299c02639 a11y: Ensure the focus lands on the correct element during cascaded popover popdown
Previously it ended on the immediate parent of the lowest level popover,
which was not good, as it very likely was some even already hidden widget, or
at least, the a11y machinery thought so.
2024-08-31 22:16:25 +00:00
Emmanuele Bassi ae13a82a9a a11y: Add missing value free function
We allocate the reference counter, so we need to free it.
2024-08-31 22:40:16 +01:00
Matthias Clasen 6c88713f82 Merge branch 'emoji-multi-click' into 'main'
emojichooser: Avoid extra work

Closes #6336

See merge request GNOME/gtk!7675
2024-08-31 21:34:29 +00:00
Matthias Clasen 5c6fedae17 emojichooser: Avoid extra work
When selecting an emoji in the recent section, there is no need
to add it to the recent section again. This avoids a sequence of
unfortunate events, where we reconstruct the entire recent section,
thereby removing the focus child, causing the focus to revert to
the entry, causing the entry to select the entire text. In the
case of Ctrl-clicking to select multiple Emoji, the effect is that
the section Emoji will replace the entire entry text, which is
suprising and unintended.

Fixes: #6336
2024-08-31 16:28:20 -04:00
Hugo Carvalho 5faa1c3d6e Update Portuguese translation 2024-08-31 20:14:46 +00:00
Matthias Clasen 074bcd33be Merge branch 'x11-input-setup-mess' into 'main'
x11: Cosmetics

Closes #6840

See merge request GNOME/gtk!7674
2024-08-31 16:57:55 +00:00
Matthias Clasen 5b6b42b5a9 x11: Fix initialization mess
When prepare_gl fails in the right way (or the wrong way?), we
end up creating the leader window twice, and as a side effect,
creating two instances of the "Virtual core pointer" device, which
is bad news for grabs.

Fixes: #6840
2024-08-31 11:28:52 -04:00
Matthias Clasen ae8a06cdca x11: Cosmetics
Don't return FALSE from a function returning a pointer.
2024-08-31 11:28:52 -04:00
Carlos Garnacho cba4ce03e5 gtkwidget: Check for destroyed controllers while propagating state
Keep a hard copy of the widget event controllers to handle state
changes across, and check for controllers that might have been detached.
This makes us:

- Tiptoe over controllers that might have been removed directly or
  indirectly as a result of a signal emitted here, which is great and
  fixes possible crashes.
- Ignore new controllers that might have been added in the handling
  of these signals, which is fair enough since these controllers did
  not handle any input related to the state change.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/6924
2024-08-31 16:37:58 +02:00
Carlos Garnacho 5e82ad3ea7 gtkeventcontroller: Reset controller when detaching from a widget
We want internal state ensured to be forgotten, and the controller
to be ready for use for any future time it might be added to a
widget again.
2024-08-31 16:37:35 +02:00
Piotr Drąg c9bbf5820b Update Polish translation 2024-08-31 15:00:38 +02:00
Simon McVittie bb0b764172 Merge branch 'wip/smcv/bug6971' into 'main'
testsuite: Add a suite for tests that require /dev/udmabuf

See merge request GNOME/gtk!7671
2024-08-31 11:53:32 +00:00
Matthias Clasen ae8e9ef650 Merge branch 'vulkan-dnd-offset' into 'main'
vulkan: Use wl_surface_offset

Closes #6972

See merge request GNOME/gtk!7673
2024-08-31 11:47:53 +00:00
Matthias Clasen 8df7ff75bb Merge branch 'radio_role_for_check_button_groups' into 'main'
a11y: Set the correct role for check button groups

See merge request GNOME/gtk!6551
2024-08-31 11:20:16 +00:00
Matthias Clasen bbfd8e0e89 vulkan: Use wl_surface_offset
Call wl_surface_offset in end_frame to apply the offset for drag
surfaces. This matches what the GL draw context already does, and
it fixes drag surfaces jumping at the beginning of the drag.

Fixes: #6972
2024-08-31 07:15:08 -04:00
Matthias Clasen 467212877f Merge branch 'wip/smcv/css-endian' into 'main'
CSS: Fix test failures on 64-bit big-endian machines

See merge request GNOME/gtk!7672
2024-08-31 11:04:45 +00:00
Simon McVittie 204b8857a1 testsuite: Add a suite for tests that require /dev/udmabuf
On GTK's official upstream CI, all Linux runners are meant to have
/dev/udmabuf available, so this should pass. On developer machines or
downstream build environments, this can't be guaranteed (not all kernel
configurations offer that device, and on those that do, an autobuilder
might not have access to it) so make it possible to skip this with
`--no-suite=needs-udmabuf`.

Any future tests that rely on /dev/udmabuf (as opposed to using it for
optional better coverage if available, like replay-node does) can be
aded to the same suite.

Signed-off-by: Simon McVittie <smcv@debian.org>
2024-08-31 10:22:49 +01:00
Simon McVittie a524524ffd gtkcssprovider: Fix sorting of custom property IDs on 64-bit big-endian
This function is used to sort a GPtrArray of "pointers" which are
actually GINT_TO_POINTER (id), so a and b are pointers to pointer-sized
quantities.

Previously it was assuming that both were int-sized quantities,
dereferencing them to get the first sizeof(int) bytes, and then
redundantly casting those bytes to int. However, on a 64-bit big-endian
platform, the first few bytes of a larger-than-int quantity are the
most significant part, in practice 0, causing an out-of-bounds array
access and a crash. This was visible in the
`gtk:css / parser variables.css` automated test.

Bug-Debian: https://bugs.debian.org/1079546
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-08-31 02:26:57 +01:00
Simon McVittie 3ef1f448a3 gtkcssvariableset: Fix listing IDs on big-endian machines
Previously this code assumed that if we have an int stored in a hash
table via GINT_TO_POINTER, we can retrieve the pointer value and treat
its first sizeof(int) bytes as an item to append to a GArray of int.

However, on a 64-bit big-endian system, the first sizeof(int)
bytes of the pointer will be zero, which is not a valid ID for a
GtkCssCustomPropertyPool, causing an out-of-bounds array access and
a crash. This was visible in the `gtk:css / style` automated test.

Bug-Debian: https://bugs.debian.org/1079546
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-08-31 02:04:00 +01:00
Matthias Clasen a5df8f2f35 Merge branch 'dead-hamza-yay' into 'main'
Update a script slightly

Closes #6968

See merge request GNOME/gtk!7670
2024-08-31 00:14:25 +00:00
Emmanuele Bassi b56a8c7f88 Merge branch 'wip/fina/accessible-atspi-fix-error-message' into 'main'
a11y: Consistently use list type for errormessage relation

See merge request GNOME/gtk!7528
2024-08-31 00:08:52 +00:00
Fina Wilke 649782b547 a11y: Consistently use list type for errormessage relation
This more closely matches the spec. This is an API break, however the
atspi backend already assumed that this was a list, and would throw
criticals whenever this relation was set. Therefore it can be assumed
that this relation was not previously in active use.
2024-08-30 20:22:59 +00:00
Matthias Clasen 97245e9baa Merge branch 'ebassi/lazier-a11y' into 'main'
a11y: Watch EventListenerRegistered/Deregistered signals

See merge request GNOME/gtk!7298
2024-08-30 20:17:17 +00:00
Matthias Clasen 0f3c27c8a5 composetable: Handle dead_hamza
A new dead key has been invented.

Fixes: #6968
2024-08-30 16:10:20 -04:00
Matthias Clasen 3273637179 Update keyname tables 2024-08-30 16:03:40 -04:00
Matthias Clasen 1eaa0e9b74 gdkkeysyms.h: Regenerate for libX11 1.8.10 2024-08-30 15:52:58 -04:00
Matthias Clasen 28d1bce2d4 Update a script slightly
Make gdkkeysyms-update.pl use #pragma once, as our headers
do nowadays.
2024-08-30 15:52:14 -04:00
Emmanuele Bassi b8072d8562 a11y: Add a check for sandboxed accessibility bus
When sandboxed, the accessibility bus needs a recent version of Flatpak
and its D-Bus proxy in order to relay event registrations.
2024-08-30 14:24:55 +01:00
Luca Bacci da9886d822 Merge branch 'fix-gdk-win32-display-name' into 'main'
GDK/Win32: Fix gdk_display_get_name()

See merge request GNOME/gtk!7664
2024-08-30 12:32:16 +00:00
Matthias Clasen 747f2e5af6 Merge branch 'demos-window-icons' into 'main'
demos: Set icon for the windows

See merge request GNOME/gtk!7661
2024-08-30 11:14:18 +00:00
Matthias Clasen aeb3ee0969 Merge branch 'update-on-print-comboentry-change' into 'main'
printeroptionwidget: Update on combo-entry change

Closes #6782

See merge request GNOME/gtk!7532
2024-08-30 11:11:55 +00:00
Benjamin Otte e248f1a4b5 Merge branch 'wip/otte/compare-render' into 'main'
Bring compare-render into 21st century

See merge request GNOME/gtk!7648
2024-08-30 11:00:36 +00:00
Arjan Molenaar d23833285e macos: Set transparent background for toplevel window
Toplevel window background is almost transparent.
For fully transparent windows the (macOS) shadow calculatation
becomes really slow.
2024-08-30 12:06:18 +02:00
Daniel Rusek ff9fe6857f Update Czech translation 2024-08-30 09:49:04 +00:00
Emmanuele Bassi 58f2d3fbe7 a11y: Add reference counting to event listeners
Event listeners can register themselves multiple times, and deregister
themselves as well. We need to remove an event listener only if it
dropped all its events.
2024-08-30 09:27:39 +01:00
Emmanuele Bassi d9f75581be a11y: Get event listeners on root registration
We ask the AT-SPI registry for event listeners already registered when
connecting the root object, in case an AT is running.
2024-08-30 09:27:39 +01:00
Emmanuele Bassi 307efe2172 a11y: Do not emit event signals if there are no listeners
Now that we track event listeners, we can skip the accessibility event
emission altogether if we know nothing is on the other side.
2024-08-30 09:27:39 +01:00
Emmanuele Bassi 4ea4dc9176 a11y: Watch EventListenerRegistered/Deregistered signals
Assistive technologies using AT-SPI typically register themselves on the
accessibility bus through the org.a11y.atspi.Registry.RegisterEvent
method, which will emit the EventListenerRegistered signal. We can use
that signal (and its corresponding EventListenerDeregistered sibling) to
know whether there is at least an AT on the other side of the
accessibility bus.
2024-08-30 09:27:39 +01:00
Benjamin Otte fa25015e8c compare-render: Appease clang and MSVC
clang wants consts not initialized from consts.

MSVC can't deal with arrays in initializers.
2024-08-30 06:28:58 +02:00
Benjamin Otte 296b6b1ed5 compare-render: Make the test runner generic
Instead of manually running each of the tests, use a loop and just
invoke the test runner.
2024-08-30 06:28:58 +02:00
Benjamin Otte b88fe301be compare-render: Run clip tests using new runner
This requires adding infrastructure to generate per-test data, so that
the random clip rect can be computed and reused for both test and
reference generation.

So add this infrastructure.
2024-08-30 06:28:58 +02:00
Benjamin Otte ffd836e6f4 compare-render: Run replay tests using new runner 2024-08-30 06:28:58 +02:00
Benjamin Otte 457cf66d0d compare-render: Run mask tests using new runner 2024-08-30 06:28:58 +02:00
Benjamin Otte 36765745a1 compare-render: Run rotate tests using new runner 2024-08-30 06:28:58 +02:00
Benjamin Otte 46c19a3d28 compare-render: Run repeat tests using new runner 2024-08-30 06:28:58 +02:00
Benjamin Otte 6cf928eb6c compare-render: Run flip tests using new runner 2024-08-30 06:28:58 +02:00
Benjamin Otte a0d076f01a compare-render: Run plain tests using new runner
Extend the runner so NULL is accepted as a method to create
reference/test, in which case the unmodified original will be used.
2024-08-30 06:28:58 +02:00
Benjamin Otte 37c744759c compare-render: Add a generic test runner
... and port the colorflip test.

This is so we can factor out generic parts of the code. This allows
making changes easier to those parts, like if we want to introduce
rules for what colorstates and memory depths to do diffs in.
2024-08-30 06:28:58 +02:00
Benjamin Otte 277a05eb8c compare-render: Use consistent naming for files
Instead of the adverb, use the verb term. That matches the argument
passed on the cmdline, so only one string is necessary.
2024-08-30 06:28:58 +02:00
Chun-wei Fan 0376e4668c GDK/Win32: Fix gdk_display_get_name()
We switched to using the Unicode (UTF-16) versions of the Windows API by
default, so we also obtain the display name in UTF-16 form as well.

This updates the implementation in the Windows backend so that we
properly acquire the names that we need in UTF-16, and then convert the
results to UTF-8, which is what we use in GTK/GLib.
2024-08-30 08:47:01 +08:00
Changwoo Ryu 9d5652de64 Update Korean translation 2024-08-29 23:29:49 +00:00
Matthias Clasen bb109b5d9e Merge branch 'matthiasc/for-main' into 'main'
docs: Mention that Broadway is an experiment

See merge request GNOME/gtk!7665
2024-08-29 22:52:39 +00:00
Benjamin Otte d630ddd182 compare-render: Pick colorstate from reference when comparing
When comparing textures, always pick the colorstate from the reference
texture. This allows us to define what color state we expect.

For now, there's no check that the color states are equal, because they
don't really have to be as long as the pixels are.
2024-08-29 20:34:23 +02:00
Benjamin Otte e268041a42 reftest-compare: Respect color states when diffing
Always pick the color state from texture1 and download the data and
generate the diff in that color state.

That now means the order of the 2 arguments matters.
2024-08-29 20:34:23 +02:00
Benjamin Otte f9cbeeeedc reftest-compare: Compare high depth images in high depth
I first tried porting everything to float, but it turns out that that
makes a compare-render run (with all 1520 tests succeeding) 9s slower
so I decided to keep the existing U8 code.

A side benefit is that saving the diff to PNG will continue creating
U8 PNGs.
2024-08-29 20:34:23 +02:00
Benjamin Otte 62542f836f compare-render: Create rotated reference without gdk-pixbuf
We use the renderer to create the reference for the rotate test by
applying the same rotate transform to the reference image instead of the
tested node.

This is somewhat suboptimal because they run very similar codepaths, but
this method works with high bit depth content and different colorstates

This concludes the port away from gdk-pixbuf and means that all rendered
content and reference images can now use high bit depth and colorstates.
2024-08-29 20:34:23 +02:00
Benjamin Otte 6d4c74fdce compare-render: Create masked reference without gdk-pixbuf
We use the renderer to create the reference for the mask test by
rendering the reference clipped.
2024-08-29 20:34:23 +02:00
Benjamin Otte 3dac4a01c6 compare-render: Create colorflipped reference without gdk-pixbuf
We use the renderer to create the reference for the colorflip test by
applying the same colorflip matrix to the reference image instead of the
tested node.

This is somewhat suboptimal because they run very similar codepaths, but
this method works with high bit depth content and different colorstates
2024-08-29 20:34:23 +02:00
Benjamin Otte f598ec00f5 compare-render: Create clipped reference without gdk-pixbuf
We use the renderer to create the reference for the clip test by
applying the same clip node to the reference image instead of the
tested node.

This is somewhat suboptimal because they run very similar codepaths, but
this method works with high bit depth content and different colorstates
2024-08-29 20:34:23 +02:00
Benjamin Otte 6fc18f4b37 compare-render: Create flipped reference without gdk-pixbuf
We use the renderer to create the reference for the flip test by
applying the same transform node to the reference image instead of the
tested node.

This is somewhat suboptimal because they run very similar codepaths, but
this method works with high bit depth content and different colorstates
and the gdk-pixbuf method does not.
2024-08-29 20:34:23 +02:00
Benjamin Otte 8c9f16fa7a compare-render: Create repeated reference without gdk-pixbuf
We use the renderer to create the reference for the repeat test by
applying the same repeat node to the reference image instead of the
tested node.

This is somewhat suboptimal because they run very similar codepaths, but
this method works with high bit depth content and different colorstates
and the gdk-pixbuf method does not.
2024-08-29 20:34:23 +02:00
Benjamin Otte 001ca0a982 compare-render: Split test variant name from extension name
This is preparation for further patches where we want to use a common
codepath for all variants.
2024-08-29 20:34:23 +02:00
Benjamin Otte b23c0248ba compare-render: Don't load reference file twice
Instead, convert from texture to pixbuf.

Ultimately, we want to avoid pixbufs entirely, but we're not there yet.
2024-08-29 20:34:23 +02:00
Benjamin Otte c4c352facc compare-render: Use TAP for the test 2024-08-29 20:34:23 +02:00
Benjamin Otte 30af6d1159 compare-render: Turn into a real test
Use g_test_run() like any other test.
2024-08-29 20:34:23 +02:00
Benjamin Otte 1fac3fe44e compare-render: Compare to reference texture
There's no need to render the original node and compare to its result,
we know that that is equal to the reference image.

Avoids duplicate renderings.
2024-08-29 20:34:23 +02:00
Benjamin Otte 8ac6c08f00 compare-render: Create the reference texture at startup
This allows exiting early when it doesn't exist.
2024-08-29 20:34:23 +02:00
Benjamin Otte 5b62f29b5e compare-render: Rename variables
They conflict with the next commit otherwise.
2024-08-29 20:34:23 +02:00
Benjamin Otte 817cfb09f8 compare-render: Failing to load an image is a failure 2024-08-29 20:34:23 +02:00
Benjamin Otte 8da478ab34 testsuite: Disable a bunch of tests on the GL renderer
We want to generate reference images with the renderers and the GL
renderer can't deal with textures well enough to generate these
reference images.
2024-08-29 20:34:20 +02:00
Matthias Clasen 8d866c5980 docs: Mention that Broadway is an experiment 2024-08-29 07:35:17 -04:00
Jordi Mas 467e622778 Update Catalan translation 2024-08-29 07:13:12 +02:00
Benjamin Otte aa81df921b testsuite: Correct values for red
The value used was for rec2020 (9/14/0/1), not rec2100-pq (9/16/0/1).
2024-08-29 03:01:30 +02:00
Benjamin Otte 328020b241 Merge branch 'wip/otte/for-main' into 'main'
gl: Fix initial EGL context creation on X11

Closes #6964

See merge request GNOME/gtk!7663
2024-08-29 00:36:19 +00:00
Benjamin Otte 41cd0c6f13 gl: Fix initial EGL context creation on X11
After commit 447bc18c48 EGL on X11 broke.

But the handling of the GL context also was quite awkward because it was
unclear who was responsible for ensuring it got reset.

Change that by making gdk_gl_context_clear_current_if_surface() return
the context (with a reference because it might be the last reference) it
had unset, so that after changing EGL properties the code that caused
the clearing can re-make it current.

This moves the responsibility to the actual code that is dealing with
updating properties and frees the outer layers of code from that task.

And that means the X11 EGL code doesn't need to care and the code in the
Wayland backend that did care can be removed.

Related: !7662
Fixes: #6964 on X11
2024-08-29 01:31:47 +02:00
Benjamin Otte db02abe54e Merge branch 'wip/otte/to-make-current-or-not-make-current' into 'main'
wayland: Rework how we handle EGLWindows

Closes #6964

See merge request GNOME/gtk!7662
2024-08-28 18:14:03 +00:00
Benjamin Otte 447bc18c48 wayland: Rework how we handle EGLWindows
This essentially reverts the changes from
c230546a2c but implies new semantics.

Namely, surface-attached contexts can now be bound to EGL_NO_SURFACE if
the windowing system isn't ready yet.

It is the task of the windowing system to make sure the context is
properly rebound when the contents become available.
We ensure this by checking in begin_frame() if we created the EGL window
and if we did, we make_current(). This works because creating the EGL
window creates the EGL surface and that does a clear_current(), so this
is always going to have the desired effect of re-making the current
context.

It is very convoluted though.

Fixes: #6964
Related: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11784
2024-08-28 19:09:45 +02:00
Balló György 283c66251b demos: Set icon for the windows 2024-08-28 17:02:44 +02:00
Luca Bacci 63b68d2f5e Merge branch 'gdk-win32-incremental-rendering-fixes' into 'main'
GdkWin32: Incremental rendering fixes

See merge request GNOME/gtk!7655
2024-08-28 09:30:29 +00:00
Marek Kašík 7e09a5648a Merge branch gtk:main into update-on-print-comboentry-change 2024-08-28 09:12:42 +00:00
Lukáš Tyrychtr 4a0b833548 Apply some review feedback
Namely be sure to set the new role of the widget in all cases
and do it always, even when we need to recreate the AT context.
2024-08-28 10:42:17 +02:00
Lukáš Tyrychtr 86bec01640 a11y: Set the correct role for check button groups
Up-until now, when a group of check boxes was created, they were
still presented as checkboxes, even they semantically were radio buttons.

Note that this approach will not always work, because we're not recreating the
AT context, but it works for the usual pattern where the group is set during
object construction
2024-08-28 10:27:46 +02:00
Matthias Clasen b07a2a968d Merge branch 'wayland-destroy-ordering' into 'main'
wayland: Fix an ordering problem

Closes #6965

See merge request GNOME/gtk!7658
2024-08-28 01:14:45 +00:00
Benjamin Otte 997d553520 Merge branch 'wip/corey/file-chooser-select' into 'main'
Implement set_selection in GtkSingleSelection

See merge request GNOME/gtk!6376
2024-08-28 00:24:51 +00:00
Corey Berla 8eb05850cb single-selection: Don't allow unselecting with autoselect
According to the documentation, when autoselect is TRUE it will
"will disallow unselecting the current item".
2024-08-27 21:18:56 +00:00
Corey Berla 98eaec99ee gtksingleselection: Implement unselect_all
The default implementation of unselect_all calls
set_selection, which SingleSelection does not have
an implementation for (it's unclear what it would
do with multiple selections).  Add a straightforward
implementation for unselect_all.
2024-08-27 21:18:56 +00:00
Matthias Clasen 8fb946f6e8 Merge branch 'scale-hotfix' into 'main'
theme: Fix positioning of scale values (hotfix!)

See merge request GNOME/gtk!7656
2024-08-27 21:07:40 +00:00
Matthias Clasen a10670c991 wayland: Fix an ordering problem
When setting an event queue on a proxy, we should not destroy
the queue before the proxy.

May fix: #6965
2024-08-27 16:35:46 -04:00
Matthijs Velsink 2e2dab9c3d theme: Fix scale sizing during .fine-tune
Using fine-tune on a GtkScale is maybe a little known feature, but it's
also quite wonky. It causes marks, values, and sliders to jump around
when activated. This is because it's implemented with less padding
around the scale and an increased minimum size.

For example a value drawn left or right of a horizontal scale, as then
the height of the scale is the value height plus padding. So fine-tuning
compresses the scale vertically.

We can fix this by adding negative margin on the trough instead, without
any changes to the padding or minimum size of the scale.

Also, because the trough now grows 3px in all directions, the slider has
to do that to, so that margin increases by 3px in all directions
compared to what it was, also for the cases with marks.

One last minor detail is that for vertical scales, fine-tuning causes
the height of the mark indicators to grow, whereas their width should
decrease. That's also fixed.
2024-08-27 22:35:02 +02:00
Matthijs Velsink a6eea6ba3c theme: Fix positioning of scale values
Commit d58b545f fixed a double counting of value size, but didn't check
whether that actually looked great. It doesn't.

Because the slider has negative margins, we need to add margin to the
value if it's on a side with no marks. If it is on a side with marks,
the scale will make it touch the marks. We therefore apply a mark's size
of margin to have the value be in the same place, with or without marks.
2024-08-27 22:33:54 +02:00
Danial Behzadi 48f347e62b Update Persian translation 2024-08-27 10:34:00 +00:00
Matthijs Velsink ed1c047cf2 theme: Fix positioning of scale values
Commit d58b545f fixed a double counting of value size, but didn't check
whether that actually looked great. It doesn't.

Because the slider has negative margins, we need to add margin to the
value if it's on a side with no marks. If it is on a side with marks,
the scale will make it touch the marks. We therefore apply a mark's size
of margin to have the value be in the same place, with or without marks.
2024-08-27 04:47:49 +02:00
Matthias Clasen ea9c2a72d9 Post-release version bump 2024-08-26 19:55:03 -04:00
Luca Bacci f4bd883003 GdkWin32: Try to call _gdk_surface_update_size() only when the size actually changed
Otherwise we adapt Vulkan and OpenGL swap chains a lot and we effectively
disable incremental rendering.

Note that the fix is not complete.
2024-08-26 17:05:19 +02:00
Luca Bacci 0fcdadc531 GdkWin32GLContextWGL: Use the previous frames paint regions kept by GdkGLContext
We do this because:

 a) The parent class (GdkGLContext) already stores the paint regions of
    previous frames, no need to do the same.
 b) The painted region passed to end_frame () includes the backbuffer's
    damage region, so it's not really what we want.

This also fixes a leak of cairo_region_t that I introduced by mistake
in !7418
2024-08-26 17:05:13 +02:00
Arjan Molenaar ffeca06bd6 macos: Revert "macos: fix window transparency"
This reverts commit 84847e46fa.

It breaks maximizing windows.
2024-08-25 12:00:51 +02:00
Marek Kasik 83035c1d4b printeroptionwidget: Maintain cursor position in combo-entry
Maintain cursor position even if the text in the entry has been filtered.
This is achieved by maintaining the same position with respect to
the end of the text buffer as we suppose that the text after the cursor
hasn't changed. This is measured in characters not bytes.

Fixes #6782
2024-08-07 20:26:57 +02:00
Marek Kasik 6435d5083a printeroptionwidget: Update on combo-entry change
Connect to "changed" signal of the entry displayed with combobox
for some options (e.g. watermark text or passcode). This ensures
that the strings are propagated to the printer backend.

Fixes #6782
2024-07-31 16:59:11 +02:00
Benjamin Otte 3a8e1c55e1 listitemfactory: Don't rebind on position or selection changes
When the item doesn't change and only the position / selection state,
then the signal list item factory should not emit bind + unbind signals.

This used to work, but probably broke while refactoring for ColumnView
during 4.10.

This caused excessive rebinding when items got inserted at the top of a
list instead of add the end.
2024-07-07 05:38:22 +02:00
robxnano 4da8d39ec5 MenuSectionBox: Increase priority of separator sync function
This ensures that the separators are made visible before a popover
menu is shown. Previously the menu would jump in size after it
appeared.

Closes https://gitlab.gnome.org/GNOME/gtk/-/issues/5166
2023-12-14 18:57:04 +00:00
571 changed files with 56679 additions and 28802 deletions
+5 -7
View File
@@ -68,7 +68,6 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gl.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles2.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
paths:
@@ -119,8 +118,9 @@ release-build:
script:
- .gitlab-ci/show-info-linux.sh
- mkdir _install
- export PATH="$HOME/.local/bin:${CI_PROJECT_DIR}/_install/bin:$PATH"
- .gitlab-ci/install-meson-project.sh --prefix ${CI_PROJECT_DIR}/_install https://gitlab.gnome.org/jadahl/catch.git main
# don't use catch by default, since it causes sporadic test failures
# - export PATH="$HOME/.local/bin:${CI_PROJECT_DIR}/_install/bin:$PATH"
# - .gitlab-ci/install-meson-project.sh --prefix ${CI_PROJECT_DIR}/_install https://gitlab.gnome.org/jadahl/catch.git main
- meson subprojects download
- meson subprojects update --reset
- meson setup
@@ -135,8 +135,6 @@ release-build:
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- .gitlab-ci/run-tests.sh _build wayland gtk
# only repeat test runs that are likely affected by test setups
- .gitlab-ci/run-tests.sh _build wayland_gles2 gtk:gdk,gtk:gsk-gl
fedora-clang:
extends: .build-fedora-default
@@ -200,11 +198,11 @@ fedora-mingw64:
- subprojects/libepoxy/
- subprojects/pango/
msys2-mingw64:
msys2-ucrt64:
extends: .mingw-defaults
needs: []
variables:
MSYSTEM: "MINGW64"
MSYSTEM: "UCRT64"
CHERE_INVOKING: "yes"
artifacts:
when: always
+21 -27
View File
@@ -2,12 +2,6 @@
set -e
if [[ "$MSYSTEM" == "MINGW32" ]]; then
export MSYS2_ARCH="i686"
else
export MSYS2_ARCH="x86_64"
fi
# Update everything
pacman --noconfirm -Suy
@@ -15,27 +9,27 @@ pacman --noconfirm -Suy
pacman --noconfirm -S --needed \
base-devel \
git \
mingw-w64-$MSYS2_ARCH-cc \
mingw-w64-$MSYS2_ARCH-ccache \
mingw-w64-$MSYS2_ARCH-pkgconf \
mingw-w64-$MSYS2_ARCH-gobject-introspection \
mingw-w64-$MSYS2_ARCH-meson \
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
mingw-w64-$MSYS2_ARCH-atk \
mingw-w64-$MSYS2_ARCH-cairo \
mingw-w64-$MSYS2_ARCH-gdk-pixbuf2 \
mingw-w64-$MSYS2_ARCH-glib2 \
mingw-w64-$MSYS2_ARCH-graphene \
mingw-w64-$MSYS2_ARCH-json-glib \
mingw-w64-$MSYS2_ARCH-libepoxy \
mingw-w64-$MSYS2_ARCH-pango \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \
mingw-w64-$MSYS2_ARCH-python-gobject \
mingw-w64-$MSYS2_ARCH-shaderc \
mingw-w64-$MSYS2_ARCH-vulkan \
mingw-w64-$MSYS2_ARCH-vulkan-headers
${MINGW_PACKAGE_PREFIX}-cc \
${MINGW_PACKAGE_PREFIX}-ccache \
${MINGW_PACKAGE_PREFIX}-pkgconf \
${MINGW_PACKAGE_PREFIX}-gobject-introspection \
${MINGW_PACKAGE_PREFIX}-meson \
${MINGW_PACKAGE_PREFIX}-adwaita-icon-theme \
${MINGW_PACKAGE_PREFIX}-atk \
${MINGW_PACKAGE_PREFIX}-cairo \
${MINGW_PACKAGE_PREFIX}-gdk-pixbuf2 \
${MINGW_PACKAGE_PREFIX}-glib2 \
${MINGW_PACKAGE_PREFIX}-graphene \
${MINGW_PACKAGE_PREFIX}-json-glib \
${MINGW_PACKAGE_PREFIX}-libepoxy \
${MINGW_PACKAGE_PREFIX}-pango \
${MINGW_PACKAGE_PREFIX}-fribidi \
${MINGW_PACKAGE_PREFIX}-gst-plugins-bad-libs \
${MINGW_PACKAGE_PREFIX}-shared-mime-info \
${MINGW_PACKAGE_PREFIX}-python-gobject \
${MINGW_PACKAGE_PREFIX}-shaderc \
${MINGW_PACKAGE_PREFIX}-vulkan \
${MINGW_PACKAGE_PREFIX}-vulkan-headers
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"
+3 -1
View File
@@ -34,7 +34,9 @@
<!--
- Which version of GTK you are using
- What operating system and version
- For Linux, which distribution
- What windowing system (X11 or Wayland)
- What graphics driver / mesa version
- For Linux, which distribution
- If you built GTK yourself, the list of options used to configure the build
-->
+184
View File
@@ -1,3 +1,187 @@
Overview of Changes in 4.17.0, xx-xx-xxxx
=========================================
Overview of Changes in 4.16.2, 09-25-2024
=========================================
* GtkLabel:
- Fix centered text in RTL
* Gsk:
- Speed up some Vulkan operations
- Improve startup speed by avoiding initialization
of GL and Vulkan in most cases
- Reduce critials at startup to warnings
- Fix a crash on startup with some Vulkan drivers
- Fix a big texture leak in NGL
* Gdk:
- Speed up memory format conversions
* Wayland:
- Be more careful with mimetypes during DND or copy-paste
* Tools:
- builder-tool: Improve conversion of boxes
* Translation updates:
Brazilian Portuguese
Bulgarian
Catalan
Chinese (China)
Georgian
German
Hebrew
Indonesian
Persian
Polish
Portuguese
Slovenian
Spanish
Turkish
Ukrainian
Overview of Changes in 4.16.1, 09-16-2024
=========================================
* GtkFileChooser:
- Plug a memory leak
* GtkCalendar:
- Avoid ending up with invalid dates
* Printing:
- Fix initial printer selection in the print dialog
* Gsk:
- Fix shadows for opaque textures
- Fix a crash in a corner case
* Css:
- Make relative paths work again in theme files
* Accessibility:
- Fix detection of the Flatpak portal
* MacOS:
- Fix keyboard input in popovers
- Keep DND icons above regular windows
- Ignore events from DND icons
* Translation updates
Basque
British English
Bulgarian
Czech
Danish
Georgian
Hungarian
Lithuanian
Portuguese
Spanish
Swedish
Overview of Changes in 4.16.0, 09-06-2024
=========================================
Note: This release changes the default GSK renderer to be Vulkan,
on Wayland. Other platforms still use ngl. The intent of this change
is to use the best available platform APIs. You can still override
the renderer choice using the GSK_RENDERER environment variable.
We believe that most of the problems reported with the new renderers
during the 4.13 and 4.15 development cycles have been addressed by now.
But the new renderers and dmabuf support are using graphics drivers
in different ways than the old gl renderer, and trigger new driver bugs.
Therefore, it is recommended to use the latest mesa release (24.2)
with the new renderers.
* GtkScale:
- Fix positioning of scale values
* GtkEmojiChooser:
- Make Control-clicks work for the recent section
* GtkPopover:
- Make sure focus lands on the right widget when cascading
* GtkSpinButton:
- Disable Emoji input for numeric spin buttons
* GtkSingleSelection:
- Implement unselect_all
* Accssibility:
- Fix roles for radio buttons
- Check if ATs are listening before exporting trees
- Add a check for sandboxed accessibility bus
- Fix handling of the error message relation
- Turn criticals into debug messages
- Set expanded states properly in menus
* CSS:
- Fix a few issues on bigendian systems
- Avoid a crash with relative colors
* GSK:
- Use the right GL context when exporting textures
- Don't let colors influence depth decisions
- Allow uploading of mipmap levels when tiling textures
* GDK:
- Update keysyms from libX11 1.8.10
- Implement cpu-side mipmapping
- Use a thread pool for color conversions and mipmapping
* Vulkan:
- Fix drag surface offsets
* Wayland:
- Fix a crash
- Associate EGL windows with context later
* X11:
- Fix initial EGL context creation
- Fix a problem with GL context creation
* Broadway:
- Implement compute_size and request_layout
* MacOS:
- Set transparent backgroiund for toplevel windows
* Windows:
- Improve debug output
- Detect Mesas d3d12 driver and request GDI compat
* Demos:
- Set window icons in demos
- Add a 64k x 64k image to the image scaling demo
* Translation updates
Belarusian
Brazilian Portuguese
Catalan
Czech
Galician
German
Hebrew
Indonesian
Korean
Lithuanian
Persian
Polish
Portuguese
Slovenian
Spanish
Turkish
Ukrainian
Overview of Changes in 4.15.6, 08-26-2024
=========================================
+4
View File
@@ -136,9 +136,13 @@ In the bug report please include:
- which version of GTK you are using
- what operating system and version
- what windowing system (X11 or Wayland)
- what graphics driver / mesa version
- for Linux, which distribution
- if you built GTK, the list of options used to configure the build
Most of this information can be found in the GTK inspector.
And anything else you think is relevant.
* How to reproduce the bug.
@@ -1,115 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#include "config.h"
#include "constraint-editor-application.h"
#include "constraint-editor-window.h"
struct _ConstraintEditorApplication
{
GtkApplication parent_instance;
};
G_DEFINE_TYPE(ConstraintEditorApplication, constraint_editor_application, GTK_TYPE_APPLICATION);
static void
constraint_editor_application_init (ConstraintEditorApplication *app)
{
}
static void
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer data)
{
g_application_quit (G_APPLICATION (data));
}
static GActionEntry app_entries[] =
{
{ "quit", quit_activated, NULL, NULL, NULL }
};
static void
constraint_editor_application_startup (GApplication *app)
{
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
const char *open_accels[2] = { "<Ctrl>O", NULL };
GtkCssProvider *provider;
G_APPLICATION_CLASS (constraint_editor_application_parent_class)->startup (app);
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/org/gtk/gtk4/constraint-editor/constraint-editor.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
static void
constraint_editor_application_activate (GApplication *app)
{
ConstraintEditorWindow *win;
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
gtk_window_present (GTK_WINDOW (win));
}
static void
constraint_editor_application_open (GApplication *app,
GFile **files,
int n_files,
const char *hint)
{
ConstraintEditorWindow *win;
int i;
for (i = 0; i < n_files; i++)
{
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
constraint_editor_window_load (win, files[i]);
gtk_window_present (GTK_WINDOW (win));
}
}
static void
constraint_editor_application_class_init (ConstraintEditorApplicationClass *class)
{
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
application_class->startup = constraint_editor_application_startup;
application_class->activate = constraint_editor_application_activate;
application_class->open = constraint_editor_application_open;
}
ConstraintEditorApplication *
constraint_editor_application_new (void)
{
return g_object_new (CONSTRAINT_EDITOR_APPLICATION_TYPE,
"application-id", "org.gtk.gtk4.ConstraintEditor",
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
}
@@ -1,652 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#include "config.h"
#include "constraint-editor-window.h"
#include "constraint-view.h"
#include "constraint-editor.h"
#include "guide-editor.h"
struct _ConstraintEditorWindow
{
GtkApplicationWindow parent_instance;
GtkWidget *paned;
GtkWidget *view;
GtkWidget *list;
};
G_DEFINE_TYPE(ConstraintEditorWindow, constraint_editor_window, GTK_TYPE_APPLICATION_WINDOW);
static GtkConstraintTarget *
find_target (GListModel *model,
GtkConstraintTarget *orig)
{
const char *name;
const char *model_name;
gpointer item;
int i;
if (orig == NULL)
return NULL;
if (GTK_IS_LABEL (orig))
name = gtk_label_get_label (GTK_LABEL (orig));
else if (GTK_IS_CONSTRAINT_GUIDE (orig))
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (orig));
else
{
g_warning ("Don't know how to handle %s targets", G_OBJECT_TYPE_NAME (orig));
return NULL;
}
for (i = 0; i < g_list_model_get_n_items (model); i++)
{
item = g_list_model_get_item (model, i);
g_object_unref (item);
if (GTK_IS_WIDGET (item))
model_name = gtk_widget_get_name (GTK_WIDGET (item));
else
model_name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
if (strcmp (name, model_name) == 0)
return GTK_CONSTRAINT_TARGET (item);
}
g_warning ("Failed to find target '%s'", name);
return NULL;
}
gboolean
constraint_editor_window_load (ConstraintEditorWindow *self,
GFile *file)
{
char *path;
GtkBuilder *builder;
GError *error = NULL;
GtkWidget *view;
GtkLayoutManager *layout;
GtkWidget *child;
const char *name;
gpointer item;
int i;
GListModel *list;
path = g_file_get_path (file);
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, path, &error))
{
g_print ("Could not load %s: %s", path, error->message);
g_error_free (error);
g_free (path);
g_object_unref (builder);
return FALSE;
}
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
if (!GTK_IS_BOX (view))
{
g_print ("Could not load %s: No GtkBox named 'view'", path);
g_free (path);
g_object_unref (builder);
return FALSE;
}
layout = gtk_widget_get_layout_manager (view);
if (!GTK_IS_CONSTRAINT_LAYOUT (layout))
{
g_print ("Could not load %s: Widget 'view' does not use GtkConstraintLayout", path);
g_free (path);
g_object_unref (builder);
return FALSE;
}
for (child = gtk_widget_get_first_child (view);
child;
child = gtk_widget_get_next_sibling (child))
{
if (!GTK_IS_LABEL (child))
{
g_print ("Skipping non-GtkLabel child\n");
continue;
}
name = gtk_label_get_label (GTK_LABEL (child));
constraint_view_add_child (CONSTRAINT_VIEW (self->view), name);
}
list = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (layout));
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
GtkConstraintGuide *guide, *clone;
int w, h;
item = g_list_model_get_item (list, i);
guide = GTK_CONSTRAINT_GUIDE (item);
/* need to clone here, to attach to the right targets */
clone = gtk_constraint_guide_new ();
gtk_constraint_guide_set_name (clone, gtk_constraint_guide_get_name (guide));
gtk_constraint_guide_set_strength (clone, gtk_constraint_guide_get_strength (guide));
gtk_constraint_guide_get_min_size (guide, &w, &h);
gtk_constraint_guide_set_min_size (clone, w, h);
gtk_constraint_guide_get_nat_size (guide, &w, &h);
gtk_constraint_guide_set_nat_size (clone, w, h);
gtk_constraint_guide_get_max_size (guide, &w, &h);
gtk_constraint_guide_set_max_size (clone, w, h);
constraint_view_add_guide (CONSTRAINT_VIEW (self->view), clone);
g_object_unref (guide);
g_object_unref (clone);
}
g_object_unref (list);
list = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (layout));
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
GtkConstraint *constraint;
GtkConstraint *clone;
GtkConstraintTarget *target;
GtkConstraintTarget *source;
GtkConstraintAttribute source_attr;
item = g_list_model_get_item (list, i);
constraint = GTK_CONSTRAINT (item);
target = gtk_constraint_get_target (constraint);
source = gtk_constraint_get_source (constraint);
source_attr = gtk_constraint_get_source_attribute (constraint);
if (source == NULL && source_attr == GTK_CONSTRAINT_ATTRIBUTE_NONE)
clone = gtk_constraint_new_constant (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
gtk_constraint_get_target_attribute (constraint),
gtk_constraint_get_relation (constraint),
gtk_constraint_get_constant (constraint),
gtk_constraint_get_strength (constraint));
else
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
gtk_constraint_get_target_attribute (constraint),
gtk_constraint_get_relation (constraint),
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
source_attr,
gtk_constraint_get_multiplier (constraint),
gtk_constraint_get_constant (constraint),
gtk_constraint_get_strength (constraint));
constraint_view_add_constraint (CONSTRAINT_VIEW (self->view), clone);
g_object_unref (constraint);
g_object_unref (clone);
}
g_object_unref (list);
g_free (path);
g_object_unref (builder);
return TRUE;
}
static void
open_response_cb (GObject *source,
GAsyncResult *result,
void *user_data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
ConstraintEditorWindow *self = user_data;
GFile *file;
file = gtk_file_dialog_open_finish (dialog, result, NULL);
if (file)
{
constraint_editor_window_load (self, file);
g_object_unref (file);
}
}
static void
open_cb (GtkWidget *button,
ConstraintEditorWindow *self)
{
GtkFileDialog *dialog;
GFile *cwd;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Open file");
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
g_object_unref (cwd);
gtk_file_dialog_open (dialog, GTK_WINDOW (self), NULL, open_response_cb, self);
g_object_unref (dialog);
}
static void
serialize_child (GString *str,
int indent,
GtkWidget *child)
{
const char *name;
name = gtk_widget_get_name (child);
g_string_append_printf (str, "%*s<child>\n", indent, "");
g_string_append_printf (str, "%*s <object class=\"GtkLabel\" id=\"%s\">\n", indent, "", name);
g_string_append_printf (str, "%*s <property name=\"label\">%s</property>\n", indent, "", name);
g_string_append_printf (str, "%*s </object>\n", indent, "");
g_string_append_printf (str, "%*s</child>\n", indent, "");
}
static char *
serialize_model (GListModel *list)
{
GString *str = g_string_new ("");
int i;
g_string_append (str, "<interface>\n");
g_string_append (str, " <object class=\"GtkBox\" id=\"view\">\n");
g_string_append (str, " <property name=\"layout-manager\">\n");
g_string_append (str, " <object class=\"GtkConstraintLayout\">\n");
g_string_append (str, " <constraints>\n");
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
gpointer item = g_list_model_get_item (list, i);
g_object_unref (item);
if (GTK_IS_CONSTRAINT (item))
constraint_editor_serialize_constraint (str, 10, GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
guide_editor_serialize_guide (str, 10, GTK_CONSTRAINT_GUIDE (item));
}
g_string_append (str, " </constraints>\n");
g_string_append (str, " </object>\n");
g_string_append (str, " </property>\n");
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
gpointer item = g_list_model_get_item (list, i);
g_object_unref (item);
if (GTK_IS_WIDGET (item))
serialize_child (str, 4, GTK_WIDGET (item));
}
g_string_append (str, " </object>\n");
g_string_append (str, "</interface>\n");
return g_string_free (str, FALSE);
}
static void
save_response_cb (GObject *source,
GAsyncResult *result,
void *user_data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
ConstraintEditorWindow *self = user_data;
GFile *file;
file = gtk_file_dialog_save_finish (dialog, result, NULL);
if (file)
{
GListModel *model;
char *text;
GError *error = NULL;
model = constraint_view_get_model (CONSTRAINT_VIEW (self->view));
text = serialize_model (model);
g_file_replace_contents (file, text, strlen (text),
NULL, FALSE,
G_FILE_CREATE_NONE,
NULL,
NULL,
&error);
if (error != NULL)
{
GtkAlertDialog *alert;
alert = gtk_alert_dialog_new ("Saving failed");
gtk_alert_dialog_set_detail (alert, error->message);
gtk_alert_dialog_show (alert,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))));
g_object_unref (alert);
g_error_free (error);
}
g_free (text);
g_object_unref (file);
}
}
static void
save_cb (GtkWidget *button,
ConstraintEditorWindow *self)
{
GtkFileDialog *dialog;
GFile *cwd;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Save constraints");
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
g_object_unref (cwd);
gtk_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
NULL,
save_response_cb, self);
g_object_unref (dialog);
}
static void
constraint_editor_window_dispose (GObject *object)
{
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_WINDOW_TYPE);
G_OBJECT_CLASS (constraint_editor_window_parent_class)->dispose (object);
}
static int child_counter;
static int guide_counter;
static void
add_child (ConstraintEditorWindow *win)
{
char *name;
child_counter++;
name = g_strdup_printf ("Child %d", child_counter);
constraint_view_add_child (CONSTRAINT_VIEW (win->view), name);
g_free (name);
}
static void
add_guide (ConstraintEditorWindow *win)
{
char *name;
GtkConstraintGuide *guide;
guide_counter++;
name = g_strdup_printf ("Guide %d", guide_counter);
guide = gtk_constraint_guide_new ();
gtk_constraint_guide_set_name (guide, name);
g_free (name);
constraint_view_add_guide (CONSTRAINT_VIEW (win->view), guide);
}
static void
constraint_editor_done (ConstraintEditor *editor,
GtkConstraint *constraint,
ConstraintEditorWindow *win)
{
GtkConstraint *old_constraint;
g_object_get (editor, "constraint", &old_constraint, NULL);
if (old_constraint)
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view), old_constraint);
constraint_view_add_constraint (CONSTRAINT_VIEW (win->view), constraint);
g_clear_object (&old_constraint);
gtk_window_destroy (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW)));
}
static void
edit_constraint (ConstraintEditorWindow *win,
GtkConstraint *constraint)
{
GtkWidget *window;
ConstraintEditor *editor;
GListModel *model;
window = gtk_window_new ();
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
if (constraint)
gtk_window_set_title (GTK_WINDOW (window), "Edit Constraint");
else
gtk_window_set_title (GTK_WINDOW (window), "Create Constraint");
model = constraint_view_get_model (CONSTRAINT_VIEW (win->view));
editor = constraint_editor_new (model, constraint);
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
g_signal_connect (editor, "done", G_CALLBACK (constraint_editor_done), win);
gtk_window_present (GTK_WINDOW (window));
}
static void
add_constraint (ConstraintEditorWindow *win)
{
edit_constraint (win, NULL);
}
static void
guide_editor_done (GuideEditor *editor,
GtkConstraintGuide *guide,
ConstraintEditorWindow *win)
{
gtk_window_destroy (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW)));
}
static void
edit_guide (ConstraintEditorWindow *win,
GtkConstraintGuide *guide)
{
GtkWidget *window;
GuideEditor *editor;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
gtk_window_set_title (GTK_WINDOW (window), "Edit Guide");
editor = guide_editor_new (guide);
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
g_signal_connect (editor, "done", G_CALLBACK (guide_editor_done), win);
gtk_window_present (GTK_WINDOW (window));
}
static void
row_activated (GtkListBox *list,
GtkListBoxRow *row,
ConstraintEditorWindow *win)
{
GObject *item;
item = G_OBJECT (g_object_get_data (G_OBJECT (row), "item"));
if (GTK_IS_CONSTRAINT (item))
edit_constraint (win, GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
}
static void
constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
g_type_ensure (CONSTRAINT_VIEW_TYPE);
object_class->dispose = constraint_editor_window_dispose;
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, paned);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, view);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, list);
gtk_widget_class_bind_template_callback (widget_class, open_cb);
gtk_widget_class_bind_template_callback (widget_class, save_cb);
gtk_widget_class_bind_template_callback (widget_class, add_child);
gtk_widget_class_bind_template_callback (widget_class, add_guide);
gtk_widget_class_bind_template_callback (widget_class, add_constraint);
gtk_widget_class_bind_template_callback (widget_class, row_activated);
}
static void
row_edit (GtkButton *button,
ConstraintEditorWindow *win)
{
GtkWidget *row;
GObject *item;
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
if (GTK_IS_CONSTRAINT (item))
edit_constraint (win, GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
}
static void
mark_constraints_invalid (ConstraintEditorWindow *win,
gpointer removed)
{
GtkWidget *child;
GObject *item;
for (child = gtk_widget_get_first_child (win->list);
child;
child = gtk_widget_get_next_sibling (child))
{
item = (GObject *)g_object_get_data (G_OBJECT (child), "item");
if (GTK_IS_CONSTRAINT (item))
{
GtkConstraint *constraint = GTK_CONSTRAINT (item);
if (gtk_constraint_get_target (constraint) == (GtkConstraintTarget *)removed ||
gtk_constraint_get_source (constraint) == (GtkConstraintTarget *)removed)
{
GtkWidget *button;
button = (GtkWidget *)g_object_get_data (G_OBJECT (child), "edit");
gtk_button_set_icon_name (GTK_BUTTON (button), "dialog-warning-symbolic");
gtk_widget_set_tooltip_text (button, "Constraint is invalid");
}
}
}
}
static void
row_delete (GtkButton *button,
ConstraintEditorWindow *win)
{
GtkWidget *row;
GObject *item;
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
if (GTK_IS_CONSTRAINT (item))
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view),
GTK_CONSTRAINT (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
{
mark_constraints_invalid (win, item);
constraint_view_remove_guide (CONSTRAINT_VIEW (win->view),
GTK_CONSTRAINT_GUIDE (item));
}
else if (GTK_IS_WIDGET (item))
{
mark_constraints_invalid (win, item);
constraint_view_remove_child (CONSTRAINT_VIEW (win->view),
GTK_WIDGET (item));
}
}
static GtkWidget *
create_widget_func (gpointer item,
gpointer user_data)
{
ConstraintEditorWindow *win = user_data;
const char *name;
char *freeme = NULL;
GtkWidget *row, *box, *label, *button;
if (GTK_IS_WIDGET (item))
name = gtk_widget_get_name (GTK_WIDGET (item));
else if (GTK_IS_CONSTRAINT_GUIDE (item))
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
else if (GTK_IS_CONSTRAINT (item))
name = freeme = constraint_editor_constraint_to_string (GTK_CONSTRAINT (item));
else
name = "";
row = gtk_list_box_row_new ();
g_object_set_data_full (G_OBJECT (row), "item", g_object_ref (item), g_object_unref);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
label = gtk_label_new (name);
if (GTK_IS_WIDGET (item) || GTK_IS_CONSTRAINT_GUIDE (item))
g_object_bind_property (item, "name",
label, "label",
G_BINDING_DEFAULT);
gtk_widget_set_margin_start (label, 10);
gtk_widget_set_margin_end (label, 10);
gtk_widget_set_margin_top (label, 10);
gtk_widget_set_margin_bottom (label, 10);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_widget_set_hexpand (label, TRUE);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box);
gtk_box_append (GTK_BOX (box), label);
if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item))
{
button = gtk_button_new_from_icon_name ("document-edit-symbolic");
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
g_object_set_data (G_OBJECT (row), "edit", button);
gtk_box_append (GTK_BOX (box), button);
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
gtk_box_append (GTK_BOX (box), button);
}
else if (GTK_IS_WIDGET (item))
{
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
gtk_box_append (GTK_BOX (box), button);
}
g_free (freeme);
return row;
}
static void
constraint_editor_window_init (ConstraintEditorWindow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
gtk_list_box_bind_model (GTK_LIST_BOX (self->list),
constraint_view_get_model (CONSTRAINT_VIEW (self->view)),
create_widget_func,
self,
NULL);
}
ConstraintEditorWindow *
constraint_editor_window_new (ConstraintEditorApplication *application)
{
return g_object_new (CONSTRAINT_EDITOR_WINDOW_TYPE,
"application", application,
NULL);
}
@@ -1,34 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#include "constraint-editor-application.h"
#define CONSTRAINT_EDITOR_WINDOW_TYPE (constraint_editor_window_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintEditorWindow, constraint_editor_window, CONSTRAINT, EDITOR_WINDOW, GtkApplicationWindow)
ConstraintEditorWindow * constraint_editor_window_new (ConstraintEditorApplication *application);
gboolean constraint_editor_window_load (ConstraintEditorWindow *self,
GFile *file);
@@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ConstraintEditorWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">GTK Constraint Editor</property>
<property name="default-width">1024</property>
<property name="default-height">768</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<child type="start">
<object class="GtkButton">
<property name="icon-name">document-open-symbolic</property>
<property name="tooltip-text">Open ui file</property>
<signal name="clicked" handler="open_cb"/>
</object>
</child>
<child type="start">
<object class="GtkButton">
<property name="icon-name">document-save-symbolic</property>
<property name="tooltip-text">Save to ui file</property>
<signal name="clicked" handler="save_cb"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPaned" id="paned">
<property name="orientation">horizontal</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<child>
<object class="GtkButton">
<property name="label">Add Child</property>
<signal name="clicked" handler="add_child" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Add Guide</property>
<signal name="clicked" handler="add_guide" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Add Constraint</property>
<signal name="clicked" handler="add_constraint" swapped="yes"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<property name="vexpand">1</property>
<child>
<object class="GtkListBox" id="list">
<property name="show-separators">1</property>
<property name="selection-mode">none</property>
<signal name="row-activated" handler="row_activated"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="ConstraintView" id="view">
</object>
</child>
</object>
</child>
</template>
</interface>
-716
View File
@@ -1,716 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#include "config.h"
#include "constraint-editor.h"
#include "constraint-view.h"
struct _ConstraintEditor
{
GtkWidget parent_instance;
GtkWidget *grid;
GtkWidget *target;
GtkWidget *target_attr;
GtkWidget *relation;
GtkWidget *source;
GtkWidget *source_attr;
GtkWidget *multiplier;
GtkWidget *constant;
GtkWidget *strength;
GtkWidget *preview;
GtkWidget *button;
GtkConstraint *constraint;
GListModel *model;
gboolean constructed;
};
enum {
PROP_MODEL = 1,
PROP_CONSTRAINT,
LAST_PROP
};
static GParamSpec *pspecs[LAST_PROP];
enum {
DONE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE(ConstraintEditor, constraint_editor, GTK_TYPE_WIDGET);
static const char *
get_target_name (GtkConstraintTarget *target)
{
if (target == NULL)
return "Super";
else if (GTK_IS_WIDGET (target))
return gtk_widget_get_name (GTK_WIDGET (target));
else if (GTK_IS_CONSTRAINT_GUIDE (target))
return gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (target));
else
return "";
}
static void
constraint_target_combo (GListModel *model,
GtkWidget *combo,
gboolean is_source)
{
GtkStringList *targets;
int i;
targets = gtk_string_list_new (NULL);
gtk_string_list_append (targets, "Super");
if (model)
{
for (i = 0; i < g_list_model_get_n_items (model); i++)
{
GObject *item = g_list_model_get_object (model, i);
if (GTK_IS_CONSTRAINT (item))
continue;
gtk_string_list_append (targets, get_target_name (GTK_CONSTRAINT_TARGET (item)));
g_object_unref (item);
}
}
gtk_drop_down_set_model (GTK_DROP_DOWN (combo), G_LIST_MODEL (targets));
g_object_unref (targets);
}
static gpointer
get_target (GListModel *model,
const char *id)
{
int i;
if (id == NULL)
return NULL;
if (strcmp ("Super", id) == 0)
return NULL;
for (i = 0; i < g_list_model_get_n_items (model); i++)
{
GObject *item = g_list_model_get_object (model, i);
g_object_unref (item);
if (GTK_IS_CONSTRAINT (item))
continue;
else if (GTK_IS_WIDGET (item))
{
if (strcmp (id, gtk_widget_get_name (GTK_WIDGET (item))) == 0)
return item;
}
else if (GTK_IS_CONSTRAINT_GUIDE (item))
{
if (strcmp (id, gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item))) == 0)
return item;
}
}
return NULL;
}
static void
select_target (GtkDropDown *combo,
const char *target_name)
{
GListModel *model = gtk_drop_down_get_model (combo);
for (unsigned int i = 0; i < g_list_model_get_n_items (model); i++)
{
GtkStringObject *s = g_list_model_get_item (model, i);
g_object_unref (s);
if (strcmp (target_name, gtk_string_object_get_string (s)) == 0)
{
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), i);
return;
}
}
}
static GtkConstraintAttribute
get_attr (unsigned int id)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_ATTRIBUTE_NONE;
case 1: return GTK_CONSTRAINT_ATTRIBUTE_LEFT;
case 2: return GTK_CONSTRAINT_ATTRIBUTE_RIGHT;
case 3: return GTK_CONSTRAINT_ATTRIBUTE_TOP;
case 4: return GTK_CONSTRAINT_ATTRIBUTE_BOTTOM;
case 5: return GTK_CONSTRAINT_ATTRIBUTE_START;
case 6: return GTK_CONSTRAINT_ATTRIBUTE_END;
case 7: return GTK_CONSTRAINT_ATTRIBUTE_WIDTH;
case 8: return GTK_CONSTRAINT_ATTRIBUTE_HEIGHT;
case 9: return GTK_CONSTRAINT_ATTRIBUTE_CENTER_X;
case 10: return GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y;
case 11: return GTK_CONSTRAINT_ATTRIBUTE_BASELINE;
default: g_assert_not_reached ();
}
}
static unsigned int
get_attr_id (GtkConstraintAttribute attr)
{
switch (attr)
{
case GTK_CONSTRAINT_ATTRIBUTE_NONE: return 0;
case GTK_CONSTRAINT_ATTRIBUTE_LEFT: return 1;
case GTK_CONSTRAINT_ATTRIBUTE_RIGHT: return 2;
case GTK_CONSTRAINT_ATTRIBUTE_TOP: return 3;
case GTK_CONSTRAINT_ATTRIBUTE_BOTTOM: return 4;
case GTK_CONSTRAINT_ATTRIBUTE_START: return 5;
case GTK_CONSTRAINT_ATTRIBUTE_END: return 6;
case GTK_CONSTRAINT_ATTRIBUTE_WIDTH: return 7;
case GTK_CONSTRAINT_ATTRIBUTE_HEIGHT: return 8;
case GTK_CONSTRAINT_ATTRIBUTE_CENTER_X: return 9;
case GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y: return 10;
case GTK_CONSTRAINT_ATTRIBUTE_BASELINE: return 11;
default: g_assert_not_reached ();
}
}
static const char *
get_attr_nick (GtkConstraintAttribute attr)
{
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
GEnumValue *value = g_enum_get_value (class, attr);
const char *nick = value->value_nick;
g_type_class_unref (class);
return nick;
}
static GtkConstraintRelation
get_relation (unsigned int id)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_RELATION_LE;
case 1: return GTK_CONSTRAINT_RELATION_EQ;
case 2: return GTK_CONSTRAINT_RELATION_GE;
default: g_assert_not_reached ();
}
}
static unsigned int
get_relation_id (GtkConstraintRelation relation)
{
switch (relation)
{
case GTK_CONSTRAINT_RELATION_LE: return 0;
case GTK_CONSTRAINT_RELATION_EQ: return 1;
case GTK_CONSTRAINT_RELATION_GE: return 2;
default: g_assert_not_reached ();
}
}
static const char *
get_relation_nick (GtkConstraintRelation relation)
{
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
GEnumValue *value = g_enum_get_value (class, relation);
const char *nick = value->value_nick;
g_type_class_unref (class);
return nick;
}
static const char *
get_relation_display_name (GtkConstraintRelation relation)
{
switch (relation)
{
case GTK_CONSTRAINT_RELATION_LE:
return "";
case GTK_CONSTRAINT_RELATION_EQ:
return "=";
case GTK_CONSTRAINT_RELATION_GE:
return "";
default:
return "?";
}
}
static GtkConstraintStrength
get_strength (unsigned int id)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
default: g_assert_not_reached ();
}
}
static unsigned int
get_strength_id (GtkConstraintStrength strength)
{
switch (strength)
{
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
default: g_assert_not_reached ();
}
}
static const char *
get_strength_nick (GtkConstraintStrength strength)
{
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
GEnumValue *value = g_enum_get_value (class, strength);
const char *nick = value->value_nick;
g_type_class_unref (class);
return nick;
}
void
constraint_editor_serialize_constraint (GString *str,
int indent,
GtkConstraint *constraint)
{
const char *target;
const char *target_attr;
const char *relation;
const char *source;
const char *source_attr;
double multiplier;
double constant;
const char *strength;
target = get_target_name (gtk_constraint_get_target (constraint));
target_attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
source = get_target_name (gtk_constraint_get_source (constraint));
source_attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
multiplier = gtk_constraint_get_multiplier (constraint);
constant = gtk_constraint_get_constant (constraint);
strength = get_strength_nick (gtk_constraint_get_strength (constraint));
g_string_append_printf (str, "%*s<constraint target=\"%s\" target-attribute=\"%s\"\n", indent, "", target, target_attr);
g_string_append_printf (str, "%*s relation=\"%s\"\n", indent, "", relation);
if (strcmp (source_attr, "none") != 0)
{
g_string_append_printf (str, "%*s source=\"%s\" source-attribute=\"%s\"\n", indent, "", source, source_attr);
g_string_append_printf (str, "%*s multiplier=\"%g\"\n", indent, "", multiplier);
}
g_string_append_printf (str, "%*s constant=\"%g\"\n", indent, "", constant);
g_string_append_printf (str, "%*s strength=\"%s\" />\n", indent, "", strength);
}
static void
create_constraint (GtkButton *button,
ConstraintEditor *editor)
{
gpointer obj;
gpointer target;
GtkConstraintAttribute target_attr;
gpointer source;
GtkConstraintAttribute source_attr;
GtkConstraintRelation relation;
double multiplier;
double constant;
int strength;
GtkConstraint *constraint;
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target));
if (obj)
target = get_target (editor->model, gtk_string_object_get_string (GTK_STRING_OBJECT (obj)));
else
target = NULL;
target_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->target_attr)));
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source));
if (obj)
source = get_target (editor->model, gtk_string_object_get_string (GTK_STRING_OBJECT (obj)));
else
source = NULL;
source_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN(editor->source_attr)));
relation = get_relation (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->relation)));
multiplier = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->multiplier)), NULL);
constant = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->constant)), NULL);
strength = get_strength (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength)));
constraint = gtk_constraint_new (target, target_attr,
relation,
source, source_attr,
multiplier,
constant,
strength);
g_signal_emit (editor, signals[DONE], 0, constraint);
g_object_unref (constraint);
}
static void
source_attr_changed (ConstraintEditor *editor)
{
if (get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr))) == GTK_CONSTRAINT_ATTRIBUTE_NONE)
{
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source), GTK_INVALID_LIST_POSITION);
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "");
gtk_widget_set_sensitive (editor->source, FALSE);
gtk_widget_set_sensitive (editor->multiplier, FALSE);
}
else
{
gtk_widget_set_sensitive (editor->source, TRUE);
gtk_widget_set_sensitive (editor->multiplier, TRUE);
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1");
}
}
char *
constraint_editor_constraint_to_string (GtkConstraint *constraint)
{
GString *str;
const char *name;
const char *attr;
const char *relation;
double c, m;
str = g_string_new ("");
name = get_target_name (gtk_constraint_get_target (constraint));
attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
relation = get_relation_display_name (gtk_constraint_get_relation (constraint));
if (name == NULL)
name = "[ ]";
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
c = gtk_constraint_get_constant (constraint);
attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
if (strcmp (attr, "none") != 0)
{
name = get_target_name (gtk_constraint_get_source (constraint));
m = gtk_constraint_get_multiplier (constraint);
if (name == NULL)
name = "[ ]";
g_string_append_printf (str, "%s.%s", name, attr);
if (m != 1.0)
g_string_append_printf (str, " × %g", m);
if (c > 0.0)
g_string_append_printf (str, " + %g", c);
else if (c < 0.0)
g_string_append_printf (str, " - %g", -c);
}
else
g_string_append_printf (str, "%g", c);
return g_string_free (str, FALSE);
}
static void
update_preview (ConstraintEditor *editor)
{
GString *str;
const char *name;
const char *attr;
const char *relation;
const char *multiplier;
const char *constant;
double c, m;
if (!editor->constructed)
return;
str = g_string_new ("");
name = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target))));
attr = get_attr_nick (get_attr (gtk_drop_down_get_selected ((GTK_DROP_DOWN (editor->target_attr)))));
relation = get_relation_nick (get_relation (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->relation))));
if (name == NULL)
name = "[ ]";
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
constant = gtk_editable_get_text (GTK_EDITABLE (editor->constant));
c = g_ascii_strtod (constant, NULL);
attr = get_attr_nick (get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr))));
if (strcmp (attr, "none") != 0)
{
name = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source))));
multiplier = gtk_editable_get_text (GTK_EDITABLE (editor->multiplier));
m = g_ascii_strtod (multiplier, NULL);
if (name == NULL)
name = "[ ]";
g_string_append_printf (str, "%s.%s", name, attr);
if (m != 1.0)
g_string_append_printf (str, " × %g", m);
if (c > 0.0)
g_string_append_printf (str, " + %g", c);
else if (c < 0.0)
g_string_append_printf (str, " - %g", -c);
}
else
g_string_append_printf (str, "%g", c);
gtk_label_set_label (GTK_LABEL (editor->preview), str->str);
g_string_free (str, TRUE);
}
static void
update_button (ConstraintEditor *editor)
{
gpointer obj;
const char *target;
const char *source;
GtkConstraintAttribute source_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr)));
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target));
target = obj ? gtk_string_object_get_string (GTK_STRING_OBJECT (obj)) : NULL;
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source));
source = obj ? gtk_string_object_get_string (GTK_STRING_OBJECT (obj)) : NULL;
if (target && (source || (source_attr == GTK_CONSTRAINT_ATTRIBUTE_NONE)))
gtk_widget_set_sensitive (editor->button, TRUE);
else
gtk_widget_set_sensitive (editor->button, FALSE);
}
static void
constraint_editor_init (ConstraintEditor *editor)
{
gtk_widget_init_template (GTK_WIDGET (editor));
}
static void
constraint_editor_constructed (GObject *object)
{
ConstraintEditor *editor = CONSTRAINT_EDITOR (object);
constraint_target_combo (editor->model, editor->target, FALSE);
constraint_target_combo (editor->model, editor->source, TRUE);
if (editor->constraint)
{
GtkConstraintTarget *target;
GtkConstraintAttribute attr;
GtkConstraintRelation relation;
GtkConstraintStrength strength;
char *val;
double multiplier;
double constant;
target = gtk_constraint_get_target (editor->constraint);
select_target (GTK_DROP_DOWN (editor->target), get_target_name (target));
attr = gtk_constraint_get_target_attribute (editor->constraint);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->target_attr), get_attr_id (attr));
target = gtk_constraint_get_source (editor->constraint);
select_target (GTK_DROP_DOWN (editor->source), get_target_name (target));
attr = gtk_constraint_get_source_attribute (editor->constraint);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source_attr), get_attr_id (attr));
relation = gtk_constraint_get_relation (editor->constraint);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->relation), get_relation_id (relation));
multiplier = gtk_constraint_get_multiplier (editor->constraint);
val = g_strdup_printf ("%g", multiplier);
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), val);
g_free (val);
constant = gtk_constraint_get_constant (editor->constraint);
val = g_strdup_printf ("%g", constant);
gtk_editable_set_text (GTK_EDITABLE (editor->constant), val);
g_free (val);
strength = gtk_constraint_get_strength (editor->constraint);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
}
else
{
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->target_attr), get_attr_id (GTK_CONSTRAINT_ATTRIBUTE_LEFT));
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source_attr), get_attr_id (GTK_CONSTRAINT_ATTRIBUTE_LEFT));
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->relation), get_relation_id (GTK_CONSTRAINT_RELATION_EQ));
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1.0");
gtk_editable_set_text (GTK_EDITABLE (editor->constant), "0.0");
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
}
editor->constructed = TRUE;
update_preview (editor);
update_button (editor);
}
static void
constraint_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
switch (property_id)
{
case PROP_MODEL:
self->model = g_value_dup_object (value);
break;
case PROP_CONSTRAINT:
self->constraint = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
constraint_editor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
switch (property_id)
{
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_CONSTRAINT:
g_value_set_object (value, self->constraint);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
constraint_editor_dispose (GObject *object)
{
ConstraintEditor *self = (ConstraintEditor *)object;
g_clear_object (&self->model);
g_clear_object (&self->constraint);
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_TYPE);
G_OBJECT_CLASS (constraint_editor_parent_class)->dispose (object);
}
static void
constraint_editor_class_init (ConstraintEditorClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->constructed = constraint_editor_constructed;
object_class->dispose = constraint_editor_dispose;
object_class->set_property = constraint_editor_set_property;
object_class->get_property = constraint_editor_get_property;
pspecs[PROP_CONSTRAINT] =
g_param_spec_object ("constraint", "constraint", "constraint",
GTK_TYPE_CONSTRAINT,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
pspecs[PROP_MODEL] =
g_param_spec_object ("model", "model", "model",
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
signals[DONE] =
g_signal_new ("done",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/gtk4/constraint-editor/constraint-editor.ui");
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, grid);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target_attr);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, relation);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source_attr);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, multiplier);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, constant);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, strength);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, preview);
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, button);
gtk_widget_class_bind_template_callback (widget_class, update_preview);
gtk_widget_class_bind_template_callback (widget_class, update_button);
gtk_widget_class_bind_template_callback (widget_class, create_constraint);
gtk_widget_class_bind_template_callback (widget_class, source_attr_changed);
}
ConstraintEditor *
constraint_editor_new (GListModel *model,
GtkConstraint *constraint)
{
return g_object_new (CONSTRAINT_EDITOR_TYPE,
"model", model,
"constraint", constraint,
NULL);
}
@@ -1,12 +0,0 @@
constraintview {
background: black;
color: white;
}
constraintview .child {
background: red;
}
constraintview .guide {
background: blue;
}
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gtk/gtk4/constraint-editor">
<file preprocess="xml-stripblanks">constraint-editor-window.ui</file>
<file preprocess="xml-stripblanks">constraint-editor.ui</file>
<file preprocess="xml-stripblanks">guide-editor.ui</file>
<file>constraint-editor.css</file>
</gresource>
</gresources>
@@ -1,34 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define CONSTRAINT_EDITOR_TYPE (constraint_editor_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintEditor, constraint_editor, CONSTRAINT, EDITOR, GtkWidget)
ConstraintEditor * constraint_editor_new (GListModel *model,
GtkConstraint *constraint);
void constraint_editor_serialize_constraint (GString *str,
int indent,
GtkConstraint *constraint);
char *constraint_editor_constraint_to_string (GtkConstraint *constraint);
@@ -1,204 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkStringList" id="targets">
<items>
<item>None</item>
<item>Left</item>
<item>Right</item>
<item>Top</item>
<item>Bottom</item>
<item>Start</item>
<item>End</item>
<item>Width</item>
<item>Height</item>
<item>Center X</item>
<item>Center Y</item>
<item>Baseline</item>
</items>
</object>
<template class="ConstraintEditor" parent="GtkWidget">
<child>
<object class="GtkGrid" id="grid">
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="label">Target</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="target">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="target_attr">
<property name="model">targets</property>
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">2</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Relation</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="relation">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<property name="model">
<object class="GtkStringList">
<items>
<item>≤</item>
<item>=</item>
<item>≥</item>
</items>
</object>
</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Source</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="source">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="source_attr">
<property name="model">targets</property>
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="source_attr_changed" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<layout>
<property name="column">2</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Multiplier</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="multiplier">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Constant</property>
<layout>
<property name="column">0</property>
<property name="row">5</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="constant">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">5</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Strength</property>
<layout>
<property name="column">0</property>
<property name="row">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="strength">
<property name="model">
<object class="GtkStringList">
<items>
<item>Weak</item>
<item>Medium</item>
<item>Strong</item>
<item>Required</item>
</items>
</object>
</property>
<layout>
<property name="column">1</property>
<property name="row">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel" id="preview">
<property name="xalign">0</property>
<layout>
<property name="column">1</property>
<property name="row">7</property>
<property name="column-span">2</property>
</layout>
<attributes>
<attribute name="scale" value="1.44"/>
</attributes>
</object>
</child>
<child>
<object class="GtkButton" id="button">
<property name="label">Create</property>
<signal name="clicked" handler="create_constraint"/>
<layout>
<property name="column">2</property>
<property name="row">8</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>
@@ -1,93 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#include "constraint-view-child.h"
struct _ConstraintViewChild
{
GObject parent_instance;
char *name;
};
enum {
PROP_NAME = 1,
LAST_PROP
};
static GParamSpec props[LAST_PROP];
G_DEFINE_TYPE (ConstraintViewChild, constraint_view_child, G_TYPE_OBJECT)
static void
constraint_view_child_init (ConstraintViewChild *child)
{
}
static void
constraint_view_child_finalize (GObject *object)
{
ConstraintViewChild *child = CONSTRAINT_VIEW_CHILD (object);
g_free (child->name);
G_OBJECT_CLASS (constraint_view_child_parent_class)->finalize (object);
}
static void
constraint_view_child_set_property (GObject *object,
static void
constraint_view_child_class_init (ConstraintViewChildClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = constraint_view_child_finalize;
object_class->get_property = constraint_view_child_get_property;
object_class->set_property = constraint_view_child_set_property;
props[PROP_NAME] =
g_param_spec_string ("name", "name", "name",
NULL,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, LAST_PROP, props);
}
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
ConstraintViewWidget * constraint_view_widget_new (void);
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
ConstraintViewGuide * constraint_view_guide_new (void);
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
ConstraintViewGuide * constraint_view_constraint_new (void);
@@ -1,44 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
ConstraintViewWidget * constraint_view_widget_new (void);
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
ConstraintViewGuide * constraint_view_guide_new (void);
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
ConstraintViewGuide * constraint_view_constraint_new (void);
-345
View File
@@ -1,345 +0,0 @@
/* Copyright (C) 2019 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 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 <gtk/gtk.h>
#include "constraint-view.h"
struct _ConstraintView
{
GtkWidget parent;
GListModel *model;
GtkWidget *drag_widget;
};
G_DEFINE_TYPE (ConstraintView, constraint_view, GTK_TYPE_WIDGET);
static void
constraint_view_dispose (GObject *object)
{
ConstraintView *view = CONSTRAINT_VIEW (object);
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (view))) != NULL)
gtk_widget_unparent (child);
g_clear_object (&view->model);
G_OBJECT_CLASS (constraint_view_parent_class)->dispose (object);
}
static void
constraint_view_class_init (ConstraintViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = constraint_view_dispose;
gtk_widget_class_set_css_name (widget_class, "constraintview");
}
static void
update_weak_position (ConstraintView *self,
GtkWidget *child,
double x,
double y)
{
GtkLayoutManager *manager;
GtkConstraint *constraint;
manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "x-constraint");
if (constraint)
{
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
g_object_set_data (G_OBJECT (child), "x-constraint", NULL);
}
if (x != -100)
{
constraint = gtk_constraint_new_constant (child,
GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
GTK_CONSTRAINT_RELATION_EQ,
x,
GTK_CONSTRAINT_STRENGTH_WEAK);
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
}
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint");
if (constraint)
{
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
g_object_set_data (G_OBJECT (child), "y-constraint", NULL);
}
if (y != -100)
{
constraint = gtk_constraint_new_constant (child,
GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
GTK_CONSTRAINT_RELATION_EQ,
y,
GTK_CONSTRAINT_STRENGTH_WEAK);
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
}
}
static void
drag_begin (GtkGestureDrag *drag,
double start_x,
double start_y,
ConstraintView *self)
{
GtkWidget *widget;
widget = gtk_widget_pick (GTK_WIDGET (self), start_x, start_y, GTK_PICK_DEFAULT);
if (GTK_IS_LABEL (widget))
{
widget = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
if (widget &&
gtk_widget_get_parent (widget) == (GtkWidget *)self)
{
self->drag_widget = widget;
}
}
}
static void
drag_update (GtkGestureDrag *drag,
double offset_x,
double offset_y,
ConstraintView *self)
{
double x, y;
if (!self->drag_widget)
return;
gtk_gesture_drag_get_start_point (drag, &x, &y);
update_weak_position (self, self->drag_widget, x + offset_x, y + offset_y);
}
static void
drag_end (GtkGestureDrag *drag,
double offset_x,
double offset_y,
ConstraintView *self)
{
self->drag_widget = NULL;
}
static gboolean
omit_internal (gpointer item, gpointer user_data)
{
if (g_object_get_data (G_OBJECT (item), "internal"))
return FALSE;
return TRUE;
}
static void
constraint_view_init (ConstraintView *self)
{
GtkLayoutManager *manager;
GtkEventController *controller;
GListStore *list;
GListModel *all_children;
GListModel *all_constraints;
GListModel *guides;
GListModel *children;
GListModel *constraints;
GtkFilter *filter;
manager = gtk_constraint_layout_new ();
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, filter);
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
children = (GListModel *)gtk_filter_list_model_new (all_children, filter);
list = g_list_store_new (G_TYPE_LIST_MODEL);
g_list_store_append (list, children);
g_list_store_append (list, guides);
g_list_store_append (list, constraints);
g_object_unref (children);
g_object_unref (guides);
g_object_unref (constraints);
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
controller = (GtkEventController *)gtk_gesture_drag_new ();
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_end), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
ConstraintView *
constraint_view_new (void)
{
return g_object_new (CONSTRAINT_VIEW_TYPE, NULL);
}
void
constraint_view_add_child (ConstraintView *view,
const char *name)
{
GtkWidget *frame;
GtkWidget *label;
label = gtk_label_new (name);
frame = gtk_frame_new (NULL);
gtk_widget_add_css_class (frame, "child");
gtk_widget_set_name (frame, name);
gtk_frame_set_child (GTK_FRAME (frame), label);
gtk_widget_set_parent (frame, GTK_WIDGET (view));
update_weak_position (view, frame, 100, 100);
}
void
constraint_view_remove_child (ConstraintView *view,
GtkWidget *child)
{
update_weak_position (view, child, -100, -100);
gtk_widget_unparent (child);
}
void
constraint_view_add_guide (ConstraintView *view,
GtkConstraintGuide *guide)
{
GtkConstraintLayout *layout;
GtkWidget *frame;
GtkWidget *label;
const char *name;
GtkConstraint *constraint;
struct {
const char *name;
GtkConstraintAttribute attr;
} names[] = {
{ "left-constraint", GTK_CONSTRAINT_ATTRIBUTE_LEFT },
{ "top-constraint", GTK_CONSTRAINT_ATTRIBUTE_TOP },
{ "width-constraint", GTK_CONSTRAINT_ATTRIBUTE_WIDTH },
{ "height-constraint", GTK_CONSTRAINT_ATTRIBUTE_HEIGHT },
};
int i;
name = gtk_constraint_guide_get_name (guide);
label = gtk_label_new (name);
g_object_bind_property (guide, "name",
label, "label",
G_BINDING_DEFAULT);
frame = gtk_frame_new (NULL);
gtk_widget_add_css_class (frame, "guide");
g_object_set_data (G_OBJECT (frame), "internal", (char *)"yes");
gtk_frame_set_child (GTK_FRAME (frame), label);
gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
g_object_set_data (G_OBJECT (guide), "frame", frame);
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
gtk_constraint_layout_add_guide (layout, g_object_ref (guide));
for (i = 0; i < G_N_ELEMENTS (names); i++)
{
constraint = gtk_constraint_new (frame,
names[i].attr,
GTK_CONSTRAINT_RELATION_EQ,
guide,
names[i].attr,
1.0, 0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED);
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
gtk_constraint_layout_add_constraint (layout, constraint);
g_object_set_data (G_OBJECT (guide), names[i].name, constraint);
}
update_weak_position (view, frame, 150, 150);
}
void
constraint_view_remove_guide (ConstraintView *view,
GtkConstraintGuide *guide)
{
GtkConstraintLayout *layout;
GtkWidget *frame;
GtkConstraint *constraint;
const char *names[] = {
"left-constraint",
"top-constraint",
"width-constraint",
"height-constraint"
};
int i;
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
for (i = 0; i < G_N_ELEMENTS (names); i++)
{
constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), names[i]);
gtk_constraint_layout_remove_constraint (layout, constraint);
}
frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame");
update_weak_position (view, frame, -100, -100);
gtk_widget_unparent (frame);
gtk_constraint_layout_remove_guide (layout, guide);
}
void
constraint_view_add_constraint (ConstraintView *view,
GtkConstraint *constraint)
{
GtkLayoutManager *manager;
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
g_object_ref (constraint));
}
void
constraint_view_remove_constraint (ConstraintView *view,
GtkConstraint *constraint)
{
GtkLayoutManager *manager;
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
constraint);
}
GListModel *
constraint_view_get_model (ConstraintView *view)
{
return view->model;
}
-45
View File
@@ -1,45 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ())
G_MODULE_EXPORT
G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget)
ConstraintView * constraint_view_new (void);
void constraint_view_add_child (ConstraintView *view,
const char *name);
void constraint_view_remove_child (ConstraintView *view,
GtkWidget *child);
void constraint_view_add_guide (ConstraintView *view,
GtkConstraintGuide *guide);
void constraint_view_remove_guide (ConstraintView *view,
GtkConstraintGuide *guide);
void constraint_view_guide_changed (ConstraintView *view,
GtkConstraintGuide *guide);
void constraint_view_add_constraint (ConstraintView *view,
GtkConstraint *constraint);
void constraint_view_remove_constraint (ConstraintView *view,
GtkConstraint *constraint);
GListModel * constraint_view_get_model (ConstraintView *view);
-355
View File
@@ -1,355 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#include "config.h"
#include "guide-editor.h"
struct _GuideEditor
{
GtkWidget parent_instance;
GtkWidget *grid;
GtkWidget *name;
GtkWidget *min_width;
GtkWidget *min_height;
GtkWidget *nat_width;
GtkWidget *nat_height;
GtkWidget *max_width;
GtkWidget *max_height;
GtkWidget *strength;
GtkWidget *button;
GtkConstraintGuide *guide;
gboolean constructed;
};
enum {
PROP_GUIDE = 1,
LAST_PROP
};
static GParamSpec *pspecs[LAST_PROP];
enum {
DONE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
static GtkConstraintStrength
get_strength (unsigned int id)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
default: g_assert_not_reached ();
}
}
static unsigned int
get_strength_id (GtkConstraintStrength strength)
{
switch (strength)
{
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
default: g_assert_not_reached ();
}
}
static const char *
get_strength_nick (GtkConstraintStrength strength)
{
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
GEnumValue *value = g_enum_get_value (class, strength);
const char *nick = value->value_nick;
g_type_class_unref (class);
return nick;
}
void
guide_editor_serialize_guide (GString *str,
int indent,
GtkConstraintGuide *guide)
{
int min_width, min_height;
int nat_width, nat_height;
int max_width, max_height;
const char *name;
const char *strength;
gtk_constraint_guide_get_min_size (guide, &min_width, &min_height);
gtk_constraint_guide_get_nat_size (guide, &nat_width, &nat_height);
gtk_constraint_guide_get_max_size (guide, &max_width, &max_height);
name = gtk_constraint_guide_get_name (guide);
strength = get_strength_nick (gtk_constraint_guide_get_strength (guide));
g_string_append_printf (str, "%*s<guide min-width=\"%d\" min-height=\"%d\"\n", indent, "", min_width, min_height);
g_string_append_printf (str, "%*s nat-width=\"%d\" nat-height=\"%d\"\n", indent, "", nat_width, nat_height);
g_string_append_printf (str, "%*s max-width=\"%d\" max-height=\"%d\"\n", indent, "", max_width, max_height);
g_string_append_printf (str, "%*s name=\"%s\" strength=\"%s\" />\n", indent, "", name, strength);
}
static void
create_guide (GtkButton *button,
GuideEditor *editor)
{
int strength;
const char *name;
int w, h;
GtkConstraintGuide *guide;
unsigned int id;
if (editor->guide)
guide = g_object_ref (editor->guide);
else
guide = gtk_constraint_guide_new ();
name = gtk_editable_get_text (GTK_EDITABLE (editor->name));
gtk_constraint_guide_set_name (guide, name);
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_width));
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_height));
gtk_constraint_guide_set_min_size (guide, w, h);
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_width));
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_height));
gtk_constraint_guide_set_nat_size (guide, w, h);
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_width));
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_height));
gtk_constraint_guide_set_max_size (guide, w, h);
id = gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength));
strength = get_strength (id);
gtk_constraint_guide_set_strength (guide, strength);
g_signal_emit (editor, signals[DONE], 0, guide);
g_object_unref (guide);
}
static void
guide_editor_init (GuideEditor *editor)
{
gtk_widget_init_template (GTK_WIDGET (editor));
}
static int guide_counter;
static int
min_input (GtkSpinButton *spin_button,
double *new_val)
{
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
{
*new_val = 0.0;
return TRUE;
}
return FALSE;
}
static int
max_input (GtkSpinButton *spin_button,
double *new_val)
{
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
{
*new_val = G_MAXINT;
return TRUE;
}
return FALSE;
}
static void
guide_editor_constructed (GObject *object)
{
GuideEditor *editor = GUIDE_EDITOR (object);
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
if (editor->guide)
{
GtkConstraintStrength strength;
const char *nick;
int w, h;
nick = gtk_constraint_guide_get_name (editor->guide);
if (nick)
gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
gtk_constraint_guide_get_min_size (editor->guide, &w, &h);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), h);
gtk_constraint_guide_get_nat_size (editor->guide, &w, &h);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), w);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), h);
gtk_constraint_guide_get_max_size (editor->guide, &w, &h);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), w);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
strength = gtk_constraint_guide_get_strength (editor->guide);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
}
else
{
char *name;
guide_counter++;
name = g_strdup_printf ("Guide %d", guide_counter);
gtk_editable_set_text (GTK_EDITABLE (editor->name), name);
g_free (name);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), G_MAXINT);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), G_MAXINT);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_MEDIUM));
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
}
editor->constructed = TRUE;
}
static void
guide_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GuideEditor *self = GUIDE_EDITOR (object);
switch (property_id)
{
case PROP_GUIDE:
self->guide = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
guide_editor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GuideEditor *self = GUIDE_EDITOR (object);
switch (property_id)
{
case PROP_GUIDE:
g_value_set_object (value, self->guide);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
guide_editor_dispose (GObject *object)
{
GuideEditor *self = (GuideEditor *)object;
g_clear_object (&self->guide);
gtk_widget_dispose_template (GTK_WIDGET (self), GUIDE_EDITOR_TYPE);
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
}
static void
guide_editor_class_init (GuideEditorClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->constructed = guide_editor_constructed;
object_class->dispose = guide_editor_dispose;
object_class->set_property = guide_editor_set_property;
object_class->get_property = guide_editor_get_property;
pspecs[PROP_GUIDE] =
g_param_spec_object ("guide", "guide", "guide",
GTK_TYPE_CONSTRAINT_GUIDE,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
signals[DONE] =
g_signal_new ("done",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT_GUIDE);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/gtk4/constraint-editor/guide-editor.ui");
gtk_widget_class_bind_template_child (widget_class, GuideEditor, grid);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, name);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_width);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_height);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_width);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_height);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_width);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_height);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, strength);
gtk_widget_class_bind_template_child (widget_class, GuideEditor, button);
gtk_widget_class_bind_template_callback (widget_class, create_guide);
}
GuideEditor *
guide_editor_new (GtkConstraintGuide *guide)
{
return g_object_new (GUIDE_EDITOR_TYPE,
"guide", guide,
NULL);
}
-32
View File
@@ -1,32 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen
*/
#pragma once
#include <gtk/gtk.h>
#define GUIDE_EDITOR_TYPE (guide_editor_get_type ())
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
void guide_editor_serialize_guide (GString *str,
int indent,
GtkConstraintGuide *guide);
-201
View File
@@ -1,201 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="min_width_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="min_height_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="nat_width_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="nat_height_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="max_width_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<object class="GtkAdjustment" id="max_height_adj">
<property name="lower">0</property>
<property name="upper">2147483647</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
<property name="page-size">0</property>
</object>
<template class="GuideEditor" parent="GtkWidget">
<child>
<object class="GtkGrid" id="grid">
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="label">Name</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="name">
<property name="max-width-chars">20</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Min Size</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="min_width">
<property name="adjustment">min_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="min_height">
<property name="adjustment">min_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">2</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Nat Size</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="nat_width">
<property name="adjustment">nat_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="nat_height">
<property name="adjustment">nat_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">2</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Max Size</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="max_width">
<property name="adjustment">max_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkSpinButton" id="max_height">
<property name="adjustment">max_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">2</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Strength</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="strength">
<property name="model">
<object class="GtkStringList">
<items>
<item>Weak</item>
<item>Medium</item>
<item>Strong</item>
<item>Required</item>
</items>
</object>
</property>
<layout>
<property name="column">1</property>
<property name="row">4</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="button">
<property name="label">Create</property>
<signal name="clicked" handler="create_guide"/>
<layout>
<property name="column">2</property>
<property name="row">5</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>
-28
View File
@@ -1,28 +0,0 @@
/*
* Copyright © 2019 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/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <constraint-editor-application.h>
int
main (int argc, char *argv[])
{
return g_application_run (G_APPLICATION (constraint_editor_application_new ()), argc, argv);
}
-23
View File
@@ -1,23 +0,0 @@
constraint_editor_sources = [
'main.c',
'constraint-editor-application.c',
'constraint-editor-window.c',
'constraint-view.c',
'constraint-editor.c',
'guide-editor.c',
]
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
'constraint-editor.gresource.xml',
source_dir: meson.current_source_dir(),
)
executable('gtk4-constraint-editor',
sources: [ constraint_editor_sources, constraint_editor_resources, ],
c_args: common_cflags,
dependencies: libgtk_dep,
include_directories: confinc,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: false,
)
File diff suppressed because it is too large Load Diff
-26
View File
@@ -1,26 +0,0 @@
uniform float u_time;
void
mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
vec2 pos = (fragCoord.xy * 2.0 - resolution.xy)/ min (resolution.x, resolution.y) ;
float t0 = sin ((u_time + 0.00)*1.0);
float t1 = sin ((u_time + 0.30)*0.4);
float t2 = cos ((u_time + 0.23)*0.9);
float t3 = cos ((u_time + 0.41)*0.6);
float t4 = cos ((u_time + 0.11)*0.3);
vec2 p0 = vec2 (t1, t0) ;
vec2 p1 = vec2 (t2, t3) ;
vec2 p2 = vec2 (t4, t3) ;
float r = 1.0/distance (pos, p0);
float g = 1.0/distance (pos, p1);
float b = 1.0/distance (pos, p2);
float sum = r + g + b;
float alpha = 1.0 - pow (1.0/(sum), 40.0)*pow (10.0, 40.0*0.7);
fragColor = vec4 (r*0.5, g*0.5, b*0.5, 1.0) * alpha;
}
-226
View File
@@ -1,226 +0,0 @@
uniform float iTime;
// Originally from: https://www.shadertoy.com/view/3ljyDD
// License CC0: Hexagonal tiling + cog wheels
// Nothing fancy, just hexagonal tiling + cog wheels
#define PI 3.141592654
#define TAU (2.0*PI)
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
float hash(in vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
}
float pcos(float a) {
return 0.5 + 0.5*cos(a);
}
void rot(inout vec2 p, float a) {
float c = cos(a);
float s = sin(a);
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
}
float modPolar(inout vec2 p, float repetitions) {
float angle = 2.0*PI/repetitions;
float a = atan(p.y, p.x) + angle/2.;
float r = length(p);
float c = floor(a/angle);
a = mod(a,angle) - angle/2.;
p = vec2(cos(a), sin(a))*r;
// For an odd number of repetitions, fix cell index of the cell in -x direction
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
if (abs(c) >= (repetitions/2.0)) c = abs(c);
return c;
}
float pmin(float a, float b, float k) {
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
return mix( b, a, h ) - k*h*(1.0-h);
}
const vec2 sz = vec2(1.0, sqrt(3.0));
const vec2 hsz = 0.5*sz;
const float smallCount = 16.0;
vec2 hextile(inout vec2 p) {
// See Art of Code: Hexagonal Tiling Explained!
// https://www.youtube.com/watch?v=VmrIDyYiJBA
vec2 p1 = mod(p, sz)-hsz;
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
vec2 n = p3 - p;
p = p3;
return n;
}
float circle(vec2 p, float r) {
return length(p) - r;
}
float box(vec2 p, vec2 b) {
vec2 d = abs(p)-b;
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}
float unevenCapsule(vec2 p, float r1, float r2, float h) {
p.x = abs(p.x);
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(p,vec2(-b,a));
if( k < 0.0 ) return length(p) - r1;
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
return dot(p, vec2(a,b) ) - r1;
}
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
float cogWidth = 0.25*innerRadius*TAU/cogs;
float d0 = circle(p, innerRadius);
vec2 icp = p;
modPolar(icp, holes);
icp -= vec2(innerRadius*0.55, 0.0);
float d1 = circle(icp, innerRadius*0.25);
vec2 cp = p;
modPolar(cp, cogs);
cp -= vec2(innerRadius, 0.0);
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
float d3 = circle(p, innerRadius*0.20);
float d = 1E6;
d = min(d, d0);
d = pmin(d, d2, 0.5*cogWidth);
d = min(d, d2);
d = max(d, -d1);
d = max(d, -d3);
return d;
}
float ccell1(vec2 p, float r) {
float d = 1E6;
const float bigCount = 60.0;
vec2 cp0 = p;
rot(cp0, -iTime*TAU/bigCount);
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
vec2 cp1 = p;
float nm = modPolar(cp1, 6.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
d = min(d, d0);
d = min(d, d1);
return d;
}
float ccell2(vec2 p, float r) {
float d = 1E6;
vec2 cp0 = p;
float nm = modPolar(cp0, 6.0);
vec2 cp1 = cp0;
const float off = 0.275;
const float count = smallCount + 2.0;
cp0 -= vec2(off, 0.0);
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
float l = length(p);
float d2 = l - (off+0.055);
float d3 = d2 + 0.020;;
vec2 tp0 = p;
modPolar(tp0, 60.0);
tp0.x -= off;
float d4 = box(tp0, vec2(0.0125, 0.005));
float ctime = -(iTime*0.05 + r)*TAU;
vec2 tp1 = p;
rot(tp1, ctime*12.0);
tp1.x -= 0.13;
float d5 = box(tp1, vec2(0.125, 0.005));
vec2 tp2 = p;
rot(tp2, ctime);
tp2.x -= 0.13*0.5;
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
float d7 = l - 0.025;
float d8 = l - 0.0125;
d = min(d, d0);
d = min(d, d1);
d = min(d, d2);
d = max(d, -d3);
d = min(d, d4);
d = min(d, d5);
d = min(d, d6);
d = min(d, d7);
d = max(d, -d8);
return d;
}
float df(vec2 p, float scale, inout vec2 nn) {
p /= scale;
nn = hextile(p);
nn = floor(nn + 0.5);
float r = hash(nn);
float d;;
if (r < 0.5) {
d = ccell1(p, r);
} else {
d = ccell2(p, r);
}
return d*scale;
}
vec3 postProcess(vec3 col, vec2 q) {
//col = saturate(col);
col=pow(clamp(col,0.0,1.0),vec3(0.75));
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
return col;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv) {
vec2 q = fragCoord/resolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= resolution.x/resolution.y;
float tm = iTime*0.1;
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
float aa = 4.0 / resolution.y;
vec2 nn = vec2(0.0);
float d = df(p, z, nn);
vec3 col = vec3(160.0)/vec3(255.0);
vec3 baseCol = vec3(0.3);
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
col = postProcess(col, q);
fragColor = vec4(col, 1.0);
}
-27
View File
@@ -1,27 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/crosswarp
// Author: Eke Péter <peterekepeter@gmail.com>
// License: MIT
vec4 transition(vec2 p) {
float x = progress;
x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));
return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
+4 -16
View File
@@ -146,21 +146,6 @@
<file>cogs.glsl</file>
<file>glowingstars.glsl</file>
</gresource>
<gresource prefix="/gltransition">
<file>gtkshaderstack.c</file>
<file>gtkshaderstack.h</file>
<file>gtkshaderbin.h</file>
<file>gtkshaderbin.c</file>
<file>gskshaderpaintable.h</file>
<file>gskshaderpaintable.c</file>
<file>wind.glsl</file>
<file>radial.glsl</file>
<file>crosswarp.glsl</file>
<file>kaleidoscope.glsl</file>
<file>cogs2.glsl</file>
<file>ripple.glsl</file>
<file>background.glsl</file>
</gresource>
<gresource prefix="/iconscroll">
<file>iconscroll.ui</file>
</gresource>
@@ -296,7 +281,6 @@
<file>gears.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>gltransition.c</file>
<file>headerbar.c</file>
<file>hypertext.c</file>
<file>iconscroll.c</file>
@@ -454,6 +438,10 @@
<file>icons/16x16/categories/applications-other.png</file>
<file>icons/48x48/status/starred.png</file>
<file alias="icons/scalable/apps/org.gtk.Demo4.svg">data/scalable/apps/org.gtk.Demo4.svg</file>
<file>portland-rose-thumbnail.png</file>
<file>large-image-thumbnail.png</file>
<file compressed="true">large-image.png</file>
<file compressed="true">Moby-Dick.txt</file>
</gresource>
<gresource prefix="/org/gtk/Demo4/gtk">
<file preprocess="xml-stripblanks">help-overlay.ui</file>
+1 -1
View File
@@ -55,7 +55,7 @@ mode_switch_state_set (GtkSwitch *sw,
{
gtk_widget_set_visible (label, TRUE);
gtk_accessible_update_relation (GTK_ACCESSIBLE (sw),
GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, label,
GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, label, NULL,
-1);
gtk_accessible_update_state (GTK_ACCESSIBLE (sw),
GTK_ACCESSIBLE_STATE_INVALID, GTK_ACCESSIBLE_INVALID_TRUE,
-42
View File
@@ -9,7 +9,6 @@
#include "gtkfishbowl.h"
#include "gtkgears.h"
#include "gskshaderpaintable.h"
#include "nodewidget.h"
#include "graphwidget.h"
@@ -152,46 +151,6 @@ create_switch (void)
return w;
}
static gboolean
update_paintable (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GskShaderPaintable *paintable;
gint64 frame_time;
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
gsk_shader_paintable_update_time (paintable, 0, frame_time);
return G_SOURCE_CONTINUE;
}
static GtkWidget *
create_cogs (void)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
GtkWidget *picture;
static GskGLShader *cog_shader = NULL;
GdkPaintable *paintable;
if (cog_shader == NULL)
cog_shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
paintable = gsk_shader_paintable_new (g_object_ref (cog_shader), NULL);
picture = gtk_picture_new_for_paintable (paintable);
gtk_widget_set_size_request (picture, 150, 75);
gtk_widget_add_tick_callback (picture, update_paintable, NULL, NULL);
return picture;
G_GNUC_END_IGNORE_DEPRECATIONS
}
static gboolean
check_cogs (GtkFishbowl *fb)
{
return GSK_IS_GL_RENDERER (gtk_native_get_renderer (gtk_widget_get_native (GTK_WIDGET (fb))));
}
static void
mapped (GtkWidget *w)
{
@@ -241,7 +200,6 @@ static const struct {
{ "Gears", create_gears, NULL },
{ "Switch", create_switch, NULL },
{ "Menubutton", create_menu_button, NULL },
{ "Shader", create_cogs, check_cogs },
{ "Tiger", create_tiger, NULL },
{ "Graph", create_graph, NULL },
};
+1 -1
View File
@@ -276,7 +276,7 @@ gtk_font_plane_class_init (GtkFontPlaneClass *class)
GtkWidget *
gtk_font_plane_new (GtkAdjustment *weight_adj,
GtkAdjustment *width_adj)
GtkAdjustment *width_adj)
{
return g_object_new (GTK_TYPE_FONT_PLANE,
"weight-adjustment", weight_adj,
+2 -2
View File
@@ -55,7 +55,7 @@ struct _GtkFontPlaneClass
GType gtk_font_plane_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_font_plane_new (GtkAdjustment *width_adj,
GtkAdjustment *weight_adj);
GtkWidget * gtk_font_plane_new (GtkAdjustment *weight_adj,
GtkAdjustment *width_adj);
G_END_DECLS
-366
View File
@@ -1,366 +0,0 @@
/* OpenGL/Transitions and Effects
* #Keywords: OpenGL, shader, effect
*
* Create transitions between pages using a custom fragment shader.
*
* The example transitions here are taken from gl-transitions.com, and you
* can edit the shader code itself on the last page of the stack.
*
* The transitions work with arbitrary content. We use images, shaders
* GL areas and plain old widgets to demonstrate this.
*
* The demo also shows some over-the-top effects like wobbly widgets,
* and animated backgrounds.
*/
#include <math.h>
#include <gtk/gtk.h>
#include "gtkshaderstack.h"
#include "gtkshaderbin.h"
#include "gtkshadertoy.h"
#include "gskshaderpaintable.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *demo_window = NULL;
static void
close_window (GtkWidget *widget)
{
/* Reset the state */
demo_window = NULL;
}
static void
text_changed (GtkTextBuffer *buffer,
GtkWidget *button)
{
gtk_widget_set_visible (button, TRUE);
}
static void
apply_text (GtkWidget *button,
GtkTextBuffer *buffer)
{
GtkWidget *stack;
GskGLShader *shader;
GtkTextIter start, end;
char *text;
stack = g_object_get_data (G_OBJECT (button), "the-stack");
gtk_text_buffer_get_bounds (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
GBytes *bytes = g_bytes_new_take (text, strlen (text));
shader = gsk_gl_shader_new_from_bytes (bytes);
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
g_object_unref (shader);
g_bytes_unref (bytes);
gtk_widget_set_visible (button, FALSE);
}
static void
go_back (GtkWidget *button,
GtkWidget *stack)
{
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), FALSE);
}
static void
go_forward (GtkWidget *button,
GtkWidget *stack)
{
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), TRUE);
}
static void
clicked_cb (GtkGestureClick *gesture,
guint n_pressed,
double x,
double y,
gpointer data)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static GtkWidget *
ripple_bin_new (void)
{
GtkWidget *bin = gtk_shader_bin_new ();
static GskGLShader *shader = NULL;
if (shader == NULL)
shader = gsk_gl_shader_new_from_resource ("/gltransition/ripple.glsl");
gtk_shader_bin_add_shader (GTK_SHADER_BIN (bin), shader, GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_PRELIGHT, 20);
return bin;
}
static GtkWidget *
new_shadertoy (const char *path)
{
GBytes *shader;
GtkWidget *toy;
toy = gtk_shadertoy_new ();
shader = g_resources_lookup_data (path, 0, NULL);
gtk_shadertoy_set_image_shader (GTK_SHADERTOY (toy),
g_bytes_get_data (shader, NULL));
g_bytes_unref (shader);
return toy;
}
static gboolean
update_paintable (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GskShaderPaintable *paintable;
gint64 frame_time;
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
gsk_shader_paintable_update_time (paintable, 0, frame_time);
return G_SOURCE_CONTINUE;
}
static GtkWidget *
make_shader_stack (const char *name,
const char *resource_path,
int active_child,
GtkWidget *scale)
{
GtkWidget *stack, *child, *widget, *vbox, *hbox, *bin;
GtkWidget *label, *button, *tv;
GskGLShader *shader;
GObjectClass *class;
GParamSpecFloat *pspec;
GtkAdjustment *adjustment;
GtkTextBuffer *buffer;
GBytes *bytes;
GtkEventController *controller;
GdkPaintable *paintable;
stack = gtk_shader_stack_new ();
shader = gsk_gl_shader_new_from_resource (resource_path);
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
g_object_unref (shader);
child = gtk_picture_new_for_resource ("/css_blendmodes/ducky.png");
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
paintable = gsk_shader_paintable_new (shader, NULL);
child = gtk_picture_new_for_paintable (paintable);
gtk_widget_add_tick_callback (child, update_paintable, NULL, NULL);
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = new_shadertoy ("/shadertoy/neon.glsl");
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
class = g_type_class_ref (GTK_TYPE_SHADER_STACK);
pspec = G_PARAM_SPEC_FLOAT (g_object_class_find_property (class, "duration"));
adjustment = gtk_range_get_adjustment (GTK_RANGE (scale));
if (gtk_adjustment_get_lower (adjustment) == 0.0 &&
gtk_adjustment_get_upper (adjustment) == 0.0)
{
gtk_adjustment_configure (adjustment,
pspec->default_value,
pspec->minimum,
pspec->maximum,
0.1, 0.5, 0);
}
g_type_class_unref (class);
g_object_bind_property (adjustment, "value",
stack, "duration",
G_BINDING_DEFAULT);
widget = gtk_scrolled_window_new ();
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (widget), TRUE);
gtk_widget_set_hexpand (widget, TRUE);
gtk_widget_set_vexpand (widget, TRUE);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), 0);
g_signal_connect (controller, "released", G_CALLBACK (clicked_cb), NULL);
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
gtk_widget_add_controller (GTK_WIDGET (widget), controller);
tv = gtk_text_view_new ();
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_top_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_bottom_margin (GTK_TEXT_VIEW (tv), 4);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
bytes = g_resources_lookup_data (resource_path, 0, NULL);
gtk_text_buffer_set_text (buffer,
(const char *)g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes));
g_bytes_unref (bytes);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (widget), tv);
gtk_box_append (GTK_BOX (child), widget);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
gtk_shader_stack_set_active (GTK_SHADER_STACK (stack), active_child);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
widget = gtk_center_box_new ();
label = gtk_label_new (name);
gtk_widget_add_css_class (label, "title-4");
gtk_widget_set_size_request (label, -1, 26);
gtk_center_box_set_center_widget (GTK_CENTER_BOX (widget), label);
button = gtk_button_new_from_icon_name ("view-refresh-symbolic");
g_signal_connect (buffer, "changed", G_CALLBACK (text_changed), button);
g_object_set_data (G_OBJECT (button), "the-stack", stack);
g_signal_connect (button, "clicked", G_CALLBACK (apply_text), buffer);
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_widget_add_css_class (button, "small");
gtk_widget_set_visible (button, FALSE);
gtk_center_box_set_end_widget (GTK_CENTER_BOX (widget), button);
gtk_box_append (GTK_BOX (vbox), widget);
GtkWidget *bin2 = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin2), stack);
gtk_box_append (GTK_BOX (vbox), bin2);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), hbox);
button = gtk_button_new_from_icon_name ("go-previous-symbolic");
g_signal_connect (button, "clicked", G_CALLBACK (go_back), stack);
bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
button = gtk_button_new_from_icon_name ("go-next-symbolic");
g_signal_connect (button, "clicked", G_CALLBACK (go_forward), stack);
bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
return vbox;
}
static void
remove_provider (gpointer data)
{
GtkStyleProvider *provider = GTK_STYLE_PROVIDER (data);
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
g_object_unref (provider);
}
static GtkWidget *
create_gltransition_window (GtkWidget *do_widget)
{
GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
GdkPaintable *paintable;
GtkCssProvider *provider;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Transitions and Effects");
headerbar = gtk_header_bar_new ();
scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
gtk_widget_set_size_request (scale, 100, -1);
gtk_widget_set_tooltip_text (scale, "Transition duration");
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), scale);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
outer_grid = gtk_grid_new ();
gtk_window_set_child (GTK_WINDOW (window), outer_grid);
paintable = gsk_shader_paintable_new (gsk_gl_shader_new_from_resource ("/gltransition/background.glsl"), NULL);
background = gtk_picture_new_for_paintable (paintable);
gtk_widget_add_tick_callback (background, update_paintable, NULL, NULL);
gtk_grid_attach (GTK_GRID (outer_grid),
background,
0, 0, 1, 1);
grid = gtk_grid_new ();
gtk_grid_attach (GTK_GRID (outer_grid),
grid,
0, 0, 1, 1);
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start (grid, 12);
gtk_widget_set_margin_end (grid, 12);
gtk_widget_set_margin_top (grid, 12);
gtk_widget_set_margin_bottom (grid, 12);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Wind", "/gltransition/wind.glsl", 0, scale),
0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Radial", "/gltransition/radial.glsl", 1, scale),
1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Crosswarp", "/gltransition/crosswarp.glsl", 2, scale),
0, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Kaleidoscope", "/gltransition/kaleidoscope.glsl", 3, scale),
1, 1, 1, 1);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, "button.small { padding: 0; }");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_set_data_full (G_OBJECT (window), "provider", provider, remove_provider);
return window;
}
GtkWidget *
do_gltransition (GtkWidget *do_widget)
{
if (!demo_window)
demo_window = create_gltransition_window (do_widget);
if (!gtk_widget_get_visible (demo_window))
gtk_widget_set_visible (demo_window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (demo_window));
return demo_window;
}
G_GNUC_END_IGNORE_DEPRECATIONS
-338
View File
@@ -1,338 +0,0 @@
/*
* Copyright © 2020 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/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gskshaderpaintable.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/**
* GskShaderPaintable:
*
* `GskShaderPaintable` is an implementation of the `GdkPaintable` interface
* that uses a `GskGLShader` to create pixels.
*
* You can set the uniform data that the shader needs for rendering
* using gsk_shader_paintable_set_args(). This function can
* be called repeatedly to change the uniform data for the next
* snapshot.
*
* Commonly, time is passed to shaders as a float uniform containing
* the elapsed time in seconds. The convenience API
* gsk_shader_paintable_update_time() can be called from a `GtkTickCallback`
* to update the time based on the frame time of the frame clock.
*/
struct _GskShaderPaintable
{
GObject parent_instance;
GskGLShader *shader;
GBytes *args;
gint64 start_time;
};
struct _GskShaderPaintableClass
{
GObjectClass parent_class;
};
enum {
PROP_0,
PROP_SHADER,
PROP_ARGS,
N_PROPS,
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gsk_shader_paintable_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (paintable);
gtk_snapshot_push_gl_shader (snapshot, self->shader, &GRAPHENE_RECT_INIT(0, 0, width, height), g_bytes_ref (self->args));
gtk_snapshot_pop (snapshot);
}
static void
gsk_shader_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gsk_shader_paintable_paintable_snapshot;
}
G_DEFINE_TYPE_EXTENDED (GskShaderPaintable, gsk_shader_paintable, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gsk_shader_paintable_paintable_init))
static void
gsk_shader_paintable_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
switch (prop_id)
{
case PROP_SHADER:
gsk_shader_paintable_set_shader (self, g_value_get_object (value));
break;
case PROP_ARGS:
gsk_shader_paintable_set_args (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gsk_shader_paintable_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
switch (prop_id)
{
case PROP_SHADER:
g_value_set_object (value, self->shader);
break;
case PROP_ARGS:
g_value_set_boxed (value, self->args);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gsk_shader_paintable_finalize (GObject *object)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
g_clear_pointer (&self->args, g_bytes_unref);
g_clear_object (&self->shader);
G_OBJECT_CLASS (gsk_shader_paintable_parent_class)->finalize (object);
}
static void
gsk_shader_paintable_class_init (GskShaderPaintableClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gsk_shader_paintable_get_property;
gobject_class->set_property = gsk_shader_paintable_set_property;
gobject_class->finalize = gsk_shader_paintable_finalize;
properties[PROP_SHADER] =
g_param_spec_object ("shader", "Shader", "The shader",
GSK_TYPE_GL_SHADER,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_ARGS] =
g_param_spec_boxed ("args", "Arguments", "The uniform arguments",
G_TYPE_BYTES,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gsk_shader_paintable_init (GskShaderPaintable *self)
{
}
/**
* gsk_shader_paintable_new:
* @shader: (transfer full) (nullable): the shader to use
* @data: (transfer full) (nullable): uniform data
*
* Creates a paintable that uses the @shader to create
* pixels. The shader must not require input textures.
* If @data is %NULL, all uniform values are set to zero.
*
* Returns: (transfer full): a new `GskShaderPaintable`
*/
GdkPaintable *
gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data)
{
GdkPaintable *ret;
g_return_val_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader), NULL);
if (shader && !data)
{
int size = gsk_gl_shader_get_args_size (shader);
data = g_bytes_new_take (g_new0 (guchar, size), size);
}
ret = g_object_new (GSK_TYPE_SHADER_PAINTABLE,
"shader", shader,
"args", data,
NULL);
g_clear_object (&shader);
g_clear_pointer (&data, g_bytes_unref);
return ret;
}
/**
* gsk_shader_paintable_set_shader:
* @self: a `GskShaderPaintable`
* @shader: the `GskGLShader` to use
*
* Sets the shader that the paintable will use
* to create pixels. The shader must not require
* input textures.
*/
void
gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader)
{
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
g_return_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader));
g_return_if_fail (shader == NULL || gsk_gl_shader_get_n_textures (shader) == 0);
if (!g_set_object (&self->shader, shader))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHADER]);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
g_clear_pointer (&self->args, g_bytes_unref);
}
/**
* gsk_shader_paintable_get_shader:
* @self: a `GskShaderPaintable`
*
* Returns the shader that the paintable is using.
*
* Returns: (transfer none): the `GskGLShader` that is used
*/
GskGLShader *
gsk_shader_paintable_get_shader (GskShaderPaintable *self)
{
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
return self->shader;
}
/**
* gsk_shader_paintable_set_args:
* @self: a `GskShaderPaintable`
* @data: Data block with uniform data for the shader
*
* Sets the uniform data that will be passed to the
* shader when rendering. The @data will typically
* be produced by a `GskUniformDataBuilder`.
*
* Note that the @data should be considered immutable
* after it has been passed to this function.
*/
void
gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data)
{
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
g_return_if_fail (data == NULL || g_bytes_get_size (data) == gsk_gl_shader_get_args_size (self->shader));
g_clear_pointer (&self->args, g_bytes_unref);
if (data)
self->args = g_bytes_ref (data);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ARGS]);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
/**
* gsk_shader_paintable_get_args:
* @self: a `GskShaderPaintable`
*
* Returns the uniform data set with
* gsk_shader_paintable_get_args().
*
* Returns: (transfer none): the uniform data
*/
GBytes *
gsk_shader_paintable_get_args (GskShaderPaintable *self)
{
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
return self->args;
}
/**
* gsk_shader_paintable_update_time:
* @self: a `GskShaderPaintable`
* @time_idx: the index of the uniform for time in seconds as float
* @frame_time: the current frame time, as returned by `GdkFrameClock`
*
* This function is a convenience wrapper for
* gsk_shader_paintable_set_args() that leaves all
* uniform values unchanged, except for the uniform with
* index @time_idx, which will be set to the elapsed time
* in seconds, since the first call to this function.
*
* This function is usually called from a `GtkTickCallback`.
*/
void
gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time)
{
GskShaderArgsBuilder *builder;
GBytes *args;
float time;
if (self->start_time == 0)
self->start_time = frame_time;
time = (frame_time - self->start_time) / (float)G_TIME_SPAN_SECOND;
builder = gsk_shader_args_builder_new (self->shader, self->args);
gsk_shader_args_builder_set_float (builder, time_idx, time);
args = gsk_shader_args_builder_free_to_args (builder);
gsk_shader_paintable_set_args (self, args);
g_bytes_unref (args);
}
G_GNUC_END_IGNORE_DEPRECATIONS
-47
View File
@@ -1,47 +0,0 @@
/*
* Copyright © 2020 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/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#pragma once
#include <gdk/gdk.h>
#include <gsk/gsk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GSK_TYPE_SHADER_PAINTABLE (gsk_shader_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GskShaderPaintable, gsk_shader_paintable, GSK, SHADER_PAINTABLE, GObject)
GdkPaintable * gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data);
GskGLShader * gsk_shader_paintable_get_shader (GskShaderPaintable *self);
void gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader);
GBytes * gsk_shader_paintable_get_args (GskShaderPaintable *self);
void gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data);
void gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS
+1 -1
View File
@@ -55,7 +55,7 @@ void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
gboolean animating);
gboolean gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
gboolean animating);
gboolean benchmark);
double gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl);
gint64 gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
-268
View File
@@ -1,268 +0,0 @@
#include "gtkshaderbin.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
typedef struct {
GskGLShader *shader;
GtkStateFlags state;
GtkStateFlags state_mask;
float extra_border;
gboolean compiled;
gboolean compiled_ok;
} ShaderInfo;
struct _GtkShaderBin
{
GtkWidget parent_instance;
GtkWidget *child;
ShaderInfo *active_shader;
GPtrArray *shaders;
guint tick_id;
float time;
float mouse_x, mouse_y;
gint64 first_frame_time;
};
struct _GtkShaderBinClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkShaderBin, gtk_shader_bin, GTK_TYPE_WIDGET)
static void
shader_info_free (ShaderInfo *info)
{
g_object_unref (info->shader);
g_free (info);
}
static void
gtk_shader_bin_finalize (GObject *object)
{
GtkShaderBin *self = GTK_SHADER_BIN (object);
g_ptr_array_free (self->shaders, TRUE);
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->finalize (object);
}
static void
gtk_shader_bin_dispose (GObject *object)
{
GtkShaderBin *self = GTK_SHADER_BIN (object);
g_clear_pointer (&self->child, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->dispose (object);
}
static gboolean
gtk_shader_bin_tick (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer unused)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
gint64 frame_time;
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
if (self->first_frame_time == 0)
self->first_frame_time = frame_time;
self->time = (frame_time - self->first_frame_time) / (float)G_USEC_PER_SEC;
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
motion_cb (GtkEventControllerMotion *controller,
double x,
double y,
GtkShaderBin *self)
{
self->mouse_x = x;
self->mouse_y = y;
}
static void
gtk_shader_bin_init (GtkShaderBin *self)
{
GtkEventController *controller;
self->shaders = g_ptr_array_new_with_free_func ((GDestroyNotify)shader_info_free);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
void
gtk_shader_bin_update_active_shader (GtkShaderBin *self)
{
GtkStateFlags new_state = gtk_widget_get_state_flags (GTK_WIDGET (self));
ShaderInfo *new_shader = NULL;
for (int i = 0; i < self->shaders->len; i++)
{
ShaderInfo *info = g_ptr_array_index (self->shaders, i);
if ((info->state_mask & new_state) == info->state)
{
new_shader = info;
break;
}
}
if (self->active_shader == new_shader)
return;
self->active_shader = new_shader;
self->first_frame_time = 0;
if (self->active_shader)
{
if (self->tick_id == 0)
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
gtk_shader_bin_tick,
NULL, NULL);
}
else
{
if (self->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
self->tick_id = 0;
}
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_shader_bin_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state_flags)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
gtk_shader_bin_update_active_shader (self);
}
void
gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
GtkStateFlags state_mask,
float extra_border)
{
ShaderInfo *info = g_new0 (ShaderInfo, 1);
info->shader = g_object_ref (shader);
info->state = state;
info->state_mask = state_mask;
info->extra_border = extra_border;
g_ptr_array_add (self->shaders, info);
gtk_shader_bin_update_active_shader (self);
}
void
gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child)
{
if (self->child == child)
return;
g_clear_pointer (&self->child, gtk_widget_unparent);
if (child)
{
self->child = child;
gtk_widget_set_parent (child, GTK_WIDGET (self));
}
}
GtkWidget *
gtk_shader_bin_get_child (GtkShaderBin *self)
{
return self->child;
}
static void
gtk_shader_bin_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
if (self->active_shader)
{
if (!self->active_shader->compiled)
{
GtkNative *native = gtk_widget_get_native (widget);
GskRenderer *renderer = gtk_native_get_renderer (native);
GError *error = NULL;
self->active_shader->compiled = TRUE;
self->active_shader->compiled_ok =
gsk_gl_shader_compile (self->active_shader->shader,
renderer, &error);
if (!self->active_shader->compiled_ok)
{
g_warning ("GtkShaderBin failed to compile shader: %s", error->message);
g_error_free (error);
}
}
if (self->active_shader->compiled_ok)
{
float border = self->active_shader->extra_border;
graphene_vec2_t mouse;
graphene_vec2_init (&mouse, self->mouse_x + border, self->mouse_y + border);
gtk_snapshot_push_gl_shader (snapshot, self->active_shader->shader,
&GRAPHENE_RECT_INIT(-border, -border, width+2*border, height+2*border),
gsk_gl_shader_format_args (self->active_shader->shader,
"u_time", self->time,
"u_mouse", &mouse,
NULL));
gtk_widget_snapshot_child (widget, self->child, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot);
gtk_snapshot_pop (snapshot);
return;
}
}
/* Non-shader fallback */
gtk_widget_snapshot_child (widget, self->child, snapshot);
}
static void
gtk_shader_bin_class_init (GtkShaderBinClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gtk_shader_bin_finalize;
object_class->dispose = gtk_shader_bin_dispose;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
widget_class->snapshot = gtk_shader_bin_snapshot;
widget_class->state_flags_changed = gtk_shader_bin_state_flags_changed;
}
GtkWidget *
gtk_shader_bin_new (void)
{
GtkShaderBin *self;
self = g_object_new (GTK_TYPE_SHADER_BIN, NULL);
return GTK_WIDGET (self);
}
G_GNUC_END_IGNORE_DEPRECATIONS
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_BIN (gtk_shader_bin_get_type ())
G_DECLARE_FINAL_TYPE (GtkShaderBin, gtk_shader_bin, GTK, SHADER_BIN, GtkWidget)
GtkWidget *gtk_shader_bin_new (void);
void gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
GtkStateFlags state_mask,
float extra_border);
void gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child);
GtkWidget *gtk_shader_bin_get_child (GtkShaderBin *self);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS
-365
View File
@@ -1,365 +0,0 @@
#include "gtkshaderstack.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
struct _GtkShaderStack
{
GtkWidget parent_instance;
GskGLShader *shader;
GPtrArray *children;
int current;
int next;
gboolean backwards;
guint tick_id;
float time;
float duration;
gint64 start_time;
};
struct _GtkShaderStackClass
{
GtkWidgetClass parent_class;
};
enum {
PROP_DURATION = 1,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL };
G_DEFINE_TYPE (GtkShaderStack, gtk_shader_stack, GTK_TYPE_WIDGET)
static void
gtk_shader_stack_finalize (GObject *object)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
g_object_unref (self->shader);
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->finalize (object);
}
static void
update_child_visible (GtkShaderStack *self)
{
int i;
for (i = 0; i < self->children->len; i++)
{
GtkWidget *child = g_ptr_array_index (self->children, i);
gtk_widget_set_child_visible (child,
i == self->current || i == self->next);
}
}
static gboolean
transition_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer unused)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
gint64 frame_time;
frame_time = gdk_frame_clock_get_frame_time (clock);
if (self->start_time == 0)
self->start_time = frame_time;
self->time = (frame_time - self->start_time) / (float)G_USEC_PER_SEC;
gtk_widget_queue_draw (widget);
if (self->time >= self->duration)
{
self->current = self->next;
self->next = -1;
update_child_visible (self);
return G_SOURCE_REMOVE;
}
else
return G_SOURCE_CONTINUE;
}
static void
start_transition (GtkShaderStack *self)
{
self->start_time = 0;
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
transition_cb,
NULL, NULL);
}
static void
stop_transition (GtkShaderStack *self)
{
if (self->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
self->tick_id = 0;
}
if (self->next != -1)
self->current = self->next;
self->next = -1;
update_child_visible (self);
}
static void
gtk_shader_stack_dispose (GObject *object)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
stop_transition (self);
g_clear_pointer (&self->children, g_ptr_array_unref);
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->dispose (object);
}
void
gtk_shader_stack_transition (GtkShaderStack *self,
gboolean forward)
{
stop_transition (self);
self->backwards = !forward;
if (self->backwards)
self->next = (self->current + self->children->len - 1) % self->children->len;
else
self->next = (self->current + 1) % self->children->len;
update_child_visible (self);
start_transition (self);
}
static void
gtk_shader_stack_init (GtkShaderStack *self)
{
self->children = g_ptr_array_new_with_free_func ((GDestroyNotify)gtk_widget_unparent);
self->current = -1;
self->next = -1;
self->backwards = FALSE;
self->duration = 1.0;
}
static void
gtk_shader_stack_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
int i;
*minimum = 0;
*natural = 0;
for (i = 0; i < self->children->len; i++)
{
GtkWidget *child = g_ptr_array_index (self->children, i);
int child_min, child_nat;
if (gtk_widget_get_visible (child))
{
gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
}
}
}
static void
gtk_shader_stack_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
GtkAllocation child_allocation;
GtkWidget *child;
int i;
child_allocation.x = 0;
child_allocation.y = 0;
child_allocation.width = width;
child_allocation.height = height;
for (i = 0; i < self->children->len; i++)
{
child = g_ptr_array_index (self->children, i);
if (gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation, -1);
}
}
static void
gtk_shader_stack_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
int width, height;
GtkWidget *current, *next;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
current = g_ptr_array_index (self->children, self->current);
if (self->next == -1)
{
gtk_widget_snapshot_child (widget, current, snapshot);
}
else
{
GtkNative *native = gtk_widget_get_native (widget);
GskRenderer *renderer = gtk_native_get_renderer (native);
float progress;
next = g_ptr_array_index (self->children, self->next);
progress = self->time / self->duration;
if (self->backwards)
{
GtkWidget *tmp = next;
next = current;
current = tmp;
progress = 1. - progress;
}
if (gsk_gl_shader_compile (self->shader, renderer, NULL))
{
gtk_snapshot_push_gl_shader (snapshot,
self->shader,
&GRAPHENE_RECT_INIT(0, 0, width, height),
gsk_gl_shader_format_args (self->shader,
"progress", progress,
NULL));
gtk_widget_snapshot_child (widget, current, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot); /* current child */
gtk_widget_snapshot_child (widget, next, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot); /* next child */
gtk_snapshot_pop (snapshot);
}
else
{
/* Non-shader fallback */
gtk_widget_snapshot_child (widget, current, snapshot);
}
}
}
static void
gtk_shader_stack_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
switch (prop_id)
{
case PROP_DURATION:
g_value_set_float (value, self->duration);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shader_stack_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
switch (prop_id)
{
case PROP_DURATION:
self->duration = g_value_get_float (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shader_stack_class_init (GtkShaderStackClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gtk_shader_stack_finalize;
object_class->dispose = gtk_shader_stack_dispose;
object_class->get_property = gtk_shader_stack_get_property;
object_class->set_property = gtk_shader_stack_set_property;
widget_class->snapshot = gtk_shader_stack_snapshot;
widget_class->measure = gtk_shader_stack_measure;
widget_class->size_allocate = gtk_shader_stack_size_allocate;
properties[PROP_DURATION] =
g_param_spec_float ("duration", "Duration", "Duration",
0.1, 3.0, 1.0,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
}
GtkWidget *
gtk_shader_stack_new (void)
{
return g_object_new (GTK_TYPE_SHADER_STACK, NULL);
}
void
gtk_shader_stack_set_shader (GtkShaderStack *self,
GskGLShader *shader)
{
g_set_object (&self->shader, shader);
}
void
gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child)
{
g_ptr_array_add (self->children, child);
gtk_widget_set_parent (child, GTK_WIDGET (self));
gtk_widget_queue_resize (GTK_WIDGET (self));
if (self->current == -1)
self->current = 0;
else
gtk_widget_set_child_visible (child, FALSE);
}
void
gtk_shader_stack_set_active (GtkShaderStack *self,
int index)
{
stop_transition (self);
self->current = MIN (index, self->children->len);
update_child_visible (self);
}
G_GNUC_END_IGNORE_DEPRECATIONS
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_STACK (gtk_shader_stack_get_type ())
G_DECLARE_FINAL_TYPE (GtkShaderStack, gtk_shader_stack, GTK, SHADER_STACK, GtkWidget)
GtkWidget * gtk_shader_stack_new (void);
void gtk_shader_stack_set_shader (GtkShaderStack *self,
GskGLShader *shader);
void gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child);
void gtk_shader_stack_transition (GtkShaderStack *self,
gboolean forward);
void gtk_shader_stack_set_active (GtkShaderStack *self,
int index);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS
+2
View File
@@ -1,5 +1,7 @@
#pragma once
#include <gdk/gdk.h>
typedef struct _GdkHSLA GdkHSLA;
struct _GdkHSLA {
+73 -29
View File
@@ -13,7 +13,7 @@ static GtkWidget *window = NULL;
static GtkWidget *scrolledwindow;
static int selected;
#define N_WIDGET_TYPES 8
#define N_WIDGET_TYPES 9
static int hincrement = 5;
@@ -73,30 +73,77 @@ populate_icons (void)
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), grid);
}
static char *content;
static gsize content_len;
extern void fontify (const char *format, GtkTextBuffer *buffer);
enum {
PLAIN_TEXT,
HIGHLIGHTED_TEXT,
UNDERLINED_TEXT,
};
static void
populate_text (gboolean highlight)
underlinify (GtkTextBuffer *buffer)
{
GtkTextTagTable *tags;
GtkTextTag *tag[3];
GtkTextIter start, end;
tags = gtk_text_buffer_get_tag_table (buffer);
tag[0] = gtk_text_tag_new ("error");
tag[1] = gtk_text_tag_new ("strikeout");
tag[2] = gtk_text_tag_new ("double");
g_object_set (tag[0], "underline", PANGO_UNDERLINE_ERROR, NULL);
g_object_set (tag[1], "strikethrough", TRUE, NULL);
g_object_set (tag[2],
"underline", PANGO_UNDERLINE_DOUBLE,
"underline-rgba", &(GdkRGBA){0., 1., 1., 1. },
NULL);
gtk_text_tag_table_add (tags, tag[0]);
gtk_text_tag_table_add (tags, tag[1]);
gtk_text_tag_table_add (tags, tag[2]);
gtk_text_buffer_get_start_iter (buffer, &end);
while (TRUE)
{
gtk_text_iter_forward_word_end (&end);
start = end;
gtk_text_iter_backward_word_start (&start);
gtk_text_buffer_apply_tag (buffer, tag[g_random_int_range (0, 3)], &start, &end);
if (!gtk_text_iter_forward_word_ends (&end, 3))
break;
}
}
static void
populate_text (const char *resource, int kind)
{
GtkWidget *textview;
GtkTextBuffer *buffer;
char *content;
gsize content_len;
GBytes *bytes;
if (!content)
{
GBytes *bytes;
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
}
bytes = g_resources_lookup_data (resource, 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_set_text (buffer, content, (int)content_len);
if (highlight)
fontify ("c", buffer);
switch (kind)
{
case HIGHLIGHTED_TEXT:
fontify ("c", buffer);
break;
case UNDERLINED_TEXT:
underlinify (buffer);
break;
case PLAIN_TEXT:
default:
break;
}
textview = gtk_text_view_new ();
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
@@ -155,14 +202,6 @@ populate_image (void)
{
GtkWidget *image;
if (!content)
{
GBytes *bytes;
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
}
image = gtk_picture_new_for_resource ("/sliding_puzzle/portland-rose.jpg");
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
@@ -255,35 +294,40 @@ set_widget_type (int type)
case 1:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling plain text");
populate_text (FALSE);
populate_text ("/sources/font_features.c", PLAIN_TEXT);
break;
case 2:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling complex text");
populate_text (TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Scrolling colored text");
populate_text ("/sources/font_features.c", HIGHLIGHTED_TEXT);
break;
case 3:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling text with underlines");
populate_text ("/org/gtk/Demo4/Moby-Dick.txt", UNDERLINED_TEXT);
break;
case 4:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling text with Emoji");
populate_emoji_text ();
break;
case 4:
case 5:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a big image");
populate_image ();
break;
case 5:
case 6:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a list");
populate_list ();
break;
case 6:
case 7:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a columned list");
populate_list2 ();
break;
case 7:
case 8:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a grid");
populate_grid ();
break;
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="resizable">0</property>
<property name="resizable">1</property>
<property name="default-width">500</property>
<property name="default-height">500</property>
<child type="titlebar">
+150 -14
View File
@@ -14,6 +14,103 @@
#include <gtk/gtk.h>
#include "demo3widget.h"
static GtkWidget *window = NULL;
static GCancellable *cancellable = NULL;
static void
load_texture (GTask *task,
gpointer source_object,
gpointer task_data,
GCancellable *cable)
{
GFile *file = task_data;
GdkTexture *texture;
GError *error = NULL;
texture = gdk_texture_new_from_file (file, &error);
if (texture)
g_task_return_pointer (task, texture, g_object_unref);
else
g_task_return_error (task, error);
}
static void
set_wait_cursor (GtkWidget *widget)
{
gtk_widget_set_cursor_from_name (GTK_WIDGET (gtk_widget_get_root (widget)), "wait");
}
static void
unset_wait_cursor (GtkWidget *widget)
{
gtk_widget_set_cursor (GTK_WIDGET (gtk_widget_get_root (widget)), NULL);
}
static void
texture_loaded (GObject *source,
GAsyncResult *result,
gpointer data)
{
GdkTexture *texture;
GError *error = NULL;
texture = g_task_propagate_pointer (G_TASK (result), &error);
if (!texture)
{
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
if (!window)
{
g_object_unref (texture);
return;
}
unset_wait_cursor (GTK_WIDGET (data));
g_object_set (G_OBJECT (data), "texture", texture, NULL);
}
static void
open_file_async (GFile *file,
GtkWidget *demo)
{
GTask *task;
set_wait_cursor (demo);
task = g_task_new (demo, cancellable, texture_loaded, demo);
g_task_set_task_data (task, g_object_ref (file), g_object_unref);
g_task_run_in_thread (task, load_texture);
g_object_unref (task);
}
static void
open_portland_rose (GtkWidget *button,
GtkWidget *demo)
{
GFile *file;
file = g_file_new_for_uri ("resource:///transparent/portland-rose.jpg");
open_file_async (file, demo);
g_object_unref (file);
}
static void
open_large_image (GtkWidget *button,
GtkWidget *demo)
{
GFile *file;
file = g_file_new_for_uri ("resource:///org/gtk/Demo4/large-image.png");
open_file_async (file, demo);
g_object_unref (file);
}
static void
file_opened (GObject *source,
GAsyncResult *result,
@@ -21,7 +118,6 @@ file_opened (GObject *source,
{
GFile *file;
GError *error = NULL;
GdkTexture *texture;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
@@ -32,17 +128,9 @@ file_opened (GObject *source,
return;
}
texture = gdk_texture_new_from_file (file, &error);
g_object_unref (file);
if (!texture)
{
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
open_file_async (file, data);
g_object_set (G_OBJECT (data), "texture", texture, NULL);
g_object_unref (texture);
g_object_unref (file);
}
static void
@@ -116,11 +204,26 @@ transform_from (GBinding *binding,
return TRUE;
}
static void
free_cancellable (gpointer data)
{
g_cancellable_cancel (cancellable);
g_clear_object (&cancellable);
}
static gboolean
cancel_load (GtkWidget *widget,
GVariant *args,
gpointer data)
{
unset_wait_cursor (widget);
g_cancellable_cancel (G_CANCELLABLE (data));
return TRUE;
}
GtkWidget *
do_image_scaling (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *box;
@@ -130,6 +233,7 @@ do_image_scaling (GtkWidget *do_widget)
GtkWidget *scale;
GtkWidget *dropdown;
GtkWidget *button;
GtkEventController *controller;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
@@ -138,6 +242,20 @@ do_image_scaling (GtkWidget *do_widget)
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
cancellable = g_cancellable_new ();
g_object_set_data_full (G_OBJECT (window), "cancellable",
cancellable, free_cancellable);
controller = gtk_shortcut_controller_new ();
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (
gtk_keyval_trigger_new (GDK_KEY_Escape, 0),
gtk_callback_action_new (cancel_load, cancellable, NULL)
));
gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
GTK_SHORTCUT_SCOPE_GLOBAL);
gtk_widget_add_controller (window, controller);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
@@ -156,6 +274,22 @@ do_image_scaling (GtkWidget *do_widget)
g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (button),
gtk_image_new_from_resource ("/org/gtk/Demo4/portland-rose-thumbnail.png"));
gtk_widget_add_css_class (button, "image-button");
gtk_widget_set_tooltip_text (button, "Portland Rose");
g_signal_connect (button, "clicked", G_CALLBACK (open_portland_rose), widget);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (button),
gtk_image_new_from_resource ("/org/gtk/Demo4/large-image-thumbnail.png"));
gtk_widget_add_css_class (button, "image-button");
gtk_widget_set_tooltip_text (button, "Large image");
g_signal_connect (button, "clicked", G_CALLBACK (open_large_image), widget);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic");
gtk_widget_set_tooltip_text (button, "Rotate");
g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
@@ -191,7 +325,9 @@ do_image_scaling (GtkWidget *do_widget)
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));
{
gtk_window_destroy (GTK_WINDOW (window));
}
return window;
}
-41
View File
@@ -1,41 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/kaleidoscope
// Author: nwoeanhinnogaehr
// License: MIT
const float speed = 1.0;
const float angle = 1.0;
const float power = 1.5;
vec4 transition(vec2 uv) {
vec2 p = uv.xy / vec2(1.0).xy;
vec2 q = p;
float t = pow(progress, power)*speed;
p = p -0.5;
for (int i = 0; i < 7; i++) {
p = vec2(sin(t)*p.x + cos(t)*p.y, sin(t)*p.y - cos(t)*p.x);
t += angle;
p = abs(mod(p, 2.0) - 1.0);
}
abs(mod(p, 1.0));
return mix(
mix(getFromColor(q), getToColor(q), progress),
mix(getFromColor(p), getToColor(p), progress), 1.0 - 2.0*abs(progress - 0.5));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 KiB

+8 -8
View File
@@ -355,28 +355,28 @@ create_clocks_model (void)
g_list_store_append (result, clock);
g_object_unref (clock);
/* A bunch of timezones with GTK hackers */
clock = gtk_clock_new ("San Francisco", g_time_zone_new ("America/Los_Angeles"));
clock = gtk_clock_new ("San Francisco", g_time_zone_new_identifier ("America/Los_Angeles"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Xalapa", g_time_zone_new ("America/Mexico_City"));
clock = gtk_clock_new ("Xalapa", g_time_zone_new_identifier ("America/Mexico_City"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Boston", g_time_zone_new ("America/New_York"));
clock = gtk_clock_new ("Boston", g_time_zone_new_identifier ("America/New_York"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("London", g_time_zone_new ("Europe/London"));
clock = gtk_clock_new ("London", g_time_zone_new_identifier ("Europe/London"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Berlin", g_time_zone_new ("Europe/Berlin"));
clock = gtk_clock_new ("Berlin", g_time_zone_new_identifier ("Europe/Berlin"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Moscow", g_time_zone_new ("Europe/Moscow"));
clock = gtk_clock_new ("Moscow", g_time_zone_new_identifier ("Europe/Moscow"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("New Delhi", g_time_zone_new ("Asia/Kolkata"));
clock = gtk_clock_new ("New Delhi", g_time_zone_new_identifier ("Asia/Kolkata"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Shanghai", g_time_zone_new ("Asia/Shanghai"));
clock = gtk_clock_new ("Shanghai", g_time_zone_new_identifier ("Asia/Shanghai"));
g_list_store_append (result, clock);
g_object_unref (clock);
+2 -8
View File
@@ -156,11 +156,6 @@ gtk_demo_run (GtkDemo *self,
if (result == NULL)
return FALSE;
if (GTK_IS_WINDOW (result))
{
gtk_window_set_transient_for (GTK_WINDOW (result), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (result), TRUE);
}
return TRUE;
}
@@ -832,9 +827,6 @@ static gboolean
demo_can_run (GtkWidget *window,
const char *name)
{
if (name != NULL && strcmp (name, "gltransition") == 0)
return GSK_IS_GL_RENDERER (gtk_native_get_renderer (GTK_NATIVE (window)));
return TRUE;
}
@@ -1068,6 +1060,8 @@ command_line (GApplication *app,
window = gtk_application_get_windows (GTK_APPLICATION (app))->data;
gtk_window_set_icon_name (GTK_WINDOW (window), "org.gtk.Demo4");
if (name == NULL)
goto out;
-4
View File
@@ -33,7 +33,6 @@ demos = files([
'gears.c',
'gestures.c',
'glarea.c',
'gltransition.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
@@ -117,10 +116,7 @@ extra_demo_sources = files([
'gtkfishbowl.c',
'fontplane.c',
'gtkgears.c',
'gtkshaderbin.c',
'gtkshadertoy.c',
'gtkshaderstack.c',
'gskshaderpaintable.c',
'hsla.c',
'puzzlepiece.c',
'bluroverlay.c',
+1 -1
View File
@@ -5,4 +5,4 @@
#define NODE_TYPE_WIDGET (node_widget_get_type ())
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
GtkWidget * node_widget_new (const char *file);
GtkWidget * node_widget_new (const char *resource);
+2 -1
View File
@@ -225,7 +225,8 @@ print_ready (GObject *source,
if (!g_output_stream_close (stream, NULL, &error))
{
g_print ("Error from close: %s\n", error->message);
if (!g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_DISMISSED))
g_print ("Error from close: %s\n", error->message);
g_error_free (error);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

-34
View File
@@ -1,34 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/Radial
// License: MIT
// Author: Xaychru
const float smoothness = 1.0;
const float PI = 3.141592653589;
vec4 transition(vec2 p) {
vec2 rp = p*2.-1.;
return mix(
getToColor(p),
getFromColor(p),
smoothstep(0., smoothness, atan(rp.y,rp.x) - (progress-.5) * PI * 2.5)
);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
-43
View File
@@ -1,43 +0,0 @@
uniform float u_time;
uniform vec2 u_mouse;
uniform sampler2D u_texture1;
#define PI 3.141592654
float decay(float v, float t)
{
return v * (1.0 / (1.0 + t*t));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
// Temporary to loop time every 1 sec
float time = u_time;
// we normalize all the effects according to the min height/width
float size = min(resolution.x, resolution.y);
// Animate one wave over size in 0.3 sec
float wave_speed = size / 0.3;
float wave_length = size / 1.0;
float wave_height = size * 0.1;
vec2 center = u_mouse;
vec2 direction_from_center = fragCoord - center;
float distance_from_center = length(direction_from_center);
/* Normalize direction */
direction_from_center = direction_from_center / distance_from_center;
float propagation_length = time * wave_speed;
float t = (propagation_length - distance_from_center) / wave_length;
float offset_magnitude = 0.0;
if (t > 0.0)
offset_magnitude = decay(wave_height * sin(t * 2.0 * PI), t);
vec2 offset = direction_from_center * min(offset_magnitude, distance_from_center);
vec2 source = fragCoord - offset;
vec2 uv2 = source / resolution;
fragColor = GskTexture(u_texture1, vec2(uv2.x, 1.0-uv2.y));
}
+1 -1
View File
@@ -43,7 +43,7 @@ GtkListItemFactory *
suggestion_entry_get_factory (SuggestionEntry *self);
void suggestion_entry_set_use_filter (SuggestionEntry *self,
gboolean use_ilter);
gboolean use_filter);
gboolean suggestion_entry_get_use_filter (SuggestionEntry *self);
void suggestion_entry_set_expression (SuggestionEntry *self,
-33
View File
@@ -1,33 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/wind
// Author: gre
// License: MIT
const float size = 0.2;
float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
vec4 transition(vec2 p) {
float r = rand(vec2(0, p.y));
float m = smoothstep(0.0, -size, p.x*(1.0-size) + size*r - (progress * (1.0 + size)));
return mix(getFromColor(p), getToColor(p), m);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.2 KiB

@@ -1,136 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="org.gtk.IconBrowser4-symbolic.svg"
height="16.03125"
id="svg7384"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
version="1.1"
width="16">
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
inkscape:bbox-paths="true"
bordercolor="#666666"
borderopacity="1"
inkscape:current-layer="layer9"
inkscape:cx="-2.5662459"
inkscape:cy="11.558672"
gridtolerance="10"
inkscape:guide-bbox="true"
guidetolerance="10"
id="namedview88"
inkscape:object-nodes="false"
inkscape:object-paths="false"
objecttolerance="10"
pagecolor="#555753"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
showborder="true"
showgrid="false"
showguides="true"
inkscape:snap-bbox="true"
inkscape:snap-bbox-midpoints="false"
inkscape:snap-global="true"
inkscape:snap-grids="true"
inkscape:snap-nodes="true"
inkscape:snap-others="false"
inkscape:snap-to-guides="true"
inkscape:window-height="1375"
inkscape:window-maximized="1"
inkscape:window-width="2560"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:zoom="1">
<inkscape:grid
empspacing="2"
enabled="true"
id="grid4866"
originx="-203"
originy="-251.96875"
snapvisiblegridlinesonly="true"
spacingx="1"
spacingy="1"
type="xygrid"
visible="true" />
</sodipodi:namedview>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
id="linearGradient7212"
osb:paint="solid">
<stop
id="stop7214"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
</linearGradient>
</defs>
<g
inkscape:groupmode="layer"
id="layer9"
inkscape:label="apps"
style="display:inline"
transform="translate(-444.0002,35)">
<path
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
d="m 457.9846,-27.96875 v -3 h 1 l -3,-3 -3,3 h 1 v 3 z"
id="path2809"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
d="m 451.9846,-23.96875 v 2 h 1 l 2,2 v -6 l -2,2 z"
id="path2811"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
d="m 455.9846,-24.96875 v 4 c 0,0 1,-1 1,-2 0,-1.31515 -1,-2 -1,-2 z"
id="path2813"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsc" />
<path
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
d="m 457.9846,-25.96875 v 6 c 0,0 1,-1.94591 1,-3 0,-1.05409 -1,-3 -1,-3 z"
id="path2815"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsc" />
<path
inkscape:connector-curvature="0"
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;enable-background:new"
d="m 450.53751,-25.96846 c 0.24647,0 0.44708,0.19694 0.44708,0.44708 v 0.0289 c -0.008,3.05189 -2.48438,5.5237 -5.53812,5.5237 h -0.0148 c -0.25145,0 -0.44711,-0.20581 -0.44711,-0.4615 v -0.46152 -0.92302 c 0,-0.25567 0.20581,-0.4615 0.4615,-0.4615 h 0.92302 c 0.25569,0 0.46152,0.20581 0.46152,0.4615 v 0.21634 c 1.18002,-0.41715 2.10674,-1.34386 2.52389,-2.52388 h -0.21635 c -0.25566,0 -0.4615,-0.20581 -0.4615,-0.46152 v -0.92302 c 0,-0.25567 0.20581,-0.4615 0.4615,-0.4615 h 0.46152 0.4615 0.44709 0.0148 0.0148 z"
id="rect5922-7-3" />
<g
id="g904-6"
transform="matrix(0.26785369,0,0,0.26785369,436.44908,-87.00581)"
style="display:inline;fill:#000000;fill-opacity:1;stroke-width:3.73338151;enable-background:new">
<path
sodipodi:nodetypes="csscccssssccccccsccsssssccccccsssss"
inkscape:connector-curvature="0"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.46676302;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 37,198.00759 c -2.76142,0 -5,2.23858 -5,5 0,2.76142 2.23858,5 5,5 0.89216,0 1.71236,-0.27804 2.4375,-0.6875 l 3.9375,3.6875 -3.9375,3.6875 c -0.72514,-0.40946 -1.54534,-0.6875 -2.4375,-0.6875 -2.76142,0 -5,2.23858 -5,5 0,2.76142 2.23858,5 5,5 2.76142,0 5,-2.23858 5,-5 0,-0.45832 -0.072,-0.89082 -0.1874,-1.3125 l 4.25,-4.125 8.9374,8.4375 h 3 v -2 l -16.1875,-15.6875 c 0.1156,-0.42168 0.1874,-0.85418 0.1874,-1.3125 0,-2.76142 -2.23858,-5 -5,-5 z m 0,3 c 1.10456,0 2,0.89544 2,2 0,1.10456 -0.89544,2 -2,2 -1.10456,0 -2,-0.89544 -2,-2 0,-1.10456 0.89544,-2 2,-2 z m 18,-1 -7.875,7.4375 2.625,2.5625 8.25,-8 v -2 z m -18,17 c 1.10456,0 2,0.89544 2,2 0,1.10456 -0.89544,2 -2,2 -1.10456,0 -2,-0.89544 -2,-2 0,-1.10456 0.89544,-2 2,-2 z"
id="path1079-7" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.1 KiB

+2
View File
@@ -139,6 +139,8 @@ icon_browser_app_activate (GApplication *app)
if (g_strcmp0 (PROFILE, "devel") == 0)
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
gtk_window_set_icon_name (GTK_WINDOW (win), "org.gtk.IconBrowser4");
gtk_window_present (GTK_WINDOW (win));
}
-2
View File
@@ -3,9 +3,7 @@
appdata_config = configuration_data()
appdata_config.set('BUILD_VERSION', meson.project_version())
subdir('constraint-editor')
subdir('gtk-demo')
subdir('icon-browser')
subdir('node-editor')
subdir('widget-factory')
subdir('print-editor')
@@ -219,6 +219,8 @@ node_editor_application_activate (GApplication *app)
if (g_strcmp0 (PROFILE, "devel") == 0)
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
gtk_window_set_icon_name (GTK_WINDOW (win), "org.gtk.gtk4.NodeEditor");
gtk_window_present (GTK_WINDOW (win));
}
+1 -1
View File
@@ -925,7 +925,7 @@ export_image_response_cb (GObject *source,
GdkTexture *texture;
GskRenderer *renderer;
renderer = gsk_gl_renderer_new ();
renderer = gsk_ngl_renderer_new ();
if (!gsk_renderer_realize_for_display (renderer, gdk_display_get_default (), NULL))
{
g_object_unref (renderer);
+1 -1
View File
@@ -798,7 +798,7 @@ activate (GApplication *app)
if (g_strcmp0 (PROFILE, "devel") == 0)
gtk_widget_add_css_class (GTK_WIDGET (main_window), "devel");
gtk_window_set_icon_name (GTK_WINDOW (main_window), "text-editor");
gtk_window_set_icon_name (GTK_WINDOW (main_window), "org.gtk.PrintEditor4");
gtk_window_set_default_size (GTK_WINDOW (main_window), 400, 600);
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (main_window), TRUE);
update_title (GTK_WINDOW (main_window));
+1
View File
@@ -2241,6 +2241,7 @@ activate (GApplication *app)
if (g_strcmp0 (PROFILE, "devel") == 0)
gtk_widget_add_css_class (GTK_WIDGET (window), "devel");
gtk_window_set_icon_name (window, "org.gtk.WidgetFactory4");
gtk_application_add_window (GTK_APPLICATION (app), window);
g_action_map_add_action_entries (G_ACTION_MAP (window),
win_entries, G_N_ELEMENTS (win_entries),
+9 -7
View File
@@ -151,10 +151,11 @@ Checks whether the widget is set to be visible or not.
- Methods are special functions whose first argument is always the instance
of a certain class. The instance argument for newly written code should be
called `self`.
- If a method is a setter or a getter for an object property, you should
add an `(attributes org.gtk.Method.set_property=property-name)` or a
an `(attributes org.gtk.Method.get_property=property-name)` annotation
to the method's identifier
- If a method is a setter or a getter for an object property
`GtkClassName:prop-name`, and if its name does not match the naming scheme
`gtk_class_name_{g,s}et_prop_name`, you should add a `(set-property
prop-name)` or a `(get-property prop-name)` annotation to the method's
identifier
- If a method changes one or more properties as side effect, link those
properties in the method's description
- If a method is a signal emitter, you should use the
@@ -192,9 +193,10 @@ Checks whether the widget is set to be visible or not.
purposes.
- Always note if setting a property has side effects, like causing another
property to change state.
- If the property has public accessors you should annotate it with
the `(attributes org.gtk.Property.set=setter_function)` and
`(attributes org.gtk.Property.get=getter_function)` attributes
- If a property `GtkClassName:prop-name` has a public getter or setter, and
they do not match the naming scheme `gtk_class_name_{g,s}et_prop_name` you
should annotate it with the `(setter setter_function)` and `(getter
getter_function)`.
- The syntax for property documentation is:
```c
+7 -3
View File
@@ -1,12 +1,16 @@
Title: The Broadway windowing system
Slug: broadway
## Using GTK with Broadway
The GDK Broadway backend provides support for displaying GTK applications in
a web browser, using HTML5 and web sockets.
To run your application in this way, first run the broadway server,
Broadway was written as an experiment and is not the most actively developed
backend. It supports the features that were required of GDK backends in GTK 4.0,
but may not be up-to-date with the latest developments.
## Using GTK with Broadway
To run your application under Broadway, first run the broadway server,
`gtk-broadwayd`, that ships with GTK:
```
+2 -2
View File
@@ -66,8 +66,8 @@ The clock has several phases:
- Layout
- Paint
The phases happens in this order and we will always run each
phase through before going back to the start.
The phases happen in this order and all phases will always run
through before going back to the start.
The Events phase is a stretch of time between each redraw where
GTK processes input events from the user and other events
-4
View File
@@ -66,10 +66,6 @@ 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.
-32
View File
@@ -1,32 +0,0 @@
.. _gtk4-icon-browser(1):
=================
gtk4-icon-browser
=================
-----------------
List themed icons
-----------------
:Version: GTK
:Manual section: 1
:Manual group: GTK commands
SYNOPSIS
--------
| **gtk4-icon-browser** [OPTIONS...]
DESCRIPTION
-----------
``gtk4-icon-browser`` is a utility to explore the icons in the current icon
theme. It shows icons in various sizes, their symbolic variants where available,
as well as a description of the icon and its context.
OPTIONS
-------
``-h, --help``
Show the application help.
-1
View File
@@ -98,7 +98,6 @@ if get_option('build-demos')
[ 'gtk4-demo', '1', ],
[ 'gtk4-demo-application', '1', ],
[ 'gtk4-widget-factory', '1', ],
[ 'gtk4-icon-browser', '1', ],
[ 'gtk4-node-editor', '1', ],
]
endif
+6 -23
View File
@@ -380,13 +380,6 @@ does not support them.
`base-instance`
:GL_EXT_base_instance
### `GDK_VULKAN_DEVICE`
This variable can be set to the index of a Vulkan device to override
the default selection of the device that is used for Vulkan rendering.
The special value `list` can be used to obtain a list of all Vulkan
devices.
### `GDK_VULKAN_DISABLE`
This variable can be set to a list of values, which cause GDK to
@@ -400,15 +393,6 @@ does not support them.
`ycbr`
: Do not support Ycbcr textures
`descriptor-indexing`
: Force slow descriptor set layout codepath
`dynamic-indexing`
: Hardcode small number of buffer and texture arrays
`nonuniform-indexing`
: Split draw calls to ensure uniform texture accesses
`semaphore-export`
: Disable sync of exported dmabufs
@@ -418,6 +402,9 @@ does not support them.
`incremental-present`
: Do not send damage regions
`swapchain-maintenance`
: Do not use advanced swapchain features
The special value `all` can be used to turn on all values. The special
value `help` can be used to obtain a list of all supported values.
@@ -436,14 +423,8 @@ using and the GDK backend supports them:
`cairo`
: Selects the fallback Cairo renderer
`opengl`
: Selects the default OpenGL renderer
`gl`
: Selects the "gl" OpenGL renderer
`ngl`
: Selects the "ngl" OpenGL renderer
: Selects the OpenGL renderer
`vulkan`
: Selects the Vulkan renderer
@@ -493,6 +474,8 @@ disable certain optimizations of the "ngl" and "vulkan" renderer.
`occlusion`
: Disable occlusion culling via opacity tracking
`repeat`
: Repeat drawing operations instead of using offscreen and GL_REPEAT
The special value `all` can be used to turn on all values. The special
value `help` can be used to obtain a list of all supported values.
+1 -1
View File
@@ -171,7 +171,7 @@ Each relation name is part of the `GtkAccessibleRelation` enumeration.
| %GTK_ACCESSIBLE_RELATION_CONTROLS | “aria-controls” | a list of `GtkAccessible` |
| %GTK_ACCESSIBLE_RELATION_DESCRIBED_BY | “aria-describedby” | a list of `GtkAccessible` |
| %GTK_ACCESSIBLE_RELATION_DETAILS | “aria-details” | a list of `GtkAccessible` |
| %GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE | “aria-errormessage” | `GtkAccessible` |
| %GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE | “aria-errormessage” | a list of `GtkAccessible` |
| %GTK_ACCESSIBLE_RELATION_FLOW_TO | “aria-flowto” | a list of `GtkAccessible` |
| %GTK_ACCESSIBLE_RELATION_LABELLED_BY | “aria-labelledby” | a list of `GtkAccessible` |
| %GTK_ACCESSIBLE_RELATION_OWNS | “aria-owns” | a list of `GtkAccessible` |
+1 -1
View File
@@ -49,7 +49,7 @@ main (int argc,
g_chdir (GTK_SRCDIR);
#endif
GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
int status = g_application_run (G_APPLICATION (app), argc, argv);
+1 -1
View File
@@ -173,7 +173,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);
+1 -1
View File
@@ -60,7 +60,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);
+2 -4
View File
@@ -37,10 +37,8 @@ main (int argc,
{
GtkApplication *app;
app = gtk_application_new ("org.gtk.Example.GtkSearchBar",
G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate",
G_CALLBACK (activate_cb), NULL);
app = gtk_application_new ("org.gtk.Example.GtkSearchBar", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate_cb), NULL);
return g_application_run (G_APPLICATION (app), argc, argv);
}
+1 -1
View File
@@ -19,7 +19,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);
+1 -1
View File
@@ -111,7 +111,7 @@ gboolean broadway_server_surface_translate (BroadwayServer *
int dx,
int dy);
guint32 broadway_server_upload_texture (BroadwayServer *server,
GBytes *texture);
GBytes *bytes);
void broadway_server_release_texture (BroadwayServer *server,
guint32 id);
cairo_surface_t * broadway_server_create_surface (int width,
+1 -1
View File
@@ -56,7 +56,7 @@ void _gdk_broadway_surface_translate (GdkSurface *surface,
int dx,
int dy);
gboolean _gdk_broadway_moveresize_handle_event (GdkDisplay *display,
BroadwayInputMsg *msg);
BroadwayInputMsg *event);
gboolean _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
GdkSurface *surface);
void _gdk_broadway_roundtrip_notify (GdkSurface *surface,
+178 -52
View File
@@ -49,6 +49,135 @@
G_DEFINE_TYPE (GdkBroadwaySurface, gdk_broadway_surface, GDK_TYPE_SURFACE)
static void
gdk_broadway_surface_toplevel_resize (GdkSurface *surface,
int width,
int height);
static void
gdk_broadway_surface_set_geometry_hints (GdkSurface *surface,
const GdkGeometry *geometry,
GdkSurfaceHints geom_mask);
static void
gdk_broadway_surface_move_resize_internal (GdkSurface *surface,
gboolean with_move,
int x,
int y,
int width,
int height);
static void
compute_toplevel_size (GdkSurface *surface,
gboolean resizible,
int *width,
int *height)
{
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
int bounds_width, bounds_height;
GdkGeometry geometry;
GdkSurfaceHints mask;
monitor = gdk_display_get_monitor_at_surface (display, surface);
if (monitor)
{
GdkRectangle monitor_geometry;
gdk_monitor_get_geometry (monitor, &monitor_geometry);
bounds_width = monitor_geometry.width;
bounds_height = monitor_geometry.height;
}
else
{
bounds_width = G_MAXINT;
bounds_height = G_MAXINT;
}
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
g_warn_if_fail (size.width > 0);
g_warn_if_fail (size.height > 0);
*width = size.width;
*height = size.height;
impl->resizible = (impl->resizible && resizible);
if (impl->resizible)
{
geometry.min_width = size.min_width;
geometry.min_height = size.min_height;
mask = GDK_HINT_MIN_SIZE;
}
else
{
geometry.max_width = geometry.min_width = size.width;
geometry.max_height = geometry.min_height = size.height;
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
}
gdk_broadway_surface_set_geometry_hints (surface, &geometry, mask);
if (!(surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_TILED |
GDK_TOPLEVEL_STATE_TOP_TILED |
GDK_TOPLEVEL_STATE_RIGHT_TILED |
GDK_TOPLEVEL_STATE_BOTTOM_TILED |
GDK_TOPLEVEL_STATE_LEFT_TILED |
GDK_TOPLEVEL_STATE_MINIMIZED)))
{
gdk_surface_constrain_size (&geometry, mask,
size.width, size.height,
&size.width, &size.height);
if (impl->last_computed_width != size.width ||
impl->last_computed_height != size.height)
{
*width = size.width;
*height = size.height;
impl->last_computed_width = size.width;
impl->last_computed_height = size.height;
gdk_broadway_surface_toplevel_resize (surface, *width, *height);
}
}
if (size.shadow.is_valid)
{
impl->shadow_left = size.shadow.left;
impl->shadow_right = size.shadow.right;
impl->shadow_top = size.shadow.top;
impl->shadow_bottom = size.shadow.bottom;
}
}
static gboolean
compute_size_idle (gpointer user_data)
{
GdkSurface *surface = user_data;
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
int width, height;
impl->compute_size_source_id = 0;
compute_toplevel_size (surface, TRUE, &width, &height);
return G_SOURCE_REMOVE;
}
static void
on_frame_clock_after_update (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
if (impl->compute_size_source_id)
{
g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
compute_size_idle (surface);
}
}
/* We need to flush in an idle rather than AFTER_PAINT, as the clock
is frozen during e.g. surface resizes so the paint will not happen
and the surface resize request is never flushed. */
@@ -112,6 +241,8 @@ connect_frame_clock (GdkSurface *surface)
g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect_after (frame_clock, "update",
G_CALLBACK (on_frame_clock_after_update), surface);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), surface);
}
@@ -123,6 +254,8 @@ disconnect_frame_clock (GdkSurface *surface)
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_update, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_paint, surface);
}
@@ -137,6 +270,7 @@ gdk_broadway_surface_constructed (GObject *object)
if (!surface->parent)
broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, self);
self->resizible = TRUE;
self->id = _gdk_broadway_server_new_surface (broadway_display->server,
self->root_x,
self->root_y,
@@ -316,6 +450,7 @@ gdk_broadway_surface_hide (GdkSurface *surface)
_gdk_broadway_surface_grab_check_unmap (surface,
_gdk_broadway_server_get_next_serial (broadway_display->server));
g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
if (_gdk_broadway_server_surface_hide (broadway_display->server, impl->id))
queue_flush (surface);
@@ -1009,6 +1144,8 @@ _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
BroadwayInputMsg *tmp_event;
MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
gdk_surface_request_layout (surface);
if (!mv_resize || surface != mv_resize->moveresize_surface)
return FALSE;
@@ -1168,6 +1305,43 @@ gdk_broadway_surface_beep (GdkSurface *surface)
return FALSE;
}
static void
gdk_broadway_surface_request_layout (GdkSurface *surface)
{
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
if (!impl->compute_size_source_id &&
GDK_IS_TOPLEVEL (surface))
{
impl->compute_size_source_id = g_idle_add_full (G_PRIORITY_HIGH - 10,
compute_size_idle,
surface,
NULL);
}
}
static gboolean
gdk_broadway_surface_compute_size (GdkSurface *surface)
{
int width, height;
if (GDK_IS_TOPLEVEL (surface))
{
compute_toplevel_size (surface, TRUE, &width, &height);
}
else
{
width = gdk_surface_get_width(surface);
height = gdk_surface_get_height(surface);
gdk_broadway_surface_move_resize_internal (surface, FALSE,
0, 0,
width,
height);
}
return FALSE;
}
static void
gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
{
@@ -1187,6 +1361,8 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
impl_class->destroy_notify = gdk_broadway_surface_destroy_notify;
impl_class->drag_begin = _gdk_broadway_surface_drag_begin;
impl_class->get_scale = gdk_broadway_surface_get_scale;
impl_class->request_layout = gdk_broadway_surface_request_layout;
impl_class->compute_size = gdk_broadway_surface_compute_size;
}
#define LAST_PROP 1
@@ -1504,55 +1680,12 @@ gdk_broadway_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
int bounds_width, bounds_height;
int width, height;
GdkGeometry geometry;
GdkSurfaceHints mask;
gboolean maximize;
gdk_broadway_surface_unminimize (surface);
monitor = gdk_display_get_monitor_at_surface (display, surface);
if (monitor)
{
GdkRectangle monitor_geometry;
gdk_monitor_get_geometry (monitor, &monitor_geometry);
bounds_width = monitor_geometry.width;
bounds_height = monitor_geometry.height;
}
else
{
bounds_width = G_MAXINT;
bounds_height = G_MAXINT;
}
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (toplevel, &size);
g_warn_if_fail (size.width > 0);
g_warn_if_fail (size.height > 0);
width = size.width;
height = size.height;
if (gdk_toplevel_layout_get_resizable (layout))
{
geometry.min_width = size.min_width;
geometry.min_height = size.min_height;
mask = GDK_HINT_MIN_SIZE;
}
else
{
geometry.max_width = geometry.min_width = width;
geometry.max_height = geometry.min_height = height;
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
}
gdk_broadway_surface_set_geometry_hints (surface, &geometry, mask);
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
gdk_broadway_surface_toplevel_resize (surface, width, height);
compute_toplevel_size (surface, gdk_toplevel_layout_get_resizable (layout), &width, &height);
if (gdk_toplevel_layout_get_maximized (layout, &maximize))
{
@@ -1562,14 +1695,7 @@ gdk_broadway_toplevel_present (GdkToplevel *toplevel,
gdk_broadway_surface_unmaximize (surface);
}
if (size.shadow.is_valid)
{
impl->shadow_left = size.shadow.left;
impl->shadow_right = size.shadow.right;
impl->shadow_top = size.shadow.top;
impl->shadow_bottom = size.shadow.bottom;
}
gdk_surface_request_layout (surface);
show_surface (surface);
}
+7
View File
@@ -76,6 +76,13 @@ struct _GdkBroadwaySurface
int shadow_right;
int shadow_top;
int shadow_bottom;
int last_computed_width;
int last_computed_height;
guint compute_size_source_id;
gboolean resizible;
};
struct _GdkBroadwaySurfaceClass
+1
View File
@@ -17,6 +17,7 @@
#pragma once
#include <gio/gio.h>
void file_transfer_portal_register (void);
+2 -2
View File
@@ -120,7 +120,7 @@ gdk_app_launch_context_class_init (GdkAppLaunchContextClass *klass)
context_class->launch_failed = gdk_app_launch_context_launch_failed;
/**
* GdkAppLaunchContext:display: (attributes org.gtk.Property.get=gdk_app_launch_context_get_display)
* GdkAppLaunchContext:display:
*
* The display that the `GdkAppLaunchContext` is on.
*/
@@ -169,7 +169,7 @@ gdk_app_launch_context_get_display_name (GAppLaunchContext *context,
}
/**
* gdk_app_launch_context_get_display: (attributes org.gtk.Method.get_property=display)
* gdk_app_launch_context_get_display:
* @context: a `GdkAppLaunchContext`
*
* Gets the `GdkDisplay` that @context is for.
+1 -1
View File
@@ -79,6 +79,6 @@ gdk_cicp_equivalent (const GdkCicp *p1,
return gdk_cicp_equal (&n1, &n2);
}
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *params);
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *self);
GdkCicpParams * gdk_cicp_params_new_for_cicp (const GdkCicp *cicp);
+8 -8
View File
@@ -353,7 +353,7 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
class->read_finish = gdk_clipboard_read_local_finish;
/**
* GdkClipboard:display: (attributes org.gtk.Property.get=gdk_clipboard_get_display)
* GdkClipboard:display:
*
* The `GdkDisplay` that the clipboard belongs to.
*/
@@ -366,7 +366,7 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
G_PARAM_EXPLICIT_NOTIFY);
/**
* GdkClipboard:formats: (attributes org.gtk.Property.get=gdk_clipboard_get_formats)
* GdkClipboard:formats:
*
* The possible formats that the clipboard can provide its data in.
*/
@@ -378,7 +378,7 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
G_PARAM_EXPLICIT_NOTIFY);
/**
* GdkClipboard:local: (attributes org.gtk.Property.get=gdk_clipboard_is_local)
* GdkClipboard:local: (getter is_local)
*
* %TRUE if the contents of the clipboard are owned by this process.
*/
@@ -390,7 +390,7 @@ gdk_clipboard_class_init (GdkClipboardClass *class)
G_PARAM_EXPLICIT_NOTIFY);
/**
* GdkClipboard:content: (attributes org.gtk.Property.get=gdk_clipboard_get_content)
* GdkClipboard:content:
*
* The `GdkContentProvider` or %NULL if the clipboard is empty or contents are
* provided otherwise.
@@ -429,7 +429,7 @@ gdk_clipboard_init (GdkClipboard *clipboard)
}
/**
* gdk_clipboard_get_display: (attributes org.gtk.Method.get_property=display)
* gdk_clipboard_get_display:
* @clipboard: a `GdkClipboard`
*
* Gets the `GdkDisplay` that the clipboard was created for.
@@ -447,7 +447,7 @@ gdk_clipboard_get_display (GdkClipboard *clipboard)
}
/**
* gdk_clipboard_get_formats: (attributes org.gtk.Method.get_property=formats)
* gdk_clipboard_get_formats:
* @clipboard: a `GdkClipboard`
*
* Gets the formats that the clipboard can provide its current contents in.
@@ -465,7 +465,7 @@ gdk_clipboard_get_formats (GdkClipboard *clipboard)
}
/**
* gdk_clipboard_is_local: (attributes org.gtk.Method.get_property=local)
* gdk_clipboard_is_local: (get-property local)
* @clipboard: a `GdkClipboard`
*
* Returns if the clipboard is local.
@@ -489,7 +489,7 @@ gdk_clipboard_is_local (GdkClipboard *clipboard)
}
/**
* gdk_clipboard_get_content: (attributes org.gtk.Method.get_property=content)
* gdk_clipboard_get_content:
* @clipboard: a `GdkClipboard`
*
* Returns the `GdkContentProvider` currently set on @clipboard.
-14
View File
@@ -229,20 +229,6 @@ gdk_color_from_rgba (GdkColor *self,
gdk_color_finish (&tmp);
}
/*< private >
* gdk_color_get_depth:
* @self: a `GdkColor`
*
* Returns the preferred depth for the color state of @self.
*
* Returns: the preferred depth
*/
GdkMemoryDepth
(gdk_color_get_depth) (const GdkColor *self)
{
return gdk_color_state_get_depth (self->color_state);
}
/*< private >
* gdk_color_print:
* @self: the `GdkColor` to print
+3
View File
@@ -20,6 +20,9 @@
* and tests, and must not include other headers.
*/
#include <glib.h>
#include <math.h>
static inline int
sign (float v)
{
+2 -7
View File
@@ -18,6 +18,8 @@
#pragma once
#include "gdkcolorprivate.h"
#include "gdkcolorstateprivate.h"
@@ -129,10 +131,3 @@ _gdk_color_to_float (const GdkColor *self,
values);
}
#define gdk_color_get_depth(self) _gdk_color_get_depth ((self))
static inline GdkMemoryDepth
_gdk_color_get_depth (const GdkColor *self)
{
return gdk_color_state_get_depth (self->color_state);
}
+2 -3
View File
@@ -79,11 +79,10 @@ void gdk_color_init_from_rgba (GdkColor *self,
const GdkRGBA *rgba);
void gdk_color_finish (GdkColor *self);
gboolean gdk_color_equal (const GdkColor *color1,
const GdkColor *color2);
gboolean gdk_color_equal (const GdkColor *self,
const GdkColor *other);
gboolean gdk_color_is_clear (const GdkColor *self);
gboolean gdk_color_is_opaque (const GdkColor *self);
GdkMemoryDepth gdk_color_get_depth (const GdkColor *self);
void gdk_color_convert (GdkColor *self,
GdkColorState *color_state,
+1 -1
View File
@@ -78,7 +78,7 @@ extern GdkDefaultColorState gdk_default_color_states[GDK_COLOR_STATE_N_IDS];
(GdkDefaultColorState *) (c) < &gdk_default_color_states[GDK_COLOR_STATE_N_IDS])
#define GDK_DEFAULT_COLOR_STATE_ID(c) ((GdkColorStateId) (((GdkDefaultColorState *) c) - gdk_default_color_states))
const char * gdk_color_state_get_name (GdkColorState *color_state);
const char * gdk_color_state_get_name (GdkColorState *self);
GdkColorState * gdk_color_state_get_no_srgb_tf (GdkColorState *self);
GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp *cicp,
+4 -4
View File
@@ -169,7 +169,7 @@ gdk_content_provider_class_init (GdkContentProviderClass *class)
class->get_value = gdk_content_provider_real_get_value;
/**
* GdkContentProvider:formats: (attributes org.gtk.Property.get=gdk_content_provider_ref_formats)
* GdkContentProvider:formats: (getter ref_formats)
*
* The possible formats that the provider can provide its data in.
*/
@@ -181,7 +181,7 @@ gdk_content_provider_class_init (GdkContentProviderClass *class)
G_PARAM_EXPLICIT_NOTIFY);
/**
* GdkContentProvider:storable-formats: (attributes org.gtk.Property.get=gdk_content_provider_ref_storable_formats)
* GdkContentProvider:storable-formats: (getter ref_storable_formats)
*
* The subset of formats that clipboard managers should store this provider's data in.
*/
@@ -214,7 +214,7 @@ gdk_content_provider_init (GdkContentProvider *provider)
}
/**
* gdk_content_provider_ref_formats: (attributes org.gtk.Method.get_property=formats)
* gdk_content_provider_ref_formats: (get-property formats)
* @provider: a `GdkContentProvider`
*
* Gets the formats that the provider can provide its current contents in.
@@ -230,7 +230,7 @@ gdk_content_provider_ref_formats (GdkContentProvider *provider)
}
/**
* gdk_content_provider_ref_storable_formats: (attributes org.gtk.Method.get_property=storable-formats)
* gdk_content_provider_ref_storable_formats: (get-property storable-formats)
* @provider: a `GdkContentProvider`
*
* Gets the formats that the provider suggests other applications to store
+8 -8
View File
@@ -172,7 +172,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
object_class->finalize = gdk_cursor_finalize;
/**
* GdkCursor:fallback: (attributes org.gtk.Property.get=gdk_cursor_get_fallback)
* GdkCursor:fallback:
*
* Cursor to fall back to if this cursor cannot be displayed.
*/
@@ -184,7 +184,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
G_PARAM_STATIC_STRINGS));
/**
* GdkCursor:hotspot-x: (attributes org.gtk.Property.get=gdk_cursor_get_hotspot_x)
* GdkCursor:hotspot-x:
*
* X position of the cursor hotspot in the cursor image.
*/
@@ -196,7 +196,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
G_PARAM_STATIC_STRINGS));
/**
* GdkCursor:hotspot-y: (attributes org.gtk.Property.get=gdk_cursor_get_hotspot_y)
* GdkCursor:hotspot-y:
*
* Y position of the cursor hotspot in the cursor image.
*/
@@ -208,7 +208,7 @@ gdk_cursor_class_init (GdkCursorClass *cursor_class)
G_PARAM_STATIC_STRINGS));
/**
* GdkCursor:name: (attributes org.gtk.Property.get=gdk_cursor_get_name)
* GdkCursor:name:
*
* Name of this this cursor.
*
@@ -407,7 +407,7 @@ gdk_cursor_new_from_callback (GdkCursorGetTextureCallback callback,
}
/**
* gdk_cursor_get_fallback: (attributes org.gtk.Method.get_property=fallback)
* gdk_cursor_get_fallback:
* @cursor: a `GdkCursor`
*
* Returns the fallback for this @cursor.
@@ -430,7 +430,7 @@ gdk_cursor_get_fallback (GdkCursor *cursor)
}
/**
* gdk_cursor_get_name: (attributes org.gtk.Method.get_property=name)
* gdk_cursor_get_name:
* @cursor: a `GdkCursor`
*
* Returns the name of the cursor.
@@ -468,7 +468,7 @@ gdk_cursor_get_texture (GdkCursor *cursor)
}
/**
* gdk_cursor_get_hotspot_x: (attributes org.gtk.Method.get_property=hotspot-x)
* gdk_cursor_get_hotspot_x:
* @cursor: a `GdkCursor`
*
* Returns the horizontal offset of the hotspot.
@@ -490,7 +490,7 @@ gdk_cursor_get_hotspot_x (GdkCursor *cursor)
}
/**
* gdk_cursor_get_hotspot_y: (attributes org.gtk.Method.get_property=hotspot-y)
* gdk_cursor_get_hotspot_y:
* @cursor: a `GdkCursor`
*
* Returns the vertical offset of the hotspot.
+28 -28
View File
@@ -104,7 +104,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
object_class->get_property = gdk_device_get_property;
/**
* GdkDevice:display: (attributes org.gtk.Property.get=gdk_device_get_display)
* GdkDevice:display:
*
* The `GdkDisplay` the `GdkDevice` pertains to.
*/
@@ -114,7 +114,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:name: (attributes org.gtk.Property.get=gdk_device_get_name)
* GdkDevice:name:
*
* The device name.
*/
@@ -125,7 +125,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:source: (attributes org.gtk.Property.get=gdk_device_get_source)
* GdkDevice:source:
*
* Source type for the device.
*/
@@ -137,7 +137,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
/**
* GdkDevice:has-cursor: (attributes org.gtk.Property.get=gdk_device_get_has_cursor)
* GdkDevice:has-cursor:
*
* Whether the device is represented by a cursor on the screen.
*/
@@ -159,7 +159,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:vendor-id: (attributes org.gtk.Property.get=gdk_device_get_vendor_id)
* GdkDevice:vendor-id:
*
* Vendor ID of this device.
*
@@ -172,7 +172,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:product-id: (attributes org.gtk.Property.get=gdk_device_get_product_id)
* GdkDevice:product-id:
*
* Product ID of this device.
*
@@ -185,7 +185,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:seat: (attributes org.gtk.Property.get=gdk_device_get_seat)
* GdkDevice:seat:
*
* `GdkSeat` of this device.
*/
@@ -196,7 +196,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:num-touches: (attributes org.gtk.Property.get=gdk_device_get_num_touches)
* GdkDevice:num-touches:
*
* The maximal number of concurrent touches on a touch device.
*
@@ -211,7 +211,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:tool: (attributes org.gtk.Property.get=gdk_device_get_device_tool)
* GdkDevice:tool: (getter get_device_tool)
*
* The `GdkDeviceTool` that is currently used with this device.
*/
@@ -221,7 +221,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:direction: (attributes org.gtk.Property.get=gdk_device_get_direction)
* GdkDevice:direction:
*
* The direction of the current layout.
*
@@ -233,7 +233,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:has-bidi-layouts: (attributes org.gtk.Property.get=gdk_device_has_bidi_layouts)
* GdkDevice:has-bidi-layouts:
*
* Whether the device has both right-to-left and left-to-right layouts.
*
@@ -245,7 +245,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:caps-lock-state: (attributes org.gtk.Property.get=gdk_device_get_caps_lock_state)
* GdkDevice:caps-lock-state:
*
* Whether Caps Lock is on.
*
@@ -257,7 +257,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:num-lock-state: (attributes org.gtk.Property.get=gdk_device_get_num_lock_state)
* GdkDevice:num-lock-state:
*
* Whether Num Lock is on.
*
@@ -269,7 +269,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:scroll-lock-state: (attributes org.gtk.Property.get=gdk_device_get_scroll_lock_state)
* GdkDevice:scroll-lock-state:
*
* Whether Scroll Lock is on.
*
@@ -281,7 +281,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDevice:modifier-state: (attributes org.gtk.Property.get=gdk_device_get_modifier_state)
* GdkDevice:modifier-state:
*
* The current modifier state of the device.
*
@@ -540,7 +540,7 @@ gdk_device_get_name (GdkDevice *device)
}
/**
* gdk_device_get_has_cursor: (attributes org.gtk.Method.get_property=has-cursor)
* gdk_device_get_has_cursor:
* @device: a `GdkDevice`
*
* Determines whether the pointer follows device motion.
@@ -559,7 +559,7 @@ gdk_device_get_has_cursor (GdkDevice *device)
}
/**
* gdk_device_get_source: (attributes org.gtk.Method.get_property=source)
* gdk_device_get_source:
* @device: a `GdkDevice`
*
* Determines the type of the device.
@@ -599,7 +599,7 @@ gdk_device_get_axis_use (GdkDevice *device,
}
/**
* gdk_device_get_display: (attributes org.gtk.Method.get_property=display)
* gdk_device_get_display:
* @device: a `GdkDevice`
*
* Returns the `GdkDisplay` to which @device pertains.
@@ -1082,7 +1082,7 @@ _gdk_device_surface_at_position (GdkDevice *device,
}
/**
* gdk_device_get_vendor_id: (attributes org.gtk.Method.get_property=vendor-id)
* gdk_device_get_vendor_id:
* @device: a physical `GdkDevice`
*
* Returns the vendor ID of this device.
@@ -1124,7 +1124,7 @@ gdk_device_get_vendor_id (GdkDevice *device)
}
/**
* gdk_device_get_product_id: (attributes org.gtk.Method.get_property=product-id)
* gdk_device_get_product_id:
* @device: a physical `GdkDevice`
*
* Returns the product ID of this device.
@@ -1157,7 +1157,7 @@ gdk_device_set_seat (GdkDevice *device,
}
/**
* gdk_device_get_seat: (attributes org.gtk.Method.get_property=seat)
* gdk_device_get_seat:
* @device: A `GdkDevice`
*
* Returns the `GdkSeat` the device belongs to.
@@ -1202,7 +1202,7 @@ gdk_device_get_num_touches (GdkDevice *device)
}
/**
* gdk_device_get_device_tool: (attributes org.gtk.Method.get_property=tool)
* gdk_device_get_device_tool: (get-property tool)
* @device: a `GdkDevice`
*
* Retrieves the current tool for @device.
@@ -1218,7 +1218,7 @@ gdk_device_get_device_tool (GdkDevice *device)
}
/**
* gdk_device_get_caps_lock_state: (attributes org.gtk.Method.get_property=caps-lock-state)
* gdk_device_get_caps_lock_state:
* @device: a `GdkDevice`
*
* Retrieves whether the Caps Lock modifier of the keyboard is locked.
@@ -1239,7 +1239,7 @@ gdk_device_get_caps_lock_state (GdkDevice *device)
}
/**
* gdk_device_get_num_lock_state: (attributes org.gtk.Method.get_property=num-lock-state)
* gdk_device_get_num_lock_state:
* @device: a ``GdkDevice`
*
* Retrieves whether the Num Lock modifier of the keyboard is locked.
@@ -1260,7 +1260,7 @@ gdk_device_get_num_lock_state (GdkDevice *device)
}
/**
* gdk_device_get_scroll_lock_state: (attributes org.gtk.Method.get_property=scroll-lock-state)
* gdk_device_get_scroll_lock_state:
* @device: a `GdkDevice`
*
* Retrieves whether the Scroll Lock modifier of the keyboard is locked.
@@ -1281,7 +1281,7 @@ gdk_device_get_scroll_lock_state (GdkDevice *device)
}
/**
* gdk_device_get_modifier_state: (attributes org.gtk.Method.get_property=modifier-state)
* gdk_device_get_modifier_state:
* @device: a `GdkDevice`
*
* Retrieves the current modifier state of the keyboard.
@@ -1302,7 +1302,7 @@ gdk_device_get_modifier_state (GdkDevice *device)
}
/**
* gdk_device_get_direction: (attributes org.gtk.Method.get_property=direction)
* gdk_device_get_direction:
* @device: a `GdkDevice`
*
* Returns the direction of effective layout of the keyboard.
@@ -1328,7 +1328,7 @@ gdk_device_get_direction (GdkDevice *device)
}
/**
* gdk_device_has_bidi_layouts: (attributes org.gtk.Method.get_property=has-bidi-layouts)
* gdk_device_has_bidi_layouts:
* @device: a `GdkDevice`
*
* Determines if layouts for both right-to-left and
+1 -1
View File
@@ -117,7 +117,7 @@ struct _GdkDeviceClass
};
void _gdk_device_set_associated_device (GdkDevice *device,
GdkDevice *relative);
GdkDevice *associated);
void _gdk_device_reset_axes (GdkDevice *device);
guint _gdk_device_add_axis (GdkDevice *device,
+8 -8
View File
@@ -107,7 +107,7 @@ gdk_device_tool_class_init (GdkDeviceToolClass *klass)
object_class->get_property = gdk_device_tool_get_property;
/**
* GdkDeviceTool:serial: (attributes org.gtk.Property.get=gdk_device_tool_get_serial)
* GdkDeviceTool:serial:
*
* The serial number of the tool.
*/
@@ -118,7 +118,7 @@ gdk_device_tool_class_init (GdkDeviceToolClass *klass)
G_PARAM_STATIC_STRINGS);
/**
* GdkDeviceTool:tool-type: (attributes org.gtk.Property.get=gdk_device_tool_get_tool_type)
* GdkDeviceTool:tool-type:
*
* The type of the tool.
*/
@@ -130,7 +130,7 @@ gdk_device_tool_class_init (GdkDeviceToolClass *klass)
G_PARAM_STATIC_STRINGS);
/**
* GdkDeviceTool:axes: (attributes org.gtk.Property.get=gdk_device_tool_get_axes)
* GdkDeviceTool:axes:
*
* The axes of the tool.
*/
@@ -140,7 +140,7 @@ gdk_device_tool_class_init (GdkDeviceToolClass *klass)
G_PARAM_CONSTRUCT_ONLY);
/**
* GdkDeviceTool:hardware-id: (attributes org.gtk.Property.get=gdk_device_tool_get_hardware_id)
* GdkDeviceTool:hardware-id:
*
* The hardware ID of the tool.
*/
@@ -173,7 +173,7 @@ gdk_device_tool_new (guint64 serial,
}
/**
* gdk_device_tool_get_serial: (attributes org.gtk.Method.get_property=serial)
* gdk_device_tool_get_serial:
* @tool: a `GdkDeviceTool`
*
* Gets the serial number of this tool.
@@ -192,7 +192,7 @@ gdk_device_tool_get_serial (GdkDeviceTool *tool)
}
/**
* gdk_device_tool_get_hardware_id: (attributes org.gtk.Method.get_property=hardware-id)
* gdk_device_tool_get_hardware_id:
* @tool: a `GdkDeviceTool`
*
* Gets the hardware ID of this tool, or 0 if it's not known.
@@ -218,7 +218,7 @@ gdk_device_tool_get_hardware_id (GdkDeviceTool *tool)
}
/**
* gdk_device_tool_get_tool_type: (attributes org.gtk.Method.get_property=tool-type)
* gdk_device_tool_get_tool_type:
* @tool: a `GdkDeviceTool`
*
* Gets the `GdkDeviceToolType` of the tool.
@@ -236,7 +236,7 @@ gdk_device_tool_get_tool_type (GdkDeviceTool *tool)
}
/**
* gdk_device_tool_get_axes: (attributes org.gtk.Method.get_property=axes)
* gdk_device_tool_get_axes:
* @tool: a `GdkDeviceTool`
*
* Gets the axes of the tool.
+26 -48
View File
@@ -230,7 +230,7 @@ gdk_display_class_init (GdkDisplayClass *class)
class->opened = gdk_display_real_opened;
/**
* GdkDisplay:composited: (attributes org.gtk.Property.get=gdk_display_is_composited)
* GdkDisplay:composited: (getter is_composited)
*
* %TRUE if the display properly composites the alpha channel.
*/
@@ -240,7 +240,7 @@ gdk_display_class_init (GdkDisplayClass *class)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDisplay:rgba: (attributes org.gtk.Property.get=gdk_display_is_rgba)
* GdkDisplay:rgba: (getter is_rgba)
*
* %TRUE if the display supports an alpha channel.
*/
@@ -250,7 +250,7 @@ gdk_display_class_init (GdkDisplayClass *class)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDisplay:shadow-width: (attributes org.gtk.Property.get=gdk_display_supports_shadow_width)
* GdkDisplay:shadow-width: (getter supports_shadow_width)
*
* %TRUE if the display supports extensible frames.
*
@@ -262,7 +262,7 @@ gdk_display_class_init (GdkDisplayClass *class)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDisplay:input-shapes: (attributes org.gtk.Property.get=gdk_display_supports_input_shapes)
* GdkDisplay:input-shapes: (getter supports_input_shapes)
*
* %TRUE if the display supports input shapes.
*/
@@ -272,7 +272,7 @@ gdk_display_class_init (GdkDisplayClass *class)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDisplay:dmabuf-formats: (attributes org.gtk.Property.get=gdk_display_get_dmabuf_formats)
* GdkDisplay:dmabuf-formats:
*
* The dma-buf formats that are supported on this display
*
@@ -418,15 +418,17 @@ gdk_display_dispose (GObject *object)
{
GdkDisplay *display = GDK_DISPLAY (object);
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
gsize i;
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders); i++)
if (display->vk_downloader)
{
if (display->dmabuf_downloaders[i] == NULL)
continue;
gdk_dmabuf_downloader_close (display->vk_downloader);
g_clear_object (&display->vk_downloader);
}
gdk_dmabuf_downloader_close (display->dmabuf_downloaders[i]);
g_clear_object (&display->dmabuf_downloaders[i]);
if (display->egl_downloader)
{
gdk_dmabuf_downloader_close (display->egl_downloader);
g_clear_object (&display->egl_downloader);
}
_gdk_display_manager_remove_display (gdk_display_manager_get (), display);
@@ -434,7 +436,7 @@ gdk_display_dispose (GObject *object)
g_queue_clear (&display->queued_events);
g_clear_pointer (&display->egl_dmabuf_formats, gdk_dmabuf_formats_unref);
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
g_clear_pointer (&display->egl_internal_formats, gdk_dmabuf_formats_unref);
#ifdef GDK_RENDERING_VULKAN
if (display->vk_dmabuf_formats)
{
@@ -1116,7 +1118,7 @@ gdk_display_get_primary_clipboard (GdkDisplay *display)
}
/**
* gdk_display_supports_input_shapes: (attributes org.gtk.Method.get_property=input-shapes)
* gdk_display_supports_input_shapes: (get-property input-shapes)
* @display: a `GdkDisplay`
*
* Returns %TRUE if the display supports input shapes.
@@ -1965,33 +1967,6 @@ gdk_display_get_egl_display (GdkDisplay *self)
#endif
}
#ifdef HAVE_DMABUF
static void
gdk_display_add_dmabuf_downloader (GdkDisplay *display,
GdkDmabufDownloader *downloader)
{
gsize i;
if (downloader == NULL)
return;
/* dmabuf_downloaders is NULL-terminated */
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++)
{
if (display->dmabuf_downloaders[i] == NULL)
break;
}
g_assert (i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1);
display->dmabuf_downloaders[i] = downloader;
}
#endif
/* To support a drm format, we must be able to import it into GL
* using the relevant EGL extensions, and download it into a memory
* texture, possibly doing format conversion with shaders (in GSK).
*/
void
gdk_display_init_dmabuf (GdkDisplay *self)
{
@@ -2009,22 +1984,25 @@ gdk_display_init_dmabuf (GdkDisplay *self)
if (gdk_has_feature (GDK_FEATURE_DMABUF))
{
#ifdef GDK_RENDERING_VULKAN
gdk_display_add_dmabuf_downloader (self, gdk_vulkan_get_dmabuf_downloader (self, builder));
gdk_vulkan_init_dmabuf (self);
if (self->vk_dmabuf_formats)
gdk_dmabuf_formats_builder_add_formats (builder, self->vk_dmabuf_formats);
#endif
#ifdef HAVE_EGL
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (self, builder));
gdk_dmabuf_egl_init (self);
if (self->egl_dmabuf_formats)
gdk_dmabuf_formats_builder_add_formats (builder, self->egl_dmabuf_formats);
#endif
gdk_dmabuf_formats_builder_add_formats (builder,
gdk_dmabuf_get_mmap_formats ());
gdk_dmabuf_formats_builder_add_formats (builder, gdk_dmabuf_get_mmap_formats ());
}
#endif
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
GDK_DISPLAY_DEBUG (self, DMABUF,
"Initialized support for %zu dmabuf formats",
"Initialization finished. Advertising %zu dmabuf formats",
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
}
@@ -2075,7 +2053,7 @@ gdk_display_set_debug_flags (GdkDisplay *display,
}
/**
* gdk_display_is_composited: (attributes org.gtk.Method.get_property=composited)
* gdk_display_is_composited: (get-property composited)
* @display: a `GdkDisplay`
*
* Returns whether surfaces can reasonably be expected to have
@@ -2120,7 +2098,7 @@ gdk_display_set_composited (GdkDisplay *display,
}
/**
* gdk_display_is_rgba: (attributes org.gtk.Method.get_property=rgba)
* gdk_display_is_rgba: (get-property rgba)
* @display: a `GdkDisplay`
*
* Returns whether surfaces on this @display are created with an
@@ -2165,7 +2143,7 @@ gdk_display_set_rgba (GdkDisplay *display,
}
/**
* gdk_display_supports_shadow_width: (attributes org.gtk.Method.get_property=shadow-width)
* gdk_display_supports_shadow_width: (get-property shadow-width)
* @display: a `GdkDisplay`
*
* Returns whether it's possible for a surface to draw outside of the window area.
+2 -2
View File
@@ -149,7 +149,7 @@ gdk_display_manager_class_init (GdkDisplayManagerClass *klass)
GDK_TYPE_DISPLAY);
/**
* GdkDisplayManager:default-display: (attributes org.gtk.Property.get=gdk_display_manager_get_default_display)
* GdkDisplayManager:default-display:
*
* The default display.
*/
@@ -301,7 +301,7 @@ gdk_display_manager_get (void)
}
/**
* gdk_display_manager_get_default_display: (attributes org.gtk.Method.get_property=default-display)
* gdk_display_manager_get_default_display:
* @manager: a `GdkDisplayManager`
*
* Gets the default `GdkDisplay`.
+9 -7
View File
@@ -48,6 +48,7 @@ typedef enum {
GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT = 1 << 2,
GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT = 1 << 3,
GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT = 1 << 4,
GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE = 1 << 5,
} GdkVulkanFeatures;
/* Tracks information about the device grab on this display */
@@ -131,11 +132,12 @@ struct _GdkDisplay
guint have_egl_gl_colorspace : 1;
GdkDmabufFormats *dmabuf_formats;
GdkDmabufDownloader *dmabuf_downloaders[4];
GdkDmabufDownloader *egl_downloader;
GdkDmabufDownloader *vk_downloader;
/* Cached data the EGL dmabuf downloader */
GdkDmabufFormats *egl_dmabuf_formats;
GdkDmabufFormats *egl_external_formats;
GdkDmabufFormats *egl_internal_formats;
};
struct _GdkDisplayClass
@@ -238,15 +240,15 @@ GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
GdkSurface *surface,
GError **error);
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *self);
gboolean gdk_display_init_egl (GdkDisplay *display,
gboolean gdk_display_init_egl (GdkDisplay *self,
int /*EGLenum*/ platform,
gpointer native_display,
gboolean allow_any,
GError **error);
gpointer gdk_display_get_egl_display (GdkDisplay *display);
gpointer gdk_display_get_egl_config (GdkDisplay *display,
gpointer gdk_display_get_egl_display (GdkDisplay *self);
gpointer gdk_display_get_egl_config (GdkDisplay *self,
GdkMemoryDepth depth);
void gdk_display_set_rgba (GdkDisplay *display,
@@ -287,7 +289,7 @@ void gdk_display_set_double_click_time (GdkDisplay *display,
void gdk_display_set_double_click_distance (GdkDisplay *display,
guint distance);
void gdk_display_set_cursor_theme (GdkDisplay *display,
const char *theme,
const char *name,
int size);
G_END_DECLS
+32 -19
View File
@@ -2068,7 +2068,7 @@ gdk_dmabuf_get_mmap_formats (void)
continue;
GDK_DEBUG (DMABUF,
"mmap dmabuf format %.4s:%#0" G_GINT64_MODIFIER "x",
"mmap advertises dmabuf format %.4s::%016" G_GINT64_MODIFIER "x",
(char *) &supported_formats[i].fourcc, (guint64) DRM_FORMAT_MOD_LINEAR);
gdk_dmabuf_formats_builder_add_format (builder,
@@ -2082,7 +2082,7 @@ gdk_dmabuf_get_mmap_formats (void)
return formats;
}
static void
static gboolean
gdk_dmabuf_do_download_mmap (GdkTexture *texture,
guchar *data,
gsize stride)
@@ -2093,16 +2093,17 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
gsize sizes[GDK_DMABUF_MAX_PLANES];
gsize needs_unmap[GDK_DMABUF_MAX_PLANES] = { FALSE, };
gsize i, j;
gboolean retval = FALSE;
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
if (dmabuf->modifier != DRM_FORMAT_MOD_LINEAR)
return FALSE;
info = get_drm_format_info (dmabuf->fourcc);
g_return_if_fail (info && info->download);
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF,
"Using mmap for downloading %dx%d dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
gdk_texture_get_width (texture), gdk_texture_get_height (texture),
(char *)&dmabuf->fourcc, dmabuf->modifier);
if (!info || !info->download)
return FALSE;
for (i = 0; i < dmabuf->n_planes; i++)
{
@@ -2139,14 +2140,21 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
needs_unmap[i] = TRUE;
}
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
retval = TRUE;
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF,
"Used mmap for downloading %dx%d dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
gdk_texture_get_width (texture), gdk_texture_get_height (texture),
(char *)&dmabuf->fourcc, dmabuf->modifier);
out:
for (i = 0; i < dmabuf->n_planes; i++)
@@ -2159,9 +2167,11 @@ out:
if (gdk_dmabuf_ioctl (dmabuf->planes[i].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dmabuf: %s", g_strerror (errno));
}
return retval;
}
void
gboolean
gdk_dmabuf_download_mmap (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
@@ -2170,10 +2180,11 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
{
GdkMemoryFormat src_format = gdk_texture_get_format (texture);
GdkColorState *src_color_state = gdk_texture_get_color_state (texture);
gboolean retval;
if (format == src_format)
{
gdk_dmabuf_do_download_mmap (texture, data, stride);
retval = gdk_dmabuf_do_download_mmap (texture, data, stride);
gdk_memory_convert_color_state (data, stride, format,
src_color_state, color_state,
gdk_texture_get_width (texture),
@@ -2191,7 +2202,7 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
src_stride = width * gdk_memory_format_bytes_per_pixel (src_format);
src_data = g_new (guchar, src_stride * height);
gdk_dmabuf_do_download_mmap (texture, src_data, src_stride);
retval = gdk_dmabuf_do_download_mmap (texture, src_data, src_stride);
gdk_memory_convert (data, stride, format, color_state,
src_data, src_stride, src_format, src_color_state,
@@ -2199,6 +2210,8 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
g_free (src_data);
}
return retval;
}
int

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