Compare commits
252 Commits
path-tests
...
gir-test
| Author | SHA1 | Date | |
|---|---|---|---|
| 90da50857c | |||
| b27b58f0d9 | |||
| b8f984e214 | |||
| 31267f1c48 | |||
| f0db36677b | |||
| bbfaacb598 | |||
| d89ff71819 | |||
| 141c725489 | |||
| bbc3aa4ff9 | |||
| f7856f29fd | |||
| 7b69c58deb | |||
| f60d245e32 | |||
| f04e5bd590 | |||
| 90c428b4a7 | |||
| 97b5fad131 | |||
| 285a91715d | |||
| 880468f5a3 | |||
| 6ddbb2a402 | |||
| 7eab565225 | |||
| b34101d45d | |||
| 6c21a7be0b | |||
| a6f2bcb220 | |||
| ef0db01d5c | |||
| ef33ec639c | |||
| 27ca4434e2 | |||
| 9861c7d25c | |||
| 13ef82fc4d | |||
| b33ca43e14 | |||
| 39e07a8d56 | |||
| 5286743cbe | |||
| 58bb998ef0 | |||
| a56b2900dd | |||
| ff34124394 | |||
| 03b60a2d5e | |||
| d939d04885 | |||
| 73fb28a058 | |||
| 65eaf8e8c4 | |||
| beeedb5141 | |||
| 1d40750a60 | |||
| 96baf9769a | |||
| 5044031b53 | |||
| 9f7119ee58 | |||
| c514c41d0e | |||
| 45848c5298 | |||
| 8c61038b9f | |||
| b5cb2f7e41 | |||
| 8af0d4b51f | |||
| 378ad75d48 | |||
| 01d19e2aa4 | |||
| 64e16ecaf1 | |||
| 6a047e53a8 | |||
| 31a7bc70c9 | |||
| 874cae1dab | |||
| 7a3dd41dba | |||
| 149962670a | |||
| 849e3c8b4b | |||
| c9807f5afe | |||
| 9a9899597c | |||
| fecb7af66e | |||
| f5efb15cba | |||
| d7d4fed0f3 | |||
| c2c2635763 | |||
| fb33e83c96 | |||
| 291ad17a22 | |||
| 0f052d46b2 | |||
| 506423cf23 | |||
| 946a496a2e | |||
| d20526570b | |||
| 8312b9d9ca | |||
| 992f092968 | |||
| 60835227a1 | |||
| 2b6b35d91f | |||
| 897164c66c | |||
| 441d944c08 | |||
| 2b8ad6c4b5 | |||
| 99b2da4c47 | |||
| 8243b5493b | |||
| d5ef906cff | |||
| a720d8bc79 | |||
| 57691eacc5 | |||
| 526e24f5b1 | |||
| 2a79152762 | |||
| f03acaf7ab | |||
| 4e7ce9edcf | |||
| ff72619333 | |||
| 59692599ea | |||
| 4761641098 | |||
| afaa275dc8 | |||
| c736deb83b | |||
| e930a20522 | |||
| 137f32f9ef | |||
| 195b98f19a | |||
| 87e0a28482 | |||
| 3ca3d7efef | |||
| d8d8322912 | |||
| 1ea1a70fd2 | |||
| 1d5bc2838b | |||
| 45ec3fc389 | |||
| 3a5eee7dbe | |||
| 0cda6f42b8 | |||
| 0d99ef7cee | |||
| 7583810c90 | |||
| 1341bc0b19 | |||
| fd073deea9 | |||
| 5652ab0a61 | |||
| 2ff23b08be | |||
| 0336af06f1 | |||
| 2af9f1ad62 | |||
| e657da6658 | |||
| fd00aa98ea | |||
| de8a8d7bde | |||
| eb6fbf907f | |||
| 4035f86b6d | |||
| 855b44f2ed | |||
| f2e0097cac | |||
| 7c9bc7a204 | |||
| f4f104c9f9 | |||
| 28a6f0df05 | |||
| 0eab4deab0 | |||
| 6e8e467cc9 | |||
| ca9801f5fb | |||
| 6b6fc1e5d8 | |||
| e3641d0568 | |||
| a5b88a53c2 | |||
| e4d0114e0d | |||
| f974c5343e | |||
| bc39da0619 | |||
| 1995b7f34b | |||
| 36eb7c40d0 | |||
| 56af472cfc | |||
| d1fcfa58b9 | |||
| cf23324749 | |||
| b79c26b39e | |||
| 532b8c71a8 | |||
| 7c5b8911d8 | |||
| e141d61593 | |||
| 9595d440cf | |||
| 1063924bd0 | |||
| 42fedfc870 | |||
| 24836c0351 | |||
| 21b6c8b5d8 | |||
| 41fb6f6a8e | |||
| 071ea6b559 | |||
| 397a71ca8b | |||
| 40c10f83e2 | |||
| fb31581bb4 | |||
| 536a67ec96 | |||
| 53fe751371 | |||
| 7901ab857b | |||
| 8f585f7a53 | |||
| 874b19b27e | |||
| fe7b11b4e9 | |||
| cf623ce774 | |||
| 36b49950e8 | |||
| 77feb51b9c | |||
| 710ef00dfe | |||
| 0c8124828f | |||
| 0605c3c167 | |||
| 93d795e7c0 | |||
| d55f938f7c | |||
| 45bb4dc80c | |||
| 53af35d256 | |||
| 51a6b29e01 | |||
| e3835476ba | |||
| 256b094b13 | |||
| 699adb0b10 | |||
| c91b5eaa41 | |||
| 7e1f20bf4c | |||
| f9fe640905 | |||
| 34ea99006f | |||
| 06cce81a97 | |||
| 4a1a7940d5 | |||
| 1108d00014 | |||
| 034672e84e | |||
| 00c885c93c | |||
| 114f0bd8d6 | |||
| 24c67efdfd | |||
| 6a3748146d | |||
| 92ec754737 | |||
| d11fbbc478 | |||
| f11f0da11c | |||
| ebdf2989f8 | |||
| bc35c5d494 | |||
| 70a3e5e8ce | |||
| 74ff61a937 | |||
| 280d7e57bd | |||
| 03f5a368ec | |||
| 0b15aba82a | |||
| d8fa9de93a | |||
| afabbc4957 | |||
| d978ba31d6 | |||
| 71efa96ef2 | |||
| e336fe2bf8 | |||
| d7f15c15e9 | |||
| fff570538c | |||
| 38166a67c7 | |||
| 01b94db73d | |||
| c804645382 | |||
| 384081ce0a | |||
| afccb86f7e | |||
| 0ba5631100 | |||
| c72589f0ee | |||
| f2e5775380 | |||
| a7164208d3 | |||
| 20f3d1608d | |||
| 9320148d71 | |||
| ad617a0e06 | |||
| 62af8365f6 | |||
| 29afe5a688 | |||
| 2d3885a44a | |||
| 75a297632e | |||
| 572649740e | |||
| b5938faa06 | |||
| a4baac7193 | |||
| bdde41e290 | |||
| d888402bf9 | |||
| 378bd9fab2 | |||
| 4ad5e77907 | |||
| 4fb70c5e4d | |||
| d5963ad109 | |||
| b5fe434fea | |||
| 224c2674ab | |||
| 878b34fae3 | |||
| 5fe433418d | |||
| 02ba9bc1da | |||
| 2336120010 | |||
| 0d54d73a51 | |||
| 6c09832b9b | |||
| 1758f88492 | |||
| 34ffdc6e3f | |||
| 108933b655 | |||
| 3344bcaf92 | |||
| f22ec063a1 | |||
| 0fcf01ddd5 | |||
| 1119a74ff0 | |||
| 18ea60e235 | |||
| d752828977 | |||
| 1034271d9a | |||
| f013d3b5d6 | |||
| 5f41d26abc | |||
| 7d5826ccf7 | |||
| daded2bc86 | |||
| bc7619abaf | |||
| 459d6e1349 | |||
| 6e108d310a | |||
| cf20cfd31e | |||
| 6bd0dc3e78 | |||
| 4f0c920a8e | |||
| b0b793dd94 | |||
| efbb649eee | |||
| 90dfb5e138 | |||
| 0d2ea14ac1 |
@@ -22,9 +22,9 @@ stages:
|
||||
variables:
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dintrospection=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v25"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v26"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v25"
|
||||
|
||||
@@ -43,6 +43,7 @@ style-check-diff:
|
||||
- .gitlab-ci/run-style-check-diff.sh
|
||||
|
||||
.build-fedora-default:
|
||||
extends: .only-default
|
||||
image: $FEDORA_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -121,6 +122,7 @@ installed-tests:
|
||||
|
||||
|
||||
.mingw-defaults:
|
||||
extends: .only-default
|
||||
stage: build
|
||||
tags:
|
||||
- win32-ps
|
||||
@@ -144,6 +146,31 @@ msys2-mingw64:
|
||||
MSYSTEM: "MINGW64"
|
||||
CHERE_INVOKING: "yes"
|
||||
|
||||
macos:
|
||||
extends: .only-default
|
||||
only:
|
||||
- branches@GNOME/gtk
|
||||
stage: build
|
||||
tags:
|
||||
- macos
|
||||
needs: []
|
||||
before_script:
|
||||
- bash .gitlab-ci/show-execution-environment.sh
|
||||
- pip3 install --user meson==0.56
|
||||
- pip3 install --user ninja
|
||||
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||
script:
|
||||
- meson -Dx11-backend=false
|
||||
-Dintrospection=disabled
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
_build
|
||||
- ninja -C _build
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
|
||||
.flatpak-defaults:
|
||||
image: $FLATPAK_IMAGE
|
||||
stage: flatpak
|
||||
|
||||
@@ -71,6 +71,7 @@ RUN dnf -y install \
|
||||
pcre-devel \
|
||||
pcre-static \
|
||||
python3 \
|
||||
python3-gobject \
|
||||
python3-jinja2 \
|
||||
python3-pip \
|
||||
python3-pygments \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v25
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v26
|
||||
|
||||
# Enable sudo for wheel users
|
||||
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eux -o pipefail
|
||||
|
||||
xcodebuild -version || :
|
||||
xcodebuild -showsdks || :
|
||||
|
||||
system_profiler SPSoftwareDataType || :
|
||||
@@ -1,3 +1,83 @@
|
||||
Overview of Changes in 4.0.1
|
||||
============================
|
||||
|
||||
* GtkPopover
|
||||
- Center titles
|
||||
- Fix menu item alignment with submenus
|
||||
|
||||
* GtkVideo
|
||||
- Fix up autoplay semantics
|
||||
- Respect pixel aspect ratio
|
||||
- Get GL textures from gstreamer
|
||||
|
||||
* GtkCenterLayout
|
||||
- Fix handling of expanding center child
|
||||
|
||||
* GtkSettings
|
||||
- Change gtk-cursor-aspect-ratio to double
|
||||
- Fix the default value of gtk-print-backends
|
||||
|
||||
* GtkGestureStylus
|
||||
- Convert motion history to surface coordinates
|
||||
|
||||
* GL renderer
|
||||
- Various optimizations
|
||||
- Avoid leaking shader objects
|
||||
|
||||
* Adwaita
|
||||
- Fine-tune flat buttons
|
||||
- Improve contrast of dim-label
|
||||
- Improve contrast of controls in headers
|
||||
|
||||
* Docs
|
||||
- Add various missing types
|
||||
- Add DND examples
|
||||
- Correct css docs for several widgets
|
||||
- Improve GtkVideo docs
|
||||
- Update migration docs for GtkClipboard
|
||||
- Improve migration docs for event controllers
|
||||
- Add migration docs for GtkBuilder
|
||||
|
||||
* gtk4-builder-tool
|
||||
- Remove GtkCheckButton::draw-indicator
|
||||
- Fix a buffer overrun
|
||||
- Remove GtkToolbar::toolbar-style
|
||||
|
||||
* Demos
|
||||
- Don't put the search bar in the scroll area
|
||||
- Make the OpenGL demos work with OpenGL ES
|
||||
|
||||
* X11
|
||||
- Fix a possible crash
|
||||
|
||||
* Build
|
||||
- Fix vulkan reference in pc file
|
||||
- Fix build with certain Vulkan versions
|
||||
|
||||
* Windows:
|
||||
- Fix build with Visual Studio 2013
|
||||
|
||||
* OS X:
|
||||
- Fix build on OS X
|
||||
- Fix crash on Mojave
|
||||
- Fix a window sizing issue
|
||||
- Fix build on OS X 10.12
|
||||
- Add a CI build
|
||||
|
||||
* Translation updates:
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
Catalan
|
||||
Galician
|
||||
German
|
||||
Japanese
|
||||
Lithuanian
|
||||
Persian
|
||||
Punjabi
|
||||
Romanian
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in GTK 4.0
|
||||
==============================
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from pathlib import PurePath
|
||||
import subprocess
|
||||
|
||||
stylesheets = [ 'gtk/theme/Adwaita/Adwaita.css',
|
||||
'gtk/theme/Adwaita/Adwaita-dark.css',
|
||||
'gtk/theme/HighContrast/HighContrast.css',
|
||||
'gtk/theme/HighContrast/HighContrast-inverse.css' ]
|
||||
|
||||
sourceroot = os.environ.get('MESON_SOURCE_ROOT')
|
||||
distroot = os.environ.get('MESON_DIST_ROOT')
|
||||
|
||||
for stylesheet in stylesheets:
|
||||
stylesheet_path = PurePath(stylesheet)
|
||||
src = PurePath(sourceroot, stylesheet_path.with_suffix('.scss'))
|
||||
dst = PurePath(distroot, stylesheet_path)
|
||||
subprocess.call(['sassc', '-a', '-M', '-t', 'compact', src, dst])
|
||||
@@ -98,6 +98,9 @@ create_page1 (GtkWidget *assistant)
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
|
||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
|
||||
-1);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
|
||||
@@ -119,13 +119,12 @@ create_label (void)
|
||||
static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
|
||||
GtkWidget *w = gtk_video_new ();
|
||||
|
||||
gtk_widget_set_size_request (w, 64, 64);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
gtk_video_set_loop (GTK_VIDEO (w), TRUE);
|
||||
gtk_video_set_autoplay (GTK_VIDEO (w), TRUE);
|
||||
gtk_video_set_resource (GTK_VIDEO (w), "/images/gtk-logo.webm");
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
@@ -787,6 +787,8 @@ gtk_gears_realize (GtkWidget *widget)
|
||||
glLinkProgram(program);
|
||||
glGetProgramInfoLog(program, sizeof msg, NULL, msg);
|
||||
g_debug ("program info: %s\n", msg);
|
||||
glDetachShader (program, v);
|
||||
glDetachShader (program, f);
|
||||
glDeleteShader (v);
|
||||
glDeleteShader (f);
|
||||
|
||||
|
||||
@@ -3298,7 +3298,6 @@ bad things might happen.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="basement-indicators"/>
|
||||
<menu id="new_style_menu_model">
|
||||
<section>
|
||||
<attribute name="display-hint">circular-buttons</attribute>
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
@@ -146,6 +146,9 @@ images = [
|
||||
'images/nwse_resize_cursor.png',
|
||||
'images/zoom_in_cursor.png',
|
||||
'images/zoom_out_cursor.png',
|
||||
'images/popup-anchors.png',
|
||||
'images/popup-flip.png',
|
||||
'images/popup-slide.png',
|
||||
]
|
||||
|
||||
src_dir = [ gdkinc ]
|
||||
|
||||
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
@@ -41,35 +41,41 @@
|
||||
<command>gtk4-builder-tool</command> can perform various operations
|
||||
on GtkBuilder .ui files.
|
||||
</para>
|
||||
<para>
|
||||
The <option>validate</option> command validates the .ui file and reports
|
||||
errors to stderr.
|
||||
</para>
|
||||
<para>
|
||||
The <option>enumerate</option> command lists all the named objects that
|
||||
are created in the .ui file.
|
||||
</para>
|
||||
<para>
|
||||
The <option>preview</option> command displays the .ui file. This command
|
||||
accepts options to specify the ID of the toplevel object and a .css file
|
||||
to use.
|
||||
</para>
|
||||
<para>
|
||||
The <option>simplify</option> command simplifies the .ui file by removing
|
||||
properties that are set to their default values and writes the resulting XML
|
||||
to stdout, or back to the input file.
|
||||
</para>
|
||||
<para>
|
||||
When the <option>--3to4</option> is specified, <option>simplify</option>
|
||||
interprets the input as a GTK 3 ui file and attempts to convert it to GTK 4
|
||||
equivalents. It performs various conversions, such as renaming properties,
|
||||
translating child properties to layout properties, rewriting the setup for
|
||||
GtkNotebook, GtkStack, GtkAssistant or changing toolbars into boxes.
|
||||
</para>
|
||||
<para>
|
||||
You should always test the modified .ui files produced by gtk4-builder-tool
|
||||
before using them in production.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Commands</title>
|
||||
<para>The following commands are understood:</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>validate</option></term>
|
||||
<listitem><para>Validates the .ui file and report errors to stderr.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>simplify</option></term>
|
||||
<listitem><para>Simplifies the .ui file by removing properties that
|
||||
are set to their default values and write the resulting XML to stdout,
|
||||
or back to the input file.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>enumerate</option></term>
|
||||
<listitem><para>Lists all the named objects that are created in the .ui file.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>preview</option></term>
|
||||
<listitem><para>Preview the .ui file. This command accepts options
|
||||
to specify the ID of an object and a .css file to use.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
Note in particular that the conversion
|
||||
done with <option>--3to4</option> is meant as a starting point for a port
|
||||
from GTK 3 to GTK 4. It is expected that you will have to do manual fixups
|
||||
after the initial conversion.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Simplify Options</title>
|
||||
|
||||
@@ -61,6 +61,13 @@
|
||||
<listitem><para>Write png files to <replaceable>DIRECTORY</replaceable>
|
||||
instead of the current working directory.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--debug</term>
|
||||
<listitem><para>Generate png files of the various channels during
|
||||
the conversion. If these files are not monochrome green, they
|
||||
are often helpful in pinpointing the problematic parts of
|
||||
the source svg.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -4668,7 +4668,6 @@ GTK_WINDOW_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkWindowPrivate
|
||||
gtk_window_get_type
|
||||
GtkWindowGeometryInfo
|
||||
gtk_window_remove_embedded_xid
|
||||
gtk_window_add_embedded_xid
|
||||
GtkWindowKeysForeachFunc
|
||||
|
||||
@@ -413,10 +413,6 @@ images = [
|
||||
'images/password-entry.png',
|
||||
'images/picture.png',
|
||||
'images/popover.png',
|
||||
'images/popup-anchors.png',
|
||||
'images/popup-at.svg',
|
||||
'images/popup-flip.png',
|
||||
'images/popup-slide.png',
|
||||
'images/printdialog.png',
|
||||
'images/progressbar.png',
|
||||
'images/right-center.png',
|
||||
|
||||
@@ -165,11 +165,11 @@ for this change.
|
||||
| ::key-release-event | #GtkEventControllerKey |
|
||||
| ::enter-notify-event | #GtkEventControllerMotion |
|
||||
| ::leave-notify-event | #GtkEventControllerMotion |
|
||||
| ::configure-event | replaced by #GdkSurface::layout |
|
||||
| ::configure-event | - |
|
||||
| ::focus-in-event | #GtkEventControllerFocus |
|
||||
| ::focus-out-event | #GtkEventControllerFocus |
|
||||
| ::map-event | replaced by #GdkSurface:mapped |
|
||||
| ::unmap-event | replaced by #GdkSurface:mapped |
|
||||
| ::map-event | - |
|
||||
| ::unmap-event | - |
|
||||
| ::property-notify-event | replaced by #GdkClipboard |
|
||||
| ::selection-clear-event | replaced by #GdkClipboard |
|
||||
| ::selection-request-event | replaced by #GdkClipboard |
|
||||
@@ -178,10 +178,17 @@ for this change.
|
||||
| ::proximity-in-event | #GtkGestureStylus |
|
||||
| ::proximity-out-event | #GtkGestureStylus |
|
||||
| ::visibility-notify-event | - |
|
||||
| ::window-state-event | replaced by #GdkToplevel:state |
|
||||
| ::window-state-event | - |
|
||||
| ::damage-event | - |
|
||||
| ::grab-broken-event | - |
|
||||
|
||||
Event signals which are not directly related to input have to be dealt
|
||||
with on a one-by-one basis. If you were using ::configure-event and
|
||||
::window-state-event to save window state, you should use property
|
||||
notification for corresponding GtkWindow properties, such as
|
||||
#GtkWindow:default-width, #GtkWindow:default-height, #GtkWindow:maximized
|
||||
or #GtkWindow:fullscreened.
|
||||
|
||||
### Set a proper application ID
|
||||
|
||||
In GTK 4 we want the application's #GApplication 'application-id'
|
||||
@@ -264,14 +271,6 @@ therefore can no longer be used to break reference cycles. A typical sign
|
||||
of a reference cycle involving a toplevel window is when closing the window
|
||||
does not make the application quit.
|
||||
|
||||
A good rule to follow is: If you set a widget pointer with
|
||||
gtk_widget_class_bind_template_child() in class_init(), you need to
|
||||
unparent it in dispose(). The slight complication here is that you need
|
||||
to respect the widget hierarchy while doing so. Ie if you set both `field1`
|
||||
and `field2`, but `field1` is an ancestor of `field2`, then you only need
|
||||
to unparent `field1` — doing so will remove the the entire subtree below
|
||||
`field1`, including `field2`.
|
||||
|
||||
### Stop using GdkScreen
|
||||
|
||||
The GdkScreen object has been removed in GTK 4. Most of its APIs already
|
||||
@@ -407,7 +406,7 @@ and gdk_keymap_get_entries_for_keyval().
|
||||
GTK 3 has the idea that use of modifiers may differ between different
|
||||
platforms, and has a #GdkModifierIntent api to let platforms provide
|
||||
hint about how modifiers are expected to be used. It also promoted
|
||||
the use of <Primary> instead of <Control> to specify accelerators that
|
||||
the use of `<Primary>` instead of `<Control>` to specify accelerators that
|
||||
adapt to platform conventions.
|
||||
|
||||
In GTK 4, the meaning of modifiers has been fixed, and backends are
|
||||
@@ -426,13 +425,88 @@ GDK_CONTROL_MASK|GDK_ALT_MASK
|
||||
: Prevent text input
|
||||
|
||||
Consequently, #GdkModifierIntent and related APIs have been removed,
|
||||
and <Control> is preferred over <Primary> in accelerators.
|
||||
and `<Control>` is preferred over `<Primary>` in accelerators.
|
||||
|
||||
A related change is that GTK 4 no longer supports the use of archaic
|
||||
X11 'real' modifiers with the names Mod1,..., Mod5, and %GDK_MOD1_MASK
|
||||
has been renamed to %GDK_ALT_MASK.
|
||||
|
||||
### Stop using gtk_get_current_... APIs
|
||||
### Replace GtkClipboard with GdkClipboard
|
||||
|
||||
The `GtkClipboard` API has been removed, and replaced by #GdkClipboard.
|
||||
There is not direct 1:1 mapping between the old an the new API, so it cannot
|
||||
be a mechanical replacement; the new API is based on object types and #GValue
|
||||
like object properties, instead of opaque identifiers, so it should be easier
|
||||
to use.
|
||||
|
||||
For instance, the example below copies the contents of an entry into the
|
||||
clipboard:
|
||||
|
||||
```
|
||||
static void
|
||||
copy_text (GtkWidget *widget)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (widget);
|
||||
|
||||
// Initialize a GValue with the contents of the widget
|
||||
GValue value = G_VALUE_INIT;
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_string (&value, gtk_editable_get_text (editable));
|
||||
|
||||
// Store the value in the clipboard object
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
gdk_clipboard_set_value (clipboard, &value);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
```
|
||||
|
||||
whereas the example below pastes the contents into the entry:
|
||||
|
||||
```
|
||||
static void
|
||||
paste_text (GtkWidget *widget)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (widget);
|
||||
|
||||
// Initialize a GValue to receive text
|
||||
GValue value = G_VALUE_INIT;
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
|
||||
// Get the content provider for the clipboard, and ask it for text
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
GdkContentProvider *provider = gdk_clipboard_get_content (clipboard);
|
||||
|
||||
// If the content provider does not contain text, we are not interested
|
||||
if (!gdk_content_provider_get_value (provider, &value, NULL))
|
||||
return;
|
||||
|
||||
const char *str = g_value_get_string (&value);
|
||||
|
||||
gtk_editable_set_text (editable, str);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
```
|
||||
|
||||
The convenience API for specific target types in `GtkClipboard` has been
|
||||
replaced by their corresponding GType:
|
||||
|
||||
| GtkClipboard | GType |
|
||||
| ----------------------------------- | ---------------------- |
|
||||
| `gtk_clipboard_request_text()` | `G_TYPE_STRING` |
|
||||
| `gtk_clipboard_request_rich_text()` | `GTK_TYPE_TEXT_BUFFER` |
|
||||
| `gtk_clipboard_request_image()` | `GDK_TYPE_PIXBUF` |
|
||||
| `gtk_clipboard_request_uris()` |` GDK_TYPE_FILE_LIST` |
|
||||
|
||||
**Note**: Support for rich text serialization across different processes
|
||||
for #GtkTextBuffer is not available any more.
|
||||
|
||||
If you are copying the contents of an image, it is recommended to use
|
||||
GDK_TYPE_PAINTABLE instead of GDK_TYPE_PIXBUF, to minimize the amount of
|
||||
potential copies.
|
||||
|
||||
### Stop using `gtk_get_current_...` APIs
|
||||
|
||||
The function gtk_get_current_event() and its variants have been
|
||||
replaced by equivalent event controller APIs:
|
||||
@@ -448,6 +522,25 @@ option. You should always review the resulting changes.
|
||||
The <requires> tag now supports for the 'lib' attribute the
|
||||
'gtk' value only, instead of the 'gtk+' one previously.
|
||||
|
||||
### Adapt to GtkBuilder API changes
|
||||
|
||||
gtk_builder_connect_signals() no longer exists. Instead, signals are
|
||||
always connected automatically. If you need to add user data to your
|
||||
signals, gtk_builder_set_current_object() must be called. An important
|
||||
caveat is that you have to do this before loading any XML. This means if
|
||||
you need to use gtk_builder_set_current_object(), you can no longer use
|
||||
gtk_builder_new_from_file(), gtk_builder_new_from_resource(), or
|
||||
gtk_builder_new_from_string(). Instead, you must use vanilla gtk_builder_new(),
|
||||
then call gtk_builder_set_current_object(), then load the XML using
|
||||
gtk_builder_add_from_file(), gtk_builder_add_from_resource(), or
|
||||
gtk_builder_add_from_string(). You must check the return value for
|
||||
failure and manually abort with g_error() if something went wrong.
|
||||
|
||||
You only have to worry about this if you were previously using
|
||||
gtk_builder_connect_signals(). If you are using templates, then
|
||||
gtk_widget_init_template() will call gtk_builder_set_current_object()
|
||||
for you, so templates work like before.
|
||||
|
||||
### Adapt to event controller API changes
|
||||
|
||||
A few changes to the event controller and #GtkGesture APIs
|
||||
@@ -458,6 +551,23 @@ Another is that #GtkGestureMultiPress has been renamed to #GtkGestureClick,
|
||||
and has lost its area property. A #GtkEventControllerFocus has been
|
||||
split off from #GtkEventcontrollerKey.
|
||||
|
||||
In GTK 3, #GtkEventController:widget was a construct-only property, so
|
||||
a #GtkWidget was provided whenever constructing a #GtkEventController.
|
||||
In GTK 4, #GtkEventController:widget is now read-only. Use
|
||||
gtk_widget_add_controller() to add an event controller to a widget.
|
||||
|
||||
In GTK 3, widgets did not own their event controllers, and event
|
||||
controllers did not own their widgets, so developers were responsible
|
||||
for manually keeping event controllers alive for the lifetime of their
|
||||
associated widgets. In GTK 4, widgets own their event controllers.
|
||||
gtk_widget_add_controller() takes ownership of the event controller, so
|
||||
there is no longer any need to store a reference to the event controller
|
||||
after it has been added to a widget.
|
||||
|
||||
Although not normally needed, an event controller could be removed from
|
||||
a widget in GTK 3 by destroying the event controller with g_object_unref().
|
||||
In GTK 4, you must use gtk_widget_remove_controller().
|
||||
|
||||
### Focus handling changes
|
||||
|
||||
The semantics of the #GtkWidget:can-focus property have changed.
|
||||
@@ -751,7 +861,8 @@ to get it.
|
||||
The ::size-allocate signal has been removed, since it is easy
|
||||
to misuse. If you need to learn about sizing changes of custom
|
||||
drawing widgets, use the #GtkDrawingArea::resize or #GtkGLArea::resize
|
||||
signals.
|
||||
signals. If you want to track the size of toplevel windows, use
|
||||
property notification for #GtkWindow:default-width and #GtkWindow:default-height.
|
||||
|
||||
### Switch to GtkWidget's children APIs
|
||||
|
||||
|
||||
@@ -611,17 +611,7 @@ _gdk_device_set_associated_device (GdkDevice *device,
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
g_return_if_fail (associated == NULL || GDK_IS_DEVICE (associated));
|
||||
|
||||
if (device->associated == associated)
|
||||
return;
|
||||
|
||||
if (device->associated)
|
||||
{
|
||||
g_object_unref (device->associated);
|
||||
device->associated = NULL;
|
||||
}
|
||||
|
||||
if (associated)
|
||||
device->associated = g_object_ref (associated);
|
||||
g_set_object (&device->associated, associated);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -280,7 +280,7 @@ gdk_draw_context_get_surface (GdkDrawContext *context)
|
||||
* implementation must use gdk_draw_context_get_frame_region() to query the
|
||||
* region that must be drawn.
|
||||
*
|
||||
* When using GTK+, the widget system automatically places calls to
|
||||
* When using GTK, the widget system automatically places calls to
|
||||
* gdk_draw_context_begin_frame() and gdk_draw_context_end_frame() via the
|
||||
* use of #GskRenderers, so application code does not need to call these
|
||||
* functions explicitly.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
static gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
|
||||
@@ -210,7 +210,7 @@ gdk_event_init (GdkEvent *self)
|
||||
GType
|
||||
gdk_event_get_type (void)
|
||||
{
|
||||
static volatile gsize event_type__volatile;
|
||||
static gsize event_type__volatile;
|
||||
|
||||
if (g_once_init_enter (&event_type__volatile))
|
||||
{
|
||||
@@ -374,7 +374,7 @@ static GType gdk_event_types[GDK_EVENT_LAST];
|
||||
GType \
|
||||
type_name ## _get_type (void) \
|
||||
{ \
|
||||
static volatile gsize gdk_define_event_type_id__volatile; \
|
||||
static gsize gdk_define_event_type_id__volatile; \
|
||||
if (g_once_init_enter (&gdk_define_event_type_id__volatile)) \
|
||||
{ \
|
||||
GType gdk_define_event_type_id = \
|
||||
@@ -452,7 +452,7 @@ gdk_event_init_types_once (void)
|
||||
void
|
||||
gdk_event_init_types (void)
|
||||
{
|
||||
static volatile gsize event_types__volatile;
|
||||
static gsize event_types__volatile;
|
||||
|
||||
if (g_once_init_enter (&event_types__volatile))
|
||||
{
|
||||
|
||||
@@ -107,6 +107,9 @@ make_program (GdkGLContextProgram *program,
|
||||
|
||||
glLinkProgram (program->program);
|
||||
|
||||
glDetachShader (program->program, vertex_shader);
|
||||
glDetachShader (program->program, fragment_shader);
|
||||
|
||||
glDeleteShader (vertex_shader);
|
||||
glDeleteShader (fragment_shader);
|
||||
|
||||
|
||||
@@ -30,6 +30,37 @@
|
||||
* Popups are positioned relative to their parent surface.
|
||||
* The GdkPopupLayout struct contains information that is
|
||||
* necessary to do so.
|
||||
*
|
||||
* The positioning requires a negotiation with the windowing system,
|
||||
* since it depends on external constraints, such as the position of
|
||||
* the parent surface, and the screen dimensions.
|
||||
*
|
||||
* The basic ingredients are a rectangle on the parent surface,
|
||||
* and the anchor on both that rectangle and the popup. The anchors
|
||||
* specify a side or corner to place next to each other.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* For cases where placing the anchors next to each other would make
|
||||
* the popup extend offscreen, the layout includes some hints for how
|
||||
* to resolve this problem. The hints may suggest to flip the anchor
|
||||
* position to the other side, or to 'slide' the popup along a side,
|
||||
* or to resize it.
|
||||
*
|
||||
* 
|
||||
*
|
||||
* 
|
||||
*
|
||||
* These hints may be combined.
|
||||
*
|
||||
* Ultimatively, it is up to the windowing system to determine the position
|
||||
* and size of the popup. You can learn about the result by calling
|
||||
* gdk_popup_get_position_x(), gdk_popup_get_position_y(),
|
||||
* gdk_popup_get_rect_anchor() and gdk_popup_get_surface_anchor() after the
|
||||
* popup has been presented. This can be used to adjust the rendering. For
|
||||
* example, GtkPopover changes its arrow position accordingly. But you have
|
||||
* to be careful avoid changing the size of the popover, or it has to be
|
||||
* presented again.
|
||||
*/
|
||||
|
||||
struct _GdkPopupLayout
|
||||
|
||||
@@ -436,9 +436,10 @@ gdk_seat_tool_removed (GdkSeat *seat,
|
||||
}
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id)
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id,
|
||||
GdkDeviceToolType type)
|
||||
{
|
||||
GdkDeviceTool *match = NULL;
|
||||
GList *tools, *l;
|
||||
@@ -449,7 +450,7 @@ gdk_seat_get_tool (GdkSeat *seat,
|
||||
{
|
||||
GdkDeviceTool *tool = l->data;
|
||||
|
||||
if (tool->serial == serial && tool->hw_id == hw_id)
|
||||
if (tool->serial == serial && tool->hw_id == hw_id && tool->type == type)
|
||||
{
|
||||
match = tool;
|
||||
break;
|
||||
|
||||
@@ -49,7 +49,7 @@ struct _GdkSeatDefaultPrivate
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GdkSeatDefault, gdk_seat_default, GDK_TYPE_SEAT)
|
||||
|
||||
static void
|
||||
gdk_seat_dispose (GObject *object)
|
||||
gdk_seat_default_dispose (GObject *object)
|
||||
{
|
||||
GdkSeatDefault *seat = GDK_SEAT_DEFAULT (object);
|
||||
GdkSeatDefaultPrivate *priv = gdk_seat_default_get_instance_private (seat);
|
||||
@@ -79,11 +79,7 @@ gdk_seat_dispose (GObject *object)
|
||||
g_object_unref (l->data);
|
||||
}
|
||||
|
||||
if (priv->tools)
|
||||
{
|
||||
g_ptr_array_unref (priv->tools);
|
||||
priv->tools = NULL;
|
||||
}
|
||||
g_clear_pointer (&priv->tools, g_ptr_array_unref);
|
||||
|
||||
g_list_free (priv->physical_pointers);
|
||||
g_list_free (priv->physical_keyboards);
|
||||
@@ -307,7 +303,7 @@ gdk_seat_default_class_init (GdkSeatDefaultClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_seat_dispose;
|
||||
object_class->dispose = gdk_seat_default_dispose;
|
||||
|
||||
seat_class->get_capabilities = gdk_seat_default_get_capabilities;
|
||||
|
||||
@@ -442,7 +438,7 @@ gdk_seat_default_remove_tool (GdkSeatDefault *seat,
|
||||
|
||||
priv = gdk_seat_default_get_instance_private (seat);
|
||||
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat), tool->serial, tool->hw_id))
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat), tool->serial, tool->hw_id, tool->type))
|
||||
return;
|
||||
|
||||
g_signal_emit_by_name (seat, "tool-removed", tool);
|
||||
|
||||
@@ -75,9 +75,10 @@ void gdk_seat_tool_removed (GdkSeat *seat,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id);
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id,
|
||||
GdkDeviceToolType type);
|
||||
|
||||
GdkGrabStatus gdk_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
|
||||
@@ -316,9 +316,9 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
* @resource_path: the path of the resource file
|
||||
*
|
||||
* Creates a new texture by loading an image from a resource.
|
||||
* The file format is detected automatically, and can be any
|
||||
* format that is supported by the gdk-pixbuf library, such as
|
||||
* JPEG or PNG.
|
||||
* The file format is detected automatically.
|
||||
* The supported formats are PNG and JPEG, though more formats might be
|
||||
* available.
|
||||
*
|
||||
* It is a fatal error if @resource_path does not specify a valid
|
||||
* image resource and the program will abort if that happens.
|
||||
@@ -352,9 +352,9 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
* @error: Return location for an error
|
||||
*
|
||||
* Creates a new texture by loading an image from a file.
|
||||
* The file format is detected automatically, and can be any
|
||||
* format that is supported by the gdk-pixbuf library, such as
|
||||
* JPEG or PNG.
|
||||
* The file format is detected automatically.
|
||||
* The supported formats are PNG and JPEG, though more formats might be
|
||||
* available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
|
||||
@@ -225,7 +225,7 @@ gdk_vulkan_strerror (VkResult result)
|
||||
case VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT:
|
||||
return "A requested pipeline creation would have required compilation, but the application requested compilation to not be performed.";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION < 142
|
||||
#if VK_HEADER_VERSION < 140
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
#endif
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
|
||||
#ifndef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
typedef NSString *CALayerContentsGravity;
|
||||
#endif
|
||||
|
||||
@implementation GdkMacosWindow
|
||||
|
||||
-(BOOL)windowShouldClose:(id)sender
|
||||
@@ -466,7 +470,7 @@
|
||||
|
||||
inTrackManualResize = YES;
|
||||
|
||||
mouse_location = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
mouse_location = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
mdx = initialResizeLocation.x - mouse_location.x;
|
||||
mdy = initialResizeLocation.y - mouse_location.y;
|
||||
|
||||
@@ -588,7 +592,7 @@
|
||||
}
|
||||
|
||||
initialResizeFrame = [self frame];
|
||||
initialResizeLocation = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifndef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
typedef NSString *NSPasteboardType;
|
||||
#endif
|
||||
|
||||
#define GDK_TYPE_MACOS_CLIPBOARD (_gdk_macos_clipboard_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
|
||||
|
||||
@@ -40,8 +40,56 @@ typedef struct
|
||||
guint done : 1;
|
||||
} WriteRequest;
|
||||
|
||||
enum {
|
||||
TYPE_STRING,
|
||||
TYPE_PBOARD,
|
||||
TYPE_URL,
|
||||
TYPE_FILE_URL,
|
||||
TYPE_COLOR,
|
||||
TYPE_TIFF,
|
||||
TYPE_PNG,
|
||||
TYPE_LAST
|
||||
};
|
||||
|
||||
#define PTYPE(k) (get_pasteboard_type(TYPE_##k))
|
||||
|
||||
static NSPasteboardType pasteboard_types[TYPE_LAST];
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
|
||||
|
||||
static NSPasteboardType
|
||||
get_pasteboard_type (int type)
|
||||
{
|
||||
static gsize initialized = FALSE;
|
||||
|
||||
g_assert (type >= 0);
|
||||
g_assert (type < TYPE_LAST);
|
||||
|
||||
if (g_once_init_enter (&initialized))
|
||||
{
|
||||
pasteboard_types[TYPE_PNG] = NSPasteboardTypePNG;
|
||||
pasteboard_types[TYPE_STRING] = NSPasteboardTypeString;
|
||||
pasteboard_types[TYPE_TIFF] = NSPasteboardTypeTIFF;
|
||||
pasteboard_types[TYPE_COLOR] = NSPasteboardTypeColor;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
pasteboard_types[TYPE_PBOARD] = NSStringPboardType;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
pasteboard_types[TYPE_URL] = NSPasteboardTypeURL;
|
||||
pasteboard_types[TYPE_FILE_URL] = NSPasteboardTypeFileURL;
|
||||
#else
|
||||
pasteboard_types[TYPE_URL] = [[NSString alloc] initWithUTF8String:"public.url"];
|
||||
pasteboard_types[TYPE_FILE_URL] = [[NSString alloc] initWithUTF8String:"public.file-url"];
|
||||
#endif
|
||||
|
||||
g_once_init_leave (&initialized, TRUE);
|
||||
}
|
||||
|
||||
return pasteboard_types[type];
|
||||
}
|
||||
|
||||
static void
|
||||
write_request_free (WriteRequest *wr)
|
||||
{
|
||||
@@ -56,17 +104,17 @@ _gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:NSPasteboardTypeString] ||
|
||||
[type isEqualToString:NSStringPboardType])
|
||||
if ([type isEqualToString:PTYPE(STRING)] ||
|
||||
[type isEqualToString:PTYPE(PBOARD)])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:NSPasteboardTypeURL] ||
|
||||
[type isEqualToString:NSPasteboardTypeFileURL])
|
||||
else if ([type isEqualToString:PTYPE(URL)] ||
|
||||
[type isEqualToString:PTYPE(FILE_URL)])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:NSPasteboardTypeColor])
|
||||
else if ([type isEqualToString:PTYPE(COLOR)])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:NSPasteboardTypeTIFF])
|
||||
else if ([type isEqualToString:PTYPE(TIFF)])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:NSPasteboardTypePNG])
|
||||
else if ([type isEqualToString:PTYPE(PNG)])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
@@ -83,25 +131,25 @@ _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return NSPasteboardTypeString;
|
||||
return PTYPE(STRING);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NSPasteboardTypeURL;
|
||||
return NSPasteboardTypeFileURL;
|
||||
*alternate = PTYPE(URL);
|
||||
return PTYPE(FILE_URL);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return NSPasteboardTypeColor;
|
||||
return PTYPE(COLOR);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return NSPasteboardTypeTIFF;
|
||||
return PTYPE(TIFF);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return NSPasteboardTypePNG;
|
||||
return PTYPE(PNG);
|
||||
}
|
||||
|
||||
return nil;
|
||||
@@ -220,7 +268,7 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[self->pasteboard types] containsObject:NSPasteboardTypeFileURL])
|
||||
if ([[self->pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
@@ -267,12 +315,12 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypeTIFF];
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(TIFF)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypePNG];
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(PNG)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacoskeymap-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacosseat-private.h"
|
||||
|
||||
#define GDK_MOD2_MASK (1 << 4)
|
||||
#define GRIP_WIDTH 15
|
||||
@@ -205,6 +206,9 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
GdkSeat *seat;
|
||||
GdkEventType type;
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer = NULL;
|
||||
GdkDeviceTool *tool = NULL;
|
||||
double *axes = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (display));
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
@@ -241,16 +245,22 @@ fill_button_event (GdkMacosDisplay *display,
|
||||
y < 0 || y > GDK_SURFACE (surface)->height))
|
||||
return NULL;
|
||||
|
||||
if (([nsevent subtype] == NSEventSubtypeTabletPoint) &&
|
||||
_gdk_macos_seat_get_tablet (GDK_MACOS_SEAT (seat), &pointer, &tool))
|
||||
axes = _gdk_macos_seat_get_tablet_axes_from_nsevent (GDK_MACOS_SEAT (seat), nsevent);
|
||||
else
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
|
||||
return gdk_button_event_new (type,
|
||||
GDK_SURFACE (surface),
|
||||
gdk_seat_get_pointer (seat),
|
||||
NULL,
|
||||
pointer,
|
||||
tool,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
get_mouse_button_from_ns_event (nsevent),
|
||||
x,
|
||||
y,
|
||||
NULL);
|
||||
axes);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -557,6 +567,9 @@ fill_motion_event (GdkMacosDisplay *display,
|
||||
{
|
||||
GdkSeat *seat;
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer = NULL;
|
||||
GdkDeviceTool *tool = NULL;
|
||||
double *axes = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (nsevent != NULL);
|
||||
@@ -566,14 +579,20 @@ fill_motion_event (GdkMacosDisplay *display,
|
||||
state = get_keyboard_modifiers_from_ns_event (nsevent) |
|
||||
_gdk_macos_display_get_current_mouse_modifiers (display);
|
||||
|
||||
if (([nsevent subtype] == NSEventSubtypeTabletPoint) &&
|
||||
_gdk_macos_seat_get_tablet (GDK_MACOS_SEAT (seat), &pointer, &tool))
|
||||
axes = _gdk_macos_seat_get_tablet_axes_from_nsevent (GDK_MACOS_SEAT (seat), nsevent);
|
||||
else
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
|
||||
return gdk_motion_event_new (GDK_SURFACE (surface),
|
||||
gdk_seat_get_pointer (seat),
|
||||
NULL,
|
||||
pointer,
|
||||
tool,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
x,
|
||||
y,
|
||||
NULL);
|
||||
axes);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -700,7 +719,7 @@ get_surface_point_from_screen_point (GdkSurface *surface,
|
||||
NSPoint point;
|
||||
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
point = [nswindow convertPointFromScreen:screen_point];
|
||||
point = convert_nspoint_from_screen (nswindow, screen_point);
|
||||
|
||||
*x = point.x;
|
||||
*y = surface->height - point.y;
|
||||
@@ -762,7 +781,7 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
GdkSurface *surface = NULL;
|
||||
NSWindow *nswindow = [nsevent window];
|
||||
|
||||
if (nswindow)
|
||||
if (GDK_IS_MACOS_WINDOW (nswindow))
|
||||
{
|
||||
GdkMacosBaseView *view;
|
||||
NSPoint point, view_point;
|
||||
@@ -821,7 +840,7 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
*screen_point = [(GdkMacosWindow *)[nsevent window] convertPointToScreen:point];
|
||||
*screen_point = convert_nspoint_to_screen ([nsevent window], point);
|
||||
*x = point.x;
|
||||
*y = surface->height - point.y;
|
||||
}
|
||||
@@ -974,11 +993,11 @@ find_surface_for_ns_event (GdkMacosDisplay *self,
|
||||
g_assert (x != NULL);
|
||||
g_assert (y != NULL);
|
||||
|
||||
view = (GdkMacosBaseView *)[[nsevent window] contentView];
|
||||
|
||||
if (!(surface = get_surface_from_ns_event (self, nsevent, &point, x, y)))
|
||||
return NULL;
|
||||
|
||||
view = (GdkMacosBaseView *)[GDK_MACOS_SURFACE (surface)->window contentView];
|
||||
|
||||
_gdk_macos_display_from_display_coords (self, point.x, point.y, &x_tmp, &y_tmp);
|
||||
|
||||
switch ((int)[nsevent type])
|
||||
@@ -1051,6 +1070,23 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We need to register the proximity event from any point on the screen
|
||||
* to properly register the devices
|
||||
* FIXME: is there a better way to detect if a tablet has been plugged?
|
||||
*/
|
||||
if (event_type == NSEventTypeTabletProximity)
|
||||
{
|
||||
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
|
||||
_gdk_macos_seat_handle_tablet_tool_event (GDK_MACOS_SEAT (seat), nsevent);
|
||||
|
||||
/* FIXME: we might want to cache this proximity event and propagate it
|
||||
* but proximity events in gdk work at a window level while on macos
|
||||
* works at a screen level. For now we just skip them.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(surface = find_surface_for_ns_event (self, nsevent, &x, &y)))
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ GetSubpixelLayout (CGDirectDisplayID screen_id)
|
||||
static char *
|
||||
GetLocalizedName (NSScreen *screen)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
NSString *str;
|
||||
@@ -158,6 +159,9 @@ GetLocalizedName (NSScreen *screen)
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&name);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosseat.h"
|
||||
|
||||
#include "gdkseatprivate.h"
|
||||
|
||||
@@ -30,6 +31,16 @@ G_BEGIN_DECLS
|
||||
|
||||
GdkSeat *_gdk_macos_seat_new (GdkMacosDisplay *display);
|
||||
|
||||
void _gdk_macos_seat_handle_tablet_tool_event (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent);
|
||||
|
||||
gboolean _gdk_macos_seat_get_tablet (GdkMacosSeat *seat,
|
||||
GdkDevice **device,
|
||||
GdkDeviceTool **tool);
|
||||
|
||||
double *_gdk_macos_seat_get_tablet_axes_from_nsevent (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_SEAT_PRIVATE_H__ */
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2021 Amazon.com, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -22,42 +23,605 @@
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
#include "gdkdevicetoolprivate.h"
|
||||
|
||||
#include "gdkmacosdevice.h"
|
||||
#include "gdkmacosseat-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NSUInteger device_id;
|
||||
char *name;
|
||||
|
||||
GdkDevice *logical_device;
|
||||
GdkDevice *stylus_device;
|
||||
GdkSeat *seat;
|
||||
|
||||
GdkDeviceTool *current_tool;
|
||||
|
||||
int axis_indices[GDK_AXIS_LAST];
|
||||
double axes[GDK_AXIS_LAST];
|
||||
} GdkMacosTabletData;
|
||||
|
||||
struct _GdkMacosSeat
|
||||
{
|
||||
GdkSeat parent_instance;
|
||||
|
||||
GdkMacosDisplay *display;
|
||||
|
||||
GdkDevice *logical_pointer;
|
||||
GdkDevice *logical_keyboard;
|
||||
|
||||
GdkMacosTabletData *current_tablet;
|
||||
GPtrArray *tablets;
|
||||
GPtrArray *tools;
|
||||
};
|
||||
|
||||
struct _GdkMacosSeatClass
|
||||
{
|
||||
GdkSeatClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosSeat, gdk_macos_seat, GDK_TYPE_SEAT)
|
||||
|
||||
#define KEYBOARD_EVENTS (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | \
|
||||
GDK_FOCUS_CHANGE_MASK)
|
||||
#define TOUCH_EVENTS (GDK_TOUCH_MASK)
|
||||
#define POINTER_EVENTS (GDK_POINTER_MOTION_MASK | \
|
||||
GDK_BUTTON_PRESS_MASK | \
|
||||
GDK_BUTTON_RELEASE_MASK | \
|
||||
GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK | \
|
||||
GDK_ENTER_NOTIFY_MASK | \
|
||||
GDK_LEAVE_NOTIFY_MASK | \
|
||||
GDK_PROXIMITY_IN_MASK | \
|
||||
GDK_PROXIMITY_OUT_MASK)
|
||||
|
||||
static void
|
||||
gdk_macos_tablet_data_free (gpointer user_data)
|
||||
{
|
||||
GdkMacosTabletData *tablet = user_data;
|
||||
|
||||
gdk_seat_device_removed (GDK_SEAT (tablet->seat), tablet->stylus_device);
|
||||
gdk_seat_device_removed (GDK_SEAT (tablet->seat), tablet->logical_device);
|
||||
|
||||
_gdk_device_set_associated_device (tablet->logical_device, NULL);
|
||||
_gdk_device_set_associated_device (tablet->stylus_device, NULL);
|
||||
|
||||
g_object_unref (tablet->logical_device);
|
||||
g_object_unref (tablet->stylus_device);
|
||||
|
||||
g_free (tablet->name);
|
||||
g_free (tablet);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_dispose (GObject *object)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (object);
|
||||
|
||||
if (self->logical_pointer)
|
||||
{
|
||||
gdk_seat_device_removed (GDK_SEAT (self), self->logical_pointer);
|
||||
g_clear_object (&self->logical_pointer);
|
||||
}
|
||||
|
||||
if (self->logical_keyboard)
|
||||
{
|
||||
gdk_seat_device_removed (GDK_SEAT (self), self->logical_keyboard);
|
||||
g_clear_object (&self->logical_pointer);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->tablets, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->tools, g_ptr_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_seat_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GdkSeatCapabilities
|
||||
gdk_macos_seat_get_capabilities (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GdkSeatCapabilities caps = 0;
|
||||
|
||||
if (self->logical_pointer)
|
||||
caps |= GDK_SEAT_CAPABILITY_POINTER;
|
||||
if (self->logical_keyboard)
|
||||
caps |= GDK_SEAT_CAPABILITY_KEYBOARD;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_macos_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
GdkSeatCapabilities capabilities,
|
||||
gboolean owner_events,
|
||||
GdkCursor *cursor,
|
||||
GdkEvent *event,
|
||||
GdkSeatGrabPrepareFunc prepare_func,
|
||||
gpointer prepare_func_data)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
guint32 evtime = event ? gdk_event_get_time (event) : GDK_CURRENT_TIME;
|
||||
GdkGrabStatus status = GDK_GRAB_SUCCESS;
|
||||
gboolean was_visible;
|
||||
|
||||
was_visible = gdk_surface_get_mapped (surface);
|
||||
|
||||
if (prepare_func)
|
||||
(prepare_func) (seat, surface, prepare_func_data);
|
||||
|
||||
if (!gdk_surface_get_mapped (surface))
|
||||
{
|
||||
g_critical ("Surface %p has not been mapped in GdkSeatGrabPrepareFunc",
|
||||
surface);
|
||||
return GDK_GRAB_NOT_VIEWABLE;
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_ALL_POINTING)
|
||||
{
|
||||
/* ALL_POINTING spans 3 capabilities; get the mask for the ones we have */
|
||||
GdkEventMask pointer_evmask = 0;
|
||||
|
||||
/* We let tablet styli take over the pointer cursor */
|
||||
if (capabilities & (GDK_SEAT_CAPABILITY_POINTER |
|
||||
GDK_SEAT_CAPABILITY_TABLET_STYLUS))
|
||||
{
|
||||
pointer_evmask |= POINTER_EVENTS;
|
||||
}
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_TOUCH)
|
||||
pointer_evmask |= TOUCH_EVENTS;
|
||||
|
||||
status = gdk_device_grab (self->logical_pointer, surface,
|
||||
owner_events,
|
||||
pointer_evmask, cursor,
|
||||
evtime);
|
||||
}
|
||||
|
||||
if (status == GDK_GRAB_SUCCESS &&
|
||||
capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
{
|
||||
status = gdk_device_grab (self->logical_keyboard, surface,
|
||||
owner_events,
|
||||
KEYBOARD_EVENTS, cursor,
|
||||
evtime);
|
||||
|
||||
if (status != GDK_GRAB_SUCCESS)
|
||||
{
|
||||
if (capabilities & ~GDK_SEAT_CAPABILITY_KEYBOARD)
|
||||
gdk_device_ungrab (self->logical_pointer, evtime);
|
||||
}
|
||||
}
|
||||
|
||||
if (status != GDK_GRAB_SUCCESS && !was_visible)
|
||||
gdk_surface_hide (surface);
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_ungrab (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
gdk_device_ungrab (self->logical_pointer, GDK_CURRENT_TIME);
|
||||
gdk_device_ungrab (self->logical_keyboard, GDK_CURRENT_TIME);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
gdk_macos_seat_get_logical_device (GdkSeat *seat,
|
||||
GdkSeatCapabilities capability)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
|
||||
/* There must be only one flag set */
|
||||
switch ((guint) capability)
|
||||
{
|
||||
case GDK_SEAT_CAPABILITY_POINTER:
|
||||
case GDK_SEAT_CAPABILITY_TOUCH:
|
||||
return self->logical_pointer;
|
||||
case GDK_SEAT_CAPABILITY_KEYBOARD:
|
||||
return self->logical_keyboard;
|
||||
default:
|
||||
g_warning ("Unhandled capability %x", capability);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_macos_seat_get_devices (GdkSeat *seat,
|
||||
GdkSeatCapabilities capabilities)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GList *physical_devices = NULL;
|
||||
|
||||
if (self->logical_pointer && (capabilities & GDK_SEAT_CAPABILITY_POINTER))
|
||||
physical_devices = g_list_prepend (physical_devices, self->logical_pointer);
|
||||
|
||||
if (self->logical_keyboard && (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD))
|
||||
physical_devices = g_list_prepend (physical_devices, self->logical_keyboard);
|
||||
|
||||
if (capabilities & GDK_SEAT_CAPABILITY_TABLET_STYLUS)
|
||||
{
|
||||
for (guint i = 0; i < self->tablets->len; i++)
|
||||
{
|
||||
GdkMacosTabletData *tablet = g_ptr_array_index (self->tablets, i);
|
||||
|
||||
physical_devices = g_list_prepend (physical_devices, tablet->stylus_device);
|
||||
}
|
||||
}
|
||||
|
||||
return physical_devices;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_macos_seat_get_tools (GdkSeat *seat)
|
||||
{
|
||||
GdkMacosSeat *self = GDK_MACOS_SEAT (seat);
|
||||
GdkDeviceTool *tool;
|
||||
GList *tools = NULL;
|
||||
|
||||
for (guint i = 0; i < self->tools->len; i++)
|
||||
{
|
||||
tool = g_ptr_array_index (self->tools, i);
|
||||
tools = g_list_prepend (tools, tool);
|
||||
}
|
||||
|
||||
return tools;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_class_init (GdkMacosSeatClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_macos_seat_dispose;
|
||||
|
||||
seat_class->get_capabilities = gdk_macos_seat_get_capabilities;
|
||||
seat_class->grab = gdk_macos_seat_grab;
|
||||
seat_class->ungrab = gdk_macos_seat_ungrab;
|
||||
seat_class->get_logical_device = gdk_macos_seat_get_logical_device;
|
||||
seat_class->get_devices = gdk_macos_seat_get_devices;
|
||||
seat_class->get_tools = gdk_macos_seat_get_tools;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_seat_init (GdkMacosSeat *self)
|
||||
{
|
||||
self->tablets = g_ptr_array_new_with_free_func (gdk_macos_tablet_data_free);
|
||||
self->tools = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
init_devices (GdkMacosSeat *self)
|
||||
{
|
||||
/* pointer */
|
||||
self->logical_pointer = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Pointer",
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", self->display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
/* keyboard */
|
||||
self->logical_keyboard = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Keyboard",
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
"has-cursor", FALSE,
|
||||
"display", self->display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
/* link both */
|
||||
_gdk_device_set_associated_device (self->logical_pointer, self->logical_keyboard);
|
||||
_gdk_device_set_associated_device (self->logical_keyboard, self->logical_pointer);
|
||||
|
||||
gdk_seat_device_added (GDK_SEAT (self), self->logical_pointer);
|
||||
gdk_seat_device_added (GDK_SEAT (self), self->logical_keyboard);
|
||||
}
|
||||
|
||||
GdkSeat *
|
||||
_gdk_macos_seat_new (GdkMacosDisplay *display)
|
||||
{
|
||||
GdkDevice *core_keyboard;
|
||||
GdkDevice *core_pointer;
|
||||
GdkSeat *seat;
|
||||
GdkMacosSeat *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
core_pointer = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Pointer",
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
NULL);
|
||||
core_keyboard = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Keyboard",
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
self = g_object_new (GDK_TYPE_MACOS_SEAT,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
self->display = display;
|
||||
|
||||
init_devices (self);
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
static GdkDeviceToolType
|
||||
get_device_tool_type_from_nsevent (NSEvent *nsevent)
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
|
||||
switch ([nsevent pointingDeviceType])
|
||||
{
|
||||
case NSPointingDeviceTypePen:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_PEN;
|
||||
break;
|
||||
case NSPointingDeviceTypeEraser:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_ERASER;
|
||||
break;
|
||||
case NSPointingDeviceTypeCursor:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_MOUSE;
|
||||
break;
|
||||
case NSPointingDeviceTypeUnknown:
|
||||
default:
|
||||
tool_type = GDK_DEVICE_TOOL_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
return tool_type;
|
||||
}
|
||||
|
||||
static GdkAxisFlags
|
||||
get_device_tool_axes_from_nsevent (NSEvent *nsevent)
|
||||
{
|
||||
/* TODO: do we need to be smarter about the capabilities? */
|
||||
return GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT | GDK_AXIS_FLAG_PRESSURE |
|
||||
GDK_AXIS_FLAG_ROTATION;
|
||||
}
|
||||
|
||||
static GdkMacosTabletData *
|
||||
create_tablet_data_from_nsevent (GdkMacosSeat *self,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet;
|
||||
GdkDisplay *display = gdk_seat_get_display (GDK_SEAT (self));
|
||||
GdkDevice *logical_device, *stylus_device;
|
||||
char *logical_name;
|
||||
char *vid, *pid;
|
||||
|
||||
tablet = g_new0 (GdkMacosTabletData, 1);
|
||||
tablet->seat = GDK_SEAT (self);
|
||||
tablet->device_id = [nsevent deviceID];
|
||||
/* FIXME: find a better name */
|
||||
tablet->name = g_strdup_printf ("Tablet %lu", [nsevent deviceID]);
|
||||
|
||||
vid = g_strdup_printf ("%.4lx", [nsevent vendorID]);
|
||||
pid = g_strdup_printf ("%.4lx", [nsevent tabletID]);
|
||||
|
||||
logical_name = g_strdup_printf ("Logical pointer for %s", tablet->name);
|
||||
logical_device = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", logical_name,
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
"seat", self,
|
||||
NULL);
|
||||
|
||||
stylus_device = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", tablet->name,
|
||||
"source", GDK_SOURCE_PEN,
|
||||
"has-cursor", FALSE,
|
||||
"display", display,
|
||||
"seat", self,
|
||||
"vendor-id", vid,
|
||||
"product-id", pid,
|
||||
NULL);
|
||||
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (core_pointer),
|
||||
GDK_DEVICE (core_keyboard));
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (core_keyboard),
|
||||
GDK_DEVICE (core_pointer));
|
||||
tablet->logical_device = logical_device;
|
||||
tablet->stylus_device = stylus_device;
|
||||
|
||||
seat = gdk_seat_default_new_for_logical_pair (core_pointer, core_keyboard);
|
||||
_gdk_device_set_associated_device (logical_device, self->logical_keyboard);
|
||||
_gdk_device_set_associated_device (stylus_device, logical_device);
|
||||
|
||||
g_object_unref (core_pointer);
|
||||
g_object_unref (core_keyboard);
|
||||
gdk_seat_device_added (GDK_SEAT (self), logical_device);
|
||||
gdk_seat_device_added (GDK_SEAT (self), stylus_device);
|
||||
|
||||
return g_steal_pointer (&seat);
|
||||
g_free (logical_name);
|
||||
g_free (vid);
|
||||
g_free (pid);
|
||||
|
||||
return tablet;
|
||||
}
|
||||
|
||||
static GdkMacosTabletData *
|
||||
get_tablet_data_from_nsevent (GdkMacosSeat *self,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet = NULL;
|
||||
|
||||
for (guint i = 0; i < self->tablets->len; i++)
|
||||
{
|
||||
GdkMacosTabletData *t = g_ptr_array_index (self->tablets, i);
|
||||
|
||||
if (t->device_id == [nsevent deviceID])
|
||||
{
|
||||
tablet = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tablet)
|
||||
tablet = create_tablet_data_from_nsevent (self, nsevent);
|
||||
|
||||
return tablet;
|
||||
}
|
||||
|
||||
static void
|
||||
device_tablet_clone_tool_axes (GdkMacosTabletData *tablet,
|
||||
GdkDeviceTool *tool)
|
||||
{
|
||||
int axis_pos;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (tablet->stylus_device));
|
||||
_gdk_device_reset_axes (tablet->stylus_device);
|
||||
|
||||
_gdk_device_add_axis (tablet->stylus_device, GDK_AXIS_X, 0, 0, 0);
|
||||
_gdk_device_add_axis (tablet->stylus_device, GDK_AXIS_Y, 0, 0, 0);
|
||||
|
||||
if (tool->tool_axes & (GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT))
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_XTILT, -1.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_XTILT] = axis_pos;
|
||||
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_YTILT, -1.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_YTILT] = axis_pos;
|
||||
}
|
||||
|
||||
if (tool->tool_axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_PRESSURE, 0.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_PRESSURE] = axis_pos;
|
||||
}
|
||||
|
||||
if (tool->tool_axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
axis_pos = _gdk_device_add_axis (tablet->stylus_device,
|
||||
GDK_AXIS_ROTATION, 0.0, 1.0, 0);
|
||||
tablet->axis_indices[GDK_AXIS_ROTATION] = axis_pos;
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (tablet->stylus_device));
|
||||
}
|
||||
|
||||
static void
|
||||
mimic_device_axes (GdkDevice *logical,
|
||||
GdkDevice *physical)
|
||||
{
|
||||
double axis_min, axis_max, axis_resolution;
|
||||
GdkAxisUse axis_use;
|
||||
int axis_count;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (logical));
|
||||
_gdk_device_reset_axes (logical);
|
||||
axis_count = gdk_device_get_n_axes (physical);
|
||||
|
||||
for (int i = 0; i < axis_count; i++)
|
||||
{
|
||||
_gdk_device_get_axis_info (physical, i, &axis_use, &axis_min,
|
||||
&axis_max, &axis_resolution);
|
||||
_gdk_device_add_axis (logical, axis_use, axis_min,
|
||||
axis_max, axis_resolution);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (logical));
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_seat_handle_tablet_tool_event (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
GdkMacosTabletData *tablet;
|
||||
GdkDeviceTool *tool;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_SEAT (seat));
|
||||
g_return_if_fail (nsevent != NULL);
|
||||
|
||||
tablet = get_tablet_data_from_nsevent (seat, nsevent);
|
||||
|
||||
tool_type = get_device_tool_type_from_nsevent (nsevent);
|
||||
|
||||
if (tool_type == GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
{
|
||||
g_warning ("Unknown device tool detected");
|
||||
return;
|
||||
}
|
||||
|
||||
tool = gdk_seat_get_tool (GDK_SEAT (seat), [nsevent tabletID], [nsevent deviceID], tool_type);
|
||||
|
||||
if ([nsevent isEnteringProximity])
|
||||
{
|
||||
if (!tool)
|
||||
{
|
||||
tool = gdk_device_tool_new ([nsevent tabletID], [nsevent vendorID], tool_type,
|
||||
get_device_tool_axes_from_nsevent (nsevent));
|
||||
g_ptr_array_add (seat->tools, tool);
|
||||
}
|
||||
|
||||
gdk_device_update_tool (tablet->stylus_device, tool);
|
||||
tablet->current_tool = tool;
|
||||
device_tablet_clone_tool_axes (tablet, tool);
|
||||
mimic_device_axes (tablet->logical_device, tablet->stylus_device);
|
||||
seat->current_tablet = tablet;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_device_update_tool (tablet->stylus_device, NULL);
|
||||
tablet->current_tool = NULL;
|
||||
seat->current_tablet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_seat_get_tablet (GdkMacosSeat *seat,
|
||||
GdkDevice **logical_device,
|
||||
GdkDeviceTool **tool)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SEAT (seat), FALSE);
|
||||
|
||||
if (!seat->current_tablet)
|
||||
return FALSE;
|
||||
|
||||
*logical_device = seat->current_tablet->logical_device;
|
||||
*tool = seat->current_tablet->current_tool;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
double *
|
||||
_gdk_macos_seat_get_tablet_axes_from_nsevent (GdkMacosSeat *seat,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosTabletData *tablet;
|
||||
int axis_index;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SEAT (seat), NULL);
|
||||
g_return_val_if_fail (nsevent != NULL, NULL);
|
||||
|
||||
tablet = seat->current_tablet;
|
||||
if (!tablet || !tablet->current_tool)
|
||||
return NULL;
|
||||
|
||||
if (tablet->current_tool->tool_axes & (GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT))
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent tilt].x, &tablet->axes[GDK_AXIS_XTILT]);
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent tilt].y, &tablet->axes[GDK_AXIS_YTILT]);
|
||||
}
|
||||
|
||||
if (tablet->current_tool->tool_axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent pressure], &tablet->axes[GDK_AXIS_PRESSURE]);
|
||||
}
|
||||
|
||||
if (tablet->current_tool->tool_axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
[nsevent rotation], &tablet->axes[GDK_AXIS_ROTATION]);
|
||||
}
|
||||
|
||||
return g_memdup (tablet->axes,
|
||||
sizeof (double) * GDK_AXIS_LAST);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright © 2021 Amazon.com, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_SEAT (gdk_macos_seat_get_type ())
|
||||
#define GDK_MACOS_SEAT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_MACOS_SEAT, GdkMacosSeat))
|
||||
#define GDK_IS_MACOS_SEAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_MACOS_SEAT))
|
||||
|
||||
typedef struct _GdkMacosSeat GdkMacosSeat;
|
||||
typedef struct _GdkMacosSeatClass GdkMacosSeatClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_seat_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
@@ -61,6 +61,7 @@ struct _GdkMacosSurface
|
||||
gint64 pending_frame_counter;
|
||||
|
||||
guint did_initial_present : 1;
|
||||
guint geometry_dirty : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosSurfaceClass
|
||||
|
||||
@@ -150,6 +150,12 @@ _gdk_macos_surface_set_shadow (GdkMacosSurface *surface,
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (self));
|
||||
|
||||
if (self->shadow_top == top &&
|
||||
self->shadow_right == right &&
|
||||
self->shadow_bottom == bottom &&
|
||||
self->shadow_left == left)
|
||||
return;
|
||||
|
||||
self->shadow_top = top;
|
||||
self->shadow_right = right;
|
||||
self->shadow_bottom = bottom;
|
||||
|
||||
@@ -81,7 +81,7 @@ _gdk_macos_toplevel_surface_unmaximize (GdkMacosToplevelSurface *self)
|
||||
[window zoom:window];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
@@ -107,6 +107,7 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
style_mask = [nswindow styleMask];
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
@@ -158,13 +159,11 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
[nswindow setStyleMask:style_mask];
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
{
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
}
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
|
||||
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
@@ -230,8 +229,6 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self));
|
||||
|
||||
GDK_MACOS_SURFACE (self)->did_initial_present = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -373,6 +370,87 @@ _gdk_macos_toplevel_surface_hide (GdkSurface *surface)
|
||||
GDK_SURFACE_CLASS (_gdk_macos_toplevel_surface_parent_class)->hide (surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
|
||||
NSWindow *nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
GdkToplevelSize size;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
int bounds_width, bounds_height;
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
NSWindowStyleMask style_mask;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
if (!GDK_MACOS_SURFACE (surface)->geometry_dirty)
|
||||
return FALSE;
|
||||
|
||||
GDK_MACOS_SURFACE (surface)->geometry_dirty = FALSE;
|
||||
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
style_mask = [nswindow styleMask];
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_macos_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
|
||||
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
|
||||
if (style_mask & NSWindowStyleMaskResizable)
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.max_width = geometry.min_width = width;
|
||||
geometry.max_height = geometry.min_height = height;
|
||||
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
|
||||
}
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
_gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
|
||||
size.shadow.top,
|
||||
size.shadow.right,
|
||||
size.shadow.bottom,
|
||||
size.shadow.left);
|
||||
|
||||
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
_gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_request_layout (GdkSurface *surface)
|
||||
{
|
||||
GDK_MACOS_SURFACE (surface)->geometry_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_destroy (GdkSurface *surface,
|
||||
gboolean foreign_destroy)
|
||||
@@ -506,6 +584,8 @@ _gdk_macos_toplevel_surface_class_init (GdkMacosToplevelSurfaceClass *klass)
|
||||
|
||||
surface_class->destroy = _gdk_macos_toplevel_surface_destroy;
|
||||
surface_class->hide = _gdk_macos_toplevel_surface_hide;
|
||||
surface_class->compute_size = _gdk_macos_toplevel_surface_compute_size;
|
||||
surface_class->request_layout = _gdk_macos_toplevel_surface_request_layout;
|
||||
|
||||
gdk_toplevel_install_properties (object_class, LAST_PROP);
|
||||
}
|
||||
|
||||
@@ -40,5 +40,36 @@ struct _GdkPoint
|
||||
};
|
||||
typedef struct _GdkPoint GdkPoint;
|
||||
|
||||
static inline NSPoint
|
||||
convert_nspoint_from_screen (NSWindow *window,
|
||||
NSPoint point)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
return [window convertPointFromScreen:point];
|
||||
#else
|
||||
/* Apple documentation claims that convertPointFromScreen is available
|
||||
* on 10.12+. However, that doesn't seem to be the case when using it.
|
||||
* Instead, we'll just use it on modern 10.15 systems and fallback to
|
||||
* converting using rects on older systems.
|
||||
*/
|
||||
return [window convertRectFromScreen:NSMakeRect (point.x, point.y, 0, 0)].origin;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline NSPoint
|
||||
convert_nspoint_to_screen (NSWindow *window,
|
||||
NSPoint point)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER
|
||||
return [window convertPointToScreen:point];
|
||||
#else
|
||||
/* Apple documentation claims that convertPointToScreen is available
|
||||
* on 10.12+. However, that doesn't seem to be the case when using it.
|
||||
* Instead, we'll just use it on modern 10.15 systems and fallback to
|
||||
* converting using rects on older systems.
|
||||
*/
|
||||
return [window convertRectToScreen:NSMakeRect (point.x, point.y, 0, 0)].origin;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __GDK_MACOS_UTILS_PRIVATE_H__ */
|
||||
|
||||
@@ -33,6 +33,7 @@ gdk_macos_public_headers = files([
|
||||
'gdkmacosglcontext.h',
|
||||
'gdkmacoskeymap.h',
|
||||
'gdkmacosmonitor.h',
|
||||
'gdkmacosseat.h',
|
||||
'gdkmacossurface.h',
|
||||
])
|
||||
|
||||
|
||||
@@ -2357,6 +2357,9 @@ touch_handle_down (void *data,
|
||||
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
if (!wl_surface)
|
||||
return;
|
||||
|
||||
touch = gdk_wayland_seat_add_touch (seat, id, wl_surface);
|
||||
touch->x = wl_fixed_to_double (x);
|
||||
touch->y = wl_fixed_to_double (y);
|
||||
@@ -2404,6 +2407,9 @@ touch_handle_up (void *data,
|
||||
_gdk_wayland_display_update_serial (display, serial);
|
||||
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
event = gdk_touch_event_new (GDK_TOUCH_END,
|
||||
GDK_SLOT_TO_EVENT_SEQUENCE (touch->id),
|
||||
touch->surface,
|
||||
@@ -2442,6 +2448,9 @@ touch_handle_motion (void *data,
|
||||
GdkEvent *event;
|
||||
|
||||
touch = gdk_wayland_seat_get_touch (seat, id);
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
touch->x = wl_fixed_to_double (x);
|
||||
touch->y = wl_fixed_to_double (y);
|
||||
|
||||
@@ -3381,9 +3390,14 @@ tablet_tool_handle_proximity_in (void *data,
|
||||
GdkWaylandTabletData *tablet = zwp_tablet_v2_get_user_data (wp_tablet);
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkSurface *surface = wl_surface_get_user_data (wsurface);
|
||||
GdkSurface *surface;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!wsurface)
|
||||
return;
|
||||
|
||||
surface = wl_surface_get_user_data (wsurface);
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
if (!GDK_IS_SURFACE (surface))
|
||||
@@ -3427,6 +3441,9 @@ tablet_tool_handle_proximity_out (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_SEAT_NOTE (tool->seat, EVENTS,
|
||||
g_message ("proximity out, seat %p, tool %d", tool->seat,
|
||||
gdk_device_tool_get_tool_type (tool->tool)));
|
||||
@@ -3490,7 +3507,7 @@ tablet_tool_handle_down (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
_gdk_wayland_display_update_serial (display_wayland, serial);
|
||||
@@ -3507,7 +3524,7 @@ tablet_tool_handle_up (void *data,
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet_create_button_event_frame (tablet, GDK_BUTTON_RELEASE, GDK_BUTTON_PRIMARY);
|
||||
@@ -3524,6 +3541,9 @@ tablet_tool_handle_motion (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.surface_x = wl_fixed_to_double (sx);
|
||||
tablet->pointer_info.surface_y = wl_fixed_to_double (sy);
|
||||
|
||||
@@ -3551,7 +3571,12 @@ tablet_tool_handle_pressure (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
pressure, &tablet->axes[GDK_AXIS_PRESSURE]);
|
||||
@@ -3568,7 +3593,12 @@ tablet_tool_handle_distance (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
distance, &tablet->axes[GDK_AXIS_DISTANCE]);
|
||||
@@ -3586,8 +3616,14 @@ tablet_tool_handle_tilt (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
int ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
int xtilt_axis_index;
|
||||
int ytilt_axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, xtilt_axis_index,
|
||||
wl_fixed_to_double (xtilt),
|
||||
@@ -3614,7 +3650,7 @@ tablet_tool_handle_button (void *data,
|
||||
GdkEventType evtype;
|
||||
guint n_button;
|
||||
|
||||
if (!tablet->pointer_info.focus)
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.press_serial = serial;
|
||||
@@ -3645,7 +3681,12 @@ tablet_tool_handle_rotation (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
wl_fixed_to_double (degrees),
|
||||
@@ -3664,7 +3705,12 @@ tablet_tool_handle_slider (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
position, &tablet->axes[GDK_AXIS_SLIDER]);
|
||||
@@ -3682,9 +3728,14 @@ tablet_tool_handle_wheel (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
GdkWaylandSeat *seat;
|
||||
GdkEvent *event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
seat = GDK_WAYLAND_SEAT (tablet->seat);
|
||||
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("tablet tool %d wheel %d/%d",
|
||||
gdk_device_tool_get_tool_type (tool->tool), degrees, clicks));
|
||||
@@ -3724,6 +3775,9 @@ tablet_tool_handle_frame (void *data,
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkEvent *frame_event;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
GDK_SEAT_NOTE (tablet->seat, EVENTS,
|
||||
g_message ("tablet frame, time %d", time));
|
||||
|
||||
@@ -4312,6 +4366,9 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pointer->pointer_surface_outputs)
|
||||
return;
|
||||
|
||||
scale = 1;
|
||||
for (l = pointer->pointer_surface_outputs; l != NULL; l = l->next)
|
||||
{
|
||||
@@ -4319,6 +4376,8 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
|
||||
if (pointer->current_output_scale == scale)
|
||||
return;
|
||||
pointer->current_output_scale = scale;
|
||||
|
||||
gdk_wayland_device_update_surface_cursor (device);
|
||||
|
||||
@@ -1836,6 +1836,7 @@ settings_portal_changed (GDBusProxy *proxy,
|
||||
char *a = g_variant_print (value, FALSE);
|
||||
g_debug ("Using changed portal setting %s %s: %s", namespace, name, a);
|
||||
g_free (a);
|
||||
entry->valid = TRUE;
|
||||
apply_portal_setting (entry, value, display);
|
||||
gdk_display_setting_changed (display, entry->setting);
|
||||
}
|
||||
|
||||
@@ -242,14 +242,22 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "swap buffers");
|
||||
if (display_wayland->have_egl_swap_buffers_with_damage)
|
||||
{
|
||||
EGLint stack_rects[4 * 4]; /* 4 rects */
|
||||
EGLint *heap_rects = NULL;
|
||||
int i, j, n_rects = cairo_region_num_rectangles (painted);
|
||||
EGLint *rects = g_new (EGLint, n_rects * 4);
|
||||
cairo_rectangle_int_t rect;
|
||||
int surface_height = gdk_surface_get_height (surface);
|
||||
int scale = gdk_surface_get_scale_factor (surface);
|
||||
EGLint *rects;
|
||||
|
||||
if (n_rects < G_N_ELEMENTS (stack_rects) / 4)
|
||||
rects = (EGLint *)&stack_rects;
|
||||
else
|
||||
heap_rects = rects = g_new (EGLint, n_rects * 4);
|
||||
|
||||
for (i = 0, j = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (painted, i, &rect);
|
||||
rects[j++] = rect.x * scale;
|
||||
rects[j++] = (surface_height - rect.height - rect.y) * scale;
|
||||
@@ -257,7 +265,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
rects[j++] = rect.height * scale;
|
||||
}
|
||||
eglSwapBuffersWithDamageEXT (display_wayland->egl_display, egl_surface, rects, n_rects);
|
||||
g_free (rects);
|
||||
g_free (heap_rects);
|
||||
}
|
||||
else
|
||||
eglSwapBuffers (display_wayland->egl_display, egl_surface);
|
||||
@@ -293,27 +301,27 @@ gdk_wayland_get_display (GdkWaylandDisplay *display_wayland)
|
||||
if (epoxy_has_egl_extension (NULL, "EGL_KHR_platform_base"))
|
||||
{
|
||||
PFNEGLGETPLATFORMDISPLAYPROC getPlatformDisplay =
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplay");
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplay");
|
||||
|
||||
if (getPlatformDisplay)
|
||||
dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
|
||||
display_wayland->wl_display,
|
||||
NULL);
|
||||
dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
|
||||
display_wayland->wl_display,
|
||||
NULL);
|
||||
if (dpy)
|
||||
return dpy;
|
||||
return dpy;
|
||||
}
|
||||
|
||||
if (epoxy_has_egl_extension (NULL, "EGL_EXT_platform_base"))
|
||||
{
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay =
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
|
||||
(void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
|
||||
|
||||
if (getPlatformDisplay)
|
||||
dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
|
||||
display_wayland->wl_display,
|
||||
NULL);
|
||||
dpy = getPlatformDisplay (EGL_PLATFORM_WAYLAND_EXT,
|
||||
display_wayland->wl_display,
|
||||
NULL);
|
||||
if (dpy)
|
||||
return dpy;
|
||||
return dpy;
|
||||
}
|
||||
|
||||
return eglGetDisplay ((EGLNativeDisplayType) display_wayland->wl_display);
|
||||
@@ -386,7 +394,7 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLint count;
|
||||
EGLConfig *configs;
|
||||
EGLConfig config;
|
||||
int i = 0;
|
||||
|
||||
attrs[i++] = EGL_SURFACE_TYPE;
|
||||
@@ -407,39 +415,26 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
attrs[i++] = EGL_NONE;
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, NULL, 0, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
configs = g_new (EGLConfig, count);
|
||||
|
||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, configs, count, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Pick first valid configuration i guess? */
|
||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, &config, 1, &count) || count < 1)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
|
||||
_("No available configurations for the given pixel format"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (egl_config_out != NULL)
|
||||
*egl_config_out = configs[0];
|
||||
|
||||
g_free (configs);
|
||||
g_assert (egl_config_out);
|
||||
*egl_config_out = config;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
gdk_wayland_surface_create_gl_context (GdkSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
@@ -526,10 +521,10 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
||||
else
|
||||
{
|
||||
if (display_wayland->have_egl_surfaceless_context)
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
else
|
||||
egl_surface = gdk_wayland_surface_get_dummy_egl_surface (surface,
|
||||
context_wayland->egl_config);
|
||||
egl_surface = gdk_wayland_surface_get_dummy_egl_surface (surface,
|
||||
context_wayland->egl_config);
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent (display_wayland->egl_display, egl_surface,
|
||||
|
||||
@@ -1721,8 +1721,8 @@ _gdk_win32_surface_fill_min_max_info (GdkSurface *window,
|
||||
mmi->ptMaxSize.y = nearest_info.rcWork.bottom - nearest_info.rcWork.top;
|
||||
}
|
||||
|
||||
mmi->ptMaxTrackSize.x = GetSystemMetrics (SM_CXVIRTUALSCREEN) + impl->margins_x * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.y = GetSystemMetrics (SM_CYVIRTUALSCREEN) + impl->margins_y * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.x = GetSystemMetrics (SM_CXVIRTUALSCREEN) + impl->shadow_x * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.y = GetSystemMetrics (SM_CYVIRTUALSCREEN) + impl->shadow_y * impl->surface_scale;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -2354,9 +2354,7 @@ gdk_event_translate (MSG *msg,
|
||||
|
||||
|
||||
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
|
||||
{
|
||||
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
|
||||
}
|
||||
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
|
||||
else if (_gdk_input_ignore_core == 0)
|
||||
{
|
||||
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
|
||||
@@ -2835,6 +2833,16 @@ gdk_event_translate (MSG *msg,
|
||||
else
|
||||
unset_bits |= GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
|
||||
/*
|
||||
* If we are minizing, pause all surface layout computations, and re-start the
|
||||
* computation once we are coming out of a minimized state
|
||||
*/
|
||||
if (!(old_state & GDK_TOPLEVEL_STATE_MINIMIZED) && set_bits & GDK_TOPLEVEL_STATE_MINIMIZED)
|
||||
gdk_surface_freeze_updates (window);
|
||||
|
||||
if (old_state & GDK_TOPLEVEL_STATE_MINIMIZED && unset_bits & GDK_TOPLEVEL_STATE_MINIMIZED)
|
||||
gdk_surface_thaw_updates (window);
|
||||
|
||||
gdk_surface_set_is_mapped (window, !!IsWindowVisible (msg->hwnd));
|
||||
gdk_synthesize_surface_state (window, unset_bits, set_bits);
|
||||
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
#include <math.h>
|
||||
|
||||
static void gdk_surface_win32_finalize (GObject *object);
|
||||
static void compute_toplevel_size (GdkSurface *surface,
|
||||
gboolean update_geometry,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
static gpointer parent_class = NULL;
|
||||
static GSList *modal_window_stack = NULL;
|
||||
@@ -1100,6 +1104,8 @@ gdk_win32_surface_resize (GdkSurface *window,
|
||||
outer_rect.bottom - outer_rect.top,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
|
||||
window->resize_count += 1;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1160,8 +1166,6 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
|
||||
{
|
||||
GdkWin32Surface *surface = GDK_WIN32_SURFACE (window);
|
||||
|
||||
surface->inhibit_configure = TRUE;
|
||||
|
||||
/* We ignore changes to the window being moved or resized by the
|
||||
user, as we don't want to fight the user */
|
||||
if (GDK_SURFACE_HWND (window) == _modal_move_resize_window)
|
||||
@@ -1186,8 +1190,6 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
|
||||
}
|
||||
|
||||
out:
|
||||
surface->inhibit_configure = FALSE;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
|
||||
@@ -1228,10 +1230,10 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
||||
gdk_surface_layout_popup_helper (surface,
|
||||
width,
|
||||
height,
|
||||
impl->margins.left,
|
||||
impl->margins.right,
|
||||
impl->margins.top,
|
||||
impl->margins.bottom,
|
||||
impl->shadow.left,
|
||||
impl->shadow.right,
|
||||
impl->shadow.top,
|
||||
impl->shadow.bottom,
|
||||
monitor,
|
||||
&bounds,
|
||||
layout,
|
||||
@@ -1256,11 +1258,24 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_notify_mapped (GdkSurface *surface)
|
||||
{
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
if (!GDK_SURFACE_IS_MAPPED (surface))
|
||||
{
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_popup (GdkSurface *surface)
|
||||
{
|
||||
gdk_win32_surface_raise (surface);
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
maybe_notify_mapped (surface);
|
||||
show_window_internal (surface, FALSE, FALSE);
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
@@ -2294,6 +2309,7 @@ snap_up (GdkSurface *window)
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_FULLUP;
|
||||
impl->resized = FALSE;
|
||||
|
||||
stash_window (window, impl);
|
||||
|
||||
@@ -2304,10 +2320,18 @@ snap_up (GdkSurface *window)
|
||||
y = 0;
|
||||
height = maxysize;
|
||||
|
||||
x = x - impl->margins.left;
|
||||
y = y - impl->margins.top;
|
||||
width += impl->margins_x;
|
||||
height += impl->margins_y;
|
||||
x = x - impl->shadow.left;
|
||||
y = y - impl->shadow.top;
|
||||
width += impl->shadow_x;
|
||||
height += impl->shadow_y;
|
||||
|
||||
/* XXX: FIXME, AeroSnap snap_up() not really working well,
|
||||
*
|
||||
* * The snap_up() puts the window at the top left corner.
|
||||
* * Without the following call, the height maximizes but we see a spew of
|
||||
* "GdkToplevelSize: geometry size (x,y) exceeds bounds" warnings
|
||||
*/
|
||||
compute_toplevel_size (window, TRUE, &width, &height);
|
||||
|
||||
gdk_win32_surface_move_resize (window, x, y, width, height);
|
||||
}
|
||||
@@ -2323,6 +2347,7 @@ snap_left (GdkSurface *window,
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_HALFLEFT;
|
||||
impl->resized = FALSE;
|
||||
|
||||
gdk_win32_monitor_get_workarea (snap_monitor, &rect);
|
||||
|
||||
@@ -2330,10 +2355,10 @@ snap_left (GdkSurface *window,
|
||||
|
||||
rect.width = rect.width / 2;
|
||||
|
||||
rect.x = rect.x - impl->margins.left;
|
||||
rect.y = rect.y - impl->margins.top;
|
||||
rect.width = rect.width + impl->margins_x;
|
||||
rect.height = rect.height + impl->margins_y;
|
||||
rect.x = rect.x - impl->shadow.left;
|
||||
rect.y = rect.y - impl->shadow.top;
|
||||
rect.width = rect.width + impl->shadow_x;
|
||||
rect.height = rect.height + impl->shadow_y;
|
||||
|
||||
gdk_win32_surface_move_resize (window,
|
||||
rect.x, rect.y,
|
||||
@@ -2351,6 +2376,7 @@ snap_right (GdkSurface *window,
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_HALFRIGHT;
|
||||
impl->resized = FALSE;
|
||||
|
||||
gdk_win32_monitor_get_workarea (snap_monitor, &rect);
|
||||
|
||||
@@ -2359,10 +2385,10 @@ snap_right (GdkSurface *window,
|
||||
rect.width = rect.width / 2;
|
||||
rect.x += rect.width;
|
||||
|
||||
rect.x = rect.x - impl->margins.left;
|
||||
rect.y = rect.y - impl->margins.top;
|
||||
rect.width = rect.width + impl->margins_x;
|
||||
rect.height = rect.height + impl->margins_y;
|
||||
rect.x = rect.x - impl->shadow.left;
|
||||
rect.y = rect.y - impl->shadow.top;
|
||||
rect.width = rect.width + impl->shadow_x;
|
||||
rect.height = rect.height + impl->shadow_y;
|
||||
|
||||
gdk_win32_surface_move_resize (window,
|
||||
rect.x, rect.y,
|
||||
@@ -3502,10 +3528,10 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE && !maximized)
|
||||
{
|
||||
swx += impl->margins.left / impl->surface_scale;
|
||||
swy += impl->margins.top / impl->surface_scale;
|
||||
swwidth -= impl->margins_x;
|
||||
swheight -= impl->margins_y;
|
||||
swx += impl->shadow.left / impl->surface_scale;
|
||||
swy += impl->shadow.top / impl->surface_scale;
|
||||
swwidth -= impl->shadow_x;
|
||||
swheight -= impl->shadow_y;
|
||||
}
|
||||
|
||||
pointer_outside_of_window = root_x < swx || root_x > swx + swwidth ||
|
||||
@@ -3555,23 +3581,23 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
unmax_width = placement.rcNormalPosition.right - placement.rcNormalPosition.left;
|
||||
unmax_height = placement.rcNormalPosition.bottom - placement.rcNormalPosition.top;
|
||||
|
||||
shadow_unmax_width = unmax_width - impl->margins_x * impl->surface_scale;
|
||||
shadow_unmax_height = unmax_height - impl->margins_y * impl->surface_scale;
|
||||
shadow_unmax_width = unmax_width - impl->shadow_x * impl->surface_scale;
|
||||
shadow_unmax_height = unmax_height - impl->shadow_y * impl->surface_scale;
|
||||
|
||||
if (offsetx * impl->surface_scale < (shadow_unmax_width / 2) &&
|
||||
offsety * impl->surface_scale < (shadow_unmax_height / 2))
|
||||
{
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->shadow.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.bottom = placement.rcNormalPosition.top + unmax_height;
|
||||
|
||||
if (left_half)
|
||||
{
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->margins.left - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->shadow.left - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.right = placement.rcNormalPosition.left + unmax_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->margins.right - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->shadow.right - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.left = placement.rcNormalPosition.right - unmax_width;
|
||||
}
|
||||
}
|
||||
@@ -3582,7 +3608,7 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
(_gdk_offset_x * impl->surface_scale);
|
||||
|
||||
if (offsety * impl->surface_scale < shadow_unmax_height / 2)
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->shadow.top - _gdk_offset_y) * impl->surface_scale;
|
||||
else
|
||||
placement.rcNormalPosition.top = (root_y * impl->surface_scale) -
|
||||
(unmax_height / 2) -
|
||||
@@ -3609,18 +3635,18 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE)
|
||||
{
|
||||
snew_pos.width -= impl->margins_x;
|
||||
snew_pos.height -= impl->margins_y;
|
||||
snew_pos.width -= impl->shadow_x;
|
||||
snew_pos.height -= impl->shadow_y;
|
||||
}
|
||||
|
||||
if (offsetx < snew_pos.width / 2 && offsety < snew_pos.height / 2)
|
||||
{
|
||||
new_pos.y = root_y - offsety + impl->margins.top / impl->surface_scale;
|
||||
new_pos.y = root_y - offsety + impl->shadow.top / impl->surface_scale;
|
||||
|
||||
if (left_half)
|
||||
new_pos.x = root_x - offsetx + impl->margins.left / impl->surface_scale;
|
||||
new_pos.x = root_x - offsetx + impl->shadow.left / impl->surface_scale;
|
||||
else
|
||||
new_pos.x = root_x + offsetx + impl->margins.left / impl->surface_scale - new_pos.width;
|
||||
new_pos.x = root_x + offsetx + impl->shadow.left / impl->surface_scale - new_pos.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4015,8 +4041,18 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
|
||||
rect.top != new_rect.top ||
|
||||
rect.bottom != new_rect.bottom))
|
||||
{
|
||||
if (GDK_IS_TOPLEVEL (window))
|
||||
{
|
||||
int scale = impl->surface_scale;
|
||||
|
||||
impl->unscaled_width = new_rect.right - new_rect.left;
|
||||
impl->unscaled_height = new_rect.bottom - new_rect.top;
|
||||
impl->next_layout.configured_width = (impl->unscaled_width + scale - 1) / scale;
|
||||
impl->next_layout.configured_height = (impl->unscaled_height + scale - 1) / scale;
|
||||
impl->resized = TRUE;
|
||||
}
|
||||
|
||||
context->native_move_resize_pending = TRUE;
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
else if (context->op == GDK_WIN32_DRAGOP_MOVE &&
|
||||
(rect.left != new_rect.left ||
|
||||
@@ -4051,6 +4087,8 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
|
||||
if (context->op == GDK_WIN32_DRAGOP_RESIZE ||
|
||||
context->op == GDK_WIN32_DRAGOP_MOVE)
|
||||
handle_aerosnap_move_resize (window, context, x, y);
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4159,6 +4197,7 @@ gdk_win32_surface_minimize (GdkSurface *window)
|
||||
static void
|
||||
gdk_win32_surface_maximize (GdkSurface *window)
|
||||
{
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
@@ -4169,6 +4208,9 @@ gdk_win32_surface_maximize (GdkSurface *window)
|
||||
GDK_SURFACE_HWND (window),
|
||||
_gdk_win32_surface_state_to_string (window->state)));
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
impl->resized = FALSE;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_MAXIMIZE);
|
||||
else
|
||||
@@ -4514,17 +4556,17 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
|
||||
"left %d, top %d, right %d, bottom %d\n",
|
||||
window, left, top, right, bottom));
|
||||
|
||||
impl->zero_margins = left == 0 && right == 0 && top == 0 && bottom == 0;
|
||||
impl->zero_shadow = left == 0 && right == 0 && top == 0 && bottom == 0;
|
||||
|
||||
if (impl->zero_margins)
|
||||
if (impl->zero_shadow)
|
||||
return;
|
||||
|
||||
impl->margins.left = left;
|
||||
impl->margins.right = right * impl->surface_scale;
|
||||
impl->margins.top = top;
|
||||
impl->margins.bottom = bottom * impl->surface_scale;
|
||||
impl->margins_x = left + right;
|
||||
impl->margins_y = top + bottom;
|
||||
impl->shadow.left = left;
|
||||
impl->shadow.right = right * impl->surface_scale;
|
||||
impl->shadow.top = top;
|
||||
impl->shadow.bottom = bottom * impl->surface_scale;
|
||||
impl->shadow_x = left + right;
|
||||
impl->shadow_y = top + bottom;
|
||||
}
|
||||
|
||||
|
||||
@@ -4597,6 +4639,118 @@ gdk_win32_surface_set_input_region (GdkSurface *window,
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
compute_toplevel_size (GdkSurface *surface,
|
||||
gboolean update_geometry,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_win32_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
*width = size.width;
|
||||
*height = size.height;
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
{
|
||||
gdk_win32_surface_set_shadow_width (surface,
|
||||
size.shadow.left,
|
||||
size.shadow.right,
|
||||
size.shadow.top,
|
||||
size.shadow.bottom);
|
||||
}
|
||||
|
||||
if (update_geometry)
|
||||
{
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
GdkToplevelLayout *layout = impl->toplevel_layout;
|
||||
|
||||
if (gdk_toplevel_layout_get_resizable (layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.max_width = geometry.min_width = *width;
|
||||
geometry.max_height = geometry.min_height = *height;
|
||||
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
|
||||
}
|
||||
gdk_win32_surface_set_geometry_hints (surface, &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, *width, *height, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_win32_surface_request_layout (GdkSurface *surface)
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
int scale = impl->surface_scale;
|
||||
RECT rect;
|
||||
|
||||
if (GDK_IS_TOPLEVEL (surface) && impl->resized)
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdk_win32_get_window_rect (surface, &rect);
|
||||
|
||||
impl->unscaled_width = rect.right - rect.left;
|
||||
impl->unscaled_height = rect.bottom - rect.top;
|
||||
|
||||
impl->next_layout.configured_width = (impl->unscaled_width + scale - 1) / scale;
|
||||
impl->next_layout.configured_height = (impl->unscaled_height + scale - 1) / scale;
|
||||
surface->x = rect.left / scale;
|
||||
surface->y = rect.top / scale;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_win32_surface_compute_size (GdkSurface *surface)
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
int width, height;
|
||||
|
||||
if (GDK_IS_TOPLEVEL (surface))
|
||||
compute_toplevel_size (surface, TRUE, &width, &height);
|
||||
|
||||
if (!impl->resized)
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
|
||||
{
|
||||
@@ -4623,6 +4777,8 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
|
||||
impl_class->create_gl_context = _gdk_win32_surface_create_gl_context;
|
||||
impl_class->get_scale_factor = _gdk_win32_surface_get_scale_factor;
|
||||
impl_class->get_unscaled_size = _gdk_win32_surface_get_unscaled_size;
|
||||
impl_class->request_layout = _gdk_win32_surface_request_layout;
|
||||
impl_class->compute_size = _gdk_win32_surface_compute_size;
|
||||
}
|
||||
|
||||
HGDIOBJ
|
||||
@@ -4912,75 +5068,18 @@ gdk_win32_toplevel_class_init (GdkWin32ToplevelClass *class)
|
||||
}
|
||||
|
||||
static void
|
||||
show_surface (GdkSurface *surface)
|
||||
{
|
||||
gboolean was_mapped;
|
||||
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
|
||||
|
||||
if (!was_mapped)
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
|
||||
gdk_win32_surface_show (surface, FALSE);
|
||||
|
||||
if (!was_mapped)
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_toplevel_present (GdkToplevel *toplevel,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (toplevel);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
gboolean maximize;
|
||||
gboolean fullscreen;
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_win32_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (toplevel, &size);
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
|
||||
if (gdk_toplevel_layout_get_resizable (layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.max_width = geometry.min_width = width;
|
||||
geometry.max_height = geometry.min_height = height;
|
||||
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
|
||||
}
|
||||
gdk_win32_surface_set_geometry_hints (surface, &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
|
||||
impl->toplevel_layout = gdk_toplevel_layout_copy (layout);
|
||||
compute_toplevel_size (surface, FALSE, &width, &height);
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
|
||||
if (gdk_toplevel_layout_get_maximized (layout, &maximize))
|
||||
@@ -4999,18 +5098,8 @@ gdk_win32_toplevel_present (GdkToplevel *toplevel,
|
||||
gdk_win32_surface_unfullscreen (surface);
|
||||
}
|
||||
|
||||
show_surface (surface);
|
||||
|
||||
if (size.shadow.is_valid)
|
||||
{
|
||||
gdk_win32_surface_set_shadow_width (surface,
|
||||
size.shadow.left,
|
||||
size.shadow.right,
|
||||
size.shadow.top,
|
||||
size.shadow.bottom);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
gdk_win32_surface_show (surface, FALSE);
|
||||
maybe_notify_mapped (surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -5093,8 +5182,9 @@ gdk_win32_drag_surface_present (GdkDragSurface *drag_surface,
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (drag_surface);
|
||||
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
show_surface (surface);
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
gdk_win32_surface_show (surface, FALSE);
|
||||
maybe_notify_mapped (surface);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -265,16 +265,16 @@ struct _GdkWin32Surface
|
||||
int initial_y;
|
||||
|
||||
/* left/right/top/bottom width of the shadow/resize-grip around the window */
|
||||
RECT margins;
|
||||
RECT shadow;
|
||||
|
||||
/* left+right and top+bottom from @margins */
|
||||
int margins_x;
|
||||
int margins_y;
|
||||
/* left+right and top+bottom from @shadow */
|
||||
int shadow_x;
|
||||
int shadow_y;
|
||||
|
||||
/* Set to TRUE when GTK tells us that margins are 0 everywhere.
|
||||
* We don't actually set margins to 0, we just set this bit.
|
||||
/* Set to TRUE when GTK tells us that shadow are 0 everywhere.
|
||||
* We don't actually set shadow to 0, we just set this bit.
|
||||
*/
|
||||
guint zero_margins : 1;
|
||||
guint zero_shadow : 1;
|
||||
guint inhibit_configure : 1;
|
||||
|
||||
/* Set to TRUE if window is using true layered mode adjustments
|
||||
@@ -354,6 +354,13 @@ struct _GdkWin32Surface
|
||||
int unscaled_width;
|
||||
int unscaled_height;
|
||||
|
||||
GdkToplevelLayout *toplevel_layout;
|
||||
struct {
|
||||
int configured_width;
|
||||
int configured_height;
|
||||
} next_layout;
|
||||
gboolean resized;
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
EGLSurface egl_surface;
|
||||
EGLSurface egl_dummy_surface;
|
||||
|
||||
@@ -1097,15 +1097,16 @@ handle_property_change (GdkX11DeviceManagerXI2 *device_manager,
|
||||
if (ev->what != XIPropertyDeleted &&
|
||||
device_get_tool_serial_and_id (device, &serial_id, &tool_id))
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
|
||||
seat = gdk_device_get_seat (device);
|
||||
tool = gdk_seat_get_tool (seat, serial_id, tool_id);
|
||||
tool_type = device_get_tool_type (device);
|
||||
|
||||
if (!tool && serial_id > 0)
|
||||
if (tool_type != GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
{
|
||||
GdkDeviceToolType tool_type;
|
||||
tool = gdk_seat_get_tool (seat, serial_id, tool_id, tool_type);
|
||||
|
||||
tool_type = device_get_tool_type (device);
|
||||
if (tool_type != GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
if (!tool && serial_id > 0)
|
||||
{
|
||||
tool = gdk_device_tool_new (serial_id, tool_id, tool_type, 0);
|
||||
gdk_seat_default_add_tool (GDK_SEAT_DEFAULT (seat), tool);
|
||||
|
||||
@@ -291,7 +291,7 @@ compute_toplevel_size (GdkSurface *surface,
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
|
||||
if (gdk_toplevel_layout_get_resizable (impl->toplevel_layout))
|
||||
if (!impl->toplevel_layout || gdk_toplevel_layout_get_resizable (impl->toplevel_layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
|
||||
@@ -224,7 +224,7 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
goto out;
|
||||
}
|
||||
|
||||
print_shader_info ("Fragment shader", vertex_id, resource_path);
|
||||
print_shader_info ("Fragment shader", fragment_id, resource_path);
|
||||
|
||||
program_id = glCreateProgram ();
|
||||
glAttachShader (program_id, vertex_id);
|
||||
@@ -232,6 +232,8 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
glBindAttribLocation (program_id, 0, "aPosition");
|
||||
glBindAttribLocation (program_id, 1, "vUv");
|
||||
glLinkProgram (program_id);
|
||||
glDetachShader (program_id, vertex_id);
|
||||
glDetachShader (program_id, fragment_id);
|
||||
|
||||
glGetProgramiv (program_id, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
@@ -252,14 +254,9 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
|
||||
glDeleteProgram (program_id);
|
||||
program_id = -1;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
glDetachShader (program_id, vertex_id);
|
||||
glDeleteShader (vertex_id);
|
||||
|
||||
glDetachShader (program_id, fragment_id);
|
||||
glDeleteShader (fragment_id);
|
||||
|
||||
out:
|
||||
|
||||
@@ -22,7 +22,7 @@ static guint gsk_debug_flags;
|
||||
static void
|
||||
init_debug_flags (void)
|
||||
{
|
||||
static volatile gsize gsk_debug_flags__set;
|
||||
static gsize gsk_debug_flags__set;
|
||||
|
||||
if (g_once_init_enter (&gsk_debug_flags__set))
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
static gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
|
||||
@@ -184,7 +184,7 @@ gsk_render_node_init (GskRenderNode *self)
|
||||
GType
|
||||
gsk_render_node_get_type (void)
|
||||
{
|
||||
static volatile gsize render_node_type__volatile;
|
||||
static gsize render_node_type__volatile;
|
||||
|
||||
if (g_once_init_enter (&render_node_type__volatile))
|
||||
{
|
||||
|
||||
@@ -5649,7 +5649,7 @@ gsk_render_node_init_types_once (void)
|
||||
void
|
||||
gsk_render_node_init_types (void)
|
||||
{
|
||||
static volatile gsize register_types__volatile;
|
||||
static gsize register_types__volatile;
|
||||
|
||||
if (g_once_init_enter (®ister_types__volatile))
|
||||
{
|
||||
|
||||
@@ -667,11 +667,21 @@ gtk_at_spi_root_constructed (GObject *gobject)
|
||||
{
|
||||
const char *program_name = g_get_prgname ();
|
||||
|
||||
char *base_name = NULL;
|
||||
if (program_name == NULL || *program_name == 0)
|
||||
base_name = g_strdup ("unknown");
|
||||
else if (*program_name == '/')
|
||||
base_name = g_path_get_basename (program_name);
|
||||
else
|
||||
base_name = g_strdup (program_name);
|
||||
|
||||
self->base_path = g_strconcat ("/org/gtk/application/",
|
||||
program_name != NULL ? program_name : "unknown",
|
||||
base_name,
|
||||
"/a11y",
|
||||
NULL);
|
||||
|
||||
g_free (base_name);
|
||||
|
||||
/* Turn potentially invalid program names into something that can be
|
||||
* used as a DBus path
|
||||
*/
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
static gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
* @line_chars: Number of characters parsed since the last line
|
||||
* break
|
||||
*
|
||||
* @GtkCssLocation is used to present a location in a file - or other
|
||||
* #GtkCssLocation is used to present a location in a file - or other
|
||||
* source of data parsed by the CSS engine.
|
||||
*
|
||||
* The @bytes and @line_bytes offsets are meant to be used to
|
||||
|
||||
@@ -30,6 +30,7 @@ struct _GtkCssTokenizer
|
||||
{
|
||||
int ref_count;
|
||||
GBytes *bytes;
|
||||
GString *name_buffer;
|
||||
|
||||
const char *data;
|
||||
const char *end;
|
||||
@@ -95,45 +96,13 @@ gtk_css_token_clear (GtkCssToken *token)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_initv (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
va_list args)
|
||||
gtk_css_token_init (GtkCssToken *token,
|
||||
GtkCssTokenType type)
|
||||
{
|
||||
token->type = type;
|
||||
|
||||
switch (type)
|
||||
switch ((guint)type)
|
||||
{
|
||||
case GTK_CSS_TOKEN_STRING:
|
||||
case GTK_CSS_TOKEN_IDENT:
|
||||
case GTK_CSS_TOKEN_FUNCTION:
|
||||
case GTK_CSS_TOKEN_AT_KEYWORD:
|
||||
case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
|
||||
case GTK_CSS_TOKEN_HASH_ID:
|
||||
case GTK_CSS_TOKEN_URL:
|
||||
token->string.string = va_arg (args, char *);
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_DELIM:
|
||||
token->delim.delim = va_arg (args, gunichar);
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_SIGNED_INTEGER:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_INTEGER:
|
||||
case GTK_CSS_TOKEN_SIGNED_NUMBER:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_NUMBER:
|
||||
case GTK_CSS_TOKEN_PERCENTAGE:
|
||||
token->number.number = va_arg (args, double);
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION:
|
||||
case GTK_CSS_TOKEN_DIMENSION:
|
||||
token->dimension.value = va_arg (args, double);
|
||||
token->dimension.dimension = va_arg (args, char *);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GTK_CSS_TOKEN_EOF:
|
||||
case GTK_CSS_TOKEN_WHITESPACE:
|
||||
case GTK_CSS_TOKEN_OPEN_PARENS:
|
||||
@@ -157,6 +126,8 @@ gtk_css_token_initv (GtkCssToken *token,
|
||||
case GTK_CSS_TOKEN_BAD_URL:
|
||||
case GTK_CSS_TOKEN_COMMENT:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,15 +486,76 @@ gtk_css_token_to_string (const GtkCssToken *token)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_init (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
...)
|
||||
gtk_css_token_init_string (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
char *string)
|
||||
{
|
||||
va_list args;
|
||||
token->type = type;
|
||||
|
||||
va_start (args, type);
|
||||
gtk_css_token_initv (token, type, args);
|
||||
va_end (args);
|
||||
switch ((guint)type)
|
||||
{
|
||||
case GTK_CSS_TOKEN_STRING:
|
||||
case GTK_CSS_TOKEN_IDENT:
|
||||
case GTK_CSS_TOKEN_FUNCTION:
|
||||
case GTK_CSS_TOKEN_AT_KEYWORD:
|
||||
case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
|
||||
case GTK_CSS_TOKEN_HASH_ID:
|
||||
case GTK_CSS_TOKEN_URL:
|
||||
token->string.string = string;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_init_delim (GtkCssToken *token,
|
||||
gunichar delim)
|
||||
{
|
||||
token->type = GTK_CSS_TOKEN_DELIM;
|
||||
token->delim.delim = delim;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_init_number (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
double value)
|
||||
{
|
||||
token->type = type;
|
||||
|
||||
switch ((guint)type)
|
||||
{
|
||||
case GTK_CSS_TOKEN_SIGNED_INTEGER:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_INTEGER:
|
||||
case GTK_CSS_TOKEN_SIGNED_NUMBER:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_NUMBER:
|
||||
case GTK_CSS_TOKEN_PERCENTAGE:
|
||||
token->number.number = value;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_init_dimension (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
double value,
|
||||
char *dimension)
|
||||
{
|
||||
token->type = type;
|
||||
|
||||
switch ((guint)type)
|
||||
{
|
||||
case GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION:
|
||||
case GTK_CSS_TOKEN_DIMENSION:
|
||||
token->dimension.value = value;
|
||||
token->dimension.dimension = dimension;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
GtkCssTokenizer *
|
||||
@@ -534,6 +566,7 @@ gtk_css_tokenizer_new (GBytes *bytes)
|
||||
tokenizer = g_slice_new0 (GtkCssTokenizer);
|
||||
tokenizer->ref_count = 1;
|
||||
tokenizer->bytes = g_bytes_ref (bytes);
|
||||
tokenizer->name_buffer = g_string_new (NULL);
|
||||
|
||||
tokenizer->data = g_bytes_get_data (bytes, NULL);
|
||||
tokenizer->end = tokenizer->data + g_bytes_get_size (bytes);
|
||||
@@ -558,6 +591,7 @@ gtk_css_tokenizer_unref (GtkCssTokenizer *tokenizer)
|
||||
if (tokenizer->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_string_free (tokenizer->name_buffer, TRUE);
|
||||
g_bytes_unref (tokenizer->bytes);
|
||||
g_slice_free (GtkCssTokenizer, tokenizer);
|
||||
}
|
||||
@@ -568,11 +602,7 @@ gtk_css_tokenizer_get_location (GtkCssTokenizer *tokenizer)
|
||||
return &tokenizer->position;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_tokenizer_parse_error (GError **error,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
static void
|
||||
static void G_GNUC_PRINTF(2, 3)
|
||||
gtk_css_tokenizer_parse_error (GError **error,
|
||||
const char *format,
|
||||
...)
|
||||
@@ -843,7 +873,7 @@ gtk_css_tokenizer_read_escape (GtkCssTokenizer *tokenizer)
|
||||
static char *
|
||||
gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
{
|
||||
GString *string = g_string_new (NULL);
|
||||
g_string_set_size (tokenizer->name_buffer, 0);
|
||||
|
||||
do {
|
||||
if (*tokenizer->data == '\\')
|
||||
@@ -851,7 +881,7 @@ gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
if (gtk_css_tokenizer_has_valid_escape (tokenizer))
|
||||
{
|
||||
gunichar value = gtk_css_tokenizer_read_escape (tokenizer);
|
||||
g_string_append_unichar (string, value);
|
||||
g_string_append_unichar (tokenizer->name_buffer, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -859,16 +889,16 @@ gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
|
||||
if (tokenizer->data == tokenizer->end)
|
||||
{
|
||||
g_string_append_unichar (string, 0xFFFD);
|
||||
g_string_append_unichar (tokenizer->name_buffer, 0xFFFD);
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_css_tokenizer_consume_char (tokenizer, string);
|
||||
gtk_css_tokenizer_consume_char (tokenizer, tokenizer->name_buffer);
|
||||
}
|
||||
}
|
||||
else if (is_name (*tokenizer->data))
|
||||
{
|
||||
gtk_css_tokenizer_consume_char (tokenizer, string);
|
||||
gtk_css_tokenizer_consume_char (tokenizer, tokenizer->name_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -877,7 +907,7 @@ gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
}
|
||||
while (tokenizer->data != tokenizer->end);
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
return g_strndup (tokenizer->name_buffer->str, tokenizer->name_buffer->len);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -970,7 +1000,7 @@ gtk_css_tokenizer_read_url (GtkCssTokenizer *tokenizer,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_URL, g_string_free (url, FALSE));
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_URL, g_string_free (url, FALSE));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -999,12 +1029,12 @@ gtk_css_tokenizer_read_ident_like (GtkCssTokenizer *tokenizer,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_FUNCTION, name);
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_FUNCTION, name);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_IDENT, name);
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_IDENT, name);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1017,6 +1047,7 @@ gtk_css_tokenizer_read_numeric (GtkCssTokenizer *tokenizer,
|
||||
gint64 integer, fractional = 0, fractional_length = 1, exponent = 0;
|
||||
gboolean is_int = TRUE, has_sign = FALSE;
|
||||
const char *data = tokenizer->data;
|
||||
double value;
|
||||
|
||||
if (*data == '-')
|
||||
{
|
||||
@@ -1082,27 +1113,34 @@ gtk_css_tokenizer_read_numeric (GtkCssTokenizer *tokenizer,
|
||||
|
||||
gtk_css_tokenizer_consume (tokenizer, data - tokenizer->data, data - tokenizer->data);
|
||||
|
||||
value = sign * (integer + ((double) fractional / fractional_length)) * pow (10, exponent_sign * exponent);
|
||||
|
||||
if (gtk_css_tokenizer_has_identifier (tokenizer))
|
||||
{
|
||||
gtk_css_token_init (token,
|
||||
is_int ? (has_sign ? GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION : GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION)
|
||||
: GTK_CSS_TOKEN_DIMENSION,
|
||||
sign * (integer + ((double) fractional / fractional_length)) * pow (10, exponent_sign * exponent),
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
GtkCssTokenType type;
|
||||
|
||||
if (is_int)
|
||||
type = has_sign ? GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION : GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION;
|
||||
else
|
||||
type = GTK_CSS_TOKEN_DIMENSION;
|
||||
|
||||
gtk_css_token_init_dimension (token, type, value, gtk_css_tokenizer_read_name (tokenizer));
|
||||
}
|
||||
else if (gtk_css_tokenizer_remaining (tokenizer) > 0 && *tokenizer->data == '%')
|
||||
{
|
||||
gtk_css_token_init (token,
|
||||
GTK_CSS_TOKEN_PERCENTAGE,
|
||||
sign * (integer + ((double) fractional / fractional_length)) * pow (10, exponent_sign * exponent));
|
||||
gtk_css_token_init_number (token, GTK_CSS_TOKEN_PERCENTAGE, value);
|
||||
gtk_css_tokenizer_consume_ascii (tokenizer);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init (token,
|
||||
is_int ? (has_sign ? GTK_CSS_TOKEN_SIGNED_INTEGER : GTK_CSS_TOKEN_SIGNLESS_INTEGER)
|
||||
: (has_sign ? GTK_CSS_TOKEN_SIGNED_NUMBER : GTK_CSS_TOKEN_SIGNLESS_NUMBER),
|
||||
sign * (integer + ((double) fractional / fractional_length)) * pow (10, exponent_sign * exponent));
|
||||
GtkCssTokenType type;
|
||||
|
||||
if (is_int)
|
||||
type = has_sign ? GTK_CSS_TOKEN_SIGNED_INTEGER : GTK_CSS_TOKEN_SIGNLESS_INTEGER;
|
||||
else
|
||||
type = has_sign ? GTK_CSS_TOKEN_SIGNED_NUMBER : GTK_CSS_TOKEN_SIGNLESS_NUMBER;
|
||||
|
||||
gtk_css_token_init_number (token, type,value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1110,7 +1148,7 @@ static void
|
||||
gtk_css_tokenizer_read_delim (GtkCssTokenizer *tokenizer,
|
||||
GtkCssToken *token)
|
||||
{
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, g_utf8_get_char (tokenizer->data));
|
||||
gtk_css_token_init_delim (token, g_utf8_get_char (tokenizer->data));
|
||||
gtk_css_tokenizer_consume_char (tokenizer, NULL);
|
||||
}
|
||||
|
||||
@@ -1194,8 +1232,8 @@ gtk_css_tokenizer_read_string (GtkCssTokenizer *tokenizer,
|
||||
gtk_css_tokenizer_consume_char (tokenizer, string);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_STRING, g_string_free (string, FALSE));
|
||||
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_STRING, g_string_free (string, FALSE));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1279,13 +1317,13 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
|
||||
else
|
||||
type = GTK_CSS_TOKEN_HASH_UNRESTRICTED;
|
||||
|
||||
gtk_css_token_init (token,
|
||||
type,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
gtk_css_token_init_string (token,
|
||||
type,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, '#');
|
||||
gtk_css_token_init_delim (token, '#');
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
@@ -1361,13 +1399,13 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
|
||||
gtk_css_tokenizer_consume_ascii (tokenizer);
|
||||
if (gtk_css_tokenizer_has_identifier (tokenizer))
|
||||
{
|
||||
gtk_css_token_init (token,
|
||||
GTK_CSS_TOKEN_AT_KEYWORD,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
gtk_css_token_init_string (token,
|
||||
GTK_CSS_TOKEN_AT_KEYWORD,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, '@');
|
||||
gtk_css_token_init_delim (token, '@');
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
@@ -1383,7 +1421,7 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, '\\');
|
||||
gtk_css_token_init_delim (token, '\\');
|
||||
gtk_css_tokenizer_consume_ascii (tokenizer);
|
||||
gtk_css_tokenizer_parse_error (error, "Newline may not follow '\' escape character");
|
||||
return FALSE;
|
||||
|
||||
@@ -63,6 +63,7 @@ GdkPixbuf *gtk_make_symbolic_pixbuf_from_data (const char *data,
|
||||
int width,
|
||||
int height,
|
||||
double scale,
|
||||
const char *debug_output_to,
|
||||
GError **error);
|
||||
GdkPixbuf *gtk_make_symbolic_pixbuf_from_file (GFile *file,
|
||||
int width,
|
||||
|
||||
@@ -34,6 +34,7 @@ xml += '''
|
||||
<file>theme/Empty/gtk.css</file>
|
||||
<file>theme/Adwaita/gtk.css</file>
|
||||
<file>theme/Adwaita/gtk-dark.css</file>
|
||||
<file alias='theme/Adwaita-dark/gtk.css'>theme/Adwaita/gtk-dark.css</file>
|
||||
<file>theme/Adwaita/Adwaita.css</file>
|
||||
<file>theme/Adwaita/Adwaita-dark.css</file>
|
||||
'''
|
||||
@@ -48,9 +49,10 @@ for f in get_files('theme/Adwaita/assets', '.svg'):
|
||||
|
||||
xml += '''
|
||||
<file>theme/HighContrast/gtk.css</file>
|
||||
<file alias='theme/HighContrastInverse/gtk.css'>theme/HighContrast/gtk-inverse.css</file>
|
||||
<file>theme/HighContrast/gtk-dark.css</file>
|
||||
<file alias='theme/HighContrastInverse/gtk.css'>theme/HighContrast/gtk-dark.css</file>
|
||||
<file>theme/HighContrast/HighContrast.css</file>
|
||||
<file>theme/HighContrast/HighContrast-inverse.css</file>
|
||||
<file>theme/HighContrast/HighContrast-dark.css</file>
|
||||
'''
|
||||
|
||||
for f in get_files('theme/HighContrast/assets', '.png'):
|
||||
|
||||
@@ -52,7 +52,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellRendererText, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellRendererToggle, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellView, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCheckButton, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkClipboard, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkColorButton, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkColorChooser, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkColorChooserDialog, g_object_unref)
|
||||
|
||||
@@ -101,6 +101,12 @@
|
||||
* "title", _("About ExampleCode"),
|
||||
* NULL);
|
||||
* ]|
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkAboutDialog has a single CSS node with the name window and style
|
||||
* class .aboutdialog.
|
||||
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
@@ -1644,41 +1650,7 @@ gtk_about_dialog_set_logo_icon_name (GtkAboutDialog *about,
|
||||
if (gtk_image_get_storage_type (GTK_IMAGE (about->logo_image)) == GTK_IMAGE_PAINTABLE)
|
||||
g_object_notify_by_pspec (G_OBJECT (about), props[PROP_LOGO]);
|
||||
|
||||
if (icon_name)
|
||||
{
|
||||
GtkIconTheme *icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (about)));
|
||||
int *sizes = gtk_icon_theme_get_icon_sizes (icon_theme, icon_name);
|
||||
int i, best_size = 0;
|
||||
|
||||
for (i = 0; sizes[i]; i++)
|
||||
{
|
||||
if (sizes[i] >= 128 || sizes[i] == -1)
|
||||
{
|
||||
best_size = 128;
|
||||
break;
|
||||
}
|
||||
else if (sizes[i] >= 96)
|
||||
{
|
||||
best_size = MAX (96, best_size);
|
||||
}
|
||||
else if (sizes[i] >= 64)
|
||||
{
|
||||
best_size = MAX (64, best_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
best_size = MAX (48, best_size);
|
||||
}
|
||||
}
|
||||
g_free (sizes);
|
||||
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (about->logo_image), icon_name);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (about->logo_image), best_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_image_clear (GTK_IMAGE (about->logo_image));
|
||||
}
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (about->logo_image), icon_name);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (about), props[PROP_LOGO_ICON_NAME]);
|
||||
|
||||
|
||||
@@ -324,7 +324,9 @@ icon_loaded (GObject *object,
|
||||
|
||||
- (void)didChangeToggled
|
||||
{
|
||||
[self setState:gtk_menu_tracker_item_get_toggled (trackerItem) ? NSControlStateValueOn : NSControlStateValueOff];
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
[self setState:gtk_menu_tracker_item_get_toggled (trackerItem) ? NSOnState : NSOffState];
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
- (void)didChangeAccel
|
||||
|
||||
@@ -32,17 +32,16 @@
|
||||
* @Short_description: A frame that constrains its child to a particular aspect ratio
|
||||
* @Title: GtkAspectFrame
|
||||
*
|
||||
* The #GtkAspectFrame is useful when you want
|
||||
* pack a widget so that it can resize but always retains
|
||||
* the same aspect ratio. For instance, one might be
|
||||
* drawing a small preview of a larger image. #GtkAspectFrame
|
||||
* derives from #GtkFrame, so it can draw a label and
|
||||
* a frame around the child. The frame will be
|
||||
* “shrink-wrapped” to the size of the child.
|
||||
* GtkAspectFrame is useful when you want pack a widget so that it can resize
|
||||
* while retaining the same aspect ratio. For instance, one might be drawing a
|
||||
* small preview of a larger image.
|
||||
*
|
||||
* The frame can respect the aspect ratio of the child widget, or use its own
|
||||
* aspect ratio.
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkAspectFrame uses a CSS node with name frame.
|
||||
* GtkAspectFrame uses a CSS node with name `frame`.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -138,6 +137,12 @@ gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
|
||||
widget_class->compute_expand = gtk_aspect_frame_compute_expand;
|
||||
widget_class->get_request_mode = gtk_aspect_frame_get_request_mode;
|
||||
|
||||
/**
|
||||
* GtkAspectFrame:xalign:
|
||||
*
|
||||
* The horizontal alignment of the #GtkAspectFrame:child widget
|
||||
* of the aspect frame.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_XALIGN,
|
||||
g_param_spec_float ("xalign",
|
||||
@@ -145,6 +150,12 @@ gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
|
||||
P_("X alignment of the child"),
|
||||
0.0, 1.0, 0.5,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
/**
|
||||
* GtkAspectFrame:yalign:
|
||||
*
|
||||
* The vertical alignment of the #GtkAspectFrame:child widget
|
||||
* of the aspect frame.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_YALIGN,
|
||||
g_param_spec_float ("yalign",
|
||||
@@ -152,6 +163,14 @@ gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
|
||||
P_("Y alignment of the child"),
|
||||
0.0, 1.0, 0.5,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
/**
|
||||
* GtkAspectFrame:ratio:
|
||||
*
|
||||
* The aspect ratio to be used by the #GtkAspectFrame.
|
||||
*
|
||||
* This property is only used if #GtkAspectFrame:obey-child is
|
||||
* set to %FALSE.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_RATIO,
|
||||
g_param_spec_float ("ratio",
|
||||
@@ -159,6 +178,12 @@ gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
|
||||
P_("Aspect ratio if obey_child is FALSE"),
|
||||
MIN_RATIO, MAX_RATIO, 1.0,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
/**
|
||||
* GtkAspectFrame:obey-child:
|
||||
*
|
||||
* Whether the #GtkAspectFrame should use the aspect ratio of
|
||||
* its #GtkAspectFrame:child widget.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_OBEY_CHILD,
|
||||
g_param_spec_boolean ("obey-child",
|
||||
@@ -166,7 +191,11 @@ gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
|
||||
P_("Force aspect ratio to match that of the frame’s child"),
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
* GtkAspectFrame:child:
|
||||
*
|
||||
* The child widget of the #GtkAspectFrame.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_CHILD,
|
||||
g_param_spec_object ("child",
|
||||
@@ -429,7 +458,8 @@ gtk_aspect_frame_set_ratio (GtkAspectFrame *self,
|
||||
* gtk_aspect_frame_get_ratio:
|
||||
* @self: a #GtkAspectFrame
|
||||
*
|
||||
* Returns the desired aspect ratio of the child.
|
||||
* Returns the desired aspect ratio of the child set using
|
||||
* gtk_aspect_frame_set_ratio().
|
||||
*
|
||||
* Returns: the desired aspect ratio
|
||||
*/
|
||||
|
||||
@@ -541,25 +541,27 @@ gtk_at_context_create (GtkAccessibleRole accessible_role,
|
||||
gtk_a11y_env = g_getenv ("GTK_A11Y");
|
||||
if (gtk_a11y_env == NULL)
|
||||
gtk_a11y_env = "0";
|
||||
|
||||
if (g_ascii_strcasecmp (gtk_a11y_env, "help") == 0)
|
||||
{
|
||||
g_print ("Supported arguments for GTK_A11Y environment variable:\n");
|
||||
|
||||
#if defined(GDK_WINDOWING_X11) || defined(GDK_WINDOWING_WAYLAND)
|
||||
g_print (" atspi - Use the AT-SPI accessibility backend\n");
|
||||
#endif
|
||||
g_print (" test - Use the test accessibility backend\n");
|
||||
g_print (" none - Disable the accessibility backend\n");
|
||||
g_print (" help - Print this help\n\n");
|
||||
g_print ("Other arguments will cause a warning and be ignored.\n");
|
||||
|
||||
gtk_a11y_env = "0";
|
||||
}
|
||||
}
|
||||
|
||||
/* Short-circuit disabling the accessibility support */
|
||||
if (g_ascii_strcasecmp (gtk_a11y_env, "none") == 0)
|
||||
return NULL;
|
||||
|
||||
if (g_ascii_strcasecmp (gtk_a11y_env, "help") == 0)
|
||||
{
|
||||
g_print ("Supported arguments for GTK_A11Y environment variable:\n");
|
||||
|
||||
#if defined(GDK_WINDOWING_X11) || defined(GDK_WINDOWING_WAYLAND)
|
||||
g_print (" atspi - Use the AT-SPI accessibility backend\n");
|
||||
#endif
|
||||
g_print (" test - Use the test accessibility backend\n");
|
||||
g_print (" none - Disable the accessibility backend\n");
|
||||
g_print (" help - Print this help\n\n");
|
||||
g_print ("Other arguments will cause a warning and be ignored.\n");
|
||||
}
|
||||
|
||||
GtkATContext *res = NULL;
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (a11y_backends); i++)
|
||||
|
||||
@@ -107,7 +107,7 @@ gtk_bitset_unref (GtkBitset *self)
|
||||
* @self: a #GtkBitset
|
||||
* @value: the value to check
|
||||
*
|
||||
* Checks if the given @value has been added to @bitset
|
||||
* Checks if the given @value has been added to @self
|
||||
*
|
||||
* Returns: %TRUE if @self contains @value
|
||||
**/
|
||||
|
||||
@@ -346,7 +346,7 @@ gtk_box_new (GtkOrientation orientation,
|
||||
*/
|
||||
void
|
||||
gtk_box_set_homogeneous (GtkBox *box,
|
||||
gboolean homogeneous)
|
||||
gboolean homogeneous)
|
||||
{
|
||||
GtkBoxLayout *box_layout;
|
||||
|
||||
@@ -393,7 +393,7 @@ gtk_box_get_homogeneous (GtkBox *box)
|
||||
*/
|
||||
void
|
||||
gtk_box_set_spacing (GtkBox *box,
|
||||
int spacing)
|
||||
int spacing)
|
||||
{
|
||||
GtkBoxLayout *box_layout;
|
||||
|
||||
@@ -441,7 +441,7 @@ gtk_box_get_spacing (GtkBox *box)
|
||||
*/
|
||||
void
|
||||
gtk_box_set_baseline_position (GtkBox *box,
|
||||
GtkBaselinePosition position)
|
||||
GtkBaselinePosition position)
|
||||
{
|
||||
GtkBoxLayout *box_layout;
|
||||
|
||||
|
||||
@@ -1153,9 +1153,6 @@ gtk_builder_create_bindings (GtkBuilder *builder,
|
||||
* or gtk_builder_add_from_string() in order to merge multiple UI
|
||||
* descriptions into a single builder.
|
||||
*
|
||||
* Most users will probably want to use gtk_builder_new_from_file(),
|
||||
* gtk_builder_new_from_resource() or gtk_builder_new_from_string().
|
||||
*
|
||||
* Returns: a new (empty) #GtkBuilder object
|
||||
**/
|
||||
GtkBuilder *
|
||||
@@ -1173,7 +1170,9 @@ gtk_builder_new (void)
|
||||
* Parses a file containing a [GtkBuilder UI definition][BUILDER-UI]
|
||||
* and merges it with the current contents of @builder.
|
||||
*
|
||||
* Most users will probably want to use gtk_builder_new_from_file().
|
||||
* This function is useful if you need to call gtk_builder_set_current_object()
|
||||
* to add user data to callbacks before loading GtkBuilder UI.
|
||||
* Otherwise, you probably want gtk_builder_new_from_file() instead.
|
||||
*
|
||||
* If an error occurs, 0 will be returned and @error will be assigned a
|
||||
* #GError from the #GTK_BUILDER_ERROR, #G_MARKUP_ERROR or #G_FILE_ERROR
|
||||
@@ -1367,7 +1366,9 @@ gtk_builder_extend_with_template (GtkBuilder *builder,
|
||||
* Parses a resource file containing a [GtkBuilder UI definition][BUILDER-UI]
|
||||
* and merges it with the current contents of @builder.
|
||||
*
|
||||
* Most users will probably want to use gtk_builder_new_from_resource().
|
||||
* This function is useful if you need to call gtk_builder_set_current_object()
|
||||
* to add user data to callbacks before loading GtkBuilder UI.
|
||||
* Otherwise, you probably want gtk_builder_new_from_resource() instead.
|
||||
*
|
||||
* If an error occurs, 0 will be returned and @error will be assigned a
|
||||
* #GError from the #GTK_BUILDER_ERROR, #G_MARKUP_ERROR or #G_RESOURCE_ERROR
|
||||
@@ -1517,7 +1518,9 @@ gtk_builder_add_objects_from_resource (GtkBuilder *builder,
|
||||
* Parses a string containing a [GtkBuilder UI definition][BUILDER-UI]
|
||||
* and merges it with the current contents of @builder.
|
||||
*
|
||||
* Most users will probably want to use gtk_builder_new_from_string().
|
||||
* This function is useful if you need to call gtk_builder_set_current_object()
|
||||
* to add user data to callbacks before loading GtkBuilder UI.
|
||||
* Otherwise, you probably want gtk_builder_new_from_string() instead.
|
||||
*
|
||||
* Upon errors %FALSE will be returned and @error will be assigned a
|
||||
* #GError from the #GTK_BUILDER_ERROR, #G_MARKUP_ERROR or
|
||||
|
||||
@@ -365,16 +365,17 @@ static void free_object_info (ObjectInfo *info);
|
||||
static inline void
|
||||
state_push (ParserData *data, gpointer info)
|
||||
{
|
||||
data->stack = g_slist_prepend (data->stack, info);
|
||||
g_ptr_array_add (data->stack, info);
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
state_peek (ParserData *data)
|
||||
{
|
||||
if (!data->stack)
|
||||
if (!data->stack ||
|
||||
data->stack->len == 0)
|
||||
return NULL;
|
||||
|
||||
return data->stack->data;
|
||||
return g_ptr_array_index (data->stack, data->stack->len - 1);
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
@@ -384,8 +385,9 @@ state_pop (ParserData *data)
|
||||
|
||||
g_assert (data->stack);
|
||||
|
||||
old = data->stack->data;
|
||||
data->stack = g_slist_delete_link (data->stack, data->stack);
|
||||
old = state_peek (data);
|
||||
g_assert (old);
|
||||
data->stack->len --;
|
||||
return old;
|
||||
}
|
||||
#define state_peek_info(data, st) ((st*)state_peek(data))
|
||||
@@ -2077,7 +2079,7 @@ text (GtkBuildableParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data->stack)
|
||||
if (!data->stack || data->stack->len == 0)
|
||||
return;
|
||||
|
||||
info = state_peek_info (data, CommonInfo);
|
||||
@@ -2118,41 +2120,6 @@ text (GtkBuildableParseContext *context,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_info (CommonInfo *info)
|
||||
{
|
||||
switch (info->tag_type)
|
||||
{
|
||||
case TAG_OBJECT:
|
||||
case TAG_TEMPLATE:
|
||||
free_object_info ((ObjectInfo *)info);
|
||||
break;
|
||||
case TAG_CHILD:
|
||||
free_child_info ((ChildInfo *)info);
|
||||
break;
|
||||
case TAG_BINDING:
|
||||
_free_binding_info ((BindingInfo *)info, NULL);
|
||||
break;
|
||||
case TAG_BINDING_EXPRESSION:
|
||||
free_binding_expression_info ((BindingExpressionInfo *) info);
|
||||
break;
|
||||
case TAG_PROPERTY:
|
||||
free_property_info ((PropertyInfo *)info);
|
||||
break;
|
||||
case TAG_SIGNAL:
|
||||
_free_signal_info ((SignalInfo *)info, NULL);
|
||||
break;
|
||||
case TAG_REQUIRES:
|
||||
free_requires_info ((RequiresInfo *)info, NULL);
|
||||
break;
|
||||
case TAG_EXPRESSION:
|
||||
free_expression_info ((ExpressionInfo *)info);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const GtkBuildableParser parser = {
|
||||
start_element,
|
||||
end_element,
|
||||
@@ -2186,6 +2153,7 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
data.domain = g_strdup (domain);
|
||||
data.object_ids = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify)g_free, NULL);
|
||||
data.stack = g_ptr_array_new ();
|
||||
|
||||
if (requested_objs)
|
||||
{
|
||||
@@ -2237,11 +2205,11 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
|
||||
out:
|
||||
|
||||
g_slist_free_full (data.stack, (GDestroyNotify)free_info);
|
||||
g_slist_free_full (data.custom_finalizers, (GDestroyNotify)free_subparser);
|
||||
g_slist_free (data.finalizers);
|
||||
g_free (data.domain);
|
||||
g_hash_table_destroy (data.object_ids);
|
||||
g_ptr_array_free (data.stack, TRUE);
|
||||
gtk_buildable_parse_context_free (&data.ctx);
|
||||
|
||||
/* restore the original domain */
|
||||
|
||||
@@ -173,7 +173,7 @@ typedef struct {
|
||||
const char *last_element;
|
||||
GtkBuilder *builder;
|
||||
char *domain;
|
||||
GSList *stack;
|
||||
GPtrArray *stack;
|
||||
SubParser *subparser;
|
||||
GtkBuildableParseContext ctx;
|
||||
const char *filename;
|
||||
@@ -190,8 +190,6 @@ typedef struct {
|
||||
GHashTable *object_ids;
|
||||
} ParserData;
|
||||
|
||||
typedef GType (*GTypeGetFunc) (void);
|
||||
|
||||
/* Things only GtkBuilder should use */
|
||||
GBytes * _gtk_buildable_parser_precompile (const char *text,
|
||||
gssize text_len,
|
||||
@@ -286,8 +284,5 @@ GObject *_gtk_builder_lookup_object (GtkBuilder *builder,
|
||||
int col);
|
||||
gboolean _gtk_builder_lookup_failed (GtkBuilder *builder,
|
||||
GError **error);
|
||||
GModule *gtk_builder_get_module (GtkBuilder *builder);
|
||||
|
||||
|
||||
|
||||
#endif /* __GTK_BUILDER_PRIVATE_H__ */
|
||||
|
||||
@@ -177,7 +177,7 @@ gtk_center_layout_distribute (GtkCenterLayout *self,
|
||||
center_pos = size - center_size - end_size - spacing;
|
||||
else if (center_expand)
|
||||
{
|
||||
center_size = size - 2 * MAX (start_size, end_size);
|
||||
center_size = size - 2 * (MAX (start_size, end_size) + spacing);
|
||||
center_pos = (size / 2) - (center_size / 2) + spacing;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,8 +58,15 @@
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkColorButton has a single CSS node with name button. To differentiate
|
||||
* it from a plain #GtkButton, it gets the .color style class.
|
||||
* |[<!-- language="plain" -->
|
||||
* colorbutton
|
||||
* ╰── button.color
|
||||
* ╰── [content]
|
||||
*]|
|
||||
*
|
||||
* GtkColorButton has a single CSS node with name colorbutton which
|
||||
* contains a button node. To differentiate it from a plain #GtkButton,
|
||||
* it gets the .color style class.
|
||||
*/
|
||||
|
||||
typedef struct _GtkColorButtonClass GtkColorButtonClass;
|
||||
|
||||
@@ -79,7 +79,7 @@ static inline gboolean gtk_counting_bloom_filter_may_contain (const GtkCounti
|
||||
*
|
||||
* The filter does not need to be freed.
|
||||
*/
|
||||
#define GTK_COUNTING_BLOOM_FILTER_INIT { 0, }
|
||||
#define GTK_COUNTING_BLOOM_FILTER_INIT {{0}}
|
||||
|
||||
/*
|
||||
* gtk_counting_bloom_filter_add:
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
* The most basic way to use a #GtkDropTarget to receive drops on a
|
||||
* widget is to create it via gtk_drop_target_new() passing in the
|
||||
* #GType of the data you want to receive and connect to the
|
||||
* GtkDropTarget::drop signal to receive the data:
|
||||
* #GtkDropTarget::drop signal to receive the data:
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* static gboolean
|
||||
@@ -677,9 +677,9 @@ gtk_drop_target_class_init (GtkDropTargetClass *class)
|
||||
* The value for this drop operation or %NULL if the data has not been
|
||||
* loaded yet or no drop operation is going on.
|
||||
*
|
||||
* Data may be available before the GtkDropTarget::drop signal gets emitted -
|
||||
* for example when the GtkDropTarget:preload property is set.
|
||||
* You can use the GObject::notify signal to be notified of available data.
|
||||
* Data may be available before the #GtkDropTarget::drop signal gets emitted -
|
||||
* for example when the #GtkDropTarget:preload property is set.
|
||||
* You can use the #GObject::notify signal to be notified of available data.
|
||||
*/
|
||||
properties[PROP_VALUE] =
|
||||
g_param_spec_boxed ("value",
|
||||
@@ -696,20 +696,20 @@ gtk_drop_target_class_init (GtkDropTargetClass *class)
|
||||
* @drop: the #GdkDrop
|
||||
*
|
||||
* The ::accept signal is emitted on the drop site when a drop operation
|
||||
* is about to begin.
|
||||
* is about to begin.
|
||||
* If the drop is not accepted, %FALSE will be returned and the drop target
|
||||
* will ignore the drop. If %TRUE is returned, the drop is accepted for now
|
||||
* but may be rejected later via a call to gtk_drop_target_reject() or
|
||||
* ultimately by returning %FALSE from GtkDropTarget::drop
|
||||
* ultimately by returning %FALSE from #GtkDropTarget::drop.
|
||||
*
|
||||
* The default handler for this signal decides whether to accept the drop
|
||||
* based on the formats provided by the @drop.
|
||||
*
|
||||
* If the decision whether the drop will be accepted or rejected needs
|
||||
* inspecting the data, this function should return %TRUE, the
|
||||
* GtkDropTarget:preload property should be set and the value
|
||||
* should be inspected via the GObject::notify:value signal and then call
|
||||
* gtk_drop_target_reject().
|
||||
* If the decision whether the drop will be accepted or rejected depends
|
||||
* on the data, this function should return %TRUE, the #GtkDropTarget:preload
|
||||
* property should be set and the value should be inspected via the
|
||||
* #GObject::notify:value signal, calling gtk_drop_target_reject() if
|
||||
* required.
|
||||
*
|
||||
* Returns: %TRUE if @drop is accepted
|
||||
*/
|
||||
@@ -874,8 +874,6 @@ gtk_drop_target_get_formats (GtkDropTarget *self)
|
||||
* @n_types: number of @types
|
||||
*
|
||||
* Sets the supported #GTypes for this drop target.
|
||||
*
|
||||
* The GtkDropTarget::drop signal will
|
||||
**/
|
||||
void
|
||||
gtk_drop_target_set_gtypes (GtkDropTarget *self,
|
||||
|
||||
@@ -249,7 +249,7 @@ struct _GtkExpressionWatch
|
||||
GType \
|
||||
type_name ## _get_type (void) \
|
||||
{ \
|
||||
static volatile gsize gtk_define_expression_type_id__volatile; \
|
||||
static gsize gtk_define_expression_type_id__volatile; \
|
||||
if (g_once_init_enter (>k_define_expression_type_id__volatile)) \
|
||||
{ \
|
||||
GType gtk_define_expression_type_id = \
|
||||
@@ -490,7 +490,7 @@ param_expression_values_cmp (GParamSpec *pspec,
|
||||
GType
|
||||
gtk_param_expression_get_type (void)
|
||||
{
|
||||
static volatile gsize param_expression_type__volatile;
|
||||
static gsize param_expression_type__volatile;
|
||||
|
||||
if (g_once_init_enter (¶m_expression_type__volatile))
|
||||
{
|
||||
@@ -598,7 +598,7 @@ gtk_expression_init (GtkExpression *self)
|
||||
GType
|
||||
gtk_expression_get_type (void)
|
||||
{
|
||||
static volatile gsize expression_type__volatile;
|
||||
static gsize expression_type__volatile;
|
||||
|
||||
if (g_once_init_enter (&expression_type__volatile))
|
||||
{
|
||||
|
||||
@@ -59,7 +59,14 @@
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkFontButton has a single CSS node with name fontbutton.
|
||||
* |[<!-- language="plain" -->
|
||||
* fontbutton
|
||||
* ╰── button.font
|
||||
* ╰── [content]
|
||||
*]|
|
||||
*
|
||||
* GtkFontButton has a single CSS node with name fontbutton which
|
||||
* contains a button node with the .font style class.
|
||||
*/
|
||||
|
||||
typedef struct _GtkFontButtonClass GtkFontButtonClass;
|
||||
|
||||
@@ -114,9 +114,6 @@ static void gtk_frame_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline);
|
||||
|
||||
static void gtk_frame_compute_child_allocation (GtkFrame *frame,
|
||||
GtkAllocation *child_allocation);
|
||||
static void gtk_frame_real_compute_child_allocation (GtkFrame *frame,
|
||||
GtkAllocation *child_allocation);
|
||||
|
||||
@@ -497,7 +494,7 @@ gtk_frame_size_allocate (GtkWidget *widget,
|
||||
GtkFramePrivate *priv = gtk_frame_get_instance_private (frame);
|
||||
GtkAllocation new_allocation;
|
||||
|
||||
gtk_frame_compute_child_allocation (frame, &new_allocation);
|
||||
GTK_FRAME_GET_CLASS (frame)->compute_child_allocation (frame, &new_allocation);
|
||||
|
||||
if (priv->label_widget &&
|
||||
gtk_widget_get_visible (priv->label_widget))
|
||||
@@ -529,16 +526,6 @@ gtk_frame_size_allocate (GtkWidget *widget,
|
||||
gtk_widget_size_allocate (priv->child, &new_allocation, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_frame_compute_child_allocation (GtkFrame *frame,
|
||||
GtkAllocation *child_allocation)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FRAME (frame));
|
||||
g_return_if_fail (child_allocation != NULL);
|
||||
|
||||
GTK_FRAME_GET_CLASS (frame)->compute_child_allocation (frame, child_allocation);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_frame_real_compute_child_allocation (GtkFrame *frame,
|
||||
GtkAllocation *child_allocation)
|
||||
|
||||
@@ -759,7 +759,7 @@ gtk_gesture_class_init (GtkGestureClass *klass)
|
||||
"to trigger the gesture"),
|
||||
1, G_MAXUINT, 1,
|
||||
GTK_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
/**
|
||||
* GtkGesture::begin:
|
||||
* @gesture: the object which received the signal
|
||||
|
||||
@@ -51,7 +51,8 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_DELAY_FACTOR = 1
|
||||
PROP_DELAY_FACTOR = 1,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
struct _GtkGestureLongPressPrivate
|
||||
@@ -67,15 +68,14 @@ struct _GtkGestureLongPressPrivate
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
static GParamSpec *props[LAST_PROP] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkGestureLongPress, gtk_gesture_long_press, GTK_TYPE_GESTURE_SINGLE)
|
||||
|
||||
static void
|
||||
gtk_gesture_long_press_init (GtkGestureLongPress *gesture)
|
||||
{
|
||||
GtkGestureLongPressPrivate *priv;
|
||||
|
||||
priv = gtk_gesture_long_press_get_instance_private (GTK_GESTURE_LONG_PRESS (gesture));
|
||||
GtkGestureLongPressPrivate *priv = gtk_gesture_long_press_get_instance_private (gesture);
|
||||
priv->delay_factor = 1.0;
|
||||
}
|
||||
|
||||
@@ -275,13 +275,14 @@ gtk_gesture_long_press_class_init (GtkGestureLongPressClass *klass)
|
||||
gesture_class->cancel = gtk_gesture_long_press_cancel;
|
||||
gesture_class->sequence_state_changed = gtk_gesture_long_press_sequence_state_changed;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DELAY_FACTOR,
|
||||
g_param_spec_double ("delay-factor",
|
||||
P_("Delay factor"),
|
||||
P_("Factor by which to modify the default timeout"),
|
||||
0.5, 2.0, 1.0,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
|
||||
props[PROP_DELAY_FACTOR] =
|
||||
g_param_spec_double ("delay-factor",
|
||||
P_("Delay factor"),
|
||||
P_("Factor by which to modify the default timeout"),
|
||||
0.5, 2.0, 1.0,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, props);
|
||||
|
||||
/**
|
||||
* GtkGestureLongPress::pressed:
|
||||
@@ -351,9 +352,12 @@ gtk_gesture_long_press_set_delay_factor (GtkGestureLongPress *gesture,
|
||||
g_return_if_fail (delay_factor >= 0.5);
|
||||
g_return_if_fail (delay_factor <= 2.0);
|
||||
|
||||
if (delay_factor == priv->delay_factor)
|
||||
return;
|
||||
|
||||
priv->delay_factor = delay_factor;
|
||||
|
||||
g_object_notify (G_OBJECT (gesture), "delay-factor");
|
||||
g_object_notify_by_pspec (G_OBJECT (gesture), props[PROP_DELAY_FACTOR]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtknative.h"
|
||||
|
||||
G_DEFINE_TYPE (GtkGestureStylus, gtk_gesture_stylus, GTK_TYPE_GESTURE_SINGLE)
|
||||
|
||||
@@ -319,6 +320,10 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus *gesture,
|
||||
GArray *backlog_array;
|
||||
GdkTimeCoord *history = NULL;
|
||||
guint n_coords = 0, i;
|
||||
double surf_x, surf_y;
|
||||
GtkNative *native;
|
||||
GtkWidget *event_widget;
|
||||
GtkWidget *controller_widget;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_GESTURE_STYLUS (gesture), FALSE);
|
||||
g_return_val_if_fail (backlog != NULL && n_elems != NULL, FALSE);
|
||||
@@ -331,28 +336,30 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus *gesture,
|
||||
if (!history)
|
||||
return FALSE;
|
||||
|
||||
native = gtk_widget_get_native (gtk_get_event_widget (event));
|
||||
gtk_native_get_surface_transform (native, &surf_x, &surf_y);
|
||||
|
||||
backlog_array = g_array_new (FALSE, FALSE, sizeof (GdkTimeCoord));
|
||||
event_widget = gtk_get_event_widget (event);
|
||||
controller_widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
for (i = 0; i < n_coords; i++)
|
||||
{
|
||||
GdkTimeCoord *time_coord = &history[i];
|
||||
const GdkTimeCoord *time_coord = &history[i];
|
||||
graphene_point_t p;
|
||||
|
||||
g_array_append_val (backlog_array, *time_coord);
|
||||
time_coord = &g_array_index (backlog_array, GdkTimeCoord, backlog_array->len - 1);
|
||||
if (gtk_widget_compute_point (gtk_get_event_widget (event),
|
||||
gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)),
|
||||
&GRAPHENE_POINT_INIT (time_coord->axes[GDK_AXIS_X],
|
||||
time_coord->axes[GDK_AXIS_Y]),
|
||||
if (gtk_widget_compute_point (event_widget, controller_widget,
|
||||
&GRAPHENE_POINT_INIT (time_coord->axes[GDK_AXIS_X] - surf_x,
|
||||
time_coord->axes[GDK_AXIS_Y] - surf_y),
|
||||
&p))
|
||||
{
|
||||
time_coord->axes[GDK_AXIS_X] = p.x;
|
||||
time_coord->axes[GDK_AXIS_Y] = p.y;
|
||||
GdkTimeCoord translated_coord = *time_coord;
|
||||
|
||||
translated_coord.axes[GDK_AXIS_X] = p.x;
|
||||
translated_coord.axes[GDK_AXIS_Y] = p.y;
|
||||
|
||||
g_array_append_val (backlog_array, translated_coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_array_set_size (backlog_array, backlog_array->len - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*n_elems = backlog_array->len;
|
||||
*backlog = (GdkTimeCoord *) g_array_free (backlog_array, FALSE);
|
||||
|
||||
@@ -167,7 +167,7 @@ create_window_controls (GtkHeaderBar *bar)
|
||||
g_object_bind_property (controls, "empty",
|
||||
controls, "visible",
|
||||
G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
|
||||
gtk_box_append (GTK_BOX (bar->start_box), controls);
|
||||
gtk_box_prepend (GTK_BOX (bar->start_box), controls);
|
||||
bar->start_window_controls = controls;
|
||||
|
||||
controls = gtk_window_controls_new (GTK_PACK_END);
|
||||
|
||||
@@ -348,7 +348,8 @@ gtk_icon_helper_invalidate_for_change (GtkIconHelper *self,
|
||||
GtkCssStyleChange *change)
|
||||
{
|
||||
if (change == NULL ||
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_TEXTURE))
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_TEXTURE |
|
||||
GTK_CSS_AFFECTS_ICON_SIZE))
|
||||
{
|
||||
/* Avoid the queue_resize in gtk_icon_helper_invalidate */
|
||||
g_clear_object (&self->paintable);
|
||||
|
||||
@@ -3133,7 +3133,7 @@ scan_directory (GtkIconTheme *self,
|
||||
|
||||
static GHashTable *
|
||||
scan_resource_directory (GtkIconTheme *self,
|
||||
char *full_dir,
|
||||
const char *full_dir,
|
||||
GtkStringSet *set)
|
||||
{
|
||||
GHashTable *icons = NULL;
|
||||
|
||||
@@ -24,27 +24,9 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _gtk_label_mnemonics_visible_apply_recursively (GtkWidget *widget,
|
||||
gboolean mnemonics_visible);
|
||||
int _gtk_label_get_cursor_position (GtkLabel *label);
|
||||
int _gtk_label_get_selection_bound (GtkLabel *label);
|
||||
|
||||
int _gtk_label_get_n_links (GtkLabel *label);
|
||||
int _gtk_label_get_link_at (GtkLabel *label,
|
||||
int pos);
|
||||
void _gtk_label_activate_link (GtkLabel *label,
|
||||
int idx);
|
||||
const char *_gtk_label_get_link_uri (GtkLabel *label,
|
||||
int idx);
|
||||
void _gtk_label_get_link_extent (GtkLabel *label,
|
||||
int idx,
|
||||
int *start,
|
||||
int *end);
|
||||
gboolean _gtk_label_get_link_visited (GtkLabel *label,
|
||||
int idx);
|
||||
gboolean _gtk_label_get_link_focused (GtkLabel *label,
|
||||
int idx);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_LABEL_PRIVATE_H__ */
|
||||
|
||||
@@ -27,10 +27,13 @@
|
||||
* SECTION:gtkmediastream
|
||||
* @Short_description: Display media in GTK
|
||||
* @Title: GtkMediaStream
|
||||
* @See_also: #GdkPaintable
|
||||
* @See_also: #GdkPaintable, #GtkMediaFile
|
||||
*
|
||||
* #GtkMediaStream is the integration point for media playback inside GTK.
|
||||
*
|
||||
* GTK provides an implementation of the #GtkMediaStream interface that
|
||||
* is called #GtkMediaFile.
|
||||
*
|
||||
* Apart from application-facing API for stream playback, #GtkMediaStream
|
||||
* has a number of APIs that are only useful for implementations and should
|
||||
* not be used in applications:
|
||||
|
||||
@@ -104,8 +104,14 @@
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkMenuButton has a single CSS node with name button. To differentiate
|
||||
* it from a plain #GtkButton, it gets the .popup style class.
|
||||
* |[<!-- language="plain" -->
|
||||
* menubutton
|
||||
* ╰── button.toggle
|
||||
* ╰── [content]
|
||||
*]|
|
||||
*
|
||||
* GtkMenuButton has a single CSS node with name menubutton
|
||||
* which contains a toggle button node.
|
||||
*
|
||||
* # Accessibility
|
||||
*
|
||||
|
||||
@@ -319,6 +319,7 @@ gtk_menu_section_box_insert_func (GtkMenuTrackerItem *item,
|
||||
|
||||
widget = g_object_new (GTK_TYPE_MODEL_BUTTON,
|
||||
"popover", submenu,
|
||||
"indicator-size-group", box->indicators,
|
||||
NULL);
|
||||
g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2003. 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/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -113,18 +113,6 @@ struct _GtkMessageDialogClass
|
||||
GtkDialogClass parent_class;
|
||||
};
|
||||
|
||||
static void gtk_message_dialog_constructed (GObject *object);
|
||||
static void gtk_message_dialog_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_message_dialog_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_message_dialog_add_buttons (GtkMessageDialog *message_dialog,
|
||||
GtkButtonsType buttons);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_MESSAGE_TYPE,
|
||||
@@ -139,148 +127,9 @@ enum {
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkMessageDialog, gtk_message_dialog, GTK_TYPE_DIALOG)
|
||||
|
||||
static void
|
||||
gtk_message_dialog_class_init (GtkMessageDialogClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class;
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
gobject_class->constructed = gtk_message_dialog_constructed;
|
||||
gobject_class->set_property = gtk_message_dialog_set_property;
|
||||
gobject_class->get_property = gtk_message_dialog_get_property;
|
||||
|
||||
/**
|
||||
* GtkMessageDialog:message-type:
|
||||
*
|
||||
* The type of the message.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MESSAGE_TYPE,
|
||||
g_param_spec_enum ("message-type",
|
||||
P_("Message Type"),
|
||||
P_("The type of message"),
|
||||
GTK_TYPE_MESSAGE_TYPE,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_PARAM_READWRITE|G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BUTTONS,
|
||||
g_param_spec_enum ("buttons",
|
||||
P_("Message Buttons"),
|
||||
P_("The buttons shown in the message dialog"),
|
||||
GTK_TYPE_BUTTONS_TYPE,
|
||||
GTK_BUTTONS_NONE,
|
||||
GTK_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
/**
|
||||
* GtkMessageDialog:text:
|
||||
*
|
||||
* The primary text of the message dialog. If the dialog has
|
||||
* a secondary text, this will appear as the title.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_TEXT,
|
||||
g_param_spec_string ("text",
|
||||
P_("Text"),
|
||||
P_("The primary text of the message dialog"),
|
||||
"",
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkMessageDialog:use-markup:
|
||||
*
|
||||
* %TRUE if the primary text of the dialog includes Pango markup.
|
||||
* See pango_parse_markup().
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_USE_MARKUP,
|
||||
g_param_spec_boolean ("use-markup",
|
||||
P_("Use Markup"),
|
||||
P_("The primary text of the title includes Pango markup."),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
* GtkMessageDialog:secondary-text:
|
||||
*
|
||||
* The secondary text of the message dialog.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SECONDARY_TEXT,
|
||||
g_param_spec_string ("secondary-text",
|
||||
P_("Secondary Text"),
|
||||
P_("The secondary text of the message dialog"),
|
||||
NULL,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkMessageDialog:secondary-use-markup:
|
||||
*
|
||||
* %TRUE if the secondary text of the dialog includes Pango markup.
|
||||
* See pango_parse_markup().
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SECONDARY_USE_MARKUP,
|
||||
g_param_spec_boolean ("secondary-use-markup",
|
||||
P_("Use Markup in secondary"),
|
||||
P_("The secondary text includes Pango markup."),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
* GtkMessageDialog:message-area:
|
||||
*
|
||||
* The #GtkBox that corresponds to the message area of this dialog. See
|
||||
* gtk_message_dialog_get_message_area() for a detailed description of this
|
||||
* area.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MESSAGE_AREA,
|
||||
g_param_spec_object ("message-area",
|
||||
P_("Message area"),
|
||||
P_("GtkBox that holds the dialog’s primary and secondary labels"),
|
||||
GTK_TYPE_WIDGET,
|
||||
GTK_PARAM_READABLE));
|
||||
|
||||
/* Setup Composite data */
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtkmessagedialog.ui");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkMessageDialog, label);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkMessageDialog, secondary_label);
|
||||
gtk_widget_class_bind_template_child_internal_private (widget_class, GtkMessageDialog, message_area);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_init (GtkMessageDialog *dialog)
|
||||
{
|
||||
GtkMessageDialogPrivate *priv = gtk_message_dialog_get_instance_private (dialog);
|
||||
GtkWidget *action_area;
|
||||
GtkSettings *settings;
|
||||
gboolean use_caret;
|
||||
|
||||
priv->has_primary_markup = FALSE;
|
||||
priv->has_secondary_text = FALSE;
|
||||
priv->has_primary_markup = FALSE;
|
||||
priv->has_secondary_text = FALSE;
|
||||
priv->message_type = GTK_MESSAGE_OTHER;
|
||||
|
||||
gtk_widget_add_css_class (GTK_WIDGET (dialog), "message");
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (dialog));
|
||||
action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
|
||||
gtk_widget_set_halign (action_area, GTK_ALIGN_FILL);
|
||||
gtk_box_set_homogeneous (GTK_BOX (action_area), TRUE);
|
||||
|
||||
settings = gtk_widget_get_settings (GTK_WIDGET (dialog));
|
||||
g_object_get (settings, "gtk-keynav-use-caret", &use_caret, NULL);
|
||||
gtk_label_set_selectable (GTK_LABEL (priv->label), use_caret);
|
||||
gtk_label_set_selectable (GTK_LABEL (priv->secondary_label), use_caret);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_type (GtkMessageDialog *dialog,
|
||||
GtkMessageType type)
|
||||
GtkMessageType type)
|
||||
{
|
||||
GtkMessageDialogPrivate *priv = gtk_message_dialog_get_instance_private (dialog);
|
||||
|
||||
@@ -292,6 +141,159 @@ setup_type (GtkMessageDialog *dialog,
|
||||
g_object_notify (G_OBJECT (dialog), "message-type");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_add_buttons (GtkMessageDialog *message_dialog,
|
||||
GtkButtonsType buttons)
|
||||
{
|
||||
GtkDialog* dialog = GTK_DIALOG (message_dialog);
|
||||
|
||||
switch (buttons)
|
||||
{
|
||||
case GTK_BUTTONS_NONE:
|
||||
/* nothing */
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_OK:
|
||||
gtk_dialog_add_button (dialog, _("_OK"), GTK_RESPONSE_OK);
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_CLOSE:
|
||||
gtk_dialog_add_button (dialog, _("_Close"), GTK_RESPONSE_CLOSE);
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_CANCEL:
|
||||
gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_YES_NO:
|
||||
gtk_dialog_add_button (dialog, _("_No"), GTK_RESPONSE_NO);
|
||||
gtk_dialog_add_button (dialog, _("_Yes"), GTK_RESPONSE_YES);
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_OK_CANCEL:
|
||||
gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_add_button (dialog, _("_OK"), GTK_RESPONSE_OK);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Unknown GtkButtonsType");
|
||||
break;
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (message_dialog), "buttons");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (object);
|
||||
GtkMessageDialogPrivate *priv = gtk_message_dialog_get_instance_private (dialog);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MESSAGE_TYPE:
|
||||
setup_type (dialog, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_BUTTONS:
|
||||
gtk_message_dialog_add_buttons (dialog, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_TEXT:
|
||||
if (priv->has_primary_markup)
|
||||
gtk_label_set_markup (GTK_LABEL (priv->label), g_value_get_string (value));
|
||||
else
|
||||
gtk_label_set_text (GTK_LABEL (priv->label), g_value_get_string (value));
|
||||
break;
|
||||
case PROP_USE_MARKUP:
|
||||
if (priv->has_primary_markup != g_value_get_boolean (value))
|
||||
{
|
||||
priv->has_primary_markup = g_value_get_boolean (value);
|
||||
gtk_label_set_use_markup (GTK_LABEL (priv->label), priv->has_primary_markup);
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
break;
|
||||
case PROP_SECONDARY_TEXT:
|
||||
{
|
||||
const char *txt = g_value_get_string (value);
|
||||
|
||||
if (gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)))
|
||||
gtk_label_set_markup (GTK_LABEL (priv->secondary_label), txt);
|
||||
else
|
||||
gtk_label_set_text (GTK_LABEL (priv->secondary_label), txt);
|
||||
|
||||
if (txt)
|
||||
{
|
||||
priv->has_secondary_text = TRUE;
|
||||
gtk_widget_add_css_class (priv->label, "title");
|
||||
gtk_widget_show (priv->secondary_label);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->has_secondary_text = FALSE;
|
||||
gtk_widget_remove_css_class (priv->label, "title");
|
||||
gtk_widget_hide (priv->secondary_label);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_SECONDARY_USE_MARKUP:
|
||||
if (gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)) != g_value_get_boolean (value))
|
||||
{
|
||||
gtk_label_set_use_markup (GTK_LABEL (priv->secondary_label), g_value_get_boolean (value));
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (object);
|
||||
GtkMessageDialogPrivate *priv = gtk_message_dialog_get_instance_private (dialog);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MESSAGE_TYPE:
|
||||
g_value_set_enum (value, (GtkMessageType) priv->message_type);
|
||||
break;
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (priv->label)));
|
||||
break;
|
||||
case PROP_USE_MARKUP:
|
||||
g_value_set_boolean (value, priv->has_primary_markup);
|
||||
break;
|
||||
case PROP_SECONDARY_TEXT:
|
||||
if (priv->has_secondary_text)
|
||||
g_value_set_string (value,
|
||||
gtk_label_get_label (GTK_LABEL (priv->secondary_label)));
|
||||
else
|
||||
g_value_set_string (value, NULL);
|
||||
break;
|
||||
case PROP_SECONDARY_USE_MARKUP:
|
||||
if (priv->has_secondary_text)
|
||||
g_value_set_boolean (value,
|
||||
gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)));
|
||||
else
|
||||
g_value_set_boolean (value, FALSE);
|
||||
break;
|
||||
case PROP_MESSAGE_AREA:
|
||||
g_value_set_object (value, priv->message_area);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_title (GObject *dialog,
|
||||
GParamSpec *pspec,
|
||||
@@ -338,115 +340,137 @@ gtk_message_dialog_constructed (GObject *object)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
static void
|
||||
gtk_message_dialog_class_init (GtkMessageDialogClass *class)
|
||||
{
|
||||
GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (object);
|
||||
GtkMessageDialogPrivate *priv = gtk_message_dialog_get_instance_private (dialog);
|
||||
GtkWidgetClass *widget_class;
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MESSAGE_TYPE:
|
||||
setup_type (dialog, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_BUTTONS:
|
||||
gtk_message_dialog_add_buttons (dialog, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_TEXT:
|
||||
if (priv->has_primary_markup)
|
||||
gtk_label_set_markup (GTK_LABEL (priv->label),
|
||||
g_value_get_string (value));
|
||||
else
|
||||
gtk_label_set_text (GTK_LABEL (priv->label),
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_USE_MARKUP:
|
||||
if (priv->has_primary_markup != g_value_get_boolean (value))
|
||||
{
|
||||
priv->has_primary_markup = g_value_get_boolean (value);
|
||||
gtk_label_set_use_markup (GTK_LABEL (priv->label), priv->has_primary_markup);
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
break;
|
||||
case PROP_SECONDARY_TEXT:
|
||||
{
|
||||
const char *txt = g_value_get_string (value);
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
if (gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)))
|
||||
gtk_label_set_markup (GTK_LABEL (priv->secondary_label), txt);
|
||||
else
|
||||
gtk_label_set_text (GTK_LABEL (priv->secondary_label), txt);
|
||||
gobject_class->constructed = gtk_message_dialog_constructed;
|
||||
gobject_class->set_property = gtk_message_dialog_set_property;
|
||||
gobject_class->get_property = gtk_message_dialog_get_property;
|
||||
|
||||
if (txt)
|
||||
{
|
||||
priv->has_secondary_text = TRUE;
|
||||
gtk_widget_show (priv->secondary_label);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->has_secondary_text = FALSE;
|
||||
gtk_widget_hide (priv->secondary_label);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_SECONDARY_USE_MARKUP:
|
||||
if (gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)) != g_value_get_boolean (value))
|
||||
{
|
||||
gtk_label_set_use_markup (GTK_LABEL (priv->secondary_label), g_value_get_boolean (value));
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
break;
|
||||
/**
|
||||
* GtkMessageDialog:message-type:
|
||||
*
|
||||
* The type of the message.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MESSAGE_TYPE,
|
||||
g_param_spec_enum ("message-type",
|
||||
P_("Message Type"),
|
||||
P_("The type of message"),
|
||||
GTK_TYPE_MESSAGE_TYPE,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_PARAM_READWRITE|G_PARAM_CONSTRUCT|G_PARAM_EXPLICIT_NOTIFY));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BUTTONS,
|
||||
g_param_spec_enum ("buttons",
|
||||
P_("Message Buttons"),
|
||||
P_("The buttons shown in the message dialog"),
|
||||
GTK_TYPE_BUTTONS_TYPE,
|
||||
GTK_BUTTONS_NONE,
|
||||
GTK_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
|
||||
/**
|
||||
* GtkMessageDialog:text:
|
||||
*
|
||||
* The primary text of the message dialog. If the dialog has
|
||||
* a secondary text, this will appear as the title.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_TEXT,
|
||||
g_param_spec_string ("text",
|
||||
P_("Text"),
|
||||
P_("The primary text of the message dialog"),
|
||||
"",
|
||||
GTK_PARAM_READWRITE));
|
||||
/**
|
||||
* GtkMessageDialog:use-markup:
|
||||
*
|
||||
* %TRUE if the primary text of the dialog includes Pango markup.
|
||||
* See pango_parse_markup().
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_USE_MARKUP,
|
||||
g_param_spec_boolean ("use-markup",
|
||||
P_("Use Markup"),
|
||||
P_("The primary text of the title includes Pango markup."),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
/**
|
||||
* GtkMessageDialog:secondary-text:
|
||||
*
|
||||
* The secondary text of the message dialog.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SECONDARY_TEXT,
|
||||
g_param_spec_string ("secondary-text",
|
||||
P_("Secondary Text"),
|
||||
P_("The secondary text of the message dialog"),
|
||||
NULL,
|
||||
GTK_PARAM_READWRITE));
|
||||
/**
|
||||
* GtkMessageDialog:secondary-use-markup:
|
||||
*
|
||||
* %TRUE if the secondary text of the dialog includes Pango markup.
|
||||
* See pango_parse_markup().
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SECONDARY_USE_MARKUP,
|
||||
g_param_spec_boolean ("secondary-use-markup",
|
||||
P_("Use Markup in secondary"),
|
||||
P_("The secondary text includes Pango markup."),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
/**
|
||||
* GtkMessageDialog:message-area:
|
||||
*
|
||||
* The #GtkBox that corresponds to the message area of this dialog. See
|
||||
* gtk_message_dialog_get_message_area() for a detailed description of this
|
||||
* area.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MESSAGE_AREA,
|
||||
g_param_spec_object ("message-area",
|
||||
P_("Message area"),
|
||||
P_("GtkBox that holds the dialog’s primary and secondary labels"),
|
||||
GTK_TYPE_WIDGET,
|
||||
GTK_PARAM_READABLE));
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtkmessagedialog.ui");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkMessageDialog, label);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkMessageDialog, secondary_label);
|
||||
gtk_widget_class_bind_template_child_internal_private (widget_class, GtkMessageDialog, message_area);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
static void
|
||||
gtk_message_dialog_init (GtkMessageDialog *dialog)
|
||||
{
|
||||
GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (object);
|
||||
GtkMessageDialogPrivate *priv = gtk_message_dialog_get_instance_private (dialog);
|
||||
GtkWidget *action_area;
|
||||
GtkSettings *settings;
|
||||
gboolean use_caret;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MESSAGE_TYPE:
|
||||
g_value_set_enum (value, (GtkMessageType) priv->message_type);
|
||||
break;
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, gtk_label_get_label (GTK_LABEL (priv->label)));
|
||||
break;
|
||||
case PROP_USE_MARKUP:
|
||||
g_value_set_boolean (value, priv->has_primary_markup);
|
||||
break;
|
||||
case PROP_SECONDARY_TEXT:
|
||||
if (priv->has_secondary_text)
|
||||
g_value_set_string (value,
|
||||
gtk_label_get_label (GTK_LABEL (priv->secondary_label)));
|
||||
else
|
||||
g_value_set_string (value, NULL);
|
||||
break;
|
||||
case PROP_SECONDARY_USE_MARKUP:
|
||||
if (priv->has_secondary_text)
|
||||
g_value_set_boolean (value,
|
||||
gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)));
|
||||
else
|
||||
g_value_set_boolean (value, FALSE);
|
||||
break;
|
||||
case PROP_MESSAGE_AREA:
|
||||
g_value_set_object (value, priv->message_area);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
priv->has_primary_markup = FALSE;
|
||||
priv->has_secondary_text = FALSE;
|
||||
priv->has_primary_markup = FALSE;
|
||||
priv->has_secondary_text = FALSE;
|
||||
priv->message_type = GTK_MESSAGE_OTHER;
|
||||
|
||||
gtk_widget_add_css_class (GTK_WIDGET (dialog), "message");
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (dialog));
|
||||
action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
|
||||
gtk_widget_set_halign (action_area, GTK_ALIGN_FILL);
|
||||
gtk_box_set_homogeneous (GTK_BOX (action_area), TRUE);
|
||||
|
||||
settings = gtk_widget_get_settings (GTK_WIDGET (dialog));
|
||||
g_object_get (settings, "gtk-keynav-use-caret", &use_caret, NULL);
|
||||
gtk_label_set_selectable (GTK_LABEL (priv->label), use_caret);
|
||||
gtk_label_set_selectable (GTK_LABEL (priv->secondary_label), use_caret);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -482,9 +506,9 @@ gtk_message_dialog_new (GtkWindow *parent,
|
||||
|
||||
widget = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
|
||||
"use-header-bar", FALSE,
|
||||
"message-type", type,
|
||||
"buttons", buttons,
|
||||
NULL);
|
||||
"message-type", type,
|
||||
"buttons", buttons,
|
||||
NULL);
|
||||
dialog = GTK_DIALOG (widget);
|
||||
|
||||
if (message_format)
|
||||
@@ -545,7 +569,7 @@ gtk_message_dialog_new (GtkWindow *parent,
|
||||
* gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
|
||||
* markup);
|
||||
* ]|
|
||||
*
|
||||
*
|
||||
* Returns: a new #GtkMessageDialog
|
||||
**/
|
||||
GtkWidget*
|
||||
@@ -582,7 +606,7 @@ gtk_message_dialog_new_with_markup (GtkWindow *parent,
|
||||
* gtk_message_dialog_set_markup:
|
||||
* @message_dialog: a #GtkMessageDialog
|
||||
* @str: markup string (see [Pango markup format][PangoMarkupFormat])
|
||||
*
|
||||
*
|
||||
* Sets the text of the message dialog to be @str, which is marked
|
||||
* up with the [Pango text markup language][PangoMarkupFormat].
|
||||
**/
|
||||
@@ -621,6 +645,7 @@ gtk_message_dialog_format_secondary_text (GtkMessageDialog *message_dialog,
|
||||
if (message_format)
|
||||
{
|
||||
priv->has_secondary_text = TRUE;
|
||||
gtk_widget_add_css_class (priv->label, "title");
|
||||
|
||||
va_start (args, message_format);
|
||||
msg = g_strdup_vprintf (message_format, args);
|
||||
@@ -634,6 +659,7 @@ gtk_message_dialog_format_secondary_text (GtkMessageDialog *message_dialog,
|
||||
else
|
||||
{
|
||||
priv->has_secondary_text = FALSE;
|
||||
gtk_widget_remove_css_class (priv->label, "title");
|
||||
gtk_widget_hide (priv->secondary_label);
|
||||
}
|
||||
}
|
||||
@@ -677,6 +703,7 @@ gtk_message_dialog_format_secondary_markup (GtkMessageDialog *message_dialog,
|
||||
if (message_format)
|
||||
{
|
||||
priv->has_secondary_text = TRUE;
|
||||
gtk_widget_add_css_class (priv->label, "title");
|
||||
|
||||
va_start (args, message_format);
|
||||
msg = g_strdup_vprintf (message_format, args);
|
||||
@@ -690,6 +717,7 @@ gtk_message_dialog_format_secondary_markup (GtkMessageDialog *message_dialog,
|
||||
else
|
||||
{
|
||||
priv->has_secondary_text = FALSE;
|
||||
gtk_widget_remove_css_class (priv->label, "title");
|
||||
gtk_widget_hide (priv->secondary_label);
|
||||
}
|
||||
}
|
||||
@@ -717,45 +745,3 @@ gtk_message_dialog_get_message_area (GtkMessageDialog *message_dialog)
|
||||
return priv->message_area;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_add_buttons (GtkMessageDialog* message_dialog,
|
||||
GtkButtonsType buttons)
|
||||
{
|
||||
GtkDialog* dialog = GTK_DIALOG (message_dialog);
|
||||
|
||||
switch (buttons)
|
||||
{
|
||||
case GTK_BUTTONS_NONE:
|
||||
/* nothing */
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_OK:
|
||||
gtk_dialog_add_button (dialog, _("_OK"), GTK_RESPONSE_OK);
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_CLOSE:
|
||||
gtk_dialog_add_button (dialog, _("_Close"), GTK_RESPONSE_CLOSE);
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_CANCEL:
|
||||
gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_YES_NO:
|
||||
gtk_dialog_add_button (dialog, _("_No"), GTK_RESPONSE_NO);
|
||||
gtk_dialog_add_button (dialog, _("_Yes"), GTK_RESPONSE_YES);
|
||||
break;
|
||||
|
||||
case GTK_BUTTONS_OK_CANCEL:
|
||||
gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_add_button (dialog, _("_OK"), GTK_RESPONSE_OK);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Unknown GtkButtonsType");
|
||||
break;
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (message_dialog), "buttons");
|
||||
}
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@ update_node_name (GtkModelButton *self)
|
||||
{
|
||||
case GTK_BUTTON_ROLE_TITLE:
|
||||
start_name = "arrow";
|
||||
end_name = NULL;
|
||||
end_name = "";
|
||||
break;
|
||||
case GTK_BUTTON_ROLE_NORMAL:
|
||||
start_name = NULL;
|
||||
|
||||
@@ -1713,7 +1713,7 @@ gtk_print_operation_run_with_dialog (GtkPrintOperation *op,
|
||||
GtkPrintOperationPrivate *priv;
|
||||
IPrintDialogCallback *callback;
|
||||
HPROPSHEETPAGE prop_page;
|
||||
static volatile gsize common_controls_initialized = 0;
|
||||
static gsize common_controls_initialized = 0;
|
||||
|
||||
if (g_once_init_enter (&common_controls_initialized))
|
||||
{
|
||||
|
||||
@@ -307,7 +307,8 @@ GtkPageSetup *gtk_print_run_page_setup_dialog (GtkWindow
|
||||
|
||||
/**
|
||||
* GtkPageSetupDoneFunc:
|
||||
* @page_setup: the #GtkPageSetup that has been
|
||||
* @page_setup: the #GtkPageSetup that has been passed to
|
||||
* gtk_print_run_page_setup_dialog_async()
|
||||
* @data: (closure): user data that has been passed to
|
||||
* gtk_print_run_page_setup_dialog_async()
|
||||
*
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
GType
|
||||
_@enum_name@_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
static gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
|
||||
@@ -368,32 +368,6 @@ gtk_render_layout (GtkStyleContext *context,
|
||||
gsk_render_node_unref (node);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_do_render_line (GtkStyleContext *context,
|
||||
cairo_t *cr,
|
||||
double x0,
|
||||
double y0,
|
||||
double x1,
|
||||
double y1)
|
||||
{
|
||||
const GdkRGBA *color;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
color = gtk_css_color_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR));
|
||||
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
|
||||
cairo_set_line_width (cr, 1);
|
||||
|
||||
cairo_move_to (cr, x0 + 0.5, y0 + 0.5);
|
||||
cairo_line_to (cr, x1 + 0.5, y1 + 0.5);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, color);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_render_line:
|
||||
* @context: a #GtkStyleContext
|
||||
@@ -413,10 +387,25 @@ gtk_render_line (GtkStyleContext *context,
|
||||
double x1,
|
||||
double y1)
|
||||
{
|
||||
const GdkRGBA *color;
|
||||
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
||||
g_return_if_fail (cr != NULL);
|
||||
|
||||
gtk_do_render_line (context, cr, x0, y0, x1, y1);
|
||||
cairo_save (cr);
|
||||
|
||||
color = gtk_css_color_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR));
|
||||
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
|
||||
cairo_set_line_width (cr, 1);
|
||||
|
||||
cairo_move_to (cr, x0 + 0.5, y0 + 0.5);
|
||||
cairo_line_to (cr, x1 + 0.5, y1 + 0.5);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, color);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1087,11 +1087,7 @@ static void
|
||||
indicator_set_over (Indicator *indicator,
|
||||
gboolean over)
|
||||
{
|
||||
if (indicator->over_timeout_id)
|
||||
{
|
||||
g_source_remove (indicator->over_timeout_id);
|
||||
indicator->over_timeout_id = 0;
|
||||
}
|
||||
g_clear_handle_id (&indicator->over_timeout_id, g_source_remove);
|
||||
|
||||
if (indicator->over == over)
|
||||
return;
|
||||
@@ -1170,11 +1166,8 @@ check_update_scrollbar_proximity (GtkScrolledWindow *sw,
|
||||
gtk_widget_is_ancestor (target, priv->hindicator.scrollbar) ||
|
||||
gtk_widget_is_ancestor (target, priv->vindicator.scrollbar)));
|
||||
|
||||
if (indicator->over_timeout_id)
|
||||
{
|
||||
g_source_remove (indicator->over_timeout_id);
|
||||
indicator->over_timeout_id = 0;
|
||||
}
|
||||
|
||||
g_clear_handle_id (&indicator->over_timeout_id, g_source_remove);
|
||||
|
||||
if (on_scrollbar)
|
||||
indicator_set_over (indicator, TRUE);
|
||||
@@ -1374,11 +1367,7 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
|
||||
new_value);
|
||||
}
|
||||
|
||||
if (priv->scroll_events_overshoot_id)
|
||||
{
|
||||
g_source_remove (priv->scroll_events_overshoot_id);
|
||||
priv->scroll_events_overshoot_id = 0;
|
||||
}
|
||||
g_clear_handle_id (&priv->scroll_events_overshoot_id, g_source_remove);
|
||||
|
||||
if (!priv->smooth_scroll &&
|
||||
_gtk_scrolled_window_get_overshoot (scrolled_window, NULL, NULL))
|
||||
@@ -2610,12 +2599,7 @@ gtk_scrolled_window_dispose (GObject *object)
|
||||
|
||||
g_clear_pointer (&priv->hscrolling, gtk_kinetic_scrolling_free);
|
||||
g_clear_pointer (&priv->vscrolling, gtk_kinetic_scrolling_free);
|
||||
|
||||
if (priv->scroll_events_overshoot_id)
|
||||
{
|
||||
g_source_remove (priv->scroll_events_overshoot_id);
|
||||
priv->scroll_events_overshoot_id = 0;
|
||||
}
|
||||
g_clear_handle_id (&priv->scroll_events_overshoot_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (gtk_scrolled_window_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -3547,17 +3531,8 @@ gtk_scrolled_window_map (GtkWidget *widget)
|
||||
static void
|
||||
indicator_reset (Indicator *indicator)
|
||||
{
|
||||
if (indicator->conceil_timer)
|
||||
{
|
||||
g_source_remove (indicator->conceil_timer);
|
||||
indicator->conceil_timer = 0;
|
||||
}
|
||||
|
||||
if (indicator->over_timeout_id)
|
||||
{
|
||||
g_source_remove (indicator->over_timeout_id);
|
||||
indicator->over_timeout_id = 0;
|
||||
}
|
||||
g_clear_handle_id (&indicator->conceil_timer, g_source_remove);
|
||||
g_clear_handle_id (&indicator->over_timeout_id, g_source_remove);
|
||||
|
||||
if (indicator->scrollbar && indicator->tick_id)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
|
||||
/*
|
||||
* Main functionality
|
||||
|
||||
@@ -95,11 +95,6 @@
|
||||
* to use gtk_widget_get_settings().
|
||||
*/
|
||||
|
||||
|
||||
#define DEFAULT_TIMEOUT_INITIAL 500
|
||||
#define DEFAULT_TIMEOUT_REPEAT 50
|
||||
#define DEFAULT_TIMEOUT_EXPAND 500
|
||||
|
||||
typedef struct _GtkSettingsClass GtkSettingsClass;
|
||||
typedef struct _GtkSettingsPropertyValue GtkSettingsPropertyValue;
|
||||
typedef struct _GtkSettingsValuePrivate GtkSettingsValuePrivate;
|
||||
@@ -241,6 +236,7 @@ static void
|
||||
gtk_settings_init (GtkSettings *settings)
|
||||
{
|
||||
GParamSpec **pspecs, **p;
|
||||
guint n_pspecs;
|
||||
guint i = 0;
|
||||
char *path;
|
||||
const char * const *config_dirs;
|
||||
@@ -255,14 +251,11 @@ gtk_settings_init (GtkSettings *settings)
|
||||
* notification for them (at least notification for internal properties
|
||||
* will instantly be caught)
|
||||
*/
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), NULL);
|
||||
for (p = pspecs; *p; p++)
|
||||
if ((*p)->owner_type == G_OBJECT_TYPE (settings))
|
||||
i++;
|
||||
settings->property_values = g_new0 (GtkSettingsPropertyValue, i);
|
||||
i = 0;
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), &n_pspecs);
|
||||
settings->property_values = g_new0 (GtkSettingsPropertyValue, n_pspecs);
|
||||
g_object_freeze_notify (G_OBJECT (settings));
|
||||
|
||||
i = 0;
|
||||
for (p = pspecs; *p; p++)
|
||||
{
|
||||
GParamSpec *pspec = *p;
|
||||
@@ -280,27 +273,23 @@ gtk_settings_init (GtkSettings *settings)
|
||||
g_free (pspecs);
|
||||
|
||||
path = g_build_filename (_gtk_get_data_prefix (), "share", "gtk-4.0", "settings.ini", NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT);
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT);
|
||||
g_free (path);
|
||||
|
||||
path = g_build_filename (_gtk_get_sysconfdir (), "gtk-4.0", "settings.ini", NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT);
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT);
|
||||
g_free (path);
|
||||
|
||||
config_dirs = g_get_system_config_dirs ();
|
||||
for (i = 0; config_dirs[i] != NULL; i++)
|
||||
{
|
||||
path = g_build_filename (config_dirs[i], "gtk-4.0", "settings.ini", NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT);
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
path = g_build_filename (g_get_user_config_dir (), "gtk-4.0", "settings.ini", NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT);
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT);
|
||||
g_free (path);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (settings));
|
||||
@@ -1695,8 +1684,7 @@ settings_update_theme (GtkSettings *settings)
|
||||
if (theme_dir)
|
||||
{
|
||||
path = g_build_filename (theme_dir, "settings.ini", NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_THEME);
|
||||
gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_THEME);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
@@ -1733,13 +1721,18 @@ gtk_settings_load_from_key_file (GtkSettings *settings,
|
||||
char **keys;
|
||||
gsize n_keys;
|
||||
int i;
|
||||
char *contents;
|
||||
gsize contents_len;
|
||||
|
||||
if (!g_file_get_contents (path, &contents, &contents_len, NULL))
|
||||
return;
|
||||
|
||||
error = NULL;
|
||||
keys = NULL;
|
||||
|
||||
keyfile = g_key_file_new ();
|
||||
|
||||
if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, &error))
|
||||
if (!g_key_file_load_from_data (keyfile, contents, contents_len, G_KEY_FILE_NONE, &error))
|
||||
{
|
||||
g_warning ("Failed to parse %s: %s", path, error->message);
|
||||
|
||||
@@ -1850,6 +1843,7 @@ gtk_settings_load_from_key_file (GtkSettings *settings,
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (contents);
|
||||
g_strfreev (keys);
|
||||
g_key_file_free (keyfile);
|
||||
}
|
||||
|
||||