Compare commits
329 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 05e8057b5b | |||
| e89365e9e3 | |||
| 6484807719 | |||
| 527ff05107 | |||
| b89cfdb77f | |||
| 499687a11d | |||
| c5e26dd591 | |||
| bc17d1d5ea | |||
| b88ac0890e | |||
| d30baf34b3 | |||
| b927ad2c87 | |||
| 4540dac11a | |||
| aa9cac695d | |||
| 52412ca944 | |||
| cd82b18cfd | |||
| da5bb6ff22 | |||
| 7871f1e13b | |||
| dd18c7dedf | |||
| a34a6e9b84 | |||
| 0a5f29c9eb | |||
| 417be0719b | |||
| 3263a26cad | |||
| 00916c2b47 | |||
| e3320633a6 | |||
| 764a8cea59 | |||
| a2599c2bb9 | |||
| e2675306e1 | |||
| 7d1429cb91 | |||
| f13a018739 | |||
| 84b3b1fab5 | |||
| 048bb6db6f | |||
| 8c548d5579 | |||
| 09d5ec1b08 | |||
| 28bba484da | |||
| 191558cfa4 | |||
| cb0c1b3f08 | |||
| 91f200167e | |||
| 2b6fb005a8 | |||
| af6bec7539 | |||
| 38362c2803 | |||
| eb7c78aa48 | |||
| 7ab39b5461 | |||
| 0c44851848 | |||
| d72ed045df | |||
| 38eb182947 | |||
| 0eba21b2b5 | |||
| 21cba193ad | |||
| ee7c83e15a | |||
| 48dbbbc099 | |||
| 1c733857b3 | |||
| 85a6517d65 | |||
| d75147db0a | |||
| d3cf7088b3 | |||
| ffa7185397 | |||
| d7fe62817c | |||
| a034bdb17e | |||
| af20f7e9b5 | |||
| 15b7a4572b | |||
| 146bb70c2e | |||
| 494de142f6 | |||
| 5d979cde82 | |||
| f48b894468 | |||
| a6e47892be | |||
| 1e0c25d96a | |||
| f57eec5288 | |||
| e938befcbc | |||
| 2af8ac655b | |||
| cc3c0125a8 | |||
| 59f9be457f | |||
| d1ce514260 | |||
| ad5e72728f | |||
| 1bf24f7b19 | |||
| a3cedb0163 | |||
| 97bab27d82 | |||
| 6030da573d | |||
| 0128574ca1 | |||
| b27a169200 | |||
| bcd0704511 | |||
| 506566b6a4 | |||
| b67da38916 | |||
| 8519ab56f5 | |||
| 89d87e3482 | |||
| 04c9c6b428 | |||
| 9bd8ed0d82 | |||
| 40386c97eb | |||
| 6649cc6e5e | |||
| e69dc04a7f | |||
| c1361f7a5a | |||
| 351ffef704 | |||
| a1ddd3fead | |||
| 79f0f4ee8e | |||
| 7b8bfb4c80 | |||
| 7106cf6524 | |||
| e706e14fd9 | |||
| 3f1021048f | |||
| ddba7f8601 | |||
| 1660a0eaf1 | |||
| ffffb382e2 | |||
| 09453bc60b | |||
| f76b749e43 | |||
| 0aca2a03b4 | |||
| fd358990a2 | |||
| 01b91c1ba3 | |||
| cc02076b75 | |||
| b726a2d902 | |||
| 654ae5928a | |||
| 1c24514798 | |||
| 33f3ab9991 | |||
| 91511a80ac | |||
| a585457861 | |||
| 4a0ddac307 | |||
| f7d9ede82d | |||
| 65839f67f8 | |||
| df40db137b | |||
| 129bc27d53 | |||
| 274e2b221f | |||
| adc4009354 | |||
| f058a42bd3 | |||
| 3a8cb276e7 | |||
| eeaa73c12a | |||
| 3873861b27 | |||
| 8e455e333b | |||
| 3d10e6c3d1 | |||
| dcc7cf7114 | |||
| f1d0886087 | |||
| 951e4ee6b2 | |||
| f9e2c106bc | |||
| 53956e5389 | |||
| 3ab63fd03b | |||
| fb4927827b | |||
| cbbca38d88 | |||
| c64836e1c9 | |||
| 6b23fe3aa7 | |||
| 9defc7fc64 | |||
| 9d56f44cdf | |||
| 1b9da2bb17 | |||
| 2efc1729e2 | |||
| a66a0dde81 | |||
| 7062411bad | |||
| 9dbd137ec8 | |||
| 79fad9f221 | |||
| 8f9ee48aaa | |||
| 8eb9844a45 | |||
| b90132c917 | |||
| 23806b7788 | |||
| d266c0d105 | |||
| 581461c2b5 | |||
| f108f053d4 | |||
| df593ee651 | |||
| 4dcd011486 | |||
| 6fe7e373e2 | |||
| 0c3583b4bd | |||
| 5bd0179a88 | |||
| f116efd48e | |||
| 8057bee295 | |||
| ab330f1efc | |||
| e5dc66b10e | |||
| aa43d97a80 | |||
| eaf4fb68f3 | |||
| bfe193e6e2 | |||
| aa8dec3d27 | |||
| d2e7060150 | |||
| 08f3acb534 | |||
| 525f96f2f8 | |||
| b6b2682bd6 | |||
| 1832964188 | |||
| eb599653e6 | |||
| e1e88ce665 | |||
| 66d21689bc | |||
| 8186cb8bee | |||
| 9b8f28903b | |||
| 1cd42825c2 | |||
| 166444f115 | |||
| 3cd68c5de5 | |||
| 9e2357d5f3 | |||
| bd0c68f641 | |||
| c3a7d79154 | |||
| 25624083dd | |||
| 407b5246a6 | |||
| 6bedcf22bc | |||
| eeb9d6c398 | |||
| cf8d2374c5 | |||
| 9fa5378d83 | |||
| 90352d760d | |||
| c3c1763a9f | |||
| 9f7c9ce6ad | |||
| 1f155bf39a | |||
| 84014e3414 | |||
| 4ced1c90f1 | |||
| 54c3b947fc | |||
| 94007caf8d | |||
| 675c8b45b1 | |||
| ea59d174a0 | |||
| 32935d9fb0 | |||
| b390e1da4f | |||
| cccd1147e7 | |||
| d8db5f3217 | |||
| f5bb364bb5 | |||
| 82f57c6a93 | |||
| 20c41dce80 | |||
| a9de385ac5 | |||
| ead210c170 | |||
| 2ad471542a | |||
| d73cff5846 | |||
| 213376ee0a | |||
| 1cc100415f | |||
| d9ad7884e9 | |||
| f545d7a910 | |||
| 206eb647a4 | |||
| 00e637b480 | |||
| bfc8b7b7b6 | |||
| c44288c739 | |||
| 2fb5104731 | |||
| 0ae4d80766 | |||
| f5098e4fc5 | |||
| 28607f082c | |||
| f3968f2f1e | |||
| 88fa226223 | |||
| c4c496a31c | |||
| c1eac4a421 | |||
| b5d1323f49 | |||
| e297ac319d | |||
| bf852bea24 | |||
| a652507b7b | |||
| 4a2a76c231 | |||
| 8cb7369b7a | |||
| 588076d166 | |||
| 3a98b28ab7 | |||
| cfeedcc321 | |||
| d0aedbc9fc | |||
| 5557a528b6 | |||
| 5316eb0c35 | |||
| e6afe28de5 | |||
| eaf0353205 | |||
| f9f9bd3f5b | |||
| ca79688f52 | |||
| efa8f903c2 | |||
| f7d0b91267 | |||
| ed4f0de2b0 | |||
| 50b96dcdd5 | |||
| cf25f2c04b | |||
| ddf07ffe22 | |||
| 82f1eaacc9 | |||
| 4cdb07fa02 | |||
| bdd5393084 | |||
| 27b87ebec5 | |||
| 8c0df66d5f | |||
| e5238bf54f | |||
| e9abcde031 | |||
| d45281e6c7 | |||
| 3fd5ebffcb | |||
| 88a621fa13 | |||
| ce4b799f1e | |||
| 4dcacff312 | |||
| fd7667246d | |||
| b8cb15f28d | |||
| 51607ce93c | |||
| 66284cd245 | |||
| f9faecd5b7 | |||
| 92261b5022 | |||
| 91f5bfd211 | |||
| 63f20b173d | |||
| 25b3bd64af | |||
| fc4d36e50a | |||
| dbede0b115 | |||
| 1e40033852 | |||
| 478bf45320 | |||
| dac0b7d609 | |||
| d14987e819 | |||
| 3a0077f65f | |||
| 03882ef8e5 | |||
| 505e10f3ea | |||
| 1e01444de8 | |||
| 4404c43cd3 | |||
| 92a7c7cdc3 | |||
| 33db142eab | |||
| 68319afd23 | |||
| 25f4e597ee | |||
| db8339ca66 | |||
| 5ba02e3459 | |||
| 999509be61 | |||
| 5dca6dce91 | |||
| d3acfa8c2b | |||
| c1cc8c979b | |||
| eed74f6ea0 | |||
| e5a4b91997 | |||
| 885b34d382 | |||
| 3faf9d85bb | |||
| 4cd4c25c25 | |||
| bffa5dfddd | |||
| 2fe20878c3 | |||
| b28c3ef3d9 | |||
| ed5fb4bbfe | |||
| 2dd86aaa00 | |||
| eaf952d902 | |||
| 88cb6a46f2 | |||
| c76b4bdc77 | |||
| 62fe4eae16 | |||
| 99a40de8ad | |||
| b8376407a4 | |||
| a5643b0c83 | |||
| 828688d5cd | |||
| fc47b913b1 | |||
| 7d8b3357a5 | |||
| e0b98bc7de | |||
| 493b145496 | |||
| 1b2c11d7f5 | |||
| a56828237a | |||
| 56e2a7e8bb | |||
| f278f3610b | |||
| c111e633e9 | |||
| eea7cf30bb | |||
| 36bdcfaccb | |||
| 45bb820656 | |||
| 617deb8bb6 | |||
| 8efcd34dbe | |||
| a78b573f8b | |||
| 226f0e0567 | |||
| 4304a494ae | |||
| b71ff21530 | |||
| 6a7da77980 | |||
| c5f92340ee | |||
| 572a884e90 | |||
| 69bc9d0702 | |||
| 34ff9e359b | |||
| de705c2a2b | |||
| d1102f586c | |||
| ab65e8e178 | |||
| 4d741bac98 |
@@ -1,143 +1,3 @@
|
||||
Overview of Changes in 4.6.3, 21-04-2022
|
||||
========================================
|
||||
|
||||
* GtkOverlay:
|
||||
- Bring back positional style classes
|
||||
|
||||
* GtkFileChooser:
|
||||
- Prevent unwanted completion popups
|
||||
- Fix small problems in save mode
|
||||
- Fix buildable suport of GtkFileFilter
|
||||
|
||||
* GtkPopover:
|
||||
- Fix button positions in right-to-left locales
|
||||
|
||||
* GtkLabel:
|
||||
- Fix small issues with link handling
|
||||
|
||||
* Tooltips:
|
||||
- Don't restrict the minimum tooltip length
|
||||
|
||||
* Theme:
|
||||
- Don't use opacity for overlay scrollbars
|
||||
- Fix selection text color in vertical spin buttons
|
||||
|
||||
* GSK:
|
||||
- Accept textures that are generated by webkit
|
||||
- Align offscreen rendering to the pixel grid
|
||||
|
||||
* Accessibility
|
||||
- Fix a crash in startup when orca is running
|
||||
|
||||
* Input:
|
||||
- Fix display changes in GtkIMMultiContext
|
||||
- Fix activating on-screen keyboards
|
||||
- Always propagate hold events in GtkEventControllerScroll
|
||||
|
||||
* Windows:
|
||||
- Fix a critical warning in clipboard handling
|
||||
- Report serial numbers for events
|
||||
|
||||
* MacOS:
|
||||
- Prevent fullscreen transition reentrancy
|
||||
|
||||
|
||||
* Translation updates
|
||||
British English
|
||||
Czech
|
||||
German
|
||||
Indonesian
|
||||
Latvian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.2, 18-03-2022
|
||||
========================================
|
||||
|
||||
* GtkScrolledWindow:
|
||||
- Set scroll-to-focus on viewports
|
||||
- Avoid doubly triggering deceleration
|
||||
|
||||
* GtkEntry:
|
||||
- Stop cursor blinking on focus-out
|
||||
|
||||
* Emoji:
|
||||
- Update Emoji data to CLDR 40 and Unicode 14
|
||||
- Add more locales for Emoji data (da, de, en, es,
|
||||
fr hu, it, ko, lt, ms, nl, pl, pt, ru, s, uk zh)
|
||||
|
||||
* GDK
|
||||
- Optimize texture conversions on x86 and ARM
|
||||
- Use EGK_KHR_swap_buffers_with_damage if available
|
||||
|
||||
* GSK
|
||||
- Avoid clearing opaque regions
|
||||
- Support using a non-default framebuffer
|
||||
- Handle large viewports by tiling
|
||||
|
||||
* Wayland:
|
||||
- Prefer xdg-activation over gtk-shell
|
||||
- text protocol: Fix text caret location
|
||||
- text protocol: Use serials to control outbound messages
|
||||
|
||||
* Inspector:
|
||||
- Show app ID and resource path
|
||||
|
||||
* Demos:
|
||||
- widget-factory: Handle F11 to toggle fullscreen
|
||||
|
||||
* Tools:
|
||||
- gtk-builder-tool: Allow use without display
|
||||
|
||||
* Windows:
|
||||
- Fix preedit window placement on HiDPI
|
||||
- Build improvements
|
||||
- Fix fullscreen handling
|
||||
|
||||
* MacOS:
|
||||
- Fix scrolling with an external mouse
|
||||
- Fix kinetic scrolling with overshoot
|
||||
- Improve monitor detection
|
||||
- Many input handling fixes
|
||||
- Support OpenGL accelerated video playback
|
||||
- Support fullscreen
|
||||
- Improve interactive window resizing and moving
|
||||
- Fix backdrop state handling
|
||||
- Fix GtkFileChooserNative filtering
|
||||
- Use CALayer and IOSurface for rendering
|
||||
- Use per monitor CVDisplayLink to support mixed-rate monitors
|
||||
- Start applications in foreground
|
||||
- Fix cursor blink time
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Croatian
|
||||
Czech
|
||||
Danish
|
||||
Finnish
|
||||
Galician
|
||||
German
|
||||
Hebrew
|
||||
Hungarian
|
||||
Italian
|
||||
Kazakh
|
||||
Korean
|
||||
Lithuanian
|
||||
Norwegian Bokmål
|
||||
Persian
|
||||
Poliah
|
||||
Portuguese
|
||||
Russian
|
||||
Slovak
|
||||
Slovenian
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.1, 11-02-2022
|
||||
========================================
|
||||
|
||||
|
||||
@@ -512,7 +512,7 @@ load_file (const char *demoname,
|
||||
|
||||
info_buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (info_buffer, "title",
|
||||
"font", "Sans 18",
|
||||
"size", 18 * 1024,
|
||||
"pixels-below-lines", 10,
|
||||
NULL);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ SYNOPSIS
|
||||
| **gtk4-builder-tool** enumerate <FILE>
|
||||
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
|
||||
| **gtk4-builder-tool** screenshot [OPTIONS...] <FILE>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -41,7 +42,7 @@ definition file.
|
||||
Preview
|
||||
^^^^^^^
|
||||
|
||||
The ``preview`` command displays the UI dfinition file.
|
||||
The ``preview`` command displays the UI definition file.
|
||||
|
||||
This command accepts options to specify the ID of the toplevel object and a CSS
|
||||
file to use.
|
||||
@@ -55,6 +56,33 @@ file to use.
|
||||
|
||||
Load style information from the given CSS file.
|
||||
|
||||
Screenshot
|
||||
^^^^^^^^^^
|
||||
|
||||
The ``screenshot`` command saves a rendering of the UI definition file
|
||||
as a png image or node file. The name of the file to write can be specified as
|
||||
a second FILE argument.
|
||||
|
||||
This command accepts options to specify the ID of the toplevel object and a CSS
|
||||
file to use.
|
||||
|
||||
``--id=ID``
|
||||
|
||||
The ID of the object to preview. If not specified, gtk4-builder-tool will
|
||||
choose a suitable object on its own.
|
||||
|
||||
``--css=FILE``
|
||||
|
||||
Load style information from the given CSS file.
|
||||
|
||||
``--node``
|
||||
|
||||
Write a serialized node file instead of a png image.
|
||||
|
||||
``--force``
|
||||
|
||||
Overwrite an existing file.
|
||||
|
||||
Simplification
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -597,7 +597,8 @@ _gdk_event_unqueue (GdkDisplay *display)
|
||||
|
||||
/*
|
||||
* If the last N events in the event queue are smooth scroll events
|
||||
* for the same surface and device, combine them into one.
|
||||
* for the same surface, the same device and the same scroll unit,
|
||||
* combine them into one.
|
||||
*
|
||||
* We give the remaining event a history with N items, and deltas
|
||||
* that are the sum over the history entries.
|
||||
@@ -611,6 +612,8 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
GdkEvent *last_event = NULL;
|
||||
GList *scrolls = NULL;
|
||||
GArray *history = NULL;
|
||||
GdkScrollUnit scroll_unit = GDK_SCROLL_UNIT_WHEEL;
|
||||
gboolean scroll_unit_defined = FALSE;
|
||||
GdkTimeCoord hist;
|
||||
|
||||
l = g_queue_peek_tail_link (&display->queued_events);
|
||||
@@ -618,6 +621,7 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
while (l)
|
||||
{
|
||||
GdkEvent *event = l->data;
|
||||
GdkScrollEvent *scroll_event = (GdkScrollEvent *) event;
|
||||
|
||||
if (event->flags & GDK_EVENT_PENDING)
|
||||
break;
|
||||
@@ -634,11 +638,17 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
device != event->device)
|
||||
break;
|
||||
|
||||
if (scroll_unit_defined &&
|
||||
scroll_unit != scroll_event->unit)
|
||||
break;
|
||||
|
||||
if (!last_event)
|
||||
last_event = event;
|
||||
|
||||
surface = event->surface;
|
||||
device = event->device;
|
||||
scroll_unit = scroll_event->unit;
|
||||
scroll_unit_defined = TRUE;
|
||||
scrolls = l;
|
||||
|
||||
l = l->prev;
|
||||
@@ -710,7 +720,8 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
gdk_event_get_modifier_state (old_event),
|
||||
dx,
|
||||
dy,
|
||||
gdk_scroll_event_is_stop (old_event));
|
||||
gdk_scroll_event_is_stop (old_event),
|
||||
scroll_unit);
|
||||
|
||||
((GdkScrollEvent *)event)->history = history;
|
||||
|
||||
@@ -746,15 +757,21 @@ gdk_motion_event_push_history (GdkEvent *event,
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (history_event);
|
||||
|
||||
if (tool)
|
||||
{
|
||||
hist.flags = gdk_device_tool_get_axes (tool);
|
||||
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
|
||||
gdk_event_get_axis (history_event, i, &hist.axes[i]);
|
||||
}
|
||||
else
|
||||
|
||||
/* GdkTimeCoord has no dedicated fields to record event position. For plain
|
||||
* pointer events, and for tools which don't report GDK_AXIS_X/GDK_AXIS_Y
|
||||
* on their own, we surface the position using the X and Y input axes.
|
||||
*/
|
||||
if (!(hist.flags & GDK_AXIS_FLAG_X) || !(hist.flags & GDK_AXIS_FLAG_Y))
|
||||
{
|
||||
hist.flags = GDK_AXIS_FLAG_X | GDK_AXIS_FLAG_Y;
|
||||
hist.flags |= GDK_AXIS_FLAG_X | GDK_AXIS_FLAG_Y;
|
||||
gdk_event_get_position (history_event, &hist.axes[GDK_AXIS_X], &hist.axes[GDK_AXIS_Y]);
|
||||
}
|
||||
|
||||
@@ -2334,7 +2351,8 @@ gdk_scroll_event_new (GdkSurface *surface,
|
||||
GdkModifierType state,
|
||||
double delta_x,
|
||||
double delta_y,
|
||||
gboolean is_stop)
|
||||
gboolean is_stop,
|
||||
GdkScrollUnit unit)
|
||||
{
|
||||
GdkScrollEvent *self = gdk_event_alloc (GDK_SCROLL, surface, device, time);
|
||||
|
||||
@@ -2344,6 +2362,7 @@ gdk_scroll_event_new (GdkSurface *surface,
|
||||
self->delta_x = delta_x;
|
||||
self->delta_y = delta_y;
|
||||
self->is_stop = is_stop;
|
||||
self->unit = unit;
|
||||
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
@@ -2363,6 +2382,7 @@ gdk_scroll_event_new_discrete (GdkSurface *surface,
|
||||
self->state = state;
|
||||
self->direction = direction;
|
||||
self->pointer_emulated = emulated;
|
||||
self->unit = GDK_SCROLL_UNIT_WHEEL;
|
||||
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
@@ -2396,6 +2416,9 @@ gdk_scroll_event_get_direction (GdkEvent *event)
|
||||
*
|
||||
* The deltas will be zero unless the scroll direction
|
||||
* is %GDK_SCROLL_SMOOTH.
|
||||
*
|
||||
* For the representation unit of these deltas, see
|
||||
* [method@Gdk.ScrollEvent.get_unit].
|
||||
*/
|
||||
void
|
||||
gdk_scroll_event_get_deltas (GdkEvent *event,
|
||||
@@ -2438,6 +2461,31 @@ gdk_scroll_event_is_stop (GdkEvent *event)
|
||||
return self->is_stop;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_scroll_event_get_unit:
|
||||
* @event: (type GdkScrollEvent): a scroll event.
|
||||
*
|
||||
* Extracts the scroll delta unit of a scroll event.
|
||||
*
|
||||
* The unit will always be %GDK_SCROLL_UNIT_WHEEL if the scroll direction is not
|
||||
* %GDK_SCROLL_SMOOTH.
|
||||
*
|
||||
* Returns: the scroll unit.
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
GdkScrollUnit
|
||||
gdk_scroll_event_get_unit (GdkEvent *event)
|
||||
{
|
||||
GdkScrollEvent *self = (GdkScrollEvent *) event;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT (event), GDK_SCROLL_UNIT_WHEEL);
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_SCROLL),
|
||||
GDK_SCROLL_UNIT_WHEEL);
|
||||
|
||||
return self->unit;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ GdkTouchpadEvent */
|
||||
|
||||
@@ -265,6 +265,37 @@ typedef enum
|
||||
GDK_SCROLL_SMOOTH
|
||||
} GdkScrollDirection;
|
||||
|
||||
/**
|
||||
* GdkScrollUnit:
|
||||
* @GDK_SCROLL_UNIT_WHEEL: The delta is in number of wheel clicks.
|
||||
* @GDK_SCROLL_UNIT_SURFACE: The delta is in surface pixels to scroll directly
|
||||
* on screen.
|
||||
*
|
||||
* Specifies the unit of scroll deltas.
|
||||
*
|
||||
* When you get %GDK_SCROLL_UNIT_WHEEL, a delta of 1.0 means 1 wheel detent
|
||||
* click in the south direction, 2.0 means 2 wheel detent clicks in the south
|
||||
* direction... This is the same logic for negative values but in the north
|
||||
* direction.
|
||||
*
|
||||
* If you get %GDK_SCROLL_UNIT_SURFACE, are managing a scrollable view and get a
|
||||
* value of 123, you have to scroll 123 surface logical pixels right if it's
|
||||
* @delta_x or down if it's @delta_y. This is the same logic for negative values
|
||||
* but you have to scroll left instead of right if it's @delta_x and up instead
|
||||
* of down if it's @delta_y.
|
||||
*
|
||||
* 1 surface logical pixel is equal to 1 real screen pixel multiplied by the
|
||||
* final scale factor of your graphical interface (the product of the desktop
|
||||
* scale factor and eventually a custom scale factor in your app).
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GDK_SCROLL_UNIT_WHEEL,
|
||||
GDK_SCROLL_UNIT_SURFACE
|
||||
} GdkScrollUnit;
|
||||
|
||||
/**
|
||||
* GdkNotifyType:
|
||||
* @GDK_NOTIFY_ANCESTOR: the surface is entered from an ancestor or
|
||||
@@ -395,6 +426,8 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_scroll_event_get_deltas (GdkEvent *event,
|
||||
double *delta_x,
|
||||
double *delta_y);
|
||||
GDK_AVAILABLE_IN_4_8
|
||||
GdkScrollUnit gdk_scroll_event_get_unit (GdkEvent *event);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_scroll_event_is_stop (GdkEvent *event);
|
||||
|
||||
@@ -212,6 +212,7 @@ struct _GdkTouchEvent
|
||||
* @history: (element-type GdkTimeCoord): array of times and deltas
|
||||
* for other scroll events that were compressed before delivering the
|
||||
* current event
|
||||
* @unit: The scroll unit in which delta_x and delta_y are represented.
|
||||
*
|
||||
* Generated from button presses for the buttons 4 to 7. Wheel mice are
|
||||
* usually configured to generate button press events for buttons 4 and 5
|
||||
@@ -234,6 +235,7 @@ struct _GdkScrollEvent
|
||||
gboolean is_stop;
|
||||
GdkDeviceTool *tool;
|
||||
GArray *history; /* <GdkTimeCoord> */
|
||||
GdkScrollUnit unit;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -486,7 +488,8 @@ GdkEvent * gdk_scroll_event_new (GdkSurface *surface,
|
||||
GdkModifierType state,
|
||||
double delta_x,
|
||||
double delta_y,
|
||||
gboolean is_stop);
|
||||
gboolean is_stop,
|
||||
GdkScrollUnit unit);
|
||||
|
||||
GdkEvent * gdk_scroll_event_new_discrete (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
|
||||
@@ -108,6 +108,16 @@
|
||||
*/
|
||||
#define GDK_VERSION_4_6 (G_ENCODE_VERSION (4, 6))
|
||||
|
||||
/**
|
||||
* GDK_VERSION_4_8:
|
||||
*
|
||||
* A macro that evaluates to the 4.8 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
#define GDK_VERSION_4_8 (G_ENCODE_VERSION (4, 8))
|
||||
|
||||
|
||||
/* evaluates to the current stable version; for development cycles,
|
||||
* this means the next stable target, with a hard backstop to the
|
||||
@@ -249,4 +259,18 @@
|
||||
# define GDK_DEPRECATED_IN_4_6_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_4_8
|
||||
# define GDK_AVAILABLE_IN_4_8 GDK_UNAVAILABLE(4, 8)
|
||||
#else
|
||||
# define GDK_AVAILABLE_IN_4_8 _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_8
|
||||
# define GDK_DEPRECATED_IN_4_8 GDK_DEPRECATED
|
||||
# define GDK_DEPRECATED_IN_4_8_FOR(f) GDK_DEPRECATED_FOR(f)
|
||||
#else
|
||||
# define GDK_DEPRECATED_IN_4_8 _GDK_EXTERN
|
||||
# define GDK_DEPRECATED_IN_4_8_FOR(f) _GDK_EXTERN
|
||||
#endif
|
||||
|
||||
#endif /* __GDK_VERSION_MACROS_H__ */
|
||||
|
||||
@@ -644,7 +644,8 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
0.0, 0.0, TRUE);
|
||||
0.0, 0.0, TRUE,
|
||||
GDK_SCROLL_UNIT_SURFACE);
|
||||
|
||||
dx = [nsevent deltaX];
|
||||
dy = [nsevent deltaY];
|
||||
@@ -665,7 +666,8 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
state,
|
||||
-sx,
|
||||
-sy,
|
||||
FALSE);
|
||||
FALSE,
|
||||
GDK_SCROLL_UNIT_SURFACE);
|
||||
|
||||
/* Fall through for scroll emulation */
|
||||
}
|
||||
@@ -714,7 +716,8 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
0.0, 0.0, TRUE);
|
||||
0.0, 0.0, TRUE,
|
||||
GDK_SCROLL_UNIT_SURFACE);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
|
||||
@@ -596,6 +596,11 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
|
||||
surface_class->set_input_region = gdk_macos_surface_set_input_region;
|
||||
surface_class->set_opaque_region = gdk_macos_surface_set_opaque_region;
|
||||
|
||||
/**
|
||||
* GdkMacosSurface:native: (attributes org.gtk.Property.get=gdk_macos_surface_get_native_window)
|
||||
*
|
||||
* The "native" property contains the underlying NSWindow.
|
||||
*/
|
||||
properties [PROP_NATIVE] =
|
||||
g_param_spec_pointer ("native",
|
||||
"Native",
|
||||
@@ -758,6 +763,27 @@ _gdk_macos_surface_get_native (GdkMacosSurface *self)
|
||||
return (NSWindow *)self->window;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_macos_surface_get_native_window: (attributes org.gtk.Method.get_property=native)
|
||||
* @self: a #GdkMacosSurface
|
||||
*
|
||||
* Gets the underlying NSWindow used by the surface.
|
||||
*
|
||||
* The NSWindow's contentView is an implementation detail and may change
|
||||
* between releases of GTK.
|
||||
*
|
||||
* Returns: (nullable): a #NSWindow or %NULL
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
gpointer
|
||||
gdk_macos_surface_get_native_window (GdkMacosSurface *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (self), NULL);
|
||||
|
||||
return _gdk_macos_surface_get_native (self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_surface_set_geometry_hints (GdkMacosSurface *self,
|
||||
const GdkGeometry *geometry,
|
||||
|
||||
@@ -36,7 +36,9 @@ typedef struct _GdkMacosSurfaceClass GdkMacosSurfaceClass;
|
||||
#define GDK_IS_MACOS_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_SURFACE))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_surface_get_type (void);
|
||||
GType gdk_macos_surface_get_type (void);
|
||||
GDK_AVAILABLE_IN_4_8
|
||||
gpointer gdk_macos_surface_get_native_window (GdkMacosSurface *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -1416,7 +1416,8 @@ flush_smooth_scroll_event (GdkWaylandSeat *seat,
|
||||
seat->pointer_info.time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
delta_x, delta_y,
|
||||
is_stop);
|
||||
is_stop,
|
||||
GDK_SCROLL_UNIT_SURFACE);
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
}
|
||||
@@ -1755,10 +1756,10 @@ pointer_handle_axis (void *data,
|
||||
switch (axis)
|
||||
{
|
||||
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
||||
pointer_frame->delta_y = wl_fixed_to_double (value) / 10.0;
|
||||
pointer_frame->delta_y = wl_fixed_to_double (value);
|
||||
break;
|
||||
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
|
||||
pointer_frame->delta_x = wl_fixed_to_double (value) / 10.0;
|
||||
pointer_frame->delta_x = wl_fixed_to_double (value);
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
@@ -1768,7 +1769,7 @@ pointer_handle_axis (void *data,
|
||||
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("scroll, axis %s, value %f, seat %p",
|
||||
get_axis_name (axis), wl_fixed_to_double (value) / 10.0,
|
||||
get_axis_name (axis), wl_fixed_to_double (value),
|
||||
seat));
|
||||
|
||||
if (display->seat_version < WL_POINTER_HAS_FRAME)
|
||||
@@ -3994,7 +3995,8 @@ tablet_tool_handle_wheel (void *data,
|
||||
tablet->pointer_info.time,
|
||||
device_get_modifiers (tablet->logical_device),
|
||||
0, clicks,
|
||||
FALSE);
|
||||
FALSE,
|
||||
GDK_SCROLL_UNIT_WHEEL);
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
|
||||
|
||||
@@ -2729,7 +2729,8 @@ gdk_event_translate (MSG *msg,
|
||||
build_pointer_event_state (msg),
|
||||
delta_x,
|
||||
delta_y,
|
||||
FALSE);
|
||||
FALSE,
|
||||
GDK_SCROLL_UNIT_WHEEL);
|
||||
|
||||
/* Append the discrete version too */
|
||||
direction = 0;
|
||||
|
||||
@@ -1778,7 +1778,8 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
state,
|
||||
delta_x,
|
||||
delta_y,
|
||||
delta_x == 0.0 && delta_y == 0.0);
|
||||
delta_x == 0.0 && delta_y == 0.0,
|
||||
GDK_SCROLL_UNIT_WHEEL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ snapshot_uniforms (GskGLUniformState *state,
|
||||
{
|
||||
const GskGLUniformMapping *mapping = &program->mappings[i];
|
||||
|
||||
if (!mapping->info.initial && mapping->location > -1)
|
||||
if (!mapping->info.initial && mapping->info.format && mapping->location > -1)
|
||||
{
|
||||
uniform[count].location = mapping->location;
|
||||
uniform[count].info = mapping->info;
|
||||
|
||||
@@ -44,9 +44,6 @@
|
||||
#include <gdk/gdkprofilerprivate.h>
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
|
||||
#define ATLAS_SIZE 512
|
||||
#define MAX_OLD_RATIO 0.5
|
||||
|
||||
G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT)
|
||||
|
||||
static guint
|
||||
@@ -156,50 +153,6 @@ gsk_gl_driver_collect_unused_textures (GskGLDriver *self,
|
||||
return collected;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_texture_atlas_free (GskGLTextureAtlas *atlas)
|
||||
{
|
||||
if (atlas->texture_id != 0)
|
||||
{
|
||||
glDeleteTextures (1, &atlas->texture_id);
|
||||
atlas->texture_id = 0;
|
||||
}
|
||||
|
||||
g_clear_pointer (&atlas->nodes, g_free);
|
||||
g_slice_free (GskGLTextureAtlas, atlas);
|
||||
}
|
||||
|
||||
GskGLTextureAtlas *
|
||||
gsk_gl_driver_create_atlas (GskGLDriver *self)
|
||||
{
|
||||
GskGLTextureAtlas *atlas;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), NULL);
|
||||
|
||||
atlas = g_slice_new0 (GskGLTextureAtlas);
|
||||
atlas->width = ATLAS_SIZE;
|
||||
atlas->height = ATLAS_SIZE;
|
||||
/* TODO: We might want to change the strategy about the amount of
|
||||
* nodes here? stb_rect_pack.h says width is optimal. */
|
||||
atlas->nodes = g_malloc0_n (atlas->width, sizeof (struct stbrp_node));
|
||||
stbrp_init_target (&atlas->context, atlas->width, atlas->height, atlas->nodes, atlas->width);
|
||||
atlas->texture_id = gsk_gl_command_queue_create_texture (self->command_queue,
|
||||
atlas->width,
|
||||
atlas->height,
|
||||
GL_RGBA8,
|
||||
GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
|
||||
gdk_gl_context_label_object_printf (gdk_gl_context_get_current (),
|
||||
GL_TEXTURE, atlas->texture_id,
|
||||
"Texture atlas %d",
|
||||
atlas->texture_id);
|
||||
|
||||
g_ptr_array_add (self->atlases, atlas);
|
||||
|
||||
return atlas;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_program (gpointer data)
|
||||
{
|
||||
@@ -226,6 +179,29 @@ gsk_gl_driver_shader_weak_cb (gpointer data,
|
||||
g_hash_table_remove (self->shader_cache, where_object_was);
|
||||
}
|
||||
|
||||
G_GNUC_NULL_TERMINATED static inline GBytes *
|
||||
join_sources (GBytes *first_bytes,
|
||||
...)
|
||||
{
|
||||
GByteArray *byte_array = g_byte_array_new ();
|
||||
GBytes *bytes = first_bytes;
|
||||
va_list args;
|
||||
|
||||
va_start (args, first_bytes);
|
||||
while (bytes != NULL)
|
||||
{
|
||||
gsize len;
|
||||
const guint8 *data = g_bytes_get_data (bytes, &len);
|
||||
if (len > 0)
|
||||
g_byte_array_append (byte_array, data, len);
|
||||
g_bytes_unref (bytes);
|
||||
bytes = va_arg (args, GBytes *);
|
||||
}
|
||||
va_end (args);
|
||||
|
||||
return g_byte_array_free_to_bytes (byte_array);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_driver_dispose (GObject *object)
|
||||
{
|
||||
@@ -235,6 +211,10 @@ gsk_gl_driver_dispose (GObject *object)
|
||||
g_assert (self->in_frame == FALSE);
|
||||
|
||||
#define GSK_GL_NO_UNIFORMS
|
||||
#define GSK_GL_SHADER_RESOURCE(name)
|
||||
#define GSK_GL_SHADER_STRING(str)
|
||||
#define GSK_GL_SHADER_SINGLE(name)
|
||||
#define GSK_GL_SHADER_JOINED(kind, ...)
|
||||
#define GSK_GL_ADD_UNIFORM(pos, KEY, name)
|
||||
#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \
|
||||
GSK_GL_DELETE_PROGRAM(name); \
|
||||
@@ -248,6 +228,10 @@ gsk_gl_driver_dispose (GObject *object)
|
||||
} G_STMT_END;
|
||||
# include "gskglprograms.defs"
|
||||
#undef GSK_GL_NO_UNIFORMS
|
||||
#undef GSK_GL_SHADER_RESOURCE
|
||||
#undef GSK_GL_SHADER_STRING
|
||||
#undef GSK_GL_SHADER_SINGLE
|
||||
#undef GSK_GL_SHADER_JOINED
|
||||
#undef GSK_GL_ADD_UNIFORM
|
||||
#undef GSK_GL_DEFINE_PROGRAM
|
||||
|
||||
@@ -289,11 +273,10 @@ gsk_gl_driver_dispose (GObject *object)
|
||||
g_assert (!self->texture_id_to_key || g_hash_table_size (self->texture_id_to_key) == 0);
|
||||
g_assert (!self->key_to_texture_id|| g_hash_table_size (self->key_to_texture_id) == 0);
|
||||
|
||||
g_clear_object (&self->glyphs);
|
||||
g_clear_object (&self->icons);
|
||||
g_clear_object (&self->shadows);
|
||||
g_clear_object (&self->glyphs_library);
|
||||
g_clear_object (&self->icons_library);
|
||||
g_clear_object (&self->shadows_library);
|
||||
|
||||
g_clear_pointer (&self->atlases, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->autorelease_framebuffers, g_array_unref);
|
||||
g_clear_pointer (&self->key_to_texture_id, g_hash_table_unref);
|
||||
g_clear_pointer (&self->textures, g_hash_table_unref);
|
||||
@@ -330,7 +313,6 @@ gsk_gl_driver_init (GskGLDriver *self)
|
||||
self->shader_cache = g_hash_table_new_full (NULL, NULL, NULL, remove_program);
|
||||
self->texture_pool = g_array_new (FALSE, FALSE, sizeof (guint));
|
||||
self->render_targets = g_ptr_array_new ();
|
||||
self->atlases = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_texture_atlas_free);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -348,14 +330,14 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
|
||||
|
||||
/* Setup preambles that are shared by all shaders */
|
||||
gsk_gl_compiler_set_preamble_from_resource (compiler,
|
||||
GSK_GL_COMPILER_ALL,
|
||||
"/org/gtk/libgsk/gl/preamble.glsl");
|
||||
GSK_GL_COMPILER_ALL,
|
||||
"/org/gtk/libgsk/gl/preamble.glsl");
|
||||
gsk_gl_compiler_set_preamble_from_resource (compiler,
|
||||
GSK_GL_COMPILER_VERTEX,
|
||||
"/org/gtk/libgsk/gl/preamble.vs.glsl");
|
||||
GSK_GL_COMPILER_VERTEX,
|
||||
"/org/gtk/libgsk/gl/preamble.vs.glsl");
|
||||
gsk_gl_compiler_set_preamble_from_resource (compiler,
|
||||
GSK_GL_COMPILER_FRAGMENT,
|
||||
"/org/gtk/libgsk/gl/preamble.fs.glsl");
|
||||
GSK_GL_COMPILER_FRAGMENT,
|
||||
"/org/gtk/libgsk/gl/preamble.fs.glsl");
|
||||
|
||||
/* Setup attributes that are provided via VBO */
|
||||
gsk_gl_compiler_bind_attribute (compiler, "aPosition", 0);
|
||||
@@ -365,10 +347,28 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
|
||||
|
||||
/* Use XMacros to register all of our programs and their uniforms */
|
||||
#define GSK_GL_NO_UNIFORMS
|
||||
#define GSK_GL_SHADER_RESOURCE(name) \
|
||||
g_resources_lookup_data("/org/gtk/libgsk/gl/" name, 0, NULL)
|
||||
#define GSK_GL_SHADER_STRING(str) \
|
||||
g_bytes_new_static(str, strlen(str))
|
||||
#define GSK_GL_SHADER_SINGLE(bytes) \
|
||||
G_STMT_START { \
|
||||
GBytes *b = bytes; \
|
||||
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_ALL, b); \
|
||||
g_bytes_unref (b); \
|
||||
} G_STMT_END;
|
||||
#define GSK_GL_SHADER_JOINED(kind, ...) \
|
||||
G_STMT_START { \
|
||||
GBytes *bytes = join_sources(__VA_ARGS__); \
|
||||
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_##kind, bytes); \
|
||||
g_bytes_unref (bytes); \
|
||||
} G_STMT_END;
|
||||
#define GSK_GL_ADD_UNIFORM(pos, KEY, name) \
|
||||
gsk_gl_program_add_uniform (program, #name, UNIFORM_##KEY);
|
||||
#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \
|
||||
gsk_gl_compiler_set_source_from_resource (compiler, GSK_GL_COMPILER_ALL, resource); \
|
||||
#define GSK_GL_DEFINE_PROGRAM(name, sources, uniforms) \
|
||||
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_VERTEX, NULL); \
|
||||
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_FRAGMENT, NULL); \
|
||||
sources \
|
||||
GSK_GL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \
|
||||
GSK_GL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \
|
||||
GSK_GL_COMPILE_PROGRAM(name, uniforms, "");
|
||||
@@ -401,6 +401,11 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
|
||||
#undef GSK_GL_DEFINE_PROGRAM_CLIP
|
||||
#undef GSK_GL_DEFINE_PROGRAM
|
||||
#undef GSK_GL_ADD_UNIFORM
|
||||
#undef GSK_GL_SHADER_SINGLE
|
||||
#undef GSK_GL_SHADER_JOINED
|
||||
#undef GSK_GL_SHADER_RESOURCE
|
||||
#undef GSK_GL_SHADER_STRING
|
||||
#undef GSK_GL_NO_UNIFORMS
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
@@ -456,9 +461,9 @@ gsk_gl_driver_new (GskGLCommandQueue *command_queue,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->glyphs = gsk_gl_glyph_library_new (self);
|
||||
self->icons = gsk_gl_icon_library_new (self);
|
||||
self->shadows = gsk_gl_shadow_library_new (self);
|
||||
self->glyphs_library = gsk_gl_glyph_library_new (self);
|
||||
self->icons_library = gsk_gl_icon_library_new (self);
|
||||
self->shadows_library = gsk_gl_shadow_library_new (self);
|
||||
|
||||
gdk_profiler_end_mark (before, "create GskGLDriver", NULL);
|
||||
|
||||
@@ -518,37 +523,6 @@ failure:
|
||||
return g_steal_pointer (&driver);
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
gsk_gl_driver_compact_atlases (GskGLDriver *self)
|
||||
{
|
||||
GPtrArray *removed = NULL;
|
||||
|
||||
g_assert (GSK_IS_GL_DRIVER (self));
|
||||
|
||||
for (guint i = self->atlases->len; i > 0; i--)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i - 1);
|
||||
|
||||
if (gsk_gl_texture_atlas_get_unused_ratio (atlas) > MAX_OLD_RATIO)
|
||||
{
|
||||
GSK_NOTE (GLYPH_CACHE,
|
||||
g_message ("Dropping atlas %d (%g.2%% old)", i,
|
||||
100.0 * gsk_gl_texture_atlas_get_unused_ratio (atlas)));
|
||||
if (removed == NULL)
|
||||
removed = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_texture_atlas_free);
|
||||
g_ptr_array_add (removed, g_ptr_array_steal_index (self->atlases, i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
GSK_NOTE (GLYPH_CACHE, {
|
||||
static guint timestamp;
|
||||
if (timestamp++ % 60 == 0)
|
||||
g_message ("%d atlases", self->atlases->len);
|
||||
});
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gl_driver_begin_frame:
|
||||
* @self: a `GskGLDriver`
|
||||
@@ -565,7 +539,6 @@ gsk_gl_driver_begin_frame (GskGLDriver *self,
|
||||
GskGLCommandQueue *command_queue)
|
||||
{
|
||||
gint64 last_frame_id;
|
||||
GPtrArray *removed;
|
||||
|
||||
g_return_if_fail (GSK_IS_GL_DRIVER (self));
|
||||
g_return_if_fail (GSK_IS_GL_COMMAND_QUEUE (command_queue));
|
||||
@@ -580,19 +553,14 @@ gsk_gl_driver_begin_frame (GskGLDriver *self,
|
||||
|
||||
gsk_gl_command_queue_begin_frame (self->command_queue);
|
||||
|
||||
/* Compact atlases with too many freed pixels */
|
||||
removed = gsk_gl_driver_compact_atlases (self);
|
||||
|
||||
/* Mark unused pixel regions of the atlases */
|
||||
gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->icons),
|
||||
self->current_frame_id,
|
||||
removed);
|
||||
gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphs),
|
||||
self->current_frame_id,
|
||||
removed);
|
||||
gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->icons_library),
|
||||
self->current_frame_id);
|
||||
gsk_gl_texture_library_begin_frame (GSK_GL_TEXTURE_LIBRARY (self->glyphs_library),
|
||||
self->current_frame_id);
|
||||
|
||||
/* Cleanup old shadows */
|
||||
gsk_gl_shadow_library_begin_frame (self->shadows);
|
||||
gsk_gl_shadow_library_begin_frame (self->shadows_library);
|
||||
|
||||
/* Remove all textures that are from a previous frame or are no
|
||||
* longer used by linked GdkTexture. We do this at the beginning
|
||||
@@ -600,9 +568,6 @@ gsk_gl_driver_begin_frame (GskGLDriver *self,
|
||||
* we block on any resources while delivering our frames.
|
||||
*/
|
||||
gsk_gl_driver_collect_unused_textures (self, last_frame_id - 1);
|
||||
|
||||
/* Now free atlas textures */
|
||||
g_clear_pointer (&removed, g_ptr_array_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1182,14 +1147,23 @@ void
|
||||
gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
|
||||
const char *directory)
|
||||
{
|
||||
GPtrArray *atlases;
|
||||
|
||||
g_return_if_fail (GSK_IS_GL_DRIVER (self));
|
||||
|
||||
if (directory == NULL)
|
||||
directory = ".";
|
||||
|
||||
for (guint i = 0; i < self->atlases->len; i++)
|
||||
#define copy_atlases(dst, library) \
|
||||
g_ptr_array_extend(dst, GSK_GL_TEXTURE_LIBRARY(library)->atlases, NULL, NULL)
|
||||
atlases = g_ptr_array_new ();
|
||||
copy_atlases (atlases, self->glyphs_library);
|
||||
copy_atlases (atlases, self->icons_library);
|
||||
#undef copy_atlases
|
||||
|
||||
for (guint i = 0; i < atlases->len; i++)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i);
|
||||
GskGLTextureAtlas *atlas = g_ptr_array_index (atlases, i);
|
||||
char *filename = g_strdup_printf ("%s%sframe-%d-atlas-%d.png",
|
||||
directory,
|
||||
G_DIR_SEPARATOR_S,
|
||||
@@ -1198,6 +1172,8 @@ gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
|
||||
write_atlas_to_png (self, atlas, filename);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
g_ptr_array_unref (atlases);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -100,17 +100,15 @@ struct _GskGLDriver
|
||||
GskGLCommandQueue *shared_command_queue;
|
||||
GskGLCommandQueue *command_queue;
|
||||
|
||||
GskGLGlyphLibrary *glyphs;
|
||||
GskGLIconLibrary *icons;
|
||||
GskGLShadowLibrary *shadows;
|
||||
GskGLGlyphLibrary *glyphs_library;
|
||||
GskGLIconLibrary *icons_library;
|
||||
GskGLShadowLibrary *shadows_library;
|
||||
|
||||
GArray *texture_pool;
|
||||
GHashTable *textures;
|
||||
GHashTable *key_to_texture_id;
|
||||
GHashTable *texture_id_to_key;
|
||||
|
||||
GPtrArray *atlases;
|
||||
|
||||
GHashTable *shader_cache;
|
||||
|
||||
GArray *autorelease_framebuffers;
|
||||
@@ -184,7 +182,6 @@ void gsk_gl_driver_add_texture_slices (GskGLDriver *s
|
||||
GskGLProgram * gsk_gl_driver_lookup_shader (GskGLDriver *self,
|
||||
GskGLShader *shader,
|
||||
GError **error);
|
||||
GskGLTextureAtlas * gsk_gl_driver_create_atlas (GskGLDriver *self);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
|
||||
|
||||
@@ -84,15 +84,64 @@ gsk_gl_glyph_value_free (gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyph_library_begin_frame (GskGLTextureLibrary *library,
|
||||
gint64 frame_id,
|
||||
GPtrArray *removed_atlases)
|
||||
gsk_gl_glyph_library_clear_cache (GskGLTextureLibrary *library)
|
||||
{
|
||||
GskGLGlyphLibrary *self = (GskGLGlyphLibrary *)library;
|
||||
|
||||
g_assert (GSK_IS_GL_GLYPH_LIBRARY (self));
|
||||
|
||||
memset (self->front, 0, sizeof self->front);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self,
|
||||
GskGLTextureAtlas *atlas)
|
||||
{
|
||||
gboolean packed G_GNUC_UNUSED;
|
||||
int x, y;
|
||||
guint gl_format;
|
||||
guint gl_type;
|
||||
guint8 pixel_data[4 * 3 * 3];
|
||||
|
||||
g_assert (GSK_IS_GL_GLYPH_LIBRARY (self));
|
||||
g_assert (atlas != NULL);
|
||||
|
||||
/* Insert a single pixel at 0,0 for use in coloring */
|
||||
|
||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||
"Initializing Atlas");
|
||||
|
||||
packed = gsk_gl_texture_library_allocate (self, atlas, 3, 3, &x, &y);
|
||||
g_assert (packed);
|
||||
g_assert (x == 0 && y == 0);
|
||||
|
||||
memset (pixel_data, 255, sizeof pixel_data);
|
||||
|
||||
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
||||
{
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
||||
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
0, 0,
|
||||
3, 3,
|
||||
gl_format, gl_type,
|
||||
pixel_data);
|
||||
|
||||
gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
|
||||
|
||||
self->driver->command_queue->n_uploads++;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gsk_gl_glyph_library_finalize (GObject *object)
|
||||
{
|
||||
@@ -111,7 +160,8 @@ gsk_gl_glyph_library_class_init (GskGLGlyphLibraryClass *klass)
|
||||
|
||||
object_class->finalize = gsk_gl_glyph_library_finalize;
|
||||
|
||||
library_class->begin_frame = gsk_gl_glyph_library_begin_frame;
|
||||
library_class->clear_cache = gsk_gl_glyph_library_clear_cache;
|
||||
library_class->init_atlas = gsk_gl_glyph_library_init_atlas;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1,71 +1,71 @@
|
||||
GSK_GL_DEFINE_PROGRAM (blend,
|
||||
"/org/gtk/libgsk/gl/blend.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blend.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, BLEND_SOURCE2, u_source2)
|
||||
GSK_GL_ADD_UNIFORM (2, BLEND_MODE, u_mode))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (blit,
|
||||
"/org/gtk/libgsk/gl/blit.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blit.glsl")),
|
||||
GSK_GL_NO_UNIFORMS)
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (blur,
|
||||
"/org/gtk/libgsk/gl/blur.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("blur.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, BLUR_RADIUS, u_blur_radius)
|
||||
GSK_GL_ADD_UNIFORM (2, BLUR_SIZE, u_blur_size)
|
||||
GSK_GL_ADD_UNIFORM (3, BLUR_DIR, u_blur_dir))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (border,
|
||||
"/org/gtk/libgsk/gl/border.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("border.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, BORDER_WIDTHS, u_widths)
|
||||
GSK_GL_ADD_UNIFORM (2, BORDER_OUTLINE_RECT, u_outline_rect))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (color,
|
||||
"/org/gtk/libgsk/gl/color.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("color.glsl")),
|
||||
GSK_GL_NO_UNIFORMS)
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (coloring,
|
||||
"/org/gtk/libgsk/gl/coloring.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("coloring.glsl")),
|
||||
GSK_GL_NO_UNIFORMS)
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (color_matrix,
|
||||
"/org/gtk/libgsk/gl/color_matrix.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("color_matrix.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, COLOR_MATRIX_COLOR_MATRIX, u_color_matrix)
|
||||
GSK_GL_ADD_UNIFORM (2, COLOR_MATRIX_COLOR_OFFSET, u_color_offset))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (conic_gradient,
|
||||
"/org/gtk/libgsk/gl/conic_gradient.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("conic_gradient.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, CONIC_GRADIENT_COLOR_STOPS, u_color_stops)
|
||||
GSK_GL_ADD_UNIFORM (2, CONIC_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
||||
GSK_GL_ADD_UNIFORM (3, CONIC_GRADIENT_GEOMETRY, u_geometry))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (cross_fade,
|
||||
"/org/gtk/libgsk/gl/cross_fade.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("cross_fade.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, CROSS_FADE_PROGRESS, u_progress)
|
||||
GSK_GL_ADD_UNIFORM (2, CROSS_FADE_SOURCE2, u_source2))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (filled_border,
|
||||
"/org/gtk/libgsk/gl/filled_border.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("filled_border.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, FILLED_BORDER_WIDTHS, u_widths)
|
||||
GSK_GL_ADD_UNIFORM (2, FILLED_BORDER_OUTLINE_RECT, u_outline_rect))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (inset_shadow,
|
||||
"/org/gtk/libgsk/gl/inset_shadow.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("inset_shadow.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, INSET_SHADOW_SPREAD, u_spread)
|
||||
GSK_GL_ADD_UNIFORM (2, INSET_SHADOW_OFFSET, u_offset)
|
||||
GSK_GL_ADD_UNIFORM (3, INSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (linear_gradient,
|
||||
"/org/gtk/libgsk/gl/linear_gradient.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("linear_gradient.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, LINEAR_GRADIENT_COLOR_STOPS, u_color_stops)
|
||||
GSK_GL_ADD_UNIFORM (2, LINEAR_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
||||
GSK_GL_ADD_UNIFORM (3, LINEAR_GRADIENT_POINTS, u_points)
|
||||
GSK_GL_ADD_UNIFORM (4, LINEAR_GRADIENT_REPEAT, u_repeat))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (outset_shadow,
|
||||
"/org/gtk/libgsk/gl/outset_shadow.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("outset_shadow.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (radial_gradient,
|
||||
"/org/gtk/libgsk/gl/radial_gradient.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("radial_gradient.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, RADIAL_GRADIENT_COLOR_STOPS, u_color_stops)
|
||||
GSK_GL_ADD_UNIFORM (2, RADIAL_GRADIENT_NUM_COLOR_STOPS, u_num_color_stops)
|
||||
GSK_GL_ADD_UNIFORM (3, RADIAL_GRADIENT_REPEAT, u_repeat)
|
||||
@@ -73,12 +73,12 @@ GSK_GL_DEFINE_PROGRAM (radial_gradient,
|
||||
GSK_GL_ADD_UNIFORM (5, RADIAL_GRADIENT_GEOMETRY, u_geometry))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (repeat,
|
||||
"/org/gtk/libgsk/gl/repeat.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("repeat.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, REPEAT_CHILD_BOUNDS, u_child_bounds)
|
||||
GSK_GL_ADD_UNIFORM (2, REPEAT_TEXTURE_RECT, u_texture_rect))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow,
|
||||
"/org/gtk/libgsk/gl/unblurred_outset_shadow.glsl",
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("unblurred_outset_shadow.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread)
|
||||
GSK_GL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset)
|
||||
GSK_GL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
||||
|
||||
@@ -2512,7 +2512,9 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
|
||||
scaled_outline.corner[i].height *= scale_y;
|
||||
}
|
||||
|
||||
cached_tid = gsk_gl_shadow_library_lookup (job->driver->shadows, &scaled_outline, blur_radius);
|
||||
cached_tid = gsk_gl_shadow_library_lookup (job->driver->shadows_library,
|
||||
&scaled_outline,
|
||||
blur_radius);
|
||||
|
||||
if (cached_tid == 0)
|
||||
{
|
||||
@@ -2574,7 +2576,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
|
||||
blur_radius * scale_x,
|
||||
blur_radius * scale_y);
|
||||
|
||||
gsk_gl_shadow_library_insert (job->driver->shadows,
|
||||
gsk_gl_shadow_library_insert (job->driver->shadows_library,
|
||||
&scaled_outline,
|
||||
blur_radius,
|
||||
blurred_texture_id);
|
||||
@@ -2858,58 +2860,6 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_non_branching (const GskRenderNode *node)
|
||||
{
|
||||
switch ((int)gsk_render_node_get_node_type (node))
|
||||
{
|
||||
case GSK_COLOR_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
case GSK_RADIAL_GRADIENT_NODE:
|
||||
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
||||
case GSK_CONIC_GRADIENT_NODE:
|
||||
case GSK_BORDER_NODE:
|
||||
case GSK_TEXTURE_NODE:
|
||||
case GSK_INSET_SHADOW_NODE:
|
||||
case GSK_OUTSET_SHADOW_NODE:
|
||||
case GSK_TEXT_NODE:
|
||||
case GSK_CAIRO_NODE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_TRANSFORM_NODE:
|
||||
return is_non_branching (gsk_transform_node_get_child (node));
|
||||
|
||||
case GSK_OPACITY_NODE:
|
||||
return is_non_branching (gsk_opacity_node_get_child (node));
|
||||
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
return is_non_branching (gsk_color_matrix_node_get_child (node));
|
||||
|
||||
case GSK_CLIP_NODE:
|
||||
return is_non_branching (gsk_clip_node_get_child (node));
|
||||
|
||||
case GSK_ROUNDED_CLIP_NODE:
|
||||
return is_non_branching (gsk_rounded_clip_node_get_child (node));
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
return is_non_branching (gsk_shadow_node_get_child (node));
|
||||
|
||||
case GSK_BLUR_NODE:
|
||||
return is_non_branching (gsk_shadow_node_get_child (node));
|
||||
|
||||
case GSK_DEBUG_NODE:
|
||||
return is_non_branching (gsk_debug_node_get_child (node));
|
||||
|
||||
case GSK_CONTAINER_NODE:
|
||||
return gsk_container_node_get_n_children (node) == 1 &&
|
||||
is_non_branching (gsk_container_node_get_child (node, 0));
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_opacity_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
@@ -2922,11 +2872,7 @@ gsk_gl_render_job_visit_opacity_node (GskGLRenderJob *job,
|
||||
{
|
||||
float prev_alpha = gsk_gl_render_job_set_alpha (job, new_alpha);
|
||||
|
||||
/* Handle a few easy cases without offscreen. We bail out
|
||||
* as soon as we see nodes with multiple children - in theory,
|
||||
* we would only need offscreens for overlapping children.
|
||||
*/
|
||||
if (is_non_branching (child))
|
||||
if (!gsk_render_node_use_offscreen_for_opacity (child))
|
||||
{
|
||||
gsk_gl_render_job_visit_node (job, child);
|
||||
gsk_gl_render_job_set_alpha (job, prev_alpha);
|
||||
@@ -2996,7 +2942,7 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
|
||||
guint num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
float x = offset->x + job->offset_x;
|
||||
float y = offset->y + job->offset_y;
|
||||
GskGLGlyphLibrary *library = job->driver->glyphs;
|
||||
GskGLGlyphLibrary *library = job->driver->glyphs_library;
|
||||
GskGLCommandBatch *batch;
|
||||
int x_position = 0;
|
||||
GskGLGlyphKey lookup;
|
||||
@@ -3499,14 +3445,14 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
GdkTexture *texture,
|
||||
GskGLRenderOffscreen *offscreen)
|
||||
{
|
||||
if (gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons,
|
||||
if (gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
|
||||
texture->width,
|
||||
texture->height) &&
|
||||
!GDK_IS_GL_TEXTURE (texture))
|
||||
{
|
||||
const GskGLIconData *icon_data;
|
||||
|
||||
gsk_gl_icon_library_lookup_or_add (job->driver->icons, texture, &icon_data);
|
||||
gsk_gl_icon_library_lookup_or_add (job->driver->icons_library, texture, &icon_data);
|
||||
offscreen->texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data);
|
||||
memcpy (&offscreen->area, &icon_data->entry.area, sizeof offscreen->area);
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
|
||||
struct _GskGLShadowLibrary
|
||||
{
|
||||
GObject parent_instance;
|
||||
GObject parent_instance;
|
||||
GskGLDriver *driver;
|
||||
GArray *shadows;
|
||||
GArray *shadows;
|
||||
};
|
||||
|
||||
typedef struct _Shadow
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
#include "gskgldriverprivate.h"
|
||||
#include "gskgltexturelibraryprivate.h"
|
||||
|
||||
#define MAX_FRAME_AGE 60
|
||||
#define DEFAULT_MAX_FRAME_AGE 60
|
||||
#define DEFAULT_ATLAS_WIDTH 512
|
||||
#define DEFAULT_ATLAS_HEIGHT 512
|
||||
#define MAX_OLD_RATIO 0.5
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GskGLTextureLibrary, gsk_gl_texture_library, G_TYPE_OBJECT)
|
||||
|
||||
@@ -39,6 +42,149 @@ enum {
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
gsk_gl_texture_atlas_free (GskGLTextureAtlas *atlas)
|
||||
{
|
||||
if (atlas->texture_id != 0)
|
||||
{
|
||||
glDeleteTextures (1, &atlas->texture_id);
|
||||
atlas->texture_id = 0;
|
||||
}
|
||||
|
||||
g_clear_pointer (&atlas->nodes, g_free);
|
||||
g_slice_free (GskGLTextureAtlas, atlas);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gl_texture_library_real_compact (GskGLTextureLibrary *self,
|
||||
gint64 frame_id)
|
||||
{
|
||||
GPtrArray *removed = NULL;
|
||||
gboolean ret = FALSE;
|
||||
gboolean periodic_scan;
|
||||
|
||||
g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||
|
||||
periodic_scan = (self->max_frame_age > 0 &&
|
||||
(frame_id % self->max_frame_age) == 0);
|
||||
|
||||
for (guint i = self->atlases->len; i > 0; i--)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i - 1);
|
||||
|
||||
if (gsk_gl_texture_atlas_get_unused_ratio (atlas) > MAX_OLD_RATIO)
|
||||
{
|
||||
GSK_NOTE (GLYPH_CACHE,
|
||||
g_message ("Dropping atlas %d (%g.2%% old)", i,
|
||||
100.0 * gsk_gl_texture_atlas_get_unused_ratio (atlas)));
|
||||
if (removed == NULL)
|
||||
removed = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_texture_atlas_free);
|
||||
g_ptr_array_add (removed, g_ptr_array_steal_index (self->atlases, i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (periodic_scan || removed != NULL)
|
||||
{
|
||||
GskGLTextureAtlasEntry *entry;
|
||||
GHashTableIter iter;
|
||||
guint dropped = 0;
|
||||
guint atlased = 0;
|
||||
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&entry))
|
||||
{
|
||||
if (entry->is_atlased)
|
||||
{
|
||||
if (removed && g_ptr_array_find (removed, entry->atlas, NULL))
|
||||
{
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
}
|
||||
else if (periodic_scan)
|
||||
{
|
||||
gsk_gl_texture_atlas_entry_mark_unused (entry);
|
||||
entry->accessed = FALSE;
|
||||
if (entry->is_atlased)
|
||||
atlased++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!entry->accessed)
|
||||
{
|
||||
gsk_gl_driver_release_texture (self->driver, entry->texture);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
}
|
||||
|
||||
if (periodic_scan)
|
||||
entry->accessed = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
GSK_NOTE (GLYPH_CACHE, g_message ("%s: Dropped %d individual items",
|
||||
G_OBJECT_TYPE_NAME (self),
|
||||
dropped);
|
||||
g_message ("%s: %d items cached (%d atlased, %d individually)",
|
||||
G_OBJECT_TYPE_NAME (self),
|
||||
g_hash_table_size (self->hash_table),
|
||||
atlased,
|
||||
g_hash_table_size (self->hash_table) - atlased));
|
||||
|
||||
if (dropped > 0)
|
||||
gsk_gl_texture_library_clear_cache (self);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
g_clear_pointer (&removed, g_ptr_array_unref);
|
||||
}
|
||||
|
||||
GSK_NOTE (GLYPH_CACHE, {
|
||||
static gint64 last_message;
|
||||
gint64 now = g_get_monotonic_time ();
|
||||
if (now - last_message > G_USEC_PER_SEC)
|
||||
{
|
||||
last_message = now;
|
||||
g_message ("%s contains %d atlases",
|
||||
G_OBJECT_TYPE_NAME (self),
|
||||
self->atlases->len);
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gl_texture_library_real_allocate (GskGLTextureLibrary *self,
|
||||
GskGLTextureAtlas *atlas,
|
||||
int width,
|
||||
int height,
|
||||
int *out_x,
|
||||
int *out_y)
|
||||
{
|
||||
stbrp_rect rect;
|
||||
|
||||
g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||
g_assert (atlas != NULL);
|
||||
g_assert (width > 0);
|
||||
g_assert (height > 0);
|
||||
g_assert (out_x != NULL);
|
||||
g_assert (out_y != NULL);
|
||||
|
||||
rect.w = width;
|
||||
rect.h = height;
|
||||
|
||||
stbrp_pack_rects (&atlas->context, &rect, 1);
|
||||
|
||||
if (rect.was_packed)
|
||||
{
|
||||
*out_x = rect.x;
|
||||
*out_y = rect.y;
|
||||
}
|
||||
|
||||
return rect.was_packed;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_texture_library_constructed (GObject *object)
|
||||
{
|
||||
@@ -52,6 +198,7 @@ gsk_gl_texture_library_dispose (GObject *object)
|
||||
{
|
||||
GskGLTextureLibrary *self = (GskGLTextureLibrary *)object;
|
||||
|
||||
g_clear_pointer (&self->atlases, g_ptr_array_unref);
|
||||
g_clear_object (&self->driver);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gl_texture_library_parent_class)->dispose (object);
|
||||
@@ -105,6 +252,9 @@ gsk_gl_texture_library_class_init (GskGLTextureLibraryClass *klass)
|
||||
object_class->get_property = gsk_gl_texture_library_get_property;
|
||||
object_class->set_property = gsk_gl_texture_library_set_property;
|
||||
|
||||
klass->compact = gsk_gl_texture_library_real_compact;
|
||||
klass->allocate = gsk_gl_texture_library_real_allocate;
|
||||
|
||||
properties [PROP_DRIVER] =
|
||||
g_param_spec_object ("driver",
|
||||
"Driver",
|
||||
@@ -118,6 +268,10 @@ gsk_gl_texture_library_class_init (GskGLTextureLibraryClass *klass)
|
||||
static void
|
||||
gsk_gl_texture_library_init (GskGLTextureLibrary *self)
|
||||
{
|
||||
self->max_frame_age = DEFAULT_MAX_FRAME_AGE;
|
||||
self->atlas_width = DEFAULT_ATLAS_WIDTH;
|
||||
self->atlas_height = DEFAULT_ATLAS_HEIGHT;
|
||||
self->atlases = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_gl_texture_atlas_free);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -136,78 +290,14 @@ gsk_gl_texture_library_set_funcs (GskGLTextureLibrary *self,
|
||||
|
||||
void
|
||||
gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self,
|
||||
gint64 frame_id,
|
||||
GPtrArray *removed_atlases)
|
||||
gint64 frame_id)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
|
||||
g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||
|
||||
gsk_gl_texture_library_compact (self, frame_id);
|
||||
|
||||
if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame)
|
||||
GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame (self, frame_id, removed_atlases);
|
||||
|
||||
if (removed_atlases != NULL)
|
||||
{
|
||||
GskGLTextureAtlasEntry *entry;
|
||||
guint dropped = 0;
|
||||
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&entry))
|
||||
{
|
||||
if (entry->is_atlased)
|
||||
{
|
||||
for (guint i = 0; i < removed_atlases->len; i++)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = g_ptr_array_index (removed_atlases, i);
|
||||
|
||||
if (atlas == entry->atlas)
|
||||
{
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSK_NOTE (GLYPH_CACHE,
|
||||
if (dropped > 0)
|
||||
g_message ("%s: Dropped %d items",
|
||||
G_OBJECT_TYPE_NAME (self), dropped));
|
||||
}
|
||||
|
||||
if (frame_id % MAX_FRAME_AGE == 0)
|
||||
{
|
||||
GskGLTextureAtlasEntry *entry;
|
||||
int atlased = 0;
|
||||
int dropped = 0;
|
||||
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&entry))
|
||||
{
|
||||
if (!entry->is_atlased && !entry->accessed)
|
||||
{
|
||||
gsk_gl_driver_release_texture (self->driver, entry->texture);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
gsk_gl_texture_atlas_entry_mark_unused (entry);
|
||||
entry->accessed = FALSE;
|
||||
if (entry->is_atlased)
|
||||
atlased++;
|
||||
}
|
||||
|
||||
GSK_NOTE (GLYPH_CACHE, g_message ("%s: Dropped %d individual items",
|
||||
G_OBJECT_TYPE_NAME (self),
|
||||
dropped);
|
||||
g_message ("%s: %d items cached (%d atlased, %d individually)",
|
||||
G_OBJECT_TYPE_NAME (self),
|
||||
g_hash_table_size (self->hash_table),
|
||||
atlased,
|
||||
g_hash_table_size (self->hash_table) - atlased));
|
||||
}
|
||||
GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->begin_frame (self, frame_id);
|
||||
}
|
||||
|
||||
static GskGLTexture *
|
||||
@@ -234,90 +324,29 @@ gsk_gl_texture_library_pack_one (GskGLTextureLibrary *self,
|
||||
return texture;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_gl_texture_atlas_pack (GskGLTextureAtlas *self,
|
||||
int width,
|
||||
int height,
|
||||
int *out_x,
|
||||
int *out_y)
|
||||
{
|
||||
stbrp_rect rect;
|
||||
|
||||
rect.w = width;
|
||||
rect.h = height;
|
||||
|
||||
stbrp_pack_rects (&self->context, &rect, 1);
|
||||
|
||||
if (rect.was_packed)
|
||||
{
|
||||
*out_x = rect.x;
|
||||
*out_y = rect.y;
|
||||
}
|
||||
|
||||
return rect.was_packed;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_texture_atlas_initialize (GskGLDriver *driver,
|
||||
GskGLTextureAtlas *atlas)
|
||||
{
|
||||
/* Insert a single pixel at 0,0 for use in coloring */
|
||||
|
||||
gboolean packed G_GNUC_UNUSED;
|
||||
int x, y;
|
||||
guint gl_format;
|
||||
guint gl_type;
|
||||
guint8 pixel_data[4 * 3 * 3];
|
||||
|
||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||
"Initializing Atlas");
|
||||
|
||||
packed = gsk_gl_texture_atlas_pack (atlas, 3, 3, &x, &y);
|
||||
g_assert (packed);
|
||||
g_assert (x == 0 && y == 0);
|
||||
|
||||
memset (pixel_data, 255, sizeof pixel_data);
|
||||
|
||||
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
||||
{
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
||||
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
0, 0,
|
||||
3, 3,
|
||||
gl_format, gl_type,
|
||||
pixel_data);
|
||||
|
||||
gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
|
||||
|
||||
driver->command_queue->n_uploads++;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_texture_atlases_pack (GskGLDriver *driver,
|
||||
int width,
|
||||
int height,
|
||||
GskGLTextureAtlas **out_atlas,
|
||||
int *out_x,
|
||||
int *out_y)
|
||||
gsk_gl_texture_library_pack_any_atlas (GskGLTextureLibrary *self,
|
||||
int width,
|
||||
int height,
|
||||
GskGLTextureAtlas **out_atlas,
|
||||
int *out_x,
|
||||
int *out_y)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = NULL;
|
||||
int x, y;
|
||||
|
||||
for (guint i = 0; i < driver->atlases->len; i++)
|
||||
{
|
||||
atlas = g_ptr_array_index (driver->atlases, i);
|
||||
g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||
g_assert (width > 0);
|
||||
g_assert (height > 0);
|
||||
g_assert (out_atlas != NULL);
|
||||
g_assert (out_x != NULL);
|
||||
g_assert (out_y != NULL);
|
||||
|
||||
if (gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
|
||||
for (guint i = 0; i < self->atlases->len; i++)
|
||||
{
|
||||
atlas = g_ptr_array_index (self->atlases, i);
|
||||
|
||||
if (gsk_gl_texture_library_allocate (self, atlas, width, height, &x, &y))
|
||||
break;
|
||||
|
||||
atlas = NULL;
|
||||
@@ -326,12 +355,10 @@ gsk_gl_texture_atlases_pack (GskGLDriver *driver,
|
||||
if (atlas == NULL)
|
||||
{
|
||||
/* No atlas has enough space, so create a new one... */
|
||||
atlas = gsk_gl_driver_create_atlas (driver);
|
||||
|
||||
gsk_gl_texture_atlas_initialize (driver, atlas);
|
||||
atlas = gsk_gl_texture_library_acquire_atlas (self);
|
||||
|
||||
/* Pack it onto that one, which surely has enough space... */
|
||||
if (!gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
|
||||
if (!gsk_gl_texture_library_allocate (self, atlas, width, height, &x, &y))
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
@@ -380,17 +407,19 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
|
||||
*out_packed_x = 0;
|
||||
*out_packed_y = 0;
|
||||
}
|
||||
else if (width <= self->max_entry_size && height <= self->max_entry_size)
|
||||
else if (self->max_entry_size == 0 ||
|
||||
(width <= self->max_entry_size &&
|
||||
height <= self->max_entry_size))
|
||||
{
|
||||
int packed_x;
|
||||
int packed_y;
|
||||
|
||||
gsk_gl_texture_atlases_pack (self->driver,
|
||||
padding + width + padding,
|
||||
padding + height + padding,
|
||||
&atlas,
|
||||
&packed_x,
|
||||
&packed_y);
|
||||
gsk_gl_texture_library_pack_any_atlas (self,
|
||||
padding + width + padding,
|
||||
padding + height + padding,
|
||||
&atlas,
|
||||
&packed_x,
|
||||
&packed_y);
|
||||
|
||||
entry->atlas = atlas;
|
||||
entry->is_atlased = TRUE;
|
||||
@@ -424,3 +453,134 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* gsk_gl_texture_library_clear_cache:
|
||||
*
|
||||
* Clear the front cache if the texture library is using one. For
|
||||
* example the glyph cache would drop it's front cache to force
|
||||
* next lookups to fall through to the GHashTable key lookup.
|
||||
*/
|
||||
void
|
||||
gsk_gl_texture_library_clear_cache (GskGLTextureLibrary *self)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||
|
||||
if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->clear_cache)
|
||||
GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->clear_cache (self);
|
||||
}
|
||||
|
||||
/*
|
||||
* gsk_gl_texture_library_compact:
|
||||
*
|
||||
* Requests that the texture library compact it's altases. That
|
||||
* generally means to traverse them to look for unused pixels over
|
||||
* a certain threshold and release them if necessary.
|
||||
*
|
||||
* Returns: %TRUE if any compaction occurred.
|
||||
*/
|
||||
gboolean
|
||||
gsk_gl_texture_library_compact (GskGLTextureLibrary *self,
|
||||
gint64 frame_id)
|
||||
{
|
||||
g_return_val_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self), FALSE);
|
||||
|
||||
if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->compact)
|
||||
return GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->compact (self, frame_id);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_texture_library_reset (GskGLTextureLibrary *self)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||
|
||||
gsk_gl_texture_library_clear_cache (self);
|
||||
|
||||
g_hash_table_remove_all (self->hash_table);
|
||||
|
||||
if (self->atlases->len)
|
||||
g_ptr_array_remove_range (self->atlases, 0, self->atlases->len);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_texture_library_set_atlas_size (GskGLTextureLibrary *self,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||
|
||||
if (width <= 0)
|
||||
width = DEFAULT_ATLAS_WIDTH;
|
||||
|
||||
if (height <= 0)
|
||||
height = DEFAULT_ATLAS_HEIGHT;
|
||||
|
||||
self->atlas_height = height;
|
||||
self->atlas_width = width;
|
||||
|
||||
gsk_gl_texture_library_reset (self);
|
||||
}
|
||||
|
||||
/*
|
||||
* gsk_gl_texture_library_acquire_atlas:
|
||||
*
|
||||
* Allocates a new texture atlas based on the current size
|
||||
* and format requirements.
|
||||
*/
|
||||
GskGLTextureAtlas *
|
||||
gsk_gl_texture_library_acquire_atlas (GskGLTextureLibrary *self)
|
||||
{
|
||||
GskGLTextureAtlas *atlas;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_TEXTURE_LIBRARY (self), NULL);
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self->driver), NULL);
|
||||
g_return_val_if_fail (GSK_IS_GL_COMMAND_QUEUE (self->driver->command_queue), NULL);
|
||||
g_return_val_if_fail (self->atlas_width > 0, NULL);
|
||||
g_return_val_if_fail (self->atlas_height > 0, NULL);
|
||||
|
||||
atlas = g_slice_new0 (GskGLTextureAtlas);
|
||||
atlas->width = self->atlas_width;
|
||||
atlas->height = self->atlas_height;
|
||||
/* TODO: We might want to change the strategy about the amount of
|
||||
* nodes here? stb_rect_pack.h says width is optimal. */
|
||||
atlas->nodes = g_malloc0_n (atlas->width, sizeof (struct stbrp_node));
|
||||
stbrp_init_target (&atlas->context, atlas->width, atlas->height, atlas->nodes, atlas->width);
|
||||
atlas->texture_id = gsk_gl_command_queue_create_texture (self->driver->command_queue,
|
||||
atlas->width,
|
||||
atlas->height,
|
||||
GL_RGBA8,
|
||||
GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
|
||||
gdk_gl_context_label_object_printf (gdk_gl_context_get_current (),
|
||||
GL_TEXTURE, atlas->texture_id,
|
||||
"Texture atlas %d",
|
||||
atlas->texture_id);
|
||||
|
||||
g_ptr_array_add (self->atlases, atlas);
|
||||
|
||||
if (GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->init_atlas)
|
||||
GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->init_atlas (self, atlas);
|
||||
|
||||
return atlas;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_gl_texture_library_allocate (GskGLTextureLibrary *self,
|
||||
GskGLTextureAtlas *atlas,
|
||||
int width,
|
||||
int height,
|
||||
int *out_x,
|
||||
int *out_y)
|
||||
{
|
||||
g_assert (GSK_IS_GL_TEXTURE_LIBRARY (self));
|
||||
g_assert (atlas != NULL);
|
||||
g_assert (width > 0);
|
||||
g_assert (height > 0);
|
||||
g_assert (out_x != NULL);
|
||||
g_assert (out_y != NULL);
|
||||
|
||||
return GSK_GL_TEXTURE_LIBRARY_GET_CLASS (self)->allocate (self, atlas, width, height, out_x, out_y);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ typedef struct _GskGLTextureAtlas
|
||||
*/
|
||||
int unused_pixels;
|
||||
|
||||
void *user_data;
|
||||
} GskGLTextureAtlas;
|
||||
|
||||
typedef struct _GskGLTextureAtlasEntry
|
||||
@@ -89,40 +88,67 @@ typedef struct _GskGLTextureAtlasEntry
|
||||
|
||||
typedef struct _GskGLTextureLibrary
|
||||
{
|
||||
GObject parent_instance;
|
||||
GObject parent_instance;
|
||||
GskGLDriver *driver;
|
||||
GHashTable *hash_table;
|
||||
guint max_entry_size;
|
||||
GPtrArray *atlases;
|
||||
GHashTable *hash_table;
|
||||
guint max_entry_size;
|
||||
guint max_frame_age;
|
||||
guint atlas_width;
|
||||
guint atlas_height;
|
||||
} GskGLTextureLibrary;
|
||||
|
||||
typedef struct _GskGLTextureLibraryClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*begin_frame) (GskGLTextureLibrary *library,
|
||||
gint64 frame_id,
|
||||
GPtrArray *removed_atlases);
|
||||
void (*begin_frame) (GskGLTextureLibrary *library,
|
||||
gint64 frame_id);
|
||||
gboolean (*compact) (GskGLTextureLibrary *library,
|
||||
gint64 frame_id);
|
||||
void (*clear_cache) (GskGLTextureLibrary *library);
|
||||
void (*init_atlas) (GskGLTextureLibrary *library,
|
||||
GskGLTextureAtlas *atlas);
|
||||
gboolean (*allocate) (GskGLTextureLibrary *library,
|
||||
GskGLTextureAtlas *atlas,
|
||||
int width,
|
||||
int height,
|
||||
int *out_x,
|
||||
int *out_y);
|
||||
} GskGLTextureLibraryClass;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GskGLTextureLibrary, g_object_unref)
|
||||
|
||||
GType gsk_gl_texture_library_get_type (void) G_GNUC_CONST;
|
||||
void gsk_gl_texture_library_set_funcs (GskGLTextureLibrary *self,
|
||||
GHashFunc hash_func,
|
||||
GEqualFunc equal_func,
|
||||
GDestroyNotify key_destroy,
|
||||
GDestroyNotify value_destroy);
|
||||
void gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self,
|
||||
gint64 frame_id,
|
||||
GPtrArray *removed_atlases);
|
||||
gpointer gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
|
||||
gpointer key,
|
||||
gsize valuelen,
|
||||
guint width,
|
||||
guint height,
|
||||
int padding,
|
||||
guint *out_packed_x,
|
||||
guint *out_packed_y);
|
||||
GType gsk_gl_texture_library_get_type (void) G_GNUC_CONST;
|
||||
gboolean gsk_gl_texture_library_compact (GskGLTextureLibrary *self,
|
||||
gint64 frame_id);
|
||||
void gsk_gl_texture_library_clear_cache (GskGLTextureLibrary *self);
|
||||
void gsk_gl_texture_library_reset (GskGLTextureLibrary *self);
|
||||
void gsk_gl_texture_library_set_atlas_size (GskGLTextureLibrary *self,
|
||||
int width,
|
||||
int height);
|
||||
GskGLTextureAtlas *gsk_gl_texture_library_acquire_atlas (GskGLTextureLibrary *self);
|
||||
void gsk_gl_texture_library_set_funcs (GskGLTextureLibrary *self,
|
||||
GHashFunc hash_func,
|
||||
GEqualFunc equal_func,
|
||||
GDestroyNotify key_destroy,
|
||||
GDestroyNotify value_destroy);
|
||||
void gsk_gl_texture_library_begin_frame (GskGLTextureLibrary *self,
|
||||
gint64 frame_id);
|
||||
gboolean gsk_gl_texture_library_allocate (GskGLTextureLibrary *self,
|
||||
GskGLTextureAtlas *atlas,
|
||||
int width,
|
||||
int height,
|
||||
int *out_x,
|
||||
int *out_y);
|
||||
gpointer gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
|
||||
gpointer key,
|
||||
gsize valuelen,
|
||||
guint width,
|
||||
guint height,
|
||||
int padding,
|
||||
guint *out_packed_x,
|
||||
guint *out_packed_y);
|
||||
|
||||
static inline void
|
||||
gsk_gl_texture_atlas_mark_unused (GskGLTextureAtlas *self,
|
||||
|
||||
@@ -58,14 +58,14 @@ value_render_node_init (GValue *value)
|
||||
{
|
||||
value->data[0].v_pointer = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
value_render_node_free_value (GValue *value)
|
||||
{
|
||||
if (value->data[0].v_pointer != NULL)
|
||||
gsk_render_node_unref (value->data[0].v_pointer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
value_render_node_copy_value (const GValue *src,
|
||||
GValue *dst)
|
||||
@@ -75,7 +75,7 @@ value_render_node_copy_value (const GValue *src,
|
||||
else
|
||||
dst->data[0].v_pointer = NULL;
|
||||
}
|
||||
|
||||
|
||||
static gpointer
|
||||
value_render_node_peek_pointer (const GValue *value)
|
||||
{
|
||||
@@ -738,3 +738,16 @@ gsk_render_node_prefers_high_depth (const GskRenderNode *node)
|
||||
{
|
||||
return node->prefers_high_depth;
|
||||
}
|
||||
|
||||
/* Whether we need an offscreen to handle opacity correctly for this node.
|
||||
* We don't if there is only one drawing node inside (could be child
|
||||
* node, or grandchild, or...).
|
||||
*
|
||||
* For containers with multiple children, we can avoid the offscreen if
|
||||
* the children are known not to overlap.
|
||||
*/
|
||||
gboolean
|
||||
gsk_render_node_use_offscreen_for_opacity (const GskRenderNode *node)
|
||||
{
|
||||
return node->offscreen_for_opacity;
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ gsk_color_node_new (const GdkRGBA *rgba,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_COLOR_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
self->color = *rgba;
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
@@ -284,6 +285,7 @@ gsk_linear_gradient_node_new (const graphene_rect_t *bounds,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_LINEAR_GRADIENT_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
graphene_point_init_from_point (&self->start, start);
|
||||
@@ -336,6 +338,7 @@ gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_REPEATING_LINEAR_GRADIENT_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
graphene_point_init_from_point (&self->start, start);
|
||||
@@ -584,6 +587,7 @@ gsk_radial_gradient_node_new (const graphene_rect_t *bounds,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_RADIAL_GRADIENT_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
graphene_point_init_from_point (&self->center, center);
|
||||
@@ -652,6 +656,7 @@ gsk_repeating_radial_gradient_node_new (const graphene_rect_t *bounds,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_REPEATING_RADIAL_GRADIENT_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
graphene_point_init_from_point (&self->center, center);
|
||||
@@ -1030,6 +1035,7 @@ gsk_conic_gradient_node_new (const graphene_rect_t *bounds,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_CONIC_GRADIENT_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
graphene_point_init_from_point (&self->center, center);
|
||||
@@ -1413,6 +1419,7 @@ gsk_border_node_new (const GskRoundedRect *outline,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_BORDER_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
gsk_rounded_rect_init_copy (&self->outline, outline);
|
||||
memcpy (self->border_width, border_width, sizeof (self->border_width));
|
||||
@@ -1559,6 +1566,7 @@ gsk_texture_node_new (GdkTexture *texture,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_TEXTURE_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
self->texture = g_object_ref (texture);
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
@@ -2014,6 +2022,7 @@ gsk_inset_shadow_node_new (const GskRoundedRect *outline,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_INSET_SHADOW_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
gsk_rounded_rect_init_copy (&self->outline, outline);
|
||||
self->color = *color;
|
||||
@@ -2313,6 +2322,7 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_OUTSET_SHADOW_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
gsk_rounded_rect_init_copy (&self->outline, outline);
|
||||
self->color = *color;
|
||||
@@ -2506,6 +2516,7 @@ gsk_cairo_node_new (const graphene_rect_t *bounds)
|
||||
|
||||
self = gsk_render_node_alloc (GSK_CAIRO_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
|
||||
@@ -2576,6 +2587,7 @@ struct _GskContainerNode
|
||||
{
|
||||
GskRenderNode render_node;
|
||||
|
||||
gboolean disjoint;
|
||||
guint n_children;
|
||||
GskRenderNode **children;
|
||||
};
|
||||
@@ -2724,6 +2736,7 @@ gsk_container_node_new (GskRenderNode **children,
|
||||
self = gsk_render_node_alloc (GSK_CONTAINER_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
|
||||
self->disjoint = TRUE;
|
||||
self->n_children = n_children;
|
||||
|
||||
if (n_children == 0)
|
||||
@@ -2743,11 +2756,14 @@ gsk_container_node_new (GskRenderNode **children,
|
||||
for (guint i = 1; i < n_children; i++)
|
||||
{
|
||||
self->children[i] = gsk_render_node_ref (children[i]);
|
||||
self->disjoint &= !graphene_rect_intersection (&bounds, &(children[i]->bounds), NULL);
|
||||
graphene_rect_union (&bounds, &(children[i]->bounds), &bounds);
|
||||
node->prefers_high_depth |= gsk_render_node_prefers_high_depth (children[i]);
|
||||
node->offscreen_for_opacity |= children[i]->offscreen_for_opacity;
|
||||
}
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, &bounds);
|
||||
node->offscreen_for_opacity |= !self->disjoint;
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -2801,6 +2817,24 @@ gsk_container_node_get_children (const GskRenderNode *node,
|
||||
return self->children;
|
||||
}
|
||||
|
||||
/*< private>
|
||||
* gsk_container_node_is_disjoint:
|
||||
* @node: a container `GskRenderNode`
|
||||
*
|
||||
* Returns `TRUE` if it is known that the child nodes are not
|
||||
* overlapping. There is no guarantee that they do overlap
|
||||
* if this function return FALSE.
|
||||
*
|
||||
* Returns: `TRUE` if children don't overlap
|
||||
*/
|
||||
gboolean
|
||||
gsk_container_node_is_disjoint (const GskRenderNode *node)
|
||||
{
|
||||
const GskContainerNode *self = (const GskContainerNode *) node;
|
||||
|
||||
return self->disjoint;
|
||||
}
|
||||
|
||||
/*** GSK_TRANSFORM_NODE ***/
|
||||
|
||||
/**
|
||||
@@ -2962,6 +2996,7 @@ gsk_transform_node_new (GskRenderNode *child,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_TRANSFORM_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->transform = gsk_transform_ref (transform);
|
||||
@@ -3106,6 +3141,7 @@ gsk_opacity_node_new (GskRenderNode *child,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_OPACITY_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->opacity = CLAMP (opacity, 0.0, 1.0);
|
||||
@@ -3309,6 +3345,7 @@ gsk_color_matrix_node_new (GskRenderNode *child,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_COLOR_MATRIX_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
graphene_matrix_init_from_matrix (&self->color_matrix, color_matrix);
|
||||
@@ -3457,6 +3494,7 @@ gsk_repeat_node_new (const graphene_rect_t *bounds,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_REPEAT_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = TRUE;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
|
||||
@@ -3594,6 +3632,7 @@ gsk_clip_node_new (GskRenderNode *child,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_CLIP_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
graphene_rect_normalize_r (clip, &self->clip);
|
||||
@@ -3727,6 +3766,7 @@ gsk_rounded_clip_node_new (GskRenderNode *child,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_ROUNDED_CLIP_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
gsk_rounded_rect_init_copy (&self->clip, clip);
|
||||
@@ -3946,6 +3986,7 @@ gsk_shadow_node_new (GskRenderNode *child,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_SHADOW_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->n_shadows = n_shadows;
|
||||
@@ -4142,6 +4183,7 @@ gsk_blend_node_new (GskRenderNode *bottom,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_BLEND_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = TRUE;
|
||||
|
||||
self->bottom = gsk_render_node_ref (bottom);
|
||||
self->top = gsk_render_node_ref (top);
|
||||
@@ -4292,6 +4334,7 @@ gsk_cross_fade_node_new (GskRenderNode *start,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_CROSS_FADE_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = TRUE;
|
||||
|
||||
self->start = gsk_render_node_ref (start);
|
||||
self->end = gsk_render_node_ref (end);
|
||||
@@ -4478,6 +4521,7 @@ gsk_text_node_new (PangoFont *font,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_TEXT_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
self->font = g_object_ref (font);
|
||||
self->color = *color;
|
||||
@@ -4884,6 +4928,7 @@ gsk_blur_node_new (GskRenderNode *child,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_BLUR_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->radius = radius;
|
||||
@@ -5013,6 +5058,7 @@ gsk_debug_node_new (GskRenderNode *child,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_DEBUG_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = child->offscreen_for_opacity;
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->message = message;
|
||||
@@ -5174,6 +5220,7 @@ gsk_gl_shader_node_new (GskGLShader *shader,
|
||||
|
||||
self = gsk_render_node_alloc (GSK_GL_SHADER_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = TRUE;
|
||||
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
self->shader = g_object_ref (shader);
|
||||
|
||||
@@ -29,6 +29,7 @@ struct _GskRenderNode
|
||||
graphene_rect_t bounds;
|
||||
|
||||
guint prefers_high_depth : 1;
|
||||
guint offscreen_for_opacity : 1;
|
||||
};
|
||||
|
||||
struct _GskRenderNodeClass
|
||||
@@ -113,6 +114,10 @@ void gsk_transform_node_get_translate (const GskRenderNode *no
|
||||
float *dy);
|
||||
gboolean gsk_render_node_prefers_high_depth (const GskRenderNode *node);
|
||||
|
||||
gboolean gsk_container_node_is_disjoint (const GskRenderNode *node);
|
||||
|
||||
gboolean gsk_render_node_use_offscreen_for_opacity (const GskRenderNode *node);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -1418,7 +1418,7 @@ gtk_at_spi_context_unregister_object (GtkAtSpiContext *self)
|
||||
g_clear_pointer (&self->interfaces, g_variant_unref);
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ GObject boilerplate */
|
||||
/* {{{ GObject boilerplate */
|
||||
static void
|
||||
gtk_at_spi_context_finalize (GObject *gobject)
|
||||
{
|
||||
@@ -1443,22 +1443,6 @@ gtk_at_spi_context_constructed (GObject *gobject)
|
||||
|
||||
static const char *get_bus_address (GdkDisplay *display);
|
||||
|
||||
static void
|
||||
register_object (GtkAtSpiRoot *root,
|
||||
GtkAtSpiContext *context)
|
||||
{
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (context));
|
||||
|
||||
gtk_atspi_connect_text_signals (accessible,
|
||||
(GtkAtspiTextChangedCallback *)emit_text_changed,
|
||||
(GtkAtspiTextSelectionCallback *)emit_text_selection_changed,
|
||||
context);
|
||||
gtk_atspi_connect_selection_signals (accessible,
|
||||
(GtkAtspiSelectionCallback *)emit_selection_changed,
|
||||
context);
|
||||
gtk_at_spi_context_register_object (context);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_context_realize (GtkATContext *context)
|
||||
{
|
||||
@@ -1505,10 +1489,11 @@ gtk_at_spi_context_realize (GtkATContext *context)
|
||||
if (self->connection == NULL)
|
||||
return;
|
||||
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (context);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GTK_DEBUG_CHECK (A11Y))
|
||||
{
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (context);
|
||||
GtkAccessibleRole role = gtk_at_context_get_accessible_role (context);
|
||||
char *role_name = g_enum_to_string (GTK_TYPE_ACCESSIBLE_ROLE, role);
|
||||
g_message ("Realizing ATSPI context “%s” for accessible “%s”, with role: “%s”",
|
||||
@@ -1519,7 +1504,16 @@ gtk_at_spi_context_realize (GtkATContext *context)
|
||||
}
|
||||
#endif
|
||||
|
||||
gtk_at_spi_root_queue_register (self->root, self, register_object);
|
||||
gtk_atspi_connect_text_signals (accessible,
|
||||
(GtkAtspiTextChangedCallback *)emit_text_changed,
|
||||
(GtkAtspiTextSelectionCallback *)emit_text_selection_changed,
|
||||
self);
|
||||
gtk_atspi_connect_selection_signals (accessible,
|
||||
(GtkAtspiSelectionCallback *)emit_selection_changed,
|
||||
self);
|
||||
gtk_at_spi_context_register_object (self);
|
||||
|
||||
gtk_at_spi_root_queue_register (self->root, self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -474,24 +474,16 @@ gtk_at_spi_root_child_changed (GtkAtSpiRoot *self,
|
||||
window_ref);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkAtSpiRoot *root;
|
||||
GtkAtSpiRootRegisterFunc register_func;
|
||||
} RegistrationData;
|
||||
|
||||
static void
|
||||
on_registration_reply (GObject *gobject,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
RegistrationData *data = user_data;
|
||||
GtkAtSpiRoot *self = data->root;
|
||||
GtkAtSpiRoot *self = user_data;
|
||||
|
||||
GError *error = NULL;
|
||||
GVariant *reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (gobject), result, &error);
|
||||
|
||||
self->register_id = 0;
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
g_critical ("Unable to register the application: %s", error->message);
|
||||
@@ -517,27 +509,19 @@ on_registration_reply (GObject *gobject,
|
||||
/* Drain the list of queued GtkAtSpiContexts, and add them to the cache */
|
||||
if (self->queued_contexts != NULL)
|
||||
{
|
||||
for (GList *l = g_list_reverse (self->queued_contexts); l != NULL; l = l->next)
|
||||
{
|
||||
if (data->register_func != NULL)
|
||||
data->register_func (self, l->data);
|
||||
|
||||
gtk_at_spi_cache_add_context (self->cache, l->data);
|
||||
}
|
||||
for (GList *l = self->queued_contexts; l != NULL; l = l->next)
|
||||
gtk_at_spi_cache_add_context (self->cache, l->data);
|
||||
|
||||
g_clear_pointer (&self->queued_contexts, g_list_free);
|
||||
}
|
||||
|
||||
self->toplevels = gtk_window_get_toplevels ();
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
root_register (gpointer user_data)
|
||||
root_register (gpointer data)
|
||||
{
|
||||
RegistrationData *data = user_data;
|
||||
GtkAtSpiRoot *self = data->root;
|
||||
GtkAtSpiRoot *self = data;
|
||||
const char *unique_name;
|
||||
|
||||
/* Register the root element; every application has a single root, so we only
|
||||
@@ -593,7 +577,9 @@ root_register (gpointer user_data)
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL,
|
||||
on_registration_reply,
|
||||
data);
|
||||
self);
|
||||
|
||||
self->register_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -601,24 +587,18 @@ root_register (gpointer user_data)
|
||||
/*< private >
|
||||
* gtk_at_spi_root_queue_register:
|
||||
* @self: a `GtkAtSpiRoot`
|
||||
* @context: the AtSpi context to register
|
||||
* @func: the function to call when the root has been registered
|
||||
*
|
||||
* Queues the registration of the root object on the AT-SPI bus.
|
||||
*/
|
||||
void
|
||||
gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
|
||||
GtkAtSpiContext *context,
|
||||
GtkAtSpiRootRegisterFunc func)
|
||||
gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
|
||||
GtkAtSpiContext *context)
|
||||
{
|
||||
/* The cache is available if the root has finished registering itself; if we
|
||||
* are still waiting for the registration to finish, add the context to a queue
|
||||
*/
|
||||
if (self->cache != NULL)
|
||||
{
|
||||
if (func != NULL)
|
||||
func (self, context);
|
||||
|
||||
gtk_at_spi_cache_add_context (self->cache, context);
|
||||
return;
|
||||
}
|
||||
@@ -632,11 +612,7 @@ gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
|
||||
if (self->register_id != 0)
|
||||
return;
|
||||
|
||||
RegistrationData *data = g_new (RegistrationData, 1);
|
||||
data->root = self;
|
||||
data->register_func = func;
|
||||
|
||||
self->register_id = g_idle_add (root_register, data);
|
||||
self->register_id = g_idle_add (root_register, self);
|
||||
gdk_source_set_static_name_by_id (self->register_id, "[gtk] ATSPI root registration");
|
||||
}
|
||||
|
||||
|
||||
@@ -34,13 +34,9 @@ G_DECLARE_FINAL_TYPE (GtkAtSpiRoot, gtk_at_spi_root, GTK, AT_SPI_ROOT, GObject)
|
||||
GtkAtSpiRoot *
|
||||
gtk_at_spi_root_new (const char *bus_address);
|
||||
|
||||
typedef void (* GtkAtSpiRootRegisterFunc) (GtkAtSpiRoot *root,
|
||||
GtkAtSpiContext *context);
|
||||
|
||||
void
|
||||
gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
|
||||
GtkAtSpiContext *context,
|
||||
GtkAtSpiRootRegisterFunc func);
|
||||
GtkAtSpiContext *context);
|
||||
|
||||
void
|
||||
gtk_at_spi_root_unregister (GtkAtSpiRoot *self,
|
||||
|
||||
@@ -523,11 +523,26 @@ gtk_center_layout_allocate (GtkLayoutManager *layout_manager,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_center_layout_dispose (GObject *object)
|
||||
{
|
||||
GtkCenterLayout *self = GTK_CENTER_LAYOUT (object);
|
||||
|
||||
g_clear_object (&self->start_widget);
|
||||
g_clear_object (&self->center_widget);
|
||||
g_clear_object (&self->end_widget);
|
||||
|
||||
G_OBJECT_CLASS (gtk_center_layout_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_center_layout_class_init (GtkCenterLayoutClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_center_layout_dispose;
|
||||
|
||||
layout_class->get_request_mode = gtk_center_layout_get_request_mode;
|
||||
layout_class->measure = gtk_center_layout_measure;
|
||||
layout_class->allocate = gtk_center_layout_allocate;
|
||||
@@ -641,11 +656,8 @@ gtk_center_layout_set_start_widget (GtkCenterLayout *self,
|
||||
g_return_if_fail (GTK_IS_CENTER_LAYOUT (self));
|
||||
g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
|
||||
|
||||
if (self->start_widget == widget)
|
||||
return;
|
||||
|
||||
self->start_widget = widget;
|
||||
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self));
|
||||
if (g_set_object (&self->start_widget, widget))
|
||||
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -680,11 +692,8 @@ gtk_center_layout_set_center_widget (GtkCenterLayout *self,
|
||||
g_return_if_fail (GTK_IS_CENTER_LAYOUT (self));
|
||||
g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
|
||||
|
||||
if (self->center_widget == widget)
|
||||
return;
|
||||
|
||||
self->center_widget = widget;
|
||||
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self));
|
||||
if (g_set_object (&self->center_widget, widget))
|
||||
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -706,7 +715,7 @@ gtk_center_layout_get_center_widget (GtkCenterLayout *self)
|
||||
/**
|
||||
* gtk_center_layout_set_end_widget:
|
||||
* @self: a `GtkCenterLayout`
|
||||
* @widget: (nullable) (transfer none): the new end widget
|
||||
* @widget: (nullable): the new end widget
|
||||
*
|
||||
* Sets the new end widget of @self.
|
||||
*
|
||||
@@ -719,11 +728,8 @@ gtk_center_layout_set_end_widget (GtkCenterLayout *self,
|
||||
g_return_if_fail (GTK_IS_CENTER_LAYOUT (self));
|
||||
g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
|
||||
|
||||
if (self->end_widget == widget)
|
||||
return;
|
||||
|
||||
self->end_widget = widget;
|
||||
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self));
|
||||
if (g_set_object (&self->end_widget, widget))
|
||||
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1703,9 +1703,8 @@ gtk_column_view_sort_by_column (GtkColumnView *self,
|
||||
g_return_if_fail (column == NULL || GTK_IS_COLUMN_VIEW_COLUMN (column));
|
||||
g_return_if_fail (column == NULL || gtk_column_view_column_get_column_view (column) == self);
|
||||
|
||||
if (column == NULL)
|
||||
gtk_column_view_sorter_clear (GTK_COLUMN_VIEW_SORTER (self->sorter));
|
||||
else
|
||||
gtk_column_view_sorter_clear (GTK_COLUMN_VIEW_SORTER (self->sorter));
|
||||
if (column != NULL)
|
||||
gtk_column_view_sorter_set_column (GTK_COLUMN_VIEW_SORTER (self->sorter),
|
||||
column,
|
||||
direction == GTK_SORT_DESCENDING);
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
|
||||
#define SCROLL_CAPTURE_THRESHOLD_MS 150
|
||||
#define HOLD_TIMEOUT_MS 50
|
||||
#define SURFACE_UNIT_DISCRETE_MAPPING 10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -85,6 +86,8 @@ struct _GtkEventControllerScroll
|
||||
double cur_dx;
|
||||
double cur_dy;
|
||||
|
||||
GdkScrollUnit cur_unit;
|
||||
|
||||
guint hold_timeout_id;
|
||||
guint active : 1;
|
||||
};
|
||||
@@ -345,6 +348,7 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
double dx = 0, dy = 0;
|
||||
gboolean handled = GDK_EVENT_PROPAGATE;
|
||||
GdkEventType event_type;
|
||||
GdkScrollUnit scroll_unit;
|
||||
|
||||
event_type = gdk_event_get_event_type (event);
|
||||
|
||||
@@ -360,6 +364,8 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
|
||||
g_clear_handle_id (&scroll->hold_timeout_id, g_source_remove);
|
||||
|
||||
scroll_unit = gdk_scroll_event_get_unit (event);
|
||||
|
||||
/* FIXME: Handle device changes */
|
||||
direction = gdk_scroll_event_get_direction (event);
|
||||
if (direction == GDK_SCROLL_SMOOTH)
|
||||
@@ -380,18 +386,31 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
scroll->cur_dy += dy;
|
||||
dx = dy = 0;
|
||||
|
||||
if (ABS (scroll->cur_dx) >= 1)
|
||||
if (scroll_unit == GDK_SCROLL_UNIT_SURFACE)
|
||||
{
|
||||
steps = trunc (scroll->cur_dx);
|
||||
scroll->cur_dx -= steps;
|
||||
dx = steps;
|
||||
}
|
||||
dx = (int) scroll->cur_dx / SURFACE_UNIT_DISCRETE_MAPPING;
|
||||
scroll->cur_dx -= dx * SURFACE_UNIT_DISCRETE_MAPPING;
|
||||
|
||||
if (ABS (scroll->cur_dy) >= 1)
|
||||
dy = (int) scroll->cur_dy / SURFACE_UNIT_DISCRETE_MAPPING;
|
||||
scroll->cur_dy -= dy * SURFACE_UNIT_DISCRETE_MAPPING;
|
||||
|
||||
scroll_unit = GDK_SCROLL_UNIT_WHEEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
steps = trunc (scroll->cur_dy);
|
||||
scroll->cur_dy -= steps;
|
||||
dy = steps;
|
||||
if (ABS (scroll->cur_dx) >= 1)
|
||||
{
|
||||
steps = trunc (scroll->cur_dx);
|
||||
scroll->cur_dx -= steps;
|
||||
dx = steps;
|
||||
}
|
||||
|
||||
if (ABS (scroll->cur_dy) >= 1)
|
||||
{
|
||||
steps = trunc (scroll->cur_dy);
|
||||
scroll->cur_dy -= steps;
|
||||
dy = steps;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -423,6 +442,8 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
dx = 0;
|
||||
}
|
||||
|
||||
scroll->cur_unit = scroll_unit;
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
g_signal_emit (controller, signals[SCROLL], 0, dx, dy, &handled);
|
||||
else if (direction == GDK_SCROLL_SMOOTH &&
|
||||
@@ -492,6 +513,9 @@ gtk_event_controller_scroll_class_init (GtkEventControllerScrollClass *klass)
|
||||
* Signals that the widget should scroll by the
|
||||
* amount specified by @dx and @dy.
|
||||
*
|
||||
* For the representation unit of the deltas, see
|
||||
* [method@Gtk.EventControllerScroll.get_unit].
|
||||
*
|
||||
* Returns: %TRUE if the scroll event was handled,
|
||||
* %FALSE otherwise.
|
||||
*/
|
||||
@@ -609,3 +633,26 @@ gtk_event_controller_scroll_get_flags (GtkEventControllerScroll *scroll)
|
||||
|
||||
return scroll->flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_event_controller_scroll_get_unit:
|
||||
* @scroll: a `GtkEventControllerScroll`.
|
||||
*
|
||||
* Gets the scroll unit of the last
|
||||
* [signal@Gtk.EventControllerScroll::scroll] signal received.
|
||||
*
|
||||
* Always returns %GDK_SCROLL_UNIT_WHEEL if the
|
||||
* %GTK_EVENT_CONTROLLER_SCROLL_DISCRETE flag is set.
|
||||
*
|
||||
* Returns: the scroll unit.
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
GdkScrollUnit
|
||||
gtk_event_controller_scroll_get_unit (GtkEventControllerScroll *scroll)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_SCROLL (scroll),
|
||||
GDK_SCROLL_UNIT_WHEEL);
|
||||
|
||||
return scroll->cur_unit;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,9 @@ GDK_AVAILABLE_IN_ALL
|
||||
GtkEventControllerScrollFlags
|
||||
gtk_event_controller_scroll_get_flags (GtkEventControllerScroll *scroll);
|
||||
|
||||
GDK_AVAILABLE_IN_4_8
|
||||
GdkScrollUnit gtk_event_controller_scroll_get_unit (GtkEventControllerScroll *scroll);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_EVENT_CONTROLLER_SCROLL_H__ */
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "gtkfilefilterprivate.h"
|
||||
|
||||
#include "macos/gdkmacos.h"
|
||||
#include "macos/gdkmacosdisplay-private.h"
|
||||
#include "macos/gdkmacossurface-private.h"
|
||||
|
||||
typedef struct {
|
||||
@@ -368,6 +369,9 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
|
||||
[data->key_window makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
/* Need to clear our cached copy of ordered windows */
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (gdk_display_get_default ()));
|
||||
|
||||
if (!data->skip_response)
|
||||
{
|
||||
g_slist_free_full (self->custom_files, g_object_unref);
|
||||
|
||||
@@ -339,7 +339,7 @@ parser_end_element (GtkBuildableParseContext *context,
|
||||
{
|
||||
SubParserData *data = (SubParserData*)user_data;
|
||||
|
||||
if (data->string && data->parsing)
|
||||
if (data->string)
|
||||
{
|
||||
switch (data->type)
|
||||
{
|
||||
|
||||
@@ -132,9 +132,7 @@ gtk_image_definition_new_paintable (GdkPaintable *paintable)
|
||||
GtkImageDefinition *
|
||||
gtk_image_definition_ref (GtkImageDefinition *def)
|
||||
{
|
||||
GtkImageDefinitionEmpty *empty = (GtkImageDefinitionEmpty *) def;
|
||||
|
||||
empty->ref_count++;
|
||||
def->empty.ref_count++;
|
||||
|
||||
return def;
|
||||
}
|
||||
@@ -142,11 +140,9 @@ gtk_image_definition_ref (GtkImageDefinition *def)
|
||||
void
|
||||
gtk_image_definition_unref (GtkImageDefinition *def)
|
||||
{
|
||||
GtkImageDefinitionEmpty *empty = (GtkImageDefinitionEmpty *) def;
|
||||
def->empty.ref_count--;
|
||||
|
||||
empty->ref_count--;
|
||||
|
||||
if (empty->ref_count > 0)
|
||||
if (def->empty.ref_count > 0)
|
||||
return;
|
||||
|
||||
switch (def->type)
|
||||
@@ -156,22 +152,13 @@ gtk_image_definition_unref (GtkImageDefinition *def)
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
{
|
||||
GtkImageDefinitionPaintable *paintable = (GtkImageDefinitionPaintable *) def;
|
||||
g_object_unref (paintable->paintable);
|
||||
}
|
||||
g_object_unref (def->paintable.paintable);
|
||||
break;
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
{
|
||||
GtkImageDefinitionIconName *icon_name = (GtkImageDefinitionIconName *) def;
|
||||
g_free (icon_name->icon_name);
|
||||
}
|
||||
g_free (def->icon_name.icon_name);
|
||||
break;
|
||||
case GTK_IMAGE_GICON:
|
||||
{
|
||||
GtkImageDefinitionGIcon *gicon = (GtkImageDefinitionGIcon *) def;
|
||||
g_object_unref (gicon->gicon);
|
||||
}
|
||||
g_object_unref (def->gicon.gicon);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -202,32 +189,27 @@ gtk_image_definition_get_scale (const GtkImageDefinition *def)
|
||||
const char *
|
||||
gtk_image_definition_get_icon_name (const GtkImageDefinition *def)
|
||||
{
|
||||
const GtkImageDefinitionIconName *icon_name = (const GtkImageDefinitionIconName *) def;
|
||||
|
||||
if (def->type != GTK_IMAGE_ICON_NAME)
|
||||
return NULL;
|
||||
|
||||
return icon_name->icon_name;
|
||||
return def->icon_name.icon_name;
|
||||
}
|
||||
|
||||
GIcon *
|
||||
gtk_image_definition_get_gicon (const GtkImageDefinition *def)
|
||||
{
|
||||
const GtkImageDefinitionGIcon *gicon = (const GtkImageDefinitionGIcon *) def;
|
||||
|
||||
if (def->type != GTK_IMAGE_GICON)
|
||||
return NULL;
|
||||
|
||||
return gicon->gicon;
|
||||
return def->gicon.gicon;
|
||||
}
|
||||
|
||||
GdkPaintable *
|
||||
gtk_image_definition_get_paintable (const GtkImageDefinition *def)
|
||||
{
|
||||
const GtkImageDefinitionPaintable *paintable = (const GtkImageDefinitionPaintable *) def;
|
||||
|
||||
if (def->type != GTK_IMAGE_PAINTABLE)
|
||||
return NULL;
|
||||
|
||||
return paintable->paintable;
|
||||
return def->paintable.paintable;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,8 +181,6 @@ gtk_kinetic_scrolling_tick (GtkKineticScrolling *data,
|
||||
{
|
||||
case GTK_KINETIC_SCROLLING_PHASE_DECELERATING:
|
||||
{
|
||||
double last_position = data->position;
|
||||
double last_time = data->t;
|
||||
double exp_part;
|
||||
|
||||
data->t += time_delta;
|
||||
@@ -199,8 +197,7 @@ gtk_kinetic_scrolling_tick (GtkKineticScrolling *data,
|
||||
{
|
||||
gtk_kinetic_scrolling_init_overshoot(data, data->upper, data->position, data->velocity);
|
||||
}
|
||||
else if (fabs(data->velocity) < 1 ||
|
||||
(last_time != 0.0 && fabs(data->position - last_position) < 1))
|
||||
else if (fabs(data->velocity) < 0.1)
|
||||
{
|
||||
gtk_kinetic_scrolling_stop (data);
|
||||
}
|
||||
@@ -254,6 +251,5 @@ gtk_kinetic_scrolling_stop (GtkKineticScrolling *data)
|
||||
{
|
||||
data->phase = GTK_KINETIC_SCROLLING_PHASE_FINISHED;
|
||||
data->position = round (data->position);
|
||||
data->velocity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,31 +897,11 @@ rewrite_event_for_surface (GdkEvent *event,
|
||||
GdkSurface *new_surface)
|
||||
{
|
||||
GdkEventType type;
|
||||
double x, y;
|
||||
double x = -G_MAXDOUBLE, y = -G_MAXDOUBLE;
|
||||
double dx, dy;
|
||||
|
||||
type = gdk_event_get_event_type (event);
|
||||
|
||||
switch ((guint) type)
|
||||
{
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_BEGIN:
|
||||
case GDK_TOUCH_UPDATE:
|
||||
case GDK_TOUCH_END:
|
||||
case GDK_TOUCH_CANCEL:
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
case GDK_TOUCHPAD_HOLD:
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
gdk_surface_translate_coordinates (gdk_event_get_surface (event), new_surface, &x, &y);
|
||||
break;
|
||||
default:
|
||||
x = y = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((guint) type)
|
||||
{
|
||||
case GDK_BUTTON_PRESS:
|
||||
@@ -1031,8 +1011,7 @@ rewrite_event_for_grabs (GdkEvent *event)
|
||||
display = gdk_event_get_display (event);
|
||||
device = gdk_event_get_device (event);
|
||||
|
||||
if (!gdk_device_grab_info (display, device, &grab_surface, &owner_events) ||
|
||||
!owner_events)
|
||||
if (!gdk_device_grab_info (display, device, &grab_surface, &owner_events))
|
||||
return NULL;
|
||||
break;
|
||||
default:
|
||||
@@ -1042,11 +1021,24 @@ rewrite_event_for_grabs (GdkEvent *event)
|
||||
event_widget = gtk_get_event_widget (event);
|
||||
grab_widget = GTK_WIDGET (gtk_native_get_for_surface (grab_surface));
|
||||
|
||||
if (grab_widget &&
|
||||
gtk_main_get_window_group (grab_widget) != gtk_main_get_window_group (event_widget))
|
||||
return rewrite_event_for_surface (event, grab_surface);
|
||||
else
|
||||
if (!grab_widget)
|
||||
return NULL;
|
||||
|
||||
/* If owner_events was set, events in client surfaces get forwarded
|
||||
* as normal, but we consider other window groups foreign surfaces.
|
||||
*/
|
||||
if (owner_events &&
|
||||
gtk_main_get_window_group (grab_widget) == gtk_main_get_window_group (event_widget))
|
||||
return NULL;
|
||||
|
||||
/* If owner_events was not set, events only get sent to the grabbing
|
||||
* surface.
|
||||
*/
|
||||
if (!owner_events &&
|
||||
grab_surface == gtk_native_get_surface (gtk_widget_get_native (event_widget)))
|
||||
return NULL;
|
||||
|
||||
return rewrite_event_for_surface (event, grab_surface);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
|
||||
@@ -2202,25 +2202,27 @@ gtk_range_scroll_controller_scroll (GtkEventControllerScroll *scroll,
|
||||
GtkRange *range)
|
||||
{
|
||||
GtkRangePrivate *priv = gtk_range_get_instance_private (range);
|
||||
double scroll_unit, delta;
|
||||
double delta;
|
||||
gboolean handled;
|
||||
GtkOrientation move_orientation;
|
||||
|
||||
#ifdef GDK_WINDOWING_MACOS
|
||||
scroll_unit = 1;
|
||||
#else
|
||||
scroll_unit = gtk_adjustment_get_page_increment (priv->adjustment);
|
||||
#endif
|
||||
GdkScrollUnit scroll_unit;
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL && dx != 0)
|
||||
{
|
||||
move_orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
delta = dx * scroll_unit;
|
||||
delta = dx;
|
||||
}
|
||||
else
|
||||
{
|
||||
move_orientation = GTK_ORIENTATION_VERTICAL;
|
||||
delta = dy * scroll_unit;
|
||||
delta = dy;
|
||||
}
|
||||
|
||||
scroll_unit = gtk_event_controller_scroll_get_unit (scroll);
|
||||
|
||||
if (scroll_unit == GDK_SCROLL_UNIT_WHEEL)
|
||||
{
|
||||
delta *= gtk_adjustment_get_page_increment (priv->adjustment);
|
||||
}
|
||||
|
||||
if (delta != 0 && should_invert_move (range, move_orientation))
|
||||
|
||||
@@ -1058,6 +1058,11 @@ gtk_scrolled_window_decelerate (GtkScrolledWindow *scrolled_window,
|
||||
gtk_scrolled_window_start_deceleration (scrolled_window);
|
||||
priv->x_velocity = priv->y_velocity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_pointer (&priv->hscrolling, gtk_kinetic_scrolling_free);
|
||||
g_clear_pointer (&priv->vscrolling, gtk_kinetic_scrolling_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1228,15 +1233,14 @@ check_update_scrollbar_proximity (GtkScrolledWindow *sw,
|
||||
}
|
||||
|
||||
static double
|
||||
get_scroll_unit (GtkScrolledWindow *sw,
|
||||
GtkOrientation orientation,
|
||||
GtkEventControllerScroll *scroll)
|
||||
get_wheel_detent_scroll_step (GtkScrolledWindow *sw,
|
||||
GtkOrientation orientation)
|
||||
{
|
||||
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
|
||||
GtkScrollbar *scrollbar;
|
||||
GtkAdjustment *adj;
|
||||
double page_size;
|
||||
double scroll_unit;
|
||||
double scroll_step;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
scrollbar = GTK_SCROLLBAR (priv->hscrollbar);
|
||||
@@ -1248,20 +1252,9 @@ get_scroll_unit (GtkScrolledWindow *sw,
|
||||
|
||||
adj = gtk_scrollbar_get_adjustment (scrollbar);
|
||||
page_size = gtk_adjustment_get_page_size (adj);
|
||||
scroll_unit = pow (page_size, 2.0 / 3.0);
|
||||
scroll_step = pow (page_size, 2.0 / 3.0);
|
||||
|
||||
#ifdef GDK_WINDOWING_MACOS
|
||||
{
|
||||
GdkEvent *event = gtk_event_controller_get_current_event (GTK_EVENT_CONTROLLER (scroll));
|
||||
|
||||
if (event != NULL &&
|
||||
gdk_event_get_event_type (event) == GDK_SCROLL &&
|
||||
gdk_scroll_event_get_direction (event) == GDK_SCROLL_SMOOTH)
|
||||
scroll_unit = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return scroll_unit;
|
||||
return scroll_step;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1403,12 +1396,18 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
double new_value;
|
||||
double scroll_unit;
|
||||
GdkScrollUnit scroll_unit;
|
||||
|
||||
adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar));
|
||||
scroll_unit = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL, scroll);
|
||||
scroll_unit = gtk_event_controller_scroll_get_unit (scroll);
|
||||
|
||||
new_value = priv->unclamped_hadj_value + delta_x * scroll_unit;
|
||||
if (scroll_unit == GDK_SCROLL_UNIT_WHEEL)
|
||||
{
|
||||
delta_x *= get_wheel_detent_scroll_step (scrolled_window,
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
}
|
||||
|
||||
new_value = priv->unclamped_hadj_value + delta_x;
|
||||
_gtk_scrolled_window_set_adjustment_value (scrolled_window, adj,
|
||||
new_value);
|
||||
}
|
||||
@@ -1418,12 +1417,18 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
double new_value;
|
||||
double scroll_unit;
|
||||
GdkScrollUnit scroll_unit;
|
||||
|
||||
adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar));
|
||||
scroll_unit = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL, scroll);
|
||||
scroll_unit = gtk_event_controller_scroll_get_unit (scroll);
|
||||
|
||||
new_value = priv->unclamped_vadj_value + delta_y * scroll_unit;
|
||||
if (scroll_unit == GDK_SCROLL_UNIT_WHEEL)
|
||||
{
|
||||
delta_y *= get_wheel_detent_scroll_step (scrolled_window,
|
||||
GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
|
||||
new_value = priv->unclamped_vadj_value + delta_y;
|
||||
_gtk_scrolled_window_set_adjustment_value (scrolled_window, adj,
|
||||
new_value);
|
||||
}
|
||||
@@ -1470,30 +1475,36 @@ scroll_controller_decelerate (GtkEventControllerScroll *scroll,
|
||||
double initial_vel_y,
|
||||
GtkScrolledWindow *scrolled_window)
|
||||
{
|
||||
double unit_x, unit_y;
|
||||
GdkScrollUnit scroll_unit;
|
||||
gboolean shifted;
|
||||
GdkModifierType state;
|
||||
|
||||
|
||||
scroll_unit = gtk_event_controller_scroll_get_unit (scroll);
|
||||
state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (scroll));
|
||||
|
||||
shifted = (state & GDK_SHIFT_MASK) != 0;
|
||||
|
||||
unit_x = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL, scroll);
|
||||
unit_y = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL, scroll);
|
||||
|
||||
if (shifted)
|
||||
{
|
||||
gtk_scrolled_window_decelerate (scrolled_window,
|
||||
initial_vel_y * unit_x,
|
||||
initial_vel_x * unit_y);
|
||||
double tmp;
|
||||
|
||||
tmp = initial_vel_x;
|
||||
initial_vel_x = initial_vel_y;
|
||||
initial_vel_y = tmp;
|
||||
}
|
||||
else
|
||||
|
||||
if (scroll_unit == GDK_SCROLL_UNIT_WHEEL)
|
||||
{
|
||||
gtk_scrolled_window_decelerate (scrolled_window,
|
||||
initial_vel_x * unit_x,
|
||||
initial_vel_y * unit_y);
|
||||
initial_vel_x *= get_wheel_detent_scroll_step (scrolled_window,
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
initial_vel_y *= get_wheel_detent_scroll_step (scrolled_window,
|
||||
GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
|
||||
gtk_scrolled_window_decelerate (scrolled_window,
|
||||
initial_vel_x,
|
||||
initial_vel_y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3264,6 +3275,7 @@ scrolled_window_deceleration_cb (GtkWidget *widget,
|
||||
GtkAdjustment *hadjustment, *vadjustment;
|
||||
gint64 current_time;
|
||||
double position, elapsed;
|
||||
gboolean retval = G_SOURCE_REMOVE;
|
||||
|
||||
current_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
elapsed = (current_time - priv->last_deceleration_time) / (double)G_TIME_SPAN_SECOND;
|
||||
@@ -3279,28 +3291,23 @@ scrolled_window_deceleration_cb (GtkWidget *widget,
|
||||
{
|
||||
priv->unclamped_hadj_value = position;
|
||||
gtk_adjustment_set_value (hadjustment, position);
|
||||
retval = G_SOURCE_CONTINUE;
|
||||
}
|
||||
else if (priv->hscrolling)
|
||||
g_clear_pointer (&priv->hscrolling, gtk_kinetic_scrolling_free);
|
||||
|
||||
if (priv->vscrolling &&
|
||||
gtk_kinetic_scrolling_tick (priv->vscrolling, elapsed, &position, NULL))
|
||||
{
|
||||
priv->unclamped_vadj_value = position;
|
||||
gtk_adjustment_set_value (vadjustment, position);
|
||||
}
|
||||
else if (priv->vscrolling)
|
||||
g_clear_pointer (&priv->vscrolling, gtk_kinetic_scrolling_free);
|
||||
|
||||
if (!priv->hscrolling && !priv->vscrolling)
|
||||
{
|
||||
gtk_scrolled_window_cancel_deceleration (scrolled_window);
|
||||
return G_SOURCE_REMOVE;
|
||||
retval = G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
gtk_scrolled_window_invalidate_overshoot (scrolled_window);
|
||||
if (retval == G_SOURCE_REMOVE)
|
||||
gtk_scrolled_window_cancel_deceleration (scrolled_window);
|
||||
else
|
||||
gtk_scrolled_window_invalidate_overshoot (scrolled_window);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3364,19 +3371,23 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window)
|
||||
GtkAdjustment *hadjustment;
|
||||
|
||||
gtk_scrolled_window_accumulate_velocity (&priv->hscrolling, elapsed, &priv->x_velocity);
|
||||
g_clear_pointer (&priv->hscrolling, gtk_kinetic_scrolling_free);
|
||||
|
||||
hadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar));
|
||||
lower = gtk_adjustment_get_lower (hadjustment);
|
||||
upper = gtk_adjustment_get_upper (hadjustment);
|
||||
upper -= gtk_adjustment_get_page_size (hadjustment);
|
||||
priv->hscrolling =
|
||||
gtk_kinetic_scrolling_new (lower,
|
||||
upper,
|
||||
MAX_OVERSHOOT_DISTANCE,
|
||||
DECELERATION_FRICTION,
|
||||
OVERSHOOT_FRICTION,
|
||||
priv->unclamped_hadj_value,
|
||||
priv->x_velocity);
|
||||
if (priv->x_velocity != 0)
|
||||
{
|
||||
hadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar));
|
||||
lower = gtk_adjustment_get_lower (hadjustment);
|
||||
upper = gtk_adjustment_get_upper (hadjustment);
|
||||
upper -= gtk_adjustment_get_page_size (hadjustment);
|
||||
priv->hscrolling =
|
||||
gtk_kinetic_scrolling_new (lower,
|
||||
upper,
|
||||
MAX_OVERSHOOT_DISTANCE,
|
||||
DECELERATION_FRICTION,
|
||||
OVERSHOOT_FRICTION,
|
||||
priv->unclamped_hadj_value,
|
||||
priv->x_velocity);
|
||||
}
|
||||
}
|
||||
else
|
||||
g_clear_pointer (&priv->hscrolling, gtk_kinetic_scrolling_free);
|
||||
@@ -3387,19 +3398,23 @@ gtk_scrolled_window_start_deceleration (GtkScrolledWindow *scrolled_window)
|
||||
GtkAdjustment *vadjustment;
|
||||
|
||||
gtk_scrolled_window_accumulate_velocity (&priv->vscrolling, elapsed, &priv->y_velocity);
|
||||
g_clear_pointer (&priv->vscrolling, gtk_kinetic_scrolling_free);
|
||||
|
||||
vadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar));
|
||||
lower = gtk_adjustment_get_lower(vadjustment);
|
||||
upper = gtk_adjustment_get_upper(vadjustment);
|
||||
upper -= gtk_adjustment_get_page_size(vadjustment);
|
||||
priv->vscrolling =
|
||||
gtk_kinetic_scrolling_new (lower,
|
||||
upper,
|
||||
MAX_OVERSHOOT_DISTANCE,
|
||||
DECELERATION_FRICTION,
|
||||
OVERSHOOT_FRICTION,
|
||||
priv->unclamped_vadj_value,
|
||||
priv->y_velocity);
|
||||
if (priv->y_velocity != 0)
|
||||
{
|
||||
vadjustment = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar));
|
||||
lower = gtk_adjustment_get_lower(vadjustment);
|
||||
upper = gtk_adjustment_get_upper(vadjustment);
|
||||
upper -= gtk_adjustment_get_page_size(vadjustment);
|
||||
priv->vscrolling =
|
||||
gtk_kinetic_scrolling_new (lower,
|
||||
upper,
|
||||
MAX_OVERSHOOT_DISTANCE,
|
||||
DECELERATION_FRICTION,
|
||||
OVERSHOOT_FRICTION,
|
||||
priv->unclamped_vadj_value,
|
||||
priv->y_velocity);
|
||||
}
|
||||
}
|
||||
else
|
||||
g_clear_pointer (&priv->vscrolling, gtk_kinetic_scrolling_free);
|
||||
|
||||
@@ -106,6 +106,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_PLACEHOLDER_TEXT,
|
||||
PROP_ACTIVATES_DEFAULT,
|
||||
PROP_SEARCH_DELAY,
|
||||
NUM_PROPERTIES,
|
||||
};
|
||||
|
||||
@@ -122,6 +123,8 @@ struct _GtkSearchEntry
|
||||
GtkWidget *capture_widget;
|
||||
GtkEventController *capture_widget_controller;
|
||||
|
||||
guint search_delay;
|
||||
|
||||
GtkWidget *entry;
|
||||
GtkWidget *icon;
|
||||
|
||||
@@ -150,9 +153,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkSearchEntry, gtk_search_entry, GTK_TYPE_WIDGET,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
||||
gtk_search_entry_editable_init))
|
||||
|
||||
/* 150 mseconds of delay */
|
||||
#define DELAYED_TIMEOUT_ID 150
|
||||
|
||||
static void
|
||||
text_changed (GtkSearchEntry *entry)
|
||||
{
|
||||
@@ -224,6 +224,10 @@ gtk_search_entry_set_property (GObject *object,
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SEARCH_DELAY:
|
||||
gtk_search_entry_set_search_delay (entry, g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -250,6 +254,10 @@ gtk_search_entry_get_property (GObject *object,
|
||||
g_value_set_boolean (value, gtk_text_get_activates_default (GTK_TEXT (entry->entry)));
|
||||
break;
|
||||
|
||||
case PROP_SEARCH_DELAY:
|
||||
g_value_set_uint (value, entry->search_delay);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -315,6 +323,21 @@ gtk_search_entry_class_init (GtkSearchEntryClass *klass)
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkSearchEntry:search-delay:
|
||||
*
|
||||
* The delay in milliseconds from last keypress to the search
|
||||
* changed signal.
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
props[PROP_SEARCH_DELAY] =
|
||||
g_param_spec_uint ("search-delay",
|
||||
P_("Search delay"),
|
||||
P_("The delay from last keypress to the search-changed signal. If this is not set, it defaults to 150ms"),
|
||||
0, G_MAXUINT, 150,
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
|
||||
gtk_editable_install_properties (object_class, NUM_PROPERTIES);
|
||||
|
||||
@@ -339,8 +362,9 @@ gtk_search_entry_class_init (GtkSearchEntryClass *klass)
|
||||
* GtkSearchEntry::search-changed:
|
||||
* @entry: the entry on which the signal was emitted
|
||||
*
|
||||
* Emitted with a short delay of 150 milliseconds after the
|
||||
* last change to the entry text.
|
||||
* Emitted with a delay. The length of the delay can be
|
||||
* changed with the [property@Gtk.SearchEntry:search-delay]
|
||||
* property.
|
||||
*/
|
||||
signals[SEARCH_CHANGED] =
|
||||
g_signal_new (I_("search-changed"),
|
||||
@@ -526,7 +550,7 @@ reset_timeout (GtkSearchEntry *entry)
|
||||
{
|
||||
if (entry->delayed_changed_id > 0)
|
||||
g_source_remove (entry->delayed_changed_id);
|
||||
entry->delayed_changed_id = g_timeout_add (DELAYED_TIMEOUT_ID,
|
||||
entry->delayed_changed_id = g_timeout_add (entry->search_delay,
|
||||
gtk_search_entry_changed_timeout_cb,
|
||||
entry);
|
||||
gdk_source_set_static_name_by_id (entry->delayed_changed_id, "[gtk] gtk_search_entry_changed_timeout_cb");
|
||||
@@ -595,6 +619,8 @@ gtk_search_entry_init (GtkSearchEntry *entry)
|
||||
GtkWidget *icon;
|
||||
GtkGesture *press, *catchall;
|
||||
|
||||
entry->search_delay = 150;
|
||||
|
||||
/* The search icon is purely presentational */
|
||||
icon = g_object_new (GTK_TYPE_IMAGE,
|
||||
"accessible-role", GTK_ACCESSIBLE_ROLE_PRESENTATION,
|
||||
@@ -773,6 +799,52 @@ gtk_search_entry_get_key_capture_widget (GtkSearchEntry *entry)
|
||||
return entry->capture_widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_search_entry_set_search_delay:
|
||||
* @entry: a `GtkSearchEntry`
|
||||
* @delay: a delay in milliseconds
|
||||
*
|
||||
* Set the delay to be used between the last keypress and the
|
||||
* [signal@Gtk.SearchEntry::search-changed] signal being emitted.
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
void
|
||||
gtk_search_entry_set_search_delay (GtkSearchEntry *entry,
|
||||
guint delay)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SEARCH_ENTRY (entry));
|
||||
|
||||
if (entry->search_delay == delay)
|
||||
return;
|
||||
|
||||
entry->search_delay = delay;
|
||||
|
||||
/* Apply the updated timeout */
|
||||
reset_timeout (entry);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_SEARCH_DELAY]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_search_entry_get_search_delay
|
||||
* @entry: a `GtkSearchEntry`
|
||||
*
|
||||
* Get the delay to be used between the last keypress and the
|
||||
* [signal@Gtk.SearchEntry::search-changed] signal being emitted.
|
||||
*
|
||||
* Returns: a delay in milliseconds.
|
||||
*
|
||||
* Since: 4.8
|
||||
*/
|
||||
guint
|
||||
gtk_search_entry_get_search_delay (GtkSearchEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_SEARCH_ENTRY (entry), 0);
|
||||
|
||||
return entry->search_delay;
|
||||
}
|
||||
|
||||
GtkEventController *
|
||||
gtk_search_entry_get_key_controller (GtkSearchEntry *entry)
|
||||
{
|
||||
|
||||
@@ -54,6 +54,11 @@ void gtk_search_entry_set_key_capture_widget (GtkSearchEntry *entry,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget* gtk_search_entry_get_key_capture_widget (GtkSearchEntry *entry);
|
||||
|
||||
GDK_AVAILABLE_IN_4_8
|
||||
void gtk_search_entry_set_search_delay (GtkSearchEntry *entry,
|
||||
guint delay);
|
||||
GDK_AVAILABLE_IN_4_8
|
||||
guint gtk_search_entry_get_search_delay (GtkSearchEntry *entry);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -6331,6 +6331,10 @@ gtk_window_unexport_handle (GtkWindow *window)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
|
||||
return;
|
||||
#endif
|
||||
|
||||
g_warning ("Couldn't unexport handle for %s surface, unsupported windowing system",
|
||||
G_OBJECT_TYPE_NAME (priv->surface));
|
||||
|
||||
|
After Width: | Height: | Size: 725 B |
|
After Width: | Height: | Size: 433 B |
|
After Width: | Height: | Size: 552 B |
|
After Width: | Height: | Size: 545 B |
|
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 236 B |
|
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 369 B |
|
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 282 B |
|
Before Width: | Height: | Size: 202 B After Width: | Height: | Size: 186 B |
|
Before Width: | Height: | Size: 187 B After Width: | Height: | Size: 181 B |
|
Before Width: | Height: | Size: 237 B After Width: | Height: | Size: 226 B |
|
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 226 B |
|
Before Width: | Height: | Size: 169 B After Width: | Height: | Size: 217 B |
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 295 B |
|
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 319 B |
|
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 318 B |
|
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 195 B |
|
Before Width: | Height: | Size: 204 B After Width: | Height: | Size: 202 B |
|
Before Width: | Height: | Size: 334 B After Width: | Height: | Size: 291 B |
|
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 209 B |
|
Before Width: | Height: | Size: 167 B After Width: | Height: | Size: 172 B |
|
Before Width: | Height: | Size: 147 B After Width: | Height: | Size: 161 B |
|
Before Width: | Height: | Size: 141 B After Width: | Height: | Size: 155 B |
|
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 155 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 161 B |
|
Before Width: | Height: | Size: 165 B After Width: | Height: | Size: 170 B |
|
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 229 B |
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 283 B |
|
Before Width: | Height: | Size: 163 B After Width: | Height: | Size: 149 B |
|
After Width: | Height: | Size: 393 B |
|
Before Width: | Height: | Size: 380 B After Width: | Height: | Size: 322 B |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 139 B |
|
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 325 B |
|
Before Width: | Height: | Size: 195 B After Width: | Height: | Size: 198 B |
|
Before Width: | Height: | Size: 372 B After Width: | Height: | Size: 375 B |
|
Before Width: | Height: | Size: 193 B After Width: | Height: | Size: 194 B |
|
Before Width: | Height: | Size: 156 B After Width: | Height: | Size: 156 B |
|
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 367 B |
|
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 367 B |
|
Before Width: | Height: | Size: 244 B After Width: | Height: | Size: 237 B |
|
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 271 B |
|
Before Width: | Height: | Size: 147 B After Width: | Height: | Size: 188 B |
|
Before Width: | Height: | Size: 280 B After Width: | Height: | Size: 265 B |
|
Before Width: | Height: | Size: 299 B After Width: | Height: | Size: 321 B |
|
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 339 B |
|
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 157 B After Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 206 B After Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 214 B |
|
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 234 B |
|
Before Width: | Height: | Size: 236 B After Width: | Height: | Size: 274 B |
|
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 220 B |
|
Before Width: | Height: | Size: 284 B After Width: | Height: | Size: 350 B |
|
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 199 B |
|
Before Width: | Height: | Size: 164 B After Width: | Height: | Size: 185 B |
|
Before Width: | Height: | Size: 157 B After Width: | Height: | Size: 226 B |
|
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 221 B |
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 190 B |
|
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 199 B |