Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 805f3bb123 |
@@ -43,7 +43,6 @@ style-check-diff:
|
||||
- .gitlab-ci/run-style-check-diff.sh
|
||||
|
||||
.build-fedora-default:
|
||||
extends: .only-default
|
||||
image: $FEDORA_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -122,7 +121,6 @@ installed-tests:
|
||||
|
||||
|
||||
.mingw-defaults:
|
||||
extends: .only-default
|
||||
stage: build
|
||||
tags:
|
||||
- win32-ps
|
||||
@@ -146,31 +144,6 @@ 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
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eux -o pipefail
|
||||
|
||||
xcodebuild -version || :
|
||||
xcodebuild -showsdks || :
|
||||
|
||||
system_profiler SPSoftwareDataType || :
|
||||
@@ -1,132 +1,3 @@
|
||||
Overview of Changes in 4.0.2
|
||||
============================
|
||||
|
||||
* GtkAboutDialog:
|
||||
- Set icon size for the logo
|
||||
- Fix initial focus to be the same as in GTK 3
|
||||
|
||||
* GtkImage:
|
||||
- Update icons on scale change
|
||||
|
||||
* Wayland: Fix crashes with touch and tablet events
|
||||
|
||||
* Windows:
|
||||
- Fix surface and geometry computation
|
||||
- Remove layered window usage
|
||||
|
||||
* MacOS: Support stylus devices
|
||||
|
||||
* Themes:
|
||||
- Adwaita: Remove edge highlights
|
||||
- Adwaita: Update image assets
|
||||
- Make Adwaita-dark available as standalone theme
|
||||
- Make HighContrastInverse the dark variant of HighContrast
|
||||
|
||||
* Docs:
|
||||
- Complete GtkAspectFrame docs
|
||||
- Clarify migration docs for widget signals
|
||||
|
||||
* Inspector:
|
||||
- Fix a critical with the recorder
|
||||
- Fix a crash with treeviews
|
||||
- Show overlay layout properties
|
||||
- Add a legend for the layout overlay
|
||||
|
||||
* Build:
|
||||
- Fix build with gcc 11
|
||||
- Support building without sassc
|
||||
|
||||
* Translation updates:
|
||||
Basque
|
||||
Czech
|
||||
Friulian
|
||||
Polish
|
||||
Romanian
|
||||
Spanish
|
||||
Swedish
|
||||
Ukrainian
|
||||
|
||||
|
||||
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
|
||||
==============================
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/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,9 +98,6 @@ 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,12 +119,13 @@ create_label (void)
|
||||
static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkWidget *w = gtk_video_new ();
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
|
||||
|
||||
gtk_widget_set_size_request (w, 64, 64);
|
||||
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");
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
@@ -787,8 +787,6 @@ 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,6 +3298,7 @@ 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>
|
||||
|
||||
@@ -146,9 +146,6 @@ 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 ]
|
||||
|
||||
@@ -41,41 +41,35 @@
|
||||
<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>
|
||||
<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>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>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Simplify Options</title>
|
||||
|
||||
@@ -61,13 +61,6 @@
|
||||
<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,6 +4668,7 @@ GTK_WINDOW_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
GtkWindowPrivate
|
||||
gtk_window_get_type
|
||||
GtkWindowGeometryInfo
|
||||
gtk_window_remove_embedded_xid
|
||||
gtk_window_add_embedded_xid
|
||||
GtkWindowKeysForeachFunc
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 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 |
@@ -413,6 +413,10 @@ 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 | - |
|
||||
| ::configure-event | replaced by #GdkSurface::layout |
|
||||
| ::focus-in-event | #GtkEventControllerFocus |
|
||||
| ::focus-out-event | #GtkEventControllerFocus |
|
||||
| ::map-event | - |
|
||||
| ::unmap-event | - |
|
||||
| ::map-event | replaced by #GdkSurface:mapped |
|
||||
| ::unmap-event | replaced by #GdkSurface:mapped |
|
||||
| ::property-notify-event | replaced by #GdkClipboard |
|
||||
| ::selection-clear-event | replaced by #GdkClipboard |
|
||||
| ::selection-request-event | replaced by #GdkClipboard |
|
||||
@@ -178,17 +178,10 @@ for this change.
|
||||
| ::proximity-in-event | #GtkGestureStylus |
|
||||
| ::proximity-out-event | #GtkGestureStylus |
|
||||
| ::visibility-notify-event | - |
|
||||
| ::window-state-event | - |
|
||||
| ::window-state-event | replaced by #GdkToplevel:state |
|
||||
| ::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'
|
||||
@@ -271,6 +264,14 @@ 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
|
||||
@@ -406,7 +407,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
|
||||
@@ -425,88 +426,13 @@ 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.
|
||||
|
||||
### 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
|
||||
### Stop using gtk_get_current_... APIs
|
||||
|
||||
The function gtk_get_current_event() and its variants have been
|
||||
replaced by equivalent event controller APIs:
|
||||
@@ -522,25 +448,6 @@ 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
|
||||
@@ -551,23 +458,6 @@ 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.
|
||||
@@ -861,8 +751,7 @@ 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. If you want to track the size of toplevel windows, use
|
||||
property notification for #GtkWindow:default-width and #GtkWindow:default-height.
|
||||
signals.
|
||||
|
||||
### Switch to GtkWidget's children APIs
|
||||
|
||||
|
||||
@@ -611,7 +611,17 @@ _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));
|
||||
|
||||
g_set_object (&device->associated, 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 gsize g_define_type_id__volatile = 0;
|
||||
static volatile 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 gsize event_type__volatile;
|
||||
static volatile 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 gsize gdk_define_event_type_id__volatile; \
|
||||
static volatile 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 gsize event_types__volatile;
|
||||
static volatile gsize event_types__volatile;
|
||||
|
||||
if (g_once_init_enter (&event_types__volatile))
|
||||
{
|
||||
|
||||
@@ -107,9 +107,6 @@ make_program (GdkGLContextProgram *program,
|
||||
|
||||
glLinkProgram (program->program);
|
||||
|
||||
glDetachShader (program->program, vertex_shader);
|
||||
glDetachShader (program->program, fragment_shader);
|
||||
|
||||
glDeleteShader (vertex_shader);
|
||||
glDeleteShader (fragment_shader);
|
||||
|
||||
|
||||
@@ -30,37 +30,6 @@
|
||||
* 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,10 +436,9 @@ gdk_seat_tool_removed (GdkSeat *seat,
|
||||
}
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id,
|
||||
GdkDeviceToolType type)
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id)
|
||||
{
|
||||
GdkDeviceTool *match = NULL;
|
||||
GList *tools, *l;
|
||||
@@ -450,7 +449,7 @@ gdk_seat_get_tool (GdkSeat *seat,
|
||||
{
|
||||
GdkDeviceTool *tool = l->data;
|
||||
|
||||
if (tool->serial == serial && tool->hw_id == hw_id && tool->type == type)
|
||||
if (tool->serial == serial && tool->hw_id == hw_id)
|
||||
{
|
||||
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_default_dispose (GObject *object)
|
||||
gdk_seat_dispose (GObject *object)
|
||||
{
|
||||
GdkSeatDefault *seat = GDK_SEAT_DEFAULT (object);
|
||||
GdkSeatDefaultPrivate *priv = gdk_seat_default_get_instance_private (seat);
|
||||
@@ -79,7 +79,11 @@ gdk_seat_default_dispose (GObject *object)
|
||||
g_object_unref (l->data);
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->tools, g_ptr_array_unref);
|
||||
if (priv->tools)
|
||||
{
|
||||
g_ptr_array_unref (priv->tools);
|
||||
priv->tools = NULL;
|
||||
}
|
||||
|
||||
g_list_free (priv->physical_pointers);
|
||||
g_list_free (priv->physical_keyboards);
|
||||
@@ -303,7 +307,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_default_dispose;
|
||||
object_class->dispose = gdk_seat_dispose;
|
||||
|
||||
seat_class->get_capabilities = gdk_seat_default_get_capabilities;
|
||||
|
||||
@@ -438,7 +442,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, tool->type))
|
||||
if (tool != gdk_seat_get_tool (GDK_SEAT (seat), tool->serial, tool->hw_id))
|
||||
return;
|
||||
|
||||
g_signal_emit_by_name (seat, "tool-removed", tool);
|
||||
|
||||
@@ -75,10 +75,9 @@ void gdk_seat_tool_removed (GdkSeat *seat,
|
||||
GdkDeviceTool *tool);
|
||||
|
||||
GdkDeviceTool *
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id,
|
||||
GdkDeviceToolType type);
|
||||
gdk_seat_get_tool (GdkSeat *seat,
|
||||
guint64 serial,
|
||||
guint64 hw_id);
|
||||
|
||||
GdkGrabStatus gdk_seat_grab (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
|
||||
@@ -92,7 +92,6 @@ enum {
|
||||
PROP_MAPPED,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_SCALE_FACTOR,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -552,13 +551,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
P_("Scale factor"),
|
||||
P_("Scale factor"),
|
||||
1, G_MAXINT, 1,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
|
||||
/**
|
||||
@@ -790,10 +782,6 @@ gdk_surface_get_property (GObject *object,
|
||||
g_value_set_int (value, surface->height);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
g_value_set_int (value, gdk_surface_get_scale_factor (surface));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -2557,7 +2545,8 @@ gdk_surface_get_frame_clock (GdkSurface *surface)
|
||||
* value can be used to determine whether to use a pixel resource
|
||||
* with higher resolution data.
|
||||
*
|
||||
* The scale of a surface may change during runtime.
|
||||
* The scale of a surface may change during runtime, if this happens
|
||||
* a configure event will be sent to the toplevel surface.
|
||||
*
|
||||
* Returns: the scale factor
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
* The supported formats are PNG and JPEG, though more formats might be
|
||||
* available.
|
||||
* The file format is detected automatically, and can be any
|
||||
* format that is supported by the gdk-pixbuf library, such as
|
||||
* JPEG or PNG.
|
||||
*
|
||||
* 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.
|
||||
* The supported formats are PNG and JPEG, though more formats might be
|
||||
* available.
|
||||
* The file format is detected automatically, and can be any
|
||||
* format that is supported by the gdk-pixbuf library, such as
|
||||
* JPEG or PNG.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
|
||||
@@ -95,143 +95,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GdkVulkanContext, gdk_vulkan_context, GDK_TYPE
|
||||
const char *
|
||||
gdk_vulkan_strerror (VkResult result)
|
||||
{
|
||||
/* If your compiler brought you here with a warning about missing
|
||||
* enumeration values, you're running a newer Vulkan version than
|
||||
* the GTK developers (or you are a GTK developer) and have
|
||||
* encountered a newly added Vulkan error message.
|
||||
* You want to add it to this enum now.
|
||||
*
|
||||
* Because the Vulkan people don't make adding this too easy, here's
|
||||
* the process to manage it:
|
||||
* 1. go to
|
||||
* https://github.com/KhronosGroup/Vulkan-Headers/blob/master/include/vulkan/vulkan_core.h
|
||||
* 2. Find the line where this enum value was added.
|
||||
* 3. Click the commit that added this line.
|
||||
* 4. The commit you're looking at now should also change
|
||||
* VK_HEADER_VERSION, find that number.
|
||||
* 5. Use that number in the #ifdef when adding the enum value to
|
||||
* this enum.
|
||||
* 6. For the error message, look at the specification (the one
|
||||
* that includes all extensions) at
|
||||
* https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkResult
|
||||
* 7. If this value has not been added to the specification yet,
|
||||
* search for the error message in the text of specification.
|
||||
* Often it will have a description that can be used as an error
|
||||
* message.
|
||||
* 8. If that didn't lead to one (or you are lazy), just use the
|
||||
* literal string of the enum value as the error message. A
|
||||
* GTK developer will add the correct one once it's added to the
|
||||
* specification.
|
||||
*/
|
||||
switch (result)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
return "Command successfully completed.";
|
||||
case VK_NOT_READY:
|
||||
return "A fence or query has not yet completed.";
|
||||
case VK_TIMEOUT:
|
||||
return "A wait operation has not completed in the specified time.";
|
||||
case VK_EVENT_SET:
|
||||
return "An event is signaled.";
|
||||
case VK_EVENT_RESET:
|
||||
return "An event is unsignaled.";
|
||||
case VK_INCOMPLETE:
|
||||
return "A return array was too small for the result.";
|
||||
case VK_SUBOPTIMAL_KHR:
|
||||
return "A swapchain no longer matches the surface properties exactly, but can still be used to present to the surface successfully.";
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||
return "A host memory allocation has failed.";
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||
return "A device memory allocation has failed.";
|
||||
case VK_ERROR_INITIALIZATION_FAILED:
|
||||
return "Initialization of an object could not be completed for implementation-specific reasons.";
|
||||
case VK_ERROR_DEVICE_LOST:
|
||||
return "The logical or physical device has been lost.";
|
||||
case VK_ERROR_MEMORY_MAP_FAILED:
|
||||
return "Mapping of a memory object has failed.";
|
||||
case VK_ERROR_LAYER_NOT_PRESENT:
|
||||
return "A requested layer is not present or could not be loaded.";
|
||||
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
return "A requested extension is not supported.";
|
||||
case VK_ERROR_FEATURE_NOT_PRESENT:
|
||||
return "A requested feature is not supported.";
|
||||
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons.";
|
||||
case VK_ERROR_TOO_MANY_OBJECTS:
|
||||
return "Too many objects of the type have already been created.";
|
||||
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||
return "A requested format is not supported on this device.";
|
||||
#if VK_HEADER_VERSION >= 24
|
||||
case VK_ERROR_FRAGMENTED_POOL:
|
||||
return "A requested pool allocation has failed due to fragmentation of the pool’s memory.";
|
||||
#endif
|
||||
case VK_ERROR_SURFACE_LOST_KHR:
|
||||
return "A surface is no longer available.";
|
||||
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||
return "The requested window is already in use by Vulkan or another API in a manner which prevents it from being used again.";
|
||||
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||
return "A surface has changed in such a way that it is no longer compatible with the swapchain.";
|
||||
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||
return "The display used by a swapchain does not use the same presentable image layout, or is incompatible in a way that prevents sharing an image.";
|
||||
case VK_ERROR_VALIDATION_FAILED_EXT:
|
||||
return "The application caused the validation layer to fail.";
|
||||
case VK_ERROR_INVALID_SHADER_NV:
|
||||
return "One or more shaders failed to compile or link.";
|
||||
#if VK_HEADER_VERSION >= 39
|
||||
case VK_ERROR_OUT_OF_POOL_MEMORY_KHR:
|
||||
return "A pool memory allocation has failed.";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 54
|
||||
case VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR:
|
||||
return "An external handle is not a valid handle of the specified type.";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 64
|
||||
case VK_ERROR_NOT_PERMITTED_EXT:
|
||||
return "The caller does not have sufficient privileges.";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 72
|
||||
case VK_ERROR_FRAGMENTATION_EXT:
|
||||
return "A descriptor pool creation has failed due to fragmentation";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 89
|
||||
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
||||
return "Invalid DRM format modifier plane layout";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 97
|
||||
case VK_ERROR_INVALID_DEVICE_ADDRESS_EXT:
|
||||
return "Invalid device address";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 105
|
||||
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
|
||||
return "An operation on a swapchain created with VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT failed as it did not have exclusive full-screen access.";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 131
|
||||
case VK_ERROR_UNKNOWN:
|
||||
return "An unknown error has occurred; either the application has provided invalid input, or an implementation failure has occurred.";
|
||||
#endif
|
||||
#if VK_HEADER_VERSION >= 135
|
||||
#if VK_HEADER_VERSION < 162
|
||||
case VK_ERROR_INCOMPATIBLE_VERSION_KHR:
|
||||
return "This error was removed by the Vulkan gods.";
|
||||
#endif
|
||||
case VK_THREAD_IDLE_KHR:
|
||||
return "A deferred operation is not complete but there is currently no work for this thread to do at the time of this call.";
|
||||
case VK_THREAD_DONE_KHR:
|
||||
return "A deferred operation is not complete but there is no work remaining to assign to additional threads.";
|
||||
case VK_OPERATION_DEFERRED_KHR:
|
||||
return "A deferred operation was requested and at least some of the work was deferred.";
|
||||
case VK_OPERATION_NOT_DEFERRED_KHR:
|
||||
return "A deferred operation was requested and no operations were deferred.";
|
||||
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 < 140
|
||||
case VK_RESULT_RANGE_SIZE:
|
||||
#endif
|
||||
case VK_RESULT_MAX_ENUM:
|
||||
default:
|
||||
return "Unknown Vulkan error.";
|
||||
}
|
||||
return "Unknown Vulkan error.";
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -306,7 +170,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
|
||||
"Could not query surface capabilities: %s", gdk_vulkan_strerror (res));
|
||||
"Could not query surface capabilities: %d", res);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -403,7 +267,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
else
|
||||
{
|
||||
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
|
||||
"Could not create swapchain for this surface: %s", gdk_vulkan_strerror (res));
|
||||
"Could not create swapchain for this surface: %d", res);
|
||||
priv->swapchain = VK_NULL_HANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -579,7 +443,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
|
||||
"Could not create surface for this surface: %s", gdk_vulkan_strerror (res));
|
||||
"Could not create surface for this surface: %d", res);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -590,7 +454,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
|
||||
"Could not check if queue family supports this surface: %s", gdk_vulkan_strerror (res));
|
||||
"Could not check if queue family supports this surface: %d", res);
|
||||
}
|
||||
else if (!supported)
|
||||
{
|
||||
@@ -1118,7 +982,7 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
|
||||
"Could not create a Vulkan instance: %s", gdk_vulkan_strerror (res));
|
||||
"Could not create a Vulkan instance: %d", res);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,10 +38,6 @@
|
||||
#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
|
||||
@@ -470,7 +466,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
|
||||
inTrackManualResize = YES;
|
||||
|
||||
mouse_location = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
mouse_location = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
mdx = initialResizeLocation.x - mouse_location.x;
|
||||
mdy = initialResizeLocation.y - mouse_location.y;
|
||||
|
||||
@@ -592,7 +588,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
}
|
||||
|
||||
initialResizeFrame = [self frame];
|
||||
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
initialResizeLocation = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
|
||||
@@ -27,10 +27,6 @@
|
||||
|
||||
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,56 +40,8 @@ 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)
|
||||
{
|
||||
@@ -104,17 +56,17 @@ _gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:PTYPE(STRING)] ||
|
||||
[type isEqualToString:PTYPE(PBOARD)])
|
||||
if ([type isEqualToString:NSPasteboardTypeString] ||
|
||||
[type isEqualToString:NSStringPboardType])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:PTYPE(URL)] ||
|
||||
[type isEqualToString:PTYPE(FILE_URL)])
|
||||
else if ([type isEqualToString:NSPasteboardTypeURL] ||
|
||||
[type isEqualToString:NSPasteboardTypeFileURL])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:PTYPE(COLOR)])
|
||||
else if ([type isEqualToString:NSPasteboardTypeColor])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:PTYPE(TIFF)])
|
||||
else if ([type isEqualToString:NSPasteboardTypeTIFF])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:PTYPE(PNG)])
|
||||
else if ([type isEqualToString:NSPasteboardTypePNG])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
@@ -131,25 +83,25 @@ _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return PTYPE(STRING);
|
||||
return NSPasteboardTypeString;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = PTYPE(URL);
|
||||
return PTYPE(FILE_URL);
|
||||
*alternate = NSPasteboardTypeURL;
|
||||
return NSPasteboardTypeFileURL;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return PTYPE(COLOR);
|
||||
return NSPasteboardTypeColor;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return PTYPE(TIFF);
|
||||
return NSPasteboardTypeTIFF;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return PTYPE(PNG);
|
||||
return NSPasteboardTypePNG;
|
||||
}
|
||||
|
||||
return nil;
|
||||
@@ -268,7 +220,7 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[self->pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
if ([[self->pasteboard types] containsObject:NSPasteboardTypeFileURL])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
@@ -315,12 +267,12 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(TIFF)];
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypeTIFF];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:PTYPE(PNG)];
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypePNG];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#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
|
||||
@@ -206,9 +205,6 @@ 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));
|
||||
@@ -245,22 +241,16 @@ 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),
|
||||
pointer,
|
||||
tool,
|
||||
gdk_seat_get_pointer (seat),
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
get_mouse_button_from_ns_event (nsevent),
|
||||
x,
|
||||
y,
|
||||
axes);
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -567,9 +557,6 @@ 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);
|
||||
@@ -579,20 +566,14 @@ 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),
|
||||
pointer,
|
||||
tool,
|
||||
gdk_seat_get_pointer (seat),
|
||||
NULL,
|
||||
get_time_from_ns_event (nsevent),
|
||||
state,
|
||||
x,
|
||||
y,
|
||||
axes);
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
@@ -719,7 +700,7 @@ get_surface_point_from_screen_point (GdkSurface *surface,
|
||||
NSPoint point;
|
||||
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
point = convert_nspoint_from_screen (nswindow, screen_point);
|
||||
point = [nswindow convertPointFromScreen:screen_point];
|
||||
|
||||
*x = point.x;
|
||||
*y = surface->height - point.y;
|
||||
@@ -781,7 +762,7 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
GdkSurface *surface = NULL;
|
||||
NSWindow *nswindow = [nsevent window];
|
||||
|
||||
if (GDK_IS_MACOS_WINDOW (nswindow))
|
||||
if (nswindow)
|
||||
{
|
||||
GdkMacosBaseView *view;
|
||||
NSPoint point, view_point;
|
||||
@@ -840,7 +821,7 @@ get_surface_from_ns_event (GdkMacosDisplay *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
*screen_point = convert_nspoint_to_screen ([nsevent window], point);
|
||||
*screen_point = [(GdkMacosWindow *)[nsevent window] convertPointToScreen:point];
|
||||
*x = point.x;
|
||||
*y = surface->height - point.y;
|
||||
}
|
||||
@@ -993,11 +974,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])
|
||||
@@ -1070,23 +1051,6 @@ _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,7 +145,6 @@ 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;
|
||||
@@ -159,9 +158,6 @@ GetLocalizedName (NSScreen *screen)
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&name);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosseat.h"
|
||||
|
||||
#include "gdkseatprivate.h"
|
||||
|
||||
@@ -31,16 +30,6 @@ 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,6 +1,5 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -23,605 +22,42 @@
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicetoolprivate.h"
|
||||
#include "gdkseatdefaultprivate.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)
|
||||
{
|
||||
GdkMacosSeat *self;
|
||||
GdkDevice *core_keyboard;
|
||||
GdkDevice *core_pointer;
|
||||
GdkSeat *seat;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
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,
|
||||
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,
|
||||
"has-cursor", FALSE,
|
||||
"display", display,
|
||||
"seat", self,
|
||||
"vendor-id", vid,
|
||||
"product-id", pid,
|
||||
NULL);
|
||||
|
||||
tablet->logical_device = logical_device;
|
||||
tablet->stylus_device = stylus_device;
|
||||
_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));
|
||||
|
||||
_gdk_device_set_associated_device (logical_device, self->logical_keyboard);
|
||||
_gdk_device_set_associated_device (stylus_device, logical_device);
|
||||
seat = gdk_seat_default_new_for_logical_pair (core_pointer, core_keyboard);
|
||||
|
||||
gdk_seat_device_added (GDK_SEAT (self), logical_device);
|
||||
gdk_seat_device_added (GDK_SEAT (self), stylus_device);
|
||||
g_object_unref (core_pointer);
|
||||
g_object_unref (core_keyboard);
|
||||
|
||||
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);
|
||||
return g_steal_pointer (&seat);
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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,7 +61,6 @@ struct _GdkMacosSurface
|
||||
gint64 pending_frame_counter;
|
||||
|
||||
guint did_initial_present : 1;
|
||||
guint geometry_dirty : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosSurfaceClass
|
||||
|
||||
@@ -150,12 +150,6 @@ _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 void
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
@@ -107,7 +107,6 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
style_mask = [nswindow styleMask];
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
@@ -159,11 +158,13 @@ _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);
|
||||
@@ -229,6 +230,8 @@ _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
|
||||
@@ -370,87 +373,6 @@ _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)
|
||||
@@ -584,8 +506,6 @@ _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,36 +40,5 @@ 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,7 +33,6 @@ gdk_macos_public_headers = files([
|
||||
'gdkmacosglcontext.h',
|
||||
'gdkmacoskeymap.h',
|
||||
'gdkmacosmonitor.h',
|
||||
'gdkmacosseat.h',
|
||||
'gdkmacossurface.h',
|
||||
])
|
||||
|
||||
|
||||
@@ -2357,9 +2357,6 @@ 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);
|
||||
@@ -2407,9 +2404,6 @@ 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,
|
||||
@@ -2448,9 +2442,6 @@ 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);
|
||||
|
||||
@@ -3390,14 +3381,9 @@ 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;
|
||||
GdkSurface *surface = wl_surface_get_user_data (wsurface);
|
||||
GdkEvent *event;
|
||||
|
||||
if (!wsurface)
|
||||
return;
|
||||
|
||||
surface = wl_surface_get_user_data (wsurface);
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
if (!GDK_IS_SURFACE (surface))
|
||||
@@ -3441,9 +3427,6 @@ 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)));
|
||||
@@ -3507,7 +3490,7 @@ tablet_tool_handle_down (void *data,
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tool->seat);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
if (!tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
_gdk_wayland_display_update_serial (display_wayland, serial);
|
||||
@@ -3524,7 +3507,7 @@ tablet_tool_handle_up (void *data,
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
if (!tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet_create_button_event_frame (tablet, GDK_BUTTON_RELEASE, GDK_BUTTON_PRIMARY);
|
||||
@@ -3541,9 +3524,6 @@ 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);
|
||||
|
||||
@@ -3571,12 +3551,7 @@ tablet_tool_handle_pressure (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_PRESSURE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
pressure, &tablet->axes[GDK_AXIS_PRESSURE]);
|
||||
@@ -3593,12 +3568,7 @@ tablet_tool_handle_distance (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_DISTANCE];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
distance, &tablet->axes[GDK_AXIS_DISTANCE]);
|
||||
@@ -3616,14 +3586,8 @@ tablet_tool_handle_tilt (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
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];
|
||||
int xtilt_axis_index = tablet->axis_indices[GDK_AXIS_XTILT];
|
||||
int ytilt_axis_index = tablet->axis_indices[GDK_AXIS_YTILT];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, xtilt_axis_index,
|
||||
wl_fixed_to_double (xtilt),
|
||||
@@ -3650,7 +3614,7 @@ tablet_tool_handle_button (void *data,
|
||||
GdkEventType evtype;
|
||||
guint n_button;
|
||||
|
||||
if (!tablet || !tablet->pointer_info.focus)
|
||||
if (!tablet->pointer_info.focus)
|
||||
return;
|
||||
|
||||
tablet->pointer_info.press_serial = serial;
|
||||
@@ -3681,12 +3645,7 @@ tablet_tool_handle_rotation (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_ROTATION];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
wl_fixed_to_double (degrees),
|
||||
@@ -3705,12 +3664,7 @@ tablet_tool_handle_slider (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
int axis_index;
|
||||
|
||||
if (!tablet)
|
||||
return;
|
||||
|
||||
axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
int axis_index = tablet->axis_indices[GDK_AXIS_SLIDER];
|
||||
|
||||
_gdk_device_translate_axis (tablet->stylus_device, axis_index,
|
||||
position, &tablet->axes[GDK_AXIS_SLIDER]);
|
||||
@@ -3728,14 +3682,9 @@ tablet_tool_handle_wheel (void *data,
|
||||
{
|
||||
GdkWaylandTabletToolData *tool = data;
|
||||
GdkWaylandTabletData *tablet = tool->current_tablet;
|
||||
GdkWaylandSeat *seat;
|
||||
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->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));
|
||||
@@ -3775,9 +3724,6 @@ 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));
|
||||
|
||||
@@ -4366,9 +4312,6 @@ 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)
|
||||
{
|
||||
@@ -4376,8 +4319,6 @@ 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,7 +1836,6 @@ 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,22 +242,14 @@ 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;
|
||||
@@ -265,7 +257,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 (heap_rects);
|
||||
g_free (rects);
|
||||
}
|
||||
else
|
||||
eglSwapBuffers (display_wayland->egl_display, egl_surface);
|
||||
@@ -301,27 +293,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);
|
||||
@@ -394,7 +386,7 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLint attrs[MAX_EGL_ATTRS];
|
||||
EGLint count;
|
||||
EGLConfig config;
|
||||
EGLConfig *configs;
|
||||
int i = 0;
|
||||
|
||||
attrs[i++] = EGL_SURFACE_TYPE;
|
||||
@@ -415,8 +407,7 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
attrs[i++] = EGL_NONE;
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
/* Pick first valid configuration i guess? */
|
||||
if (!eglChooseConfig (display_wayland->egl_display, attrs, &config, 1, &count) || count < 1)
|
||||
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,
|
||||
@@ -424,17 +415,31 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_assert (egl_config_out);
|
||||
*egl_config_out = config;
|
||||
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 (egl_config_out != NULL)
|
||||
*egl_config_out = configs[0];
|
||||
|
||||
g_free (configs);
|
||||
|
||||
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);
|
||||
@@ -521,10 +526,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,
|
||||
|
||||
@@ -389,13 +389,10 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
int scale)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
gboolean width_changed, height_changed, scale_changed;
|
||||
|
||||
width_changed = surface->width != width;
|
||||
height_changed = surface->height != height;
|
||||
scale_changed = impl->scale != scale;
|
||||
|
||||
if (!width_changed && !height_changed && !scale_changed)
|
||||
if ((surface->width == width) &&
|
||||
(surface->height == height) &&
|
||||
(impl->scale == scale))
|
||||
return;
|
||||
|
||||
surface->width = width;
|
||||
@@ -408,13 +405,6 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
wl_surface_set_buffer_scale (impl->display_server.wl_surface, scale);
|
||||
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
|
||||
if (width_changed)
|
||||
g_object_notify (G_OBJECT (surface), "width");
|
||||
if (height_changed)
|
||||
g_object_notify (G_OBJECT (surface), "height");
|
||||
if (scale_changed)
|
||||
g_object_notify (G_OBJECT (surface), "scale-factor");
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
||||
@@ -31,6 +31,46 @@
|
||||
|
||||
G_DEFINE_TYPE (GdkWin32CairoContext, gdk_win32_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static cairo_surface_t *
|
||||
create_cairo_surface_for_layered_window (GdkWin32Surface *impl,
|
||||
int width,
|
||||
int height,
|
||||
int scale)
|
||||
{
|
||||
if (width > impl->dib_width ||
|
||||
height > impl->dib_height)
|
||||
{
|
||||
cairo_surface_t *new_cache;
|
||||
|
||||
impl->dib_width = MAX (impl->dib_width, MAX (width, 1));
|
||||
impl->dib_height = MAX (impl->dib_height, MAX (height, 1));
|
||||
/* Create larger cache surface, copy old cache surface over it */
|
||||
new_cache = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32,
|
||||
impl->dib_width,
|
||||
impl->dib_height);
|
||||
|
||||
if (impl->cache_surface)
|
||||
{
|
||||
cairo_t *cr = cairo_create (new_cache);
|
||||
cairo_set_source_surface (cr, impl->cache_surface, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_flush (new_cache);
|
||||
|
||||
cairo_surface_destroy (impl->cache_surface);
|
||||
}
|
||||
|
||||
impl->cache_surface = new_cache;
|
||||
|
||||
cairo_surface_set_device_scale (impl->cache_surface,
|
||||
scale,
|
||||
scale);
|
||||
}
|
||||
|
||||
return cairo_surface_reference (impl->cache_surface);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
create_cairo_surface_for_surface (GdkSurface *surface,
|
||||
int scale)
|
||||
@@ -74,11 +114,22 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
width = MAX (width, 1);
|
||||
height = MAX (height, 1);
|
||||
|
||||
self->window_surface = create_cairo_surface_for_surface (surface, scale);
|
||||
if (self->layered)
|
||||
self->window_surface = create_cairo_surface_for_layered_window (impl, width, height, scale);
|
||||
else
|
||||
self->window_surface = create_cairo_surface_for_surface (surface, scale);
|
||||
|
||||
if (!self->double_buffered)
|
||||
/* Non-double-buffered windows paint on the window surface directly */
|
||||
self->paint_surface = cairo_surface_reference (self->window_surface);
|
||||
if (self->layered ||
|
||||
!self->double_buffered)
|
||||
{
|
||||
/* Layered windows paint on the window_surface (which is itself
|
||||
* an in-memory cache that the window maintains, since layered windows
|
||||
* do not support incremental redraws.
|
||||
* Non-double-buffered windows paint on the window surface directly
|
||||
* as well.
|
||||
*/
|
||||
self->paint_surface = cairo_surface_reference (self->window_surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (width > self->db_width ||
|
||||
@@ -102,10 +153,11 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
}
|
||||
|
||||
/* Clear the paint region.
|
||||
* For non-double-buffered rendering we must clear it, otherwise
|
||||
* semi-transparent pixels will "add up" with each repaint.
|
||||
* We must also clear the old pixels from the DB cache surface
|
||||
* that we're going to use as a buffer.
|
||||
* For non-double-buffered and for layered rendering we must
|
||||
* clear it, otherwise semi-transparent pixels will "add up"
|
||||
* with each repaint.
|
||||
* For double-buffered rendering we must clear the old pixels
|
||||
* from the DB cache surface that we're going to use as a buffer.
|
||||
*/
|
||||
cr = cairo_create (self->paint_surface);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 00);
|
||||
@@ -132,10 +184,12 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
* to be here.
|
||||
*/
|
||||
|
||||
/* For double-buffered windows we need to blit
|
||||
/* Layered windows have their own, special copying section
|
||||
* further down. For double-buffered windows we need to blit
|
||||
* the DB buffer contents into the window itself.
|
||||
*/
|
||||
if (self->double_buffered)
|
||||
if (!self->layered &&
|
||||
self->double_buffered)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
@@ -153,6 +207,18 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
|
||||
cairo_surface_flush (self->window_surface);
|
||||
|
||||
/* Update layered window, updating its contents, size and position
|
||||
* in one call.
|
||||
*/
|
||||
if (self->layered)
|
||||
{
|
||||
RECT client_rect;
|
||||
|
||||
/* Get the position/size of the window that GDK wants. */
|
||||
_gdk_win32_get_window_client_area_rect (surface, scale, &client_rect);
|
||||
_gdk_win32_update_layered_window_from_cache (surface, &client_rect, TRUE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->paint_surface, cairo_surface_destroy);
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,10 @@ struct _GdkWin32CairoContext
|
||||
* code that is unaffected by this flag.
|
||||
*/
|
||||
guint double_buffered : 1;
|
||||
/* Re-set to the same value as GdkSurfaceImplWin32->layered
|
||||
* every frame (since layeredness can change at runtime).
|
||||
*/
|
||||
guint layered : 1;
|
||||
|
||||
/* The a surface for double-buffering. We keep it
|
||||
* around between repaints, and only re-allocate it
|
||||
@@ -52,11 +56,12 @@ struct _GdkWin32CairoContext
|
||||
int db_width;
|
||||
int db_height;
|
||||
|
||||
/* Surface for the window DC */
|
||||
/* Surface for the window DC (in non-layered mode).
|
||||
* A reference of the cache surface (in layered mode). */
|
||||
cairo_surface_t *window_surface;
|
||||
/* A reference to db_surface (when double-buffering).
|
||||
* When not using double-buffering this is a reference
|
||||
* to window_surface.
|
||||
* When not using double-buffering or in layered mode
|
||||
* this is a reference to window_surface.
|
||||
*/
|
||||
cairo_surface_t *paint_surface;
|
||||
};
|
||||
|
||||
@@ -2113,6 +2113,7 @@ gdk_drag_anim_timeout (gpointer data)
|
||||
(drag->start_y - drag->util_data.last_y) * t -
|
||||
drag->hot_y);
|
||||
gdk_win32_surface_move (drag->drag_surface, x, y);
|
||||
gdk_win32_surface_set_opacity (drag->drag_surface, 1.0 - f);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -1495,6 +1495,15 @@ handle_dpi_changed (GdkSurface *window,
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, window);
|
||||
gdk_monitor_set_scale_factor (monitor, impl->surface_scale);
|
||||
|
||||
if (impl->layered)
|
||||
{
|
||||
/* We only need to set the cairo surface device scale here ourselves for layered windows */
|
||||
if (impl->cache_surface != NULL)
|
||||
cairo_surface_set_device_scale (impl->cache_surface,
|
||||
impl->surface_scale,
|
||||
impl->surface_scale);
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_win32_adjust_client_rect (window, rect);
|
||||
@@ -1712,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->shadow_x * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.y = GetSystemMetrics (SM_CYVIRTUALSCREEN) + impl->shadow_y * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.x = GetSystemMetrics (SM_CXVIRTUALSCREEN) + impl->margins_x * impl->surface_scale;
|
||||
mmi->ptMaxTrackSize.y = GetSystemMetrics (SM_CYVIRTUALSCREEN) + impl->margins_y * impl->surface_scale;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -2345,7 +2354,9 @@ 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;
|
||||
@@ -2824,16 +2835,6 @@ 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);
|
||||
|
||||
|
||||
@@ -88,6 +88,19 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (surface != NULL)
|
||||
{
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
if (impl->suppress_layered > 0)
|
||||
impl->suppress_layered--;
|
||||
|
||||
/* If we don't have any surface that forces layered windows off,
|
||||
* trigger update_style_bits() to enable layered windows again
|
||||
*/
|
||||
if (impl->suppress_layered == 0)
|
||||
_gdk_win32_surface_update_style_bits (surface);
|
||||
}
|
||||
G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
@@ -988,6 +1001,17 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
|
||||
/* set whether we are using GLES */
|
||||
gdk_gl_context_set_use_es (context, use_es);
|
||||
|
||||
/* OpenGL does not work with WS_EX_LAYERED enabled, so we need to
|
||||
* disable WS_EX_LAYERED when we acquire a valid HGLRC
|
||||
*/
|
||||
impl->suppress_layered++;
|
||||
|
||||
/* if this is the first time a GL context is acquired for the surface,
|
||||
* disable layered windows by triggering update_style_bits()
|
||||
*/
|
||||
if (impl->suppress_layered == 1)
|
||||
_gdk_win32_surface_update_style_bits (surface);
|
||||
|
||||
/* Ensure that any other context is created with a legacy bit set */
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
|
||||
|
||||
@@ -351,6 +351,7 @@ _gdk_win32_surface_exstyle_to_string (LONG style)
|
||||
BIT (CONTEXTHELP);
|
||||
BIT (CONTROLPARENT);
|
||||
BIT (DLGMODALFRAME);
|
||||
BIT (LAYERED);
|
||||
BIT (LAYOUTRTL);
|
||||
BIT (LEFTSCROLLBAR);
|
||||
BIT (MDICHILD);
|
||||
|
||||
@@ -53,10 +53,6 @@
|
||||
#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;
|
||||
@@ -275,6 +271,7 @@ _gdk_win32_adjust_client_rect (GdkSurface *window,
|
||||
gboolean
|
||||
_gdk_win32_surface_enable_transparency (GdkSurface *window)
|
||||
{
|
||||
GdkWin32Surface *impl;
|
||||
DWM_BLURBEHIND blur_behind;
|
||||
HRGN empty_region;
|
||||
HRESULT call_result;
|
||||
@@ -283,6 +280,12 @@ _gdk_win32_surface_enable_transparency (GdkSurface *window)
|
||||
if (window == NULL || GDK_SURFACE_HWND (window) == NULL)
|
||||
return FALSE;
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
/* layered windows don't need blurbehind for transparency */
|
||||
if (impl->layered)
|
||||
return TRUE;
|
||||
|
||||
if (!gdk_display_is_composited (gdk_surface_get_display (window)))
|
||||
return FALSE;
|
||||
|
||||
@@ -519,6 +522,9 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
impl->layered = FALSE;
|
||||
impl->layered_opacity = 1.0;
|
||||
|
||||
impl->surface_scale = _gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL, NULL);
|
||||
impl->unscaled_width = width * impl->surface_scale;
|
||||
impl->unscaled_height = height * impl->surface_scale;
|
||||
@@ -1094,8 +1100,6 @@ 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
|
||||
@@ -1156,6 +1160,8 @@ 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)
|
||||
@@ -1180,6 +1186,8 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
|
||||
}
|
||||
|
||||
out:
|
||||
surface->inhibit_configure = FALSE;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
}
|
||||
|
||||
@@ -1220,10 +1228,10 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
|
||||
gdk_surface_layout_popup_helper (surface,
|
||||
width,
|
||||
height,
|
||||
impl->shadow.left,
|
||||
impl->shadow.right,
|
||||
impl->shadow.top,
|
||||
impl->shadow.bottom,
|
||||
impl->margins.left,
|
||||
impl->margins.right,
|
||||
impl->margins.top,
|
||||
impl->margins.bottom,
|
||||
monitor,
|
||||
&bounds,
|
||||
layout,
|
||||
@@ -1248,24 +1256,11 @@ 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);
|
||||
maybe_notify_mapped (surface);
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
show_window_internal (surface, FALSE, FALSE);
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
@@ -1751,6 +1746,11 @@ update_single_bit (LONG *style,
|
||||
* Returns TRUE if window has no decorations.
|
||||
* Usually it means CSD windows, because GTK
|
||||
* calls gdk_surface_set_decorations (window, 0);
|
||||
* This is used to decide whether a toplevel should
|
||||
* be made layered, thus it
|
||||
* only returns TRUE for toplevels (until GTK minimal
|
||||
* system requirements are lifted to Windows 8 or newer,
|
||||
* because only toplevels can be layered).
|
||||
*/
|
||||
gboolean
|
||||
_gdk_win32_surface_lacks_wm_decorations (GdkSurface *window)
|
||||
@@ -1844,6 +1844,27 @@ _gdk_win32_surface_update_style_bits (GdkSurface *window)
|
||||
new_exstyle &= ~WS_EX_TOOLWINDOW;
|
||||
}
|
||||
|
||||
/* We can get away with using layered windows
|
||||
* only when no decorations are needed. It can mean
|
||||
* CSD or borderless non-CSD windows (tooltips?).
|
||||
*
|
||||
* If this window cannot use layered windows, disable it always.
|
||||
* This currently applies to windows using OpenGL, which
|
||||
* does not work with layered windows.
|
||||
*/
|
||||
if (impl->suppress_layered == 0)
|
||||
{
|
||||
if (_gdk_win32_surface_lacks_wm_decorations (window))
|
||||
impl->layered = g_strcmp0 (g_getenv ("GDK_WIN32_LAYERED"), "0") != 0;
|
||||
}
|
||||
else
|
||||
impl->layered = FALSE;
|
||||
|
||||
if (impl->layered)
|
||||
new_exstyle |= WS_EX_LAYERED;
|
||||
else
|
||||
new_exstyle &= ~WS_EX_LAYERED;
|
||||
|
||||
if (get_effective_window_decorations (window, &decorations))
|
||||
{
|
||||
all = (decorations & GDK_DECOR_ALL);
|
||||
@@ -2273,7 +2294,6 @@ snap_up (GdkSurface *window)
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
impl->snap_state = GDK_WIN32_AEROSNAP_STATE_FULLUP;
|
||||
impl->resized = FALSE;
|
||||
|
||||
stash_window (window, impl);
|
||||
|
||||
@@ -2284,18 +2304,10 @@ snap_up (GdkSurface *window)
|
||||
y = 0;
|
||||
height = maxysize;
|
||||
|
||||
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);
|
||||
x = x - impl->margins.left;
|
||||
y = y - impl->margins.top;
|
||||
width += impl->margins_x;
|
||||
height += impl->margins_y;
|
||||
|
||||
gdk_win32_surface_move_resize (window, x, y, width, height);
|
||||
}
|
||||
@@ -2311,7 +2323,6 @@ 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);
|
||||
|
||||
@@ -2319,10 +2330,10 @@ snap_left (GdkSurface *window,
|
||||
|
||||
rect.width = rect.width / 2;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
gdk_win32_surface_move_resize (window,
|
||||
rect.x, rect.y,
|
||||
@@ -2340,7 +2351,6 @@ 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);
|
||||
|
||||
@@ -2349,10 +2359,10 @@ snap_right (GdkSurface *window,
|
||||
rect.width = rect.width / 2;
|
||||
rect.x += rect.width;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
gdk_win32_surface_move_resize (window,
|
||||
rect.x, rect.y,
|
||||
@@ -3492,10 +3502,10 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE && !maximized)
|
||||
{
|
||||
swx += impl->shadow.left / impl->surface_scale;
|
||||
swy += impl->shadow.top / impl->surface_scale;
|
||||
swwidth -= impl->shadow_x;
|
||||
swheight -= impl->shadow_y;
|
||||
swx += impl->margins.left / impl->surface_scale;
|
||||
swy += impl->margins.top / impl->surface_scale;
|
||||
swwidth -= impl->margins_x;
|
||||
swheight -= impl->margins_y;
|
||||
}
|
||||
|
||||
pointer_outside_of_window = root_x < swx || root_x > swx + swwidth ||
|
||||
@@ -3545,23 +3555,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->shadow_x * impl->surface_scale;
|
||||
shadow_unmax_height = unmax_height - impl->shadow_y * impl->surface_scale;
|
||||
shadow_unmax_width = unmax_width - impl->margins_x * impl->surface_scale;
|
||||
shadow_unmax_height = unmax_height - impl->margins_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->shadow.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.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->shadow.left - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.left = (root_x - offsetx + impl->margins.left - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.right = placement.rcNormalPosition.left + unmax_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->shadow.right - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.right = (root_x + offsetx + impl->margins.right - _gdk_offset_x) * impl->surface_scale;
|
||||
placement.rcNormalPosition.left = placement.rcNormalPosition.right - unmax_width;
|
||||
}
|
||||
}
|
||||
@@ -3572,7 +3582,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->shadow.top - _gdk_offset_y) * impl->surface_scale;
|
||||
placement.rcNormalPosition.top = (root_y - offsety + impl->margins.top - _gdk_offset_y) * impl->surface_scale;
|
||||
else
|
||||
placement.rcNormalPosition.top = (root_y * impl->surface_scale) -
|
||||
(unmax_height / 2) -
|
||||
@@ -3599,18 +3609,18 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE)
|
||||
{
|
||||
snew_pos.width -= impl->shadow_x;
|
||||
snew_pos.height -= impl->shadow_y;
|
||||
snew_pos.width -= impl->margins_x;
|
||||
snew_pos.height -= impl->margins_y;
|
||||
}
|
||||
|
||||
if (offsetx < snew_pos.width / 2 && offsety < snew_pos.height / 2)
|
||||
{
|
||||
new_pos.y = root_y - offsety + impl->shadow.top / impl->surface_scale;
|
||||
new_pos.y = root_y - offsety + impl->margins.top / impl->surface_scale;
|
||||
|
||||
if (left_half)
|
||||
new_pos.x = root_x - offsetx + impl->shadow.left / impl->surface_scale;
|
||||
new_pos.x = root_x - offsetx + impl->margins.left / impl->surface_scale;
|
||||
else
|
||||
new_pos.x = root_x + offsetx + impl->shadow.left / impl->surface_scale - new_pos.width;
|
||||
new_pos.x = root_x + offsetx + impl->margins.left / impl->surface_scale - new_pos.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3775,6 +3785,67 @@ gdk_win32_get_window_size_and_position_from_client_rect (GdkSurface *window,
|
||||
window_size->cy = window_rect->bottom - window_rect->top;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_win32_update_layered_window_from_cache (GdkSurface *surface,
|
||||
RECT *client_rect,
|
||||
gboolean do_move,
|
||||
gboolean do_resize,
|
||||
gboolean do_paint)
|
||||
{
|
||||
POINT window_position;
|
||||
SIZE window_size;
|
||||
BLENDFUNCTION blender;
|
||||
HDC hdc;
|
||||
SIZE *window_size_ptr;
|
||||
POINT source_point = { 0, 0 };
|
||||
POINT *source_point_ptr;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
gdk_win32_get_window_size_and_position_from_client_rect (surface,
|
||||
client_rect,
|
||||
&window_size,
|
||||
&window_position);
|
||||
|
||||
blender.BlendOp = AC_SRC_OVER;
|
||||
blender.BlendFlags = 0;
|
||||
blender.AlphaFormat = AC_SRC_ALPHA;
|
||||
blender.SourceConstantAlpha = impl->layered_opacity * 255;
|
||||
|
||||
/* Strictly speaking, we don't need to supply hdc, source_point and
|
||||
* window_size to just move the window. However, without these arguments
|
||||
* the window moves but does not update its contents on Windows 7 when
|
||||
* desktop composition is off. This forces us to provide hdc and
|
||||
* source_point. window_size is here to avoid the function
|
||||
* inexplicably failing with error 317.
|
||||
*/
|
||||
hdc = cairo_win32_surface_get_dc (impl->cache_surface);
|
||||
window_size_ptr = &window_size;
|
||||
source_point_ptr = &source_point;
|
||||
|
||||
if (gdk_display_is_composited (gdk_surface_get_display (surface)))
|
||||
{
|
||||
if (!do_paint)
|
||||
hdc = NULL;
|
||||
if (!do_resize)
|
||||
window_size_ptr = NULL;
|
||||
if (!do_move)
|
||||
source_point_ptr = NULL;
|
||||
}
|
||||
|
||||
/* Don't use UpdateLayeredWindow on minimized windows */
|
||||
if (IsIconic (GDK_SURFACE_HWND (surface)))
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (surface),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
window_position.x, window_position.y,
|
||||
window_size.cx, window_size.cy,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW));
|
||||
else
|
||||
API_CALL (UpdateLayeredWindow, (GDK_SURFACE_HWND (surface), NULL,
|
||||
&window_position, window_size_ptr,
|
||||
hdc, source_point_ptr,
|
||||
0, &blender, ULW_ALPHA));
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
|
||||
int x,
|
||||
@@ -3944,47 +4015,42 @@ 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 ||
|
||||
rect.top != new_rect.top))
|
||||
{
|
||||
SIZE window_size;
|
||||
POINT window_position;
|
||||
|
||||
context->native_move_resize_pending = FALSE;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
|
||||
gdk_win32_get_window_size_and_position_from_client_rect (window,
|
||||
&new_rect,
|
||||
&window_size,
|
||||
&window_position);
|
||||
if (impl->layered)
|
||||
{
|
||||
_gdk_win32_update_layered_window_from_cache (window, &new_rect, TRUE, FALSE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SIZE window_size;
|
||||
POINT window_position;
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
window_position.x, window_position.y,
|
||||
0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE));
|
||||
gdk_win32_get_window_size_and_position_from_client_rect (window,
|
||||
&new_rect,
|
||||
&window_size,
|
||||
&window_position);
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
window_position.x, window_position.y,
|
||||
0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE));
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -4093,7 +4159,6 @@ gdk_win32_surface_minimize (GdkSurface *window)
|
||||
static void
|
||||
gdk_win32_surface_maximize (GdkSurface *window)
|
||||
{
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
@@ -4104,9 +4169,6 @@ 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
|
||||
@@ -4251,6 +4313,61 @@ gdk_win32_surface_lookup_for_display (GdkDisplay *display,
|
||||
return (GdkSurface*) gdk_win32_handle_table_lookup (anid);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_set_opacity (GdkSurface *window,
|
||||
double opacity)
|
||||
{
|
||||
LONG exstyle;
|
||||
typedef BOOL (WINAPI *PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
|
||||
PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return;
|
||||
|
||||
if (opacity < 0)
|
||||
opacity = 0;
|
||||
else if (opacity > 1)
|
||||
opacity = 1;
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
if (impl->layered)
|
||||
{
|
||||
if (impl->layered_opacity != opacity)
|
||||
{
|
||||
RECT window_rect;
|
||||
|
||||
impl->layered_opacity = opacity;
|
||||
|
||||
_gdk_win32_get_window_client_area_rect (window, impl->surface_scale, &window_rect);
|
||||
_gdk_win32_update_layered_window_from_cache (window, &window_rect, TRUE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
exstyle = GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE);
|
||||
|
||||
if (!(exstyle & WS_EX_LAYERED))
|
||||
SetWindowLong (GDK_SURFACE_HWND (window),
|
||||
GWL_EXSTYLE,
|
||||
exstyle | WS_EX_LAYERED);
|
||||
|
||||
setLayeredWindowAttributes =
|
||||
(PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
|
||||
|
||||
if (setLayeredWindowAttributes)
|
||||
{
|
||||
API_CALL (setLayeredWindowAttributes, (GDK_SURFACE_HWND (window),
|
||||
0,
|
||||
opacity * 0xff,
|
||||
LWA_ALPHA));
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_win32_surface_is_win32 (GdkSurface *window)
|
||||
{
|
||||
@@ -4330,6 +4447,9 @@ GtkShowWindow (GdkSurface *window,
|
||||
if (IsWindowVisible (hwnd))
|
||||
break;
|
||||
|
||||
if ((WS_EX_LAYERED & GetWindowLongPtr (hwnd, GWL_EXSTYLE)) != WS_EX_LAYERED)
|
||||
break;
|
||||
|
||||
/* Window was hidden, will be shown. Erase it, GDK will repaint soon,
|
||||
* but not soon enough, so it's possible to see old content before
|
||||
* the next redraw, unless we erase the window first.
|
||||
@@ -4394,17 +4514,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_shadow = left == 0 && right == 0 && top == 0 && bottom == 0;
|
||||
impl->zero_margins = left == 0 && right == 0 && top == 0 && bottom == 0;
|
||||
|
||||
if (impl->zero_shadow)
|
||||
if (impl->zero_margins)
|
||||
return;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -4477,118 +4597,6 @@ 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)
|
||||
{
|
||||
@@ -4615,8 +4623,6 @@ 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
|
||||
@@ -4906,18 +4912,75 @@ 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);
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
gboolean maximize;
|
||||
gboolean fullscreen;
|
||||
|
||||
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);
|
||||
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);
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
|
||||
if (gdk_toplevel_layout_get_maximized (layout, &maximize))
|
||||
@@ -4936,8 +4999,18 @@ gdk_win32_toplevel_present (GdkToplevel *toplevel,
|
||||
gdk_win32_surface_unfullscreen (surface);
|
||||
}
|
||||
|
||||
gdk_win32_surface_show (surface, FALSE);
|
||||
maybe_notify_mapped (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;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -5020,9 +5093,8 @@ gdk_win32_drag_surface_present (GdkDragSurface *drag_surface,
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (drag_surface);
|
||||
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
gdk_win32_surface_show (surface, FALSE);
|
||||
maybe_notify_mapped (surface);
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
show_surface (surface);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -5113,6 +5185,7 @@ gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
|
||||
RECT
|
||||
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkWin32CairoContext *cairo_ctx = NULL;
|
||||
GdkSurface *surface;
|
||||
GdkWin32Surface *impl;
|
||||
int scale;
|
||||
@@ -5122,16 +5195,23 @@ gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context)
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
scale = gdk_surface_get_scale_factor (surface);
|
||||
|
||||
if (GDK_IS_WIN32_CAIRO_CONTEXT (draw_context))
|
||||
{
|
||||
cairo_ctx = GDK_WIN32_CAIRO_CONTEXT (draw_context);
|
||||
cairo_ctx->layered = impl->layered;
|
||||
}
|
||||
|
||||
gdk_win32_surface_get_queued_window_rect (surface, scale, &queued_window_rect);
|
||||
|
||||
/* Apply queued resizes for non-double-buffered windows
|
||||
/* Apply queued resizes for non-double-buffered and non-layered windows
|
||||
* before painting them (we paint on the window DC directly,
|
||||
* it must have the right size).
|
||||
* Due to some poorly-undetstood issue delayed
|
||||
* resizing of double-buffered windows can produce weird
|
||||
* artefacts, so these are also resized before we paint.
|
||||
*/
|
||||
if (impl->drag_move_resize_context.native_move_resize_pending)
|
||||
if (impl->drag_move_resize_context.native_move_resize_pending &&
|
||||
(cairo_ctx == NULL || !cairo_ctx->layered))
|
||||
{
|
||||
impl->drag_move_resize_context.native_move_resize_pending = FALSE;
|
||||
gdk_win32_surface_apply_queued_move_resize (surface, queued_window_rect);
|
||||
|
||||
@@ -265,18 +265,25 @@ struct _GdkWin32Surface
|
||||
int initial_y;
|
||||
|
||||
/* left/right/top/bottom width of the shadow/resize-grip around the window */
|
||||
RECT shadow;
|
||||
RECT margins;
|
||||
|
||||
/* left+right and top+bottom from @shadow */
|
||||
int shadow_x;
|
||||
int shadow_y;
|
||||
/* left+right and top+bottom from @margins */
|
||||
int margins_x;
|
||||
int margins_y;
|
||||
|
||||
/* 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.
|
||||
/* 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.
|
||||
*/
|
||||
guint zero_shadow : 1;
|
||||
guint zero_margins : 1;
|
||||
guint inhibit_configure : 1;
|
||||
|
||||
/* Set to TRUE if window is using true layered mode adjustments
|
||||
* via UpdateLayeredWindow().
|
||||
* Layered windows that get SetLayeredWindowAttributes() called
|
||||
* on them are not true layered windows.
|
||||
*/
|
||||
guint layered : 1;
|
||||
|
||||
/* If TRUE, the @temp_styles is set to the styles that were temporarily
|
||||
* added to this window.
|
||||
*/
|
||||
@@ -302,6 +309,12 @@ struct _GdkWin32Surface
|
||||
int dib_width;
|
||||
int dib_height;
|
||||
|
||||
/* If the client wants uniformly-transparent window,
|
||||
* we remember the opacity value here and apply it
|
||||
* during UpdateLayredWindow() call, for layered windows.
|
||||
*/
|
||||
double layered_opacity;
|
||||
|
||||
HDC hdc;
|
||||
int hdc_count;
|
||||
HBITMAP saved_dc_bitmap; /* Original bitmap for dc */
|
||||
@@ -327,6 +340,9 @@ struct _GdkWin32Surface
|
||||
/* Enable all decorations? */
|
||||
gboolean decorate_all;
|
||||
|
||||
/* No. of windows to force layered windows off */
|
||||
guint suppress_layered;
|
||||
|
||||
/* Temporary styles that this window got for the purpose of
|
||||
* handling WM_SYSMENU.
|
||||
* They are removed at the first opportunity (usually WM_INITMENU).
|
||||
@@ -338,13 +354,6 @@ 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;
|
||||
@@ -366,6 +375,11 @@ int _gdk_win32_surface_get_scale_factor (GdkSurface *window);
|
||||
void _gdk_win32_get_window_client_area_rect (GdkSurface *window,
|
||||
int scale,
|
||||
RECT *rect);
|
||||
void _gdk_win32_update_layered_window_from_cache (GdkSurface *window,
|
||||
RECT *client_rect,
|
||||
gboolean do_move,
|
||||
gboolean do_resize,
|
||||
gboolean do_paint);
|
||||
|
||||
void gdk_win32_surface_move (GdkSurface *surface,
|
||||
int x,
|
||||
|
||||
@@ -63,6 +63,12 @@ gdk_win32_vulkan_context_create_surface (GdkVulkanContext *context,
|
||||
NULL,
|
||||
surface);
|
||||
|
||||
if (result == VK_SUCCESS)
|
||||
win32_surface->suppress_layered ++;
|
||||
|
||||
if (win32_surface->suppress_layered == 1)
|
||||
_gdk_win32_surface_update_style_bits (window);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1097,16 +1097,15 @@ 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_type = device_get_tool_type (device);
|
||||
tool = gdk_seat_get_tool (seat, serial_id, tool_id);
|
||||
|
||||
if (tool_type != GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
if (!tool && serial_id > 0)
|
||||
{
|
||||
tool = gdk_seat_get_tool (seat, serial_id, tool_id, tool_type);
|
||||
GdkDeviceToolType tool_type;
|
||||
|
||||
if (!tool && serial_id > 0)
|
||||
tool_type = device_get_tool_type (device);
|
||||
if (tool_type != GDK_DEVICE_TOOL_TYPE_UNKNOWN)
|
||||
{
|
||||
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 (!impl->toplevel_layout || gdk_toplevel_layout_get_resizable (impl->toplevel_layout))
|
||||
if (gdk_toplevel_layout_get_resizable (impl->toplevel_layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
@@ -2013,8 +2013,6 @@ _gdk_x11_surface_set_surface_scale (GdkSurface *surface,
|
||||
surface->height * impl->surface_scale);
|
||||
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
|
||||
g_object_notify (G_OBJECT (surface), "scale-factor");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1554,7 +1554,7 @@ rounded_inner_rect_contains_rect (const GskRoundedRect *rounded,
|
||||
MAX (rounded->corner[GSK_CORNER_BOTTOM_LEFT].height,
|
||||
rounded->corner[GSK_CORNER_BOTTOM_RIGHT].height);
|
||||
|
||||
return _graphene_rect_contains_rect (&inner, rect);
|
||||
return graphene_rect_contains_rect (&inner, rect);
|
||||
}
|
||||
|
||||
/* Current clip is NOT rounded but new one is definitely! */
|
||||
@@ -1644,8 +1644,8 @@ render_clipped_child (GskGLRenderer *self,
|
||||
/* well fuck */
|
||||
const float scale_x = builder->scale_x;
|
||||
const float scale_y = builder->scale_y;
|
||||
const GskRoundedRect scaled_clip = GSK_ROUNDED_RECT_INIT ((builder->dx + clip->origin.x) * scale_x,
|
||||
(builder->dy + clip->origin.y) * scale_y,
|
||||
const GskRoundedRect scaled_clip = GSK_ROUNDED_RECT_INIT (clip->origin.x * scale_x,
|
||||
clip->origin.y * scale_y,
|
||||
clip->size.width * scale_x,
|
||||
clip->size.height * scale_y);
|
||||
gboolean is_offscreen;
|
||||
@@ -1746,6 +1746,7 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
GskRoundedRect scaled_clip;
|
||||
gboolean is_offscreen;
|
||||
TextureRegion region;
|
||||
/* NOTE: We are *not* transforming the clip by the current modelview here.
|
||||
@@ -1754,7 +1755,19 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
*
|
||||
* We do, however, apply the scale factor to the child clip of course.
|
||||
*/
|
||||
ops_push_clip (builder, &transformed_clip);
|
||||
scaled_clip.bounds.origin.x = clip->bounds.origin.x * scale_x;
|
||||
scaled_clip.bounds.origin.y = clip->bounds.origin.y * scale_y;
|
||||
scaled_clip.bounds.size.width = clip->bounds.size.width * scale_x;
|
||||
scaled_clip.bounds.size.height = clip->bounds.size.height * scale_y;
|
||||
|
||||
/* Increase corner radius size by scale factor */
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
scaled_clip.corner[i].width = clip->corner[i].width * scale_x;
|
||||
scaled_clip.corner[i].height = clip->corner[i].height * scale_y;
|
||||
}
|
||||
|
||||
ops_push_clip (builder, &scaled_clip);
|
||||
if (!add_offscreen_ops (self, builder, &node->bounds,
|
||||
child,
|
||||
®ion, &is_offscreen,
|
||||
@@ -1766,8 +1779,7 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
ops_set_program (builder, &self->programs->blit_program);
|
||||
ops_set_texture (builder, region.texture_id);
|
||||
|
||||
load_vertex_data_with_region (ops_draw (builder, NULL), &node->bounds, builder,
|
||||
®ion, is_offscreen);
|
||||
load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3818,9 +3830,9 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
gboolean *is_offscreen,
|
||||
guint flags)
|
||||
{
|
||||
float width, height;
|
||||
const float dx = builder->dx;
|
||||
const float dy = builder->dy;
|
||||
float width, height;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
int render_target;
|
||||
@@ -3919,8 +3931,8 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
render_target);
|
||||
}
|
||||
|
||||
viewport = GRAPHENE_RECT_INIT ((bounds->origin.x + dx) * scale_x,
|
||||
(bounds->origin.y + dy) * scale_y,
|
||||
viewport = GRAPHENE_RECT_INIT (bounds->origin.x * scale_x,
|
||||
bounds->origin.y * scale_y,
|
||||
width, height);
|
||||
|
||||
init_projection_matrix (&item_proj, &viewport);
|
||||
@@ -3933,8 +3945,8 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
if (flags & RESET_CLIP)
|
||||
ops_push_clip (builder, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
|
||||
|
||||
builder->dx = dx;
|
||||
builder->dy = dy;
|
||||
builder->dx = 0;
|
||||
builder->dy = 0;
|
||||
|
||||
prev_opacity = ops_set_opacity (builder, 1.0);
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
|
||||
goto out;
|
||||
}
|
||||
|
||||
print_shader_info ("Fragment shader", fragment_id, resource_path);
|
||||
print_shader_info ("Fragment shader", vertex_id, resource_path);
|
||||
|
||||
program_id = glCreateProgram ();
|
||||
glAttachShader (program_id, vertex_id);
|
||||
@@ -232,8 +232,6 @@ 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)
|
||||
@@ -254,9 +252,14 @@ 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 gsize gsk_debug_flags__set;
|
||||
static volatile 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 gsize g_define_type_id__volatile = 0;
|
||||
static volatile 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 gsize render_node_type__volatile;
|
||||
static volatile 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 gsize register_types__volatile;
|
||||
static volatile gsize register_types__volatile;
|
||||
|
||||
if (g_once_init_enter (®ister_types__volatile))
|
||||
{
|
||||
|
||||
@@ -51,36 +51,11 @@ any license fees or royalties.</description>
|
||||
<gnome:userid>matthiasc</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Emmanuele Bassi</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:ebassi@gnome.org"/>
|
||||
<gnome:userid>ebassi</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Timm Baeder</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:mail@baedert.org"/>
|
||||
<gnome:userid>baedert</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Benjamin Otte</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:otte@gnome.org"/>
|
||||
<gnome:userid>otte</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Carlos Garnacho</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:carlosg@gnome.org"/>
|
||||
<gnome:userid>carlosg</gnome:userid>
|
||||
<foaf:name>Tim Janik</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:timj@gtk.org"/>
|
||||
<gnome:userid>timj</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
|
||||
@@ -667,21 +667,11 @@ 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/",
|
||||
base_name,
|
||||
program_name != NULL ? program_name : "unknown",
|
||||
"/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 gsize g_define_type_id__volatile = 0;
|
||||
static volatile 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,7 +30,6 @@ struct _GtkCssTokenizer
|
||||
{
|
||||
int ref_count;
|
||||
GBytes *bytes;
|
||||
GString *name_buffer;
|
||||
|
||||
const char *data;
|
||||
const char *end;
|
||||
@@ -96,13 +95,45 @@ gtk_css_token_clear (GtkCssToken *token)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_init (GtkCssToken *token,
|
||||
GtkCssTokenType type)
|
||||
gtk_css_token_initv (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
va_list args)
|
||||
{
|
||||
token->type = type;
|
||||
|
||||
switch ((guint)type)
|
||||
switch (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:
|
||||
@@ -126,8 +157,6 @@ gtk_css_token_init (GtkCssToken *token,
|
||||
case GTK_CSS_TOKEN_BAD_URL:
|
||||
case GTK_CSS_TOKEN_COMMENT:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,76 +515,15 @@ gtk_css_token_to_string (const GtkCssToken *token)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_init_string (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
char *string)
|
||||
gtk_css_token_init (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
...)
|
||||
{
|
||||
token->type = type;
|
||||
va_list 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 ();
|
||||
}
|
||||
va_start (args, type);
|
||||
gtk_css_token_initv (token, type, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
GtkCssTokenizer *
|
||||
@@ -566,7 +534,6 @@ 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);
|
||||
@@ -591,7 +558,6 @@ 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);
|
||||
}
|
||||
@@ -602,7 +568,11 @@ gtk_css_tokenizer_get_location (GtkCssTokenizer *tokenizer)
|
||||
return &tokenizer->position;
|
||||
}
|
||||
|
||||
static void G_GNUC_PRINTF(2, 3)
|
||||
static void
|
||||
gtk_css_tokenizer_parse_error (GError **error,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
static void
|
||||
gtk_css_tokenizer_parse_error (GError **error,
|
||||
const char *format,
|
||||
...)
|
||||
@@ -873,7 +843,7 @@ gtk_css_tokenizer_read_escape (GtkCssTokenizer *tokenizer)
|
||||
static char *
|
||||
gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
{
|
||||
g_string_set_size (tokenizer->name_buffer, 0);
|
||||
GString *string = g_string_new (NULL);
|
||||
|
||||
do {
|
||||
if (*tokenizer->data == '\\')
|
||||
@@ -881,7 +851,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 (tokenizer->name_buffer, value);
|
||||
g_string_append_unichar (string, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -889,16 +859,16 @@ gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
|
||||
if (tokenizer->data == tokenizer->end)
|
||||
{
|
||||
g_string_append_unichar (tokenizer->name_buffer, 0xFFFD);
|
||||
g_string_append_unichar (string, 0xFFFD);
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_css_tokenizer_consume_char (tokenizer, tokenizer->name_buffer);
|
||||
gtk_css_tokenizer_consume_char (tokenizer, string);
|
||||
}
|
||||
}
|
||||
else if (is_name (*tokenizer->data))
|
||||
{
|
||||
gtk_css_tokenizer_consume_char (tokenizer, tokenizer->name_buffer);
|
||||
gtk_css_tokenizer_consume_char (tokenizer, string);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -907,7 +877,7 @@ gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
}
|
||||
while (tokenizer->data != tokenizer->end);
|
||||
|
||||
return g_strndup (tokenizer->name_buffer->str, tokenizer->name_buffer->len);
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1000,7 +970,7 @@ gtk_css_tokenizer_read_url (GtkCssTokenizer *tokenizer,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_URL, g_string_free (url, FALSE));
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_URL, g_string_free (url, FALSE));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1029,12 +999,12 @@ gtk_css_tokenizer_read_ident_like (GtkCssTokenizer *tokenizer,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_FUNCTION, name);
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_FUNCTION, name);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_IDENT, name);
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_IDENT, name);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1047,7 +1017,6 @@ 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 == '-')
|
||||
{
|
||||
@@ -1113,34 +1082,27 @@ 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))
|
||||
{
|
||||
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));
|
||||
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));
|
||||
}
|
||||
else if (gtk_css_tokenizer_remaining (tokenizer) > 0 && *tokenizer->data == '%')
|
||||
{
|
||||
gtk_css_token_init_number (token, GTK_CSS_TOKEN_PERCENTAGE, value);
|
||||
gtk_css_token_init (token,
|
||||
GTK_CSS_TOKEN_PERCENTAGE,
|
||||
sign * (integer + ((double) fractional / fractional_length)) * pow (10, exponent_sign * exponent));
|
||||
gtk_css_tokenizer_consume_ascii (tokenizer);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,7 +1110,7 @@ static void
|
||||
gtk_css_tokenizer_read_delim (GtkCssTokenizer *tokenizer,
|
||||
GtkCssToken *token)
|
||||
{
|
||||
gtk_css_token_init_delim (token, g_utf8_get_char (tokenizer->data));
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, g_utf8_get_char (tokenizer->data));
|
||||
gtk_css_tokenizer_consume_char (tokenizer, NULL);
|
||||
}
|
||||
|
||||
@@ -1232,8 +1194,8 @@ gtk_css_tokenizer_read_string (GtkCssTokenizer *tokenizer,
|
||||
gtk_css_tokenizer_consume_char (tokenizer, string);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_STRING, g_string_free (string, FALSE));
|
||||
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_STRING, g_string_free (string, FALSE));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1317,13 +1279,13 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
|
||||
else
|
||||
type = GTK_CSS_TOKEN_HASH_UNRESTRICTED;
|
||||
|
||||
gtk_css_token_init_string (token,
|
||||
type,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
gtk_css_token_init (token,
|
||||
type,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init_delim (token, '#');
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, '#');
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
@@ -1399,13 +1361,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_string (token,
|
||||
GTK_CSS_TOKEN_AT_KEYWORD,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
gtk_css_token_init (token,
|
||||
GTK_CSS_TOKEN_AT_KEYWORD,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init_delim (token, '@');
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, '@');
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
@@ -1421,7 +1383,7 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init_delim (token, '\\');
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_DELIM, '\\');
|
||||
gtk_css_tokenizer_consume_ascii (tokenizer);
|
||||
gtk_css_tokenizer_parse_error (error, "Newline may not follow '\' escape character");
|
||||
return FALSE;
|
||||
|
||||
@@ -63,7 +63,6 @@ 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,7 +34,6 @@ 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>
|
||||
'''
|
||||
@@ -49,10 +48,9 @@ for f in get_files('theme/Adwaita/assets', '.svg'):
|
||||
|
||||
xml += '''
|
||||
<file>theme/HighContrast/gtk.css</file>
|
||||
<file>theme/HighContrast/gtk-dark.css</file>
|
||||
<file alias='theme/HighContrastInverse/gtk.css'>theme/HighContrast/gtk-dark.css</file>
|
||||
<file alias='theme/HighContrastInverse/gtk.css'>theme/HighContrast/gtk-inverse.css</file>
|
||||
<file>theme/HighContrast/HighContrast.css</file>
|
||||
<file>theme/HighContrast/HighContrast-dark.css</file>
|
||||
<file>theme/HighContrast/HighContrast-inverse.css</file>
|
||||
'''
|
||||
|
||||
for f in get_files('theme/HighContrast/assets', '.png'):
|
||||
|
||||
@@ -101,12 +101,6 @@
|
||||
* "title", _("About ExampleCode"),
|
||||
* NULL);
|
||||
* ]|
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkAboutDialog has a single CSS node with the name window and style
|
||||
* class .aboutdialog.
|
||||
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
@@ -315,17 +309,6 @@ stack_visible_child_notify (GtkStack *stack,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_about_dialog_map (GtkWidget *widget)
|
||||
{
|
||||
GtkAboutDialog *about = GTK_ABOUT_DIALOG (widget);
|
||||
|
||||
if (gtk_widget_get_visible (about->stack_switcher))
|
||||
gtk_widget_grab_focus (gtk_widget_get_first_child (about->stack_switcher));
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_about_dialog_parent_class)->map (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_about_dialog_class_init (GtkAboutDialogClass *klass)
|
||||
{
|
||||
@@ -340,8 +323,6 @@ gtk_about_dialog_class_init (GtkAboutDialogClass *klass)
|
||||
|
||||
object_class->finalize = gtk_about_dialog_finalize;
|
||||
|
||||
widget_class->map = gtk_about_dialog_map;
|
||||
|
||||
klass->activate_link = gtk_about_dialog_activate_link;
|
||||
|
||||
/**
|
||||
@@ -1663,7 +1644,41 @@ 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]);
|
||||
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (about->logo_image), icon_name);
|
||||
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));
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (about), props[PROP_LOGO_ICON_NAME]);
|
||||
|
||||
|
||||
@@ -496,12 +496,12 @@ gtk_accessible_update_relation_value (GtkAccessible *self,
|
||||
GtkAccessibleRelation relations[],
|
||||
const GValue values[])
|
||||
{
|
||||
GtkATContext *context;
|
||||
|
||||
g_return_if_fail (GTK_IS_ACCESSIBLE (self));
|
||||
g_return_if_fail (n_relations > 0);
|
||||
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
GtkATContext *context = gtk_accessible_get_at_context (self);
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < n_relations; i++)
|
||||
{
|
||||
@@ -520,15 +520,13 @@ gtk_accessible_update_relation_value (GtkAccessible *self,
|
||||
break;
|
||||
}
|
||||
|
||||
if (context)
|
||||
gtk_at_context_set_accessible_relation (context, relation, real_value);
|
||||
gtk_at_context_set_accessible_relation (context, relation, real_value);
|
||||
|
||||
if (real_value != NULL)
|
||||
gtk_accessible_value_unref (real_value);
|
||||
}
|
||||
|
||||
if (context)
|
||||
gtk_at_context_update (context);
|
||||
gtk_at_context_update (context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -324,9 +324,7 @@ icon_loaded (GObject *object,
|
||||
|
||||
- (void)didChangeToggled
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
[self setState:gtk_menu_tracker_item_get_toggled (trackerItem) ? NSOnState : NSOffState];
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
[self setState:gtk_menu_tracker_item_get_toggled (trackerItem) ? NSControlStateValueOn : NSControlStateValueOff];
|
||||
}
|
||||
|
||||
- (void)didChangeAccel
|
||||
|
||||
@@ -32,16 +32,17 @@
|
||||
* @Short_description: A frame that constrains its child to a particular aspect ratio
|
||||
* @Title: GtkAspectFrame
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkAspectFrame uses a CSS node with name `frame`.
|
||||
* GtkAspectFrame uses a CSS node with name frame.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -137,12 +138,6 @@ 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",
|
||||
@@ -150,12 +145,6 @@ 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",
|
||||
@@ -163,14 +152,6 @@ 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",
|
||||
@@ -178,12 +159,6 @@ 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",
|
||||
@@ -191,11 +166,7 @@ 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",
|
||||
@@ -458,8 +429,7 @@ gtk_aspect_frame_set_ratio (GtkAspectFrame *self,
|
||||
* gtk_aspect_frame_get_ratio:
|
||||
* @self: a #GtkAspectFrame
|
||||
*
|
||||
* Returns the desired aspect ratio of the child set using
|
||||
* gtk_aspect_frame_set_ratio().
|
||||
* Returns the desired aspect ratio of the child.
|
||||
*
|
||||
* Returns: the desired aspect ratio
|
||||
*/
|
||||
|
||||
@@ -541,27 +541,25 @@ 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 @self
|
||||
* Checks if the given @value has been added to @bitset
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -260,7 +260,7 @@ typedef struct
|
||||
char *domain;
|
||||
GHashTable *objects;
|
||||
GSList *delayed_properties;
|
||||
GPtrArray *signals;
|
||||
GSList *signals;
|
||||
GSList *bindings;
|
||||
char *filename;
|
||||
char *resource_prefix;
|
||||
@@ -375,8 +375,8 @@ gtk_builder_finalize (GObject *object)
|
||||
#endif
|
||||
|
||||
g_hash_table_destroy (priv->objects);
|
||||
if (priv->signals)
|
||||
g_ptr_array_free (priv->signals, TRUE);
|
||||
|
||||
g_slist_free_full (priv->signals, (GDestroyNotify)_free_signal_info);
|
||||
|
||||
G_OBJECT_CLASS (gtk_builder_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -527,21 +527,19 @@ static void
|
||||
gtk_builder_get_parameters (GtkBuilder *builder,
|
||||
GType object_type,
|
||||
const char *object_name,
|
||||
GPtrArray *properties,
|
||||
GSList *properties,
|
||||
GParamFlags filter_flags,
|
||||
ObjectProperties *parameters,
|
||||
ObjectProperties *filtered_parameters)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
GSList *l;
|
||||
DelayedProperty *property;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!properties)
|
||||
return;
|
||||
|
||||
for (guint i = 0; i < properties->len; i++)
|
||||
for (l = properties; l; l = l->next)
|
||||
{
|
||||
PropertyInfo *prop = g_ptr_array_index (properties, i);
|
||||
PropertyInfo *prop = (PropertyInfo*)l->data;
|
||||
const char *property_name = g_intern_string (prop->pspec->name);
|
||||
GValue property_value = G_VALUE_INIT;
|
||||
|
||||
@@ -1020,14 +1018,12 @@ _gtk_builder_add (GtkBuilder *builder,
|
||||
|
||||
void
|
||||
_gtk_builder_add_signals (GtkBuilder *builder,
|
||||
GPtrArray *signals)
|
||||
GSList *signals)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
|
||||
if (G_UNLIKELY (!priv->signals))
|
||||
priv->signals = g_ptr_array_new_with_free_func ((GDestroyNotify)_free_signal_info);
|
||||
|
||||
g_ptr_array_extend_and_steal (priv->signals, signals);
|
||||
priv->signals = g_slist_concat (priv->signals,
|
||||
g_slist_copy (signals));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1157,6 +1153,9 @@ 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 *
|
||||
@@ -1174,9 +1173,7 @@ gtk_builder_new (void)
|
||||
* Parses a file containing a [GtkBuilder UI definition][BUILDER-UI]
|
||||
* and merges it with the current contents of @builder.
|
||||
*
|
||||
* 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.
|
||||
* Most users will probably want to use gtk_builder_new_from_file().
|
||||
*
|
||||
* 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
|
||||
@@ -1370,9 +1367,7 @@ 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.
|
||||
*
|
||||
* 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.
|
||||
* Most users will probably want to use gtk_builder_new_from_resource().
|
||||
*
|
||||
* 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
|
||||
@@ -1522,9 +1517,7 @@ 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.
|
||||
*
|
||||
* 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.
|
||||
* Most users will probably want to use gtk_builder_new_from_string().
|
||||
*
|
||||
* Upon errors %FALSE will be returned and @error will be assigned a
|
||||
* #GError from the #GTK_BUILDER_ERROR, #G_MARKUP_ERROR or
|
||||
@@ -1855,17 +1848,18 @@ gtk_builder_connect_signals (GtkBuilder *builder,
|
||||
GError **error)
|
||||
{
|
||||
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
|
||||
GSList *l;
|
||||
GObject *object;
|
||||
GObject *connect_object;
|
||||
gboolean result = TRUE;
|
||||
gboolean result = FALSE;
|
||||
|
||||
if (!priv->signals ||
|
||||
priv->signals->len == 0)
|
||||
if (!priv->signals)
|
||||
return TRUE;
|
||||
|
||||
for (guint i = 0; i < priv->signals->len; i++)
|
||||
priv->signals = g_slist_reverse (priv->signals);
|
||||
for (l = priv->signals; l; l = l->next)
|
||||
{
|
||||
SignalInfo *signal = g_ptr_array_index (priv->signals, i);
|
||||
SignalInfo *signal = (SignalInfo*)l->data;
|
||||
GClosure *closure;
|
||||
|
||||
g_assert (signal != NULL);
|
||||
@@ -1898,10 +1892,7 @@ gtk_builder_connect_signals (GtkBuilder *builder,
|
||||
error);
|
||||
|
||||
if (closure == NULL)
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
g_signal_connect_closure_by_id (object,
|
||||
signal->id,
|
||||
@@ -1909,8 +1900,10 @@ gtk_builder_connect_signals (GtkBuilder *builder,
|
||||
closure,
|
||||
signal->flags & G_CONNECT_AFTER ? TRUE : FALSE);
|
||||
}
|
||||
if (l == NULL)
|
||||
result = TRUE;
|
||||
|
||||
g_ptr_array_free (priv->signals, TRUE);
|
||||
g_slist_free_full (priv->signals, (GDestroyNotify)_free_signal_info);
|
||||
priv->signals = NULL;
|
||||
|
||||
return result;
|
||||
|
||||
@@ -32,8 +32,7 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
const GtkBuildableParser *last_parser;
|
||||
gpointer last_user_data;
|
||||
int last_depth;
|
||||
@@ -42,8 +41,9 @@ typedef struct
|
||||
static void
|
||||
pop_subparser_stack (GtkBuildableParseContext *context)
|
||||
{
|
||||
GtkBuildableParserStack *stack = &g_array_index (context->subparser_stack, GtkBuildableParserStack,
|
||||
context->subparser_stack->len - 1);
|
||||
GtkBuildableParserStack *stack =
|
||||
&g_array_index (context->subparser_stack, GtkBuildableParserStack,
|
||||
context->subparser_stack->len - 1);
|
||||
|
||||
context->awaiting_pop = TRUE;
|
||||
context->held_user_data = context->user_data;
|
||||
@@ -57,17 +57,15 @@ pop_subparser_stack (GtkBuildableParseContext *context)
|
||||
static void
|
||||
possibly_finish_subparser (GtkBuildableParseContext *context)
|
||||
{
|
||||
GtkBuildableParserStack *stack;
|
||||
if (context->subparser_stack->len > 0)
|
||||
{
|
||||
GtkBuildableParserStack *stack =
|
||||
&g_array_index (context->subparser_stack, GtkBuildableParserStack,
|
||||
context->subparser_stack->len - 1);
|
||||
|
||||
if (!context->subparser_stack ||
|
||||
context->subparser_stack->len == 0)
|
||||
return;
|
||||
|
||||
stack = &g_array_index (context->subparser_stack, GtkBuildableParserStack,
|
||||
context->subparser_stack->len - 1);
|
||||
|
||||
if (stack->last_depth == context->tag_stack->len)
|
||||
pop_subparser_stack (context);
|
||||
if (stack->last_depth == context->tag_stack->len)
|
||||
pop_subparser_stack (context);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -130,9 +128,6 @@ proxy_error (GMarkupParseContext *gm_context,
|
||||
|
||||
/* report the error all the way up to free all the user-data */
|
||||
|
||||
if (!context->subparser_stack)
|
||||
return;
|
||||
|
||||
while (context->subparser_stack->len > 0)
|
||||
{
|
||||
pop_subparser_stack (context);
|
||||
@@ -162,7 +157,7 @@ gtk_buildable_parse_context_init (GtkBuildableParseContext *context,
|
||||
context->parser = parser;
|
||||
context->user_data = user_data;
|
||||
|
||||
context->subparser_stack = NULL;
|
||||
context->subparser_stack = g_array_new (FALSE, FALSE, sizeof (GtkBuildableParserStack));
|
||||
context->tag_stack = g_ptr_array_new ();
|
||||
context->held_user_data = NULL;
|
||||
context->awaiting_pop = FALSE;
|
||||
@@ -171,9 +166,7 @@ gtk_buildable_parse_context_init (GtkBuildableParseContext *context,
|
||||
static void
|
||||
gtk_buildable_parse_context_free (GtkBuildableParseContext *context)
|
||||
{
|
||||
if (context->subparser_stack)
|
||||
g_array_unref (context->subparser_stack);
|
||||
|
||||
g_array_unref (context->subparser_stack);
|
||||
g_ptr_array_unref (context->tag_stack);
|
||||
}
|
||||
|
||||
@@ -252,9 +245,6 @@ gtk_buildable_parse_context_push (GtkBuildableParseContext *context,
|
||||
context->parser = parser;
|
||||
context->user_data = user_data;
|
||||
|
||||
if (!context->subparser_stack)
|
||||
context->subparser_stack = g_array_new (FALSE, FALSE, sizeof (GtkBuildableParserStack));
|
||||
|
||||
g_array_append_val (context->subparser_stack, stack);
|
||||
}
|
||||
|
||||
@@ -375,17 +365,16 @@ static void free_object_info (ObjectInfo *info);
|
||||
static inline void
|
||||
state_push (ParserData *data, gpointer info)
|
||||
{
|
||||
g_ptr_array_add (data->stack, info);
|
||||
data->stack = g_slist_prepend (data->stack, info);
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
state_peek (ParserData *data)
|
||||
{
|
||||
if (!data->stack ||
|
||||
data->stack->len == 0)
|
||||
if (!data->stack)
|
||||
return NULL;
|
||||
|
||||
return g_ptr_array_index (data->stack, data->stack->len - 1);
|
||||
return data->stack->data;
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
@@ -395,9 +384,8 @@ state_pop (ParserData *data)
|
||||
|
||||
g_assert (data->stack);
|
||||
|
||||
old = state_peek (data);
|
||||
g_assert (old);
|
||||
data->stack->len --;
|
||||
old = data->stack->data;
|
||||
data->stack = g_slist_delete_link (data->stack, data->stack);
|
||||
return old;
|
||||
}
|
||||
#define state_peek_info(data, st) ((st*)state_peek(data))
|
||||
@@ -471,6 +459,8 @@ builder_construct (ParserData *data,
|
||||
if (object_info->object && object_info->applied_properties)
|
||||
return object_info->object;
|
||||
|
||||
object_info->properties = g_slist_reverse (object_info->properties);
|
||||
|
||||
if (object_info->object == NULL)
|
||||
{
|
||||
object = _gtk_builder_construct (data->builder, object_info, error);
|
||||
@@ -797,21 +787,19 @@ free_object_info (ObjectInfo *info)
|
||||
{
|
||||
/* Do not free the signal items, which GtkBuilder takes ownership of */
|
||||
g_type_class_unref (info->oclass);
|
||||
if (info->signals)
|
||||
g_ptr_array_free (info->signals, TRUE);
|
||||
if (info->properties)
|
||||
g_ptr_array_free (info->properties, TRUE);
|
||||
g_slist_free (info->signals);
|
||||
g_slist_free_full (info->properties, (GDestroyNotify)free_property_info);
|
||||
g_free (info->constructor);
|
||||
g_free (info->id);
|
||||
g_slice_free (ObjectInfo, info);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_child (ParserData *data,
|
||||
const char *element_name,
|
||||
parse_child (ParserData *data,
|
||||
const char *element_name,
|
||||
const char **names,
|
||||
const char **values,
|
||||
GError **error)
|
||||
GError **error)
|
||||
|
||||
{
|
||||
ObjectInfo* object_info;
|
||||
@@ -1707,6 +1695,7 @@ parse_custom (GtkBuildableParseContext *context,
|
||||
ObjectInfo* object_info = (ObjectInfo*)parent_info;
|
||||
if (!object_info->object)
|
||||
{
|
||||
object_info->properties = g_slist_reverse (object_info->properties);
|
||||
object_info->object = _gtk_builder_construct (data->builder,
|
||||
object_info,
|
||||
error);
|
||||
@@ -1884,10 +1873,7 @@ end_element (GtkBuildableParseContext *context,
|
||||
g_string_assign (prop_info->text, translated);
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (!object_info->properties))
|
||||
object_info->properties = g_ptr_array_new_with_free_func ((GDestroyNotify)free_property_info);
|
||||
|
||||
g_ptr_array_add (object_info->properties, prop_info);
|
||||
object_info->properties = g_slist_prepend (object_info->properties, prop_info);
|
||||
}
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
@@ -1955,13 +1941,8 @@ end_element (GtkBuildableParseContext *context,
|
||||
|
||||
if (GTK_IS_BUILDABLE (object_info->object) &&
|
||||
GTK_BUILDABLE_GET_IFACE (object_info->object)->parser_finished)
|
||||
g_ptr_array_add (data->finalizers, object_info->object);
|
||||
|
||||
if (object_info->signals)
|
||||
{
|
||||
_gtk_builder_add_signals (data->builder, object_info->signals);
|
||||
object_info->signals = NULL;
|
||||
}
|
||||
data->finalizers = g_slist_prepend (data->finalizers, object_info->object);
|
||||
_gtk_builder_add_signals (data->builder, object_info->signals);
|
||||
|
||||
free_object_info (object_info);
|
||||
}
|
||||
@@ -1979,11 +1960,7 @@ end_element (GtkBuildableParseContext *context,
|
||||
ObjectInfo *object_info = (ObjectInfo*)state_peek_info (data, CommonInfo);
|
||||
g_assert (object_info != NULL);
|
||||
signal_info->object_name = g_strdup (object_info->id);
|
||||
|
||||
if (G_UNLIKELY (!object_info->signals))
|
||||
object_info->signals = g_ptr_array_new ();
|
||||
|
||||
g_ptr_array_add (object_info->signals, signal_info);
|
||||
object_info->signals = g_slist_prepend (object_info->signals, signal_info);
|
||||
}
|
||||
else if (strcmp (element_name, "constant") == 0 ||
|
||||
strcmp (element_name, "closure") == 0 ||
|
||||
@@ -2100,7 +2077,7 @@ text (GtkBuildableParseContext *context,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data->stack || data->stack->len == 0)
|
||||
if (!data->stack)
|
||||
return;
|
||||
|
||||
info = state_peek_info (data, CommonInfo);
|
||||
@@ -2141,6 +2118,41 @@ 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,
|
||||
@@ -2174,8 +2186,6 @@ _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 ();
|
||||
data.finalizers = g_ptr_array_new ();
|
||||
|
||||
if (requested_objs)
|
||||
{
|
||||
@@ -2215,9 +2225,10 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
}
|
||||
|
||||
/* Common parser_finished, for all created objects */
|
||||
for (guint i = 0; i < data.finalizers->len; i++)
|
||||
data.finalizers = g_slist_reverse (data.finalizers);
|
||||
for (l = data.finalizers; l; l = l->next)
|
||||
{
|
||||
GtkBuildable *buildable = g_ptr_array_index (data.finalizers, i);
|
||||
GtkBuildable *buildable = (GtkBuildable*)l->data;
|
||||
|
||||
gtk_buildable_parser_finished (GTK_BUILDABLE (buildable), builder);
|
||||
if (_gtk_builder_lookup_failed (builder, error))
|
||||
@@ -2226,11 +2237,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);
|
||||
g_ptr_array_free (data.finalizers, TRUE);
|
||||
gtk_buildable_parse_context_free (&data.ctx);
|
||||
|
||||
/* restore the original domain */
|
||||
|
||||
@@ -46,11 +46,9 @@ typedef struct {
|
||||
GObjectClass *oclass;
|
||||
char *id;
|
||||
char *constructor;
|
||||
|
||||
GPtrArray *properties;
|
||||
GPtrArray *signals;
|
||||
GSList *properties;
|
||||
GSList *signals;
|
||||
GSList *bindings;
|
||||
|
||||
GObject *object;
|
||||
CommonInfo *parent;
|
||||
gboolean applied_properties;
|
||||
@@ -175,11 +173,11 @@ typedef struct {
|
||||
const char *last_element;
|
||||
GtkBuilder *builder;
|
||||
char *domain;
|
||||
GPtrArray *stack;
|
||||
GSList *stack;
|
||||
SubParser *subparser;
|
||||
GtkBuildableParseContext ctx;
|
||||
const char *filename;
|
||||
GPtrArray *finalizers;
|
||||
GSList *finalizers;
|
||||
GSList *custom_finalizers;
|
||||
|
||||
const char **requested_objects; /* NULL if all the objects are requested */
|
||||
@@ -192,6 +190,8 @@ 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,
|
||||
@@ -220,7 +220,7 @@ void _gtk_builder_add_object (GtkBuilder *builder,
|
||||
void _gtk_builder_add (GtkBuilder *builder,
|
||||
ChildInfo *child_info);
|
||||
void _gtk_builder_add_signals (GtkBuilder *builder,
|
||||
GPtrArray *signals);
|
||||
GSList *signals);
|
||||
gboolean _gtk_builder_finish (GtkBuilder *builder,
|
||||
GError **error);
|
||||
void _free_signal_info (SignalInfo *info,
|
||||
@@ -286,5 +286,8 @@ 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__ */
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "gtkcellrenderertoggle.h"
|
||||
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcsstransientnodeprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkprivate.h"
|
||||
@@ -127,12 +126,26 @@ gtk_cell_renderer_toggle_init (GtkCellRendererToggle *celltoggle)
|
||||
priv->active = FALSE;
|
||||
priv->radio = FALSE;
|
||||
|
||||
priv->cssnode = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("check"));
|
||||
|
||||
g_object_set (celltoggle, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
|
||||
gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (celltoggle), 2, 2);
|
||||
|
||||
priv->inconsistent = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_renderer_toggle_dispose (GObject *object)
|
||||
{
|
||||
GtkCellRendererToggle *celltoggle = GTK_CELL_RENDERER_TOGGLE (object);
|
||||
GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (celltoggle);
|
||||
|
||||
g_clear_object (&priv->cssnode);
|
||||
|
||||
G_OBJECT_CLASS (gtk_cell_renderer_toggle_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_cell_renderer_toggle_get_request_mode (GtkCellRenderer *cell)
|
||||
{
|
||||
@@ -183,6 +196,7 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class)
|
||||
|
||||
object_class->get_property = gtk_cell_renderer_toggle_get_property;
|
||||
object_class->set_property = gtk_cell_renderer_toggle_set_property;
|
||||
object_class->dispose = gtk_cell_renderer_toggle_dispose;
|
||||
|
||||
cell_class->get_request_mode = gtk_cell_renderer_toggle_get_request_mode;
|
||||
cell_class->get_preferred_width = gtk_cell_renderer_toggle_get_preferred_width;
|
||||
@@ -342,30 +356,29 @@ gtk_cell_renderer_toggle_new (void)
|
||||
|
||||
static GtkStyleContext *
|
||||
gtk_cell_renderer_toggle_save_context (GtkCellRendererToggle *cell,
|
||||
GtkWidget *widget)
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (cell);
|
||||
GtkStyleContext *context;
|
||||
GtkCssNode *cssnode;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
cssnode = gtk_css_transient_node_new (gtk_widget_get_css_node (widget));
|
||||
if (priv->radio)
|
||||
gtk_css_node_set_name (cssnode, g_quark_from_static_string ("radio"));
|
||||
else
|
||||
gtk_css_node_set_name (cssnode, g_quark_from_static_string ("check"));
|
||||
gtk_style_context_save_to_node (context, cssnode);
|
||||
g_object_unref (cssnode);
|
||||
gtk_css_node_set_parent (priv->cssnode, gtk_widget_get_css_node (widget));
|
||||
gtk_style_context_save_to_node (context, priv->cssnode);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static void
|
||||
static GtkStyleContext *
|
||||
gtk_cell_renderer_toggle_restore_context (GtkCellRendererToggle *cell,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (cell);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
gtk_css_node_set_parent (priv->cssnode, NULL);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -551,6 +564,10 @@ gtk_cell_renderer_toggle_set_radio (GtkCellRendererToggle *toggle,
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle));
|
||||
|
||||
priv->radio = radio;
|
||||
if (radio)
|
||||
gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("radio"));
|
||||
else
|
||||
gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("check"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) + spacing);
|
||||
center_size = size - 2 * MAX (start_size, end_size);
|
||||
center_pos = (size / 2) - (center_size / 2) + spacing;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 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.
|
||||
* 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().
|
||||
*
|
||||
* Returns: %TRUE if @drop is accepted
|
||||
*/
|
||||
@@ -874,6 +874,8 @@ 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 gsize gtk_define_expression_type_id__volatile; \
|
||||
static volatile 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 gsize param_expression_type__volatile;
|
||||
static volatile 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 gsize expression_type__volatile;
|
||||
static volatile gsize expression_type__volatile;
|
||||
|
||||
if (g_once_init_enter (&expression_type__volatile))
|
||||
{
|
||||
|
||||
@@ -280,7 +280,7 @@ gtk_file_chooser_get_create_folders (GtkFileChooser *chooser)
|
||||
/**
|
||||
* gtk_file_chooser_set_current_name:
|
||||
* @chooser: a #GtkFileChooser
|
||||
* @name: (type utf8): the filename to use, as a UTF-8 string
|
||||
* @name: (type filename): the filename to use, as a UTF-8 string
|
||||
*
|
||||
* Sets the current name in the file selector, as if entered
|
||||
* by the user. Note that the name passed in here is a UTF-8
|
||||
|
||||
@@ -114,6 +114,9 @@ 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);
|
||||
|
||||
@@ -494,7 +497,7 @@ gtk_frame_size_allocate (GtkWidget *widget,
|
||||
GtkFramePrivate *priv = gtk_frame_get_instance_private (frame);
|
||||
GtkAllocation new_allocation;
|
||||
|
||||
GTK_FRAME_GET_CLASS (frame)->compute_child_allocation (frame, &new_allocation);
|
||||
gtk_frame_compute_child_allocation (frame, &new_allocation);
|
||||
|
||||
if (priv->label_widget &&
|
||||
gtk_widget_get_visible (priv->label_widget))
|
||||
@@ -526,6 +529,16 @@ 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,8 +51,7 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_DELAY_FACTOR = 1,
|
||||
LAST_PROP
|
||||
PROP_DELAY_FACTOR = 1
|
||||
};
|
||||
|
||||
struct _GtkGestureLongPressPrivate
|
||||
@@ -68,14 +67,15 @@ 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 = gtk_gesture_long_press_get_instance_private (gesture);
|
||||
GtkGestureLongPressPrivate *priv;
|
||||
|
||||
priv = gtk_gesture_long_press_get_instance_private (GTK_GESTURE_LONG_PRESS (gesture));
|
||||
priv->delay_factor = 1.0;
|
||||
}
|
||||
|
||||
@@ -275,14 +275,13 @@ 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;
|
||||
|
||||
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);
|
||||
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));
|
||||
|
||||
/**
|
||||
* GtkGestureLongPress::pressed:
|
||||
@@ -352,12 +351,9 @@ 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_by_pspec (G_OBJECT (gesture), props[PROP_DELAY_FACTOR]);
|
||||
g_object_notify (G_OBJECT (gesture), "delay-factor");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -322,8 +322,6 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus *gesture,
|
||||
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);
|
||||
@@ -340,26 +338,28 @@ gtk_gesture_stylus_get_backlog (GtkGestureStylus *gesture,
|
||||
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++)
|
||||
{
|
||||
const GdkTimeCoord *time_coord = &history[i];
|
||||
GdkTimeCoord *time_coord = &history[i];
|
||||
graphene_point_t p;
|
||||
|
||||
if (gtk_widget_compute_point (event_widget, controller_widget,
|
||||
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_WIDGET (native),
|
||||
gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)),
|
||||
&GRAPHENE_POINT_INIT (time_coord->axes[GDK_AXIS_X] - surf_x,
|
||||
time_coord->axes[GDK_AXIS_Y] - surf_y),
|
||||
&p))
|
||||
{
|
||||
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);
|
||||
time_coord->axes[GDK_AXIS_X] = p.x;
|
||||
time_coord->axes[GDK_AXIS_Y] = p.y;
|
||||
}
|
||||
}
|
||||
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_prepend (GTK_BOX (bar->start_box), controls);
|
||||
gtk_box_append (GTK_BOX (bar->start_box), controls);
|
||||
bar->start_window_controls = controls;
|
||||
|
||||
controls = gtk_window_controls_new (GTK_PACK_END);
|
||||
|
||||
@@ -348,8 +348,7 @@ 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_AFFECTS_ICON_SIZE))
|
||||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_TEXTURE))
|
||||
{
|
||||
/* 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,
|
||||
const char *full_dir,
|
||||
char *full_dir,
|
||||
GtkStringSet *set)
|
||||
{
|
||||
GHashTable *icons = NULL;
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
* SECTION:gtkimage
|
||||
* @Short_description: A widget displaying an image
|
||||
* @Title: GtkImage
|
||||
* @SeeAlso: #GdkTexture, #GtkPicture
|
||||
* @SeeAlso: #GdkTexture
|
||||
*
|
||||
* The #GtkImage widget displays an image. Various kinds of object
|
||||
* can be displayed as an image; most typically, you would load a
|
||||
@@ -67,10 +67,6 @@
|
||||
* In this case, the #GtkImage:resource, gtk_image_new_from_resource() and
|
||||
* gtk_image_set_from_resource() should be used.
|
||||
*
|
||||
* GtkImage displays its image as an icon, with a size that is determined
|
||||
* by the application. See #GtkPicture if you want to show an image at is
|
||||
* actual size.
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkImage has a single CSS node with the name image. The style classes
|
||||
|
||||
@@ -24,9 +24,27 @@
|
||||
|
||||
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,13 +27,10 @@
|
||||
* SECTION:gtkmediastream
|
||||
* @Short_description: Display media in GTK
|
||||
* @Title: GtkMediaStream
|
||||
* @See_also: #GdkPaintable, #GtkMediaFile
|
||||
* @See_also: #GdkPaintable
|
||||
*
|
||||
* #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:
|
||||
|
||||
@@ -319,7 +319,6 @@ 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,6 +113,18 @@ 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,
|
||||
@@ -127,9 +139,148 @@ 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);
|
||||
|
||||
@@ -141,159 +292,6 @@ 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,
|
||||
@@ -340,137 +338,115 @@ gtk_message_dialog_constructed (GObject *object)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_class_init (GtkMessageDialogClass *class)
|
||||
static void
|
||||
gtk_message_dialog_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkWidgetClass *widget_class;
|
||||
GObjectClass *gobject_class;
|
||||
GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (object);
|
||||
GtkMessageDialogPrivate *priv = gtk_message_dialog_get_instance_private (dialog);
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
gobject_class = G_OBJECT_CLASS (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);
|
||||
|
||||
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 (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);
|
||||
|
||||
/**
|
||||
* 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));
|
||||
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;
|
||||
|
||||
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);
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_init (GtkMessageDialog *dialog)
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -506,9 +482,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)
|
||||
@@ -569,7 +545,7 @@ gtk_message_dialog_new (GtkWindow *parent,
|
||||
* gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
|
||||
* markup);
|
||||
* ]|
|
||||
*
|
||||
*
|
||||
* Returns: a new #GtkMessageDialog
|
||||
**/
|
||||
GtkWidget*
|
||||
@@ -606,7 +582,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].
|
||||
**/
|
||||
@@ -645,7 +621,6 @@ 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);
|
||||
@@ -659,7 +634,6 @@ 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);
|
||||
}
|
||||
}
|
||||
@@ -703,7 +677,6 @@ 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);
|
||||
@@ -717,7 +690,6 @@ 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);
|
||||
}
|
||||
}
|
||||
@@ -745,3 +717,45 @@ 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");
|
||||
}
|
||||
|
||||
|
||||