Compare commits
264 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c96113e6d8 | |||
| 3e766a4fe2 | |||
| 60a8367594 | |||
| 22b9cf1644 | |||
| 224a8390eb | |||
| 5fee68f80d | |||
| 41086f0756 | |||
| 78c153ae14 | |||
| 53c02a1e84 | |||
| 1523fecfe1 | |||
| 75821de2d7 | |||
| 91d2e1bc7f | |||
| 986fd9959d | |||
| 92b6c59f80 | |||
| 1860da7a1a | |||
| 09a0151233 | |||
| c47759bd3d | |||
| c543206d79 | |||
| 3523b02a35 | |||
| f936d7a883 | |||
| 804caae32a | |||
| bc09956d79 | |||
| 7104861614 | |||
| 22288d9854 | |||
| 7703aa5cd3 | |||
| 17896f9841 | |||
| a67f82975e | |||
| 9bc9116d24 | |||
| 1ff47f246b | |||
| 2b1c09dd42 | |||
| 4559bbbb9a | |||
| 700c30d465 | |||
| 2d8a8e3575 | |||
| 9ea6bcb7b3 | |||
| 394e0ab3be | |||
| fc533c6598 | |||
| 40709245ad | |||
| 1e6bad6c4f | |||
| 6d95ac9299 | |||
| ce003f4eec | |||
| f737131d27 | |||
| f54c153775 | |||
| f2436eaf7b | |||
| 2f9387630f | |||
| c1895ad823 | |||
| f60e5950dc | |||
| 5ae37c6d99 | |||
| d91c612eab | |||
| 3894f04d0e | |||
| a39d55e5b0 | |||
| fc5966a347 | |||
| 55a4b4a174 | |||
| 045446c3da | |||
| f0120700dc | |||
| 6b740c86f9 | |||
| fb6de419f6 | |||
| 1e561035e2 | |||
| 0a23c4678f | |||
| edc21ef202 | |||
| 2441409b34 | |||
| ae01669737 | |||
| 21103ad811 | |||
| 6e5573f5bb | |||
| e17d51df66 | |||
| 01f63c87b2 | |||
| e449bd8459 | |||
| edb69f0bb3 | |||
| cf48d15c2c | |||
| 7cc49ba288 | |||
| 6809a78321 | |||
| c1002b20ee | |||
| fdf3ae31c6 | |||
| f915c6bb5c | |||
| 659c1c41de | |||
| 8f2be7e840 | |||
| 14772602a0 | |||
| 93921f32bd | |||
| 812c8926ec | |||
| b14bc4749e | |||
| d56276f6d6 | |||
| f1d44635bd | |||
| de8cb17ee8 | |||
| e69eb24b32 | |||
| 4a388b5540 | |||
| 25bedcd85d | |||
| feb3d3b274 | |||
| e191519d30 | |||
| aa1921cbef | |||
| e2abb0211c | |||
| b024c9a743 | |||
| 91c60dcac0 | |||
| 66117d1017 | |||
| 177302cf4d | |||
| d1fc90e8a2 | |||
| da152ac37e | |||
| 29d4821e3d | |||
| cbd03cda56 | |||
| 018bbd6774 | |||
| e50e2136d2 | |||
| a5eeb99f37 | |||
| 52cb3b2ec4 | |||
| 9ca55cb5bf | |||
| bc4b2c142f | |||
| b65d7c86d7 | |||
| cc37c9c86c | |||
| e41a4ced8b | |||
| eb2699aa9f | |||
| fcab393c3b | |||
| 8a6de521e7 | |||
| 88db5509a3 | |||
| 7538ff9798 | |||
| c0a60ece97 | |||
| c799b05f2a | |||
| d468dd2f3b | |||
| 029fc0fdef | |||
| c43737324a | |||
| 270e643c7b | |||
| edd8d55b42 | |||
| 3b50f2e8b9 | |||
| d4dd7969d6 | |||
| a0bebefef8 | |||
| 42a4c62025 | |||
| dd198cfc06 | |||
| 3ef96c445f | |||
| d9c39f6795 | |||
| aec7ca8200 | |||
| f567bf62e1 | |||
| 1f00cdc7a6 | |||
| dc875b6af9 | |||
| e2873bc614 | |||
| 3e4bfa2bae | |||
| 9bbf09fb0a | |||
| c874f65d95 | |||
| 8a12628af9 | |||
| 17e0618ff6 | |||
| 73d5f7061b | |||
| ccbaa020ff | |||
| a9c89fa23e | |||
| 36730537cc | |||
| 9456f6eea1 | |||
| 2c630a74cd | |||
| 9462b3fea2 | |||
| d62313e75c | |||
| 023bf9aea7 | |||
| 4bc593c761 | |||
| f47e6dda78 | |||
| 5c2d9d6f19 | |||
| 5efa8071d6 | |||
| 659832ccab | |||
| 913f6d4a4f | |||
| cb386ec2a2 | |||
| 2f873052f9 | |||
| 60aceb984f | |||
| 9dbd79f2d8 | |||
| 0aabf47f09 | |||
| 2961cc44c5 | |||
| 46da364289 | |||
| cb99370ce4 | |||
| c2d1a21f9c | |||
| edc6790fbb | |||
| b0d7889b20 | |||
| 867f2de194 | |||
| 50e2a8239b | |||
| 42f9ea07e2 | |||
| 9b28153571 | |||
| 2e1e7e7265 | |||
| 7369ce58da | |||
| c7a6d1e8bf | |||
| 17b40ca148 | |||
| 29d424ef91 | |||
| 27e9b87fbd | |||
| f2ac5576c2 | |||
| 590a1c2f3a | |||
| 75b186eb62 | |||
| 998c787638 | |||
| b2ab0b1fcb | |||
| b19526489e | |||
| 856728ea10 | |||
| df2fb3b520 | |||
| 48c650c102 | |||
| ccf18c239d | |||
| 48b408e2c3 | |||
| 433de2849d | |||
| 94deb551aa | |||
| 9767b3a97e | |||
| 676e9ab127 | |||
| 5b15bc86a3 | |||
| bad392eb2a | |||
| 278f976add | |||
| f58ece72cf | |||
| af3f34ca94 | |||
| 07a5cf4996 | |||
| d808298b68 | |||
| 108b7025dc | |||
| 9822d2b6b2 | |||
| a36594e754 | |||
| c331e22f3a | |||
| d077f113b2 | |||
| 1ab89b3908 | |||
| c5da579cda | |||
| 38bbcb7411 | |||
| 3223f3e3b8 | |||
| ba885e2ace | |||
| 9cc051ffa5 | |||
| e8dd40ccca | |||
| 53263d3d27 | |||
| 71c935d1f4 | |||
| 5e07e216d3 | |||
| 88894b705b | |||
| b8d01bf041 | |||
| c636ea036a | |||
| 08099ed17d | |||
| f0e8ee3c29 | |||
| 33a1cf203e | |||
| 5adce748cb | |||
| 21d39b6054 | |||
| a2f30ac1ab | |||
| 3764b27bab | |||
| 8fb610915c | |||
| 16a7e3e3d8 | |||
| 47ea51efab | |||
| 50554bb92b | |||
| 0ea0fc9c7b | |||
| 206e837dde | |||
| f43d0365dd | |||
| 72a557087c | |||
| b59f9b97f3 | |||
| a1f4735652 | |||
| c5e372490d | |||
| 78e083b014 | |||
| 6ac723321f | |||
| 343b08f3e6 | |||
| c8d1f23ff5 | |||
| 8a7fd71697 | |||
| 39fcfa4473 | |||
| d188c6dbaf | |||
| 8aec0dc200 | |||
| 9053fd8335 | |||
| a9720259f0 | |||
| b012886294 | |||
| 5de26c684b | |||
| b1d9259e7d | |||
| 89bba41fd7 | |||
| 248d7ec93c | |||
| 2be2912e43 | |||
| 2755ad19be | |||
| 156f99560d | |||
| 159e9de034 | |||
| f679b0648b | |||
| f1ffa6eae9 | |||
| ec1b61494f | |||
| cc561915b7 | |||
| 15707acb82 | |||
| a8ce293bfc | |||
| 4eee322654 | |||
| 67ae05d855 | |||
| 5c535517b5 | |||
| ded6bc04ff | |||
| 3e8179c66e | |||
| 3c21d6bf92 | |||
| 4c7af43eb3 | |||
| 5ce96d5f3b | |||
| 6b61cd1869 | |||
| 9bbf5966d3 |
@@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
||||
|
||||
:: FIXME: make warnings fatal
|
||||
pip3 install --upgrade --user meson==0.59 || goto :error
|
||||
meson -Dmedia-gstreamer=disabled _build || goto :error
|
||||
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
|
||||
ninja -C _build || goto :error
|
||||
|
||||
goto :EOF
|
||||
|
||||
@@ -15,9 +15,9 @@ pacman --noconfirm -Suy
|
||||
pacman --noconfirm -S --needed \
|
||||
base-devel \
|
||||
git \
|
||||
mingw-w64-$MSYS2_ARCH-toolchain \
|
||||
mingw-w64-$MSYS2_ARCH-cc \
|
||||
mingw-w64-$MSYS2_ARCH-ccache \
|
||||
mingw-w64-$MSYS2_ARCH-pkg-config \
|
||||
mingw-w64-$MSYS2_ARCH-pkgconf \
|
||||
mingw-w64-$MSYS2_ARCH-gobject-introspection \
|
||||
mingw-w64-$MSYS2_ARCH-meson \
|
||||
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
|
||||
@@ -30,7 +30,7 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-libepoxy \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
mingw-w64-$MSYS2_ARCH-python-gobject
|
||||
|
||||
|
||||
@@ -1,3 +1,202 @@
|
||||
Overview of Changes in 4.6.5, 27-05-2022
|
||||
========================================
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix pasting text into the name field
|
||||
|
||||
* GtkText:
|
||||
- Remove an assertion that is sometimes hit
|
||||
|
||||
* Wayland:
|
||||
- Ensure that our cursor surfaces don't violate
|
||||
protocol constraints
|
||||
|
||||
* Accssibility:
|
||||
- Fix a problem in the accessibility tree
|
||||
|
||||
* Translation updates:
|
||||
Brazilian Portuguese
|
||||
German
|
||||
Persian
|
||||
Polish
|
||||
Portuguese
|
||||
Russian
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.6.4, 13-05-2022
|
||||
========================================
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix select button sensitivity in select_folder mode
|
||||
- Fix some fallout from list model porting
|
||||
|
||||
* GtkListView, GtkColumnView:
|
||||
- Optimize scrolling
|
||||
|
||||
* print-to-file:
|
||||
- Handle nonexisting files better in the dialog
|
||||
|
||||
* Avoid infinite loops in size allocation
|
||||
|
||||
* CSS:
|
||||
- Optimize a case of reparenting that is important in GtkListView
|
||||
|
||||
* GSK:
|
||||
- Check for half-float support before using it
|
||||
|
||||
* Wayland:
|
||||
- Ignore empty preedit updates This fixes a problem with
|
||||
textview scrolling
|
||||
- Freeze popups when hidden. This addresses a frame rate drop
|
||||
|
||||
* Translation updates
|
||||
Hebrew
|
||||
Nepali
|
||||
|
||||
|
||||
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
|
||||
========================================
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ do_cursors (GtkWidget *do_widget)
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
@@ -34,9 +35,7 @@ do_cursors (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
}
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -1040,7 +1040,7 @@ out:
|
||||
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
|
||||
}
|
||||
else
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
if (autoquit)
|
||||
g_timeout_add_seconds (1, auto_quit, app);
|
||||
|
||||
@@ -160,7 +160,7 @@ endif
|
||||
|
||||
ld = find_program('ld', required : false)
|
||||
|
||||
if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
|
||||
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
|
||||
glib_compile_resources = find_program('glib-compile-resources')
|
||||
|
||||
# Create the resource blob
|
||||
|
||||
@@ -871,7 +871,7 @@ activate (GApplication *app)
|
||||
|
||||
update_ui ();
|
||||
|
||||
gtk_widget_show (main_window);
|
||||
gtk_window_present (GTK_WINDOW (main_window));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -8,7 +8,7 @@ endif
|
||||
|
||||
ld = find_program('ld', required : false)
|
||||
|
||||
if build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
|
||||
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
|
||||
glib_compile_resources = find_program('glib-compile-resources')
|
||||
|
||||
# Create the resource blob
|
||||
|
||||
@@ -2360,7 +2360,7 @@ activate (GApplication *app)
|
||||
model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model");
|
||||
set_up_context_popover (widget, model);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_window_present (window);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
@@ -479,7 +479,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">page1</property>
|
||||
<property name="title" translatable="1">Page _1</property>
|
||||
<property name="title" translatable="yes">Page _1</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="page1">
|
||||
@@ -497,7 +497,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="has-entry">1</property>
|
||||
<child internal-child="entry">
|
||||
<object class="GtkEntry" id="comboboxtext-entry">
|
||||
<property name="text" translatable="1">comboboxentry</property>
|
||||
<property name="text" translatable="yes">comboboxentry</property>
|
||||
</object>
|
||||
</child>
|
||||
<items>
|
||||
@@ -514,7 +514,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child internal-child="entry">
|
||||
<object class="GtkEntry" id="comboboxtext-entry2">
|
||||
<property name="invisible-char">•</property>
|
||||
<property name="text" translatable="1">comboboxentry</property>
|
||||
<property name="text" translatable="yes">comboboxentry</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -523,7 +523,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<object class="GtkEntry" id="entry1">
|
||||
<property name="enable-emoji-completion">1</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="placeholder-text" translatable="1">Click icon to change mode</property>
|
||||
<property name="placeholder-text" translatable="yes">Click icon to change mode</property>
|
||||
<property name="secondary-icon-name">view-refresh-symbolic</property>
|
||||
<property name="secondary-icon-tooltip-text">Change mode</property>
|
||||
<signal name="icon-release" handler="on_entry_icon_release" swapped="no"/>
|
||||
@@ -532,7 +532,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry2">
|
||||
<property name="sensitive">0</property>
|
||||
<property name="text" translatable="1">entry</property>
|
||||
<property name="text" translatable="yes">entry</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -543,7 +543,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry24">
|
||||
<property name="enable-emoji-completion">1</property>
|
||||
<property name="text" translatable="1">entry</property>
|
||||
<property name="text" translatable="yes">entry</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -557,7 +557,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkPasswordEntry">
|
||||
<property name="show-peek-icon">1</property>
|
||||
<property name="placeholder-text" translatable="1">Password…</property>
|
||||
<property name="placeholder-text" translatable="yes">Password…</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -612,13 +612,13 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="spacing">20</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="label" translatable="1">label</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="sensitive">0</property>
|
||||
<property name="label" translatable="1">label</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -644,13 +644,13 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton1">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton2">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
@@ -659,7 +659,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton3">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
@@ -669,7 +669,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton4">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
@@ -680,7 +680,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton5">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
@@ -690,7 +690,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="checkbutton6">
|
||||
<property name="label" translatable="1">checkbutton</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<layout>
|
||||
@@ -701,7 +701,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton1">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
@@ -711,7 +711,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="group">radiobutton1</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
@@ -721,7 +721,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton3">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<property name="group">radiobutton1</property>
|
||||
<layout>
|
||||
@@ -732,7 +732,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton4">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
@@ -743,7 +743,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton5">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="group">radiobutton4</property>
|
||||
<layout>
|
||||
@@ -754,7 +754,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="radiobutton6">
|
||||
<property name="label" translatable="1">radiobutton</property>
|
||||
<property name="label" translatable="yes">radiobutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="inconsistent">1</property>
|
||||
<property name="group">radiobutton4</property>
|
||||
@@ -809,27 +809,27 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton1">
|
||||
<property name="label" translatable="1">togglebutton</property>
|
||||
<property name="label" translatable="yes">togglebutton</property>
|
||||
<property name="receives-default">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton2">
|
||||
<property name="label" translatable="1">togglebutton</property>
|
||||
<property name="label" translatable="yes">togglebutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="receives-default">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton3">
|
||||
<property name="label" translatable="1">togglebutton</property>
|
||||
<property name="label" translatable="yes">togglebutton</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton4">
|
||||
<property name="label" translatable="1">togglebutton</property>
|
||||
<property name="label" translatable="yes">togglebutton</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="active">1</property>
|
||||
@@ -874,7 +874,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLinkButton" id="linkbutton1">
|
||||
<property name="label" translatable="1">link button</property>
|
||||
<property name="label" translatable="yes">link button</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="has-tooltip">1</property>
|
||||
<property name="has-frame">0</property>
|
||||
@@ -1061,7 +1061,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<object class="GtkFrame">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="label" translatable="1"><b>Text Styles</b></property>
|
||||
<property name="label" translatable="yes"><b>Text Styles</b></property>
|
||||
<property name="use-markup">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -1176,7 +1176,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="treeviewcolumn3">
|
||||
<property name="title" translatable="1">Cool</property>
|
||||
<property name="title" translatable="yes">Cool</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="cellrenderertoggle1"/>
|
||||
<attributes>
|
||||
@@ -1188,7 +1188,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="treeviewcolumn4">
|
||||
<property name="title" translatable="1">Icon</property>
|
||||
<property name="title" translatable="yes">Icon</property>
|
||||
<property name="reorderable">1</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="cellrendererpixbuf1"/>
|
||||
@@ -1200,7 +1200,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
|
||||
<property name="title" translatable="1">Name</property>
|
||||
<property name="title" translatable="yes">Name</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="reorderable">1</property>
|
||||
<property name="sort-indicator">1</property>
|
||||
@@ -1217,7 +1217,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="treeviewcolumn2">
|
||||
<property name="title" translatable="1">Nick</property>
|
||||
<property name="title" translatable="yes">Nick</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="reorderable">1</property>
|
||||
<property name="sort-indicator">1</property>
|
||||
@@ -1281,7 +1281,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="label" translatable="1">Sunset</property>
|
||||
<property name="label" translatable="yes">Sunset</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1307,7 +1307,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="label" translatable="1">NYC</property>
|
||||
<property name="label" translatable="yes">NYC</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1333,7 +1333,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label7">
|
||||
<property name="label" translatable="1">Beach</property>
|
||||
<property name="label" translatable="yes">Beach</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1352,7 +1352,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="label" translatable="1">page 1</property>
|
||||
<property name="label" translatable="yes">page 1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1367,7 +1367,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label9">
|
||||
<property name="label" translatable="1">page 2</property>
|
||||
<property name="label" translatable="yes">page 2</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1382,7 +1382,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label10">
|
||||
<property name="label" translatable="1">page 3</property>
|
||||
<property name="label" translatable="yes">page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1401,7 +1401,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label11">
|
||||
<property name="label" translatable="1">page 1</property>
|
||||
<property name="label" translatable="yes">page 1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1416,7 +1416,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label12">
|
||||
<property name="label" translatable="1">page 2</property>
|
||||
<property name="label" translatable="yes">page 2</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1431,7 +1431,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label13">
|
||||
<property name="label" translatable="1">page 3</property>
|
||||
<property name="label" translatable="yes">page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1450,7 +1450,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label14">
|
||||
<property name="label" translatable="1">page 1</property>
|
||||
<property name="label" translatable="yes">page 1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1465,7 +1465,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label15">
|
||||
<property name="label" translatable="1">page 2</property>
|
||||
<property name="label" translatable="yes">page 2</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1480,7 +1480,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel" id="label16">
|
||||
<property name="label" translatable="1">page 3</property>
|
||||
<property name="label" translatable="yes">page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -1496,7 +1496,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">page2</property>
|
||||
<property name="title" translatable="1">Page _2</property>
|
||||
<property name="title" translatable="yes">Page _2</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkOverlay" id="page2">
|
||||
@@ -1527,7 +1527,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="page2reset">
|
||||
<property name="valign">3</property>
|
||||
<property name="label" translatable="1">Reset</property>
|
||||
<property name="label" translatable="yes">Reset</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1700,7 +1700,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 1</property>
|
||||
<property name="label" translatable="yes">Row 1</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1723,7 +1723,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 2</property>
|
||||
<property name="label" translatable="yes">Row 2</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1747,7 +1747,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 3</property>
|
||||
<property name="label" translatable="yes">Row 3</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1772,7 +1772,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 4</property>
|
||||
<property name="label" translatable="yes">Row 4</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1797,7 +1797,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 5</property>
|
||||
<property name="label" translatable="yes">Row 5</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1821,7 +1821,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 6</property>
|
||||
<property name="label" translatable="yes">Row 6</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1843,7 +1843,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 7</property>
|
||||
<property name="label" translatable="yes">Row 7</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1859,7 +1859,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Row 8</property>
|
||||
<property name="label" translatable="yes">Row 8</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
@@ -1896,16 +1896,16 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="1">New</property>
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="icon-name">document-new</property>
|
||||
<property name="tooltip-text" translatable="1">Create a new document</property>
|
||||
<property name="tooltip-text" translatable="yes">Create a new document</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="1">Save</property>
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
<property name="icon-name">document-save</property>
|
||||
<property name="tooltip-text" translatable="1">Save the current document</property>
|
||||
<property name="tooltip-text" translatable="yes">Save the current document</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1913,24 +1913,24 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="1">Search</property>
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
<property name="icon-name">edit-find</property>
|
||||
<property name="action-name">win.search</property>
|
||||
<property name="tooltip-text" translatable="1">Search for it</property>
|
||||
<property name="tooltip-text" translatable="yes">Search for it</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="sensitive">0</property>
|
||||
<property name="label" translatable="1">Insert</property>
|
||||
<property name="label" translatable="yes">Insert</property>
|
||||
<property name="icon-name">insert-image</property>
|
||||
<property name="tooltip-text" translatable="1">Insert something</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert something</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton">
|
||||
<property name="rgba">#9141AC</property>
|
||||
<property name="tooltip-text" translatable="1">Select a color</property>
|
||||
<property name="tooltip-text" translatable="yes">Select a color</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2107,32 +2107,32 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label19">
|
||||
<property name="label" translatable="1">Expander</property>
|
||||
<property name="label" translatable="yes">Expander</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="info_dialog_button">
|
||||
<property name="label" translatable="1">_Inform</property>
|
||||
<property name="label" translatable="yes">_Inform</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="action_dialog_button">
|
||||
<property name="label" translatable="1">_Act</property>
|
||||
<property name="label" translatable="yes">_Act</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="preference_dialog_button">
|
||||
<property name="label" translatable="1">_Configure</property>
|
||||
<property name="label" translatable="yes">_Configure</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="selection_dialog_button">
|
||||
<property name="label" translatable="1">S_elect</property>
|
||||
<property name="label" translatable="yes">S_elect</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2147,7 +2147,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">page3</property>
|
||||
<property name="title" translatable="1">Page _3</property>
|
||||
<property name="title" translatable="yes">Page _3</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
@@ -2179,7 +2179,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="1">Name</property>
|
||||
<property name="title" translatable="yes">Name</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
@@ -2190,7 +2190,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="1">Birth</property>
|
||||
<property name="title" translatable="yes">Birth</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
@@ -2201,7 +2201,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="1">Death</property>
|
||||
<property name="title" translatable="yes">Death</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
@@ -2219,7 +2219,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="selectable">1</property>
|
||||
<property name="halign">1</property>
|
||||
<property name="use-markup">1</property>
|
||||
<property name="label" translatable="1"><small>Data source: <a href="http://en.wikipedia.org/wiki/Charlemagne#Ancestry">Wikipedia</a></small></property>
|
||||
<property name="label" translatable="yes"><small>Data source: <a href="http://en.wikipedia.org/wiki/Charlemagne#Ancestry">Wikipedia</a></small></property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2553,28 +2553,28 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkButton" id="toolbutton1">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Insert ⌘</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert ⌘</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="toolbutton2">
|
||||
<property name="icon-name">send-to-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Insert ⚽</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert ⚽</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="toolbutton3">
|
||||
<property name="icon-name">view-fullscreen-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Insert ⤢</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert ⤢</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="toolbutton4">
|
||||
<property name="icon-name">star-new-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Insert ☆</property>
|
||||
<property name="tooltip-text" translatable="yes">Insert ☆</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2602,7 +2602,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="icon-name">edit-cut-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Cut</property>
|
||||
<property name="tooltip-text" translatable="yes">Cut</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2610,7 +2610,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="icon-name">edit-copy-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Copy</property>
|
||||
<property name="tooltip-text" translatable="yes">Copy</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2618,7 +2618,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="icon-name">edit-paste-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Paste</property>
|
||||
<property name="tooltip-text" translatable="yes">Paste</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2629,7 +2629,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="valign">2</property>
|
||||
<property name="icon-name">edit-delete-symbolic</property>
|
||||
<property name="focus-on-click">0</property>
|
||||
<property name="tooltip-text" translatable="1">Delete</property>
|
||||
<property name="tooltip-text" translatable="yes">Delete</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2715,7 +2715,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 1</property>
|
||||
<property name="label" translatable="yes">Page 1</property>
|
||||
<property name="halign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
@@ -2747,7 +2747,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 2</property>
|
||||
<property name="label" translatable="yes">Page 2</property>
|
||||
<property name="halign">3</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
@@ -2781,7 +2781,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 3</property>
|
||||
<property name="label" translatable="yes">Page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2810,7 +2810,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="placeholder-text" translatable="1">Name…</property>
|
||||
<property name="placeholder-text" translatable="yes">Name…</property>
|
||||
<property name="completion">name_completion</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2818,7 +2818,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<object class="GtkEntry">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="show-emoji-icon">1</property>
|
||||
<property name="placeholder-text" translatable="1">Age…</property>
|
||||
<property name="placeholder-text" translatable="yes">Age…</property>
|
||||
<signal name="notify::text" handler="age_entry_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2851,7 +2851,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 1</property>
|
||||
<property name="label" translatable="yes">Page 1</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2866,7 +2866,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 2</property>
|
||||
<property name="label" translatable="yes">Page 2</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2879,7 +2879,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 3</property>
|
||||
<property name="label" translatable="yes">Page 3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2892,7 +2892,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 4</property>
|
||||
<property name="label" translatable="yes">Page 4</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2905,7 +2905,7 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</property>
|
||||
<property name="tab">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="1">Page 5</property>
|
||||
<property name="label" translatable="yes">Page 5</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
@@ -2932,19 +2932,19 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="transient-for">window</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="text" translatable="1">Do something?</property>
|
||||
<property name="secondary-text" translatable="1">If you don't do something,
|
||||
<property name="text" translatable="yes">Do something?</property>
|
||||
<property name="secondary-text" translatable="yes">If you don't do something,
|
||||
bad things might happen.</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="cancel_info_dialog">
|
||||
<property name="label" translatable="1">_Cancel</property>
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="doit_info_dialog">
|
||||
<property name="label" translatable="1">_Do It</property>
|
||||
<property name="label" translatable="yes">_Do It</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2958,7 +2958,7 @@ bad things might happen.</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="1">Zelda</property>
|
||||
<property name="title" translatable="yes">Zelda</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="default-widget">act_action_dialog</property>
|
||||
<child internal-child="content_area">
|
||||
@@ -2969,20 +2969,20 @@ bad things might happen.</property>
|
||||
<property name="margin-end">20</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">20</property>
|
||||
<property name="label" translatable="1">To free the princess, you have to slay the dragon.</property>
|
||||
<property name="label" translatable="yes">To free the princess, you have to slay the dragon.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="cancel_action_dialog">
|
||||
<property name="label" translatable="1">_Run</property>
|
||||
<property name="label" translatable="yes">_Run</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="act_action_dialog">
|
||||
<property name="label" translatable="1">_Act</property>
|
||||
<property name="label" translatable="yes">_Act</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2996,7 +2996,7 @@ bad things might happen.</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="1">Settings</property>
|
||||
<property name="title" translatable="yes">Settings</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
@@ -3141,7 +3141,7 @@ bad things might happen.</property>
|
||||
<property name="transient-for">window</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="1">Choose one</property>
|
||||
<property name="title" translatable="yes">Choose one</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="default-widget">select_selection_dialog</property>
|
||||
<child internal-child="content_area">
|
||||
@@ -3162,13 +3162,13 @@ bad things might happen.</property>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="cancel_selection_dialog">
|
||||
<property name="label" translatable="1">_Cancel</property>
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="select_selection_dialog">
|
||||
<property name="label" translatable="1">_Select</property>
|
||||
<property name="label" translatable="yes">_Select</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "GPL-2.1-or-later"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
devhelp = true
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
website_url = "https://www.gtk.org"
|
||||
authors = "GTK Development Team"
|
||||
logo_url = "gtk-logo.svg"
|
||||
license = "GPL-2.1-or-later"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "The GTK toolkit"
|
||||
dependencies = ["Gdk-4.0"]
|
||||
devhelp = true
|
||||
|
||||
@@ -57,7 +57,7 @@ if get_option('gtk_doc')
|
||||
)
|
||||
endif
|
||||
|
||||
rst2man = find_program('rst2man', required: false)
|
||||
rst2man = find_program('rst2man', 'rst2man.py', required: false)
|
||||
if get_option('man-pages') and not rst2man.found()
|
||||
error('No rst2man found, but man pages were explicitly enabled')
|
||||
endif
|
||||
|
||||
@@ -372,7 +372,7 @@ library you are using:
|
||||
The `test` accessibility backend is recommended for test suites and remote
|
||||
continuous integration pipelines.
|
||||
|
||||
### `XDG_DTA_HOME`, `XDG_DATA_DIRS`
|
||||
### `XDG_DATA_HOME`, `XDG_DATA_DIRS`
|
||||
|
||||
GTK uses these environment variables to locate icon themes
|
||||
and MIME information. For more information, see the
|
||||
|
||||
@@ -354,6 +354,7 @@ typedef struct {
|
||||
|
||||
typedef union {
|
||||
BroadwayReplyBase base;
|
||||
BroadwayReplySync sync;
|
||||
BroadwayReplyEvent event;
|
||||
BroadwayReplyQueryMouse query_mouse;
|
||||
BroadwayReplyNewSurface new_surface;
|
||||
|
||||
+14
-18
@@ -219,11 +219,7 @@ static void
|
||||
client_handle_request (BroadwayClient *client,
|
||||
BroadwayRequest *request)
|
||||
{
|
||||
BroadwayReplyNewSurface reply_new_surface;
|
||||
BroadwayReplySync reply_sync;
|
||||
BroadwayReplyQueryMouse reply_query_mouse;
|
||||
BroadwayReplyGrabPointer reply_grab_pointer;
|
||||
BroadwayReplyUngrabPointer reply_ungrab_pointer;
|
||||
BroadwayReply reply;
|
||||
guint32 before_serial, now_serial;
|
||||
guint32 global_id;
|
||||
int fd;
|
||||
@@ -233,7 +229,7 @@ client_handle_request (BroadwayClient *client,
|
||||
switch (request->base.type)
|
||||
{
|
||||
case BROADWAY_REQUEST_NEW_SURFACE:
|
||||
reply_new_surface.id =
|
||||
reply.new_surface.id =
|
||||
broadway_server_new_surface (server, client->id,
|
||||
request->new_surface.x,
|
||||
request->new_surface.y,
|
||||
@@ -241,9 +237,9 @@ client_handle_request (BroadwayClient *client,
|
||||
request->new_surface.height);
|
||||
client->surfaces =
|
||||
g_list_prepend (client->surfaces,
|
||||
GUINT_TO_POINTER (reply_new_surface.id));
|
||||
GUINT_TO_POINTER (reply.new_surface.id));
|
||||
|
||||
send_reply (client, request, (BroadwayReply *)&reply_new_surface, sizeof (reply_new_surface),
|
||||
send_reply (client, request, &reply, sizeof (reply.new_surface),
|
||||
BROADWAY_REPLY_NEW_SURFACE);
|
||||
break;
|
||||
case BROADWAY_REQUEST_FLUSH:
|
||||
@@ -251,7 +247,7 @@ client_handle_request (BroadwayClient *client,
|
||||
break;
|
||||
case BROADWAY_REQUEST_SYNC:
|
||||
broadway_server_flush (server);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_sync, sizeof (reply_sync),
|
||||
send_reply (client, request, &reply, sizeof (reply.sync),
|
||||
BROADWAY_REPLY_SYNC);
|
||||
break;
|
||||
case BROADWAY_REQUEST_ROUNDTRIP:
|
||||
@@ -261,11 +257,11 @@ client_handle_request (BroadwayClient *client,
|
||||
break;
|
||||
case BROADWAY_REQUEST_QUERY_MOUSE:
|
||||
broadway_server_query_mouse (server,
|
||||
&reply_query_mouse.surface,
|
||||
&reply_query_mouse.root_x,
|
||||
&reply_query_mouse.root_y,
|
||||
&reply_query_mouse.mask);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_query_mouse, sizeof (reply_query_mouse),
|
||||
&reply.query_mouse.surface,
|
||||
&reply.query_mouse.root_x,
|
||||
&reply.query_mouse.root_y,
|
||||
&reply.query_mouse.mask);
|
||||
send_reply (client, request, &reply, sizeof (reply.query_mouse),
|
||||
BROADWAY_REPLY_QUERY_MOUSE);
|
||||
break;
|
||||
case BROADWAY_REQUEST_DESTROY_SURFACE:
|
||||
@@ -361,21 +357,21 @@ client_handle_request (BroadwayClient *client,
|
||||
request->move_resize.height);
|
||||
break;
|
||||
case BROADWAY_REQUEST_GRAB_POINTER:
|
||||
reply_grab_pointer.status =
|
||||
reply.grab_pointer.status =
|
||||
broadway_server_grab_pointer (server,
|
||||
client->id,
|
||||
request->grab_pointer.id,
|
||||
request->grab_pointer.owner_events,
|
||||
request->grab_pointer.event_mask,
|
||||
request->grab_pointer.time_);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_grab_pointer, sizeof (reply_grab_pointer),
|
||||
send_reply (client, request, &reply, sizeof (reply.grab_pointer),
|
||||
BROADWAY_REPLY_GRAB_POINTER);
|
||||
break;
|
||||
case BROADWAY_REQUEST_UNGRAB_POINTER:
|
||||
reply_ungrab_pointer.status =
|
||||
reply.ungrab_pointer.status =
|
||||
broadway_server_ungrab_pointer (server,
|
||||
request->ungrab_pointer.time_);
|
||||
send_reply (client, request, (BroadwayReply *)&reply_ungrab_pointer, sizeof (reply_ungrab_pointer),
|
||||
send_reply (client, request, &reply, sizeof (reply.ungrab_pointer),
|
||||
BROADWAY_REPLY_UNGRAB_POINTER);
|
||||
break;
|
||||
case BROADWAY_REQUEST_FOCUS_SURFACE:
|
||||
|
||||
@@ -576,7 +576,7 @@ gdk_content_deserialize_async (GInputStream *stream,
|
||||
/**
|
||||
* gdk_content_deserialize_finish:
|
||||
* @result: the `GAsyncResult`
|
||||
* @value: return location for the result of the operation
|
||||
* @value: (out): return location for the result of the operation
|
||||
* @error: return location for an error
|
||||
*
|
||||
* Finishes a content deserialization operation.
|
||||
|
||||
+3
-5
@@ -1628,10 +1628,10 @@ gdk_display_check_egl_extensions (EGLDisplay egl_display,
|
||||
/* translators: Arguments are the number of missing extensions
|
||||
* followed by a comma-separated list of their names */
|
||||
g_dngettext (GETTEXT_PACKAGE,
|
||||
"EGL implementation is missing extension %2$s",
|
||||
"EGL implementation is missing %d extensions: %s",
|
||||
"EGL implementation is missing extension %s",
|
||||
"EGL implementation is missing %2$d extensions: %1$s",
|
||||
n_missing),
|
||||
(int) n_missing, missing->str);
|
||||
missing->str, (int) n_missing);
|
||||
|
||||
g_string_free (missing, TRUE);
|
||||
return FALSE;
|
||||
@@ -1721,8 +1721,6 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
|
||||
self->have_egl_buffer_age =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_buffer_age");
|
||||
self->have_egl_swap_buffers_with_damage =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_swap_buffers_with_damage");
|
||||
self->have_egl_no_config_context =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
||||
self->have_egl_pixel_format_float =
|
||||
|
||||
@@ -107,7 +107,6 @@ struct _GdkDisplay
|
||||
|
||||
/* egl info */
|
||||
guint have_egl_buffer_age : 1;
|
||||
guint have_egl_swap_buffers_with_damage : 1;
|
||||
guint have_egl_no_config_context : 1;
|
||||
guint have_egl_pixel_format_float : 1;
|
||||
guint have_egl_win32_libangle : 1;
|
||||
|
||||
+26
-6
@@ -1,7 +1,7 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* gdkglcontext.c: GL context abstraction
|
||||
*
|
||||
*
|
||||
* Copyright © 2014 Emmanuele Bassi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -103,6 +103,7 @@ typedef struct {
|
||||
|
||||
guint has_khr_debug : 1;
|
||||
guint use_khr_debug : 1;
|
||||
guint has_half_float : 1;
|
||||
guint has_unpack_subimage : 1;
|
||||
guint has_debug_output : 1;
|
||||
guint extensions_checked : 1;
|
||||
@@ -117,6 +118,7 @@ typedef struct {
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
EGLContext egl_context;
|
||||
EGLBoolean (*eglSwapBuffersWithDamage) (EGLDisplay, EGLSurface, const EGLint *, EGLint);
|
||||
#endif
|
||||
} GdkGLContextPrivate;
|
||||
|
||||
@@ -420,6 +422,11 @@ gdk_gl_context_real_realize (GdkGLContext *context,
|
||||
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
|
||||
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
|
||||
priv->eglSwapBuffersWithDamage = (gpointer)epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageKHR");
|
||||
else if (epoxy_has_egl_extension (egl_display, "EGL_EXT_swap_buffers_with_damage"))
|
||||
priv->eglSwapBuffersWithDamage = (gpointer)epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageEXT");
|
||||
|
||||
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
|
||||
|
||||
return api;
|
||||
@@ -608,7 +615,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "EGL", "swap buffers");
|
||||
|
||||
if (display->have_egl_swap_buffers_with_damage)
|
||||
if (priv->eglSwapBuffersWithDamage)
|
||||
{
|
||||
EGLint stack_rects[4 * 4]; /* 4 rects */
|
||||
EGLint *heap_rects = NULL;
|
||||
@@ -632,7 +639,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
||||
rects[j++] = rect.width * scale;
|
||||
rects[j++] = rect.height * scale;
|
||||
}
|
||||
eglSwapBuffersWithDamageEXT (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
|
||||
priv->eglSwapBuffersWithDamage (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
|
||||
g_free (heap_rects);
|
||||
}
|
||||
else
|
||||
@@ -1536,18 +1543,23 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
glGetIntegerv (GL_MAX_LABEL_LENGTH, &priv->max_debug_label_length);
|
||||
}
|
||||
|
||||
priv->has_half_float = gdk_gl_context_check_version (context, 3, 0, 3, 0) ||
|
||||
epoxy_has_gl_extension ("OES_vertex_half_float");
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), OPENGL,
|
||||
g_message ("%s version: %d.%d (%s)\n"
|
||||
"* GLSL version: %s\n"
|
||||
"* Extensions checked:\n"
|
||||
" - GL_KHR_debug: %s\n"
|
||||
" - GL_EXT_unpack_subimage: %s",
|
||||
" - GL_EXT_unpack_subimage: %s\n"
|
||||
" - OES_vertex_half_float: %s",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
priv->gl_version / 10, priv->gl_version % 10,
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
glGetString (GL_SHADING_LANGUAGE_VERSION),
|
||||
priv->has_khr_debug ? "yes" : "no",
|
||||
priv->has_unpack_subimage ? "yes" : "no"));
|
||||
priv->has_unpack_subimage ? "yes" : "no",
|
||||
priv->has_half_float ? "yes" : "no"));
|
||||
|
||||
priv->extensions_checked = TRUE;
|
||||
}
|
||||
@@ -1751,6 +1763,14 @@ gdk_gl_context_has_debug (GdkGLContext *self)
|
||||
return priv->debug_enabled || priv->use_khr_debug;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_has_vertex_half_float (GdkGLContext *self)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
return priv->has_half_float;
|
||||
}
|
||||
|
||||
/* This is currently private! */
|
||||
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
|
||||
gboolean
|
||||
@@ -1793,7 +1813,7 @@ gboolean
|
||||
gdk_gl_backend_can_be_used (GdkGLBackend backend_type,
|
||||
GError **error)
|
||||
{
|
||||
if (the_gl_backend_type == GDK_GL_NONE ||
|
||||
if (the_gl_backend_type == GDK_GL_NONE ||
|
||||
the_gl_backend_type == backend_type)
|
||||
return TRUE;
|
||||
|
||||
|
||||
@@ -139,6 +139,8 @@ gboolean gdk_gl_context_has_debug (GdkGLContext
|
||||
|
||||
gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context);
|
||||
|
||||
gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext *self) G_GNUC_PURE;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_GL_CONTEXT_PRIVATE_H__ */
|
||||
|
||||
@@ -365,6 +365,42 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
texture->format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
||||
break;
|
||||
|
||||
case GL_RGBA:
|
||||
{
|
||||
GLint red_size = 0;
|
||||
GLint green_size = 0;
|
||||
GLint blue_size = 0;
|
||||
GLint alpha_size = 0;
|
||||
GLint red_type = 0;
|
||||
GLint green_type = 0;
|
||||
GLint blue_type = 0;
|
||||
GLint alpha_type = 0;
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_RED_TYPE, &red_type);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_TYPE, &green_type);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_TYPE, &blue_type);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_TYPE, &alpha_type);
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &red_size);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &green_size);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &blue_size);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
|
||||
#define CHECK_RGBA(rt,gt,bt,at,rs,gs,bs,as) \
|
||||
(red_type == rt && green_type == gt && blue_type == bt && alpha_type == at && \
|
||||
red_size == rs && green_size == gs && blue_size == bs && alpha_size == as)
|
||||
|
||||
if (CHECK_RGBA (GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8))
|
||||
{
|
||||
texture->format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
break;
|
||||
}
|
||||
|
||||
#undef CHECK_RGBA
|
||||
}
|
||||
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
default:
|
||||
g_warning ("Texture in unexpected format 0x%X (%d). File a bug about adding it to GTK", internal_format, internal_format);
|
||||
/* fallback to the dumbest possible format
|
||||
|
||||
+2
-6
@@ -19,7 +19,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __GDKINTL_H__
|
||||
@@ -27,10 +27,6 @@
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
#define P_(String) dgettext(GETTEXT_PACKAGE "-properties",String)
|
||||
#else
|
||||
#define P_(String) (String)
|
||||
#endif
|
||||
#define P_(String) dgettext (GETTEXT_PACKAGE "-properties", String)
|
||||
|
||||
#endif
|
||||
|
||||
+86
-73
@@ -25,10 +25,6 @@
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#ifdef __ARM_NEON
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
typedef struct _GdkMemoryFormatDescription GdkMemoryFormatDescription;
|
||||
|
||||
#define TYPED_FUNCS(name, T, R, G, B, A, bpp, scale) \
|
||||
@@ -170,75 +166,54 @@ r32g32b32a32_float_from_float (guchar *dest,
|
||||
memcpy (dest, src, sizeof (float) * n * 4);
|
||||
}
|
||||
|
||||
// This one conversion is quite important, it converts from RGBA with straight
|
||||
// alpha (as found in PNG for instance) to BGRA with premultiplied alpha (the
|
||||
// sole cairo format available).
|
||||
static void
|
||||
r8g8b8a8_to_b8g8r8a8_premultiplied (guchar *dest,
|
||||
const guchar *src,
|
||||
gsize n)
|
||||
{
|
||||
#ifdef __ARM_NEON
|
||||
uint16x8_t one = vdupq_n_u16 (1);
|
||||
uint16x8_t half = vdupq_n_u16 (127);
|
||||
|
||||
for (gsize i = n / 8; i > 0; i--)
|
||||
{
|
||||
// Work on “just” 8 pixels at once, since we need the full 16-bytes of
|
||||
// the q registers for the multiplication.
|
||||
uint8x8x4_t rgba = vld4_u8 (src);
|
||||
uint8x8_t r8 = rgba.val[0];
|
||||
uint8x8_t g8 = rgba.val[1];
|
||||
uint8x8_t b8 = rgba.val[2];
|
||||
uint8x8_t a8 = rgba.val[3];
|
||||
|
||||
// This is the same algorithm as premultiply(), but on packed 16-bit
|
||||
// instead of float.
|
||||
uint16x8_t r16 = vmull_u8 (r8, a8);
|
||||
uint16x8_t g16 = vmull_u8 (g8, a8);
|
||||
uint16x8_t b16 = vmull_u8 (b8, a8);
|
||||
|
||||
r16 = vaddq_u16 (r16, half);
|
||||
g16 = vaddq_u16 (g16, half);
|
||||
b16 = vaddq_u16 (b16, half);
|
||||
|
||||
r16 = vsraq_n_u16 (r16, r16, 8);
|
||||
g16 = vsraq_n_u16 (g16, g16, 8);
|
||||
b16 = vsraq_n_u16 (b16, b16, 8);
|
||||
|
||||
r16 = vaddq_u16 (r16, one);
|
||||
g16 = vaddq_u16 (g16, one);
|
||||
b16 = vaddq_u16 (b16, one);
|
||||
|
||||
// Just like the other one, here we use BGRA instead of RGBA!
|
||||
rgba.val[0] = vshrn_n_u16 (b16, 8);
|
||||
rgba.val[1] = vshrn_n_u16 (g16, 8);
|
||||
rgba.val[2] = vshrn_n_u16 (r16, 8);
|
||||
|
||||
vst4_u8 (dest, rgba);
|
||||
src += 32;
|
||||
dest += 32;
|
||||
}
|
||||
|
||||
// We want the fallthrough here for the last (up to) seven bytes of the row.
|
||||
n = n % 8;
|
||||
#endif // __ARM_NEON
|
||||
|
||||
for (; n > 0; n--)
|
||||
{
|
||||
guchar a = src[3];
|
||||
guint16 r = (guint16)src[0] * a + 127;
|
||||
guint16 g = (guint16)src[1] * a + 127;
|
||||
guint16 b = (guint16)src[2] * a + 127;
|
||||
dest[0] = (b + (b >> 8) + 1) >> 8;
|
||||
dest[1] = (g + (g >> 8) + 1) >> 8;
|
||||
dest[2] = (r + (r >> 8) + 1) >> 8;
|
||||
dest[3] = a;
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
#define PREMULTIPLY_FUNC(name, R1, G1, B1, A1, R2, G2, B2, A2) \
|
||||
static void \
|
||||
name (guchar *dest, \
|
||||
const guchar *src, \
|
||||
gsize n) \
|
||||
{ \
|
||||
for (; n > 0; n--) \
|
||||
{ \
|
||||
guchar a = src[A1]; \
|
||||
guint16 r = (guint16)src[R1] * a + 127; \
|
||||
guint16 g = (guint16)src[G1] * a + 127; \
|
||||
guint16 b = (guint16)src[B1] * a + 127; \
|
||||
dest[R2] = (r + (r >> 8) + 1) >> 8; \
|
||||
dest[G2] = (g + (g >> 8) + 1) >> 8; \
|
||||
dest[B2] = (b + (b >> 8) + 1) >> 8; \
|
||||
dest[A2] = a; \
|
||||
dest += 4; \
|
||||
src += 4; \
|
||||
} \
|
||||
}
|
||||
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_r8g8b8a8_premultiplied, 0, 1, 2, 3, 0, 1, 2, 3)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_b8g8r8a8_premultiplied, 0, 1, 2, 3, 2, 1, 0, 3)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_a8r8g8b8_premultiplied, 0, 1, 2, 3, 1, 2, 3, 0)
|
||||
PREMULTIPLY_FUNC(r8g8b8a8_to_a8b8g8r8_premultiplied, 0, 1, 2, 3, 3, 2, 1, 0)
|
||||
|
||||
#define ADD_ALPHA_FUNC(name, R1, G1, B1, R2, G2, B2, A2) \
|
||||
static void \
|
||||
name (guchar *dest, \
|
||||
const guchar *src, \
|
||||
gsize n) \
|
||||
{ \
|
||||
for (; n > 0; n--) \
|
||||
{ \
|
||||
dest[R2] = src[R1]; \
|
||||
dest[G2] = src[G1]; \
|
||||
dest[B2] = src[B1]; \
|
||||
dest[A2] = 255; \
|
||||
dest += 4; \
|
||||
src += 3; \
|
||||
} \
|
||||
}
|
||||
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_r8g8b8a8, 0, 1, 2, 0, 1, 2, 3)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_b8g8r8a8, 0, 1, 2, 2, 1, 0, 3)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_a8r8g8b8, 0, 1, 2, 1, 2, 3, 0)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_a8b8g8r8, 0, 1, 2, 3, 2, 1, 0)
|
||||
|
||||
struct _GdkMemoryFormatDescription
|
||||
{
|
||||
GdkMemoryAlpha alpha;
|
||||
@@ -548,15 +523,53 @@ gdk_memory_convert (guchar *dest_data,
|
||||
const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
|
||||
float *tmp;
|
||||
gsize y;
|
||||
void (*func) (guchar *, const guchar *, gsize) = NULL;
|
||||
|
||||
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
|
||||
g_assert (src_format < GDK_MEMORY_N_FORMATS);
|
||||
|
||||
if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_b8g8r8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_r8g8b8a8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_a8r8g8b8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8a8_to_a8b8g8r8_premultiplied;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_a8r8g8b8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_A8R8G8B8_PREMULTIPLIED)
|
||||
func = r8g8b8_to_a8b8g8r8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_R8G8B8A8)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_R8G8B8A8)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_B8G8R8A8)
|
||||
func = r8g8b8_to_b8g8r8a8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_B8G8R8A8)
|
||||
func = r8g8b8_to_r8g8b8a8;
|
||||
else if (src_format == GDK_MEMORY_R8G8B8 && dest_format == GDK_MEMORY_A8R8G8B8)
|
||||
func = r8g8b8_to_a8r8g8b8;
|
||||
else if (src_format == GDK_MEMORY_B8G8R8 && dest_format == GDK_MEMORY_A8R8G8B8)
|
||||
func = r8g8b8_to_a8b8g8r8;
|
||||
|
||||
if (func != NULL)
|
||||
{
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
r8g8b8a8_to_b8g8r8a8_premultiplied (dest_data, src_data, width);
|
||||
func (dest_data, src_data, width);
|
||||
src_data += src_stride;
|
||||
dest_data += dest_stride;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1125,7 +1125,7 @@ gdk_surface_ensure_egl_surface (GdkSurface *self,
|
||||
gdk_display_get_egl_config_high_depth (display) != gdk_display_get_egl_config (display))
|
||||
{
|
||||
gdk_gl_context_clear_current_if_surface (self);
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
eglDestroySurface (gdk_display_get_egl_display (display), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#import "GdkMacosLayer.h"
|
||||
#import "GdkMacosView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
@implementation GdkMacosView
|
||||
|
||||
@@ -56,6 +57,19 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)mouseDown:(NSEvent *)nsevent
|
||||
{
|
||||
if ([(GdkMacosWindow *)[self window] needsMouseDownQuirk])
|
||||
/* We should only hit this when we are trying to click through
|
||||
* the shadow of a window into another window. Just request
|
||||
* that the application not activate this window on mouseUp.
|
||||
* See gdkmacosdisplay-translate.c for the other half of this.
|
||||
*/
|
||||
[NSApp preventWindowOrdering];
|
||||
else
|
||||
[super mouseDown:nsevent];
|
||||
}
|
||||
|
||||
-(void)setFrame:(NSRect)rect
|
||||
{
|
||||
[super setFrame:rect];
|
||||
|
||||
@@ -171,6 +171,11 @@ typedef NSString *CALayerContentsGravity;
|
||||
return inMove;
|
||||
}
|
||||
|
||||
- (BOOL)inFullscreenTransition;
|
||||
{
|
||||
return inFullscreenTransition;
|
||||
}
|
||||
|
||||
-(void)checkSendEnterNotify
|
||||
{
|
||||
/* When a new window has been created, and the mouse is in the window
|
||||
@@ -253,7 +258,8 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(BOOL)canBecomeKeyWindow
|
||||
{
|
||||
return GDK_IS_TOPLEVEL (gdk_surface) || GDK_IS_POPUP (gdk_surface);
|
||||
return GDK_IS_TOPLEVEL (gdk_surface) ||
|
||||
(GDK_IS_POPUP (gdk_surface) && GDK_SURFACE (gdk_surface)->input_region != NULL);
|
||||
}
|
||||
|
||||
-(void)showAndMakeKey:(BOOL)makeKey
|
||||
@@ -261,9 +267,12 @@ typedef NSString *CALayerContentsGravity;
|
||||
inShowOrHide = YES;
|
||||
|
||||
if (makeKey && [self canBecomeKeyWindow])
|
||||
[self makeKeyAndOrderFront:nil];
|
||||
[self makeKeyAndOrderFront:self];
|
||||
else
|
||||
[self orderFront:nil];
|
||||
[self orderFront:self];
|
||||
|
||||
if (makeKey && [self canBecomeMainWindow])
|
||||
[self makeMainWindow];
|
||||
|
||||
inShowOrHide = NO;
|
||||
|
||||
@@ -373,9 +382,17 @@ typedef NSString *CALayerContentsGravity;
|
||||
_gdk_macos_surface_configure ([self gdkSurface]);
|
||||
}
|
||||
|
||||
- (void)windowDidResize:(NSNotification *)notification
|
||||
-(void)windowDidResize:(NSNotification *)notification
|
||||
{
|
||||
_gdk_macos_surface_configure ([self gdkSurface]);
|
||||
_gdk_macos_surface_configure (gdk_surface);
|
||||
|
||||
/* If we're using server-side decorations, this notification is coming
|
||||
* in from a display-side change. We need to request a layout in
|
||||
* addition to the configure event.
|
||||
*/
|
||||
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) &&
|
||||
GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated)
|
||||
gdk_surface_request_layout (GDK_SURFACE (gdk_surface));
|
||||
}
|
||||
|
||||
/* Used by gdkmacosdisplay-translate.c to decide if our sendEvent() handler
|
||||
@@ -668,7 +685,12 @@ typedef NSString *CALayerContentsGravity;
|
||||
is_opaque = (([self styleMask] & NSWindowStyleMaskTitled) != 0);
|
||||
|
||||
if (was_fullscreen != is_fullscreen)
|
||||
_gdk_macos_surface_update_fullscreen_state (gdk_surface);
|
||||
{
|
||||
if (was_fullscreen)
|
||||
[self setFrame:lastUnfullscreenFrame display:NO];
|
||||
|
||||
_gdk_macos_surface_update_fullscreen_state (gdk_surface);
|
||||
}
|
||||
|
||||
if (was_opaque != is_opaque)
|
||||
{
|
||||
@@ -742,32 +764,37 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
-(void)windowWillEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = YES;
|
||||
lastUnfullscreenFrame = [self frame];
|
||||
}
|
||||
|
||||
-(void)windowDidEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = NO;
|
||||
initialPositionKnown = NO;
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowWillExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
[self setFrame:lastUnfullscreenFrame display:NO];
|
||||
inFullscreenTransition = YES;
|
||||
}
|
||||
|
||||
-(void)windowDidExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = NO;
|
||||
initialPositionKnown = NO;
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = NO;
|
||||
}
|
||||
|
||||
-(void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
inFullscreenTransition = NO;
|
||||
}
|
||||
|
||||
-(void)windowDidChangeScreen:(NSNotification *)aNotification
|
||||
@@ -814,4 +841,10 @@ typedef NSString *CALayerContentsGravity;
|
||||
[(GdkMacosView *)[self contentView] swapBuffer:buffer withDamage:damage];
|
||||
}
|
||||
|
||||
-(BOOL)needsMouseDownQuirk
|
||||
{
|
||||
return GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) &&
|
||||
!GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
NSRect lastMaximizedFrame;
|
||||
NSRect lastUnfullscreenFrame;
|
||||
BOOL inMaximizeTransition;
|
||||
BOOL inFullscreenTransition;
|
||||
}
|
||||
|
||||
-(void)beginManualMove;
|
||||
@@ -69,5 +70,7 @@
|
||||
-(BOOL)trackManualResize;
|
||||
-(void)setDecorated:(BOOL)decorated;
|
||||
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage;
|
||||
-(BOOL)needsMouseDownQuirk;
|
||||
-(BOOL)inFullscreenTransition;
|
||||
|
||||
@end
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
|
||||
#include "gdkdisplaylinksource.h"
|
||||
|
||||
#include "gdkdebug.h"
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
static gint64 host_to_frame_clock_time (gint64 val);
|
||||
@@ -65,7 +67,7 @@ gdk_display_link_source_dispatch (GSource *source,
|
||||
|
||||
impl->needs_dispatch = FALSE;
|
||||
|
||||
if (callback != NULL)
|
||||
if (!impl->paused && callback != NULL)
|
||||
ret = callback (user_data);
|
||||
|
||||
return ret;
|
||||
@@ -76,7 +78,9 @@ gdk_display_link_source_finalize (GSource *source)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
|
||||
CVDisplayLinkStop (impl->display_link);
|
||||
if (!impl->paused)
|
||||
CVDisplayLinkStop (impl->display_link);
|
||||
|
||||
CVDisplayLinkRelease (impl->display_link);
|
||||
}
|
||||
|
||||
@@ -90,12 +94,18 @@ static GSourceFuncs gdk_display_link_source_funcs = {
|
||||
void
|
||||
gdk_display_link_source_pause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
g_return_if_fail (source->paused == FALSE);
|
||||
|
||||
source->paused = TRUE;
|
||||
CVDisplayLinkStop (source->display_link);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_link_source_unpause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
g_return_if_fail (source->paused == TRUE);
|
||||
|
||||
source->paused = FALSE;
|
||||
CVDisplayLinkStart (source->display_link);
|
||||
}
|
||||
|
||||
@@ -147,6 +157,7 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
|
||||
|
||||
/**
|
||||
* gdk_display_link_source_new:
|
||||
* @display_id: the identifier of the monitor
|
||||
*
|
||||
* Creates a new `GSource` that will activate the dispatch function upon
|
||||
* notification from a CVDisplayLink that a new frame should be drawn.
|
||||
@@ -159,41 +170,61 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
|
||||
* Returns: (transfer full): A newly created `GSource`
|
||||
*/
|
||||
GSource *
|
||||
gdk_display_link_source_new (void)
|
||||
gdk_display_link_source_new (CGDirectDisplayID display_id,
|
||||
CGDisplayModeRef mode)
|
||||
{
|
||||
GdkDisplayLinkSource *impl;
|
||||
GSource *source;
|
||||
CVReturn ret;
|
||||
double period;
|
||||
char *name;
|
||||
|
||||
source = g_source_new (&gdk_display_link_source_funcs, sizeof *impl);
|
||||
impl = (GdkDisplayLinkSource *)source;
|
||||
impl->display_id = display_id;
|
||||
impl->paused = TRUE;
|
||||
|
||||
/*
|
||||
* Create our link based on currently connected displays.
|
||||
* If there are multiple displays, this will be something that tries
|
||||
* to work for all of them. In the future, we may want to explore multiple
|
||||
* links based on the connected displays.
|
||||
/* Create DisplayLink for timing information for the display in
|
||||
* question so that we can produce graphics for that display at whatever
|
||||
* rate it can provide.
|
||||
*/
|
||||
ret = CVDisplayLinkCreateWithActiveCGDisplays (&impl->display_link);
|
||||
if (ret != kCVReturnSuccess)
|
||||
if (CVDisplayLinkCreateWithCGDisplay (display_id, &impl->display_link) != kCVReturnSuccess)
|
||||
{
|
||||
g_warning ("Failed to initialize CVDisplayLink!");
|
||||
return source;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine our nominal period between frames.
|
||||
*/
|
||||
period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
|
||||
if (period == 0.0)
|
||||
period = 1.0 / 60.0;
|
||||
impl->refresh_interval = period * 1000000L;
|
||||
impl->refresh_rate = 1.0 / period * 1000L;
|
||||
impl->refresh_rate = CGDisplayModeGetRefreshRate (mode) * 1000.0;
|
||||
|
||||
/*
|
||||
* Wire up our callback to be executed within the high-priority thread.
|
||||
*/
|
||||
if (impl->refresh_rate == 0)
|
||||
{
|
||||
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod (impl->display_link);
|
||||
if (!(time.flags & kCVTimeIsIndefinite))
|
||||
impl->refresh_rate = (double)time.timeScale / (double)time.timeValue * 1000.0;
|
||||
}
|
||||
|
||||
if (impl->refresh_rate != 0)
|
||||
{
|
||||
impl->refresh_interval = 1000000.0 / (double)impl->refresh_rate * 1000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
|
||||
|
||||
if (period == 0.0)
|
||||
period = 1.0 / 60.0;
|
||||
|
||||
impl->refresh_rate = 1.0 / period * 1000L;
|
||||
impl->refresh_interval = period * 1000000L;
|
||||
}
|
||||
|
||||
name = _gdk_macos_monitor_get_connector_name (display_id);
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("Monitor \"%s\" discovered with Refresh Rate %d and Interval %"G_GINT64_FORMAT,
|
||||
name ? name : "unknown",
|
||||
impl->refresh_rate,
|
||||
impl->refresh_interval));
|
||||
g_free (name);
|
||||
|
||||
/* Wire up our callback to be executed within the high-priority thread. */
|
||||
CVDisplayLinkSetOutputCallback (impl->display_link,
|
||||
gdk_display_link_source_frame_cb,
|
||||
source);
|
||||
@@ -201,6 +232,10 @@ gdk_display_link_source_new (void)
|
||||
g_source_set_static_name (source, "[gdk] quartz frame clock");
|
||||
|
||||
return source;
|
||||
|
||||
failure:
|
||||
g_source_unref (source);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gint64
|
||||
|
||||
@@ -30,17 +30,20 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSource source;
|
||||
GSource source;
|
||||
|
||||
CVDisplayLinkRef display_link;
|
||||
gint64 refresh_interval;
|
||||
guint refresh_rate;
|
||||
CGDirectDisplayID display_id;
|
||||
CVDisplayLinkRef display_link;
|
||||
gint64 refresh_interval;
|
||||
guint refresh_rate;
|
||||
guint paused : 1;
|
||||
|
||||
volatile gint64 presentation_time;
|
||||
volatile guint needs_dispatch;
|
||||
volatile gint64 presentation_time;
|
||||
volatile guint needs_dispatch;
|
||||
} GdkDisplayLinkSource;
|
||||
|
||||
GSource *gdk_display_link_source_new (void);
|
||||
GSource *gdk_display_link_source_new (CGDirectDisplayID display_id,
|
||||
CGDisplayModeRef mode);
|
||||
void gdk_display_link_source_pause (GdkDisplayLinkSource *source);
|
||||
void gdk_display_link_source_unpause (GdkDisplayLinkSource *source);
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ GdkMacosBuffer *_gdk_macos_buffer_new (int width
|
||||
IOSurfaceRef _gdk_macos_buffer_get_native (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_lock (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_unlock (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_read_lock (GdkMacosBuffer *self);
|
||||
void _gdk_macos_buffer_read_unlock (GdkMacosBuffer *self);
|
||||
guint _gdk_macos_buffer_get_width (GdkMacosBuffer *self);
|
||||
guint _gdk_macos_buffer_get_height (GdkMacosBuffer *self);
|
||||
guint _gdk_macos_buffer_get_stride (GdkMacosBuffer *self);
|
||||
|
||||
@@ -192,6 +192,45 @@ _gdk_macos_buffer_unlock (GdkMacosBuffer *self)
|
||||
IOSurfaceUnlock (self->surface, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gdk_macos_buffer_lock_readonly:
|
||||
*
|
||||
* Like _gdk_macos_buffer_lock() but uses the read-only flag to
|
||||
* indicate we are not interested in retrieving the updates from
|
||||
* the GPU before modifying the CPU-side cache.
|
||||
*
|
||||
* Must be used with _gdk_macos_buffer_unlock_readonly().
|
||||
*/
|
||||
void
|
||||
_gdk_macos_buffer_read_lock (GdkMacosBuffer *self)
|
||||
{
|
||||
kern_return_t ret;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
|
||||
g_return_if_fail (self->lock_count == 0);
|
||||
|
||||
self->lock_count++;
|
||||
|
||||
ret = IOSurfaceLock (self->surface, kIOSurfaceLockReadOnly, NULL);
|
||||
|
||||
g_return_if_fail (ret == KERN_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_buffer_read_unlock (GdkMacosBuffer *self)
|
||||
{
|
||||
kern_return_t ret;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
|
||||
g_return_if_fail (self->lock_count == 1);
|
||||
|
||||
self->lock_count--;
|
||||
|
||||
ret = IOSurfaceUnlock (self->surface, kIOSurfaceLockReadOnly, NULL);
|
||||
|
||||
g_return_if_fail (ret == KERN_SUCCESS);
|
||||
}
|
||||
|
||||
guint
|
||||
_gdk_macos_buffer_get_width (GdkMacosBuffer *self)
|
||||
{
|
||||
@@ -242,7 +281,7 @@ _gdk_macos_buffer_set_damage (GdkMacosBuffer *self,
|
||||
return;
|
||||
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
self->damage = cairo_region_reference (damage);
|
||||
self->damage = cairo_region_copy (damage);
|
||||
}
|
||||
|
||||
gpointer
|
||||
|
||||
@@ -42,19 +42,6 @@ struct _GdkMacosCairoContextClass
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosCairoContext, _gdk_macos_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static const cairo_user_data_key_t buffer_key;
|
||||
|
||||
static void
|
||||
unlock_buffer (gpointer data)
|
||||
{
|
||||
GdkMacosBuffer *buffer = data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_BUFFER (buffer));
|
||||
|
||||
_gdk_macos_buffer_unlock (buffer);
|
||||
g_clear_object (&buffer);
|
||||
}
|
||||
|
||||
static cairo_t *
|
||||
_gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
|
||||
{
|
||||
@@ -106,12 +93,9 @@ _gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
|
||||
stride);
|
||||
cairo_surface_set_device_scale (image_surface, scale, scale);
|
||||
|
||||
/* Lock the buffer so we can modify it safely */
|
||||
_gdk_macos_buffer_lock (buffer);
|
||||
cairo_surface_set_user_data (image_surface,
|
||||
&buffer_key,
|
||||
g_object_ref (buffer),
|
||||
unlock_buffer);
|
||||
/* The buffer should already be locked at this point, and will
|
||||
* be unlocked as part of end_frame.
|
||||
*/
|
||||
|
||||
if (!(cr = cairo_create (image_surface)))
|
||||
goto failure;
|
||||
@@ -158,6 +142,52 @@ failure:
|
||||
return cr;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_surface_data (GdkMacosBuffer *from,
|
||||
GdkMacosBuffer *to,
|
||||
const cairo_region_t *region,
|
||||
int scale)
|
||||
{
|
||||
const guint8 *from_base;
|
||||
guint8 *to_base;
|
||||
guint from_stride;
|
||||
guint to_stride;
|
||||
guint n_rects;
|
||||
|
||||
g_assert (GDK_IS_MACOS_BUFFER (from));
|
||||
g_assert (GDK_IS_MACOS_BUFFER (to));
|
||||
g_assert (region != NULL);
|
||||
g_assert (!cairo_region_is_empty (region));
|
||||
|
||||
from_base = _gdk_macos_buffer_get_data (from);
|
||||
from_stride = _gdk_macos_buffer_get_stride (from);
|
||||
|
||||
to_base = _gdk_macos_buffer_get_data (to);
|
||||
to_stride = _gdk_macos_buffer_get_stride (to);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
int y2;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
rect.y *= scale;
|
||||
rect.height *= scale;
|
||||
rect.x *= scale;
|
||||
rect.width *= scale;
|
||||
|
||||
y2 = rect.y + rect.height;
|
||||
|
||||
for (int y = rect.y; y < y2; y++)
|
||||
memcpy (&to_base[y * to_stride + rect.x * 4],
|
||||
&from_base[y * from_stride + rect.x * 4],
|
||||
rect.width * 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
gboolean prefers_high_depth,
|
||||
@@ -165,34 +195,68 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
GdkMacosBuffer *buffer;
|
||||
GdkSurface *surface;
|
||||
GdkMacosSurface *surface;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
[CATransaction begin];
|
||||
[CATransaction setDisableActions:YES];
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
|
||||
surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (draw_context));
|
||||
buffer = _gdk_macos_surface_get_buffer (surface);
|
||||
|
||||
_gdk_macos_buffer_set_damage (buffer, region);
|
||||
_gdk_macos_buffer_set_flipped (buffer, FALSE);
|
||||
|
||||
_gdk_macos_buffer_lock (buffer);
|
||||
|
||||
/* If there is damage that was on the previous frame that is not on
|
||||
* this frame, we need to copy that rendered region over to the back
|
||||
* buffer so that when swapping buffers, we still have that content.
|
||||
* This is done with a read-only lock on the IOSurface to avoid
|
||||
* invalidating the buffer contents.
|
||||
*/
|
||||
if (surface->front != NULL)
|
||||
{
|
||||
const cairo_region_t *previous = _gdk_macos_buffer_get_damage (surface->front);
|
||||
|
||||
if (previous != NULL)
|
||||
{
|
||||
cairo_region_t *copy;
|
||||
|
||||
copy = cairo_region_copy (previous);
|
||||
cairo_region_subtract (copy, region);
|
||||
|
||||
if (!cairo_region_is_empty (copy))
|
||||
{
|
||||
int scale = gdk_surface_get_scale_factor (GDK_SURFACE (surface));
|
||||
|
||||
_gdk_macos_buffer_read_lock (surface->front);
|
||||
copy_surface_data (surface->front, buffer, copy, scale);
|
||||
_gdk_macos_buffer_read_unlock (surface->front);
|
||||
}
|
||||
|
||||
cairo_region_destroy (copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
GdkMacosSurface *surface;
|
||||
GdkMacosBuffer *buffer;
|
||||
GdkSurface *surface;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (draw_context));
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
|
||||
surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (draw_context));
|
||||
buffer = _gdk_macos_surface_get_buffer (surface);
|
||||
|
||||
_gdk_macos_surface_swap_buffers (GDK_MACOS_SURFACE (surface), painted);
|
||||
_gdk_macos_buffer_set_damage (buffer, NULL);
|
||||
_gdk_macos_buffer_unlock (buffer);
|
||||
|
||||
_gdk_macos_surface_swap_buffers (surface, painted);
|
||||
|
||||
[CATransaction commit];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright © 2022 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
static void
|
||||
gdk_macos_display_user_defaults_changed_cb (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosDisplay *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
_gdk_macos_display_reload_settings (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_monitors_changed_cb (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosDisplay *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
_gdk_macos_display_reload_monitors (self);
|
||||
|
||||
/* Now we need to update all our surface positions since they
|
||||
* probably just changed origins.
|
||||
*/
|
||||
for (const GList *iter = _gdk_macos_display_get_surfaces (self);
|
||||
iter != NULL;
|
||||
iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
_gdk_macos_surface_monitor_changed (surface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gdk_macos_display_feedback_init (GdkMacosDisplay *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetLocalCenter (),
|
||||
self,
|
||||
gdk_macos_display_monitors_changed_cb,
|
||||
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
gdk_macos_display_user_defaults_changed_cb,
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_feedback_destroy (GdkMacosDisplay *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
|
||||
NULL);
|
||||
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL);
|
||||
|
||||
}
|
||||
@@ -43,6 +43,8 @@ G_BEGIN_DECLS
|
||||
#define GIC_FILTER_PASSTHRU 0
|
||||
#define GIC_FILTER_FILTERED 1
|
||||
|
||||
#define GDK_MACOS_EVENT_DROP (GdkEvent *)GSIZE_TO_POINTER(1)
|
||||
|
||||
struct _GdkMacosDisplay
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
@@ -68,16 +70,6 @@ struct _GdkMacosDisplay
|
||||
*/
|
||||
GQueue sorted_surfaces;
|
||||
|
||||
/* Our CVDisplayLink based GSource which we use to freeze/thaw the
|
||||
* GdkFrameClock for the surface.
|
||||
*/
|
||||
GSource *frame_source;
|
||||
|
||||
/* A queue of surfaces which we know are awaiting frames to be drawn. This
|
||||
* uses the GdkMacosSurface.frame link.
|
||||
*/
|
||||
GQueue awaiting_frames;
|
||||
|
||||
/* The surface that is receiving keyboard events */
|
||||
GdkMacosSurface *keyboard_surface;
|
||||
|
||||
@@ -92,6 +84,14 @@ struct _GdkMacosDisplay
|
||||
int min_y;
|
||||
int max_x;
|
||||
int max_y;
|
||||
|
||||
/* A GSource to select a new main/key window */
|
||||
guint select_key_in_idle;
|
||||
|
||||
/* Note if we have a key window that is not a GdkMacosWindow
|
||||
* such as a NSPanel used for native dialogs.
|
||||
*/
|
||||
guint key_window_is_foregin : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosDisplayClass
|
||||
@@ -124,6 +124,8 @@ GdkMonitor *_gdk_macos_display_get_monitor_at_display_coords (GdkMacosDisp
|
||||
int y);
|
||||
GdkEvent *_gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
NSEvent *event);
|
||||
void _gdk_macos_display_feedback_init (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_feedback_destroy (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_break_all_grabs (GdkMacosDisplay *self,
|
||||
guint32 time);
|
||||
GdkModifierType _gdk_macos_display_get_current_keyboard_modifiers (GdkMacosDisplay *self);
|
||||
@@ -136,10 +138,6 @@ GdkMacosSurface *_gdk_macos_display_get_surface_at_display_coords (GdkMacosDisp
|
||||
void _gdk_macos_display_reload_monitors (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_surface_removed (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_remove_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
NSWindow *_gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
|
||||
int *x,
|
||||
int *y);
|
||||
@@ -155,7 +153,6 @@ void _gdk_macos_display_surface_resigned_key (GdkMacosDisp
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
int _gdk_macos_display_get_nominal_refresh_rate (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self);
|
||||
const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
|
||||
@@ -34,7 +34,7 @@ typedef struct
|
||||
const char *font_name;
|
||||
int xft_dpi;
|
||||
int double_click_time;
|
||||
int cursor_blink_timeout;
|
||||
int cursor_blink_time;
|
||||
guint enable_animations : 1;
|
||||
guint shell_shows_desktop : 1;
|
||||
guint shell_shows_menubar : 1;
|
||||
@@ -65,9 +65,9 @@ _gdk_macos_settings_load (GdkMacosSettings *settings)
|
||||
|
||||
ival = [defaults integerForKey:@"NSTextInsertionPointBlinkPeriod"];
|
||||
if (ival > 0)
|
||||
settings->cursor_blink_timeout = ival;
|
||||
settings->cursor_blink_time = ival;
|
||||
else
|
||||
settings->cursor_blink_timeout = 1000;
|
||||
settings->cursor_blink_time = 1000;
|
||||
|
||||
settings->primary_button_warps_slider =
|
||||
[[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"] == YES;
|
||||
@@ -124,9 +124,9 @@ _gdk_macos_display_get_setting (GdkMacosDisplay *self,
|
||||
g_value_set_int (value, current_settings.xft_dpi);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-cursor-blink-timeout") == 0)
|
||||
else if (strcmp (setting, "gtk-cursor-blink-time") == 0)
|
||||
{
|
||||
g_value_set_int (value, current_settings.cursor_blink_timeout);
|
||||
g_value_set_int (value, current_settings.cursor_blink_time);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-double-click-time") == 0)
|
||||
|
||||
@@ -612,6 +612,8 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer;
|
||||
GdkEvent *ret = NULL;
|
||||
NSEventPhase phase;
|
||||
NSEventPhase momentumPhase;
|
||||
GdkSeat *seat;
|
||||
double dx;
|
||||
double dy;
|
||||
@@ -619,11 +621,31 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (nsevent != NULL);
|
||||
|
||||
phase = [nsevent phase];
|
||||
momentumPhase = [nsevent momentumPhase];
|
||||
|
||||
/* Ignore kinetic scroll events from the display server as we already
|
||||
* handle those internally.
|
||||
*/
|
||||
if (phase == 0 && momentumPhase != 0)
|
||||
return GDK_MACOS_EVENT_DROP;
|
||||
|
||||
seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
state = _gdk_macos_display_get_current_mouse_modifiers (self) |
|
||||
_gdk_macos_display_get_current_keyboard_modifiers (self);
|
||||
|
||||
/* If we are starting a new phase, send a stop so any previous
|
||||
* scrolling immediately stops.
|
||||
*/
|
||||
if (phase == NSEventPhaseMayBegin)
|
||||
return gdk_scroll_event_new (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
0.0, 0.0, TRUE);
|
||||
|
||||
dx = [nsevent deltaX];
|
||||
dy = [nsevent deltaY];
|
||||
|
||||
@@ -667,34 +689,32 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
dy = 0.0;
|
||||
}
|
||||
|
||||
if (dx != 0.0 || dy != 0.0)
|
||||
if ((dx != 0.0 || dy != 0.0) && ![nsevent hasPreciseScrollingDeltas])
|
||||
{
|
||||
if ([nsevent hasPreciseScrollingDeltas])
|
||||
{
|
||||
GdkEvent *emulated;
|
||||
g_assert (ret == NULL);
|
||||
|
||||
emulated = gdk_scroll_event_new_discrete (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
direction,
|
||||
TRUE);
|
||||
_gdk_event_queue_append (GDK_DISPLAY (self), emulated);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (ret == NULL);
|
||||
ret = gdk_scroll_event_new_discrete (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
direction,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
ret = gdk_scroll_event_new (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
-dx * 32,
|
||||
-dy * 32,
|
||||
FALSE);
|
||||
}
|
||||
if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled)
|
||||
{
|
||||
/* The user must have released their fingers in a touchpad
|
||||
* scroll, so try to send a scroll is_stop event.
|
||||
*/
|
||||
if (ret != NULL)
|
||||
_gdk_event_queue_append (GDK_DISPLAY (self), g_steal_pointer (&ret));
|
||||
ret = gdk_scroll_event_new (GDK_SURFACE (surface),
|
||||
pointer,
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
0.0, 0.0, TRUE);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
@@ -1066,6 +1086,7 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface;
|
||||
GdkMacosWindow *window;
|
||||
NSEventType event_type;
|
||||
NSWindow *event_window;
|
||||
GdkEvent *ret = NULL;
|
||||
int x;
|
||||
int y;
|
||||
@@ -1108,6 +1129,15 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the event was delivered to NSWindow that is foreign (or rather,
|
||||
* Cocoa native), then we should pass the event along to that window.
|
||||
*/
|
||||
if ((event_window = [nsevent window]) && !GDK_IS_MACOS_WINDOW (event_window))
|
||||
return NULL;
|
||||
|
||||
/* If we can't find a GdkSurface to deliver the event to, then we
|
||||
* should pass it along to the NSApp.
|
||||
*/
|
||||
if (!(surface = find_surface_for_ns_event (self, nsevent, &x, &y)))
|
||||
return NULL;
|
||||
|
||||
@@ -1139,15 +1169,31 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
if (test_resize (nsevent, surface, x, y))
|
||||
return NULL;
|
||||
|
||||
if ((event_type == NSEventTypeRightMouseDown ||
|
||||
event_type == NSEventTypeOtherMouseDown ||
|
||||
event_type == NSEventTypeLeftMouseDown))
|
||||
if (event_type == NSEventTypeRightMouseDown ||
|
||||
event_type == NSEventTypeOtherMouseDown ||
|
||||
event_type == NSEventTypeLeftMouseDown)
|
||||
{
|
||||
if (![NSApp isActive])
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
if (![window isKeyWindow])
|
||||
[window makeKeyWindow];
|
||||
{
|
||||
NSWindow *orig_window = [nsevent window];
|
||||
|
||||
/* To get NSApp to supress activating the window we might
|
||||
* have clicked through the shadow of, we need to dispatch
|
||||
* the event and handle it in GdkMacosView:mouseDown to call
|
||||
* [NSApp preventWindowOrdering]. Calling it here will not
|
||||
* do anything as the event is not registered.
|
||||
*/
|
||||
if (orig_window &&
|
||||
GDK_IS_MACOS_WINDOW (orig_window) &&
|
||||
[(GdkMacosWindow *)orig_window needsMouseDownQuirk])
|
||||
[NSApp sendEvent:nsevent];
|
||||
|
||||
[window showAndMakeKey:YES];
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
}
|
||||
|
||||
switch ((int)event_type)
|
||||
@@ -1180,7 +1226,11 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
GdkDevice *pointer = gdk_seat_get_pointer (seat);
|
||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer);
|
||||
|
||||
if (grab == NULL)
|
||||
if ([(GdkMacosWindow *)window isInManualResizeOrMove])
|
||||
{
|
||||
ret = GDK_MACOS_EVENT_DROP;
|
||||
}
|
||||
else if (grab == NULL)
|
||||
{
|
||||
if (event_type == NSEventTypeMouseExited)
|
||||
[[NSCursor arrowCursor] set];
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosmonitor.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacostoplevelsurface-private.h"
|
||||
|
||||
#define WARP_OFFSET_X 15
|
||||
#define WARP_OFFSET_Y 15
|
||||
|
||||
static void
|
||||
_gdk_macos_display_position_toplevel_with_parent (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface,
|
||||
@@ -33,52 +36,49 @@ _gdk_macos_display_position_toplevel_with_parent (GdkMacosDisplay *self,
|
||||
{
|
||||
GdkRectangle surface_rect;
|
||||
GdkRectangle parent_rect;
|
||||
GdkRectangle workarea;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (surface));
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (parent));
|
||||
|
||||
/* If x/y is set, we should place relative to parent */
|
||||
if (GDK_SURFACE (surface)->x != 0 || GDK_SURFACE (surface)->y != 0)
|
||||
{
|
||||
*x = parent->root_x + GDK_SURFACE (surface)->x;
|
||||
*y = parent->root_y + GDK_SURFACE (surface)->y;
|
||||
return;
|
||||
}
|
||||
monitor = _gdk_macos_surface_get_best_monitor (parent);
|
||||
|
||||
/* Try to center on top of the parent but also try to make the whole thing
|
||||
* visible in case that lands us under the topbar/panel/etc.
|
||||
*/
|
||||
surface_rect.x = surface->root_x + surface->shadow_left;
|
||||
surface_rect.y = surface->root_y + surface->shadow_top;
|
||||
parent_rect.x = parent->root_x + parent->shadow_left;
|
||||
parent_rect.y = parent->root_y + parent->shadow_top;
|
||||
parent_rect.width = GDK_SURFACE (parent)->width - parent->shadow_left - parent->shadow_right;
|
||||
parent_rect.height = GDK_SURFACE (parent)->height - parent->shadow_top - parent->shadow_bottom;
|
||||
|
||||
surface_rect.width = GDK_SURFACE (surface)->width - surface->shadow_left - surface->shadow_right;
|
||||
surface_rect.height = GDK_SURFACE (surface)->height - surface->shadow_top - surface->shadow_bottom;
|
||||
|
||||
parent_rect.x = parent->root_x + surface->shadow_left;
|
||||
parent_rect.y = parent->root_y + surface->shadow_top;
|
||||
parent_rect.width = GDK_SURFACE (parent)->width - surface->shadow_left - surface->shadow_right;
|
||||
parent_rect.height = GDK_SURFACE (parent)->height - surface->shadow_top - surface->shadow_bottom;
|
||||
|
||||
/* Try to place centered atop parent */
|
||||
surface_rect.x = parent_rect.x + ((parent_rect.width - surface_rect.width) / 2);
|
||||
surface_rect.y = parent_rect.y + ((parent_rect.height - surface_rect.height) / 2);
|
||||
|
||||
/* Now make sure that we don't overlap the top-bar */
|
||||
monitor = _gdk_macos_surface_get_best_monitor (parent);
|
||||
gdk_macos_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
if (surface_rect.x < workarea.x)
|
||||
surface_rect.x = workarea.x;
|
||||
|
||||
if (surface_rect.y < workarea.y)
|
||||
surface_rect.y = workarea.y;
|
||||
_gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (monitor), &surface_rect);
|
||||
|
||||
*x = surface_rect.x - surface->shadow_left;
|
||||
*y = surface_rect.y - surface->shadow_top;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
has_surface_at_origin (const GList *surfaces,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
for (const GList *iter = surfaces; iter; iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
if (surface->root_x == x && surface->root_y == y)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface,
|
||||
@@ -87,6 +87,7 @@ _gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
|
||||
{
|
||||
cairo_rectangle_int_t surface_rect;
|
||||
GdkRectangle workarea;
|
||||
const GList *surfaces;
|
||||
GdkMonitor *monitor;
|
||||
CGPoint mouse;
|
||||
|
||||
@@ -103,16 +104,29 @@ _gdk_macos_display_position_toplevel (GdkMacosDisplay *self,
|
||||
surface_rect.x = workarea.x + ((workarea.width - surface_rect.width) / 2);
|
||||
surface_rect.y = workarea.y + ((workarea.height - surface_rect.height) / 2);
|
||||
|
||||
if (surface_rect.x < workarea.x)
|
||||
surface_rect.x = workarea.x;
|
||||
|
||||
if (surface_rect.y < workarea.y)
|
||||
surface_rect.y = workarea.y;
|
||||
|
||||
/* TODO: If there is another window at this same position, perhaps we should move it */
|
||||
_gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (surface->best_monitor), &surface_rect);
|
||||
|
||||
*x = surface_rect.x - surface->shadow_left;
|
||||
*y = surface_rect.y - surface->shadow_top;
|
||||
|
||||
/* Try to see if there are any other surfaces at this origin and if so,
|
||||
* adjust until we get something better.
|
||||
*/
|
||||
surfaces = _gdk_macos_display_get_surfaces (self);
|
||||
while (has_surface_at_origin (surfaces, *x, *y))
|
||||
{
|
||||
*x += WARP_OFFSET_X;
|
||||
*y += WARP_OFFSET_Y;
|
||||
|
||||
/* If we reached the bottom right, just bail and try the workspace origin */
|
||||
if (*x + surface->shadow_left + WARP_OFFSET_X > workarea.x + workarea.width ||
|
||||
*y + surface->shadow_top + WARP_OFFSET_Y > workarea.y + workarea.height)
|
||||
{
|
||||
*x = workarea.x - surface->shadow_left;
|
||||
*y = workarea.y - surface->shadow_top;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*<private>
|
||||
|
||||
+57
-207
@@ -156,51 +156,13 @@ gdk_macos_display_update_bounds (GdkMacosDisplay *self)
|
||||
self->width = self->max_x - self->min_x;
|
||||
self->height = self->max_y - self->min_y;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("Displays reconfigured to bounds %d,%d %dx%d",
|
||||
self->min_x, self->min_y, self->width, self->height));
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_monitors_changed_cb (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosDisplay *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
_gdk_macos_display_reload_monitors (self);
|
||||
|
||||
/* Now we need to update all our surface positions since they
|
||||
* probably just changed origins.
|
||||
*/
|
||||
for (const GList *iter = _gdk_macos_display_get_surfaces (self);
|
||||
iter != NULL;
|
||||
iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
_gdk_macos_surface_monitor_changed (surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_user_defaults_changed_cb (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosDisplay *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
_gdk_macos_display_reload_settings (self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_reload_monitors (GdkMacosDisplay *self)
|
||||
{
|
||||
@@ -273,56 +235,6 @@ gdk_macos_display_load_seat (GdkMacosDisplay *self)
|
||||
g_object_unref (seat);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_display_frame_cb (gpointer data)
|
||||
{
|
||||
GdkMacosDisplay *self = data;
|
||||
GdkDisplayLinkSource *source;
|
||||
gint64 presentation_time;
|
||||
gint64 now;
|
||||
GList *iter;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
source = (GdkDisplayLinkSource *)self->frame_source;
|
||||
|
||||
presentation_time = source->presentation_time;
|
||||
now = g_source_get_time ((GSource *)source);
|
||||
|
||||
iter = self->awaiting_frames.head;
|
||||
|
||||
while (iter != NULL)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
iter = iter->next;
|
||||
|
||||
_gdk_macos_surface_publish_timings (surface,
|
||||
source->presentation_time,
|
||||
source->refresh_interval);
|
||||
|
||||
_gdk_macos_display_remove_frame_callback (self, surface);
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (surface)))
|
||||
gdk_surface_thaw_updates (GDK_SURFACE (surface));
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_load_display_link (GdkMacosDisplay *self)
|
||||
{
|
||||
self->frame_source = gdk_display_link_source_new ();
|
||||
g_source_set_callback (self->frame_source,
|
||||
gdk_macos_display_frame_cb,
|
||||
self,
|
||||
NULL);
|
||||
g_source_attach (self->frame_source, NULL);
|
||||
}
|
||||
|
||||
static const char *
|
||||
gdk_macos_display_get_name (GdkDisplay *display)
|
||||
{
|
||||
@@ -398,11 +310,15 @@ gdk_macos_display_queue_events (GdkDisplay *display)
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
if ((nsevent = _gdk_macos_event_source_get_pending ()))
|
||||
while ((nsevent = _gdk_macos_event_source_get_pending ()))
|
||||
{
|
||||
GdkEvent *event = _gdk_macos_display_translate (self, nsevent);
|
||||
|
||||
if (event != NULL)
|
||||
if (event == GDK_MACOS_EVENT_DROP)
|
||||
{
|
||||
[nsevent release];
|
||||
}
|
||||
else if (event != NULL)
|
||||
{
|
||||
push_nsevent (event, nsevent);
|
||||
_gdk_windowing_got_event (GDK_DISPLAY (self),
|
||||
@@ -426,7 +342,6 @@ _gdk_macos_display_surface_added (GdkMacosDisplay *self,
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (!queue_contains (&self->sorted_surfaces, &surface->sorted));
|
||||
g_assert (!queue_contains (&self->main_surfaces, &surface->main));
|
||||
g_assert (!queue_contains (&self->awaiting_frames, &surface->frame));
|
||||
g_assert (surface->sorted.data == surface);
|
||||
g_assert (surface->main.data == surface);
|
||||
g_assert (surface->frame.data == surface);
|
||||
@@ -453,9 +368,6 @@ _gdk_macos_display_surface_removed (GdkMacosDisplay *self,
|
||||
if (queue_contains (&self->main_surfaces, &surface->main))
|
||||
_gdk_macos_display_surface_resigned_main (self, surface);
|
||||
|
||||
if (queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
g_queue_unlink (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
g_return_if_fail (self->keyboard_surface != surface);
|
||||
}
|
||||
|
||||
@@ -501,6 +413,39 @@ _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
|
||||
gdk_surface_request_motion (GDK_SURFACE (surface));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
select_key_in_idle_cb (gpointer data)
|
||||
{
|
||||
GdkMacosDisplay *self = data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
self->select_key_in_idle = 0;
|
||||
|
||||
/* Don't steal focus from NSPanel, etc */
|
||||
if (self->key_window_is_foregin)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
if (self->keyboard_surface == NULL)
|
||||
{
|
||||
const GList *surfaces = _gdk_macos_display_get_surfaces (self);
|
||||
|
||||
for (const GList *iter = surfaces; iter; iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (surface)) &&
|
||||
([surface->window styleMask] & NSWindowStyleMaskMiniaturizable) == 0)
|
||||
{
|
||||
[surface->window showAndMakeKey:YES];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
@@ -545,6 +490,9 @@ _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
|
||||
}
|
||||
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
|
||||
if (self->select_key_in_idle == 0)
|
||||
self->select_key_in_idle = g_idle_add (select_key_in_idle_cb, self);
|
||||
}
|
||||
|
||||
/* Raises a transient window.
|
||||
@@ -583,8 +531,6 @@ void
|
||||
_gdk_macos_display_surface_resigned_main (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
{
|
||||
GdkMacosSurface *new_surface = NULL;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
@@ -592,40 +538,6 @@ _gdk_macos_display_surface_resigned_main (GdkMacosDisplay *self,
|
||||
g_queue_unlink (&self->main_surfaces, &surface->main);
|
||||
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
|
||||
if (GDK_SURFACE (surface)->transient_for &&
|
||||
gdk_surface_get_mapped (GDK_SURFACE (surface)->transient_for))
|
||||
{
|
||||
new_surface = GDK_MACOS_SURFACE (GDK_SURFACE (surface)->transient_for);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GList *surfaces = _gdk_macos_display_get_surfaces (self);
|
||||
|
||||
for (const GList *iter = surfaces; iter; iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *item = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (item));
|
||||
|
||||
if (item == surface)
|
||||
continue;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (item)))
|
||||
{
|
||||
new_surface = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new_surface != NULL)
|
||||
{
|
||||
NSWindow *nswindow = _gdk_macos_surface_get_native (new_surface);
|
||||
[nswindow makeKeyAndOrderFront:nswindow];
|
||||
}
|
||||
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
@@ -686,20 +598,12 @@ gdk_macos_display_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosDisplay *self = (GdkMacosDisplay *)object;
|
||||
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
|
||||
NULL);
|
||||
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL);
|
||||
_gdk_macos_display_feedback_destroy (self);
|
||||
|
||||
g_clear_handle_id (&self->select_key_in_idle, g_source_remove);
|
||||
g_clear_pointer (&self->active_drags, g_hash_table_unref);
|
||||
g_clear_pointer (&self->active_drops, g_hash_table_unref);
|
||||
g_clear_object (&GDK_DISPLAY (self)->clipboard);
|
||||
g_clear_pointer (&self->frame_source, g_source_unref);
|
||||
g_clear_object (&self->monitors);
|
||||
g_clear_pointer (&self->name, g_free);
|
||||
|
||||
@@ -774,24 +678,10 @@ _gdk_macos_display_open (const char *display_name)
|
||||
|
||||
gdk_macos_display_load_seat (self);
|
||||
gdk_macos_display_load_clipboard (self);
|
||||
|
||||
/* Load CVDisplayLink before monitors to access refresh rates */
|
||||
gdk_macos_display_load_display_link (self);
|
||||
_gdk_macos_display_reload_monitors (self);
|
||||
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetLocalCenter (),
|
||||
self,
|
||||
gdk_macos_display_monitors_changed_cb,
|
||||
CFSTR ("NSApplicationDidChangeScreenParametersNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
gdk_macos_display_user_defaults_changed_cb,
|
||||
CFSTR ("NSUserDefaultsDidChangeNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
/* Initialize feedback from display server */
|
||||
_gdk_macos_display_feedback_init (self);
|
||||
|
||||
if (event_source == NULL)
|
||||
{
|
||||
@@ -803,6 +693,8 @@ _gdk_macos_display_open (const char *display_name)
|
||||
|
||||
gdk_display_emit_opened (GDK_DISPLAY (self));
|
||||
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
return GDK_DISPLAY (self);
|
||||
}
|
||||
|
||||
@@ -1033,42 +925,6 @@ _gdk_macos_display_get_surface_at_display_coords (GdkMacosDisplay *self,
|
||||
return _gdk_macos_display_get_surface_at_coords (self, x_gdk, y_gdk, surface_x, surface_y);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if (!queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
{
|
||||
/* Processing frames is always head to tail, so push to the
|
||||
* head so that we don't possibly re-enter this right after
|
||||
* adding to the queue.
|
||||
*/
|
||||
g_queue_push_head_link (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
if (self->awaiting_frames.length == 1)
|
||||
gdk_display_link_source_unpause ((GdkDisplayLinkSource *)self->frame_source);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_remove_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if (queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
{
|
||||
g_queue_unlink (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
if (self->awaiting_frames.length == 0)
|
||||
gdk_display_link_source_pause ((GdkDisplayLinkSource *)self->frame_source);
|
||||
}
|
||||
}
|
||||
|
||||
NSWindow *
|
||||
_gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
|
||||
int *x,
|
||||
@@ -1088,17 +944,6 @@ _gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
_gdk_macos_display_get_nominal_refresh_rate (GdkMacosDisplay *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), 60 * 1000);
|
||||
|
||||
if (self->frame_source == NULL)
|
||||
return 60 * 1000;
|
||||
|
||||
return ((GdkDisplayLinkSource *)self->frame_source)->refresh_rate;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_clear_sorting (GdkMacosDisplay *self)
|
||||
{
|
||||
@@ -1120,11 +965,16 @@ _gdk_macos_display_get_surfaces (GdkMacosDisplay *self)
|
||||
NSArray *array = [NSApp orderedWindows];
|
||||
GQueue sorted = G_QUEUE_INIT;
|
||||
|
||||
self->key_window_is_foregin = FALSE;
|
||||
|
||||
for (id obj in array)
|
||||
{
|
||||
NSWindow *nswindow = (NSWindow *)obj;
|
||||
GdkMacosSurface *surface;
|
||||
|
||||
if ([nswindow isKeyWindow])
|
||||
self->key_window_is_foregin = !GDK_IS_MACOS_WINDOW (nswindow);
|
||||
|
||||
if (!GDK_IS_MACOS_WINDOW (nswindow))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -38,8 +38,6 @@ struct _GdkMacosGLContext
|
||||
{
|
||||
GdkGLContext parent_instance;
|
||||
|
||||
cairo_region_t *damage;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
CGLContextObj cgl_context;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
@@ -469,6 +469,7 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
_gdk_macos_buffer_set_flipped (buffer, TRUE);
|
||||
_gdk_macos_buffer_set_damage (buffer, region);
|
||||
|
||||
/* Create our render target and bind it */
|
||||
gdk_gl_context_make_current (GDK_GL_CONTEXT (self));
|
||||
@@ -476,9 +477,6 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->begin_frame (context, prefers_high_depth, region);
|
||||
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
self->damage = g_steal_pointer (©);
|
||||
|
||||
gdk_gl_context_make_current (GDK_GL_CONTEXT (self));
|
||||
CHECK_GL (NULL, glBindFramebuffer (GL_FRAMEBUFFER, self->fbo));
|
||||
}
|
||||
@@ -531,8 +529,6 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
|
||||
|
||||
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
|
||||
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
|
||||
if (self->cgl_context != NULL)
|
||||
CGLUpdateContext (self->cgl_context);
|
||||
}
|
||||
@@ -587,9 +583,16 @@ static cairo_region_t *
|
||||
gdk_macos_gl_context_get_damage (GdkGLContext *context)
|
||||
{
|
||||
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
|
||||
const cairo_region_t *damage;
|
||||
GdkMacosBuffer *buffer;
|
||||
GdkSurface *surface;
|
||||
|
||||
if (self->damage)
|
||||
return cairo_region_copy (self->damage);
|
||||
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
|
||||
|
||||
if ((surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context))) &&
|
||||
(buffer = GDK_MACOS_SURFACE (surface)->front) &&
|
||||
(damage = _gdk_macos_buffer_get_damage (buffer)))
|
||||
return cairo_region_copy (damage);
|
||||
|
||||
return GDK_GL_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->get_damage (context);
|
||||
}
|
||||
@@ -619,8 +622,6 @@ gdk_macos_gl_context_dispose (GObject *gobject)
|
||||
CGLDestroyContext (cgl_context);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,16 +24,25 @@
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosmonitor.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkMacosMonitor *_gdk_macos_monitor_new (GdkMacosDisplay *display,
|
||||
CGDirectDisplayID screen_id);
|
||||
CGDirectDisplayID _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self);
|
||||
gboolean _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self);
|
||||
CGColorSpaceRef _gdk_macos_monitor_copy_colorspace (GdkMacosMonitor *self);
|
||||
char *_gdk_macos_monitor_get_localized_name (NSScreen *screen);
|
||||
char *_gdk_macos_monitor_get_connector_name (CGDirectDisplayID screen_id);
|
||||
GdkMacosMonitor *_gdk_macos_monitor_new (GdkMacosDisplay *display,
|
||||
CGDirectDisplayID screen_id);
|
||||
CGDirectDisplayID _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self);
|
||||
gboolean _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self);
|
||||
CGColorSpaceRef _gdk_macos_monitor_copy_colorspace (GdkMacosMonitor *self);
|
||||
void _gdk_macos_monitor_add_frame_callback (GdkMacosMonitor *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_monitor_remove_frame_callback (GdkMacosMonitor *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_monitor_clamp (GdkMacosMonitor *self,
|
||||
GdkRectangle *area);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+166
-11
@@ -22,16 +22,21 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gdkdisplaylinksource.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
struct _GdkMacosMonitor
|
||||
{
|
||||
GdkMonitor parent_instance;
|
||||
CGDirectDisplayID screen_id;
|
||||
NSRect workarea;
|
||||
guint has_opengl : 1;
|
||||
GdkMonitor parent_instance;
|
||||
CGDirectDisplayID screen_id;
|
||||
GdkDisplayLinkSource *display_link;
|
||||
NSRect workarea;
|
||||
GQueue awaiting_frames;
|
||||
guint has_opengl : 1;
|
||||
guint in_frame : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosMonitorClass
|
||||
@@ -75,9 +80,26 @@ gdk_macos_monitor_get_workarea (GdkMonitor *monitor,
|
||||
geometry->height = self->workarea.size.height;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_monitor_dispose (GObject *object)
|
||||
{
|
||||
GdkMacosMonitor *self = (GdkMacosMonitor *)object;
|
||||
|
||||
if (self->display_link)
|
||||
{
|
||||
g_source_destroy ((GSource *)self->display_link);
|
||||
g_clear_pointer ((GSource **)&self->display_link, g_source_unref);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_monitor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_monitor_class_init (GdkMacosMonitorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_macos_monitor_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -138,8 +160,8 @@ GetSubpixelLayout (CGDirectDisplayID screen_id)
|
||||
return GDK_SUBPIXEL_LAYOUT_UNKNOWN;
|
||||
}
|
||||
|
||||
static char *
|
||||
GetLocalizedName (NSScreen *screen)
|
||||
char *
|
||||
_gdk_macos_monitor_get_localized_name (NSScreen *screen)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
@@ -160,8 +182,8 @@ GetLocalizedName (NSScreen *screen)
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *
|
||||
GetConnectorName (CGDirectDisplayID screen_id)
|
||||
char *
|
||||
_gdk_macos_monitor_get_connector_name (CGDirectDisplayID screen_id)
|
||||
{
|
||||
guint unit = CGDisplayUnitNumber (screen_id);
|
||||
return g_strdup_printf ("unit-%u", unit);
|
||||
@@ -188,6 +210,68 @@ find_screen (CGDirectDisplayID screen_id)
|
||||
return screen;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_monitor_display_link_cb (GdkMacosMonitor *self)
|
||||
{
|
||||
gint64 presentation_time;
|
||||
gint64 refresh_interval;
|
||||
gint64 now;
|
||||
GList *iter;
|
||||
|
||||
g_assert (GDK_IS_MACOS_MONITOR (self));
|
||||
g_assert (!self->display_link->paused);
|
||||
|
||||
self->in_frame = TRUE;
|
||||
|
||||
presentation_time = self->display_link->presentation_time;
|
||||
refresh_interval = self->display_link->refresh_interval;
|
||||
now = g_source_get_time ((GSource *)self->display_link);
|
||||
|
||||
iter = self->awaiting_frames.head;
|
||||
|
||||
while (iter != NULL)
|
||||
{
|
||||
GdkMacosSurface *surface = iter->data;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
iter = iter->next;
|
||||
|
||||
g_queue_unlink (&self->awaiting_frames, &surface->frame);
|
||||
_gdk_macos_surface_frame_presented (surface, presentation_time, refresh_interval);
|
||||
}
|
||||
|
||||
if (self->awaiting_frames.length == 0 && !self->display_link->paused)
|
||||
gdk_display_link_source_pause (self->display_link);
|
||||
|
||||
self->in_frame = FALSE;
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_monitor_reset_display_link (GdkMacosMonitor *self,
|
||||
CGDisplayModeRef mode)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
g_assert (GDK_IS_MACOS_MONITOR (self));
|
||||
|
||||
if (self->display_link)
|
||||
{
|
||||
g_source_destroy ((GSource *)self->display_link);
|
||||
g_clear_pointer ((GSource **)&self->display_link, g_source_unref);
|
||||
}
|
||||
|
||||
source = gdk_display_link_source_new (self->screen_id, mode);
|
||||
self->display_link = (GdkDisplayLinkSource *)source;
|
||||
g_source_set_callback (source,
|
||||
(GSourceFunc) gdk_macos_monitor_display_link_cb,
|
||||
self,
|
||||
NULL);
|
||||
g_source_attach (source, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_monitor_reconfigure (GdkMacosMonitor *self)
|
||||
{
|
||||
@@ -222,8 +306,8 @@ _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self)
|
||||
pixel_width = CGDisplayModeGetPixelWidth (mode);
|
||||
has_opengl = CGDisplayUsesOpenGLAcceleration (self->screen_id);
|
||||
subpixel_layout = GetSubpixelLayout (self->screen_id);
|
||||
name = GetLocalizedName (screen);
|
||||
connector = GetConnectorName (self->screen_id);
|
||||
name = _gdk_macos_monitor_get_localized_name (screen);
|
||||
connector = _gdk_macos_monitor_get_connector_name (self->screen_id);
|
||||
|
||||
if (width != 0 && pixel_width != 0)
|
||||
scale_factor = MAX (1, pixel_width / width);
|
||||
@@ -241,7 +325,7 @@ _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self)
|
||||
* setting (which is also used by the frame clock).
|
||||
*/
|
||||
if (!(refresh_rate = CGDisplayModeGetRefreshRate (mode)))
|
||||
refresh_rate = _gdk_macos_display_get_nominal_refresh_rate (display);
|
||||
refresh_rate = 60 * 1000;
|
||||
|
||||
gdk_monitor_set_connector (GDK_MONITOR (self), connector);
|
||||
gdk_monitor_set_model (GDK_MONITOR (self), name);
|
||||
@@ -261,6 +345,9 @@ _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self)
|
||||
*/
|
||||
self->has_opengl = !!has_opengl;
|
||||
|
||||
/* Create a new display link to receive feedback about when to render */
|
||||
_gdk_macos_monitor_reset_display_link (self, mode);
|
||||
|
||||
CGDisplayModeRelease (mode);
|
||||
g_free (name);
|
||||
g_free (connector);
|
||||
@@ -302,3 +389,71 @@ _gdk_macos_monitor_copy_colorspace (GdkMacosMonitor *self)
|
||||
|
||||
return CGDisplayCopyColorSpace (self->screen_id);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_monitor_add_frame_callback (GdkMacosMonitor *self,
|
||||
GdkMacosSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_MONITOR (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_return_if_fail (surface->frame.data == (gpointer)surface);
|
||||
g_return_if_fail (surface->frame.prev == NULL);
|
||||
g_return_if_fail (surface->frame.next == NULL);
|
||||
g_return_if_fail (self->awaiting_frames.head != &surface->frame);
|
||||
g_return_if_fail (self->awaiting_frames.tail != &surface->frame);
|
||||
|
||||
/* Processing frames is always head to tail, so push to the
|
||||
* head so that we don't possibly re-enter this right after
|
||||
* adding to the queue.
|
||||
*/
|
||||
if (!queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
{
|
||||
g_queue_push_head_link (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
if (!self->in_frame && self->awaiting_frames.length == 1)
|
||||
gdk_display_link_source_unpause (self->display_link);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_monitor_remove_frame_callback (GdkMacosMonitor *self,
|
||||
GdkMacosSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_MONITOR (self));
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_return_if_fail (surface->frame.data == (gpointer)surface);
|
||||
|
||||
if (queue_contains (&self->awaiting_frames, &surface->frame))
|
||||
{
|
||||
g_queue_unlink (&self->awaiting_frames, &surface->frame);
|
||||
|
||||
if (!self->in_frame && self->awaiting_frames.length == 0)
|
||||
gdk_display_link_source_pause (self->display_link);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_monitor_clamp (GdkMacosMonitor *self,
|
||||
GdkRectangle *area)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
GdkRectangle geom;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_MONITOR (self));
|
||||
g_return_if_fail (area != NULL);
|
||||
|
||||
gdk_macos_monitor_get_workarea (GDK_MONITOR (self), &workarea);
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (self), &geom);
|
||||
|
||||
if (area->x + area->width > workarea.x + workarea.width)
|
||||
area->x = workarea.x + workarea.width - area->width;
|
||||
|
||||
if (area->x < workarea.x)
|
||||
area->x = workarea.x;
|
||||
|
||||
if (area->y + area->height > workarea.y + workarea.height)
|
||||
area->y = workarea.y + workarea.height - area->height;
|
||||
|
||||
if (area->y < workarea.y)
|
||||
area->y = workarea.y;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ struct _GdkMacosPopupSurface
|
||||
{
|
||||
GdkMacosSurface parent_instance;
|
||||
GdkPopupLayout *layout;
|
||||
guint attached : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosPopupSurfaceClass
|
||||
@@ -87,6 +88,9 @@ gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
|
||||
|
||||
gdk_surface_get_origin (GDK_SURFACE (self)->parent, &x, &y);
|
||||
|
||||
GDK_SURFACE (self)->x = final_rect.x;
|
||||
GDK_SURFACE (self)->y = final_rect.y;
|
||||
|
||||
x += final_rect.x;
|
||||
y += final_rect.y;
|
||||
|
||||
@@ -135,6 +139,9 @@ gdk_macos_popup_surface_present (GdkPopup *popup,
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)))
|
||||
return TRUE;
|
||||
|
||||
if (!self->attached && GDK_SURFACE (self)->parent != NULL)
|
||||
_gdk_macos_popup_surface_attach_to_parent (self);
|
||||
|
||||
if (GDK_SURFACE (self)->autohide)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (popup));
|
||||
@@ -200,6 +207,19 @@ enum {
|
||||
LAST_PROP,
|
||||
};
|
||||
|
||||
static void
|
||||
_gdk_macos_popup_surface_hide (GdkSurface *surface)
|
||||
{
|
||||
GdkMacosPopupSurface *self = (GdkMacosPopupSurface *)surface;
|
||||
|
||||
g_assert (GDK_IS_MACOS_POPUP_SURFACE (self));
|
||||
|
||||
if (self->attached)
|
||||
_gdk_macos_popup_surface_detach_from_parent (self);
|
||||
|
||||
GDK_SURFACE_CLASS (_gdk_macos_popup_surface_parent_class)->hide (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_popup_surface_finalize (GObject *object)
|
||||
{
|
||||
@@ -267,12 +287,15 @@ static void
|
||||
_gdk_macos_popup_surface_class_init (GdkMacosPopupSurfaceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (klass);
|
||||
|
||||
object_class->finalize = _gdk_macos_popup_surface_finalize;
|
||||
object_class->get_property = _gdk_macos_popup_surface_get_property;
|
||||
object_class->set_property = _gdk_macos_popup_surface_set_property;
|
||||
|
||||
gdk_popup_install_properties (object_class, 1);
|
||||
surface_class->hide = _gdk_macos_popup_surface_hide;
|
||||
|
||||
gdk_popup_install_properties (object_class, LAST_PROP);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -323,14 +346,8 @@ _gdk_macos_popup_surface_new (GdkMacosDisplay *display,
|
||||
[window setOpaque:NO];
|
||||
[window setBackgroundColor:[NSColor clearColor]];
|
||||
[window setDecorated:NO];
|
||||
|
||||
#if 0
|
||||
/* NOTE: We could set these to be popup level, but then
|
||||
* [NSApp orderedWindows] would not give us the windows
|
||||
* back with the stacking order applied.
|
||||
*/
|
||||
[window setExcludedFromWindowsMenu:YES];
|
||||
[window setLevel:NSPopUpMenuWindowLevel];
|
||||
#endif
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_POPUP_SURFACE,
|
||||
"display", display,
|
||||
@@ -361,6 +378,8 @@ _gdk_macos_popup_surface_attach_to_parent (GdkMacosPopupSurface *self)
|
||||
|
||||
[parent addChildWindow:window ordered:NSWindowAbove];
|
||||
|
||||
self->attached = TRUE;
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (surface->display));
|
||||
}
|
||||
}
|
||||
@@ -382,6 +401,8 @@ _gdk_macos_popup_surface_detach_from_parent (GdkMacosPopupSurface *self)
|
||||
|
||||
[parent removeChildWindow:window];
|
||||
|
||||
self->attached = FALSE;
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (surface->display));
|
||||
}
|
||||
}
|
||||
@@ -391,9 +412,7 @@ _gdk_macos_popup_surface_reposition (GdkMacosPopupSurface *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_POPUP_SURFACE (self));
|
||||
|
||||
if (self->layout == NULL ||
|
||||
!gdk_surface_get_mapped (GDK_SURFACE (self)) ||
|
||||
GDK_SURFACE (self)->parent == NULL)
|
||||
if (self->layout == NULL || GDK_SURFACE (self)->parent == NULL)
|
||||
return;
|
||||
|
||||
gdk_macos_popup_surface_layout (self,
|
||||
|
||||
@@ -49,7 +49,7 @@ struct _GdkMacosSurface
|
||||
GdkMacosBuffer *buffer;
|
||||
GdkMacosBuffer *front;
|
||||
GPtrArray *monitors;
|
||||
cairo_region_t *opaque_region;
|
||||
GdkMonitor *best_monitor;
|
||||
char *title;
|
||||
|
||||
int root_x;
|
||||
@@ -75,6 +75,9 @@ struct _GdkMacosSurface
|
||||
guint geometry_dirty : 1;
|
||||
guint next_frame_set : 1;
|
||||
guint show_on_next_swap : 1;
|
||||
guint in_change_monitor : 1;
|
||||
guint in_frame : 1;
|
||||
guint awaiting_frame : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosSurfaceClass
|
||||
@@ -116,11 +119,11 @@ void _gdk_macos_surface_resize (GdkMacosSurface
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_update_position (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_show (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_publish_timings (GdkMacosSurface *self,
|
||||
void _gdk_macos_surface_request_frame (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_frame_presented (GdkMacosSurface *self,
|
||||
gint64 predicted_presentation_time,
|
||||
gint64 refresh_interval);
|
||||
void _gdk_macos_surface_show (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_synthesize_null_key (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_move (GdkMacosSurface *self,
|
||||
int x,
|
||||
|
||||
+224
-123
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
#include "gdkdebug.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
@@ -63,16 +64,87 @@ window_is_fullscreen (GdkMacosSurface *self)
|
||||
return ([self->window styleMask] & NSWindowStyleMaskFullScreen) != 0;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_surface_request_frame (GdkMacosSurface *self)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (self->awaiting_frame)
|
||||
return;
|
||||
|
||||
if (self->best_monitor != NULL)
|
||||
{
|
||||
self->awaiting_frame = TRUE;
|
||||
_gdk_macos_monitor_add_frame_callback (GDK_MACOS_MONITOR (self->best_monitor), self);
|
||||
gdk_surface_freeze_updates (GDK_SURFACE (self));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_surface_cancel_frame (GdkMacosSurface *self)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (!self->awaiting_frame)
|
||||
return;
|
||||
|
||||
if (self->best_monitor != NULL)
|
||||
{
|
||||
self->awaiting_frame = FALSE;
|
||||
_gdk_macos_monitor_remove_frame_callback (GDK_MACOS_MONITOR (self->best_monitor), self);
|
||||
gdk_surface_thaw_updates (GDK_SURFACE (self));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_surface_frame_presented (GdkMacosSurface *self,
|
||||
gint64 presentation_time,
|
||||
gint64 refresh_interval)
|
||||
{
|
||||
GdkFrameTimings *timings;
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
self->awaiting_frame = FALSE;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
return;
|
||||
|
||||
frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self));
|
||||
|
||||
if (self->pending_frame_counter)
|
||||
{
|
||||
timings = gdk_frame_clock_get_timings (frame_clock, self->pending_frame_counter);
|
||||
|
||||
if (timings != NULL)
|
||||
{
|
||||
timings->presentation_time = presentation_time - refresh_interval;
|
||||
timings->complete = TRUE;
|
||||
}
|
||||
|
||||
self->pending_frame_counter = 0;
|
||||
}
|
||||
|
||||
timings = gdk_frame_clock_get_current_timings (frame_clock);
|
||||
|
||||
if (timings != NULL)
|
||||
{
|
||||
timings->refresh_interval = refresh_interval;
|
||||
timings->predicted_presentation_time = presentation_time;
|
||||
}
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)))
|
||||
gdk_surface_thaw_updates (GDK_SURFACE (self));
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_surface_reposition_children (GdkMacosSurface *self)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
return;
|
||||
|
||||
if (!gdk_surface_get_mapped (GDK_SURFACE (self)))
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
return;
|
||||
|
||||
for (const GList *iter = GDK_SURFACE (self)->children;
|
||||
@@ -86,9 +158,6 @@ _gdk_macos_surface_reposition_children (GdkMacosSurface *self)
|
||||
if (GDK_IS_MACOS_POPUP_SURFACE (child))
|
||||
_gdk_macos_popup_surface_reposition (GDK_MACOS_POPUP_SURFACE (child));
|
||||
}
|
||||
|
||||
if (GDK_IS_POPUP (self) && self->did_initial_present)
|
||||
gdk_surface_request_layout (GDK_SURFACE (self));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -117,12 +186,6 @@ gdk_macos_surface_set_opaque_region (GdkSurface *surface,
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (region != self->opaque_region)
|
||||
{
|
||||
g_clear_pointer (&self->opaque_region, cairo_region_destroy);
|
||||
self->opaque_region = cairo_region_copy (region);
|
||||
}
|
||||
|
||||
if ((nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface))))
|
||||
[(GdkMacosView *)nsview setOpaqueRegion:region];
|
||||
}
|
||||
@@ -139,9 +202,9 @@ gdk_macos_surface_hide (GdkSurface *surface)
|
||||
|
||||
self->show_on_next_swap = FALSE;
|
||||
|
||||
_gdk_macos_display_remove_frame_callback (GDK_MACOS_DISPLAY (surface->display), self);
|
||||
_gdk_macos_surface_cancel_frame (self);
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
was_key = [self->window isKeyWindow];
|
||||
|
||||
seat = gdk_display_get_default_seat (surface->display);
|
||||
@@ -156,17 +219,21 @@ gdk_macos_surface_hide (GdkSurface *surface)
|
||||
|
||||
if (was_key)
|
||||
{
|
||||
GdkSurface *parent;
|
||||
|
||||
if (GDK_IS_TOPLEVEL (surface))
|
||||
parent = surface->transient_for;
|
||||
else
|
||||
parent = surface->parent;
|
||||
|
||||
/* Return key input to the parent window if necessary */
|
||||
if (surface->parent != NULL && GDK_SURFACE_IS_MAPPED (surface->parent))
|
||||
if (parent != NULL && GDK_SURFACE_IS_MAPPED (parent))
|
||||
{
|
||||
GdkMacosWindow *parentWindow = GDK_MACOS_SURFACE (surface->parent)->window;
|
||||
GdkMacosWindow *parentWindow = GDK_MACOS_SURFACE (parent)->window;
|
||||
|
||||
[parentWindow showAndMakeKey:YES];
|
||||
}
|
||||
}
|
||||
|
||||
if (was_mapped)
|
||||
gdk_surface_freeze_updates (GDK_SURFACE (self));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -210,6 +277,7 @@ gdk_macos_surface_begin_frame (GdkMacosSurface *self)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
self->in_frame = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -230,11 +298,9 @@ gdk_macos_surface_end_frame (GdkMacosSurface *self)
|
||||
if ((timings = gdk_frame_clock_get_current_timings (frame_clock)))
|
||||
self->pending_frame_counter = timings->frame_counter;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)))
|
||||
{
|
||||
_gdk_macos_display_add_frame_callback (GDK_MACOS_DISPLAY (display), self);
|
||||
gdk_surface_freeze_updates (GDK_SURFACE (self));
|
||||
}
|
||||
self->in_frame = FALSE;
|
||||
|
||||
_gdk_macos_surface_request_frame (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -408,6 +474,9 @@ gdk_macos_surface_destroy (GdkSurface *surface,
|
||||
GdkMacosWindow *window = g_steal_pointer (&self->window);
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
_gdk_macos_surface_cancel_frame (self);
|
||||
g_clear_object (&self->best_monitor);
|
||||
|
||||
if ((frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self))))
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (frame_clock,
|
||||
@@ -419,7 +488,6 @@ gdk_macos_surface_destroy (GdkSurface *surface,
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->title, g_free);
|
||||
g_clear_pointer (&self->opaque_region, cairo_region_destroy);
|
||||
|
||||
if (window != NULL)
|
||||
[window close];
|
||||
@@ -561,7 +629,7 @@ _gdk_macos_surface_new (GdkMacosDisplay *display,
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
if (parent != NULL)
|
||||
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
|
||||
frame_clock = g_object_ref (parent->frame_clock);
|
||||
else
|
||||
frame_clock = _gdk_frame_clock_idle_new ();
|
||||
|
||||
@@ -621,14 +689,16 @@ _gdk_macos_surface_get_shadow (GdkMacosSurface *self,
|
||||
gboolean
|
||||
_gdk_macos_surface_is_opaque (GdkMacosSurface *self)
|
||||
{
|
||||
GdkSurface *surface = (GdkSurface *)self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (self), FALSE);
|
||||
|
||||
if (self->opaque_region != NULL &&
|
||||
cairo_region_num_rectangles (self->opaque_region) == 1)
|
||||
if (surface->opaque_region != NULL &&
|
||||
cairo_region_num_rectangles (surface->opaque_region) == 1)
|
||||
{
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
cairo_region_get_extents (self->opaque_region, &extents);
|
||||
cairo_region_get_extents (surface->opaque_region, &extents);
|
||||
|
||||
return (extents.x == 0 &&
|
||||
extents.y == 0 &&
|
||||
@@ -748,8 +818,9 @@ _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self)
|
||||
void
|
||||
_gdk_macos_surface_configure (GdkMacosSurface *self)
|
||||
{
|
||||
GdkMacosDisplay *display;
|
||||
GdkSurface *surface = (GdkSurface *)self;
|
||||
GdkMacosDisplay *display;
|
||||
GdkMacosSurface *parent;
|
||||
NSRect frame_rect;
|
||||
NSRect content_rect;
|
||||
|
||||
@@ -758,6 +829,13 @@ _gdk_macos_surface_configure (GdkMacosSurface *self)
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
return;
|
||||
|
||||
if (surface->parent != NULL)
|
||||
parent = GDK_MACOS_SURFACE (surface->parent);
|
||||
else if (surface->transient_for != NULL)
|
||||
parent = GDK_MACOS_SURFACE (surface->transient_for);
|
||||
else
|
||||
parent = NULL;
|
||||
|
||||
display = GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display);
|
||||
frame_rect = [self->window frame];
|
||||
content_rect = [self->window contentRectForFrameRect:frame_rect];
|
||||
@@ -767,18 +845,15 @@ _gdk_macos_surface_configure (GdkMacosSurface *self)
|
||||
content_rect.origin.y + content_rect.size.height,
|
||||
&self->root_x, &self->root_y);
|
||||
|
||||
if (self->did_initial_present)
|
||||
if (parent != NULL)
|
||||
{
|
||||
if (surface->parent != NULL)
|
||||
{
|
||||
surface->x = self->root_x - GDK_MACOS_SURFACE (surface->parent)->root_x;
|
||||
surface->y = self->root_y - GDK_MACOS_SURFACE (surface->parent)->root_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
surface->x = self->root_x;
|
||||
surface->y = self->root_y;
|
||||
}
|
||||
surface->x = self->root_x - parent->root_x;
|
||||
surface->y = self->root_y - parent->root_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
surface->x = self->root_x;
|
||||
surface->y = self->root_y;
|
||||
}
|
||||
|
||||
if (surface->width != content_rect.size.width ||
|
||||
@@ -791,48 +866,12 @@ _gdk_macos_surface_configure (GdkMacosSurface *self)
|
||||
g_clear_object (&self->front);
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
gdk_surface_request_layout (surface);
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
|
||||
_gdk_macos_surface_reposition_children (self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_surface_publish_timings (GdkMacosSurface *self,
|
||||
gint64 presentation_time,
|
||||
gint64 refresh_interval)
|
||||
{
|
||||
GdkFrameTimings *timings;
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (!(frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self))))
|
||||
return;
|
||||
|
||||
if (self->pending_frame_counter)
|
||||
{
|
||||
timings = gdk_frame_clock_get_timings (frame_clock, self->pending_frame_counter);
|
||||
|
||||
if (timings != NULL)
|
||||
{
|
||||
timings->presentation_time = presentation_time - refresh_interval;
|
||||
timings->complete = TRUE;
|
||||
}
|
||||
|
||||
self->pending_frame_counter = 0;
|
||||
}
|
||||
|
||||
timings = gdk_frame_clock_get_current_timings (frame_clock);
|
||||
|
||||
if (timings != NULL)
|
||||
{
|
||||
timings->refresh_interval = refresh_interval;
|
||||
timings->predicted_presentation_time = presentation_time;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_surface_show (GdkMacosSurface *self)
|
||||
{
|
||||
@@ -843,22 +882,17 @@ _gdk_macos_surface_show (GdkMacosSurface *self)
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
return;
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display));
|
||||
self->show_on_next_swap = TRUE;
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
|
||||
|
||||
if (!was_mapped)
|
||||
gdk_surface_set_is_mapped (GDK_SURFACE (self), TRUE);
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display));
|
||||
|
||||
self->show_on_next_swap = TRUE;
|
||||
|
||||
if (!was_mapped)
|
||||
{
|
||||
if (gdk_surface_get_mapped (GDK_SURFACE (self)))
|
||||
{
|
||||
_gdk_macos_surface_configure (self);
|
||||
gdk_surface_thaw_updates (GDK_SURFACE (self));
|
||||
}
|
||||
gdk_surface_set_is_mapped (GDK_SURFACE (self), TRUE);
|
||||
gdk_surface_request_layout (GDK_SURFACE (self));
|
||||
gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL);
|
||||
gdk_surface_thaw_updates (GDK_SURFACE (self));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -911,36 +945,59 @@ _gdk_macos_surface_move_resize (GdkMacosSurface *self,
|
||||
GdkDisplay *display;
|
||||
NSRect content_rect;
|
||||
NSRect frame_rect;
|
||||
gboolean ignore_move;
|
||||
gboolean ignore_size;
|
||||
GdkRectangle current;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if ((x == -1 || (x == self->root_x)) &&
|
||||
(y == -1 || (y == self->root_y)) &&
|
||||
(width == -1 || (width == surface->width)) &&
|
||||
(height == -1 || (height == surface->height)))
|
||||
/* Query for up-to-date values in case we're racing against
|
||||
* an incoming frame notify which could be queued behind whatever
|
||||
* we're processing right now.
|
||||
*/
|
||||
frame_rect = [self->window frame];
|
||||
content_rect = [self->window contentRectForFrameRect:frame_rect];
|
||||
_gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display),
|
||||
content_rect.origin.x, content_rect.origin.y,
|
||||
¤t.x, ¤t.y);
|
||||
current.width = content_rect.size.width;
|
||||
current.height = content_rect.size.height;
|
||||
|
||||
/* Check if we can ignore the operation all together */
|
||||
ignore_move = (x == -1 || (x == current.x)) &&
|
||||
(y == -1 || (y == current.y));
|
||||
ignore_size = (width == -1 || (width == current.width)) &&
|
||||
(height == -1 || (height == current.height));
|
||||
|
||||
if (ignore_move && ignore_size)
|
||||
return;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
|
||||
if (width == -1)
|
||||
width = surface->width;
|
||||
width = current.width;
|
||||
|
||||
if (height == -1)
|
||||
height = surface->height;
|
||||
height = current.height;
|
||||
|
||||
if (x == -1)
|
||||
x = self->root_x;
|
||||
x = current.x;
|
||||
|
||||
if (y == -1)
|
||||
y = self->root_y;
|
||||
y = current.y;
|
||||
|
||||
_gdk_macos_display_to_display_coords (GDK_MACOS_DISPLAY (display),
|
||||
x, y + height,
|
||||
&x, &y);
|
||||
|
||||
content_rect = NSMakeRect (x, y, width, height);
|
||||
if (!ignore_move)
|
||||
content_rect.origin = NSMakePoint (x, y);
|
||||
|
||||
if (!ignore_size)
|
||||
content_rect.size = NSMakeSize (width, height);
|
||||
|
||||
frame_rect = [self->window frameRectForContentRect:content_rect];
|
||||
[self->window setFrame:frame_rect display:YES];
|
||||
[self->window setFrame:frame_rect display:NO];
|
||||
}
|
||||
|
||||
void
|
||||
@@ -995,14 +1052,24 @@ void
|
||||
_gdk_macos_surface_monitor_changed (GdkMacosSurface *self)
|
||||
{
|
||||
GListModel *monitors;
|
||||
GdkMonitor *best = NULL;
|
||||
GdkRectangle rect;
|
||||
GdkRectangle intersect;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
guint n_monitors;
|
||||
int best_area = 0;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (self->in_change_monitor)
|
||||
return;
|
||||
|
||||
self->in_change_monitor = TRUE;
|
||||
|
||||
_gdk_macos_surface_cancel_frame (self);
|
||||
_gdk_macos_surface_configure (self);
|
||||
|
||||
rect.x = self->root_x;
|
||||
rect.y = self->root_y;
|
||||
rect.width = GDK_SURFACE (self)->width;
|
||||
@@ -1042,29 +1109,10 @@ _gdk_macos_surface_monitor_changed (GdkMacosSurface *self)
|
||||
g_clear_object (&self->buffer);
|
||||
g_clear_object (&self->front);
|
||||
|
||||
_gdk_macos_surface_configure (self);
|
||||
|
||||
gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL);
|
||||
}
|
||||
|
||||
GdkMonitor *
|
||||
_gdk_macos_surface_get_best_monitor (GdkMacosSurface *self)
|
||||
{
|
||||
GdkMonitor *best = NULL;
|
||||
GdkRectangle rect;
|
||||
int best_area = 0;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (self), NULL);
|
||||
|
||||
rect.x = self->root_x;
|
||||
rect.y = self->root_y;
|
||||
rect.width = GDK_SURFACE (self)->width;
|
||||
rect.height = GDK_SURFACE (self)->height;
|
||||
|
||||
/* Determine the best-fit monitor */
|
||||
for (guint i = 0; i < self->monitors->len; i++)
|
||||
{
|
||||
GdkMonitor *monitor = g_ptr_array_index (self->monitors, i);
|
||||
GdkRectangle intersect;
|
||||
monitor = g_ptr_array_index (self->monitors, i);
|
||||
|
||||
if (gdk_rectangle_intersect (&monitor->geometry, &rect, &intersect))
|
||||
{
|
||||
@@ -1072,13 +1120,62 @@ _gdk_macos_surface_get_best_monitor (GdkMacosSurface *self)
|
||||
|
||||
if (area > best_area)
|
||||
{
|
||||
best = monitor;
|
||||
best_area = area;
|
||||
best = monitor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
if (g_set_object (&self->best_monitor, best))
|
||||
{
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("Surface \"%s\" moved to monitor \"%s\"",
|
||||
self->title ? self->title : "unknown",
|
||||
gdk_monitor_get_connector (best)));
|
||||
|
||||
_gdk_macos_surface_configure (self);
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)))
|
||||
{
|
||||
_gdk_macos_surface_request_frame (self);
|
||||
gdk_surface_request_layout (GDK_SURFACE (self));
|
||||
}
|
||||
|
||||
for (const GList *iter = GDK_SURFACE (self)->children;
|
||||
iter != NULL;
|
||||
iter = iter->next)
|
||||
{
|
||||
GdkMacosSurface *child = iter->data;
|
||||
GdkRectangle area;
|
||||
|
||||
g_set_object (&child->best_monitor, best);
|
||||
|
||||
area.x = self->root_x + GDK_SURFACE (child)->x + child->shadow_left;
|
||||
area.y = self->root_y + GDK_SURFACE (child)->y + child->shadow_top;
|
||||
area.width = GDK_SURFACE (child)->width - child->shadow_left - child->shadow_right;
|
||||
area.height = GDK_SURFACE (child)->height - child->shadow_top - child->shadow_bottom;
|
||||
|
||||
_gdk_macos_monitor_clamp (GDK_MACOS_MONITOR (best), &area);
|
||||
|
||||
area.x -= child->shadow_left;
|
||||
area.y -= child->shadow_top;
|
||||
|
||||
_gdk_macos_surface_move (child, area.x, area.y);
|
||||
gdk_surface_invalidate_rect (GDK_SURFACE (child), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL);
|
||||
|
||||
self->in_change_monitor = FALSE;
|
||||
}
|
||||
|
||||
GdkMonitor *
|
||||
_gdk_macos_surface_get_best_monitor (GdkMacosSurface *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (self), NULL);
|
||||
|
||||
return self->best_monitor;
|
||||
}
|
||||
|
||||
NSView *
|
||||
@@ -1154,11 +1251,15 @@ _gdk_macos_surface_get_buffer (GdkMacosSurface *self)
|
||||
static void
|
||||
_gdk_macos_surface_do_delayed_show (GdkMacosSurface *self)
|
||||
{
|
||||
GdkSurface *surface = (GdkSurface *)self;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
self->show_on_next_swap = FALSE;
|
||||
[self->window showAndMakeKey:YES];
|
||||
gdk_surface_request_motion (GDK_SURFACE (self));
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (surface->display));
|
||||
gdk_surface_request_motion (surface);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -33,26 +33,26 @@
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_fullscreen (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
NSWindow *window;
|
||||
GdkMacosWindow *window;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
window = (GdkMacosWindow *)_gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
if (([window styleMask] & NSWindowStyleMaskFullScreen) == 0)
|
||||
if (![window inFullscreenTransition] && ([window styleMask] & NSWindowStyleMaskFullScreen) == 0)
|
||||
[window toggleFullScreen:window];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_unfullscreen (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
NSWindow *window;
|
||||
GdkMacosWindow *window;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
window = (GdkMacosWindow *)_gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
if (([window styleMask] & NSWindowStyleMaskFullScreen) != 0)
|
||||
if (![window inFullscreenTransition] && ([window styleMask] & NSWindowStyleMaskFullScreen) != 0)
|
||||
[window toggleFullScreen:window];
|
||||
}
|
||||
|
||||
@@ -82,6 +82,19 @@ _gdk_macos_toplevel_surface_unmaximize (GdkMacosToplevelSurface *self)
|
||||
[window zoom:window];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_unminimize (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
NSWindow *window;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
if ([window isMiniaturized])
|
||||
[window deminiaturize:window];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
GdkToplevelLayout *layout)
|
||||
@@ -174,6 +187,14 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
|
||||
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("Resizing \"%s\" to %dx%d",
|
||||
GDK_MACOS_SURFACE (self)->title ?
|
||||
GDK_MACOS_SURFACE (self)->title :
|
||||
"untitled",
|
||||
width, height));
|
||||
|
||||
_gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
|
||||
|
||||
/* Maximized state */
|
||||
@@ -194,6 +215,8 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
_gdk_macos_toplevel_surface_unfullscreen (self);
|
||||
}
|
||||
|
||||
_gdk_macos_toplevel_surface_unminimize (self);
|
||||
|
||||
if (!GDK_MACOS_SURFACE (self)->did_initial_present)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
@@ -202,6 +225,13 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
GDK_MACOS_SURFACE (self),
|
||||
&x, &y);
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("Placing new toplevel \"%s\" at %d,%d",
|
||||
GDK_MACOS_SURFACE (self)->title ?
|
||||
GDK_MACOS_SURFACE (self)->title :
|
||||
"untitled",
|
||||
x, y));
|
||||
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self), x, y);
|
||||
}
|
||||
|
||||
@@ -421,7 +451,8 @@ _gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
|
||||
GDK_TOPLEVEL_STATE_RIGHT_TILED |
|
||||
GDK_TOPLEVEL_STATE_BOTTOM_TILED |
|
||||
GDK_TOPLEVEL_STATE_LEFT_TILED |
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED))
|
||||
GDK_TOPLEVEL_STATE_MINIMIZED) ||
|
||||
[macos_surface->window inLiveResize])
|
||||
return FALSE;
|
||||
|
||||
/* If we delayed a user resize until the beginning of the frame,
|
||||
@@ -632,10 +663,10 @@ _gdk_macos_toplevel_surface_new (GdkMacosDisplay *display,
|
||||
|
||||
GdkMacosWindow *window;
|
||||
GdkMacosSurface *self;
|
||||
NSScreen *screen;
|
||||
NSUInteger style_mask;
|
||||
NSRect content_rect;
|
||||
NSRect screen_rect;
|
||||
NSRect visible_frame;
|
||||
NSScreen *screen;
|
||||
int nx;
|
||||
int ny;
|
||||
|
||||
@@ -648,14 +679,17 @@ _gdk_macos_toplevel_surface_new (GdkMacosDisplay *display,
|
||||
NSWindowStyleMaskMiniaturizable |
|
||||
NSWindowStyleMaskResizable);
|
||||
|
||||
_gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
|
||||
if (parent != NULL)
|
||||
{
|
||||
x += GDK_MACOS_SURFACE (parent)->root_x;
|
||||
y += GDK_MACOS_SURFACE (parent)->root_y;
|
||||
}
|
||||
|
||||
_gdk_macos_display_to_display_coords (display, x, y + height, &nx, &ny);
|
||||
|
||||
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
|
||||
screen_rect = [screen visibleFrame];
|
||||
nx -= screen_rect.origin.x;
|
||||
ny -= screen_rect.origin.y;
|
||||
content_rect = NSMakeRect (nx, ny - height, width, height);
|
||||
|
||||
visible_frame = [screen visibleFrame];
|
||||
content_rect = NSMakeRect (nx - visible_frame.origin.x, ny - visible_frame.origin.y, width, height);
|
||||
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
|
||||
styleMask:style_mask
|
||||
backing:NSBackingStoreBuffered
|
||||
@@ -691,13 +725,21 @@ _gdk_macos_toplevel_surface_attach_to_parent (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
NSWindow *parent = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface->transient_for));
|
||||
NSWindow *window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
int x, y;
|
||||
|
||||
[parent addChildWindow:window ordered:NSWindowAbove];
|
||||
|
||||
if (GDK_SURFACE (self)->modal_hint)
|
||||
[window setLevel:NSModalPanelWindowLevel];
|
||||
|
||||
surface->x = 0;
|
||||
surface->y = 0;
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (surface->display));
|
||||
_gdk_macos_display_position_surface (GDK_MACOS_DISPLAY (surface->display),
|
||||
GDK_MACOS_SURFACE (surface),
|
||||
&x, &y);
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (surface), x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ gdk_macos_sources = files([
|
||||
'gdkmacoscursor.c',
|
||||
'gdkmacosdevice.c',
|
||||
'gdkmacosdisplay.c',
|
||||
'gdkmacosdisplay-feedback.c',
|
||||
'gdkmacosdisplay-settings.c',
|
||||
'gdkmacosdisplay-translate.c',
|
||||
'gdkmacosdisplay-wm.c',
|
||||
|
||||
@@ -200,23 +200,51 @@ wl_cursor_destroy(struct wl_cursor *cursor)
|
||||
}
|
||||
|
||||
static struct wl_cursor *
|
||||
wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
||||
struct wl_cursor_theme *theme,
|
||||
wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int load_size)
|
||||
unsigned int size,
|
||||
unsigned int scale)
|
||||
{
|
||||
char *path;
|
||||
XcursorImages *images;
|
||||
struct cursor *cursor;
|
||||
struct cursor_image *image;
|
||||
int i, size;
|
||||
int i, nbytes;
|
||||
unsigned int load_size;
|
||||
int load_scale = 1;
|
||||
|
||||
load_size = size * scale;
|
||||
|
||||
path = g_strconcat (theme->path, "/", name, NULL);
|
||||
images = xcursor_load_images (path, load_size);
|
||||
|
||||
if (!images)
|
||||
{
|
||||
g_free (path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (images->images[0]->width != load_size ||
|
||||
images->images[0]->height != load_size)
|
||||
{
|
||||
xcursor_images_destroy (images);
|
||||
images = xcursor_load_images (path, size);
|
||||
load_scale = scale;
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
|
||||
cursor = malloc(sizeof *cursor);
|
||||
if (!cursor)
|
||||
if (!cursor) {
|
||||
xcursor_images_destroy (images);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cursor->cursor.images =
|
||||
malloc(images->nimage * sizeof cursor->cursor.images[0]);
|
||||
if (!cursor->cursor.images) {
|
||||
free(cursor);
|
||||
xcursor_images_destroy (images);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -232,22 +260,37 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
||||
image->theme = theme;
|
||||
image->buffer = NULL;
|
||||
|
||||
image->image.width = images->images[i]->width;
|
||||
image->image.height = images->images[i]->height;
|
||||
image->image.hotspot_x = images->images[i]->xhot;
|
||||
image->image.hotspot_y = images->images[i]->yhot;
|
||||
image->image.width = images->images[i]->width * load_scale;
|
||||
image->image.height = images->images[i]->height * load_scale;
|
||||
image->image.hotspot_x = images->images[i]->xhot * load_scale;
|
||||
image->image.hotspot_y = images->images[i]->yhot * load_scale;
|
||||
image->image.delay = images->images[i]->delay;
|
||||
|
||||
size = image->image.width * image->image.height * 4;
|
||||
image->offset = shm_pool_allocate(theme->pool, size);
|
||||
nbytes = image->image.width * image->image.height * 4;
|
||||
image->offset = shm_pool_allocate(theme->pool, nbytes);
|
||||
if (image->offset < 0) {
|
||||
free(image);
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy pixels to shm pool */
|
||||
memcpy(theme->pool->data + image->offset,
|
||||
images->images[i]->pixels, size);
|
||||
if (load_scale == 1) {
|
||||
/* copy pixels to shm pool */
|
||||
memcpy(theme->pool->data + image->offset,
|
||||
images->images[i]->pixels, nbytes);
|
||||
}
|
||||
else {
|
||||
/* scale image up while copying it */
|
||||
for (int y = 0; y < image->image.height; y++) {
|
||||
char *p = theme->pool->data + image->offset + y * image->image.width * 4;
|
||||
char *q = ((char *)images->images[i]->pixels) + (y / load_scale) * images->images[i]->width * 4;
|
||||
for (int x = 0; x < image->image.width; x++) {
|
||||
p[4 * x] = q[4 * (x/load_scale)];
|
||||
p[4 * x + 1] = q[4 * (x/load_scale) + 1];
|
||||
p[4 * x + 2] = q[4 * (x/load_scale) + 2];
|
||||
p[4 * x + 3] = q[4 * (x/load_scale) + 3];
|
||||
}
|
||||
}
|
||||
}
|
||||
cursor->total_delay += image->image.delay;
|
||||
cursor->cursor.images[i] = (struct wl_cursor_image *) image;
|
||||
}
|
||||
@@ -257,27 +300,24 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
||||
free(cursor->cursor.name);
|
||||
free(cursor->cursor.images);
|
||||
free(cursor);
|
||||
xcursor_images_destroy (images);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xcursor_images_destroy (images);
|
||||
|
||||
return &cursor->cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
load_cursor(struct wl_cursor_theme *theme, const char *name, unsigned int size)
|
||||
load_cursor(struct wl_cursor_theme *theme,
|
||||
const char *name,
|
||||
unsigned int size,
|
||||
unsigned int scale)
|
||||
{
|
||||
XcursorImages *images;
|
||||
struct wl_cursor *cursor;
|
||||
char *path;
|
||||
|
||||
path = g_strconcat (theme->path, "/", name, NULL);
|
||||
images = xcursor_load_images (path, size);
|
||||
g_free (path);
|
||||
|
||||
if (!images)
|
||||
return;
|
||||
|
||||
cursor = wl_cursor_create_from_xcursor_images(images, theme, name, size);
|
||||
cursor = wl_cursor_create_from_xcursor_images(theme, name, size, scale);
|
||||
|
||||
if (cursor) {
|
||||
theme->cursor_count++;
|
||||
@@ -292,8 +332,6 @@ load_cursor(struct wl_cursor_theme *theme, const char *name, unsigned int size)
|
||||
theme->cursors[theme->cursor_count - 1] = cursor;
|
||||
}
|
||||
}
|
||||
|
||||
xcursor_images_destroy (images);
|
||||
}
|
||||
|
||||
/** Load a cursor theme to memory shared with the compositor
|
||||
@@ -373,7 +411,7 @@ wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
|
||||
return theme->cursors[i];
|
||||
}
|
||||
|
||||
load_cursor (theme, name, size);
|
||||
load_cursor (theme, name, theme->size, scale);
|
||||
|
||||
if (i < theme->cursor_count) {
|
||||
if (size == theme->cursors[i]->size &&
|
||||
|
||||
@@ -73,8 +73,9 @@ gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context
|
||||
xdg_activation_token_v1_set_serial (token,
|
||||
_gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL),
|
||||
gdk_wayland_seat_get_wl_seat (GDK_SEAT (seat)));
|
||||
xdg_activation_token_v1_set_surface (token,
|
||||
gdk_wayland_surface_get_wl_surface (focus_surface));
|
||||
if (focus_surface)
|
||||
xdg_activation_token_v1_set_surface (token,
|
||||
gdk_wayland_surface_get_wl_surface (focus_surface));
|
||||
xdg_activation_token_v1_commit (token);
|
||||
|
||||
while (app_launch_data.token == NULL)
|
||||
|
||||
@@ -178,6 +178,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
if (c)
|
||||
{
|
||||
struct wl_cursor_image *image;
|
||||
int cursor_scale;
|
||||
|
||||
if (image_index >= c->image_count)
|
||||
{
|
||||
@@ -189,12 +190,22 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
|
||||
image = c->images[image_index];
|
||||
|
||||
*hotspot_x = image->hotspot_x / desired_scale;
|
||||
*hotspot_y = image->hotspot_y / desired_scale;
|
||||
cursor_scale = desired_scale;
|
||||
if ((image->width % cursor_scale != 0) ||
|
||||
(image->height % cursor_scale != 0))
|
||||
{
|
||||
g_warning (G_STRLOC " cursor image size (%dx%d) not an integer"
|
||||
"multiple of scale (%d)", image->width, image->height,
|
||||
cursor_scale);
|
||||
cursor_scale = 1;
|
||||
}
|
||||
|
||||
*width = image->width / desired_scale;
|
||||
*height = image->height / desired_scale;
|
||||
*scale = desired_scale;
|
||||
*hotspot_x = image->hotspot_x / cursor_scale;
|
||||
*hotspot_y = image->hotspot_y / cursor_scale;
|
||||
|
||||
*width = image->width / cursor_scale;
|
||||
*height = image->height / cursor_scale;
|
||||
*scale = cursor_scale;
|
||||
|
||||
return wl_cursor_image_get_buffer (image);
|
||||
}
|
||||
|
||||
@@ -854,6 +854,10 @@ gdk_wayland_display_notify_startup_complete (GdkDisplay *display,
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
char *free_this = NULL;
|
||||
|
||||
/* Will be signaled with focus activation */
|
||||
if (display_wayland->xdg_activation)
|
||||
return;
|
||||
|
||||
if (startup_id == NULL)
|
||||
{
|
||||
startup_id = free_this = display_wayland->startup_notification_id;
|
||||
|
||||
@@ -113,6 +113,7 @@ struct _GdkWaylandSurface
|
||||
|
||||
PopupState popup_state;
|
||||
|
||||
unsigned int popup_thaw_upon_show : 1;
|
||||
unsigned int initial_configure_received : 1;
|
||||
unsigned int has_uncommitted_ack_configure : 1;
|
||||
unsigned int mapped : 1;
|
||||
@@ -2984,6 +2985,9 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
|
||||
if (GDK_IS_POPUP (surface))
|
||||
{
|
||||
impl->popup_thaw_upon_show = TRUE;
|
||||
gdk_surface_freeze_updates (surface);
|
||||
|
||||
switch (impl->popup_state)
|
||||
{
|
||||
case POPUP_STATE_WAITING_FOR_REPOSITIONED:
|
||||
@@ -3223,6 +3227,12 @@ show_popup (GdkSurface *surface,
|
||||
if (!impl->display_server.wl_surface)
|
||||
gdk_wayland_surface_create_surface (surface);
|
||||
|
||||
if (impl->popup_thaw_upon_show)
|
||||
{
|
||||
impl->popup_thaw_upon_show = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
gdk_wayland_surface_map_popup (surface, width, height, layout);
|
||||
}
|
||||
|
||||
@@ -3453,39 +3463,80 @@ gdk_wayland_surface_destroy (GdkSurface *surface,
|
||||
display->toplevels = g_list_remove (display->toplevels, surface);
|
||||
}
|
||||
|
||||
static void
|
||||
token_done (gpointer data,
|
||||
struct xdg_activation_token_v1 *provider,
|
||||
const char *token)
|
||||
{
|
||||
char **token_out = data;
|
||||
|
||||
*token_out = g_strdup (token);
|
||||
}
|
||||
|
||||
static const struct xdg_activation_token_v1_listener token_listener = {
|
||||
token_done,
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_focus (GdkSurface *surface,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
gchar *startup_id = NULL;
|
||||
|
||||
if (!impl->display_server.gtk_surface)
|
||||
return;
|
||||
startup_id = g_steal_pointer (&display_wayland->startup_notification_id);
|
||||
|
||||
if (timestamp == GDK_CURRENT_TIME)
|
||||
if (display_wayland->xdg_activation)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkWaylandSeat *seat =
|
||||
GDK_WAYLAND_SEAT (gdk_display_get_default_seat (display));
|
||||
|
||||
if (display_wayland->startup_notification_id)
|
||||
/* If the focus request does not have a startup ID associated, get a
|
||||
* new token to activate the window.
|
||||
*/
|
||||
if (!startup_id)
|
||||
{
|
||||
if (display_wayland->xdg_activation)
|
||||
{
|
||||
xdg_activation_v1_activate (display_wayland->xdg_activation,
|
||||
display_wayland->startup_notification_id,
|
||||
impl->display_server.wl_surface);
|
||||
}
|
||||
else if (display_wayland->gtk_shell_version >= 3)
|
||||
{
|
||||
gtk_surface1_request_focus (impl->display_server.gtk_surface,
|
||||
display_wayland->startup_notification_id);
|
||||
}
|
||||
struct xdg_activation_token_v1 *token;
|
||||
struct wl_event_queue *event_queue;
|
||||
|
||||
g_clear_pointer (&display_wayland->startup_notification_id, g_free);
|
||||
event_queue = wl_display_create_queue (display_wayland->wl_display);
|
||||
|
||||
token = xdg_activation_v1_get_activation_token (display_wayland->xdg_activation);
|
||||
wl_proxy_set_queue ((struct wl_proxy *) token, event_queue);
|
||||
|
||||
xdg_activation_token_v1_add_listener (token,
|
||||
&token_listener,
|
||||
&startup_id);
|
||||
xdg_activation_token_v1_set_serial (token,
|
||||
_gdk_wayland_seat_get_last_implicit_grab_serial (seat, NULL),
|
||||
gdk_wayland_seat_get_wl_seat (GDK_SEAT (seat)));
|
||||
xdg_activation_token_v1_set_surface (token,
|
||||
gdk_wayland_surface_get_wl_surface (surface));
|
||||
xdg_activation_token_v1_commit (token);
|
||||
|
||||
while (startup_id == NULL)
|
||||
wl_display_dispatch_queue (display_wayland->wl_display, event_queue);
|
||||
|
||||
xdg_activation_token_v1_destroy (token);
|
||||
wl_event_queue_destroy (event_queue);
|
||||
}
|
||||
|
||||
xdg_activation_v1_activate (display_wayland->xdg_activation,
|
||||
startup_id,
|
||||
impl->display_server.wl_surface);
|
||||
}
|
||||
else
|
||||
gtk_surface1_present (impl->display_server.gtk_surface, timestamp);
|
||||
else if (impl->display_server.gtk_surface)
|
||||
{
|
||||
if (timestamp != GDK_CURRENT_TIME)
|
||||
gtk_surface1_present (impl->display_server.gtk_surface, timestamp);
|
||||
else if (startup_id && display_wayland->gtk_shell_version >= 3)
|
||||
gtk_surface1_request_focus (impl->display_server.gtk_surface,
|
||||
startup_id);
|
||||
}
|
||||
|
||||
g_free (startup_id);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -142,9 +142,13 @@ gdk_win32_clipboard_claim_remote (GdkWin32Clipboard *cb)
|
||||
cb->sequence_number = -1;
|
||||
|
||||
formats = gdk_win32_clipboard_request_contentformats (cb);
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
cb->sequence_number = GetClipboardSequenceNumber ();
|
||||
|
||||
if (formats != NULL)
|
||||
{
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
cb->sequence_number = GetClipboardSequenceNumber ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1219,11 +1219,10 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
SetLastError (0);
|
||||
hwnd_owner = GetClipboardOwner ();
|
||||
|
||||
if ((hwnd_owner == NULL) &&
|
||||
(GetLastError () != ERROR_SUCCESS))
|
||||
WIN32_API_FAILED ("GetClipboardOwner");
|
||||
if (hwnd_owner == NULL && GetLastError () != 0)
|
||||
WIN32_API_FAILED ("GetClipboardOwner");
|
||||
|
||||
hwnd_opener = GetOpenClipboardWindow ();
|
||||
|
||||
|
||||
+55
-68
@@ -873,6 +873,7 @@ _gdk_win32_append_event (GdkEvent *event)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GList *link;
|
||||
gulong serial;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
|
||||
@@ -880,8 +881,9 @@ _gdk_win32_append_event (GdkEvent *event)
|
||||
#if 1
|
||||
link = _gdk_event_queue_append (display, event);
|
||||
GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
|
||||
serial = _gdk_display_get_next_serial (display);
|
||||
/* event morphing, the passed in may not be valid afterwards */
|
||||
_gdk_windowing_got_event (display, link, event, 0);
|
||||
_gdk_windowing_got_event (display, link, event, serial);
|
||||
#else
|
||||
_gdk_event_queue_append (display, event);
|
||||
GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
|
||||
@@ -2242,6 +2244,10 @@ gdk_event_translate (MSG *msg,
|
||||
button = 5;
|
||||
|
||||
buttonup0:
|
||||
{
|
||||
gboolean release_implicit_grab = FALSE;
|
||||
GdkSurface *prev_surface = NULL;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print (" (%d,%d)",
|
||||
GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
|
||||
@@ -2251,41 +2257,18 @@ gdk_event_translate (MSG *msg,
|
||||
g_set_object (&window, find_window_for_mouse_event (window, msg));
|
||||
|
||||
if (pointer_grab != NULL && pointer_grab->implicit)
|
||||
{
|
||||
int state = build_pointer_event_state (msg);
|
||||
{
|
||||
int state = build_pointer_event_state (msg);
|
||||
|
||||
/* We keep the implicit grab until no buttons at all are held down */
|
||||
if ((state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (button - 1))) == 0)
|
||||
{
|
||||
ReleaseCapture ();
|
||||
/* We keep the implicit grab until no buttons at all are held down */
|
||||
if ((state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (button - 1))) == 0)
|
||||
{
|
||||
release_implicit_grab = TRUE;
|
||||
prev_surface = pointer_grab->surface;
|
||||
}
|
||||
}
|
||||
|
||||
new_window = NULL;
|
||||
hwnd = WindowFromPoint (msg->pt);
|
||||
if (hwnd != NULL)
|
||||
{
|
||||
POINT client_pt = msg->pt;
|
||||
|
||||
ScreenToClient (hwnd, &client_pt);
|
||||
GetClientRect (hwnd, &rect);
|
||||
if (PtInRect (&rect, client_pt))
|
||||
new_window = gdk_win32_handle_table_lookup (hwnd);
|
||||
}
|
||||
|
||||
synthesize_crossing_events (display,
|
||||
_gdk_device_manager->system_pointer,
|
||||
pointer_grab->surface, new_window,
|
||||
GDK_CROSSING_UNGRAB,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
mouse_window_ignored_leave = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
generate_button_event (GDK_BUTTON_RELEASE, button,
|
||||
window, msg);
|
||||
generate_button_event (GDK_BUTTON_RELEASE, button, window, msg);
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
@@ -2294,8 +2277,37 @@ gdk_event_translate (MSG *msg,
|
||||
impl->drag_move_resize_context.button == button)
|
||||
gdk_win32_surface_end_move_resize_drag (window);
|
||||
|
||||
if (release_implicit_grab)
|
||||
{
|
||||
ReleaseCapture ();
|
||||
|
||||
new_window = NULL;
|
||||
hwnd = WindowFromPoint (msg->pt);
|
||||
if (hwnd != NULL)
|
||||
{
|
||||
POINT client_pt = msg->pt;
|
||||
|
||||
ScreenToClient (hwnd, &client_pt);
|
||||
GetClientRect (hwnd, &rect);
|
||||
if (PtInRect (&rect, client_pt))
|
||||
new_window = gdk_win32_handle_table_lookup (hwnd);
|
||||
}
|
||||
|
||||
synthesize_crossing_events (display,
|
||||
_gdk_device_manager->system_pointer,
|
||||
prev_surface, new_window,
|
||||
GDK_CROSSING_UNGRAB,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
mouse_window_ignored_leave = NULL;
|
||||
}
|
||||
|
||||
return_val = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
GDK_NOTE (EVENTS,
|
||||
@@ -2320,60 +2332,35 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
pen_touch_input = FALSE;
|
||||
|
||||
new_window = window;
|
||||
g_set_object (&window, find_window_for_mouse_event (window, msg));
|
||||
|
||||
if (pointer_grab != NULL)
|
||||
{
|
||||
POINT pt;
|
||||
pt = msg->pt;
|
||||
|
||||
new_window = NULL;
|
||||
hwnd = WindowFromPoint (pt);
|
||||
if (hwnd != NULL)
|
||||
{
|
||||
POINT client_pt = pt;
|
||||
|
||||
ScreenToClient (hwnd, &client_pt);
|
||||
GetClientRect (hwnd, &rect);
|
||||
if (PtInRect (&rect, client_pt))
|
||||
new_window = gdk_win32_handle_table_lookup (hwnd);
|
||||
}
|
||||
|
||||
if (!pointer_grab->owner_events &&
|
||||
new_window != NULL &&
|
||||
new_window != pointer_grab->surface)
|
||||
new_window = NULL;
|
||||
}
|
||||
|
||||
if (mouse_window != new_window)
|
||||
if (mouse_window != window)
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_print (" mouse_window %p -> %p",
|
||||
mouse_window ? GDK_SURFACE_HWND (mouse_window) : NULL,
|
||||
new_window ? GDK_SURFACE_HWND (new_window) : NULL));
|
||||
window ? GDK_SURFACE_HWND (window) : NULL));
|
||||
synthesize_crossing_events (display,
|
||||
_gdk_device_manager->system_pointer,
|
||||
mouse_window, new_window,
|
||||
mouse_window, window,
|
||||
GDK_CROSSING_NORMAL,
|
||||
&msg->pt,
|
||||
0, /* TODO: Set right mask */
|
||||
_gdk_win32_get_next_tick (msg->time),
|
||||
FALSE);
|
||||
g_set_object (&mouse_window, new_window);
|
||||
g_set_object (&mouse_window, window);
|
||||
mouse_window_ignored_leave = NULL;
|
||||
if (new_window != NULL)
|
||||
track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (new_window));
|
||||
if (window != NULL)
|
||||
track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (window));
|
||||
}
|
||||
else if (new_window != NULL &&
|
||||
new_window == mouse_window_ignored_leave)
|
||||
else if (window != NULL && window == mouse_window_ignored_leave)
|
||||
{
|
||||
/* If we ignored a leave event for this window and we're now getting
|
||||
input again we need to re-arm the mouse tracking, as that was
|
||||
cancelled by the mouseleave. */
|
||||
mouse_window_ignored_leave = NULL;
|
||||
track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (new_window));
|
||||
track_mouse_event (TME_LEAVE, GDK_SURFACE_HWND (window));
|
||||
}
|
||||
|
||||
g_set_object (&window, find_window_for_mouse_event (window, msg));
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
/* If we haven't moved, don't create any GDK event. Windows
|
||||
|
||||
+25
-24
@@ -229,14 +229,9 @@ fail1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the file path of the keyboard layout dll.
|
||||
* The result is heap-allocated and should be freed with g_free().
|
||||
*/
|
||||
static char*
|
||||
get_keyboard_layout_file (const char *layout_name)
|
||||
_get_keyboard_layout_file (const char *layout_name)
|
||||
{
|
||||
char *final_layout_name = NULL;
|
||||
HKEY hkey = 0;
|
||||
DWORD var_type = REG_SZ;
|
||||
char *result = NULL;
|
||||
@@ -249,24 +244,8 @@ get_keyboard_layout_file (const char *layout_name)
|
||||
"Keyboard Layouts\\";
|
||||
char kbdKeyPath[sizeof (prefix) + KL_NAMELENGTH];
|
||||
|
||||
/* The user may have a keyboard substitute configured */
|
||||
final_layout_name = get_keyboard_layout_substituted_name (layout_name);
|
||||
if (final_layout_name != NULL)
|
||||
{
|
||||
g_debug ("Substituting keyboard layout name from '%s' to '%s'",
|
||||
layout_name, final_layout_name);
|
||||
g_snprintf (kbdKeyPath, sizeof (prefix) + KL_NAMELENGTH, "%s%s",
|
||||
prefix, final_layout_name);
|
||||
g_free (final_layout_name);
|
||||
final_layout_name = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Could not get substitute keyboard layout name for '%s', "
|
||||
"will use '%s' directly", layout_name, layout_name);
|
||||
g_snprintf (kbdKeyPath, sizeof (prefix) + KL_NAMELENGTH, "%s%s",
|
||||
prefix, layout_name);
|
||||
}
|
||||
g_snprintf (kbdKeyPath, sizeof (prefix) + KL_NAMELENGTH, "%s%s",
|
||||
prefix, layout_name);
|
||||
|
||||
status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, (LPCSTR) kbdKeyPath, 0,
|
||||
KEY_QUERY_VALUE, &hkey);
|
||||
@@ -326,6 +305,28 @@ fail1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the file path of the keyboard layout dll.
|
||||
* The result is heap-allocated and should be freed with g_free().
|
||||
*/
|
||||
static char*
|
||||
get_keyboard_layout_file (const char *layout_name)
|
||||
{
|
||||
char *result = _get_keyboard_layout_file (layout_name);
|
||||
|
||||
/* If we could not retrieve a path, it may be that we need to perform layout
|
||||
* substitution
|
||||
*/
|
||||
if (result == NULL)
|
||||
{
|
||||
char *substituted = get_keyboard_layout_substituted_name (layout_name);
|
||||
result = _get_keyboard_layout_file (substituted);
|
||||
g_free (substituted);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_keyboard_layout_info (gpointer data)
|
||||
{
|
||||
|
||||
@@ -4152,6 +4152,9 @@ gdk_win32_surface_fullscreen (GdkSurface *window)
|
||||
g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
|
||||
fi->style = GetWindowLong (GDK_SURFACE_HWND (window), GWL_STYLE);
|
||||
|
||||
impl->inhibit_configure = TRUE;
|
||||
impl->force_recompute_size = FALSE;
|
||||
|
||||
/* Send state change before configure event */
|
||||
gdk_synthesize_surface_state (window, 0, GDK_TOPLEVEL_STATE_FULLSCREEN);
|
||||
|
||||
@@ -4160,7 +4163,7 @@ gdk_win32_surface_fullscreen (GdkSurface *window)
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window), HWND_TOP,
|
||||
x, y, width, height,
|
||||
SWP_NOCOPYBITS | SWP_SHOWWINDOW));
|
||||
SWP_NOCOPYBITS | SWP_SHOWWINDOW | SWP_FRAMECHANGED));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4184,11 +4187,17 @@ gdk_win32_surface_unfullscreen (GdkSurface *window)
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window), HWND_NOTOPMOST,
|
||||
fi->r.left, fi->r.top,
|
||||
fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
|
||||
SWP_NOCOPYBITS | SWP_SHOWWINDOW));
|
||||
SWP_NOCOPYBITS | SWP_SHOWWINDOW | SWP_FRAMECHANGED));
|
||||
|
||||
g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
|
||||
g_free (fi);
|
||||
_gdk_win32_surface_update_style_bits (window);
|
||||
|
||||
if (impl->inhibit_configure)
|
||||
{
|
||||
impl->inhibit_configure = FALSE;
|
||||
impl->force_recompute_size = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -248,6 +248,10 @@ gdk_x11_clipboard_formats_from_atoms (GdkDisplay *display,
|
||||
const char *name;
|
||||
|
||||
name = gdk_x11_get_xatom_name_for_display (display , atoms[i]);
|
||||
if (!name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (strchr (name, '/'))
|
||||
{
|
||||
gdk_content_formats_builder_add_mime_type (builder, name);
|
||||
|
||||
@@ -280,7 +280,7 @@ compute_toplevel_size (GdkSurface *surface,
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
|
||||
|
||||
if (size.shadow.is_valid && update_geometry)
|
||||
if (size.shadow.is_valid)
|
||||
{
|
||||
update_shadow_size (surface,
|
||||
size.shadow.left,
|
||||
|
||||
@@ -831,7 +831,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
* to upload data, map to a framebuffer, or other uses which may
|
||||
* modify the texture immediately.
|
||||
*
|
||||
* Typical examples for @format are GK_RGBA8, GL_RGBA16F or GL_RGBA32F.
|
||||
* Typical examples for @format are GL_RGBA8, GL_RGBA16F or GL_RGBA32F.
|
||||
*
|
||||
* Use gsk_gl_driver_release_texture() to release this texture back into
|
||||
* the pool so it may be reused later in the pipeline.
|
||||
|
||||
+57
-3
@@ -24,6 +24,7 @@
|
||||
#include <gdk/gdkdisplayprivate.h>
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdksurfaceprivate.h>
|
||||
#include <gdk/gdkintl.h>
|
||||
#include <gsk/gskdebugprivate.h>
|
||||
#include <gsk/gskrendererprivate.h>
|
||||
#include <gsk/gskrendernodeprivate.h>
|
||||
@@ -93,6 +94,7 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
GdkDisplay *display;
|
||||
gboolean ret = FALSE;
|
||||
gboolean debug_shaders = FALSE;
|
||||
GdkGLAPI api;
|
||||
|
||||
if (self->context != NULL)
|
||||
return TRUE;
|
||||
@@ -115,6 +117,24 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
if (!context || !gdk_gl_context_realize (context, error))
|
||||
goto failure;
|
||||
|
||||
api = gdk_gl_context_get_api (context);
|
||||
if (api == GDK_GL_API_GLES)
|
||||
{
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
if (!gdk_gl_context_has_vertex_half_float (context))
|
||||
{
|
||||
int major, minor;
|
||||
|
||||
gdk_gl_context_get_version (context, &major, &minor);
|
||||
g_set_error (error,
|
||||
GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("This GLES %d.%d implementation does not support half-float vertex data"),
|
||||
major, minor);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SHADERS))
|
||||
debug_shaders = TRUE;
|
||||
@@ -306,10 +326,9 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
GskGLRenderer *self = (GskGLRenderer *)renderer;
|
||||
GskGLRenderTarget *render_target;
|
||||
GskGLRenderJob *job;
|
||||
GdkTexture *texture = NULL;
|
||||
GdkTexture *texture;
|
||||
guint texture_id;
|
||||
int width;
|
||||
int height;
|
||||
int width, height, max_size;
|
||||
int format;
|
||||
|
||||
g_assert (GSK_IS_GL_RENDERER (renderer));
|
||||
@@ -317,6 +336,37 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
width = ceilf (viewport->size.width);
|
||||
height = ceilf (viewport->size.height);
|
||||
max_size = self->command_queue->max_texture_size;
|
||||
if (width > max_size || height > max_size)
|
||||
{
|
||||
gsize x, y, size, stride;
|
||||
GBytes *bytes;
|
||||
guchar *data;
|
||||
|
||||
stride = width * 4;
|
||||
size = stride * height;
|
||||
data = g_malloc_n (stride, height);
|
||||
|
||||
for (y = 0; y < height; y += max_size)
|
||||
{
|
||||
for (x = 0; x < width; x += max_size)
|
||||
{
|
||||
texture = gsk_gl_renderer_render_texture (renderer, root,
|
||||
&GRAPHENE_RECT_INIT (x, y,
|
||||
MIN (max_size, viewport->size.width - x),
|
||||
MIN (max_size, viewport->size.height - y)));
|
||||
gdk_texture_download (texture,
|
||||
data + stride * y + x * 4,
|
||||
stride);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
}
|
||||
|
||||
bytes = g_bytes_new_take (data, size);
|
||||
texture = gdk_memory_texture_new (width, height, GDK_MEMORY_DEFAULT, bytes, stride);
|
||||
g_bytes_unref (bytes);
|
||||
return texture;
|
||||
}
|
||||
|
||||
format = gsk_render_node_prefers_high_depth (root) ? GL_RGBA32F : GL_RGBA8;
|
||||
|
||||
@@ -342,6 +392,10 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
gsk_gl_driver_after_frame (self->driver);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return g_steal_pointer (&texture);
|
||||
}
|
||||
|
||||
+89
-51
@@ -3869,7 +3869,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
|
||||
filter = offscreen->linear_filter ? GL_LINEAR : GL_NEAREST;
|
||||
|
||||
/* Check if we've already cached the drawn texture. */
|
||||
key.pointer = node;
|
||||
key.pointer_is_child = TRUE; /* Don't conflict with the child using the cache too */
|
||||
key.parent_rect = *offscreen->bounds;
|
||||
@@ -3877,61 +3876,111 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
key.scale_y = job->scale_y;
|
||||
key.filter = filter;
|
||||
|
||||
cached_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||
float offset_x = job->offset_x;
|
||||
float offset_y = job->offset_y;
|
||||
gboolean flipped_x = job->scale_x < 0;
|
||||
gboolean flipped_y = job->scale_y < 0;
|
||||
graphene_rect_t viewport;
|
||||
|
||||
if (cached_id != 0)
|
||||
if (flipped_x || flipped_y)
|
||||
{
|
||||
offscreen->texture_id = cached_id;
|
||||
init_full_texture_region (offscreen);
|
||||
/* We didn't render it offscreen, but hand out an offscreen texture id */
|
||||
offscreen->was_offscreen = TRUE;
|
||||
return TRUE;
|
||||
GskTransform *transform = gsk_transform_scale (NULL,
|
||||
flipped_x ? -1 : 1,
|
||||
flipped_y ? -1 : 1);
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
}
|
||||
|
||||
float scaled_width;
|
||||
float scaled_height;
|
||||
float downscale_x = 1;
|
||||
float downscale_y = 1;
|
||||
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
|
||||
|
||||
g_assert (job->command_queue->max_texture_size > 0);
|
||||
float aligned_x = floorf (viewport.origin.x);
|
||||
float padding_left = viewport.origin.x - aligned_x;
|
||||
float aligned_width = ceilf (viewport.size.width + padding_left);
|
||||
float padding_right = aligned_width - viewport.size.width - padding_left;
|
||||
|
||||
float aligned_y = floorf (viewport.origin.y);
|
||||
float padding_top = viewport.origin.y - aligned_y;
|
||||
float aligned_height = ceilf (viewport.size.height + padding_top);
|
||||
float padding_bottom = aligned_height - viewport.size.height - padding_top;
|
||||
|
||||
/* Tweak the scale factor so that the required texture doesn't
|
||||
* exceed the max texture limit. This will render with a lower
|
||||
* resolution, but this is better than clipping.
|
||||
*/
|
||||
{
|
||||
int max_texture_size = job->command_queue->max_texture_size;
|
||||
|
||||
scaled_width = ceilf (offscreen->bounds->size.width * fabs (job->scale_x));
|
||||
if (scaled_width > max_texture_size)
|
||||
{
|
||||
downscale_x = (float)max_texture_size / scaled_width;
|
||||
scaled_width = max_texture_size;
|
||||
}
|
||||
if (job->scale_x < 0)
|
||||
downscale_x = -downscale_x;
|
||||
g_assert (job->command_queue->max_texture_size > 0);
|
||||
|
||||
scaled_height = ceilf (offscreen->bounds->size.height * fabs (job->scale_y));
|
||||
if (scaled_height > max_texture_size)
|
||||
{
|
||||
downscale_y = (float)max_texture_size / scaled_height;
|
||||
scaled_height = max_texture_size;
|
||||
}
|
||||
if (job->scale_y < 0)
|
||||
downscale_y = -downscale_y;
|
||||
}
|
||||
float downscale_x = 1;
|
||||
float downscale_y = 1;
|
||||
int texture_width;
|
||||
int texture_height;
|
||||
int max_texture_size = job->command_queue->max_texture_size;
|
||||
|
||||
if (aligned_width > max_texture_size)
|
||||
downscale_x = (float)max_texture_size / viewport.size.width;
|
||||
|
||||
if (aligned_height > max_texture_size)
|
||||
downscale_y = (float)max_texture_size / viewport.size.height;
|
||||
|
||||
if (downscale_x != 1 || downscale_y != 1)
|
||||
{
|
||||
GskTransform *transform = gsk_transform_scale (NULL, downscale_x, downscale_y);
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
|
||||
}
|
||||
|
||||
if (downscale_x == 1)
|
||||
{
|
||||
viewport.origin.x = aligned_x;
|
||||
viewport.size.width = aligned_width;
|
||||
offscreen->area.x = padding_left / aligned_width;
|
||||
offscreen->area.x2 = 1.0f - (padding_right / aligned_width);
|
||||
texture_width = aligned_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
offscreen->area.x = 0;
|
||||
offscreen->area.x2 = 1;
|
||||
texture_width = max_texture_size;
|
||||
}
|
||||
|
||||
if (downscale_y == 1)
|
||||
{
|
||||
viewport.origin.y = aligned_y;
|
||||
viewport.size.height = aligned_height;
|
||||
offscreen->area.y = padding_bottom / aligned_height;
|
||||
offscreen->area.y2 = 1.0f - padding_top / aligned_height;
|
||||
texture_height = aligned_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
offscreen->area.y = 0;
|
||||
offscreen->area.y2 = 1;
|
||||
texture_height = max_texture_size;
|
||||
}
|
||||
|
||||
/* Check if we've already cached the drawn texture. */
|
||||
cached_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||
|
||||
if (cached_id != 0)
|
||||
{
|
||||
if (downscale_x != 1 || downscale_y != 1)
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
if (flipped_x || flipped_y)
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
offscreen->texture_id = cached_id;
|
||||
/* We didn't render it offscreen, but hand out an offscreen texture id */
|
||||
offscreen->was_offscreen = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GskGLRenderTarget *render_target;
|
||||
graphene_matrix_t prev_projection;
|
||||
graphene_rect_t prev_viewport;
|
||||
graphene_rect_t viewport;
|
||||
float offset_x = job->offset_x;
|
||||
float offset_y = job->offset_y;
|
||||
float prev_alpha;
|
||||
guint prev_fbo;
|
||||
|
||||
if (!gsk_gl_driver_create_render_target (job->driver,
|
||||
scaled_width, scaled_height,
|
||||
texture_width, texture_height,
|
||||
get_target_format (job, node),
|
||||
filter, filter,
|
||||
&render_target))
|
||||
@@ -3953,19 +4002,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
render_target->framebuffer_id);
|
||||
}
|
||||
|
||||
if (downscale_x != 1 || downscale_y != 1)
|
||||
{
|
||||
GskTransform *transform = gsk_transform_scale (NULL, downscale_x, downscale_y);
|
||||
gsk_gl_render_job_push_modelview (job, transform);
|
||||
gsk_transform_unref (transform);
|
||||
}
|
||||
|
||||
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
|
||||
/* Code above will scale the size with the scale we use in the render ops,
|
||||
* but for the viewport size, we need our own size limited by the texture size */
|
||||
viewport.size.width = scaled_width;
|
||||
viewport.size.height = scaled_height;
|
||||
|
||||
gsk_gl_render_job_set_viewport (job, &viewport, &prev_viewport);
|
||||
gsk_gl_render_job_set_projection_from_rect (job, &job->viewport, &prev_projection);
|
||||
prev_alpha = gsk_gl_render_job_set_alpha (job, 1.0f);
|
||||
@@ -3983,6 +4019,10 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
|
||||
if (downscale_x != 1 || downscale_y != 1)
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
if (flipped_x || flipped_y)
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
|
||||
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
|
||||
gsk_gl_render_job_set_projection (job, &prev_projection);
|
||||
gsk_gl_render_job_set_alpha (job, prev_alpha);
|
||||
@@ -3996,8 +4036,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
render_target,
|
||||
FALSE);
|
||||
|
||||
init_full_texture_region (offscreen);
|
||||
|
||||
if (!offscreen->do_not_cache)
|
||||
gsk_gl_driver_cache_texture (job->driver, &key, offscreen->texture_id);
|
||||
|
||||
|
||||
+37
-1
@@ -107,8 +107,44 @@ gsk_cairo_renderer_render_texture (GskRenderer *renderer,
|
||||
GdkTexture *texture;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
int width, height;
|
||||
/* limit from cairo's source code */
|
||||
#define MAX_IMAGE_SIZE 32767
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ceil (viewport->size.width), ceil (viewport->size.height));
|
||||
width = ceil (viewport->size.width);
|
||||
height = ceil (viewport->size.height);
|
||||
if (width > MAX_IMAGE_SIZE || height > MAX_IMAGE_SIZE)
|
||||
{
|
||||
gsize x, y, size, stride;
|
||||
GBytes *bytes;
|
||||
guchar *data;
|
||||
|
||||
stride = width * 4;
|
||||
size = stride * height;
|
||||
data = g_malloc_n (stride, height);
|
||||
|
||||
for (y = 0; y < height; y += MAX_IMAGE_SIZE)
|
||||
{
|
||||
for (x = 0; x < width; x += MAX_IMAGE_SIZE)
|
||||
{
|
||||
texture = gsk_cairo_renderer_render_texture (renderer, root,
|
||||
&GRAPHENE_RECT_INIT (x, y,
|
||||
MIN (MAX_IMAGE_SIZE, viewport->size.width - x),
|
||||
MIN (MAX_IMAGE_SIZE, viewport->size.height - y)));
|
||||
gdk_texture_download (texture,
|
||||
data + stride * y + x * 4,
|
||||
stride);
|
||||
g_object_unref (texture);
|
||||
}
|
||||
}
|
||||
|
||||
bytes = g_bytes_new_take (data, size);
|
||||
texture = gdk_memory_texture_new (width, height, GDK_MEMORY_DEFAULT, bytes, stride);
|
||||
g_bytes_unref (bytes);
|
||||
return texture;
|
||||
}
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
cairo_translate (cr, - viewport->origin.x, - viewport->origin.y);
|
||||
|
||||
@@ -5130,10 +5130,10 @@ gsk_gl_shader_node_diff (GskRenderNode *node1,
|
||||
* @shader: the `GskGLShader`
|
||||
* @bounds: the rectangle to render the shader into
|
||||
* @args: Arguments for the uniforms
|
||||
* @children: (array length=n_children): array of child nodes, these will
|
||||
* be rendered to textures and used as input.
|
||||
* @children: (nullable) (array length=n_children): array of child nodes,
|
||||
* these will be rendered to textures and used as input.
|
||||
* @n_children: Length of @children (currenly the GL backend supports
|
||||
* up to 4 children)
|
||||
* up to 4 children)
|
||||
*
|
||||
* Creates a `GskRenderNode` that will render the given @shader into the
|
||||
* area given by @bounds.
|
||||
@@ -5167,10 +5167,10 @@ gsk_gl_shader_node_new (GskGLShader *shader,
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_SHADER (shader), NULL);
|
||||
g_return_val_if_fail (bounds != NULL, NULL);
|
||||
g_return_val_if_fail ((args == NULL && gsk_gl_shader_get_n_uniforms (shader) == 0) ||
|
||||
(args != NULL && g_bytes_get_size (args) == gsk_gl_shader_get_args_size (shader)), NULL);
|
||||
g_return_val_if_fail (args != NULL, NULL);
|
||||
g_return_val_if_fail (g_bytes_get_size (args) == gsk_gl_shader_get_args_size (shader), NULL);
|
||||
g_return_val_if_fail ((children == NULL && n_children == 0) ||
|
||||
(children != NULL && n_children == gsk_gl_shader_get_n_textures (shader)), NULL);
|
||||
(n_children == gsk_gl_shader_get_n_textures (shader)), NULL);
|
||||
|
||||
self = gsk_render_node_alloc (GSK_GL_SHADER_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
|
||||
+24
-14
@@ -436,7 +436,11 @@ get_parent_context_ref (GtkAccessible *accessible)
|
||||
gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent));
|
||||
|
||||
if (parent_context != NULL)
|
||||
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
|
||||
{
|
||||
gtk_at_context_realize (parent_context);
|
||||
|
||||
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
|
||||
}
|
||||
}
|
||||
|
||||
if (res == NULL)
|
||||
@@ -1418,7 +1422,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,6 +1447,22 @@ 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)
|
||||
{
|
||||
@@ -1489,11 +1509,10 @@ 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”",
|
||||
@@ -1504,16 +1523,7 @@ gtk_at_spi_context_realize (GtkATContext *context)
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
gtk_at_spi_root_queue_register (self->root, self, register_object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+35
-11
@@ -474,16 +474,24 @@ 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)
|
||||
{
|
||||
GtkAtSpiRoot *self = user_data;
|
||||
RegistrationData *data = user_data;
|
||||
GtkAtSpiRoot *self = data->root;
|
||||
|
||||
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);
|
||||
@@ -509,19 +517,27 @@ 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 = self->queued_contexts; l != NULL; l = l->next)
|
||||
gtk_at_spi_cache_add_context (self->cache, l->data);
|
||||
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);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->queued_contexts, g_list_free);
|
||||
}
|
||||
|
||||
self->toplevels = gtk_window_get_toplevels ();
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
root_register (gpointer data)
|
||||
root_register (gpointer user_data)
|
||||
{
|
||||
GtkAtSpiRoot *self = data;
|
||||
RegistrationData *data = user_data;
|
||||
GtkAtSpiRoot *self = data->root;
|
||||
const char *unique_name;
|
||||
|
||||
/* Register the root element; every application has a single root, so we only
|
||||
@@ -577,9 +593,7 @@ root_register (gpointer data)
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
NULL,
|
||||
on_registration_reply,
|
||||
self);
|
||||
|
||||
self->register_id = 0;
|
||||
data);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -587,18 +601,24 @@ root_register (gpointer 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)
|
||||
gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
|
||||
GtkAtSpiContext *context,
|
||||
GtkAtSpiRootRegisterFunc func)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
@@ -612,7 +632,11 @@ gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
|
||||
if (self->register_id != 0)
|
||||
return;
|
||||
|
||||
self->register_id = g_idle_add (root_register, self);
|
||||
RegistrationData *data = g_new (RegistrationData, 1);
|
||||
data->root = self;
|
||||
data->register_func = func;
|
||||
|
||||
self->register_id = g_idle_add (root_register, data);
|
||||
gdk_source_set_static_name_by_id (self->register_id, "[gtk] ATSPI root registration");
|
||||
}
|
||||
|
||||
|
||||
@@ -34,9 +34,13 @@ 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);
|
||||
GtkAtSpiContext *context,
|
||||
GtkAtSpiRootRegisterFunc func);
|
||||
|
||||
void
|
||||
gtk_at_spi_root_unregister (GtkAtSpiRoot *self,
|
||||
|
||||
+1
-1
@@ -425,7 +425,7 @@ gtk_accessible_reset_property (GtkAccessible *self,
|
||||
* gtk_accessible_update_relation (accessible,
|
||||
* GTK_ACCESSIBLE_RELATION_CONTROLS,
|
||||
* ref1, NULL,
|
||||
* GTK_ACCESSIBLE_LABELLED_BY,
|
||||
* GTK_ACCESSIBLE_RELATION_LABELLED_BY,
|
||||
* ref1, ref2, ref3, NULL,
|
||||
* -1);
|
||||
* ```
|
||||
|
||||
@@ -991,13 +991,15 @@ gtk_action_muxer_unregister_observer (GtkActionObservable *observable,
|
||||
GtkActionObserver *observer)
|
||||
{
|
||||
GtkActionMuxer *muxer = GTK_ACTION_MUXER (observable);
|
||||
Action *action;
|
||||
Action *action = find_observers (muxer, name);
|
||||
|
||||
action = find_observers (muxer, name);
|
||||
if (action)
|
||||
{
|
||||
g_object_weak_unref (G_OBJECT (observer), gtk_action_muxer_weak_notify, action);
|
||||
gtk_action_muxer_unregister_internal (action, observer);
|
||||
if (g_slist_find (action->watchers, observer) != NULL)
|
||||
{
|
||||
g_object_weak_unref (G_OBJECT (observer), gtk_action_muxer_weak_notify, action);
|
||||
gtk_action_muxer_unregister_internal (action, observer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1269,7 +1271,7 @@ gtk_action_muxer_insert (GtkActionMuxer *muxer,
|
||||
if (!muxer->groups)
|
||||
muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gtk_action_muxer_free_group);
|
||||
|
||||
group = g_slice_new (Group);
|
||||
group = g_slice_new0 (Group);
|
||||
group->muxer = muxer;
|
||||
group->group = g_object_ref (action_group);
|
||||
group->prefix = g_strdup (prefix);
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
*
|
||||
* `GtkApplication` will automatically load menus from the `GtkBuilder`
|
||||
* resource located at "gtk/menus.ui", relative to the application's
|
||||
* resource base path (see `g_application_set_resource_base_path()`).
|
||||
* resource base path (see [method@Gio.Application.set_resource_base_path]).
|
||||
* The menu with the ID "menubar" is taken as the application's
|
||||
* menubar. Additional menus (most interesting submenus) can be named
|
||||
* and accessed via [method@Gtk.Application.get_menu_by_id] which allows for
|
||||
@@ -83,8 +83,8 @@
|
||||
* resources. See [method@Gtk.IconTheme.add_resource_path] for more
|
||||
* information.
|
||||
*
|
||||
* If there is a resource located at "gtk/help-overlay.ui" which
|
||||
* defines a [class@Gtk.ShortcutsWindow] with ID "help_overlay" then
|
||||
* If there is a resource located at `gtk/help-overlay.ui` which
|
||||
* defines a [class@Gtk.ShortcutsWindow] with ID `help_overlay` then
|
||||
* `GtkApplication` associates an instance of this shortcuts window with
|
||||
* each [class@Gtk.ApplicationWindow] and sets up the keyboard accelerator
|
||||
* <kbd>Control</kbd>+<kbd>?</kbd> to open it. To create a menu item that
|
||||
|
||||
+41
-2
@@ -288,6 +288,12 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
|
||||
*natural = largest_nat;
|
||||
}
|
||||
|
||||
/* if widgets haven't reached their min opposite size at this
|
||||
* huge value, things went massively wrong and we need to bail to not
|
||||
* cause an infinite loop.
|
||||
*/
|
||||
#define MAX_ALLOWED_SIZE (1 << 20)
|
||||
|
||||
static int
|
||||
distribute_remaining_size (GtkRequestedSize *sizes,
|
||||
gsize n_sizes,
|
||||
@@ -321,7 +327,40 @@ distribute_remaining_size (GtkRequestedSize *sizes,
|
||||
{
|
||||
int test;
|
||||
|
||||
if (max == G_MAXINT)
|
||||
if (min > MAX_ALLOWED_SIZE)
|
||||
{
|
||||
/* sanity check! */
|
||||
for (i = 0; i < n_sizes; i++)
|
||||
{
|
||||
int check_min, check_nat;
|
||||
gtk_widget_measure (sizes[i].data,
|
||||
orientation,
|
||||
MAX_ALLOWED_SIZE,
|
||||
&sizes[i].minimum_size, &sizes[i].natural_size,
|
||||
NULL, NULL);
|
||||
gtk_widget_measure (sizes[i].data,
|
||||
orientation,
|
||||
-1,
|
||||
&check_min, &check_nat,
|
||||
NULL, NULL);
|
||||
if (check_min < sizes[i].minimum_size)
|
||||
{
|
||||
g_critical ("%s %p reports a minimum %s of %u, but minimum %s for %s of %u is %u. Expect overlapping widgets.",
|
||||
G_OBJECT_TYPE_NAME (sizes[i].data), sizes[i].data,
|
||||
orientation == GTK_ORIENTATION_HORIZONTAL ? "width" : "height",
|
||||
check_min,
|
||||
orientation == GTK_ORIENTATION_HORIZONTAL ? "width" : "height",
|
||||
orientation == GTK_ORIENTATION_HORIZONTAL ? "height" : "width",
|
||||
MAX_ALLOWED_SIZE, sizes[i].minimum_size);
|
||||
sizes[i].minimum_size = check_min;
|
||||
sizes[i].natural_size = check_nat;
|
||||
}
|
||||
total_size += sizes[i].minimum_size;
|
||||
}
|
||||
return MAX (0, available - total_size);
|
||||
}
|
||||
|
||||
if (max == MAX_ALLOWED_SIZE)
|
||||
test = min * 2;
|
||||
else
|
||||
test = (min + max) / 2;
|
||||
@@ -465,7 +504,7 @@ gtk_box_layout_compute_opposite_size_for_size (GtkBoxLayout *self,
|
||||
self->orientation,
|
||||
available,
|
||||
min_size,
|
||||
G_MAXINT);
|
||||
MAX_ALLOWED_SIZE);
|
||||
|
||||
/* Bring children up to size first */
|
||||
available = gtk_distribute_natural_allocation (available, nvis_children, sizes);
|
||||
|
||||
+8
-8
@@ -239,7 +239,7 @@ gtk_css_node_dispose (GObject *object)
|
||||
}
|
||||
|
||||
gtk_css_node_set_invalid (cssnode, FALSE);
|
||||
|
||||
|
||||
g_clear_pointer (&cssnode->cache, gtk_css_node_style_cache_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_node_parent_class)->dispose (object);
|
||||
@@ -292,7 +292,7 @@ may_use_global_parent_cache (GtkCssNode *node)
|
||||
{
|
||||
GtkStyleProvider *provider;
|
||||
GtkCssNode *parent;
|
||||
|
||||
|
||||
parent = gtk_css_node_get_parent (node);
|
||||
if (parent == NULL)
|
||||
return FALSE;
|
||||
@@ -700,10 +700,10 @@ gtk_css_node_invalidate_style (GtkCssNode *cssnode)
|
||||
|
||||
cssnode->style_is_invalid = TRUE;
|
||||
gtk_css_node_set_invalid (cssnode, TRUE);
|
||||
|
||||
|
||||
if (cssnode->first_child)
|
||||
gtk_css_node_invalidate_style (cssnode->first_child);
|
||||
|
||||
|
||||
if (cssnode->next_sibling)
|
||||
gtk_css_node_invalidate_style (cssnode->next_sibling);
|
||||
}
|
||||
@@ -796,7 +796,7 @@ gtk_css_node_reposition (GtkCssNode *node,
|
||||
gtk_css_node_invalidate_style (node->next_sibling);
|
||||
}
|
||||
|
||||
gtk_css_node_invalidate (node, GTK_CSS_CHANGE_ANY_PARENT
|
||||
gtk_css_node_invalidate (node, (old_parent != new_parent ? GTK_CSS_CHANGE_ANY_PARENT : 0)
|
||||
| GTK_CSS_CHANGE_ANY_SIBLING
|
||||
| GTK_CSS_CHANGE_NTH_CHILD
|
||||
| (node->previous_sibling ? 0 : GTK_CSS_CHANGE_FIRST_CHILD)
|
||||
@@ -842,7 +842,7 @@ gtk_css_node_insert_before (GtkCssNode *parent,
|
||||
g_return_if_fail (next_sibling == NULL || next_sibling->parent == parent);
|
||||
g_return_if_fail (cssnode != next_sibling);
|
||||
|
||||
if (cssnode->next_sibling == next_sibling &&
|
||||
if (cssnode->next_sibling == next_sibling &&
|
||||
cssnode->parent == parent)
|
||||
return;
|
||||
|
||||
@@ -1067,7 +1067,7 @@ gtk_css_node_set_visible (GtkCssNode *cssnode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cssnode->previous_sibling)
|
||||
{
|
||||
if (gtk_css_node_is_last_child (cssnode))
|
||||
@@ -1424,7 +1424,7 @@ gtk_css_node_print (GtkCssNode *cssnode,
|
||||
|
||||
change = gtk_css_static_style_get_change (gtk_css_style_get_static_style (style));
|
||||
g_string_append (string, " ");
|
||||
gtk_css_change_print (change, string);
|
||||
gtk_css_change_print (change, string);
|
||||
}
|
||||
|
||||
g_string_append_c (string, '\n');
|
||||
|
||||
+10
-3
@@ -69,11 +69,18 @@ gtk_css_calc_value_new_from_array (GtkCssValue **values,
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_css_value_number_free (GtkCssValue *value)
|
||||
gtk_css_value_number_free (GtkCssValue *number)
|
||||
{
|
||||
g_slice_free (GtkCssValue, value);
|
||||
if (number->type == TYPE_CALC)
|
||||
{
|
||||
const guint n_terms = number->calc.n_terms;
|
||||
|
||||
for (guint i = 0; i < n_terms; i++)
|
||||
_gtk_css_value_unref (number->calc.terms[i]);
|
||||
}
|
||||
|
||||
g_slice_free (GtkCssValue, number);
|
||||
}
|
||||
|
||||
static double
|
||||
|
||||
@@ -149,7 +149,8 @@ gtk_event_controller_focus_handle_crossing (GtkEventController *controller,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
if (crossing->type == GTK_CROSSING_FOCUS)
|
||||
if (crossing->type == GTK_CROSSING_FOCUS ||
|
||||
crossing->type == GTK_CROSSING_ACTIVE)
|
||||
update_focus (controller, crossing);
|
||||
}
|
||||
|
||||
|
||||
@@ -238,28 +238,26 @@ gtk_event_controller_scroll_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
gtk_event_controller_scroll_begin (GtkEventController *controller)
|
||||
{
|
||||
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
|
||||
|
||||
if (scroll->active)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
g_signal_emit (controller, signals[SCROLL_BEGIN], 0);
|
||||
scroll_history_reset (scroll);
|
||||
scroll->active = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
gtk_event_controller_scroll_end (GtkEventController *controller)
|
||||
{
|
||||
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
|
||||
|
||||
if (!scroll->active)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
g_signal_emit (controller, signals[SCROLL_END], 0);
|
||||
scroll->active = FALSE;
|
||||
@@ -271,8 +269,6 @@ gtk_event_controller_scroll_end (GtkEventController *controller)
|
||||
scroll_history_finish (scroll, &vel_x, &vel_y);
|
||||
g_signal_emit (controller, signals[DECELERATE], 0, vel_x, vel_y);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -295,30 +291,29 @@ gtk_event_controller_scroll_handle_hold_event (GtkEventController *controller,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
|
||||
gboolean handled = GDK_EVENT_PROPAGATE;
|
||||
GdkTouchpadGesturePhase phase;
|
||||
guint n_fingers = 0;
|
||||
|
||||
if (gdk_event_get_event_type (event) != GDK_TOUCHPAD_HOLD)
|
||||
return handled;
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
|
||||
n_fingers = gdk_touchpad_event_get_n_fingers (event);
|
||||
if (n_fingers != 1 && n_fingers != 2)
|
||||
return handled;
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
|
||||
if (scroll->hold_timeout_id != 0)
|
||||
return handled;
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
|
||||
phase = gdk_touchpad_event_get_gesture_phase (event);
|
||||
|
||||
switch (phase)
|
||||
{
|
||||
case GDK_TOUCHPAD_GESTURE_PHASE_BEGIN:
|
||||
handled = gtk_event_controller_scroll_begin (controller);
|
||||
gtk_event_controller_scroll_begin (controller);
|
||||
break;
|
||||
|
||||
case GDK_TOUCHPAD_GESTURE_PHASE_END:
|
||||
handled = gtk_event_controller_scroll_end (controller);
|
||||
gtk_event_controller_scroll_end (controller);
|
||||
break;
|
||||
|
||||
case GDK_TOUCHPAD_GESTURE_PHASE_CANCEL:
|
||||
@@ -336,7 +331,7 @@ gtk_event_controller_scroll_handle_hold_event (GtkEventController *controller,
|
||||
break;
|
||||
}
|
||||
|
||||
return handled;
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@
|
||||
* a `GtkExpression` object is needed like in a `<property>` tag for an expression
|
||||
* property, or in a `<binding name="property">` tag to bind a property to an expression.
|
||||
*
|
||||
* To create an property expression, use the `<lookup>` element. It can have a `type`
|
||||
* To create a property expression, use the `<lookup>` element. It can have a `type`
|
||||
* attribute to specify the object type, and a `name` attribute to specify the property
|
||||
* to look up. The content of `<lookup>` can either be an element specfiying the expression
|
||||
* to use the object, or a string that specifies the name of the object to use.
|
||||
|
||||
+46
-15
@@ -236,6 +236,7 @@ struct _GtkFileChooserWidget
|
||||
LocationMode location_mode;
|
||||
|
||||
GtkWidget *external_entry;
|
||||
GtkEventController *external_entry_controller;
|
||||
|
||||
GtkWidget *choice_box;
|
||||
GHashTable *choices;
|
||||
@@ -2193,7 +2194,9 @@ update_default (GtkFileChooserWidget *impl)
|
||||
return;
|
||||
|
||||
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (impl));
|
||||
sensitive = (g_list_model_get_n_items (files) > 0);
|
||||
sensitive = (g_list_model_get_n_items (files) > 0 ||
|
||||
impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
|
||||
impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
||||
gtk_widget_set_sensitive (button, sensitive);
|
||||
|
||||
g_object_unref (files);
|
||||
@@ -2300,6 +2303,28 @@ forward_key (GtkEventControllerKey *key,
|
||||
return gtk_event_controller_key_forward (key, GTK_WIDGET (impl));
|
||||
}
|
||||
|
||||
static void
|
||||
external_entry_setup (GtkFileChooserWidget *impl)
|
||||
{
|
||||
/* Make keybindings (for example, Ctrl+H to toggle showing hidden files)
|
||||
* work even when the focus is on the external entry (which is outside
|
||||
* the hierarchy of GtkFileChooserWidget) */
|
||||
|
||||
impl->external_entry_controller = gtk_event_controller_key_new ();
|
||||
gtk_event_controller_set_propagation_phase (impl->external_entry_controller,
|
||||
GTK_PHASE_BUBBLE);
|
||||
g_signal_connect (impl->external_entry_controller, "key-pressed",
|
||||
G_CALLBACK (forward_key), impl);
|
||||
gtk_widget_add_controller (impl->external_entry, impl->external_entry_controller);
|
||||
}
|
||||
|
||||
static void
|
||||
external_entry_disconnect (GtkFileChooserWidget *impl)
|
||||
{
|
||||
gtk_widget_remove_controller (impl->external_entry, impl->external_entry_controller);
|
||||
impl->external_entry_controller = NULL;
|
||||
}
|
||||
|
||||
/* Creates the widgets specific to Save mode */
|
||||
static void
|
||||
save_widgets_create (GtkFileChooserWidget *impl)
|
||||
@@ -2321,10 +2346,7 @@ save_widgets_create (GtkFileChooserWidget *impl)
|
||||
impl->location_entry = impl->external_entry;
|
||||
g_object_add_weak_pointer (G_OBJECT (impl->external_entry), (gpointer *)&impl->location_entry);
|
||||
location_entry_setup (impl);
|
||||
|
||||
g_signal_connect_after (gtk_entry_get_key_controller (GTK_ENTRY (impl->external_entry)),
|
||||
"key-pressed",
|
||||
G_CALLBACK (forward_key), impl);
|
||||
external_entry_setup (impl);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2361,9 +2383,7 @@ save_widgets_destroy (GtkFileChooserWidget *impl)
|
||||
{
|
||||
if (impl->external_entry && impl->external_entry == impl->location_entry)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (gtk_entry_get_key_controller (GTK_ENTRY (impl->external_entry)),
|
||||
forward_key, impl);
|
||||
|
||||
external_entry_disconnect (impl);
|
||||
location_entry_disconnect (impl);
|
||||
impl->location_entry = NULL;
|
||||
}
|
||||
@@ -3102,7 +3122,6 @@ gtk_file_chooser_widget_dispose (GObject *object)
|
||||
GtkFileChooserWidget *impl = (GtkFileChooserWidget *) object;
|
||||
|
||||
cancel_all_operations (impl);
|
||||
|
||||
g_clear_pointer (&impl->rename_file_popover, gtk_widget_unparent);
|
||||
g_clear_pointer (&impl->browse_files_popover, gtk_widget_unparent);
|
||||
g_clear_object (&impl->extra_widget);
|
||||
@@ -3110,6 +3129,7 @@ gtk_file_chooser_widget_dispose (GObject *object)
|
||||
|
||||
if (impl->external_entry && impl->location_entry == impl->external_entry)
|
||||
{
|
||||
external_entry_disconnect (impl);
|
||||
location_entry_disconnect (impl);
|
||||
impl->external_entry = NULL;
|
||||
}
|
||||
@@ -4748,9 +4768,15 @@ update_chooser_entry (GtkFileChooserWidget *impl)
|
||||
|
||||
if (change_entry && !impl->auto_selecting_first_row)
|
||||
{
|
||||
GtkEntryCompletion *completion = gtk_entry_get_completion (GTK_ENTRY (impl->location_entry));
|
||||
|
||||
if (completion)
|
||||
gtk_entry_completion_set_popup_completion (completion, FALSE);
|
||||
g_signal_handlers_block_by_func (impl->location_entry, G_CALLBACK (location_entry_changed_cb), impl);
|
||||
gtk_editable_set_text (GTK_EDITABLE (impl->location_entry), impl->browse_files_last_selected_name);
|
||||
g_signal_handlers_unblock_by_func (impl->location_entry, G_CALLBACK (location_entry_changed_cb), impl);
|
||||
if (completion)
|
||||
gtk_entry_completion_set_popup_completion (completion, TRUE);
|
||||
|
||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
_gtk_file_chooser_entry_select_filename (GTK_FILE_CHOOSER_ENTRY (impl->location_entry));
|
||||
@@ -5440,7 +5466,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
|
||||
* So we want the selection to be "bar/foo.txt". Jump to the case for the
|
||||
* filename entry to see if that is the case.
|
||||
*/
|
||||
if (info.result == NULL && impl->location_entry)
|
||||
if (g_list_model_get_n_items (G_LIST_MODEL (info.result)) == 0 && impl->location_entry)
|
||||
goto file_entry;
|
||||
}
|
||||
else if (impl->location_entry &&
|
||||
@@ -5458,7 +5484,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
|
||||
goto out;
|
||||
|
||||
if (!is_well_formed)
|
||||
return NULL;
|
||||
goto empty;
|
||||
|
||||
if (info.file_from_entry)
|
||||
{
|
||||
@@ -5468,7 +5494,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
|
||||
else if (!file_list_seen)
|
||||
goto file_list;
|
||||
else
|
||||
return NULL;
|
||||
goto empty;
|
||||
}
|
||||
else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
|
||||
goto file_list;
|
||||
@@ -5489,7 +5515,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
|
||||
* then we fall back to the current directory
|
||||
*/
|
||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
|
||||
info.result == NULL)
|
||||
g_list_model_get_n_items (G_LIST_MODEL (info.result)) == 0)
|
||||
{
|
||||
GFile *current_folder;
|
||||
|
||||
@@ -5500,6 +5526,11 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
|
||||
}
|
||||
|
||||
return G_LIST_MODEL (info.result);
|
||||
|
||||
empty:
|
||||
|
||||
g_list_store_remove_all (info.result);
|
||||
return G_LIST_MODEL (info.result);
|
||||
}
|
||||
|
||||
/* Shows or hides the filter widgets */
|
||||
@@ -7841,11 +7872,11 @@ gtk_file_chooser_widget_set_save_entry (GtkFileChooserWidget *impl,
|
||||
g_return_if_fail (GTK_IS_FILE_CHOOSER_WIDGET (impl));
|
||||
g_return_if_fail (entry == NULL || GTK_IS_FILE_CHOOSER_ENTRY (entry));
|
||||
|
||||
impl->external_entry = entry;
|
||||
|
||||
if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
{
|
||||
save_widgets_destroy (impl);
|
||||
|
||||
impl->external_entry = entry;
|
||||
save_widgets_create (impl);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -283,7 +283,8 @@ parser_start_element (GtkBuildableParseContext *context,
|
||||
}
|
||||
|
||||
if (strcmp (element_name, "mime-types") == 0 ||
|
||||
strcmp (element_name, "patterns") == 0)
|
||||
strcmp (element_name, "patterns") == 0 ||
|
||||
strcmp (element_name, "suffixes") == 0)
|
||||
{
|
||||
if (!_gtk_builder_check_parent (data->builder, context, "object", error))
|
||||
return;
|
||||
@@ -338,7 +339,7 @@ parser_end_element (GtkBuildableParseContext *context,
|
||||
{
|
||||
SubParserData *data = (SubParserData*)user_data;
|
||||
|
||||
if (data->string)
|
||||
if (data->string && data->parsing)
|
||||
{
|
||||
switch (data->type)
|
||||
{
|
||||
@@ -422,7 +423,8 @@ gtk_file_filter_buildable_custom_tag_end (GtkBuildable *buildable,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (strcmp (tagname, "mime-types") == 0 ||
|
||||
strcmp (tagname, "patterns") == 0)
|
||||
strcmp (tagname, "patterns") == 0 ||
|
||||
strcmp (tagname, "suffixes") == 0)
|
||||
{
|
||||
SubParserData *data = (SubParserData*)user_data;
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@
|
||||
* GtkFilter:
|
||||
*
|
||||
* A `GtkFilter` object describes the filtering to be performed by a
|
||||
* `GtkFilterListModel`.
|
||||
* [class@Gtk.FilterListModel].
|
||||
*
|
||||
* The model will use the filter to determine if it should include items
|
||||
* or not by calling [method@Gtk.Filter.match] for each item and only
|
||||
|
||||
+13
-13
@@ -72,8 +72,8 @@ static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
static FlattenNode *
|
||||
gtk_flatten_list_model_get_nth (GtkRbTree *tree,
|
||||
guint position,
|
||||
guint *model_position)
|
||||
guint position,
|
||||
guint *model_position)
|
||||
{
|
||||
FlattenNode *node, *tmp;
|
||||
guint model_n_items;
|
||||
@@ -110,8 +110,8 @@ gtk_flatten_list_model_get_nth (GtkRbTree *tree,
|
||||
|
||||
static FlattenNode *
|
||||
gtk_flatten_list_model_get_nth_model (GtkRbTree *tree,
|
||||
guint position,
|
||||
guint *items_before)
|
||||
guint position,
|
||||
guint *items_before)
|
||||
{
|
||||
FlattenNode *node, *tmp;
|
||||
guint before;
|
||||
@@ -202,11 +202,11 @@ G_DEFINE_TYPE_WITH_CODE (GtkFlattenListModel, gtk_flatten_list_model, G_TYPE_OBJ
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_flatten_list_model_model_init))
|
||||
|
||||
static void
|
||||
gtk_flatten_list_model_items_changed_cb (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
gpointer _node)
|
||||
gtk_flatten_list_model_items_changed_cb (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
gpointer _node)
|
||||
{
|
||||
FlattenNode *node = _node, *parent, *left;
|
||||
GtkFlattenListModel *self = node->list;
|
||||
@@ -323,10 +323,10 @@ gtk_flatten_list_model_set_property (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_flatten_list_model_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
gtk_flatten_list_model_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkFlattenListModel *self = GTK_FLATTEN_LIST_MODEL (object);
|
||||
|
||||
|
||||
+1
-1
@@ -1291,7 +1291,7 @@ gtk_grid_view_set_factory (GtkGridView *self,
|
||||
GtkListItemFactory *factory)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_GRID_VIEW (self));
|
||||
g_return_if_fail (factory == NULL || GTK_LIST_ITEM_FACTORY (factory));
|
||||
g_return_if_fail (factory == NULL || GTK_IS_LIST_ITEM_FACTORY (factory));
|
||||
|
||||
if (factory == gtk_list_item_manager_get_factory (self->item_manager))
|
||||
return;
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@
|
||||
* maximize and close buttons, or the window icon.
|
||||
*
|
||||
* For these reasons, `GtkHeaderBar` is the natural choice for use as the
|
||||
* custom titlebar widget of a `GtkWindow (see [method@Gtk.Window.set_titlebar]),
|
||||
* custom titlebar widget of a `GtkWindow` (see [method@Gtk.Window.set_titlebar]),
|
||||
* as it gives features typical of titlebars while allowing the addition of
|
||||
* child widgets.
|
||||
*
|
||||
|
||||
+28
-10
@@ -132,7 +132,9 @@ gtk_image_definition_new_paintable (GdkPaintable *paintable)
|
||||
GtkImageDefinition *
|
||||
gtk_image_definition_ref (GtkImageDefinition *def)
|
||||
{
|
||||
def->empty.ref_count++;
|
||||
GtkImageDefinitionEmpty *empty = (GtkImageDefinitionEmpty *) def;
|
||||
|
||||
empty->ref_count++;
|
||||
|
||||
return def;
|
||||
}
|
||||
@@ -140,9 +142,11 @@ gtk_image_definition_ref (GtkImageDefinition *def)
|
||||
void
|
||||
gtk_image_definition_unref (GtkImageDefinition *def)
|
||||
{
|
||||
def->empty.ref_count--;
|
||||
GtkImageDefinitionEmpty *empty = (GtkImageDefinitionEmpty *) def;
|
||||
|
||||
if (def->empty.ref_count > 0)
|
||||
empty->ref_count--;
|
||||
|
||||
if (empty->ref_count > 0)
|
||||
return;
|
||||
|
||||
switch (def->type)
|
||||
@@ -152,13 +156,22 @@ gtk_image_definition_unref (GtkImageDefinition *def)
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
g_object_unref (def->paintable.paintable);
|
||||
{
|
||||
GtkImageDefinitionPaintable *paintable = (GtkImageDefinitionPaintable *) def;
|
||||
g_object_unref (paintable->paintable);
|
||||
}
|
||||
break;
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
g_free (def->icon_name.icon_name);
|
||||
{
|
||||
GtkImageDefinitionIconName *icon_name = (GtkImageDefinitionIconName *) def;
|
||||
g_free (icon_name->icon_name);
|
||||
}
|
||||
break;
|
||||
case GTK_IMAGE_GICON:
|
||||
g_object_unref (def->gicon.gicon);
|
||||
{
|
||||
GtkImageDefinitionGIcon *gicon = (GtkImageDefinitionGIcon *) def;
|
||||
g_object_unref (gicon->gicon);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -189,27 +202,32 @@ 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 def->icon_name.icon_name;
|
||||
return 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 def->gicon.gicon;
|
||||
return 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 def->paintable.paintable;
|
||||
return paintable->paintable;
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -274,7 +274,6 @@ gtk_im_context_simple_init_compose_table (void)
|
||||
char **lang = NULL;
|
||||
const char * const sys_langs[] = { "el_gr", "fi_fi", "pt_br", NULL };
|
||||
const char * const *sys_lang = NULL;
|
||||
char *x11_compose_file_dir = get_x11_compose_file_dir ();
|
||||
|
||||
path = g_build_filename (g_get_user_config_dir (), "gtk-4.0", "Compose", NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
@@ -323,7 +322,9 @@ gtk_im_context_simple_init_compose_table (void)
|
||||
{
|
||||
if (g_ascii_strncasecmp (*lang, *sys_lang, strlen (*sys_lang)) == 0)
|
||||
{
|
||||
char *x11_compose_file_dir = get_x11_compose_file_dir ();
|
||||
path = g_build_filename (x11_compose_file_dir, *lang, "Compose", NULL);
|
||||
g_free (x11_compose_file_dir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -336,7 +337,6 @@ gtk_im_context_simple_init_compose_table (void)
|
||||
g_clear_pointer (&path, g_free);
|
||||
}
|
||||
|
||||
g_free (x11_compose_file_dir);
|
||||
g_strfreev (langs);
|
||||
|
||||
if (path != NULL &&
|
||||
@@ -406,7 +406,7 @@ gtk_im_context_simple_finalize (GObject *obj)
|
||||
|
||||
/**
|
||||
* gtk_im_context_simple_new:
|
||||
*
|
||||
*
|
||||
* Creates a new `GtkIMContextSimple`.
|
||||
*
|
||||
* Returns: a new `GtkIMContextSimple`
|
||||
@@ -483,14 +483,14 @@ check_hex (GtkIMContextSimple *context_simple,
|
||||
priv->tentative_match_len = 0;
|
||||
|
||||
str = g_string_new (NULL);
|
||||
|
||||
|
||||
i = 0;
|
||||
while (i < n_compose)
|
||||
{
|
||||
gunichar ch;
|
||||
|
||||
|
||||
ch = gdk_keyval_to_unicode (priv->compose_buffer[i]);
|
||||
|
||||
|
||||
if (ch == 0)
|
||||
return FALSE;
|
||||
|
||||
@@ -500,7 +500,7 @@ check_hex (GtkIMContextSimple *context_simple,
|
||||
buf[g_unichar_to_utf8 (ch, buf)] = '\0';
|
||||
|
||||
g_string_append (str, buf);
|
||||
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -523,7 +523,7 @@ check_hex (GtkIMContextSimple *context_simple,
|
||||
g_string_append_unichar (priv->tentative_match, n);
|
||||
priv->tentative_match_len = n_compose;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple,
|
||||
FALSE,
|
||||
&translated,
|
||||
&translated);
|
||||
|
||||
|
||||
gtk_im_context_filter_keypress (context, tmp_event);
|
||||
gdk_event_unref (tmp_event);
|
||||
}
|
||||
@@ -725,7 +725,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple,
|
||||
g_signal_emit_by_name (context, "preedit-end");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
keyval = gdk_key_event_get_keyval (event);
|
||||
ch = gdk_keyval_to_unicode (keyval);
|
||||
if (ch != 0 && !g_unichar_iscntrl (ch))
|
||||
@@ -783,7 +783,7 @@ canonical_hex_keyval (GdkEvent *event)
|
||||
}
|
||||
|
||||
g_free (keyvals);
|
||||
|
||||
|
||||
if (keyval)
|
||||
return keyval;
|
||||
else
|
||||
@@ -954,7 +954,7 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
|
||||
|
||||
if (!priv->in_hex_sequence)
|
||||
g_signal_emit_by_name (context_simple, "preedit-end");
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -991,7 +991,7 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
|
||||
priv->compose_buffer[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check for hex sequence start */
|
||||
if (!priv->in_hex_sequence && have_hex_mods && is_hex_start)
|
||||
{
|
||||
@@ -1002,7 +1002,7 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
|
||||
|
||||
g_signal_emit_by_name (context_simple, "preedit-start");
|
||||
g_signal_emit_by_name (context_simple, "preedit-changed");
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
+54
-22
@@ -48,6 +48,7 @@ struct _GtkIMContextWaylandGlobal
|
||||
gboolean focused;
|
||||
|
||||
guint serial;
|
||||
guint done_serial;
|
||||
};
|
||||
|
||||
struct _GtkIMContextWaylandClass
|
||||
@@ -70,6 +71,7 @@ struct _GtkIMContextWayland
|
||||
{
|
||||
GtkIMContextSimple parent_instance;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *controller_widget;
|
||||
|
||||
GtkGesture *gesture;
|
||||
double press_x;
|
||||
@@ -172,6 +174,9 @@ text_input_preedit_apply (GtkIMContextWaylandGlobal *global)
|
||||
return;
|
||||
|
||||
context = GTK_IM_CONTEXT_WAYLAND (global->current);
|
||||
if (context->pending_preedit.text == NULL &&
|
||||
context->current_preedit.text == NULL)
|
||||
return;
|
||||
|
||||
state_change = ((context->pending_preedit.text == NULL)
|
||||
!= (context->current_preedit.text == NULL));
|
||||
@@ -207,11 +212,11 @@ text_input_commit (void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_commit_apply (GtkIMContextWaylandGlobal *global, gboolean valid)
|
||||
text_input_commit_apply (GtkIMContextWaylandGlobal *global)
|
||||
{
|
||||
GtkIMContextWayland *context;
|
||||
context = GTK_IM_CONTEXT_WAYLAND (global->current);
|
||||
if (context->pending_commit && valid)
|
||||
if (context->pending_commit)
|
||||
g_signal_emit_by_name (global->current, "commit", context->pending_commit);
|
||||
g_free (context->pending_commit);
|
||||
context->pending_commit = NULL;
|
||||
@@ -236,8 +241,7 @@ text_input_delete_surrounding_text (void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_delete_surrounding_text_apply (GtkIMContextWaylandGlobal *global,
|
||||
gboolean valid)
|
||||
text_input_delete_surrounding_text_apply (GtkIMContextWaylandGlobal *global)
|
||||
{
|
||||
GtkIMContextWayland *context;
|
||||
gboolean retval;
|
||||
@@ -248,7 +252,7 @@ text_input_delete_surrounding_text_apply (GtkIMContextWaylandGlobal *global,
|
||||
|
||||
len = context->pending_surrounding_delete.after_length
|
||||
+ context->pending_surrounding_delete.before_length;
|
||||
if (len > 0 && valid)
|
||||
if (len > 0)
|
||||
g_signal_emit_by_name (global->current, "delete-surrounding",
|
||||
-context->pending_surrounding_delete.before_length,
|
||||
len, &retval);
|
||||
@@ -262,16 +266,16 @@ text_input_done (void *data,
|
||||
{
|
||||
GtkIMContextWaylandGlobal *global = data;
|
||||
gboolean result;
|
||||
gboolean valid;
|
||||
|
||||
|
||||
global->done_serial = serial;
|
||||
|
||||
if (!global->current)
|
||||
return;
|
||||
|
||||
valid = serial == global->serial;
|
||||
text_input_delete_surrounding_text_apply(global, valid);
|
||||
text_input_commit_apply(global, valid);
|
||||
text_input_delete_surrounding_text_apply (global);
|
||||
text_input_commit_apply (global);
|
||||
g_signal_emit_by_name (global->current, "retrieve-surrounding", &result);
|
||||
text_input_preedit_apply(global);
|
||||
text_input_preedit_apply (global);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -288,6 +292,8 @@ notify_surrounding_text (GtkIMContextWayland *context)
|
||||
global = gtk_im_context_wayland_get_global (context);
|
||||
if (global == NULL)
|
||||
return;
|
||||
if (global->done_serial != global->serial)
|
||||
return;
|
||||
|
||||
len = strlen (context->surrounding.text);
|
||||
cursor = context->surrounding.cursor_idx;
|
||||
@@ -357,11 +363,13 @@ notify_cursor_location (GtkIMContextWayland *context)
|
||||
{
|
||||
GtkIMContextWaylandGlobal *global;
|
||||
cairo_rectangle_int_t rect;
|
||||
double x, y;
|
||||
double x, y, sx, sy;
|
||||
|
||||
global = gtk_im_context_wayland_get_global (context);
|
||||
if (global == NULL)
|
||||
return;
|
||||
if (global->done_serial != global->serial)
|
||||
return;
|
||||
|
||||
rect = context->cursor_rect;
|
||||
gtk_widget_translate_coordinates (context->widget,
|
||||
@@ -369,8 +377,11 @@ notify_cursor_location (GtkIMContextWayland *context)
|
||||
rect.x, rect.y,
|
||||
&x, &y);
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
gtk_native_get_surface_transform (gtk_widget_get_native (context->widget),
|
||||
&sx, &sy);
|
||||
|
||||
rect.x = x + sx;
|
||||
rect.y = y + sy;
|
||||
zwp_text_input_v3_set_cursor_rectangle (global->text_input,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
@@ -449,6 +460,8 @@ notify_content_type (GtkIMContextWayland *context)
|
||||
global = gtk_im_context_wayland_get_global (context);
|
||||
if (global == NULL)
|
||||
return;
|
||||
if (global->done_serial != global->serial)
|
||||
return;
|
||||
|
||||
g_object_get (context,
|
||||
"input-hints", &hints,
|
||||
@@ -546,16 +559,21 @@ gtk_im_context_wayland_set_client_widget (GtkIMContext *context,
|
||||
return;
|
||||
|
||||
if (context_wayland->widget)
|
||||
gtk_im_context_wayland_focus_out (context);
|
||||
|
||||
if (context_wayland->controller_widget)
|
||||
{
|
||||
gtk_im_context_wayland_focus_out (context);
|
||||
gtk_widget_remove_controller (context_wayland->widget, GTK_EVENT_CONTROLLER (context_wayland->gesture));
|
||||
gtk_widget_remove_controller (context_wayland->controller_widget,
|
||||
GTK_EVENT_CONTROLLER (context_wayland->gesture));
|
||||
context_wayland->gesture = NULL;
|
||||
g_clear_object (&context_wayland->controller_widget);
|
||||
}
|
||||
|
||||
g_set_object (&context_wayland->widget, widget);
|
||||
|
||||
if (widget)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
GtkGesture *gesture;
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
@@ -566,7 +584,18 @@ gtk_im_context_wayland_set_client_widget (GtkIMContext *context,
|
||||
G_CALLBACK (pressed_cb), context);
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (released_cb), context);
|
||||
gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
parent = gtk_widget_get_parent (widget);
|
||||
|
||||
if (parent &&
|
||||
GTK_IS_EDITABLE (widget) &&
|
||||
GTK_IS_EDITABLE (parent))
|
||||
g_set_object (&context_wayland->controller_widget, parent);
|
||||
else
|
||||
g_set_object (&context_wayland->controller_widget, widget);
|
||||
|
||||
gtk_widget_add_controller (context_wayland->controller_widget,
|
||||
GTK_EVENT_CONTROLLER (gesture));
|
||||
context_wayland->gesture = gesture;
|
||||
}
|
||||
}
|
||||
@@ -884,17 +913,20 @@ gtk_im_context_wayland_set_surrounding (GtkIMContext *context,
|
||||
|
||||
context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
|
||||
|
||||
if (context_wayland->surrounding.text && text &&
|
||||
(len < 0 || len == strlen (context_wayland->surrounding.text)) &&
|
||||
strncmp (context_wayland->surrounding.text, text, len) == 0 &&
|
||||
context_wayland->surrounding.cursor_idx == cursor_index &&
|
||||
context_wayland->surrounding.anchor_idx == selection_bound)
|
||||
return;
|
||||
|
||||
g_free (context_wayland->surrounding.text);
|
||||
context_wayland->surrounding.text = g_strndup (text, len);
|
||||
context_wayland->surrounding.cursor_idx = cursor_index;
|
||||
context_wayland->surrounding.anchor_idx = selection_bound;
|
||||
|
||||
notify_surrounding_text (context_wayland);
|
||||
/* State changes coming from reset don't have any other opportunity to get
|
||||
* committed. */
|
||||
if (context_wayland->surrounding_change !=
|
||||
ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD)
|
||||
commit_state (context_wayland);
|
||||
commit_state (context_wayland);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -314,6 +314,11 @@ gtk_im_multicontext_set_client_widget (GtkIMContext *context,
|
||||
GtkIMContext *delegate;
|
||||
GtkSettings *settings;
|
||||
|
||||
if (priv->client_widget == widget)
|
||||
return;
|
||||
|
||||
gtk_im_multicontext_set_delegate (self, NULL, TRUE);
|
||||
|
||||
if (priv->client_widget != NULL)
|
||||
{
|
||||
settings = gtk_widget_get_settings (priv->client_widget);
|
||||
@@ -332,11 +337,11 @@ gtk_im_multicontext_set_client_widget (GtkIMContext *context,
|
||||
g_signal_connect (settings, "notify::gtk-im-module",
|
||||
G_CALLBACK (im_module_setting_changed),
|
||||
self);
|
||||
}
|
||||
|
||||
delegate = gtk_im_multicontext_get_delegate (self);
|
||||
if (delegate)
|
||||
gtk_im_context_set_client_widget (delegate, widget);
|
||||
delegate = gtk_im_multicontext_get_delegate (self);
|
||||
if (delegate)
|
||||
gtk_im_context_set_client_widget (delegate, widget);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+1
-5
@@ -3,11 +3,7 @@
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
#define P_(String) g_dgettext(GETTEXT_PACKAGE "-properties",String)
|
||||
#else
|
||||
#define P_(String) (String)
|
||||
#endif
|
||||
#define P_(String) g_dgettext (GETTEXT_PACKAGE "-properties", String)
|
||||
|
||||
/* not really I18N-related, but also a string marker macro */
|
||||
#define I_(string) g_intern_static_string (string)
|
||||
|
||||
+23
-9
@@ -1793,6 +1793,7 @@ gtk_label_focus (GtkWidget *widget,
|
||||
{
|
||||
info->selection_anchor = focus_link->start;
|
||||
info->selection_end = focus_link->start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1856,7 +1857,6 @@ gtk_label_focus (GtkWidget *widget,
|
||||
{
|
||||
int focus_link_index;
|
||||
int new_index = -1;
|
||||
int i;
|
||||
|
||||
if (info->n_links == 0)
|
||||
goto out;
|
||||
@@ -1870,29 +1870,39 @@ gtk_label_focus (GtkWidget *widget,
|
||||
{
|
||||
case GTK_DIR_TAB_FORWARD:
|
||||
if (focus_link)
|
||||
new_index = (focus_link_index + 1) % info->n_links;
|
||||
new_index = focus_link_index + 1;
|
||||
else
|
||||
new_index = 0;
|
||||
|
||||
for (i = new_index; i < info->n_links; i++)
|
||||
if (new_index >= info->n_links)
|
||||
goto out;
|
||||
|
||||
while (new_index < info->n_links)
|
||||
{
|
||||
const GtkLabelLink *link = &info->links[i];
|
||||
const GtkLabelLink *link = &info->links[new_index];
|
||||
if (!range_is_in_ellipsis (self, link->start, link->end))
|
||||
break;
|
||||
|
||||
new_index++;
|
||||
}
|
||||
break;
|
||||
|
||||
case GTK_DIR_TAB_BACKWARD:
|
||||
if (focus_link)
|
||||
new_index = focus_link_index == 0 ? info->n_links - 1 : focus_link_index - 1;
|
||||
new_index = focus_link_index - 1;
|
||||
else
|
||||
new_index = info->n_links - 1;
|
||||
|
||||
for (i = new_index; i >= 0; i--)
|
||||
if (new_index < 0)
|
||||
goto out;
|
||||
|
||||
while (new_index >= 0)
|
||||
{
|
||||
const GtkLabelLink *link = &info->links[i];
|
||||
const GtkLabelLink *link = &info->links[new_index];
|
||||
if (!range_is_in_ellipsis (self, link->start, link->end))
|
||||
break;
|
||||
|
||||
new_index--;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1904,7 +1914,7 @@ gtk_label_focus (GtkWidget *widget,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (new_index != -1)
|
||||
if (new_index != -1 && new_index < info->n_links)
|
||||
{
|
||||
focus_link = &info->links[new_index];
|
||||
info->selection_anchor = focus_link->start;
|
||||
@@ -3615,7 +3625,11 @@ static void
|
||||
gtk_label_ensure_has_tooltip (GtkLabel *self)
|
||||
{
|
||||
guint i;
|
||||
gboolean has_tooltip = FALSE;
|
||||
gboolean has_tooltip = gtk_widget_get_has_tooltip(GTK_WIDGET(self));
|
||||
|
||||
if (has_tooltip) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < self->select_info->n_links; i++)
|
||||
{
|
||||
|
||||
@@ -247,6 +247,22 @@ gtk_list_item_new (void)
|
||||
return g_object_new (GTK_TYPE_LIST_ITEM, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_item_do_notify (GtkListItem *list_item,
|
||||
gboolean notify_item,
|
||||
gboolean notify_position,
|
||||
gboolean notify_selected)
|
||||
{
|
||||
GObject *object = G_OBJECT (list_item);
|
||||
|
||||
if (notify_item)
|
||||
g_object_notify_by_pspec (object, properties[PROP_ITEM]);
|
||||
if (notify_position)
|
||||
g_object_notify_by_pspec (object, properties[PROP_POSITION]);
|
||||
if (notify_selected)
|
||||
g_object_notify_by_pspec (object, properties[PROP_SELECTED]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_list_item_get_item: (attributes org.gtk.Method.get_property=item)
|
||||
* @self: a `GtkListItem`
|
||||
|
||||
@@ -162,9 +162,5 @@ gtk_list_item_factory_update (GtkListItemFactory *self,
|
||||
|
||||
list_item = gtk_list_item_widget_get_list_item (widget);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (list_item));
|
||||
|
||||
GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->update (self, widget, list_item, position, item, selected);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (list_item));
|
||||
}
|
||||
|
||||
@@ -825,7 +825,7 @@ gtk_list_item_manager_set_factory (GtkListItemManager *self,
|
||||
GSList *l;
|
||||
|
||||
g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self));
|
||||
g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (factory));
|
||||
g_return_if_fail (factory == NULL || GTK_IS_LIST_ITEM_FACTORY (factory));
|
||||
|
||||
if (self->factory == factory)
|
||||
return;
|
||||
|
||||
@@ -40,6 +40,11 @@ struct _GtkListItem
|
||||
|
||||
GtkListItem * gtk_list_item_new (void);
|
||||
|
||||
void gtk_list_item_do_notify (GtkListItem *list_item,
|
||||
gboolean notify_item,
|
||||
gboolean notify_position,
|
||||
gboolean notify_selected);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+23
-16
@@ -485,20 +485,27 @@ gtk_list_item_widget_update (GtkListItemWidget *self,
|
||||
gboolean selected)
|
||||
{
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
gboolean was_selected;
|
||||
|
||||
was_selected = priv->selected;
|
||||
|
||||
if (priv->list_item)
|
||||
gtk_list_item_factory_update (priv->factory, self, position, item, selected);
|
||||
else
|
||||
gtk_list_item_widget_default_update (self, NULL, position, item, selected);
|
||||
|
||||
if (selected)
|
||||
gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED);
|
||||
/* don't look at selected variable, it's not reentrancy safe */
|
||||
if (was_selected != priv->selected)
|
||||
{
|
||||
if (priv->selected)
|
||||
gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED);
|
||||
|
||||
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_SELECTED, selected,
|
||||
-1);
|
||||
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_SELECTED, priv->selected,
|
||||
-1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -554,29 +561,29 @@ gtk_list_item_widget_default_update (GtkListItemWidget *self,
|
||||
gpointer item,
|
||||
gboolean selected)
|
||||
{
|
||||
/* Track notify manually instead of freeze/thaw_notify for performance reasons. */
|
||||
gboolean notify_item = FALSE, notify_position = FALSE, notify_selected = FALSE;
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
/* FIXME: It's kinda evil to notify external objects from here... */
|
||||
|
||||
|
||||
if (g_set_object (&priv->item, item))
|
||||
{
|
||||
if (list_item)
|
||||
g_object_notify (G_OBJECT (list_item), "item");
|
||||
}
|
||||
notify_item = TRUE;
|
||||
|
||||
if (priv->position != position)
|
||||
{
|
||||
priv->position = position;
|
||||
if (list_item)
|
||||
g_object_notify (G_OBJECT (list_item), "position");
|
||||
notify_position = TRUE;
|
||||
}
|
||||
|
||||
if (priv->selected != selected)
|
||||
{
|
||||
priv->selected = selected;
|
||||
if (list_item)
|
||||
g_object_notify (G_OBJECT (list_item), "selected");
|
||||
notify_selected = TRUE;
|
||||
}
|
||||
|
||||
if (list_item)
|
||||
gtk_list_item_do_notify (list_item, notify_item, notify_position, notify_selected);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+1
-1
@@ -1032,7 +1032,7 @@ gtk_list_view_set_factory (GtkListView *self,
|
||||
GtkListItemFactory *factory)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_LIST_VIEW (self));
|
||||
g_return_if_fail (factory == NULL || GTK_LIST_ITEM_FACTORY (factory));
|
||||
g_return_if_fail (factory == NULL || GTK_IS_LIST_ITEM_FACTORY (factory));
|
||||
|
||||
if (factory == gtk_list_item_manager_get_factory (self->item_manager))
|
||||
return;
|
||||
|
||||
+1
-3
@@ -505,13 +505,11 @@ gettext_initialization (void)
|
||||
{
|
||||
setlocale_initialization ();
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
bindtextdomain (GETTEXT_PACKAGE, _gtk_get_localedir ());
|
||||
bindtextdomain (GETTEXT_PACKAGE "-properties", _gtk_get_localedir ());
|
||||
# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
|
||||
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE "-properties", "UTF-8");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -379,8 +379,8 @@ update_node_ordering (GtkModelButton *button)
|
||||
gtk_widget_insert_before (button->end_indicator, GTK_WIDGET (button), child);
|
||||
|
||||
child = gtk_widget_get_last_child (GTK_WIDGET (button));
|
||||
if (child != button->start_box)
|
||||
gtk_widget_insert_after (button->start_box, GTK_WIDGET (button), child);
|
||||
if (button->end_indicator && child != button->end_indicator)
|
||||
gtk_widget_insert_after (button->end_indicator, GTK_WIDGET (button), child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -346,10 +346,10 @@ gtk_overlay_child_update_style_classes (GtkOverlay *overlay,
|
||||
gboolean is_left, is_right, is_top, is_bottom;
|
||||
gboolean has_left, has_right, has_top, has_bottom;
|
||||
|
||||
has_left = gtk_widget_has_css_class (widget, "left");
|
||||
has_right = gtk_widget_has_css_class (widget, "right");
|
||||
has_top = gtk_widget_has_css_class (widget, "top");
|
||||
has_bottom = gtk_widget_has_css_class (widget, "bottom");
|
||||
has_left = gtk_widget_has_css_class (child, "left");
|
||||
has_right = gtk_widget_has_css_class (child, "right");
|
||||
has_top = gtk_widget_has_css_class (child, "top");
|
||||
has_bottom = gtk_widget_has_css_class (child, "bottom");
|
||||
|
||||
is_left = is_right = is_top = is_bottom = FALSE;
|
||||
|
||||
@@ -372,24 +372,24 @@ gtk_overlay_child_update_style_classes (GtkOverlay *overlay,
|
||||
is_bottom = (child_allocation->y + child_allocation->height == height);
|
||||
|
||||
if (has_left && !is_left)
|
||||
gtk_widget_remove_css_class (widget, "left");
|
||||
gtk_widget_remove_css_class (child, "left");
|
||||
else if (!has_left && is_left)
|
||||
gtk_widget_add_css_class (widget, "left");
|
||||
gtk_widget_add_css_class (child, "left");
|
||||
|
||||
if (has_right && !is_right)
|
||||
gtk_widget_remove_css_class (widget, "right");
|
||||
gtk_widget_remove_css_class (child, "right");
|
||||
else if (!has_right && is_right)
|
||||
gtk_widget_add_css_class (widget, "right");
|
||||
gtk_widget_add_css_class (child, "right");
|
||||
|
||||
if (has_top && !is_top)
|
||||
gtk_widget_remove_css_class (widget, "top");
|
||||
gtk_widget_remove_css_class (child, "top");
|
||||
else if (!has_top && is_top)
|
||||
gtk_widget_add_css_class (widget, "top");
|
||||
gtk_widget_add_css_class (child, "top");
|
||||
|
||||
if (has_bottom && !is_bottom)
|
||||
gtk_widget_remove_css_class (widget, "bottom");
|
||||
gtk_widget_remove_css_class (child, "bottom");
|
||||
else if (!has_bottom && is_bottom)
|
||||
gtk_widget_add_css_class (widget, "bottom");
|
||||
gtk_widget_add_css_class (child, "bottom");
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+43
-40
@@ -44,7 +44,7 @@
|
||||
/**
|
||||
* GtkPaned:
|
||||
*
|
||||
* `GtkPaned` has two panes, arranged either horizontally or vertically.
|
||||
* A widget with two panes, arranged either horizontally or vertically.
|
||||
*
|
||||
* 
|
||||
*
|
||||
@@ -63,13 +63,13 @@
|
||||
* each child inside a [class@Gtk.Frame] so that the gutter appears as a
|
||||
* ridge. No separator is drawn if one of the children is missing.
|
||||
*
|
||||
* Each child has two options that can be set, @resize and @shrink. If
|
||||
* @resize is true, then when the `GtkPaned` is resized, that child will
|
||||
* expand or shrink along with the paned widget. If @shrink is true, then
|
||||
* Each child has two options that can be set, "resize" and "shrink". If
|
||||
* "resize" is true then, when the `GtkPaned` is resized, that child will
|
||||
* expand or shrink along with the paned widget. If "shrink" is true, then
|
||||
* that child can be made smaller than its requisition by the user.
|
||||
* Setting @shrink to %FALSE allows the application to set a minimum size.
|
||||
* If @resize is false for both children, then this is treated as if
|
||||
* @resize is true for both children.
|
||||
* Setting "shrink" to false allows the application to set a minimum size.
|
||||
* If "resize" is false for both children, then this is treated as if
|
||||
* "resize" is true for both children.
|
||||
*
|
||||
* The application can set the position of the slider as if it were set
|
||||
* by the user, by calling [method@Gtk.Paned.set_position].
|
||||
@@ -431,7 +431,7 @@ gtk_paned_class_init (GtkPanedClass *class)
|
||||
/**
|
||||
* GtkPaned:position-set:
|
||||
*
|
||||
* %TRUE if the `position` property has been set.
|
||||
* Whether the [property@Gtk.Paned:position] property has been set.
|
||||
*/
|
||||
paned_props[PROP_POSITION_SET] =
|
||||
g_param_spec_boolean ("position-set",
|
||||
@@ -443,7 +443,8 @@ gtk_paned_class_init (GtkPanedClass *class)
|
||||
/**
|
||||
* GtkPaned:min-position:
|
||||
*
|
||||
* The smallest possible value for the position property.
|
||||
* The smallest possible value for the [property@Gtk.Paned:position]
|
||||
* property.
|
||||
*
|
||||
* This property is derived from the size and shrinkability
|
||||
* of the widget's children.
|
||||
@@ -458,7 +459,8 @@ gtk_paned_class_init (GtkPanedClass *class)
|
||||
/**
|
||||
* GtkPaned:max-position:
|
||||
*
|
||||
* The largest possible value for the position property.
|
||||
* The largest possible value for the [property@Gtk.Paned:position]
|
||||
* property.
|
||||
*
|
||||
* This property is derived from the size and shrinkability
|
||||
* of the widget's children.
|
||||
@@ -573,7 +575,7 @@ gtk_paned_class_init (GtkPanedClass *class)
|
||||
*
|
||||
* This is a [keybinding signal](class.SignalAction.html).
|
||||
*
|
||||
* The default binding is F6.
|
||||
* The default binding is <kbd>F6</kbd>.
|
||||
*/
|
||||
signals [CYCLE_CHILD_FOCUS] =
|
||||
g_signal_new (I_("cycle-child-focus"),
|
||||
@@ -594,7 +596,7 @@ gtk_paned_class_init (GtkPanedClass *class)
|
||||
*
|
||||
* This is a [keybinding signal](class.SignalAction.html).
|
||||
*
|
||||
* The default binding is Tab.
|
||||
* The default binding is <kbd>Tab</kbd>.
|
||||
*/
|
||||
signals [TOGGLE_HANDLE_FOCUS] =
|
||||
g_signal_new (I_("toggle-handle-focus"),
|
||||
@@ -634,7 +636,7 @@ gtk_paned_class_init (GtkPanedClass *class)
|
||||
*
|
||||
* This is a [keybinding signal](class.SignalAction.html).
|
||||
*
|
||||
* The default binding for this signal is F8.
|
||||
* The default binding for this signal is <kbd>F8</kbd>.
|
||||
*/
|
||||
signals [CYCLE_HANDLE_FOCUS] =
|
||||
g_signal_new (I_("cycle-handle-focus"),
|
||||
@@ -655,7 +657,8 @@ gtk_paned_class_init (GtkPanedClass *class)
|
||||
*
|
||||
* This is a [keybinding signal](class.SignalAction.html).
|
||||
*
|
||||
* The default binding for this signal is Return or Space.
|
||||
* The default binding for this signal is <kbd>Return</kbd> or
|
||||
* <kbd>Space</kbd>.
|
||||
*/
|
||||
signals [ACCEPT_POSITION] =
|
||||
g_signal_new (I_("accept-position"),
|
||||
@@ -678,7 +681,7 @@ gtk_paned_class_init (GtkPanedClass *class)
|
||||
*
|
||||
* This is a [keybinding signal](class.SignalAction.html).
|
||||
*
|
||||
* The default binding for this signal is Escape.
|
||||
* The default binding for this signal is <kbd>Escape</kbd>.
|
||||
*/
|
||||
signals [CANCEL_POSITION] =
|
||||
g_signal_new (I_("cancel-position"),
|
||||
@@ -1555,7 +1558,7 @@ gtk_paned_css_changed (GtkWidget *widget,
|
||||
*
|
||||
* Creates a new `GtkPaned` widget.
|
||||
*
|
||||
* Returns: a new `GtkPaned`.
|
||||
* Returns: the newly created paned widget
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_paned_new (GtkOrientation orientation)
|
||||
@@ -1568,9 +1571,11 @@ gtk_paned_new (GtkOrientation orientation)
|
||||
/**
|
||||
* gtk_paned_set_start_child: (attributes org.gtk.Method.set_property=start-child)
|
||||
* @paned: a `GtkPaned`
|
||||
* @child: the widget to add
|
||||
* @child: (nullable): the widget to add
|
||||
*
|
||||
* Sets the start child of @paned to @child.
|
||||
*
|
||||
* If @child is `NULL`, the existing child will be removed.
|
||||
*/
|
||||
void
|
||||
gtk_paned_set_start_child (GtkPaned *paned,
|
||||
@@ -1596,8 +1601,6 @@ gtk_paned_set_start_child (GtkPaned *paned,
|
||||
*
|
||||
* Retrieves the start child of the given `GtkPaned`.
|
||||
*
|
||||
* See also: `GtkPaned`:start-child
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the start child widget
|
||||
*/
|
||||
GtkWidget *
|
||||
@@ -1611,9 +1614,9 @@ gtk_paned_get_start_child (GtkPaned *paned)
|
||||
/**
|
||||
* gtk_paned_set_resize_start_child: (attributes org.gtk.Method.set_property=resize-start-child)
|
||||
* @paned: a `GtkPaned`
|
||||
* @resize: %TRUE to let the start child be resized
|
||||
* @resize: true to let the start child be resized
|
||||
*
|
||||
* Sets the `GtkPaned`:resize-start-child property
|
||||
* Sets whether the [property@Gtk.Paned:start-child] can be resized.
|
||||
*/
|
||||
void
|
||||
gtk_paned_set_resize_start_child (GtkPaned *paned,
|
||||
@@ -1633,9 +1636,9 @@ gtk_paned_set_resize_start_child (GtkPaned *paned,
|
||||
* gtk_paned_get_resize_start_child: (attributes org.gtk.Method.get_property=resize-start-child)
|
||||
* @paned: a `GtkPaned`
|
||||
*
|
||||
* Returns whether the start child can be resized.
|
||||
* Returns whether the [property@Gtk.Paned:start-child] can be resized.
|
||||
*
|
||||
* Returns: %TRUE if the start child is resizable
|
||||
* Returns: true if the start child is resizable
|
||||
*/
|
||||
gboolean
|
||||
gtk_paned_get_resize_start_child (GtkPaned *paned)
|
||||
@@ -1648,9 +1651,9 @@ gtk_paned_get_resize_start_child (GtkPaned *paned)
|
||||
/**
|
||||
* gtk_paned_set_shrink_start_child: (attributes org.gtk.Method.set_property=shrink-start-child)
|
||||
* @paned: a `GtkPaned`
|
||||
* @resize: %TRUE to let the start child be shrunk
|
||||
* @resize: true to let the start child be shrunk
|
||||
*
|
||||
* Sets the `GtkPaned`:shrink-start-child property
|
||||
* Sets whether the [property@Gtk.Paned:start-child] can shrink.
|
||||
*/
|
||||
void
|
||||
gtk_paned_set_shrink_start_child (GtkPaned *paned,
|
||||
@@ -1670,9 +1673,9 @@ gtk_paned_set_shrink_start_child (GtkPaned *paned,
|
||||
* gtk_paned_get_shrink_start_child: (attributes org.gtk.Method.get_property=shrink-start-child)
|
||||
* @paned: a `GtkPaned`
|
||||
*
|
||||
* Returns whether the start child can be shrunk.
|
||||
* Returns whether the [property@Gtk.Paned:start-child] can shrink.
|
||||
*
|
||||
* Returns: %TRUE if the start child is shrinkable
|
||||
* Returns: true if the start child is shrinkable
|
||||
*/
|
||||
gboolean
|
||||
gtk_paned_get_shrink_start_child (GtkPaned *paned)
|
||||
@@ -1685,9 +1688,11 @@ gtk_paned_get_shrink_start_child (GtkPaned *paned)
|
||||
/**
|
||||
* gtk_paned_set_end_child: (attributes org.gtk.Method.set_property=end-child)
|
||||
* @paned: a `GtkPaned`
|
||||
* @child: the widget to add
|
||||
* @child: (nullable): the widget to add
|
||||
*
|
||||
* Sets the end child of @paned to @child.
|
||||
*
|
||||
* If @child is `NULL`, the existing child will be removed.
|
||||
*/
|
||||
void
|
||||
gtk_paned_set_end_child (GtkPaned *paned,
|
||||
@@ -1713,8 +1718,6 @@ gtk_paned_set_end_child (GtkPaned *paned,
|
||||
*
|
||||
* Retrieves the end child of the given `GtkPaned`.
|
||||
*
|
||||
* See also: `GtkPaned`:end-child
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the end child widget
|
||||
*/
|
||||
GtkWidget *
|
||||
@@ -1728,9 +1731,9 @@ gtk_paned_get_end_child (GtkPaned *paned)
|
||||
/**
|
||||
* gtk_paned_set_resize_end_child: (attributes org.gtk.Method.set_property=resize-end-child)
|
||||
* @paned: a `GtkPaned`
|
||||
* @resize: %TRUE to let the end child be resized
|
||||
* @resize: true to let the end child be resized
|
||||
*
|
||||
* Sets the `GtkPaned`:resize-end-child property
|
||||
* Sets whether the [property@Gtk.Paned:end-child] can be resized.
|
||||
*/
|
||||
void
|
||||
gtk_paned_set_resize_end_child (GtkPaned *paned,
|
||||
@@ -1750,9 +1753,9 @@ gtk_paned_set_resize_end_child (GtkPaned *paned,
|
||||
* gtk_paned_get_resize_end_child: (attributes org.gtk.Method.get_property=resize-end-child)
|
||||
* @paned: a `GtkPaned`
|
||||
*
|
||||
* Returns whether the end child can be resized.
|
||||
* Returns whether the [property@Gtk.Paned:end-child] can be resized.
|
||||
*
|
||||
* Returns: %TRUE if the end child is resizable
|
||||
* Returns: true if the end child is resizable
|
||||
*/
|
||||
gboolean
|
||||
gtk_paned_get_resize_end_child (GtkPaned *paned)
|
||||
@@ -1765,9 +1768,9 @@ gtk_paned_get_resize_end_child (GtkPaned *paned)
|
||||
/**
|
||||
* gtk_paned_set_shrink_end_child: (attributes org.gtk.Method.set_property=shrink-end-child)
|
||||
* @paned: a `GtkPaned`
|
||||
* @resize: %TRUE to let the end child be shrunk
|
||||
* @resize: true to let the end child be shrunk
|
||||
*
|
||||
* Sets the `GtkPaned`:shrink-end-child property
|
||||
* Sets whether the [property@Gtk.Paned:end-child] can shrink.
|
||||
*/
|
||||
void
|
||||
gtk_paned_set_shrink_end_child (GtkPaned *paned,
|
||||
@@ -1787,9 +1790,9 @@ gtk_paned_set_shrink_end_child (GtkPaned *paned,
|
||||
* gtk_paned_get_shrink_end_child: (attributes org.gtk.Method.get_property=shrink-end-child)
|
||||
* @paned: a `GtkPaned`
|
||||
*
|
||||
* Returns whether the end child can be shrunk.
|
||||
* Returns whether the [property@Gtk.Paned:end-child] can shrink.
|
||||
*
|
||||
* Returns: %TRUE if the end child is shrinkable
|
||||
* Returns: true if the end child is shrinkable
|
||||
*/
|
||||
gboolean
|
||||
gtk_paned_get_shrink_end_child (GtkPaned *paned)
|
||||
@@ -1805,7 +1808,7 @@ gtk_paned_get_shrink_end_child (GtkPaned *paned)
|
||||
*
|
||||
* Obtains the position of the divider between the two panes.
|
||||
*
|
||||
* Returns: position of the divider
|
||||
* Returns: the position of the divider, in pixels
|
||||
**/
|
||||
int
|
||||
gtk_paned_get_position (GtkPaned *paned)
|
||||
@@ -1822,7 +1825,7 @@ gtk_paned_get_position (GtkPaned *paned)
|
||||
* is unset
|
||||
*
|
||||
* Sets the position of the divider between the two panes.
|
||||
**/
|
||||
*/
|
||||
void
|
||||
gtk_paned_set_position (GtkPaned *paned,
|
||||
int position)
|
||||
|
||||
@@ -921,7 +921,8 @@ create_cloud_provider_account_row (GtkPlacesSidebar *sidebar,
|
||||
|
||||
g_free (tooltip);
|
||||
g_free (mount_uri);
|
||||
g_object_unref (end_icon);
|
||||
g_clear_object (&end_icon);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user