Compare commits
252 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61f7ac09bc | |||
| 688085cfaf | |||
| 7257d1c15f | |||
| 21d40fc038 | |||
| 93ff65c685 | |||
| 7e7201745d | |||
| 50a986605c | |||
| 96994568fd | |||
| b494d94bdb | |||
| 9d6ccc0fe0 | |||
| a56e187352 | |||
| dcdcc659ef | |||
| ae8e844dec | |||
| e566ba54d9 | |||
| 70732afb95 | |||
| f2aed69f87 | |||
| 6bd96522e8 | |||
| 1e26c352d6 | |||
| 2de65ebd4d | |||
| ed3d9aaaed | |||
| 27a3998c8f | |||
| 979c124e57 | |||
| 20ad839075 | |||
| bed67edd2e | |||
| 6efcc02806 | |||
| 8a6dd2805f | |||
| 464219c0fa | |||
| e602768794 | |||
| 262f2a1453 | |||
| b408967278 | |||
| 1fd97fed91 | |||
| fef179b625 | |||
| 87ac411c50 | |||
| 46a7aaac76 | |||
| e14d6fe9d5 | |||
| fb5b2d3d8e | |||
| 9dccdd1008 | |||
| 8e8a746cce | |||
| ee71effe98 | |||
| ce2c4f0f08 | |||
| ef9dbf73cc | |||
| 3bed5334bf | |||
| 5dc940ead2 | |||
| 7872b41f16 | |||
| be81f6b4ab | |||
| 1229032b4e | |||
| ad73e2d07b | |||
| 6d80135342 | |||
| c36a10da83 | |||
| c30d09cef4 | |||
| 716e0b97bd | |||
| ff862dc926 | |||
| 17c2a1cb4e | |||
| 895e640fd0 | |||
| e8f5f86ad5 | |||
| 5055b41ee7 | |||
| 7efd08ca2e | |||
| 76b421e064 | |||
| 063e6baa0a | |||
| 9e5d412a8b | |||
| fa9b634d8f | |||
| d76379428d | |||
| 46509b6dd2 | |||
| 89dbf9cc81 | |||
| c138aaabf3 | |||
| 7cef454c86 | |||
| 5cb8d15505 | |||
| 2aab55983d | |||
| 31714e5c1d | |||
| 96c351e792 | |||
| edd57004d3 | |||
| 234d20641c | |||
| dd802f21e7 | |||
| dbbc990c72 | |||
| 3a6e772cba | |||
| c9fa16fcfa | |||
| 07b04fbea9 | |||
| 1c633cbea2 | |||
| 2f685d5d2a | |||
| 0fdf2cc195 | |||
| 4f7d18a28f | |||
| c77272a7d7 | |||
| 7a1004df73 | |||
| 0e86d2b345 | |||
| 2441bdb900 | |||
| 57679b7b7f | |||
| 37063e7a05 | |||
| 791dc7b9be | |||
| ff24dfb2e7 | |||
| 4db60fa5a8 | |||
| 5301367630 | |||
| 9409b7ef7d | |||
| afeb7f668b | |||
| 38b8da0f5f | |||
| d029b62d23 | |||
| 1e9bdb4647 | |||
| 1d72024605 | |||
| 06570443b7 | |||
| 77f7caf18d | |||
| 8767ffde2f | |||
| d58b7fa779 | |||
| dcbf3f8879 | |||
| 30d8c8e17c | |||
| b803bb5edb | |||
| 985a39d41f | |||
| f846eec894 | |||
| e7fc8ad1f5 | |||
| 95169ad54b | |||
| ddb2e91a42 | |||
| 90357193c9 | |||
| a336fe2850 | |||
| fcb8e4cf37 | |||
| b7b6c147f9 | |||
| 35ee82ca07 | |||
| 2dc56a6e9b | |||
| e12ef76de5 | |||
| 536b05e35b | |||
| 1354854d23 | |||
| 2b062d60f2 | |||
| c8bdb4c7fb | |||
| 80328e8a4f | |||
| 1138e3770b | |||
| ec58013b22 | |||
| 70cb61fb71 | |||
| 8e6a0ec23d | |||
| e2ab334636 | |||
| dd0effe957 | |||
| ac210c1765 | |||
| c58e48e648 | |||
| acdadab617 | |||
| aa19194f7b | |||
| 9319a6e39b | |||
| b41206abab | |||
| 07c3dc6b6f | |||
| fa71a2a993 | |||
| b997d1e892 | |||
| 4b71fba540 | |||
| 48d39c0a57 | |||
| 0aad053507 | |||
| 6ed14b2a5f | |||
| c7df5ef957 | |||
| a9013febcf | |||
| 815c430ba1 | |||
| e94d5bf006 | |||
| a00480f4a1 | |||
| 6da952100c | |||
| df8588e9b7 | |||
| fce9b35e4d | |||
| 6fd4421add | |||
| 7149bfd100 | |||
| 344ad0355e | |||
| e7871fbc43 | |||
| 99d8dd751e | |||
| 22b1abb36d | |||
| aa289d1023 | |||
| ef51e02767 | |||
| 7118127139 | |||
| 2ce2afa036 | |||
| 5803dd765d | |||
| 6a310b5069 | |||
| 2caab68be9 | |||
| 4e2dbc1258 | |||
| 40eca1a68e | |||
| 98f937ba15 | |||
| a70988ecd5 | |||
| 6f2ff620bd | |||
| bd772610b1 | |||
| de42b5bfae | |||
| fcdd5173bd | |||
| c419799313 | |||
| c5973a630b | |||
| e5a88b64b1 | |||
| 74f58a49b9 | |||
| cff9d9f5eb | |||
| ddd64f2918 | |||
| 9f06f53a59 | |||
| 4c00d7a306 | |||
| 88726e12f7 | |||
| 248bb148af | |||
| 49589e1da1 | |||
| 552267b93d | |||
| 855357f871 | |||
| c83cba2322 | |||
| 20dcc31d19 | |||
| 29e6cc5808 | |||
| 4e6ee28bcb | |||
| 4b3247576a | |||
| 69edf17c2a | |||
| d91a4ad1dd | |||
| 9b750ef69f | |||
| 0bf22ee3ce | |||
| 981ed22dff | |||
| d40321ef63 | |||
| c94996e8e8 | |||
| 4b19dd46dd | |||
| 942e841cbc | |||
| e0a595273a | |||
| 92ca52822c | |||
| f89dbce93c | |||
| 28f0e2eb2a | |||
| 47ac080565 | |||
| afdf5cfde9 | |||
| a4760bcff7 | |||
| 72e571a3de | |||
| 484c0fdd15 | |||
| 2636fb7c8d | |||
| 99c2936e90 | |||
| 66c74d6091 | |||
| a43ba245e2 | |||
| 810d734eda | |||
| 687d6c5dc4 | |||
| 5e090c1fac | |||
| ceb61e6600 | |||
| ae60293c24 | |||
| e411081c84 | |||
| 0682a5e45e | |||
| 4f751aa53d | |||
| 27fa51cfa6 | |||
| 2772ff624f | |||
| 69b160cfe8 | |||
| ee7541c032 | |||
| abf6068d91 | |||
| 9d5f3e787d | |||
| ab2b9ba444 | |||
| 6ab1aff531 | |||
| 6012276093 | |||
| 9648cf226b | |||
| 56532a505d | |||
| 6bb2e5625a | |||
| d57a5dffa1 | |||
| 1028ca0841 | |||
| 6dbe6b42c2 | |||
| 7611c3ea03 | |||
| 2fa9f934b6 | |||
| e9fd7b7ed6 | |||
| 075e954b71 | |||
| 3f7122b3d2 | |||
| 35251c6d9c | |||
| 173594365c | |||
| 2fc44fb27d | |||
| 0264630c90 | |||
| e2b4108377 | |||
| 02c484e844 | |||
| 5face79cd0 | |||
| da535164b4 | |||
| 82d9570ed4 | |||
| a619e8af4a | |||
| 25ec20d861 | |||
| 0579220546 | |||
| 031c37c7b0 | |||
| 860821114a | |||
| 73bba62d82 |
@@ -31,7 +31,8 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||
mingw-w64-$MSYS2_ARCH-python-gobject
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
|
||||
@@ -1,8 +1,127 @@
|
||||
Overview of Changes
|
||||
===================
|
||||
|
||||
* GtkProgressBar:
|
||||
- Fix handling of "inverted"
|
||||
|
||||
* GtkLabel:
|
||||
- Add a "natural wrap mode" property to influence how
|
||||
natural width is determined
|
||||
|
||||
* GtkTextView
|
||||
- Scroll insertion on-screen after undo / redo
|
||||
|
||||
* gsk:
|
||||
- Abort region diffing when changes are too complex
|
||||
|
||||
* gdk:
|
||||
- Avoid compressing discrete scroll events
|
||||
- Fix problems with hiding windows
|
||||
- Improve GL and GLES version checks
|
||||
|
||||
* Wayland:
|
||||
- Support new high-contrast setting
|
||||
|
||||
* Inspector:
|
||||
- Add DND inspection support
|
||||
|
||||
* build:
|
||||
- Avoid deprecated meson apis
|
||||
|
||||
* Translation updates
|
||||
Galician
|
||||
Portuguese
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.5.1, 16-12-2021
|
||||
========================================
|
||||
|
||||
* GtkWidget sizing has been rewritten to implement
|
||||
width-for-height more properly. This had some fallout,
|
||||
and some widgets may still not react kindly to the
|
||||
new way of doing things.
|
||||
|
||||
See https://blog.gtk.org/2021/12/03/sizable-news/
|
||||
for details, and please file issues if you notice fallout.
|
||||
|
||||
* Rename git `master` branch to `main`
|
||||
|
||||
* Css:
|
||||
- Fully support font-variant-caps
|
||||
- Fix a crash with gradients
|
||||
|
||||
* Make various widgets activatable:
|
||||
- GtkComboBox
|
||||
- GtkDropDown
|
||||
|
||||
* GtkPopover:
|
||||
- Make focus indicators not disappear
|
||||
|
||||
* GtkTextView:
|
||||
- Don't leave embedded children stranded when scrolling
|
||||
- Don't insert Emoji into non-editable textviews
|
||||
- Fix Emoji chooser positioning
|
||||
- Fix problems with pasting text
|
||||
- Improve scroll-to-mark behavior
|
||||
- Support right-aligned, centered and decimal tabs
|
||||
- Make child anchor replacement character settable
|
||||
- Provide more context to input methods
|
||||
|
||||
* GtkDragIcon:
|
||||
- Provide default icons for paintables and files
|
||||
|
||||
* GtkBuilder:
|
||||
- Speed up template precompilation
|
||||
|
||||
* Actions:
|
||||
- Reduce allocations during signal emissions
|
||||
- Avoid duplication and unnecessary recursion
|
||||
|
||||
* Inspector:
|
||||
- Show the selected im-module in the General tab
|
||||
- Add a clipboard viewer
|
||||
- Make the recorder record events too
|
||||
- Add a graph visualizing gtk_widget_measure()
|
||||
|
||||
* Gsk:
|
||||
- Fix hexbox rendering
|
||||
- Fix transformed linear gradient rendering
|
||||
|
||||
* Printing:
|
||||
- Fix dialog-less printing
|
||||
|
||||
* Windows:
|
||||
- Use the common EGL setup code
|
||||
- Respect GDK_DEBUG=gl-egl
|
||||
- Fix AeroSnap indicator and positioning
|
||||
|
||||
* X11:
|
||||
- Improve behavior of windows drags on headerbar controls
|
||||
- Trap errors for RANDR changes
|
||||
- Fix problems with drag icons
|
||||
|
||||
* Wayland:
|
||||
- Ensure we prefer the Wayland im-module over others
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Catalan
|
||||
Croatian
|
||||
Friulian
|
||||
Galician
|
||||
Hebrew
|
||||
Icelandic
|
||||
Italian
|
||||
Latvian
|
||||
Lithuanian
|
||||
Occitan
|
||||
Persian
|
||||
Portuguese
|
||||
Spanish
|
||||
Swedish
|
||||
Ukrainian
|
||||
|
||||
Overview of Changes in 4.5.0
|
||||
============================
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ executable('gtk4-constraint-editor',
|
||||
c_args: common_cflags,
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false,
|
||||
)
|
||||
|
||||
@@ -45,9 +45,7 @@
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Font Features</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
<property name="attributes" translatable="yes">0 -1 weight bold</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -75,9 +73,7 @@
|
||||
<object class="GtkLabel" id="variations_heading">
|
||||
<property name="label" translatable="yes">Font Variations</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
<property name="attributes" translatable="yes">0 -1 weight bold</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save _As...</attribute>
|
||||
<attribute name="action">app.save-as</attribute>
|
||||
<attribute name="accel"><Control>s</attribute>
|
||||
<attribute name="accel"><Control><Shift>s</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
|
||||
@@ -242,7 +242,7 @@ executable('gtk4-demo',
|
||||
c_args: gtkdemo_args + demo_cflags,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
@@ -252,7 +252,7 @@ executable('gtk4-demo-application',
|
||||
c_args: gtkdemo_args + common_cflags,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ executable('gtk4-icon-browser',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ demo_profile = get_option('profile')
|
||||
|
||||
demo_conf_h = declare_dependency(
|
||||
sources: custom_target('demo-header',
|
||||
command: [gen_demo_header, meson.source_root(), demo_profile],
|
||||
command: [gen_demo_header, meson.project_source_root(), demo_profile],
|
||||
capture: true,
|
||||
output: 'demo_conf.h',
|
||||
build_by_default: true,
|
||||
|
||||
@@ -17,7 +17,7 @@ executable('gtk4-node-editor',
|
||||
c_args: [
|
||||
'-DNODE_EDITOR_SOURCE_DIR="@0@/../../testsuite/gsk/compare/"'.format(meson.current_source_dir())
|
||||
] + common_cflags,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false,
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ executable('gtk4-print-editor',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -74,7 +74,7 @@ executable('gtk4-widget-factory',
|
||||
c_args: common_cflags,
|
||||
dependencies: [ libgtk_dep, demo_conf_h ],
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true,
|
||||
)
|
||||
|
||||
@@ -1927,6 +1927,12 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="tooltip-text" translatable="1">Insert something</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton">
|
||||
<property name="rgba">#9141AC</property>
|
||||
<property name="tooltip-text" translatable="1">Select a color</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -1276,6 +1276,15 @@ is provided in the form of a `GtkIconPaintable` (this can be checked with
|
||||
[method@Gtk.IconPaintable.is_symbolic]), you have to call
|
||||
[method@Gtk.IconPaintable.get_icon_name] and set the icon name on a `GtkImage`.
|
||||
|
||||
### Adapt to GtkImage changes
|
||||
`GtkPicture`'s behaviour was "split out" of `GtkImage` as the latter was covering
|
||||
too many use cases; if you're loading an icon, [class@Gtk.Image] in GTK3 and GTK4 are
|
||||
perfectly equivalent. If you are loading a more complex image asset, like a picture
|
||||
or a thumbnail, then [class@Gtk.Picture] is the appropriate widget.
|
||||
|
||||
One noteworthy distinction is that while `GtkImage` has its size computed by
|
||||
GTK, `GtkPicture` lets you decide about the size.
|
||||
|
||||
### Update to GtkFileChooser API changes
|
||||
|
||||
`GtkFileChooser` moved to a GFile-based API. If you need to convert a path
|
||||
|
||||
@@ -286,7 +286,7 @@ requires that GTK is compiled with support for that backend.
|
||||
The following backends can be selected, provided they are
|
||||
included in the GDK libraries you are using:
|
||||
|
||||
`quartz`
|
||||
`macos`
|
||||
: Selects the native Quartz backend
|
||||
|
||||
`win32`
|
||||
@@ -336,9 +336,6 @@ using and the GDK backend supports them:
|
||||
`gl`
|
||||
: Selects the "gl" OpenGL renderer
|
||||
|
||||
`ngl`
|
||||
: Selects the "ngl" OpenGL renderer
|
||||
|
||||
`vulkan`
|
||||
: Selects the Vulkan renderer
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ gdk_content_deserializer_get_priority (GdkContentDeserializer *deserializer)
|
||||
*
|
||||
* This is the `GCancellable` that was passed to [func@Gdk.content_deserialize_async].
|
||||
*
|
||||
* Returns: (transfer none): the cancellable for the current operation
|
||||
* Returns: (transfer none) (nullable): the cancellable for the current operation
|
||||
*/
|
||||
GCancellable *
|
||||
gdk_content_deserializer_get_cancellable (GdkContentDeserializer *deserializer)
|
||||
|
||||
@@ -342,7 +342,7 @@ gdk_content_provider_write_mime_type_finish (GdkContentProvider *provider,
|
||||
/**
|
||||
* gdk_content_provider_get_value:
|
||||
* @provider: a `GdkContentProvider`
|
||||
* @value: the `GValue` to fill
|
||||
* @value: (out caller-allocates): the `GValue` to fill
|
||||
* @error: a `GError` location to store the error occurring
|
||||
*
|
||||
* Gets the contents of @provider stored in @value.
|
||||
|
||||
@@ -270,7 +270,7 @@ gdk_content_serializer_get_priority (GdkContentSerializer *serializer)
|
||||
*
|
||||
* This is the `GCancellable` that was passed to [func@content_serialize_async].
|
||||
*
|
||||
* Returns: (transfer none): the cancellable for the current operation
|
||||
* Returns: (transfer none) (nullable): the cancellable for the current operation
|
||||
*/
|
||||
GCancellable *
|
||||
gdk_content_serializer_get_cancellable (GdkContentSerializer *serializer)
|
||||
|
||||
+1
-2
@@ -47,8 +47,7 @@
|
||||
* Cursors by themselves are not very interesting: they must be bound to a
|
||||
* window for users to see them. This is done with [method@Gdk.Surface.set_cursor]
|
||||
* or [method@Gdk.Surface.set_device_cursor]. Applications will typically
|
||||
* use higher-level GTK functions such as [method@Gtk.Widget.set_cursor]`
|
||||
* instead.
|
||||
* use higher-level GTK functions such as [method@Gtk.Widget.set_cursor] instead.
|
||||
*
|
||||
* Cursors are not bound to a given [class@Gdk.Display], so they can be shared.
|
||||
* However, the appearance of cursors may vary when used on different
|
||||
|
||||
+135
-62
@@ -19,7 +19,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -522,7 +522,9 @@ _gdk_event_queue_find_first (GdkDisplay *display)
|
||||
if (pending_motion)
|
||||
return pending_motion;
|
||||
|
||||
if (event->event_type == GDK_MOTION_NOTIFY && (event->flags & GDK_EVENT_FLUSHED) == 0)
|
||||
if ((event->event_type == GDK_MOTION_NOTIFY ||
|
||||
(event->event_type == GDK_SCROLL && gdk_scroll_event_get_direction (event) == GDK_SCROLL_SMOOTH)) &&
|
||||
(event->flags & GDK_EVENT_FLUSHED) == 0)
|
||||
pending_motion = tmp_list;
|
||||
else
|
||||
return tmp_list;
|
||||
@@ -596,6 +598,9 @@ _gdk_event_unqueue (GdkDisplay *display)
|
||||
/*
|
||||
* If the last N events in the event queue are smooth scroll events
|
||||
* for the same surface and device, combine them into one.
|
||||
*
|
||||
* We give the remaining event a history with N items, and deltas
|
||||
* that are the sum over the history entries.
|
||||
*/
|
||||
void
|
||||
gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
@@ -605,7 +610,6 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
GdkDevice *device = NULL;
|
||||
GdkEvent *last_event = NULL;
|
||||
GList *scrolls = NULL;
|
||||
double delta_x, delta_y;
|
||||
GArray *history = NULL;
|
||||
GdkTimeCoord hist;
|
||||
|
||||
@@ -640,35 +644,42 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
l = l->prev;
|
||||
}
|
||||
|
||||
delta_x = delta_y = 0;
|
||||
|
||||
while (scrolls && scrolls->next != NULL)
|
||||
{
|
||||
GdkEvent *event = scrolls->data;
|
||||
GList *next = scrolls->next;
|
||||
double dx, dy;
|
||||
gboolean inherited = FALSE;
|
||||
|
||||
if (!history && ((GdkScrollEvent *)event)->history)
|
||||
{
|
||||
history = ((GdkScrollEvent *)event)->history;
|
||||
((GdkScrollEvent *)event)->history = NULL;
|
||||
inherited = TRUE;
|
||||
}
|
||||
|
||||
if (!history)
|
||||
history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
|
||||
gdk_scroll_event_get_deltas (event, &dx, &dy);
|
||||
delta_x += dx;
|
||||
delta_y += dy;
|
||||
if (!inherited)
|
||||
{
|
||||
gdk_scroll_event_get_deltas (event, &dx, &dy);
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
|
||||
g_array_append_val (history, hist);
|
||||
g_array_append_val (history, hist);
|
||||
}
|
||||
|
||||
gdk_event_unref (event);
|
||||
g_queue_delete_link (&display->queued_events, scrolls);
|
||||
scrolls = next;
|
||||
}
|
||||
|
||||
if (scrolls)
|
||||
if (scrolls && history)
|
||||
{
|
||||
GdkEvent *old_event, *event;
|
||||
double dx, dy;
|
||||
@@ -676,13 +687,29 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
|
||||
old_event = scrolls->data;
|
||||
|
||||
gdk_scroll_event_get_deltas (old_event, &dx, &dy);
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (old_event);
|
||||
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
|
||||
hist.axes[GDK_AXIS_DELTA_X] = dx;
|
||||
hist.axes[GDK_AXIS_DELTA_Y] = dy;
|
||||
g_array_append_val (history, hist);
|
||||
|
||||
dx = dy = 0;
|
||||
for (int i = 0; i < history->len; i++)
|
||||
{
|
||||
GdkTimeCoord *val = &g_array_index (history, GdkTimeCoord, i);
|
||||
dx += val->axes[GDK_AXIS_DELTA_X];
|
||||
dy += val->axes[GDK_AXIS_DELTA_Y];
|
||||
}
|
||||
|
||||
event = gdk_scroll_event_new (surface,
|
||||
device,
|
||||
gdk_event_get_device_tool (old_event),
|
||||
gdk_event_get_time (old_event),
|
||||
gdk_event_get_modifier_state (old_event),
|
||||
delta_x + dx,
|
||||
delta_y + dy,
|
||||
dx,
|
||||
dy,
|
||||
gdk_scroll_event_is_stop (old_event));
|
||||
|
||||
((GdkScrollEvent *)event)->history = history;
|
||||
@@ -714,24 +741,41 @@ gdk_motion_event_push_history (GdkEvent *event,
|
||||
g_assert (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY));
|
||||
g_assert (GDK_IS_EVENT_TYPE (history_event, GDK_MOTION_NOTIFY));
|
||||
|
||||
if (!self->tool)
|
||||
return;
|
||||
if (G_UNLIKELY (!self->history))
|
||||
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
|
||||
if (((GdkMotionEvent *)history_event)->history)
|
||||
{
|
||||
GArray *history = ((GdkMotionEvent *)history_event)->history;
|
||||
g_array_append_vals (self->history, history->data, history->len);
|
||||
}
|
||||
|
||||
tool = gdk_event_get_device_tool (history_event);
|
||||
|
||||
memset (&hist, 0, sizeof (GdkTimeCoord));
|
||||
hist.time = gdk_event_get_time (history_event);
|
||||
hist.flags = gdk_device_tool_get_axes (tool);
|
||||
|
||||
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
|
||||
gdk_event_get_axis (history_event, i, &hist.axes[i]);
|
||||
|
||||
if (G_UNLIKELY (!self->history))
|
||||
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
|
||||
if (tool)
|
||||
{
|
||||
hist.flags = gdk_device_tool_get_axes (tool);
|
||||
for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
|
||||
gdk_event_get_axis (history_event, i, &hist.axes[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
hist.flags = GDK_AXIS_FLAG_X | GDK_AXIS_FLAG_Y;
|
||||
gdk_event_get_position (history_event, &hist.axes[GDK_AXIS_X], &hist.axes[GDK_AXIS_Y]);
|
||||
}
|
||||
|
||||
g_array_append_val (self->history, hist);
|
||||
}
|
||||
|
||||
/* If the last N events in the event queue are motion notify
|
||||
* events for the same surface, drop all but the last.
|
||||
*
|
||||
* If a button is held down or the device has a tool, then
|
||||
* we give the remaining events a history containing the N-1
|
||||
* dropped events.
|
||||
*/
|
||||
void
|
||||
_gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
{
|
||||
@@ -741,9 +785,6 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
GdkDevice *pending_motion_device = NULL;
|
||||
GdkEvent *last_motion = NULL;
|
||||
|
||||
/* If the last N events in the event queue are motion notify
|
||||
* events for the same surface, drop all but the last */
|
||||
|
||||
tmp_list = g_queue_peek_tail_link (&display->queued_events);
|
||||
|
||||
while (tmp_list)
|
||||
@@ -780,12 +821,11 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
|
||||
|
||||
if (last_motion != NULL)
|
||||
{
|
||||
GdkModifierType state = gdk_event_get_modifier_state (last_motion);
|
||||
|
||||
if (state &
|
||||
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK))
|
||||
gdk_motion_event_push_history (last_motion, pending_motions->data);
|
||||
if ((gdk_event_get_modifier_state (last_motion) &
|
||||
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) ||
|
||||
gdk_event_get_device_tool (last_motion) != NULL)
|
||||
gdk_motion_event_push_history (last_motion, pending_motions->data);
|
||||
}
|
||||
|
||||
gdk_event_unref (pending_motions->data);
|
||||
@@ -903,6 +943,9 @@ gdk_event_get_pointer_emulated (GdkEvent *event)
|
||||
* Extract the axis value for a particular axis use from
|
||||
* an event structure.
|
||||
*
|
||||
* To find out which axes are used, use [method@Gdk.DeviceTool.get_axes]
|
||||
* on the device tool returned by [method@Gdk.Event.get_device_tool].
|
||||
*
|
||||
* Returns: %TRUE if the specified axis was found, otherwise %FALSE
|
||||
*/
|
||||
gboolean
|
||||
@@ -1129,6 +1172,9 @@ G_DEFINE_BOXED_TYPE (GdkEventSequence, gdk_event_sequence,
|
||||
*
|
||||
* Extracts all axis values from an event.
|
||||
*
|
||||
* To find out which axes are used, use [method@Gdk.DeviceTool.get_axes]
|
||||
* on the device tool returned by [method@Gdk.Event.get_device_tool].
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE
|
||||
*/
|
||||
gboolean
|
||||
@@ -1179,7 +1225,7 @@ gdk_event_get_event_type (GdkEvent *event)
|
||||
*
|
||||
* Extracts the surface associated with an event.
|
||||
*
|
||||
* Returns: (transfer none): The `GdkSurface` associated with the event
|
||||
* Returns: (transfer none) (nullable): The `GdkSurface` associated with the event
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_event_get_surface (GdkEvent *event)
|
||||
@@ -2431,6 +2477,14 @@ gdk_touchpad_event_get_state (GdkEvent *event)
|
||||
return self->state;
|
||||
}
|
||||
|
||||
static GdkEventSequence *
|
||||
gdk_touchpad_event_get_sequence (GdkEvent *event)
|
||||
{
|
||||
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
|
||||
|
||||
return self->sequence;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_touchpad_event_get_position (GdkEvent *event,
|
||||
double *x,
|
||||
@@ -2450,7 +2504,7 @@ static const GdkEventTypeInfo gdk_touchpad_event_info = {
|
||||
NULL,
|
||||
gdk_touchpad_event_get_state,
|
||||
gdk_touchpad_event_get_position,
|
||||
NULL,
|
||||
gdk_touchpad_event_get_sequence,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
@@ -2461,19 +2515,28 @@ GDK_DEFINE_EVENT_TYPE (GdkTouchpadEvent, gdk_touchpad_event,
|
||||
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH))
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy)
|
||||
gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy)
|
||||
{
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, time);
|
||||
GdkTouchpadEvent *self;
|
||||
|
||||
g_return_val_if_fail (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_END ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL, NULL);
|
||||
|
||||
self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, time);
|
||||
|
||||
self->sequence = sequence;
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
@@ -2486,21 +2549,30 @@ gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
}
|
||||
|
||||
GdkEvent *
|
||||
gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy,
|
||||
double scale,
|
||||
double angle_delta)
|
||||
gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy,
|
||||
double scale,
|
||||
double angle_delta)
|
||||
{
|
||||
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, time);
|
||||
GdkTouchpadEvent *self;
|
||||
|
||||
g_return_val_if_fail (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_END ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_UPDATE ||
|
||||
phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL, NULL);
|
||||
|
||||
self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, time);
|
||||
|
||||
self->sequence = sequence;
|
||||
self->state = state;
|
||||
self->phase = phase;
|
||||
self->x = x;
|
||||
@@ -2907,7 +2979,8 @@ gdk_motion_event_new (GdkSurface *surface,
|
||||
* to the application because they occurred in the same frame as @event.
|
||||
*
|
||||
* Note that only motion and scroll events record history, and motion
|
||||
* events do it only if one of the mouse buttons is down.
|
||||
* events do it only if one of the mouse buttons is down, or the device
|
||||
* has a tool.
|
||||
*
|
||||
* Returns: (transfer container) (array length=out_n_coords) (nullable): an
|
||||
* array of time and coordinates
|
||||
|
||||
+14
-11
@@ -209,7 +209,7 @@ struct _GdkTouchEvent
|
||||
* @pointer_emulated: whether the scroll event was the result of
|
||||
* a pointer emulation
|
||||
* @tool: a `GdkDeviceTool`
|
||||
* @history: (element-type GdkScrollHistory): array of times and deltas
|
||||
* @history: (element-type GdkTimeCoord): array of times and deltas
|
||||
* for other scroll events that were compressed before delivering the
|
||||
* current event
|
||||
*
|
||||
@@ -233,7 +233,7 @@ struct _GdkScrollEvent
|
||||
gboolean pointer_emulated;
|
||||
gboolean is_stop;
|
||||
GdkDeviceTool *tool;
|
||||
GArray *history; /* <GdkScrollHistory> */
|
||||
GArray *history; /* <GdkTimeCoord> */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -402,6 +402,7 @@ struct _GdkTouchpadEvent
|
||||
{
|
||||
GdkEvent parent_instance;
|
||||
|
||||
GdkEventSequence *sequence;
|
||||
GdkModifierType state;
|
||||
gint8 phase;
|
||||
gint8 n_fingers;
|
||||
@@ -506,18 +507,20 @@ GdkEvent * gdk_touch_event_new (GdkEventType type,
|
||||
double *axes,
|
||||
gboolean emulating);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkEvent * gdk_touchpad_event_new_swipe (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkTouchpadGesturePhase phase,
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy);
|
||||
double x,
|
||||
double y,
|
||||
int n_fingers,
|
||||
double dx,
|
||||
double dy);
|
||||
|
||||
GdkEvent * gdk_touchpad_event_new_pinch (GdkSurface *surface,
|
||||
GdkEventSequence *sequence,
|
||||
GdkDevice *device,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
|
||||
+70
-13
@@ -151,6 +151,12 @@ unmask_context (MaskedContext *mask)
|
||||
return GDK_GL_CONTEXT (GSIZE_TO_POINTER (GPOINTER_TO_SIZE (mask) & ~(gsize) 1));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
mask_is_surfaceless (MaskedContext *mask)
|
||||
{
|
||||
return GPOINTER_TO_SIZE (mask) & (gsize) 1;
|
||||
}
|
||||
|
||||
static void
|
||||
unref_unmasked (gpointer data)
|
||||
{
|
||||
@@ -179,8 +185,7 @@ gdk_gl_context_dispose (GObject *gobject)
|
||||
|
||||
if (priv->egl_context != NULL)
|
||||
{
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
EGLDisplay *egl_display = gdk_display_get_egl_display (display);
|
||||
|
||||
if (eglGetCurrentContext () == priv->egl_context)
|
||||
@@ -574,8 +579,8 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||
glViewport (0, 0, ww, wh);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (priv->egl_context)
|
||||
glDrawBuffers (1, (GLenum[1]) { GL_BACK_LEFT });
|
||||
if (priv->egl_context && gdk_gl_context_check_version (context, 0, 0, 3, 0))
|
||||
glDrawBuffers (1, (GLenum[1]) { gdk_gl_context_get_use_es (context) ? GL_BACK : GL_BACK_LEFT });
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -997,16 +1002,33 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_check_version (GdkGLContext *context,
|
||||
int required_major,
|
||||
int required_minor)
|
||||
gdk_gl_context_check_version (GdkGLContext *self,
|
||||
int required_gl_major,
|
||||
int required_gl_minor,
|
||||
int required_gles_major,
|
||||
int required_gles_minor)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (required_minor < 10, FALSE);
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||
g_return_val_if_fail (required_gl_minor < 10, FALSE);
|
||||
g_return_val_if_fail (required_gles_minor < 10, FALSE);
|
||||
|
||||
return priv->gl_version >= required_major * 10 + required_minor;
|
||||
if (!gdk_gl_context_is_realized (self))
|
||||
return FALSE;
|
||||
|
||||
switch (priv->api)
|
||||
{
|
||||
case GDK_GL_API_GL:
|
||||
return priv->gl_version >= required_gl_major * 10 + required_gl_minor;
|
||||
|
||||
case GDK_GL_API_GLES:
|
||||
return priv->gl_version >= required_gles_major * 10 + required_gles_minor;
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1323,6 +1345,7 @@ gl_debug_message_callback (GLenum source,
|
||||
const char *message_source;
|
||||
const char *message_type;
|
||||
const char *message_severity;
|
||||
GLogLevelFlags log_level;
|
||||
|
||||
if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)
|
||||
return;
|
||||
@@ -1384,22 +1407,31 @@ gl_debug_message_callback (GLenum source,
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH:
|
||||
message_severity = "High";
|
||||
log_level = G_LOG_LEVEL_CRITICAL;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM:
|
||||
message_severity = "Medium";
|
||||
log_level = G_LOG_LEVEL_WARNING;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_LOW:
|
||||
message_severity = "Low";
|
||||
log_level = G_LOG_LEVEL_MESSAGE;
|
||||
break;
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
||||
message_severity = "Notification";
|
||||
log_level = G_LOG_LEVEL_INFO;
|
||||
break;
|
||||
default:
|
||||
message_severity = "Unknown";
|
||||
log_level = G_LOG_LEVEL_MESSAGE;
|
||||
}
|
||||
|
||||
g_warning ("OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
|
||||
message_source, message_type, message_severity, message);
|
||||
/* There's no higher level function taking a log level argument... */
|
||||
g_log_structured_standard (G_LOG_DOMAIN, log_level,
|
||||
__FILE__, G_STRINGIFY (__LINE__),
|
||||
G_STRFUNC,
|
||||
"OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
|
||||
message_source, message_type, message_severity, message);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1655,6 +1687,31 @@ gdk_gl_context_clear_current (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_gl_context_clear_current_if_surface:
|
||||
* @surface: surface to clear for
|
||||
*
|
||||
* Does a gdk_gl_context_clear_current() if the current context is attached
|
||||
* to @surface, leaves the current context alone otherwise.
|
||||
**/
|
||||
void
|
||||
gdk_gl_context_clear_current_if_surface (GdkSurface *surface)
|
||||
{
|
||||
MaskedContext *current;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current != NULL && !mask_is_surfaceless (current))
|
||||
{
|
||||
GdkGLContext *context = unmask_context (current);
|
||||
|
||||
if (gdk_gl_context_get_surface (context) != surface)
|
||||
return;
|
||||
|
||||
if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_get_current:
|
||||
*
|
||||
|
||||
@@ -99,6 +99,8 @@ gboolean gdk_gl_backend_can_be_used (GdkGLBackend
|
||||
GError **error);
|
||||
void gdk_gl_backend_use (GdkGLBackend backend_type);
|
||||
|
||||
void gdk_gl_context_clear_current_if_surface (GdkSurface *surface);
|
||||
|
||||
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
|
||||
GdkSurface *surface);
|
||||
|
||||
@@ -109,8 +111,10 @@ void gdk_gl_context_set_is_legacy (GdkGLContext
|
||||
gboolean is_legacy);
|
||||
|
||||
gboolean gdk_gl_context_check_version (GdkGLContext *context,
|
||||
int required_major,
|
||||
int required_minor);
|
||||
int required_gl_major,
|
||||
int required_gl_minor,
|
||||
int required_gles_major,
|
||||
int required_gles_minor);
|
||||
|
||||
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
|
||||
void gdk_gl_context_push_debug_group (GdkGLContext *context,
|
||||
|
||||
+7
-3
@@ -21,6 +21,7 @@
|
||||
#include "gdkgltextureprivate.h"
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
@@ -305,9 +306,11 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
GLint active_texture;
|
||||
GLint internal_format;
|
||||
|
||||
if (self->context != gdk_gl_context_get_current ())
|
||||
/* Abort if somebody else is GL-ing here... */
|
||||
if (self->context != gdk_gl_context_get_current () ||
|
||||
/* ... or glGetTexLevelParameter() isn't supported */
|
||||
!gdk_gl_context_check_version (self->context, 0, 0, 3, 1))
|
||||
{
|
||||
/* Somebody else is GL-ing here, abort! */
|
||||
texture->format = GDK_MEMORY_DEFAULT;
|
||||
return;
|
||||
}
|
||||
@@ -380,7 +383,8 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
* which will happen when the GdkTexture object is finalized, or due to
|
||||
* an explicit call of [method@Gdk.GLTexture.release].
|
||||
*
|
||||
* Return value: (transfer full): A newly-created `GdkTexture`
|
||||
* Return value: (transfer full) (type GdkGLTexture): A newly-created
|
||||
* `GdkTexture`
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_gl_texture_new (GdkGLContext *context,
|
||||
|
||||
@@ -133,10 +133,10 @@ gdk_memory_sanitize (GBytes *bytes,
|
||||
*
|
||||
* Creates a new texture for a blob of image data.
|
||||
*
|
||||
* The `GBytes` must contain @stride x @height pixels
|
||||
* The `GBytes` must contain @stride × @height pixels
|
||||
* in the given format.
|
||||
*
|
||||
* Returns: A newly-created `GdkTexture`
|
||||
* Returns: (type GdkMemoryTexture): A newly-created `GdkTexture`
|
||||
*/
|
||||
GdkTexture *
|
||||
gdk_memory_texture_new (int width,
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ gdk_popup_get_rect_anchor (GdkPopup *popup)
|
||||
*
|
||||
* Returns the parent surface of a popup.
|
||||
*
|
||||
* Returns: (transfer none): the parent surface
|
||||
* Returns: (transfer none) (nullable): the parent surface
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_popup_get_parent (GdkPopup *popup)
|
||||
|
||||
@@ -1095,6 +1095,7 @@ gdk_surface_set_egl_native_window (GdkSurface *self,
|
||||
|
||||
if (priv->egl_surface != NULL)
|
||||
{
|
||||
gdk_gl_context_clear_current_if_surface (self);
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
@@ -1123,6 +1124,7 @@ gdk_surface_ensure_egl_surface (GdkSurface *self,
|
||||
priv->egl_surface != NULL &&
|
||||
gdk_display_get_egl_config_high_depth (display) != gdk_display_get_egl_config (display))
|
||||
{
|
||||
gdk_gl_context_clear_current_if_surface (self);
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
|
||||
+10
-10
@@ -25,14 +25,14 @@
|
||||
* multiple frames, and will be used for a long time.
|
||||
*
|
||||
* There are various ways to create `GdkTexture` objects from a
|
||||
* `GdkPixbuf`, or a Cairo surface, or other pixel data.
|
||||
* [class@GdkPixbuf.Pixbuf], or a Cairo surface, or other pixel data.
|
||||
*
|
||||
* The ownership of the pixel data is transferred to the `GdkTexture`
|
||||
* instance; you can only make a copy of it, via [method@Gdk.Texture.download].
|
||||
*
|
||||
* `GdkTexture` is an immutable object: That means you cannot change
|
||||
* anything about it other than increasing the reference count via
|
||||
* g_object_ref().
|
||||
* [method@GObject.Object.ref], and consequently, it is a thread-safe object.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -346,7 +346,7 @@ gdk_texture_init (GdkTexture *self)
|
||||
*
|
||||
* Creates a new texture object representing the surface.
|
||||
*
|
||||
* @surface must be an image surface with format CAIRO_FORMAT_ARGB32.
|
||||
* @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
|
||||
*
|
||||
* Returns: a new `GdkTexture`
|
||||
*/
|
||||
@@ -384,7 +384,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
|
||||
* Creates a new texture object representing the `GdkPixbuf`.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Returns: a new `GdkTexture`
|
||||
@@ -430,7 +430,7 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
|
||||
* [ctor@Gdk.Texture.new_from_file] to load it.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -454,7 +454,7 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
texture = NULL;
|
||||
|
||||
if (texture == NULL)
|
||||
g_error ("Resource path %s s not a valid image: %s", resource_path, error->message);
|
||||
g_error ("Resource path %s is not a valid image: %s", resource_path, error->message);
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -472,7 +472,7 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -565,7 +565,7 @@ gdk_texture_new_from_bytes_pixbuf (GBytes *bytes,
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -611,7 +611,7 @@ gdk_texture_new_from_bytes (GBytes *bytes,
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
* This function is threadsafe, so that you can e.g. use GTask
|
||||
* and g_task_run_in_thread() to avoid blocking the main thread
|
||||
* and [method@Gio.Task.run_in_thread] to avoid blocking the main thread
|
||||
* while loading a big image.
|
||||
*
|
||||
* Return value: A newly-created `GdkTexture`
|
||||
@@ -796,7 +796,7 @@ gdk_texture_get_render_data (GdkTexture *self,
|
||||
*
|
||||
* This is a utility function intended for debugging and testing.
|
||||
* If you want more control over formats, proper error handling or
|
||||
* want to store to a `GFile` or other location, you might want to
|
||||
* want to store to a [iface@Gio.File] or other location, you might want to
|
||||
* use [method@Gdk.Texture.save_to_png_bytes] or look into the
|
||||
* gdk-pixbuf library.
|
||||
*
|
||||
|
||||
@@ -222,11 +222,7 @@ gdk_load_png (GBytes *bytes,
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
if (depth == 8)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8A8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_A8B8G8R8;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -236,11 +232,7 @@ gdk_load_png (GBytes *bytes,
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
if (depth == 8)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_B8G8R8;
|
||||
#endif
|
||||
}
|
||||
else if (depth == 16)
|
||||
{
|
||||
@@ -325,22 +317,14 @@ gdk_save_png (GdkTexture *texture)
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
case GDK_MEMORY_R8G8B8A8:
|
||||
case GDK_MEMORY_A8B8G8R8:
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8A8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_A8B8G8R8;
|
||||
#endif
|
||||
png_format = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
depth = 8;
|
||||
break;
|
||||
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GDK_MEMORY_B8G8R8;
|
||||
#endif
|
||||
png_format = PNG_COLOR_TYPE_RGB;
|
||||
depth = 8;
|
||||
break;
|
||||
|
||||
@@ -537,6 +537,7 @@ fill_pinch_event (GdkMacosDisplay *display,
|
||||
seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
|
||||
|
||||
return gdk_touchpad_event_new_pinch (GDK_SURFACE (surface),
|
||||
NULL, /* FIXME make up sequences */
|
||||
gdk_seat_get_pointer (seat),
|
||||
get_time_from_ns_event (nsevent),
|
||||
get_keyboard_modifiers_from_ns_event (nsevent),
|
||||
|
||||
@@ -137,6 +137,7 @@ struct _GdkWaylandPointerData {
|
||||
guint cursor_timeout_id;
|
||||
guint cursor_image_index;
|
||||
guint cursor_image_delay;
|
||||
guint touchpad_event_sequence;
|
||||
|
||||
guint current_output_scale;
|
||||
GSList *pointer_surface_outputs;
|
||||
@@ -1127,7 +1128,7 @@ data_offer_source_actions (void *data,
|
||||
seat->pending_source_actions = gdk_wayland_actions_to_gdk_actions (source_actions);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
@@ -1152,7 +1153,7 @@ data_offer_action (void *data,
|
||||
seat->pending_action = gdk_wayland_actions_to_gdk_actions (action);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (seat->drop == NULL)
|
||||
return;
|
||||
|
||||
@@ -2164,7 +2165,7 @@ deliver_key_event (GdkWaylandSeat *seat,
|
||||
key,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
_gdk_wayland_keymap_key_is_modifier (keymap, key),
|
||||
&translated,
|
||||
&translated,
|
||||
&no_lock);
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
@@ -2667,7 +2668,11 @@ emit_gesture_swipe_event (GdkWaylandSeat *seat,
|
||||
|
||||
seat->pointer_info.time = _time;
|
||||
|
||||
if (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN)
|
||||
seat->pointer_info.touchpad_event_sequence++;
|
||||
|
||||
event = gdk_touchpad_event_new_swipe (seat->pointer_info.focus,
|
||||
GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence),
|
||||
seat->logical_pointer,
|
||||
_time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
@@ -2763,7 +2768,11 @@ emit_gesture_pinch_event (GdkWaylandSeat *seat,
|
||||
|
||||
seat->pointer_info.time = _time;
|
||||
|
||||
if (phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN)
|
||||
seat->pointer_info.touchpad_event_sequence++;
|
||||
|
||||
event = gdk_touchpad_event_new_pinch (seat->pointer_info.focus,
|
||||
GDK_SLOT_TO_EVENT_SEQUENCE (seat->pointer_info.touchpad_event_sequence),
|
||||
seat->logical_pointer,
|
||||
_time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
@@ -4088,7 +4097,7 @@ tablet_pad_strip_handle_frame (void *data,
|
||||
event = gdk_pad_event_new_strip (seat->keyboard_focus,
|
||||
pad->device,
|
||||
time,
|
||||
g_list_index (pad->mode_groups, group),
|
||||
g_list_index (pad->mode_groups, group),
|
||||
g_list_index (pad->strips, wp_tablet_pad_strip),
|
||||
group->current_mode,
|
||||
group->axis_tmp_info.value);
|
||||
|
||||
@@ -1662,6 +1662,7 @@ static TranslationEntry translations[] = {
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
|
||||
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } },
|
||||
{ FALSE, "org.gnome.desktop.a11y.interface", "high-contrast", "high-contast", G_TYPE_NONE, { .b = FALSE } },
|
||||
/* Note, this setting doesn't exist, the portal and gsd fake it */
|
||||
{ FALSE, "org.gnome.fontconfig", "serial", "gtk-fontconfig-timestamp", G_TYPE_NONE, { .i = 0 } },
|
||||
};
|
||||
@@ -1711,6 +1712,13 @@ find_translation_entry_by_setting (const char *setting)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
high_contrast_changed (GdkDisplay *display)
|
||||
{
|
||||
gdk_display_setting_changed (display, "gtk-theme-name");
|
||||
gdk_display_setting_changed (display, "gtk-icon-theme-name");
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
@@ -1724,6 +1732,8 @@ settings_changed (GSettings *settings,
|
||||
{
|
||||
if (entry->type != G_TYPE_NONE)
|
||||
gdk_display_setting_changed (display, entry->setting);
|
||||
else if (strcmp (key, "high-contrast") == 0)
|
||||
high_contrast_changed (display);
|
||||
else
|
||||
update_xft_settings (display);
|
||||
}
|
||||
@@ -2090,6 +2100,36 @@ set_decoration_layout_from_entry (GdkDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_theme_from_entry (GdkDisplay *display,
|
||||
TranslationEntry *entry,
|
||||
GValue *value)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GSettings *settings = NULL;
|
||||
GSettingsSchema *schema = NULL;
|
||||
gboolean hc = FALSE;
|
||||
|
||||
if (display_wayland->settings_portal == NULL)
|
||||
{
|
||||
settings = (GSettings *)g_hash_table_lookup (display_wayland->settings,
|
||||
"org.gnome.desktop.a11y.interface");
|
||||
}
|
||||
|
||||
if (settings)
|
||||
g_object_get (settings, "settings-schema", &schema, NULL);
|
||||
|
||||
if (schema && g_settings_schema_has_key (schema, "high-contrast"))
|
||||
hc = g_settings_get_boolean (settings, "high-contrast");
|
||||
|
||||
g_clear_pointer (&schema, g_settings_schema_unref);
|
||||
|
||||
if (hc)
|
||||
g_value_set_static_string (value, "HighContrast");
|
||||
else
|
||||
set_value_from_entry (display, entry, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_capability_setting (GdkDisplay *display,
|
||||
GValue *value,
|
||||
@@ -2121,6 +2161,9 @@ gdk_wayland_display_get_setting (GdkDisplay *display,
|
||||
{
|
||||
if (strcmp (name, "gtk-decoration-layout") == 0)
|
||||
set_decoration_layout_from_entry (display, entry, value);
|
||||
else if (strcmp (name, "gtk-theme-name") == 0 ||
|
||||
strcmp (name, "gtk-icon-theme-name") == 0)
|
||||
set_theme_from_entry (display, entry, value);
|
||||
else
|
||||
set_value_from_entry (display, entry, value);
|
||||
return TRUE;
|
||||
|
||||
@@ -118,7 +118,6 @@ struct _GdkWaylandSurface
|
||||
unsigned int mapped : 1;
|
||||
unsigned int awaiting_frame : 1;
|
||||
unsigned int awaiting_frame_frozen : 1;
|
||||
unsigned int is_drag_surface : 1;
|
||||
|
||||
int pending_buffer_offset_x;
|
||||
int pending_buffer_offset_y;
|
||||
@@ -780,11 +779,22 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
|
||||
return;
|
||||
}
|
||||
|
||||
scale = 1;
|
||||
for (l = impl->display_server.outputs; l != NULL; l = l->next)
|
||||
if (!impl->display_server.outputs)
|
||||
{
|
||||
guint32 output_scale = gdk_wayland_display_get_output_scale (display_wayland, l->data);
|
||||
scale = MAX (scale, output_scale);
|
||||
scale = impl->scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = 1;
|
||||
for (l = impl->display_server.outputs; l != NULL; l = l->next)
|
||||
{
|
||||
struct wl_output *output = l->data;
|
||||
uint32_t output_scale;
|
||||
|
||||
output_scale = gdk_wayland_display_get_output_scale (display_wayland,
|
||||
output);
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify app that scale changed */
|
||||
@@ -2825,27 +2835,12 @@ find_grab_input_seat (GdkSurface *surface,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_be_mapped (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
/* Don't map crazy temp that GTK uses for internal X11 shenanigans. */
|
||||
if (GDK_IS_DRAG_SURFACE (surface) && surface->x < 0 && surface->y < 0)
|
||||
return FALSE;
|
||||
|
||||
if (impl->is_drag_surface)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_map_toplevel (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!should_be_mapped (surface))
|
||||
if (!GDK_IS_WAYLAND_TOPLEVEL (surface))
|
||||
return;
|
||||
|
||||
if (impl->mapped)
|
||||
@@ -4703,7 +4698,6 @@ create_dnd_surface (GdkDisplay *display)
|
||||
GDK_SURFACE_TEMP,
|
||||
NULL,
|
||||
0, 0, 100, 100);
|
||||
GDK_WAYLAND_SURFACE (surface)->is_drag_surface = TRUE;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
@@ -1,406 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2001 Stefan Ondrejicka
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int id;
|
||||
char *bitmap;
|
||||
int hotx;
|
||||
int hoty;
|
||||
} font_info_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int id;
|
||||
int width;
|
||||
int height;
|
||||
int hotx;
|
||||
int hoty;
|
||||
char *data;
|
||||
} cursor_info_t;
|
||||
|
||||
static GSList *fonts = NULL;
|
||||
static GSList *cursors = NULL;
|
||||
|
||||
static int dw,dh;
|
||||
|
||||
static gboolean debug = FALSE;
|
||||
|
||||
#define HEX(c) (((c) >= '0' && (c) <= '9') ? \
|
||||
((c) - '0') : (toupper(c) - 'A' + 10))
|
||||
|
||||
static void print_font(fi)
|
||||
font_info_t *fi;
|
||||
{
|
||||
int x,y;
|
||||
|
||||
for (y = 0; y < dh; y++)
|
||||
{
|
||||
for (x = 0; x < dw; x++)
|
||||
{
|
||||
printf(fi->bitmap[y*dw+x]? "X" : " ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_cursor(ci)
|
||||
cursor_info_t *ci;
|
||||
{
|
||||
int x,y;
|
||||
|
||||
for (y = 0; y < ci->height; y++)
|
||||
{
|
||||
printf("/* ");
|
||||
for (x = 0; x < ci->width; x++)
|
||||
{
|
||||
if (ci->hotx == x && ci->hoty == y)
|
||||
printf("o");
|
||||
else
|
||||
switch (ci->data[y*ci->width+x])
|
||||
{
|
||||
case 0:
|
||||
printf(" ");
|
||||
break;
|
||||
case 1:
|
||||
printf(".");
|
||||
break;
|
||||
case 2:
|
||||
printf("X");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf(" */\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int read_bdf_font(fname)
|
||||
char *fname;
|
||||
{
|
||||
FILE *f;
|
||||
char line[2048];
|
||||
int rv = 0;
|
||||
gboolean startchar = FALSE, startbitmap = FALSE;
|
||||
char *charname,*p,*bitmap;
|
||||
int dx = 0,dy = 0;
|
||||
int w,h,x,y,py;
|
||||
int id,tmp;
|
||||
|
||||
dw = 0;
|
||||
dh = 0;
|
||||
|
||||
if (!(f = fopen(fname, "r")))
|
||||
{
|
||||
perror(fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fgets(line, sizeof(line), f) && strncasecmp("STARTFONT ", line, 10))
|
||||
{
|
||||
printf("!BDF font file\n");
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = line;
|
||||
while (fgets(line, sizeof(line), f))
|
||||
{
|
||||
if (!startchar)
|
||||
{
|
||||
if (!strncasecmp("STARTCHAR ", line, 10))
|
||||
{
|
||||
startchar = TRUE;
|
||||
charname = g_strndup(p + 10,
|
||||
strcspn(p+10, "\r\n"));
|
||||
}
|
||||
else if (!strncasecmp("FONTBOUNDINGBOX ", line, 16))
|
||||
sscanf(p+16, "%d %d %d %d", &dw, &dh, &dx, &dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strncasecmp("ENDCHAR", line, 7))
|
||||
{
|
||||
font_info_t *nfi;
|
||||
|
||||
if (debug)
|
||||
printf(" %*s*/\n", dw, "");
|
||||
startchar = FALSE;
|
||||
startbitmap = FALSE;
|
||||
|
||||
nfi = g_malloc(sizeof(font_info_t));
|
||||
memset(nfi, '\0', sizeof(font_info_t));
|
||||
|
||||
nfi->name = charname;
|
||||
nfi->id = id;
|
||||
nfi->bitmap = bitmap;
|
||||
nfi->hotx = 0 - dx;
|
||||
nfi->hoty = 0 - dy;
|
||||
|
||||
fonts = g_slist_append(fonts, nfi);
|
||||
}
|
||||
else if (startbitmap)
|
||||
{
|
||||
int px,cx;
|
||||
guchar mask;
|
||||
|
||||
px = x - dx + py * dw;
|
||||
for (cx = 0; cx < w; cx++)
|
||||
{
|
||||
mask = 1 << (3 - (cx % 4));
|
||||
|
||||
bitmap[px+cx] =
|
||||
(mask & HEX(line[cx/4])) != 0;
|
||||
|
||||
if (debug)
|
||||
printf(bitmap[px+cx] ? "X" : " ");
|
||||
}
|
||||
py++;
|
||||
if (debug)
|
||||
printf(" %*s*/\n/* %*s", dw-w, "", dw+dx, "");
|
||||
}
|
||||
else if (!strncasecmp("BBX ", line, 4))
|
||||
{
|
||||
sscanf(p+4, "%d %d %d %d", &w, &h, &x, &y);
|
||||
if (debug)
|
||||
printf("/* %s: */\n/* %*s", charname, dw+dx, "");
|
||||
}
|
||||
else if (!strncasecmp("ENCODING ", line, 9))
|
||||
{
|
||||
if (sscanf(p+9, "%d %d", &tmp, &id) != 2)
|
||||
id = tmp;
|
||||
}
|
||||
else if (!strncasecmp("BITMAP", line, 6))
|
||||
{
|
||||
py = y - dy;
|
||||
startbitmap = TRUE;
|
||||
bitmap = g_malloc(dw*dh);
|
||||
memset(bitmap, '\0', dw*dh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strncasecmp("ENDFONT", line, 7))
|
||||
rv = -1;
|
||||
|
||||
fclose(f);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int font_info_compare(fi, name)
|
||||
font_info_t *fi;
|
||||
char *name;
|
||||
{
|
||||
return strcmp(name, fi->name);
|
||||
}
|
||||
|
||||
static cursor_info_t *gen_cursor(bmap, mask)
|
||||
font_info_t *bmap;
|
||||
font_info_t *mask;
|
||||
{
|
||||
cursor_info_t *ci;
|
||||
int bx = dw,by = dh,ex = 0,ey = 0;
|
||||
int i,j;
|
||||
|
||||
for (j = 0; j < dh; j++)
|
||||
{
|
||||
gboolean havep = FALSE;
|
||||
|
||||
for (i = 0; i < dw; i++)
|
||||
{
|
||||
if (bmap->bitmap[j*dw+i] || mask->bitmap[j*dw+i])
|
||||
{
|
||||
havep = TRUE;
|
||||
bx = MIN(bx, i);
|
||||
ex = MAX(i+1, ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (havep)
|
||||
{
|
||||
by = MIN(by, j);
|
||||
ey = MAX(ey, j+1);
|
||||
}
|
||||
}
|
||||
|
||||
ci = g_malloc(sizeof(cursor_info_t));
|
||||
ci->name = g_strdup(bmap->name);
|
||||
ci->id = bmap->id;
|
||||
|
||||
ci->width = ex - bx;
|
||||
ci->height = ey - by;
|
||||
|
||||
ci->hotx = bmap->hotx - bx;
|
||||
ci->hoty = ci->height - (bmap->hoty - by);
|
||||
|
||||
ci->data = g_malloc(ci->width * ci->height);
|
||||
memset(ci->data, '\0', ci->width * ci->height);
|
||||
|
||||
for (j = 0; j < ci->height; j++)
|
||||
{
|
||||
for (i = 0; i < ci->width; i++)
|
||||
{
|
||||
int ofs = (by + j) * dw + bx + i;
|
||||
|
||||
ci->data[j*ci->width + i] = mask->bitmap[ofs] *
|
||||
(1 + bmap->bitmap[ofs]);
|
||||
}
|
||||
}
|
||||
|
||||
return ci;
|
||||
}
|
||||
|
||||
static void compose_cursors_from_fonts()
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = g_slist_copy (fonts); l; l = g_slist_delete_link (l,l))
|
||||
{
|
||||
font_info_t *fi = l->data;
|
||||
char *name;
|
||||
GSList *ml;
|
||||
|
||||
name = g_strconcat(fi->name, "_mask", NULL);
|
||||
|
||||
if ((ml = g_slist_find_custom(fonts, name,
|
||||
(GCompareFunc) font_info_compare)))
|
||||
{
|
||||
cursors = g_slist_append(cursors, gen_cursor(l->data, ml->data));
|
||||
fonts = g_slist_remove(fonts, l->data);
|
||||
fonts = g_slist_remove(fonts, ml->data);
|
||||
}
|
||||
|
||||
g_free(name);
|
||||
}
|
||||
}
|
||||
|
||||
static char *dump_cursor(ci, id)
|
||||
cursor_info_t *ci;
|
||||
int id;
|
||||
{
|
||||
static char cdata[8192];
|
||||
char *p;
|
||||
int i;
|
||||
int c;
|
||||
gboolean flushed;
|
||||
|
||||
sprintf(cdata, " { \"%s\", %d, %d, %d, %d, %d, \n \"",
|
||||
ci->name, ci->id, ci->width, ci->height, ci->hotx, ci->hoty);
|
||||
p = cdata + strlen(cdata);
|
||||
|
||||
for (i = 0; i < ci->width * ci->height; i++)
|
||||
{
|
||||
flushed = FALSE;
|
||||
|
||||
if (!(i%4))
|
||||
c = 0;
|
||||
|
||||
c = c << 2;
|
||||
|
||||
c += ci->data[i];
|
||||
|
||||
if ((i % 4) == 3)
|
||||
{
|
||||
flushed = TRUE;
|
||||
sprintf(p, "\\%03o", c);
|
||||
p += strlen(p);
|
||||
}
|
||||
|
||||
if (i > 0 && !(i % 64))
|
||||
{
|
||||
strcpy(p ,"\"\n \"");
|
||||
p += strlen(p);
|
||||
}
|
||||
}
|
||||
if (!flushed)
|
||||
{
|
||||
sprintf(p, "\\%03o", c);
|
||||
p += strlen(p);
|
||||
}
|
||||
|
||||
strcpy(p, "\" }");
|
||||
|
||||
return cdata;
|
||||
}
|
||||
|
||||
static int dump_cursors()
|
||||
{
|
||||
GSList *ptr;
|
||||
FILE *f = stdout;
|
||||
|
||||
fprintf(f, "static const struct { const char *name; int type; guchar width; guchar height; guchar hotx; guchar hoty; guchar *data; } cursors[] = {\n");
|
||||
|
||||
for (ptr = cursors; ptr; ptr = ptr->next)
|
||||
{
|
||||
if (debug)
|
||||
print_cursor(ptr->data);
|
||||
fprintf(f, "%s, \n", dump_cursor(ptr->data));
|
||||
}
|
||||
|
||||
fprintf(f, " { NULL, 0, 0, 0, 0, 0, NULL },\n};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("missing parameters !\n");
|
||||
printf("Usage: %s [BDF cursor file]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (g_getenv ("BDFCURSOR_DEBUG") != NULL)
|
||||
debug = TRUE;
|
||||
|
||||
if (read_bdf_font(argv[1]) || !fonts)
|
||||
{
|
||||
printf("Error reading font\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
compose_cursors_from_fonts();
|
||||
|
||||
if (!cursors)
|
||||
{
|
||||
printf("failed to generate cursors from font!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dump_cursors();
|
||||
|
||||
if (fonts)
|
||||
{
|
||||
printf("some fonts remained unconverted!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -157,7 +157,6 @@ static HKL latin_locale = NULL;
|
||||
|
||||
static gboolean in_ime_composition = FALSE;
|
||||
static UINT modal_timer;
|
||||
static UINT sync_timer = 0;
|
||||
|
||||
static int debug_indent = 0;
|
||||
|
||||
@@ -1453,23 +1452,6 @@ _gdk_win32_end_modal_call (GdkWin32ModalOpKind kind)
|
||||
}
|
||||
}
|
||||
|
||||
static VOID CALLBACK
|
||||
sync_timer_proc (HWND hwnd,
|
||||
UINT msg,
|
||||
UINT_PTR id,
|
||||
DWORD time)
|
||||
{
|
||||
MSG message;
|
||||
if (PeekMessageW (&message, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RedrawWindow (hwnd, NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW|RDW_ALLCHILDREN);
|
||||
|
||||
KillTimer (hwnd, sync_timer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_nchittest (HWND hwnd,
|
||||
GdkSurface *window,
|
||||
@@ -2854,12 +2836,6 @@ gdk_event_translate (MSG *msg,
|
||||
*ret_valp = 1;
|
||||
break;
|
||||
|
||||
case WM_SYNCPAINT:
|
||||
sync_timer = SetTimer (GDK_SURFACE_HWND (window),
|
||||
1,
|
||||
200, sync_timer_proc);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
handle_wm_paint (msg, window);
|
||||
break;
|
||||
|
||||
+140
-140
@@ -653,6 +653,7 @@ _gdk_win32_display_create_surface (GdkDisplay *display,
|
||||
|
||||
g_object_unref (frame_clock);
|
||||
impl->hdc = GetDC (impl->handle);
|
||||
impl->inhibit_configure = TRUE;
|
||||
|
||||
return surface;
|
||||
}
|
||||
@@ -786,26 +787,6 @@ show_window_internal (GdkSurface *window,
|
||||
if (!unminimize && !already_mapped && IsWindowVisible (GDK_SURFACE_HWND (window)))
|
||||
return;
|
||||
|
||||
/* Other cases */
|
||||
|
||||
exstyle = GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE);
|
||||
|
||||
/* Use SetWindowPos to show transparent windows so automatic redraws
|
||||
* in other windows can be suppressed.
|
||||
*/
|
||||
if (exstyle & WS_EX_TRANSPARENT)
|
||||
{
|
||||
UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
||||
|
||||
if (GDK_IS_DRAG_SURFACE (window))
|
||||
flags |= SWP_NOACTIVATE;
|
||||
|
||||
SetWindowPos (GDK_SURFACE_HWND (window),
|
||||
SWP_NOZORDER_SPECIFIED, 0, 0, 0, 0, flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* For initial map of "normal" windows we want to emulate WM window
|
||||
* positioning behaviour, which means:
|
||||
* + default to the initial CW_USEDEFAULT placement,
|
||||
@@ -952,6 +933,8 @@ show_window_internal (GdkSurface *window,
|
||||
GtkShowWindow (window, SW_SHOW);
|
||||
}
|
||||
|
||||
exstyle = GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE);
|
||||
|
||||
/* Sync STATE_ABOVE to TOPMOST */
|
||||
if (!GDK_IS_DRAG_SURFACE (window) &&
|
||||
(((window->state & GDK_TOPLEVEL_STATE_ABOVE) &&
|
||||
@@ -988,22 +971,7 @@ gdk_win32_surface_hide (GdkSurface *window)
|
||||
|
||||
_gdk_surface_clear_update_area (window);
|
||||
|
||||
if (GDK_IS_TOPLEVEL (window))
|
||||
ShowOwnedPopups (GDK_SURFACE_HWND (window), FALSE);
|
||||
|
||||
/* Use SetWindowPos to hide transparent windows so automatic redraws
|
||||
* in other windows can be suppressed.
|
||||
*/
|
||||
if (GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
|
||||
{
|
||||
SetWindowPos (GDK_SURFACE_HWND (window), SWP_NOZORDER_SPECIFIED,
|
||||
0, 0, 0, 0,
|
||||
SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkShowWindow (window, SW_HIDE);
|
||||
}
|
||||
GtkShowWindow (window, SW_HIDE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1042,14 +1010,15 @@ gdk_win32_surface_do_move (GdkSurface *window,
|
||||
}
|
||||
|
||||
void
|
||||
gdk_win32_surface_resize (GdkSurface *window,
|
||||
int width, int height)
|
||||
gdk_win32_surface_resize (GdkSurface *surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
RECT outer_rect;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (width < 1)
|
||||
@@ -1058,28 +1027,29 @@ gdk_win32_surface_resize (GdkSurface *window,
|
||||
height = 1;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_win32_surface_resize: %p: %dx%d\n",
|
||||
GDK_SURFACE_HWND (window), width, height));
|
||||
GDK_SURFACE_HWND (surface), width, height));
|
||||
|
||||
if (window->state & GDK_TOPLEVEL_STATE_FULLSCREEN)
|
||||
if (surface->state & GDK_TOPLEVEL_STATE_FULLSCREEN)
|
||||
return;
|
||||
|
||||
get_outer_rect (window, width, height, &outer_rect);
|
||||
get_outer_rect (surface, width, height, &outer_rect);
|
||||
|
||||
GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
|
||||
"NOACTIVATE|NOMOVE|NOZORDER)\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
GDK_SURFACE_HWND (surface),
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top));
|
||||
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
|
||||
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (surface),
|
||||
SWP_NOZORDER_SPECIFIED,
|
||||
0, 0,
|
||||
outer_rect.right - outer_rect.left,
|
||||
outer_rect.bottom - outer_rect.top,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
|
||||
window->resize_count += 1;
|
||||
surface->resize_count += 1;
|
||||
|
||||
gdk_surface_request_layout (window);
|
||||
if (!GDK_WIN32_SURFACE (surface)->force_recompute_size)
|
||||
gdk_surface_request_layout (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1333,33 +1303,22 @@ gdk_win32_surface_set_urgency_hint (GdkSurface *window,
|
||||
gboolean urgent)
|
||||
{
|
||||
FLASHWINFO flashwinfo;
|
||||
typedef BOOL (WINAPI *PFN_FlashWindowEx) (FLASHWINFO*);
|
||||
PFN_FlashWindowEx flashWindowEx = NULL;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return;
|
||||
|
||||
flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
|
||||
|
||||
if (flashWindowEx)
|
||||
{
|
||||
flashwinfo.cbSize = sizeof (flashwinfo);
|
||||
flashwinfo.hwnd = GDK_SURFACE_HWND (window);
|
||||
if (urgent)
|
||||
flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
|
||||
else
|
||||
flashwinfo.dwFlags = FLASHW_STOP;
|
||||
flashwinfo.uCount = 0;
|
||||
flashwinfo.dwTimeout = 0;
|
||||
|
||||
flashWindowEx (&flashwinfo);
|
||||
}
|
||||
flashwinfo.cbSize = sizeof (flashwinfo);
|
||||
flashwinfo.hwnd = GDK_SURFACE_HWND (window);
|
||||
if (urgent)
|
||||
flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
|
||||
else
|
||||
{
|
||||
FlashWindow (GDK_SURFACE_HWND (window), urgent);
|
||||
}
|
||||
flashwinfo.dwFlags = FLASHW_STOP;
|
||||
flashwinfo.uCount = 0;
|
||||
flashwinfo.dwTimeout = 0;
|
||||
|
||||
FlashWindowEx (&flashwinfo);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2495,35 +2454,41 @@ _gdk_win32_surface_handle_aerosnap (GdkSurface *window,
|
||||
}
|
||||
|
||||
static void
|
||||
apply_snap (GdkSurface *window,
|
||||
GdkWin32AeroSnapState snap)
|
||||
apply_snap (GdkSurface *surface,
|
||||
GdkWin32AeroSnapState snap)
|
||||
{
|
||||
GdkMonitor *monitor;
|
||||
GdkDisplay *display;
|
||||
|
||||
display = gdk_surface_get_display (window);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, window);
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
|
||||
switch (snap)
|
||||
{
|
||||
case GDK_WIN32_AEROSNAP_STATE_UNDETERMINED:
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_MAXIMIZE:
|
||||
unsnap (window, monitor);
|
||||
gdk_win32_surface_maximize (window);
|
||||
unsnap (surface, monitor);
|
||||
gdk_win32_surface_maximize (surface);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_HALFLEFT:
|
||||
unsnap (window, monitor);
|
||||
snap_left (window, monitor, monitor);
|
||||
unsnap (surface, monitor);
|
||||
snap_left (surface, monitor, monitor);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_HALFRIGHT:
|
||||
unsnap (window, monitor);
|
||||
snap_right (window, monitor, monitor);
|
||||
unsnap (surface, monitor);
|
||||
snap_right (surface, monitor, monitor);
|
||||
break;
|
||||
case GDK_WIN32_AEROSNAP_STATE_FULLUP:
|
||||
snap_up (window);
|
||||
snap_up (surface);
|
||||
break;
|
||||
}
|
||||
|
||||
if (snap != GDK_WIN32_AEROSNAP_STATE_UNDETERMINED)
|
||||
{
|
||||
GDK_WIN32_SURFACE (surface)->inhibit_configure = TRUE;
|
||||
GDK_WIN32_SURFACE (surface)->force_recompute_size = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Registers a dumb window class. This window
|
||||
@@ -3403,10 +3368,10 @@ get_cursor_name_from_op (GdkW32WindowDragOp op,
|
||||
}
|
||||
|
||||
static void
|
||||
setup_drag_move_resize_context (GdkSurface *window,
|
||||
setup_drag_move_resize_context (GdkSurface *surface,
|
||||
GdkW32DragMoveResizeContext *context,
|
||||
GdkW32WindowDragOp op,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkDevice *device,
|
||||
int button,
|
||||
double x,
|
||||
@@ -3415,12 +3380,13 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
{
|
||||
RECT rect;
|
||||
const char *cursor_name;
|
||||
GdkSurface *pointer_window;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (window);
|
||||
gboolean maximized = gdk_toplevel_get_state (GDK_TOPLEVEL (window)) & GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
GdkSurface *pointer_surface;
|
||||
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
|
||||
gboolean maximized = gdk_toplevel_get_state (GDK_TOPLEVEL (surface)) & GDK_TOPLEVEL_STATE_MAXIMIZED;
|
||||
int root_x, root_y;
|
||||
gboolean restore_configure = FALSE;
|
||||
|
||||
gdk_win32_surface_get_root_coords (window, x, y, &root_x, &root_y);
|
||||
gdk_win32_surface_get_root_coords (surface, x, y, &root_x, &root_y);
|
||||
|
||||
/* Before we drag, we need to undo any maximization or snapping.
|
||||
* AeroSnap behaviour:
|
||||
@@ -3443,7 +3409,7 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
* resize
|
||||
* don't unsnap
|
||||
* apply new width and x position to unsnapped cache,
|
||||
* so that unsnapped window only regains its height
|
||||
* so that unsnapped surface only regains its height
|
||||
* and y position, but inherits x and width from
|
||||
* the fullup snapped state
|
||||
* vertical resize:
|
||||
@@ -3458,7 +3424,7 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
*
|
||||
* TODO: make this implementation behave as AeroSnap on resizes?
|
||||
* There's also the case where
|
||||
* a halfleft/halfright window isn't unsnapped when it's
|
||||
* a halfleft/halfright surface isn't unsnapped when it's
|
||||
* being moved horizontally, but it's more difficult to implement.
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_RESIZE &&
|
||||
@@ -3466,7 +3432,8 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
impl->snap_state == GDK_WIN32_AEROSNAP_STATE_HALFLEFT ||
|
||||
impl->snap_state == GDK_WIN32_AEROSNAP_STATE_FULLUP))
|
||||
{
|
||||
discard_snapinfo (window);
|
||||
discard_snapinfo (surface);
|
||||
restore_configure = TRUE;
|
||||
}
|
||||
else if (maximized ||
|
||||
(impl->snap_state == GDK_WIN32_AEROSNAP_STATE_HALFRIGHT ||
|
||||
@@ -3476,24 +3443,25 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
GdkMonitor *monitor;
|
||||
int wx, wy, wwidth, wheight;
|
||||
int swx, swy, swwidth, swheight;
|
||||
gboolean pointer_outside_of_window;
|
||||
gboolean pointer_outside_of_surface;
|
||||
int offsetx, offsety;
|
||||
gboolean left_half;
|
||||
GdkDisplay *display;
|
||||
|
||||
display = gdk_surface_get_display (window);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, window);
|
||||
gdk_surface_get_geometry (window, &wx, &wy, &wwidth, &wheight);
|
||||
restore_configure = TRUE;
|
||||
display = gdk_surface_get_display (surface);
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
gdk_surface_get_geometry (surface, &wx, &wy, &wwidth, &wheight);
|
||||
|
||||
swx = wx;
|
||||
swy = wy;
|
||||
swwidth = wwidth;
|
||||
swheight = wheight;
|
||||
|
||||
/* Subtract window shadow. We don't want pointer to go outside of
|
||||
* the visible window during drag-move. For drag-resize it's OK.
|
||||
* Don't take shadow into account if the window is maximized -
|
||||
* maximized windows don't have shadows.
|
||||
/* Subtract surface shadow. We don't want pointer to go outside of
|
||||
* the visible surface during drag-move. For drag-resize it's OK.
|
||||
* Don't take shadow into account if the surface is maximized -
|
||||
* maximized surfaces don't have shadows.
|
||||
*/
|
||||
if (op == GDK_WIN32_DRAGOP_MOVE && !maximized)
|
||||
{
|
||||
@@ -3503,16 +3471,16 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
swheight -= impl->shadow_y;
|
||||
}
|
||||
|
||||
pointer_outside_of_window = root_x < swx || root_x > swx + swwidth ||
|
||||
pointer_outside_of_surface = root_x < swx || root_x > swx + swwidth ||
|
||||
root_y < swy || root_y > swy + swheight;
|
||||
/* Calculate the offset of the pointer relative to the window */
|
||||
/* Calculate the offset of the pointer relative to the surface */
|
||||
offsetx = root_x - swx;
|
||||
offsety = root_y - swy;
|
||||
|
||||
/* Figure out in which half of the window the pointer is.
|
||||
/* Figure out in which half of the surface the pointer is.
|
||||
* The code currently only concerns itself with horizontal
|
||||
* dimension (left/right halves).
|
||||
* There's no upper/lower half, because usually window
|
||||
* There's no upper/lower half, because usually surface
|
||||
* is dragged by its upper half anyway. If that changes, adjust
|
||||
* accordingly.
|
||||
*/
|
||||
@@ -3522,26 +3490,26 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
if (!left_half)
|
||||
offsetx = swwidth - offsetx;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d, this is %d : %d relative to the window's %s\n",
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d, this is %d : %d relative to the surface's %s\n",
|
||||
root_x, root_y, offsetx, offsety,
|
||||
left_half ? "left half" : "right half"));
|
||||
|
||||
/* Move window in such a way that on unmaximization/unsnapping the pointer
|
||||
* is still pointing at the appropriate half of the window,
|
||||
/* Move surface in such a way that on unmaximization/unsnapping the pointer
|
||||
* is still pointing at the appropriate half of the surface,
|
||||
* with the same offset from the left or right edge. If the new
|
||||
* window size is too small, and adding that offset puts the pointer
|
||||
* surface size is too small, and adding that offset puts the pointer
|
||||
* into the other half or even beyond, move the pointer to the middle.
|
||||
*/
|
||||
if (!pointer_outside_of_window && maximized)
|
||||
if (!pointer_outside_of_surface && maximized)
|
||||
{
|
||||
WINDOWPLACEMENT placement;
|
||||
int unmax_width, unmax_height;
|
||||
int shadow_unmax_width, shadow_unmax_height;
|
||||
|
||||
placement.length = sizeof (placement);
|
||||
API_CALL (GetWindowPlacement, (GDK_SURFACE_HWND (window), &placement));
|
||||
API_CALL (GetWindowPlacement, (GDK_SURFACE_HWND (surface), &placement));
|
||||
|
||||
GDK_NOTE (MISC, g_print ("W32 WM unmaximized window placement is %ld x %ld @ %ld : %ld\n",
|
||||
GDK_NOTE (MISC, g_print ("W32 WM unmaximized surface placement is %ld x %ld @ %ld : %ld\n",
|
||||
placement.rcNormalPosition.right - placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.bottom - placement.rcNormalPosition.top,
|
||||
placement.rcNormalPosition.left,
|
||||
@@ -3587,9 +3555,9 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
placement.rcNormalPosition.left,
|
||||
placement.rcNormalPosition.top));
|
||||
|
||||
API_CALL (SetWindowPlacement, (GDK_SURFACE_HWND (window), &placement));
|
||||
API_CALL (SetWindowPlacement, (GDK_SURFACE_HWND (surface), &placement));
|
||||
}
|
||||
else if (!pointer_outside_of_window && impl->snap_stash_int)
|
||||
else if (!pointer_outside_of_surface && impl->snap_stash_int)
|
||||
{
|
||||
GdkRectangle new_pos;
|
||||
GdkRectangle snew_pos;
|
||||
@@ -3619,22 +3587,22 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
new_pos.y = root_y - new_pos.height / 2;
|
||||
}
|
||||
|
||||
GDK_NOTE (MISC, g_print ("Unsnapped window to %d : %d\n",
|
||||
GDK_NOTE (MISC, g_print ("Unsnapped surface to %d : %d\n",
|
||||
new_pos.x, new_pos.y));
|
||||
discard_snapinfo (window);
|
||||
gdk_win32_surface_move_resize (window, new_pos.x, new_pos.y,
|
||||
discard_snapinfo (surface);
|
||||
gdk_win32_surface_move_resize (surface, new_pos.x, new_pos.y,
|
||||
new_pos.width, new_pos.height);
|
||||
}
|
||||
|
||||
|
||||
if (maximized)
|
||||
gdk_win32_surface_unmaximize (window);
|
||||
gdk_win32_surface_unmaximize (surface);
|
||||
else
|
||||
unsnap (window, monitor);
|
||||
unsnap (surface, monitor);
|
||||
|
||||
if (pointer_outside_of_window)
|
||||
if (pointer_outside_of_surface)
|
||||
{
|
||||
/* Pointer outside of the window, move pointer into window */
|
||||
/* Pointer outside of the surface, move pointer into surface */
|
||||
GDK_NOTE (MISC, g_print ("Pointer at %d : %d is outside of %d x %d @ %d : %d, move it to %d : %d\n",
|
||||
root_x, root_y, wwidth, wheight, wx, wy, wx + wwidth / 2, wy + wheight / 2));
|
||||
root_x = wx + wwidth / 2;
|
||||
@@ -3647,26 +3615,29 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_win32_get_window_rect (window, &rect);
|
||||
if (restore_configure)
|
||||
impl->inhibit_configure = FALSE;
|
||||
|
||||
_gdk_win32_get_window_rect (surface, &rect);
|
||||
|
||||
cursor_name = get_cursor_name_from_op (op, edge);
|
||||
|
||||
context->cursor = gdk_cursor_new_from_name (cursor_name, NULL);
|
||||
|
||||
pointer_window = window;
|
||||
pointer_surface = surface;
|
||||
|
||||
/* Note: This triggers a WM_CAPTURECHANGED, which will trigger
|
||||
* gdk_win32_surface_end_move_resize_drag(), which will end
|
||||
* our op before it even begins, but only if context->op is not NONE.
|
||||
* This is why we first do the grab, *then* set the op.
|
||||
*/
|
||||
gdk_device_grab (device, pointer_window,
|
||||
gdk_device_grab (device, pointer_surface,
|
||||
FALSE,
|
||||
GDK_ALL_EVENTS_MASK,
|
||||
context->cursor,
|
||||
timestamp);
|
||||
|
||||
context->window = g_object_ref (window);
|
||||
context->window = g_object_ref (surface);
|
||||
context->op = op;
|
||||
context->edge = edge;
|
||||
context->device = device;
|
||||
@@ -3686,10 +3657,10 @@ setup_drag_move_resize_context (GdkSurface *window,
|
||||
calculate_aerosnap_regions (context);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print ("begin drag moveresize: window %p, toplevel %p, "
|
||||
g_print ("begin drag moveresize: surface %p, toplevel %p, "
|
||||
"op %u, edge %d, device %p, "
|
||||
"button %d, coord %d:%d, time %u\n",
|
||||
pointer_window, window,
|
||||
pointer_surface, surface,
|
||||
context->op, context->edge, context->device,
|
||||
context->button, context->start_root_x,
|
||||
context->start_root_y, context->timestamp));
|
||||
@@ -4084,45 +4055,61 @@ gdk_win32_surface_minimize (GdkSurface *window)
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_maximize (GdkSurface *window)
|
||||
gdk_win32_surface_maximize (GdkSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_surface_maximize: %p: %s\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
_gdk_win32_surface_state_to_string (window->state)));
|
||||
GDK_SURFACE_HWND (surface),
|
||||
_gdk_win32_surface_state_to_string (surface->state)));
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_MAXIMIZE);
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
impl->inhibit_configure = TRUE;
|
||||
impl->force_recompute_size = FALSE;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (surface))
|
||||
GtkShowWindow (surface, SW_MAXIMIZE);
|
||||
else
|
||||
gdk_synthesize_surface_state (window,
|
||||
gdk_synthesize_surface_state (surface,
|
||||
0,
|
||||
GDK_TOPLEVEL_STATE_MAXIMIZED);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_surface_unmaximize (GdkSurface *window)
|
||||
gdk_win32_surface_unmaximize (GdkSurface *surface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SURFACE (window));
|
||||
GdkWin32Surface *impl;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
GDK_NOTE (MISC, g_print ("gdk_surface_unmaximize: %p: %s\n",
|
||||
GDK_SURFACE_HWND (window),
|
||||
_gdk_win32_surface_state_to_string (window->state)));
|
||||
GDK_SURFACE_HWND (surface),
|
||||
_gdk_win32_surface_state_to_string (surface->state)));
|
||||
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (window);
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (surface);
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
GtkShowWindow (window, SW_RESTORE);
|
||||
if (GDK_SURFACE_IS_MAPPED (surface))
|
||||
GtkShowWindow (surface, SW_RESTORE);
|
||||
else
|
||||
gdk_synthesize_surface_state (window,
|
||||
gdk_synthesize_surface_state (surface,
|
||||
GDK_TOPLEVEL_STATE_MAXIMIZED,
|
||||
0);
|
||||
|
||||
impl = GDK_WIN32_SURFACE (surface);
|
||||
|
||||
if (impl->inhibit_configure)
|
||||
{
|
||||
impl->inhibit_configure = FALSE;
|
||||
impl->force_recompute_size = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4547,6 +4534,9 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
|
||||
&surface->x, &surface->y,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!impl->inhibit_configure)
|
||||
impl->force_recompute_size = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4561,8 +4551,18 @@ _gdk_win32_surface_compute_size (GdkSurface *surface)
|
||||
|
||||
if (!impl->drag_move_resize_context.native_move_resize_pending)
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
if (GDK_IS_TOPLEVEL (surface) && impl->force_recompute_size)
|
||||
{
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
gdk_win32_surface_resize (surface, width, height);
|
||||
impl->force_recompute_size = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
surface->width = impl->next_layout.configured_width;
|
||||
surface->height = impl->next_layout.configured_height;
|
||||
}
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ struct _GdkWin32Surface
|
||||
int configured_height;
|
||||
RECT configured_rect;
|
||||
} next_layout;
|
||||
gboolean force_recompute_size;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
guint egl_force_redraw_all : 1;
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# libwntab32x.la - a libtool library file
|
||||
# Generated by hand, compatible with libtool
|
||||
# Just a wrapper for libwntab32x.a, which is just a copy of wntab32x.lib
|
||||
#
|
||||
# The name that we can dlopen(3).
|
||||
dlname=''
|
||||
|
||||
# Names of this library.
|
||||
library_names=''
|
||||
|
||||
# The name of the static archive.
|
||||
old_library='libwntab32x.a'
|
||||
|
||||
# Libraries that this one depends upon.
|
||||
dependency_libs=''
|
||||
|
||||
# Version information
|
||||
current=0
|
||||
age=0
|
||||
revision=0
|
||||
|
||||
# Is this an already installed library?
|
||||
installed=no
|
||||
|
||||
# Files to dlopen/dlpreopen
|
||||
dlopen=''
|
||||
dlpreopen=''
|
||||
|
||||
# Directory that this library needs to be installed in:
|
||||
libdir=''
|
||||
@@ -1665,7 +1665,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
_gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group),
|
||||
direction,
|
||||
FALSE);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1799,7 +1799,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
_gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group),
|
||||
x, y,
|
||||
axes);
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1838,7 +1838,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
x = (double) xev->event_x / scale;
|
||||
y = (double) xev->event_y / scale;
|
||||
|
||||
|
||||
event = gdk_touch_event_new (ev->evtype == XI_TouchBegin
|
||||
? GDK_TOUCH_BEGIN
|
||||
: GDK_TOUCH_END,
|
||||
@@ -1946,6 +1946,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
y = (double) xev->event_y / scale;
|
||||
|
||||
event = gdk_touchpad_event_new_pinch (surface,
|
||||
NULL, /* FIXME make up sequences */
|
||||
device,
|
||||
xev->time,
|
||||
state,
|
||||
@@ -2006,6 +2007,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
y = (double) xev->event_y / scale;
|
||||
|
||||
event = gdk_touchpad_event_new_swipe (surface,
|
||||
NULL, /* FIXME make up sequences */
|
||||
device,
|
||||
xev->time,
|
||||
state,
|
||||
|
||||
@@ -71,6 +71,8 @@ gdk_x11_surface_destroy_glx_drawable (GdkX11Surface *self)
|
||||
if (self->glx_drawable == None)
|
||||
return;
|
||||
|
||||
gdk_gl_context_clear_current_if_surface (GDK_SURFACE (self));
|
||||
|
||||
glXDestroyWindow (gdk_x11_display_get_xdisplay (gdk_surface_get_display (GDK_SURFACE (self))),
|
||||
self->glx_drawable);
|
||||
|
||||
|
||||
@@ -3535,7 +3535,7 @@ gdk_x11_surface_unfullscreen (GdkSurface *surface)
|
||||
*
|
||||
* Returns the group this surface belongs to.
|
||||
*
|
||||
* Returns: (transfer none): The group of this surface;
|
||||
* Returns: (transfer none) (nullable): The group of this surface;
|
||||
*/
|
||||
GdkSurface *
|
||||
gdk_x11_surface_get_group (GdkSurface *surface)
|
||||
|
||||
@@ -952,9 +952,9 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
guint program = 0;
|
||||
guint width = 0;
|
||||
guint height = 0;
|
||||
guint n_binds = 0;
|
||||
G_GNUC_UNUSED guint n_binds = 0;
|
||||
guint n_fbos = 0;
|
||||
guint n_uniforms = 0;
|
||||
G_GNUC_UNUSED guint n_uniforms = 0;
|
||||
guint n_programs = 0;
|
||||
guint vao_id;
|
||||
guint vbo_id;
|
||||
@@ -1396,7 +1396,7 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
|
||||
}
|
||||
else if (stride % bpp == 0 &&
|
||||
(!use_es || gdk_gl_context_check_version (context, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
|
||||
(gdk_gl_context_check_version (context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
|
||||
{
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
|
||||
|
||||
|
||||
@@ -147,7 +147,8 @@ gsk_gl_compiler_new (GskGLDriver *driver,
|
||||
|
||||
gdk_gl_context_get_version (context, &maj, &min);
|
||||
|
||||
if (maj == 3)
|
||||
/* On Windows, legacy contexts can give us a GL 4.x context */
|
||||
if (maj >= 3)
|
||||
self->glsl_version = SHADER_VERSION_GL3_LEGACY;
|
||||
else
|
||||
self->glsl_version = SHADER_VERSION_GL2_LEGACY;
|
||||
|
||||
@@ -4117,14 +4117,19 @@ gsk_gl_render_job_set_debug_fallback (GskGLRenderJob *job,
|
||||
}
|
||||
|
||||
static int
|
||||
get_framebuffer_format (guint framebuffer)
|
||||
get_framebuffer_format (GdkGLContext *context,
|
||||
guint framebuffer)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (!gdk_gl_context_check_version (context, 0, 0, 3, 0))
|
||||
return GL_RGBA8;
|
||||
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
|
||||
glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
|
||||
framebuffer ? GL_COLOR_ATTACHMENT0
|
||||
: GL_BACK_LEFT,
|
||||
: gdk_gl_context_get_use_es (context) ? GL_BACK
|
||||
: GL_BACK_LEFT,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &size);
|
||||
|
||||
if (size > 16)
|
||||
@@ -4161,7 +4166,7 @@ gsk_gl_render_job_new (GskGLDriver *driver,
|
||||
job->scale_x = scale_factor;
|
||||
job->scale_y = scale_factor;
|
||||
job->viewport = *viewport;
|
||||
job->target_format = get_framebuffer_format (framebuffer);
|
||||
job->target_format = get_framebuffer_format (job->command_queue->context, framebuffer);
|
||||
|
||||
gsk_gl_render_job_set_alpha (job, 1.0f);
|
||||
gsk_gl_render_job_set_projection_from_rect (job, viewport, NULL);
|
||||
|
||||
+14
-5
@@ -356,6 +356,8 @@ compare (gconstpointer *elem1,
|
||||
const GskDiffSettings *settings,
|
||||
gpointer data)
|
||||
{
|
||||
GskDiffResult res;
|
||||
|
||||
/*
|
||||
* Shrink the box by walking through each diagonal snake (SW and NE).
|
||||
*/
|
||||
@@ -364,7 +366,9 @@ compare (gconstpointer *elem1,
|
||||
if (settings->compare_func (elem1[off1], elem2[off2], data) != 0)
|
||||
break;
|
||||
|
||||
settings->keep_func (elem1[off1], elem2[off2], data);
|
||||
res = settings->keep_func (elem1[off1], elem2[off2], data);
|
||||
if (res != GSK_DIFF_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
for (; off1 < lim1 && off2 < lim2; lim1--, lim2--)
|
||||
@@ -372,7 +376,9 @@ compare (gconstpointer *elem1,
|
||||
if (settings->compare_func (elem1[lim1 - 1], elem2[lim2 - 1], data) != 0)
|
||||
break;
|
||||
|
||||
settings->keep_func (elem1[lim1 - 1], elem2[lim2 - 1], data);
|
||||
res = settings->keep_func (elem1[lim1 - 1], elem2[lim2 - 1], data);
|
||||
if (res != GSK_DIFF_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -383,20 +389,23 @@ compare (gconstpointer *elem1,
|
||||
{
|
||||
for (; off2 < lim2; off2++)
|
||||
{
|
||||
settings->insert_func (elem2[off2], off2, data);
|
||||
res = settings->insert_func (elem2[off2], off2, data);
|
||||
if (res != GSK_DIFF_OK)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else if (off2 == lim2)
|
||||
{
|
||||
for (; off1 < lim1; off1++)
|
||||
{
|
||||
settings->delete_func (elem1[off1], off1, data);
|
||||
res = settings->delete_func (elem1[off1], off1, data);
|
||||
if (res != GSK_DIFF_OK)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitResult spl = { 0, };
|
||||
GskDiffResult res;
|
||||
|
||||
/*
|
||||
* Divide ...
|
||||
|
||||
@@ -29,9 +29,9 @@ typedef enum {
|
||||
GSK_DIFF_ABORTED,
|
||||
} GskDiffResult;
|
||||
|
||||
typedef void (* GskKeepFunc) (gconstpointer elem1, gconstpointer elem2, gpointer data);
|
||||
typedef void (* GskDeleteFunc) (gconstpointer elem, gsize idx, gpointer data);
|
||||
typedef void (* GskInsertFunc) (gconstpointer elem, gsize idx, gpointer data);
|
||||
typedef GskDiffResult (* GskKeepFunc) (gconstpointer elem1, gconstpointer elem2, gpointer data);
|
||||
typedef GskDiffResult (* GskDeleteFunc) (gconstpointer elem, gsize idx, gpointer data);
|
||||
typedef GskDiffResult (* GskInsertFunc) (gconstpointer elem, gsize idx, gpointer data);
|
||||
|
||||
typedef struct _GskDiffSettings GskDiffSettings;
|
||||
|
||||
|
||||
+6
-1
@@ -289,10 +289,15 @@ gsk_renderer_is_realized (GskRenderer *renderer)
|
||||
*
|
||||
* Since GTK 4.6, the surface may be `NULL`, which allows using
|
||||
* renderers without having to create a surface.
|
||||
*
|
||||
* Note that it is mandatory to call [method@Gsk.Renderer.unrealize] before
|
||||
* destroying the renderer.
|
||||
*
|
||||
* Returns: Whether the renderer was successfully realized
|
||||
*/
|
||||
gboolean
|
||||
gsk_renderer_realize (GskRenderer *renderer,
|
||||
GdkSurface *surface,
|
||||
GdkSurface *surface,
|
||||
GError **error)
|
||||
{
|
||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||
|
||||
+9
-9
@@ -20,7 +20,7 @@
|
||||
* GskRenderNode: (ref-func gsk_render_node_ref) (unref-func gsk_render_node_unref) (set-value-func gsk_value_set_render_node) (get-value-func gsk_value_get_render_node)
|
||||
*
|
||||
* `GskRenderNode` is the basic block in a scene graph to be
|
||||
* rendered using `GskRenderer`.
|
||||
* rendered using [class@Gsk.Renderer].
|
||||
*
|
||||
* Each node has a parent, except the top-level node; each node may have
|
||||
* children nodes.
|
||||
@@ -424,7 +424,7 @@ gsk_render_node_get_bounds (GskRenderNode *node,
|
||||
*
|
||||
* Typically, you'll use this function to implement fallback rendering
|
||||
* of `GskRenderNode`s on an intermediate Cairo context, instead of using
|
||||
* the drawing context associated to a `GdkSurface`'s rendering buffer.
|
||||
* the drawing context associated to a [class@Gdk.Surface]'s rendering buffer.
|
||||
*
|
||||
* For advanced nodes that cannot be supported using Cairo, in particular
|
||||
* for nodes doing 3D operations, this function may fail.
|
||||
@@ -565,8 +565,8 @@ gsk_render_node_diff (GskRenderNode *node1,
|
||||
* @filename: (type filename): the file to save it to.
|
||||
* @error: Return location for a potential error
|
||||
*
|
||||
* This function is equivalent to calling gsk_render_node_serialize()
|
||||
* followed by g_file_set_contents().
|
||||
* This function is equivalent to calling [method@Gsk.RenderNode.serialize]
|
||||
* followed by [func@GLib.file_set_contents].
|
||||
*
|
||||
* See those two functions for details on the arguments.
|
||||
*
|
||||
@@ -603,7 +603,7 @@ gsk_render_node_write_to_file (GskRenderNode *node,
|
||||
* @error_func: (nullable) (scope call): Callback on parsing errors
|
||||
* @user_data: (closure error_func): user_data for @error_func
|
||||
*
|
||||
* Loads data previously created via gsk_render_node_serialize().
|
||||
* Loads data previously created via [method@Gsk.RenderNode.serialize].
|
||||
*
|
||||
* For a discussion of the supported format, see that function.
|
||||
*
|
||||
@@ -623,12 +623,12 @@ gsk_render_node_deserialize (GBytes *bytes,
|
||||
|
||||
/**
|
||||
* gsk_value_set_render_node:
|
||||
* @value: a `GValue` initialized with type `GSK_TYPE_RENDER_NODE`
|
||||
* @value: a [struct@GObject.Value] initialized with type `GSK_TYPE_RENDER_NODE`
|
||||
* @node: a `GskRenderNode`
|
||||
*
|
||||
* Stores the given `GskRenderNode` inside `value`.
|
||||
*
|
||||
* The `GValue` will acquire a reference to the `node`.
|
||||
* The [struct@GObject.Value] will acquire a reference to the `node`.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
@@ -659,7 +659,7 @@ gsk_value_set_render_node (GValue *value,
|
||||
|
||||
/**
|
||||
* gsk_value_take_render_node:
|
||||
* @value: a `GValue` initialized with type `GSK_TYPE_RENDER_NODE`
|
||||
* @value: a [struct@GObject.Value] initialized with type `GSK_TYPE_RENDER_NODE`
|
||||
* @node: (transfer full) (nullable): a `GskRenderNode`
|
||||
*
|
||||
* Stores the given `GskRenderNode` inside `value`.
|
||||
@@ -713,7 +713,7 @@ gsk_value_get_render_node (const GValue *value)
|
||||
|
||||
/**
|
||||
* gsk_value_dup_render_node:
|
||||
* @value: a `GValue` initialized with type `GSK_TYPE_RENDER_NODE`
|
||||
* @value: a [struct@GObject.Value] initialized with type `GSK_TYPE_RENDER_NODE`
|
||||
*
|
||||
* Retrieves the `GskRenderNode` stored inside the given `value`, and acquires
|
||||
* a reference to it.
|
||||
|
||||
+22
-13
@@ -33,6 +33,12 @@
|
||||
|
||||
#include <hb-ot.h>
|
||||
|
||||
/* maximal number of rectangles we keep in a diff region before we throw
|
||||
* the towel and just use the bounding box of the parent node.
|
||||
* Meant to avoid performance corner cases.
|
||||
*/
|
||||
#define MAX_RECTS_IN_DIFF 30
|
||||
|
||||
static inline void
|
||||
gsk_cairo_rectangle (cairo_t *cr,
|
||||
const graphene_rect_t *rect)
|
||||
@@ -2601,32 +2607,35 @@ gsk_container_node_draw (GskRenderNode *node,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_render_node_add_to_region (GskRenderNode *node,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
rectangle_init_from_graphene (&rect, &node->bounds);
|
||||
cairo_region_union_rectangle (region, &rect);
|
||||
}
|
||||
|
||||
static int
|
||||
gsk_container_node_compare_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
|
||||
{
|
||||
return gsk_render_node_can_diff ((const GskRenderNode *) elem1, (const GskRenderNode *) elem2) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void
|
||||
static GskDiffResult
|
||||
gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
|
||||
{
|
||||
gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, data);
|
||||
if (cairo_region_num_rectangles (data) > MAX_RECTS_IN_DIFF)
|
||||
return GSK_DIFF_ABORTED;
|
||||
|
||||
return GSK_DIFF_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
static GskDiffResult
|
||||
gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer data)
|
||||
{
|
||||
gsk_render_node_add_to_region ((GskRenderNode *) elem, data);
|
||||
const GskRenderNode *node = elem;
|
||||
cairo_region_t *region = data;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
rectangle_init_from_graphene (&rect, &node->bounds);
|
||||
cairo_region_union_rectangle (region, &rect);
|
||||
if (cairo_region_num_rectangles (region) > MAX_RECTS_IN_DIFF)
|
||||
return GSK_DIFF_ABORTED;
|
||||
|
||||
return GSK_DIFF_OK;
|
||||
}
|
||||
|
||||
static GskDiffSettings *
|
||||
|
||||
@@ -334,6 +334,9 @@ get_index_in_parent (GtkWidget *widget)
|
||||
GtkWidget *child;
|
||||
int idx;
|
||||
|
||||
if (parent == NULL)
|
||||
return -1;
|
||||
|
||||
idx = 0;
|
||||
for (child = gtk_widget_get_first_child (parent);
|
||||
child;
|
||||
|
||||
@@ -140,7 +140,7 @@ gtk_css_section_get_parent (const GtkCssSection *section)
|
||||
* If no such file exists, for example because the CSS was loaded via
|
||||
* [method@Gtk.CssProvider.load_from_data], then `NULL` is returned.
|
||||
*
|
||||
* Returns: (transfer none): the `GFile` from which the `section`
|
||||
* Returns: (transfer none) (nullable): the `GFile` from which the `section`
|
||||
* was parsed
|
||||
**/
|
||||
GFile *
|
||||
|
||||
@@ -36,7 +36,7 @@ G_BEGIN_DECLS
|
||||
* Defines a part of a CSS document.
|
||||
*
|
||||
* Because sections are nested into one another, you can use
|
||||
* gtk_css_section_get_parent() to get the containing region.
|
||||
* [method@CssSection.get_parent] to get the containing region.
|
||||
*/
|
||||
typedef struct _GtkCssSection GtkCssSection;
|
||||
|
||||
|
||||
+11
-11
@@ -44,10 +44,10 @@
|
||||
|
||||
/**
|
||||
* GtkActionableInterface:
|
||||
* @get_action_name: virtual function for gtk_actionable_get_action_name()
|
||||
* @set_action_name: virtual function for gtk_actionable_set_action_name()
|
||||
* @get_action_target_value: virtual function for gtk_actionable_get_action_target_value()
|
||||
* @set_action_target_value: virtual function for gtk_actionable_set_action_target_value()
|
||||
* @get_action_name: virtual function for [method@Actionable.get_action_name]
|
||||
* @set_action_name: virtual function for [method@Actionable.set_action_name]
|
||||
* @get_action_target_value: virtual function for [method@Actionable.get_action_target_value]
|
||||
* @set_action_target_value: virtual function for [method@Actionable.set_action_target_value]
|
||||
*
|
||||
* The interface vtable for `GtkActionable`.
|
||||
**/
|
||||
@@ -100,8 +100,8 @@ gtk_actionable_get_action_name (GtkActionable *actionable)
|
||||
* located) within the hierarchy of a `GtkApplicationWindow`.
|
||||
*
|
||||
* Names are of the form “win.save” or “app.quit” for actions on the
|
||||
* containing `GtkApplicationWindow` or its associated `GtkApplication`,
|
||||
* respectively. This is the same form used for actions in the `GMenu`
|
||||
* containing [class@ApplicationWindow] or its associated [class@Application],
|
||||
* respectively. This is the same form used for actions in the [class@Gio.Menu]
|
||||
* associated with the window.
|
||||
*/
|
||||
void
|
||||
@@ -134,7 +134,7 @@ gtk_actionable_get_action_target_value (GtkActionable *actionable)
|
||||
/**
|
||||
* gtk_actionable_set_action_target_value: (attributes org.gtk.Method.set_property=action-target)
|
||||
* @actionable: a `GtkActionable` widget
|
||||
* @target_value: (nullable): a `GVariant` to set as the target value
|
||||
* @target_value: (nullable): a [struct@GLib.Variant] to set as the target value
|
||||
*
|
||||
* Sets the target value of an actionable widget.
|
||||
*
|
||||
@@ -145,7 +145,7 @@ gtk_actionable_get_action_target_value (GtkActionable *actionable)
|
||||
* Second, it is used to determine if the widget should be rendered as
|
||||
* “active” — the widget is active if the state is equal to the given target.
|
||||
*
|
||||
* Consider the example of associating a set of buttons with a `GAction`
|
||||
* Consider the example of associating a set of buttons with a [iface@Gio.Action]
|
||||
* with string state in a typical “radio button” situation. Each button
|
||||
* will be associated with the same action, but with a different target
|
||||
* value for that action. Clicking on a particular button will activate
|
||||
@@ -168,12 +168,12 @@ gtk_actionable_set_action_target_value (GtkActionable *actionable,
|
||||
/**
|
||||
* gtk_actionable_set_action_target:
|
||||
* @actionable: a `GtkActionable` widget
|
||||
* @format_string: a GVariant format string
|
||||
* @format_string: a [struct@GLib.Variant] format string
|
||||
* @...: arguments appropriate for @format_string
|
||||
*
|
||||
* Sets the target of an actionable widget.
|
||||
*
|
||||
* This is a convenience function that calls g_variant_new() for
|
||||
* This is a convenience function that calls [ctor@GLib.Variant.new] for
|
||||
* @format_string and uses the result to call
|
||||
* [method@Gtk.Actionable.set_action_target_value].
|
||||
*
|
||||
@@ -202,7 +202,7 @@ gtk_actionable_set_action_target (GtkActionable *actionable,
|
||||
* actionable widget.
|
||||
*
|
||||
* @detailed_action_name is a string in the format accepted by
|
||||
* g_action_parse_detailed_name().
|
||||
* [func@Gio.Action.parse_detailed_name].
|
||||
*/
|
||||
void
|
||||
gtk_actionable_set_detailed_action_name (GtkActionable *actionable,
|
||||
|
||||
@@ -435,9 +435,11 @@ gtk_application_window_measure (GtkWidget *widget,
|
||||
gtk_widget_measure (priv->menubar, GTK_ORIENTATION_VERTICAL,
|
||||
for_size, &menubar_height, NULL, NULL, NULL);
|
||||
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_application_window_parent_class)->measure (widget,
|
||||
orientation,
|
||||
for_size - menubar_height,
|
||||
for_size > -1 ?
|
||||
for_size - menubar_height : -1,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
|
||||
|
||||
+22
-4
@@ -546,7 +546,7 @@ gtk_bitset_union (GtkBitset *self,
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (other != NULL);
|
||||
|
||||
|
||||
if (self == other)
|
||||
return;
|
||||
|
||||
@@ -571,7 +571,7 @@ gtk_bitset_intersect (GtkBitset *self,
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (other != NULL);
|
||||
|
||||
|
||||
if (self == other)
|
||||
return;
|
||||
|
||||
@@ -596,7 +596,7 @@ gtk_bitset_subtract (GtkBitset *self,
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (other != NULL);
|
||||
|
||||
|
||||
if (self == other)
|
||||
{
|
||||
roaring_bitmap_clear (&self->roaring);
|
||||
@@ -626,7 +626,7 @@ gtk_bitset_difference (GtkBitset *self,
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (other != NULL);
|
||||
|
||||
|
||||
if (self == other)
|
||||
{
|
||||
roaring_bitmap_clear (&self->roaring);
|
||||
@@ -756,6 +756,24 @@ gtk_bitset_splice (GtkBitset *self,
|
||||
|
||||
G_STATIC_ASSERT (sizeof (GtkBitsetIter) >= sizeof (roaring_uint32_iterator_t));
|
||||
|
||||
static GtkBitsetIter *
|
||||
gtk_bitset_iter_copy (GtkBitsetIter *iter)
|
||||
{
|
||||
roaring_uint32_iterator_t *riter = (roaring_uint32_iterator_t *) iter;
|
||||
|
||||
return (GtkBitsetIter *) roaring_copy_uint32_iterator (riter);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_bitset_iter_free (GtkBitsetIter *iter)
|
||||
{
|
||||
roaring_uint32_iterator_t *riter = (roaring_uint32_iterator_t *) iter;
|
||||
|
||||
roaring_free_uint32_iterator (riter);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GtkBitsetIter, gtk_bitset_iter, gtk_bitset_iter_copy, gtk_bitset_iter_free)
|
||||
|
||||
/**
|
||||
* gtk_bitset_iter_init_first:
|
||||
* @iter: (out): a pointer to an uninitialized `GtkBitsetIter`
|
||||
|
||||
+3
-2
@@ -148,6 +148,9 @@ struct _GtkBitsetIter
|
||||
gpointer private_data[10];
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
GType gtk_bitset_iter_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_bitset_iter_init_first (GtkBitsetIter *iter,
|
||||
const GtkBitset *set,
|
||||
@@ -171,8 +174,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
guint gtk_bitset_iter_get_value (const GtkBitsetIter *iter);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_bitset_iter_is_valid (const GtkBitsetIter *iter);
|
||||
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ gtk_buildable_set_buildable_id (GtkBuildable *buildable,
|
||||
* `GtkBuilder` sets the name based on the ID attribute
|
||||
* of the <object> tag used to construct the @buildable.
|
||||
*
|
||||
* Returns: the ID of the buildable object
|
||||
* Returns: (nullable): the ID of the buildable object
|
||||
**/
|
||||
const char *
|
||||
gtk_buildable_get_buildable_id (GtkBuildable *buildable)
|
||||
|
||||
@@ -2322,6 +2322,40 @@ gtk_builder_value_from_string_type (GtkBuilder *builder,
|
||||
{
|
||||
g_value_take_boxed (value, g_bytes_new (string, strlen (string)));
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, PANGO_TYPE_FONT_DESCRIPTION))
|
||||
{
|
||||
PangoFontDescription *desc;
|
||||
|
||||
desc = pango_font_description_from_string (string);
|
||||
if (desc)
|
||||
g_value_take_boxed (value, desc);
|
||||
else
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_VALUE,
|
||||
"Could not parse '%s' as a %s",
|
||||
string, G_VALUE_TYPE_NAME (value));
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, PANGO_TYPE_ATTR_LIST))
|
||||
{
|
||||
PangoAttrList *attrs;
|
||||
|
||||
attrs = pango_attr_list_from_string (string);
|
||||
if (attrs)
|
||||
g_value_take_boxed (value, attrs);
|
||||
else
|
||||
{
|
||||
g_set_error (error,
|
||||
GTK_BUILDER_ERROR,
|
||||
GTK_BUILDER_ERROR_INVALID_VALUE,
|
||||
"Could not parse '%s' as a %s",
|
||||
string, G_VALUE_TYPE_NAME (value));
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error,
|
||||
|
||||
@@ -942,7 +942,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
GtkCssTransform transform;
|
||||
GtkCssTransform transform = { 0, };
|
||||
|
||||
if (gtk_css_parser_has_function (parser, "matrix"))
|
||||
{
|
||||
|
||||
+188
-66
@@ -65,6 +65,25 @@ enum {
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
typedef struct _QueuedEvent QueuedEvent;
|
||||
struct _QueuedEvent
|
||||
{
|
||||
GtkDirectoryList *list;
|
||||
GFile *file;
|
||||
GFileInfo *info;
|
||||
GFileMonitorEvent event;
|
||||
};
|
||||
|
||||
static void
|
||||
free_queued_event (gpointer data)
|
||||
{
|
||||
QueuedEvent *event = data;
|
||||
|
||||
g_clear_object (&event->file);
|
||||
g_clear_object (&event->info);
|
||||
g_free (event);
|
||||
}
|
||||
|
||||
struct _GtkDirectoryList
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -78,6 +97,7 @@ struct _GtkDirectoryList
|
||||
GCancellable *cancellable;
|
||||
GError *error; /* Error while loading */
|
||||
GSequence *items; /* Use GPtrArray or GListStore here? */
|
||||
GQueue events;
|
||||
};
|
||||
|
||||
struct _GtkDirectoryListClass
|
||||
@@ -140,7 +160,6 @@ gtk_directory_list_set_property (GObject *object,
|
||||
case PROP_ATTRIBUTES:
|
||||
gtk_directory_list_set_attributes (self, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_FILE:
|
||||
gtk_directory_list_set_file (self, g_value_get_object (value));
|
||||
break;
|
||||
@@ -238,6 +257,9 @@ gtk_directory_list_dispose (GObject *object)
|
||||
g_clear_error (&self->error);
|
||||
g_clear_pointer (&self->items, g_sequence_free);
|
||||
|
||||
g_queue_foreach (&self->events, (GFunc) free_queued_event, NULL);
|
||||
g_queue_clear (&self->events);
|
||||
|
||||
G_OBJECT_CLASS (gtk_directory_list_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -331,6 +353,7 @@ gtk_directory_list_init (GtkDirectoryList *self)
|
||||
self->items = g_sequence_new (g_object_unref);
|
||||
self->io_priority = G_PRIORITY_DEFAULT;
|
||||
self->monitored = TRUE;
|
||||
g_queue_init (&self->events);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -519,24 +542,123 @@ gtk_directory_list_start_loading (GtkDirectoryList *self)
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LOADING]);
|
||||
}
|
||||
|
||||
static GSequenceIter *
|
||||
find_file (GSequence *sequence,
|
||||
GFile *file)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (sequence);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
GFileInfo *item = G_FILE_INFO (g_sequence_get (iter));
|
||||
GFile *f = G_FILE (g_file_info_get_attribute_object (item, "standard::file"));
|
||||
|
||||
if (g_file_equal (f, file))
|
||||
return iter;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_event (QueuedEvent *event)
|
||||
{
|
||||
GtkDirectoryList *self = event->list;
|
||||
GFile *file = event->file;
|
||||
GFileInfo *info = event->info;
|
||||
GSequenceIter *iter;
|
||||
unsigned int position;
|
||||
|
||||
switch ((int)event->event)
|
||||
{
|
||||
case G_FILE_MONITOR_EVENT_MOVED_IN:
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
|
||||
iter = find_file (self->items, file);
|
||||
if (iter)
|
||||
{
|
||||
position = g_sequence_iter_get_position (iter);
|
||||
g_sequence_set (iter, g_object_ref (info));
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
position = g_sequence_get_length (self->items);
|
||||
g_sequence_append (self->items, g_object_ref (info));
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_MOVED_OUT:
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
iter = find_file (self->items, file);
|
||||
if (iter)
|
||||
{
|
||||
position = g_sequence_iter_get_position (iter);
|
||||
g_sequence_remove (iter);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
|
||||
iter = find_file (self->items, file);
|
||||
if (iter)
|
||||
{
|
||||
position = g_sequence_iter_get_position (iter);
|
||||
g_sequence_set (iter, g_object_ref (info));
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_events (GtkDirectoryList *self)
|
||||
{
|
||||
QueuedEvent *event;
|
||||
|
||||
do
|
||||
{
|
||||
event = g_queue_peek_tail (&self->events);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
if (!handle_event (event))
|
||||
return;
|
||||
|
||||
event = g_queue_pop_tail (&self->events);
|
||||
free_queued_event (event);
|
||||
}
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
got_new_file_info_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GFile *file = G_FILE (source);
|
||||
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
|
||||
GFileInfo *info;
|
||||
guint position;
|
||||
QueuedEvent *event = data;
|
||||
GtkDirectoryList *self = event->list;
|
||||
GFile *file = event->file;
|
||||
|
||||
info = g_file_query_info_finish (file, res, NULL);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
position = g_sequence_get_length (self->items);
|
||||
g_sequence_append (self->items, info);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
|
||||
event->info = g_file_query_info_finish (file, res, NULL);
|
||||
handle_events (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -544,53 +666,12 @@ got_existing_file_info_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GFile *file = G_FILE (source);
|
||||
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
|
||||
GFileInfo *info;
|
||||
GSequenceIter *iter;
|
||||
QueuedEvent *event = data;
|
||||
GtkDirectoryList *self = event->list;
|
||||
GFile *file = event->file;
|
||||
|
||||
info = g_file_query_info_finish (file, res, NULL);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (self->items);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
GFileInfo *item = g_sequence_get (iter);
|
||||
GFile *f = G_FILE (g_file_info_get_attribute_object (item, "standard::file"));
|
||||
if (g_file_equal (f, file))
|
||||
{
|
||||
guint position = g_sequence_iter_get_position (iter);
|
||||
g_sequence_set (iter, g_object_ref (info));
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_directory_list_remove_file (GtkDirectoryList *self,
|
||||
GFile *file)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (self->items);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
GFileInfo *item = g_sequence_get (iter);
|
||||
GFile *f = G_FILE (g_file_info_get_attribute_object (item, "standard::file"));
|
||||
if (g_file_equal (f, file))
|
||||
{
|
||||
guint position = g_sequence_iter_get_position (iter);
|
||||
g_sequence_remove (iter);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
event->info = g_file_query_info_finish (file, res, NULL);
|
||||
handle_events (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -601,30 +682,74 @@ directory_changed (GFileMonitor *monitor,
|
||||
gpointer data)
|
||||
{
|
||||
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
|
||||
QueuedEvent *ev;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case G_FILE_MONITOR_EVENT_MOVED_IN:
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
ev = g_new0 (QueuedEvent, 1);
|
||||
ev->list = self;
|
||||
ev->event = event;
|
||||
ev->file = g_object_ref (file);
|
||||
g_queue_push_head (&self->events, ev);
|
||||
|
||||
g_file_query_info_async (file,
|
||||
self->attributes,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
self->io_priority,
|
||||
self->cancellable,
|
||||
got_new_file_info_cb,
|
||||
self);
|
||||
ev);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_MOVED_OUT:
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
gtk_directory_list_remove_file (self, file);
|
||||
ev = g_new0 (QueuedEvent, 1);
|
||||
ev->list = self;
|
||||
ev->event = event;
|
||||
ev->file = g_object_ref (file);
|
||||
g_queue_push_head (&self->events, ev);
|
||||
|
||||
handle_events (self);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
|
||||
ev = g_new0 (QueuedEvent, 1);
|
||||
ev->list = self;
|
||||
ev->event = event;
|
||||
ev->file = g_object_ref (file);
|
||||
g_queue_push_head (&self->events, ev);
|
||||
|
||||
g_file_query_info_async (file,
|
||||
self->attributes,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
self->io_priority,
|
||||
self->cancellable,
|
||||
got_existing_file_info_cb,
|
||||
self);
|
||||
ev);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_RENAMED:
|
||||
ev = g_new0 (QueuedEvent, 1);
|
||||
ev->list = self;
|
||||
ev->event = G_FILE_MONITOR_EVENT_DELETED;
|
||||
ev->file = g_object_ref (file);
|
||||
g_queue_push_head (&self->events, ev);
|
||||
|
||||
ev = g_new0 (QueuedEvent, 1);
|
||||
ev->list = self;
|
||||
ev->event = G_FILE_MONITOR_EVENT_CREATED;
|
||||
ev->file = g_object_ref (other_file);
|
||||
g_queue_push_head (&self->events, ev);
|
||||
|
||||
g_file_query_info_async (other_file,
|
||||
self->attributes,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
self->io_priority,
|
||||
self->cancellable,
|
||||
got_existing_file_info_cb,
|
||||
ev);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_CHANGED:
|
||||
@@ -632,9 +757,6 @@ directory_changed (GFileMonitor *monitor,
|
||||
case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
|
||||
case G_FILE_MONITOR_EVENT_UNMOUNTED:
|
||||
case G_FILE_MONITOR_EVENT_MOVED:
|
||||
case G_FILE_MONITOR_EVENT_RENAMED:
|
||||
case G_FILE_MONITOR_EVENT_MOVED_IN:
|
||||
case G_FILE_MONITOR_EVENT_MOVED_OUT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -644,7 +766,7 @@ static void
|
||||
gtk_directory_list_start_monitoring (GtkDirectoryList *self)
|
||||
{
|
||||
g_assert (self->monitor == NULL);
|
||||
self->monitor = g_file_monitor_directory (self->file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
self->monitor = g_file_monitor_directory (self->file, G_FILE_MONITOR_WATCH_MOVES, NULL, NULL);
|
||||
g_signal_connect (self->monitor, "changed", G_CALLBACK (directory_changed), self);
|
||||
}
|
||||
|
||||
|
||||
@@ -285,6 +285,31 @@ typedef enum
|
||||
GTK_MOVEMENT_HORIZONTAL_PAGES
|
||||
} GtkMovementStep;
|
||||
|
||||
/**
|
||||
* GtkNaturalWrapMode:
|
||||
* @GTK_NATURAL_WRAP_INHERIT: Inherit the minimum size request.
|
||||
* In particular, this should be used with %PANGO_WRAP_CHAR.
|
||||
* @GTK_NATURAL_WRAP_NONE: Try not to wrap the text. This mode is the
|
||||
* closest to GTK3's behavior but can lead to a wide label leaving
|
||||
* lots of empty space below the text.
|
||||
* @GTK_NATURAL_WRAP_WORD: Attempt to wrap at word boundaries. This
|
||||
* is useful in particular when using %PANGO_WRAP_WORD_CHAR as the
|
||||
* wrap mode.
|
||||
*
|
||||
* Options for selecting a different wrap mode for natural size
|
||||
* requests.
|
||||
*
|
||||
* See for example the [property@Gtk.Label:natural-wrap-mode] property.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_NATURAL_WRAP_INHERIT,
|
||||
GTK_NATURAL_WRAP_NONE,
|
||||
GTK_NATURAL_WRAP_WORD
|
||||
} GtkNaturalWrapMode;
|
||||
|
||||
/**
|
||||
* GtkScrollStep:
|
||||
* @GTK_SCROLL_STEPS: Scroll in steps.
|
||||
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
@@ -1372,7 +1371,7 @@ gtk_property_expression_new_for_pspec (GtkExpression *expression,
|
||||
* Gets the expression specifying the object of
|
||||
* a property expression.
|
||||
*
|
||||
* Returns: (transfer none): the object expression
|
||||
* Returns: (transfer none) (nullable): the object expression
|
||||
*/
|
||||
GtkExpression *
|
||||
gtk_property_expression_get_expression (GtkExpression *expression)
|
||||
|
||||
@@ -50,6 +50,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
GtkExpression * gtk_expression_ref (GtkExpression *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_expression_unref (GtkExpression *self);
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkExpression, gtk_expression_unref)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_expression_get_value_type (GtkExpression *self);
|
||||
|
||||
@@ -523,7 +523,7 @@ gtk_file_chooser_set_file (GtkFileChooser *chooser,
|
||||
* If the file chooser is in folder mode, this function returns
|
||||
* the selected folder.
|
||||
*
|
||||
* Returns: (transfer full): a selected `GFile`. You own the
|
||||
* Returns: (transfer full) (nullable): a selected `GFile`. You own the
|
||||
* returned file; use g_object_unref() to release it.
|
||||
*/
|
||||
GFile *
|
||||
@@ -794,7 +794,7 @@ gtk_file_chooser_set_choice (GtkFileChooser *chooser,
|
||||
*
|
||||
* Gets the currently selected option in the 'choice' with the given ID.
|
||||
*
|
||||
* Returns: the ID of the currently selected option
|
||||
* Returns: (nullable): the ID of the currently selected option
|
||||
*/
|
||||
const char *
|
||||
gtk_file_chooser_get_choice (GtkFileChooser *chooser,
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "gtktogglebutton.h"
|
||||
#include "gtkheaderbar.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkfilefilterprivate.h"
|
||||
#include "gtknative.h"
|
||||
|
||||
@@ -50,6 +51,9 @@
|
||||
|
||||
typedef struct {
|
||||
GtkFileChooserNative *self;
|
||||
|
||||
GtkWidget *grab_widget;
|
||||
|
||||
IFileDialogEvents *events;
|
||||
|
||||
HWND parent;
|
||||
@@ -318,6 +322,12 @@ filechooser_win32_thread_data_free (FilechooserWin32ThreadData *data)
|
||||
if (data->events)
|
||||
IFileDialogEvents_Release (data->events);
|
||||
|
||||
if (data->grab_widget)
|
||||
{
|
||||
gtk_grab_remove (data->grab_widget);
|
||||
g_object_unref (data->grab_widget);
|
||||
}
|
||||
|
||||
g_clear_object (&data->current_folder);
|
||||
g_clear_object (&data->current_file);
|
||||
g_free (data->current_name);
|
||||
@@ -969,6 +979,12 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (data->modal)
|
||||
{
|
||||
data->grab_widget = g_object_ref_sink (gtk_label_new (""));
|
||||
gtk_grab_add (GTK_WIDGET (data->grab_widget));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -510,7 +510,7 @@ gtk_flatten_list_model_get_model (GtkFlattenListModel *self)
|
||||
*
|
||||
* Returns the model containing the item at the given position.
|
||||
*
|
||||
* Returns: (transfer none): the model containing the item at @position
|
||||
* Returns: (transfer none) (nullable): the model containing the item at @position
|
||||
*/
|
||||
GListModel *
|
||||
gtk_flatten_list_model_get_model_for_item (GtkFlattenListModel *self,
|
||||
|
||||
@@ -433,6 +433,8 @@ gtk_font_button_font_chooser_set_font_map (GtkFontChooser *chooser,
|
||||
|
||||
context = gtk_widget_get_pango_context (font_button->font_label);
|
||||
pango_context_set_font_map (context, font_map);
|
||||
if (font_button->font_dialog)
|
||||
gtk_font_chooser_set_font_map (GTK_FONT_CHOOSER (font_button->font_dialog), font_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+233
-199
@@ -64,12 +64,8 @@
|
||||
#include "gtkstringsorter.h"
|
||||
|
||||
#include <hb-ot.h>
|
||||
#if defined(HAVE_PANGOFT) && defined(HAVE_HARFBUZZ)
|
||||
#include <pango/pangofc-font.h>
|
||||
#endif
|
||||
|
||||
#include "language-names.h"
|
||||
#include "script-names.h"
|
||||
#include "open-type-layout.h"
|
||||
|
||||
/**
|
||||
@@ -155,6 +151,8 @@ struct _GtkFontChooserWidget
|
||||
GList *feature_items;
|
||||
|
||||
GAction *tweak_action;
|
||||
|
||||
hb_map_t *glyphmap;
|
||||
};
|
||||
|
||||
struct _GtkFontChooserWidgetClass
|
||||
@@ -362,7 +360,6 @@ user_filter_cb (gpointer item,
|
||||
!pango_font_family_is_monospace (family))
|
||||
return FALSE;
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
if (self->filter_by_language &&
|
||||
self->filter_language)
|
||||
{
|
||||
@@ -370,6 +367,7 @@ user_filter_cb (gpointer item,
|
||||
PangoContext *context;
|
||||
PangoFont *font;
|
||||
gboolean ret;
|
||||
PangoLanguage **langs;
|
||||
|
||||
desc = pango_font_face_describe (face);
|
||||
pango_font_description_set_size (desc, 20);
|
||||
@@ -377,27 +375,19 @@ user_filter_cb (gpointer item,
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
|
||||
font = pango_context_load_font (context, desc);
|
||||
|
||||
ret = TRUE;
|
||||
ret = FALSE;
|
||||
|
||||
if (PANGO_IS_FC_FONT (font))
|
||||
langs = pango_font_get_languages (font);
|
||||
if (langs)
|
||||
{
|
||||
PangoLanguage **langs;
|
||||
int i;
|
||||
|
||||
ret = FALSE;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
langs = pango_fc_font_get_languages (PANGO_FC_FONT (font));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
if (langs)
|
||||
for (i = 0; langs[i]; i++)
|
||||
{
|
||||
if (langs[i] == self->filter_language)
|
||||
{
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; langs[i]; i++)
|
||||
{
|
||||
if (langs[i] == self->filter_language)
|
||||
{
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (font);
|
||||
@@ -405,7 +395,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -549,10 +538,16 @@ maybe_update_preview_text (GtkFontChooserWidget *self,
|
||||
PangoFontFace *face,
|
||||
PangoFontDescription *desc)
|
||||
{
|
||||
#if defined(HAVE_PANGOFT) && defined(HAVE_HARFBUZZ)
|
||||
PangoContext *context;
|
||||
PangoFont *font;
|
||||
const char *sample;
|
||||
PangoLanguage **languages;
|
||||
GHashTable *langs = NULL;
|
||||
PangoLanguage *default_lang;
|
||||
PangoLanguage *alt_default = NULL;
|
||||
PangoLanguage *lang = NULL;
|
||||
int i;
|
||||
const char *p;
|
||||
|
||||
/* If the user has typed text into the entry, we don't touch it */
|
||||
if (self->preview_text_set)
|
||||
@@ -576,88 +571,77 @@ maybe_update_preview_text (GtkFontChooserWidget *self,
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
|
||||
font = pango_context_load_font (context, desc);
|
||||
|
||||
if (PANGO_IS_FC_FONT (font))
|
||||
default_lang = pango_language_get_default ();
|
||||
p = pango_language_to_string (default_lang);
|
||||
|
||||
/* The default language tends to be of the form en-us.
|
||||
* Since fontconfig languages just have the language part,
|
||||
* and we want to use direct pointer comparisons, we need
|
||||
* an PangoLanguage for the shortened default language.
|
||||
*/
|
||||
if (strchr (p, '-'))
|
||||
{
|
||||
PangoLanguage **languages;
|
||||
GHashTable *langs = NULL;
|
||||
PangoLanguage *default_lang;
|
||||
PangoLanguage *alt_default = NULL;
|
||||
PangoLanguage *lang = NULL;
|
||||
int i;
|
||||
const char *p;
|
||||
char q[10];
|
||||
for (i = 0; p[i] != '-' && i < 9; i++)
|
||||
q[i] = p[i];
|
||||
q[i] = '\0';
|
||||
alt_default = pango_language_from_string (q);
|
||||
}
|
||||
|
||||
default_lang = pango_language_get_default ();
|
||||
p = pango_language_to_string (default_lang);
|
||||
languages = pango_font_get_languages (font);
|
||||
|
||||
/* The default language tends to be of the form en-us.
|
||||
* Since fontconfig languages just have the language part,
|
||||
* and we want to use direct pointer comparisons, we need
|
||||
* an PangoLanguage for the shortened default language.
|
||||
*/
|
||||
if (strchr (p, '-'))
|
||||
{
|
||||
char q[10];
|
||||
for (i = 0; p[i] != '-' && i < 9; i++)
|
||||
q[i] = p[i];
|
||||
q[i] = '\0';
|
||||
alt_default = pango_language_from_string (q);
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
languages = pango_fc_font_get_languages (PANGO_FC_FONT (font));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
/* If the font supports the default language, just use it. */
|
||||
if (languages)
|
||||
for (i = 0; languages[i]; i++)
|
||||
/* If the font supports the default language, just use it. */
|
||||
if (languages)
|
||||
for (i = 0; languages[i]; i++)
|
||||
{
|
||||
if (languages[i] == default_lang || languages[i] == alt_default)
|
||||
{
|
||||
if (languages[i] == default_lang || languages[i] == alt_default)
|
||||
{
|
||||
lang = default_lang;
|
||||
goto found;
|
||||
}
|
||||
lang = default_lang;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, we make a list of representative languages */
|
||||
langs = g_hash_table_new (NULL, NULL);
|
||||
/* Otherwise, we make a list of representative languages */
|
||||
langs = g_hash_table_new (NULL, NULL);
|
||||
|
||||
for (i = 0; languages[i]; i++)
|
||||
if (languages)
|
||||
for (i = 0; languages[i]; i++)
|
||||
{
|
||||
const PangoScript *scripts;
|
||||
int num, j;
|
||||
|
||||
scripts = pango_language_get_scripts (languages[i], &num);
|
||||
for (j = 0; j < num; j++)
|
||||
{
|
||||
lang = pango_script_get_sample_language (scripts[j]);
|
||||
if (lang)
|
||||
g_hash_table_add (langs, lang);
|
||||
}
|
||||
}
|
||||
|
||||
/* ... and compare it to the users default and preferred languages */
|
||||
if (g_hash_table_contains (langs, default_lang) ||
|
||||
g_hash_table_contains (langs, alt_default))
|
||||
{
|
||||
lang = default_lang;
|
||||
}
|
||||
else
|
||||
{
|
||||
PangoLanguage **preferred;
|
||||
|
||||
preferred = pango_language_get_preferred ();
|
||||
if (preferred)
|
||||
{
|
||||
const PangoScript *scripts;
|
||||
int num, j;
|
||||
|
||||
scripts = pango_language_get_scripts (languages[i], &num);
|
||||
for (j = 0; j < num; j++)
|
||||
for (i = 0; preferred[i]; i++)
|
||||
{
|
||||
lang = pango_script_get_sample_language (scripts[j]);
|
||||
if (lang)
|
||||
g_hash_table_add (langs, lang);
|
||||
}
|
||||
}
|
||||
|
||||
/* ... and compare it to the users default and preferred languages */
|
||||
if (g_hash_table_contains (langs, default_lang) ||
|
||||
g_hash_table_contains (langs, alt_default))
|
||||
{
|
||||
lang = default_lang;
|
||||
}
|
||||
else
|
||||
{
|
||||
PangoLanguage **preferred;
|
||||
|
||||
preferred = pango_language_get_preferred ();
|
||||
if (preferred)
|
||||
{
|
||||
for (i = 0; preferred[i]; i++)
|
||||
if (g_hash_table_contains (langs, preferred[i]))
|
||||
{
|
||||
if (g_hash_table_contains (langs, preferred[i]))
|
||||
{
|
||||
lang = preferred[i];
|
||||
break;
|
||||
}
|
||||
lang = preferred[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_unref (langs);
|
||||
|
||||
found:
|
||||
@@ -667,7 +651,6 @@ found:
|
||||
}
|
||||
|
||||
g_object_unref (font);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1027,7 +1010,6 @@ axis_free (gpointer v)
|
||||
g_free (a);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
static void
|
||||
select_added (GListModel *model,
|
||||
guint position,
|
||||
@@ -1051,6 +1033,10 @@ add_languages_from_font (GtkFontChooserWidget *self,
|
||||
PangoFontDescription *desc;
|
||||
PangoFont *font;
|
||||
PangoContext *context;
|
||||
GtkSelectionModel *model = gtk_list_view_get_model (GTK_LIST_VIEW (self->language_list));
|
||||
PangoLanguage *default_lang = pango_language_get_default ();
|
||||
PangoLanguage **langs;
|
||||
int i;
|
||||
|
||||
if (PANGO_IS_FONT_FAMILY (item))
|
||||
face = pango_font_family_get_face (PANGO_FONT_FAMILY (item), NULL);
|
||||
@@ -1066,44 +1052,35 @@ add_languages_from_font (GtkFontChooserWidget *self,
|
||||
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
|
||||
font = pango_context_load_font (context, desc);
|
||||
|
||||
if (PANGO_IS_FC_FONT (font))
|
||||
langs = pango_font_get_languages (font);
|
||||
if (langs)
|
||||
{
|
||||
GtkSelectionModel *model = gtk_list_view_get_model (GTK_LIST_VIEW (self->language_list));
|
||||
PangoLanguage *default_lang = pango_language_get_default ();
|
||||
PangoLanguage **langs;
|
||||
int i;
|
||||
for (i = 0; langs[i]; i++)
|
||||
{
|
||||
if (!g_hash_table_contains (self->language_table, langs[i]))
|
||||
{
|
||||
g_hash_table_add (self->language_table, langs[i]);
|
||||
if (get_language_name (langs[i]))
|
||||
{
|
||||
const char *l = pango_language_to_string (langs[i]);
|
||||
gulong id = 0;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
langs = pango_fc_font_get_languages (PANGO_FC_FONT (font));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
if (langs)
|
||||
for (i = 0; langs[i]; i++)
|
||||
{
|
||||
if (!g_hash_table_contains (self->language_table, langs[i]))
|
||||
{
|
||||
g_hash_table_add (self->language_table, langs[i]);
|
||||
if (get_language_name (langs[i]))
|
||||
{
|
||||
const char *l = pango_language_to_string (langs[i]);
|
||||
gulong id = 0;
|
||||
/* Pre-select the default language */
|
||||
if (pango_language_matches (default_lang, l))
|
||||
id = g_signal_connect (model, "items-changed", G_CALLBACK (select_added), NULL);
|
||||
|
||||
/* Pre-select the default language */
|
||||
if (pango_language_matches (default_lang, l))
|
||||
id = g_signal_connect (model, "items-changed", G_CALLBACK (select_added), NULL);
|
||||
gtk_string_list_append (self->languages, l);
|
||||
|
||||
gtk_string_list_append (self->languages, l);
|
||||
|
||||
if (id)
|
||||
g_signal_handler_disconnect (model, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (id)
|
||||
g_signal_handler_disconnect (model, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (font);
|
||||
pango_font_description_free (desc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
gtk_font_chooser_widget_ensure_matching_selection (GtkFontChooserWidget *self);
|
||||
@@ -1130,7 +1107,6 @@ add_to_fontlist (GtkWidget *widget,
|
||||
|
||||
n = gtk_slice_list_model_get_size (model);
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
for (i = n; i < n + 10; i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (child_model, i);
|
||||
@@ -1139,7 +1115,6 @@ add_to_fontlist (GtkWidget *widget,
|
||||
add_languages_from_font (self, item);
|
||||
g_object_unref (item);
|
||||
}
|
||||
#endif
|
||||
|
||||
n += 10;
|
||||
|
||||
@@ -1179,7 +1154,6 @@ update_fontlist (GtkFontChooserWidget *self)
|
||||
g_object_unref (model);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
static void
|
||||
setup_lang_item (GtkSignalListItemFactory *factory,
|
||||
gpointer item,
|
||||
@@ -1269,7 +1243,6 @@ setup_language_list (GtkFontChooserWidget *self)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_font_chooser_widget_init (GtkFontChooserWidget *self)
|
||||
@@ -1310,12 +1283,7 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *self)
|
||||
|
||||
gtk_custom_filter_set_filter_func (self->user_filter, user_filter_cb, self, NULL);
|
||||
|
||||
#ifdef HAVE_PANGOFT
|
||||
setup_language_list (self);
|
||||
#else
|
||||
gtk_widget_hide (GTK_WIDGET (self->language_button));
|
||||
gtk_widget_hide (GTK_WIDGET (self->language_frame));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1501,26 +1469,23 @@ add_font_variations (GtkFontChooserWidget *fontchooser,
|
||||
{
|
||||
GHashTableIter iter;
|
||||
Axis *axis;
|
||||
const char *sep = "";
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_hash_table_iter_init (&iter, fontchooser->axes);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
|
||||
{
|
||||
char tag[5];
|
||||
double value;
|
||||
char buf[128];
|
||||
|
||||
value = gtk_adjustment_get_value (axis->adjustment);
|
||||
|
||||
if (value == axis->default_value)
|
||||
continue;
|
||||
|
||||
tag[0] = (axis->tag >> 24) & 0xff;
|
||||
tag[1] = (axis->tag >> 16) & 0xff;
|
||||
tag[2] = (axis->tag >> 8) & 0xff;
|
||||
tag[3] = (axis->tag >> 0) & 0xff;
|
||||
tag[4] = '\0';
|
||||
g_string_append_printf (s, "%s%s=%s", sep, tag, g_ascii_dtostr (buf, sizeof(buf), value));
|
||||
sep = ",";
|
||||
hb_variation_to_string (&(hb_variation_t) { axis->tag, value }, buf, sizeof (buf));
|
||||
|
||||
if (s->len > 0)
|
||||
g_string_append_c (s, ',');
|
||||
g_string_append (s, buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1549,10 +1514,7 @@ adjustment_changed (GtkAdjustment *adjustment,
|
||||
static gboolean
|
||||
should_show_axis (hb_ot_var_axis_info_t *ax)
|
||||
{
|
||||
if (ax->flags & HB_OT_VAR_AXIS_FLAG_HIDDEN)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
return (ax->flags & HB_OT_VAR_AXIS_FLAG_HIDDEN) == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1566,11 +1528,11 @@ static struct {
|
||||
guint32 tag;
|
||||
const char *name;
|
||||
} axis_names[] = {
|
||||
{ HB_OT_TAG_VAR_AXIS_WIDTH, N_("Width") },
|
||||
{ HB_OT_TAG_VAR_AXIS_WEIGHT, N_("Weight") },
|
||||
{ HB_OT_TAG_VAR_AXIS_ITALIC, N_("Italic") },
|
||||
{ HB_OT_TAG_VAR_AXIS_SLANT, N_("Slant") },
|
||||
{ HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE, N_("Optical Size") },
|
||||
{ HB_OT_TAG_VAR_AXIS_WIDTH, NC_("Font variation axis", "Width") },
|
||||
{ HB_OT_TAG_VAR_AXIS_WEIGHT, NC_("Font variation axis", "Weight") },
|
||||
{ HB_OT_TAG_VAR_AXIS_ITALIC, NC_("Font variation axis", "Italic") },
|
||||
{ HB_OT_TAG_VAR_AXIS_SLANT, NC_("Font variation axis", "Slant") },
|
||||
{ HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE, NC_("Font variation axis", "Optical Size") },
|
||||
};
|
||||
|
||||
static gboolean
|
||||
@@ -1601,7 +1563,7 @@ add_axis (GtkFontChooserWidget *fontchooser,
|
||||
{
|
||||
if (axis_names[i].tag == ax->tag)
|
||||
{
|
||||
name = _(axis_names[i].name);
|
||||
name = g_dpgettext2 (NULL, "Font variation axis", axis_names[i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1643,6 +1605,33 @@ add_axis (GtkFontChooserWidget *fontchooser,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if HB_VERSION_ATLEAST (3, 3, 0)
|
||||
static void
|
||||
get_axes_and_values (hb_font_t *font,
|
||||
unsigned int n_axes,
|
||||
hb_ot_var_axis_info_t *axes,
|
||||
float *coords)
|
||||
{
|
||||
const float *dcoords;
|
||||
unsigned int length = n_axes;
|
||||
|
||||
hb_ot_var_get_axis_infos (hb_font_get_face (font), 0, &length, axes);
|
||||
|
||||
dcoords = hb_font_get_var_coords_design (font, &length);
|
||||
if (dcoords)
|
||||
memcpy (coords, dcoords, sizeof (float) * length);
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < n_axes; i++)
|
||||
{
|
||||
hb_ot_var_axis_info_t *axis = &axes[i];
|
||||
coords[axis->axis_index] = axis->default_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* FIXME: This doesn't work if the font has an avar table */
|
||||
static float
|
||||
denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
|
||||
@@ -1655,16 +1644,40 @@ denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
|
||||
return axis->default_value + r * (axis->max_value - axis->default_value);
|
||||
}
|
||||
|
||||
static void
|
||||
get_axes_and_values (hb_font_t *font,
|
||||
unsigned int n_axes,
|
||||
hb_ot_var_axis_info_t *axes,
|
||||
float *coords)
|
||||
{
|
||||
const int *ncoords;
|
||||
unsigned int length = n_axes;
|
||||
|
||||
hb_ot_var_get_axis_infos (hb_font_get_face (font), 0, &length, axes);
|
||||
|
||||
ncoords = hb_font_get_var_coords_normalized (font, &length);
|
||||
|
||||
for (int i = 0; i < n_axes; i++)
|
||||
{
|
||||
hb_ot_var_axis_info_t *axis = &axes[i];
|
||||
int idx = axis->axis_index;
|
||||
if (ncoords)
|
||||
coords[idx] = denorm_coord (axis, ncoords[idx]);
|
||||
else
|
||||
coords[idx] = axis->default_value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchooser)
|
||||
{
|
||||
PangoFont *pango_font;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
const int *coords;
|
||||
unsigned int n_coords;
|
||||
unsigned int n_axes;
|
||||
hb_ot_var_axis_info_t *axes;
|
||||
float *coords;
|
||||
gboolean has_axis = FALSE;
|
||||
int i;
|
||||
|
||||
@@ -1685,24 +1698,17 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose
|
||||
if (!hb_ot_var_has_data (hb_face))
|
||||
return FALSE;
|
||||
|
||||
coords = hb_font_get_var_coords_normalized (hb_font, &n_coords);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_count (hb_face);
|
||||
axes = g_new0 (hb_ot_var_axis_info_t, n_axes);
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, axes);
|
||||
axes = g_alloca (sizeof (hb_ot_var_axis_info_t) * n_axes);
|
||||
coords = g_alloca (sizeof (float) * n_axes);
|
||||
get_axes_and_values (hb_font, n_axes, axes, coords);
|
||||
|
||||
for (i = 0; i < n_axes; i++)
|
||||
{
|
||||
float value;
|
||||
if (coords && i < n_coords)
|
||||
value = denorm_coord (&axes[i], coords[i]);
|
||||
else
|
||||
value = axes[i].default_value;
|
||||
if (add_axis (fontchooser, hb_font, &axes[i], value, i + 4))
|
||||
if (add_axis (fontchooser, hb_font, &axes[i], coords[axes[i].axis_index], i + 4))
|
||||
has_axis = TRUE;
|
||||
}
|
||||
|
||||
g_free (axes);
|
||||
g_object_unref (pango_font);
|
||||
|
||||
return has_axis;
|
||||
@@ -1827,11 +1833,12 @@ feat_pressed (GtkGestureClick *gesture,
|
||||
}
|
||||
|
||||
static char *
|
||||
find_affected_text (hb_tag_t feature_tag,
|
||||
hb_font_t *hb_font,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t lang_tag,
|
||||
int max_chars)
|
||||
find_affected_text (GtkFontChooserWidget *fontchooser,
|
||||
hb_tag_t feature_tag,
|
||||
hb_font_t *hb_font,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t lang_tag,
|
||||
int max_chars)
|
||||
{
|
||||
hb_face_t *hb_face;
|
||||
unsigned int script_index = 0;
|
||||
@@ -1881,24 +1888,35 @@ find_affected_text (hb_tag_t feature_tag,
|
||||
glyphs_after,
|
||||
glyphs_output);
|
||||
|
||||
gid = -1;
|
||||
while (hb_set_next (glyphs_input, &gid)) {
|
||||
hb_codepoint_t ch;
|
||||
if (n_chars == max_chars)
|
||||
{
|
||||
g_string_append (chars, "…");
|
||||
break;
|
||||
}
|
||||
for (ch = 0; ch < 0xffff; ch++) {
|
||||
hb_codepoint_t glyph = 0;
|
||||
hb_font_get_nominal_glyph (hb_font, ch, &glyph);
|
||||
if (glyph == gid) {
|
||||
g_string_append_unichar (chars, (gunichar)ch);
|
||||
n_chars++;
|
||||
break;
|
||||
}
|
||||
if (!fontchooser->glyphmap)
|
||||
{
|
||||
fontchooser->glyphmap = hb_map_create ();
|
||||
for (hb_codepoint_t ch = 0; ch < 0xffff; ch++)
|
||||
{
|
||||
hb_codepoint_t glyph = 0;
|
||||
if (hb_font_get_nominal_glyph (hb_font, ch, &glyph) &&
|
||||
!hb_map_has (fontchooser->glyphmap, glyph))
|
||||
hb_map_set (fontchooser->glyphmap, glyph, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (hb_set_next (glyphs_input, &gid))
|
||||
{
|
||||
hb_codepoint_t ch;
|
||||
|
||||
if (n_chars == max_chars)
|
||||
{
|
||||
g_string_append (chars, "…");
|
||||
break;
|
||||
}
|
||||
ch = hb_map_get (fontchooser->glyphmap, gid);
|
||||
if (ch != HB_MAP_VALUE_INVALID)
|
||||
{
|
||||
g_string_append_unichar (chars, (gunichar)ch);
|
||||
n_chars++;
|
||||
}
|
||||
}
|
||||
|
||||
hb_set_destroy (glyphs_input);
|
||||
}
|
||||
}
|
||||
@@ -1907,7 +1925,8 @@ find_affected_text (hb_tag_t feature_tag,
|
||||
}
|
||||
|
||||
static void
|
||||
update_feature_example (FeatureItem *item,
|
||||
update_feature_example (GtkFontChooserWidget *fontchooser,
|
||||
FeatureItem *item,
|
||||
hb_font_t *hb_font,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t lang_tag,
|
||||
@@ -1962,9 +1981,9 @@ update_feature_example (FeatureItem *item,
|
||||
else if (strcmp (item->name, "frac") == 0)
|
||||
input = g_strdup ("1/2 2/3 7/8");
|
||||
else if (strcmp (item->name, "nalt") == 0)
|
||||
input = find_affected_text (item->tag, hb_font, script_tag, lang_tag, 3);
|
||||
input = find_affected_text (fontchooser, item->tag, hb_font, script_tag, lang_tag, 3);
|
||||
else
|
||||
input = find_affected_text (item->tag, hb_font, script_tag, lang_tag, 10);
|
||||
input = find_affected_text (fontchooser, item->tag, hb_font, script_tag, lang_tag, 10);
|
||||
|
||||
if (input[0] != '\0')
|
||||
{
|
||||
@@ -2244,7 +2263,7 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
|
||||
gtk_widget_show (item->top);
|
||||
gtk_widget_show (gtk_widget_get_parent (item->top));
|
||||
|
||||
update_feature_example (item, hb_font, script_tag, lang_tag, fontchooser->font_desc);
|
||||
update_feature_example (fontchooser, item, hb_font, script_tag, lang_tag, fontchooser->font_desc);
|
||||
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
@@ -2260,6 +2279,12 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fontchooser->glyphmap)
|
||||
{
|
||||
hb_map_destroy (fontchooser->glyphmap);
|
||||
fontchooser->glyphmap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (pango_font);
|
||||
@@ -2272,6 +2297,7 @@ update_font_features (GtkFontChooserWidget *fontchooser)
|
||||
{
|
||||
GString *s;
|
||||
GList *l;
|
||||
char buf[128];
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
@@ -2287,17 +2313,24 @@ update_font_features (GtkFontChooserWidget *fontchooser)
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)) &&
|
||||
strcmp (item->name, "xxxx") != 0)
|
||||
{
|
||||
g_string_append_printf (s, "%s\"%s\" %d", s->len > 0 ? ", " : "", item->name, 1);
|
||||
hb_feature_to_string (&(hb_feature_t) { item->tag, 1, 0, -1 }, buf, sizeof (buf));
|
||||
if (s->len > 0)
|
||||
g_string_append_c (s, ',');
|
||||
g_string_append (s, buf);
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
guint32 value;
|
||||
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (item->feat)))
|
||||
continue;
|
||||
|
||||
g_string_append_printf (s, "%s\"%s\" %d",
|
||||
s->len > 0 ? ", " : "", item->name,
|
||||
gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)));
|
||||
value = gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat));
|
||||
hb_feature_to_string (&(hb_feature_t) { item->tag, value, 0, -1 }, buf, sizeof (buf));
|
||||
if (s->len > 0)
|
||||
g_string_append_c (s, ',');
|
||||
g_string_append (s, buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2335,7 +2368,8 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser
|
||||
{
|
||||
double font_size = (double) pango_font_description_get_size (fontchooser->font_desc) / PANGO_SCALE;
|
||||
/* XXX: This clamps, which can cause it to reloop into here, do we need
|
||||
* to block its signal handler? */
|
||||
* to block its signal handler?
|
||||
*/
|
||||
gtk_range_set_value (GTK_RANGE (fontchooser->size_slider), font_size);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (fontchooser->size_spin), font_size);
|
||||
}
|
||||
|
||||
+5
-1
@@ -833,6 +833,10 @@ gtk_gl_area_class_init (GtkGLAreaClass *klass)
|
||||
*
|
||||
* If set to %TRUE the widget will allocate and enable a depth buffer for the
|
||||
* target framebuffer.
|
||||
*
|
||||
* Setting this property will enable GL's depth testing as a side effect. If
|
||||
* you don't need depth testing, you should call `glDisable(GL_DEPTH_TEST)`
|
||||
* in your `GtkGLArea::render` handler.
|
||||
*/
|
||||
obj_props[PROP_HAS_DEPTH_BUFFER] =
|
||||
g_param_spec_boolean ("has-depth-buffer",
|
||||
@@ -1317,7 +1321,7 @@ gtk_gl_area_set_auto_render (GtkGLArea *area,
|
||||
*
|
||||
* Retrieves the `GdkGLContext` used by @area.
|
||||
*
|
||||
* Returns: (transfer none): the `GdkGLContext`
|
||||
* Returns: (transfer none) (nullable): the `GdkGLContext`
|
||||
*/
|
||||
GdkGLContext *
|
||||
gtk_gl_area_get_context (GtkGLArea *area)
|
||||
|
||||
+9
-2
@@ -4993,8 +4993,15 @@ gtk_icon_view_unselect_path (GtkIconView *icon_view,
|
||||
* want to convert the returned list into a list of `GtkTreeRowReferences`.
|
||||
* To do this, you can use gtk_tree_row_reference_new().
|
||||
*
|
||||
* To free the return value, use:
|
||||
* To free the return value, use `g_list_free_full`:
|
||||
* |[<!-- language="C" -->
|
||||
* GtkWidget *icon_view = gtk_icon_view_new ();
|
||||
* // Use icon_view
|
||||
*
|
||||
* GList *list = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (icon_view));
|
||||
*
|
||||
* // use list
|
||||
*
|
||||
* g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
|
||||
* ]|
|
||||
*
|
||||
@@ -6519,7 +6526,7 @@ gtk_icon_view_get_dest_item_at_pos (GtkIconView *icon_view,
|
||||
* Creates a `GdkPaintable` representation of the item at @path.
|
||||
* This image is used for a drag icon.
|
||||
*
|
||||
* Returns: (transfer full): a newly-allocated `GdkPaintable` of the drag icon.
|
||||
* Returns: (transfer full) (nullable): a newly-allocated `GdkPaintable` of the drag icon.
|
||||
**/
|
||||
GdkPaintable *
|
||||
gtk_icon_view_create_drag_icon (GtkIconView *icon_view,
|
||||
|
||||
+133
-21
@@ -55,6 +55,7 @@
|
||||
#include "gtkjoinedmenuprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
@@ -272,6 +273,7 @@ struct _GtkLabel
|
||||
guint ellipsize : 3;
|
||||
guint use_markup : 1;
|
||||
guint wrap_mode : 3;
|
||||
guint natural_wrap_mode : 3;
|
||||
guint single_line_mode : 1;
|
||||
guint in_click : 1;
|
||||
guint track_links : 1;
|
||||
@@ -380,6 +382,7 @@ enum {
|
||||
PROP_JUSTIFY,
|
||||
PROP_WRAP,
|
||||
PROP_WRAP_MODE,
|
||||
PROP_NATURAL_WRAP_MODE,
|
||||
PROP_SELECTABLE,
|
||||
PROP_MNEMONIC_KEYVAL,
|
||||
PROP_MNEMONIC_WIDGET,
|
||||
@@ -484,6 +487,9 @@ gtk_label_set_property (GObject *object,
|
||||
case PROP_WRAP_MODE:
|
||||
gtk_label_set_wrap_mode (self, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_NATURAL_WRAP_MODE:
|
||||
gtk_label_set_natural_wrap_mode (self, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_SELECTABLE:
|
||||
gtk_label_set_selectable (self, g_value_get_boolean (value));
|
||||
break;
|
||||
@@ -551,6 +557,9 @@ gtk_label_get_property (GObject *object,
|
||||
case PROP_WRAP_MODE:
|
||||
g_value_set_enum (value, self->wrap_mode);
|
||||
break;
|
||||
case PROP_NATURAL_WRAP_MODE:
|
||||
g_value_set_enum (value, self->natural_wrap_mode);
|
||||
break;
|
||||
case PROP_SELECTABLE:
|
||||
g_value_set_boolean (value, gtk_label_get_selectable (self));
|
||||
break;
|
||||
@@ -604,6 +613,7 @@ gtk_label_init (GtkLabel *self)
|
||||
self->jtype = GTK_JUSTIFY_LEFT;
|
||||
self->wrap = FALSE;
|
||||
self->wrap_mode = PANGO_WRAP_WORD;
|
||||
self->natural_wrap_mode = GTK_NATURAL_WRAP_INHERIT;
|
||||
self->ellipsize = PANGO_ELLIPSIZE_NONE;
|
||||
|
||||
self->use_underline = FALSE;
|
||||
@@ -1158,6 +1168,34 @@ get_height_for_width (GtkLabel *self,
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
static int
|
||||
my_pango_layout_get_width_for_height (PangoLayout *layout,
|
||||
int for_height,
|
||||
int min,
|
||||
int max)
|
||||
{
|
||||
int mid, text_width, text_height;
|
||||
|
||||
min = PANGO_PIXELS_CEIL (min);
|
||||
max = PANGO_PIXELS_CEIL (max);
|
||||
|
||||
while (min < max)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
pango_layout_set_width (layout, mid * PANGO_SCALE);
|
||||
pango_layout_get_size (layout, &text_width, &text_height);
|
||||
text_width = PANGO_PIXELS_CEIL (text_width);
|
||||
if (text_width > mid)
|
||||
min = text_width;
|
||||
else if (text_height > for_height)
|
||||
min = mid + 1;
|
||||
else
|
||||
max = mid;
|
||||
}
|
||||
|
||||
return min * PANGO_SCALE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_width_for_height (GtkLabel *self,
|
||||
int height,
|
||||
@@ -1183,7 +1221,7 @@ get_width_for_height (GtkLabel *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
int min, max, mid, text_width, text_height;
|
||||
int min, max;
|
||||
|
||||
/* Can't use a measuring layout here, because we need to force
|
||||
* ellipsizing mode */
|
||||
@@ -1198,24 +1236,19 @@ get_width_for_height (GtkLabel *self,
|
||||
pango_layout_set_width (layout, -1);
|
||||
pango_layout_get_size (layout, &max, NULL);
|
||||
|
||||
min = PANGO_PIXELS_CEIL (min);
|
||||
max = PANGO_PIXELS_CEIL (max);
|
||||
while (min < max)
|
||||
/* first, do natural width */
|
||||
if (self->natural_wrap_mode == GTK_NATURAL_WRAP_NONE)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
pango_layout_set_width (layout, mid * PANGO_SCALE);
|
||||
pango_layout_get_size (layout, &text_width, &text_height);
|
||||
text_width = PANGO_PIXELS_CEIL (text_width);
|
||||
if (text_width > mid)
|
||||
min = mid = text_width;
|
||||
else if (text_height > height)
|
||||
min = mid + 1;
|
||||
else
|
||||
max = mid;
|
||||
*natural_width = max;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->natural_wrap_mode == GTK_NATURAL_WRAP_WORD)
|
||||
pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
|
||||
*natural_width = my_pango_layout_get_width_for_height (layout, height, min, max);
|
||||
}
|
||||
|
||||
*natural_width = min * PANGO_SCALE;
|
||||
|
||||
/* then, do minimum width */
|
||||
if (self->ellipsize != PANGO_ELLIPSIZE_NONE)
|
||||
{
|
||||
g_object_unref (layout);
|
||||
@@ -1223,10 +1256,15 @@ get_width_for_height (GtkLabel *self,
|
||||
pango_layout_get_size (layout, minimum_width, NULL);
|
||||
*minimum_width = MAX (*minimum_width, minimum_default);
|
||||
}
|
||||
else
|
||||
else if (self->natural_wrap_mode == GTK_NATURAL_WRAP_INHERIT)
|
||||
{
|
||||
*minimum_width = *natural_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
pango_layout_set_wrap (layout, self->wrap_mode);
|
||||
*minimum_width = my_pango_layout_get_width_for_height (layout, height, min, *natural_width);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
@@ -2356,6 +2394,9 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
* This only affects the formatting if line wrapping is on (see the
|
||||
* [property@Gtk.Label:wrap] property). The default is %PANGO_WRAP_WORD,
|
||||
* which means wrap on word boundaries.
|
||||
*
|
||||
* For sizing behavior, also consider the [property@Gtk.Label:natural-wrap-mode]
|
||||
* property.
|
||||
*/
|
||||
label_props[PROP_WRAP_MODE] =
|
||||
g_param_spec_enum ("wrap-mode",
|
||||
@@ -2365,6 +2406,27 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
PANGO_WRAP_WORD,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkLabel:natural-wrap-mode: (attributes org.gtk.Property.get=gtk_label_get_natural_wrap_mode org.gtk.Property.set=gtk_label_set_natural_wrap_mode)
|
||||
*
|
||||
* Select the line wrapping for the natural size request.
|
||||
*
|
||||
* This only affects the natural size requested. For the actual wrapping used,
|
||||
* see the [property@Gtk.Label:wrap-mode] property.
|
||||
*
|
||||
* The default is %GTK_NATURAL_WRAP_INHERIT, which inherits the behavior of the
|
||||
* [property@Gtk.Label:wrap-mode] property.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
label_props[PROP_NATURAL_WRAP_MODE] =
|
||||
g_param_spec_enum ("natural-wrap-mode",
|
||||
P_("Natural wrap mode"),
|
||||
P_("If wrap is set, controls linewrapping for natural size requests"),
|
||||
GTK_TYPE_NATURAL_WRAP_MODE,
|
||||
GTK_NATURAL_WRAP_INHERIT,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkLabel:selectable: (attributes org.gtk.Property.get=gtk_label_get_selectable og.gtk.Property.set=gtk_label_set_selectable)
|
||||
*
|
||||
@@ -2431,7 +2493,7 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
*
|
||||
* If this property is set to -1, the width will be calculated automatically.
|
||||
*
|
||||
* See the section on [text layout](#text-layout) for details of how
|
||||
* See the section on [text layout](class.Label.html#text-layout) for details of how
|
||||
* [property@Gtk.Label:width-chars] and [property@Gtk.Label:max-width-chars]
|
||||
* determine the width of ellipsized and wrapped labels.
|
||||
*/
|
||||
@@ -2467,7 +2529,7 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
*
|
||||
* If this property is set to -1, the width will be calculated automatically.
|
||||
*
|
||||
* See the section on [text layout](#text-layout) for details of how
|
||||
* See the section on [text layout](class.Label.html#text-layout) for details of how
|
||||
* [property@Gtk.Label:width-chars] and [property@Gtk.Label:max-width-chars]
|
||||
* determine the width of ellipsized and wrapped labels.
|
||||
*/
|
||||
@@ -3979,6 +4041,9 @@ gtk_label_get_wrap (GtkLabel *self)
|
||||
* This only affects the label if line wrapping is on. (See
|
||||
* [method@Gtk.Label.set_wrap]) The default is %PANGO_WRAP_WORD
|
||||
* which means wrap on word boundaries.
|
||||
*
|
||||
* For sizing behavior, also consider the [property@Gtk.Label:natural-wrap-mode]
|
||||
* property.
|
||||
*/
|
||||
void
|
||||
gtk_label_set_wrap_mode (GtkLabel *self,
|
||||
@@ -4003,16 +4068,63 @@ gtk_label_set_wrap_mode (GtkLabel *self,
|
||||
*
|
||||
* See [method@Gtk.Label.set_wrap_mode].
|
||||
*
|
||||
* Returns: %TRUE if the lines of the label are automatically wrapped.
|
||||
* Returns: the line wrap mode
|
||||
*/
|
||||
PangoWrapMode
|
||||
gtk_label_get_wrap_mode (GtkLabel *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LABEL (self), FALSE);
|
||||
g_return_val_if_fail (GTK_IS_LABEL (self), PANGO_WRAP_WORD);
|
||||
|
||||
return self->wrap_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_label_set_natural_wrap_mode: (attributes org.gtk.Method.set_property=natural-wrap-mode)
|
||||
* @self: a `GtkLabel`
|
||||
* @wrap_mode: the line wrapping mode
|
||||
*
|
||||
* Select the line wrapping for the natural size request.
|
||||
*
|
||||
* This only affects the natural size requested, for the actual wrapping used,
|
||||
* see the [property@Gtk.Label:wrap-mode] property.
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
void
|
||||
gtk_label_set_natural_wrap_mode (GtkLabel *self,
|
||||
GtkNaturalWrapMode wrap_mode)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_LABEL (self));
|
||||
|
||||
if (self->natural_wrap_mode != wrap_mode)
|
||||
{
|
||||
self->natural_wrap_mode = wrap_mode;
|
||||
g_object_notify_by_pspec (G_OBJECT (self), label_props[PROP_NATURAL_WRAP_MODE]);
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_label_get_natural_wrap_mode: (attributes org.gtk.Method.get_property=natural-wrap-mode)
|
||||
* @self: a `GtkLabel`
|
||||
*
|
||||
* Returns line wrap mode used by the label.
|
||||
*
|
||||
* See [method@Gtk.Label.set_natural_wrap_mode].
|
||||
*
|
||||
* Returns: the natural line wrap mode
|
||||
*
|
||||
* Since: 4.6
|
||||
*/
|
||||
GtkNaturalWrapMode
|
||||
gtk_label_get_natural_wrap_mode (GtkLabel *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LABEL (self), GTK_NATURAL_WRAP_INHERIT);
|
||||
|
||||
return self->natural_wrap_mode;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_clear_layout (GtkLabel *self)
|
||||
{
|
||||
|
||||
@@ -122,6 +122,11 @@ void gtk_label_set_wrap_mode (GtkLabel *self,
|
||||
PangoWrapMode wrap_mode);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
PangoWrapMode gtk_label_get_wrap_mode (GtkLabel *self);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
void gtk_label_set_natural_wrap_mode (GtkLabel *self,
|
||||
GtkNaturalWrapMode wrap_mode);
|
||||
GDK_AVAILABLE_IN_4_6
|
||||
GtkNaturalWrapMode gtk_label_get_natural_wrap_mode(GtkLabel *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_label_set_selectable (GtkLabel *self,
|
||||
gboolean setting);
|
||||
|
||||
+1
-1
@@ -1078,7 +1078,7 @@ gtk_list_box_set_adjustment (GtkListBox *box,
|
||||
* Gets the adjustment (if any) that the widget uses to
|
||||
* for vertical scrolling.
|
||||
*
|
||||
* Returns: (transfer none): the adjustment
|
||||
* Returns: (transfer none) (nullable): the adjustment
|
||||
*/
|
||||
GtkAdjustment *
|
||||
gtk_list_box_get_adjustment (GtkListBox *box)
|
||||
|
||||
+1
-1
@@ -535,7 +535,7 @@ gtk_lock_button_new (GPermission *permission)
|
||||
*
|
||||
* Obtains the `GPermission` object that controls @button.
|
||||
*
|
||||
* Returns: (transfer none): the `GPermission` of @button
|
||||
* Returns: (transfer none) (nullable): the `GPermission` of @button
|
||||
*/
|
||||
GPermission *
|
||||
gtk_lock_button_get_permission (GtkLockButton *button)
|
||||
|
||||
+14
-3
@@ -68,6 +68,7 @@
|
||||
#include "gtknative.h"
|
||||
#include "gtkpopcountprivate.h"
|
||||
|
||||
#include "inspector/init.h"
|
||||
#include "inspector/window.h"
|
||||
|
||||
#include "gdk/gdkeventsprivate.h"
|
||||
@@ -566,6 +567,8 @@ do_post_parse_initialization (void)
|
||||
g_signal_connect (display_manager, "notify::default-display",
|
||||
G_CALLBACK (default_display_notify_cb),
|
||||
NULL);
|
||||
|
||||
gtk_inspector_register_extension ();
|
||||
}
|
||||
|
||||
#ifdef G_PLATFORM_WIN32
|
||||
@@ -750,9 +753,15 @@ gtk_is_initialized (void)
|
||||
* you can use it to update the default text direction as follows:
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* setlocale (LC_ALL, new_locale);
|
||||
* direction = gtk_get_locale_direction ();
|
||||
* gtk_widget_set_default_direction (direction);
|
||||
* #include <locale.h>
|
||||
*
|
||||
* static void
|
||||
* update_locale (const char *new_locale)
|
||||
* {
|
||||
* setlocale (LC_ALL, new_locale);
|
||||
* GtkTextDirection direction = gtk_get_locale_direction ();
|
||||
* gtk_widget_set_default_direction (direction);
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* Returns: the `GtkTextDirection` of the current locale
|
||||
@@ -951,6 +960,7 @@ rewrite_event_for_surface (GdkEvent *event,
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
gdk_touchpad_event_get_deltas (event, &dx, &dy);
|
||||
return gdk_touchpad_event_new_swipe (new_surface,
|
||||
gdk_event_get_event_sequence (event),
|
||||
gdk_event_get_device (event),
|
||||
gdk_event_get_time (event),
|
||||
gdk_event_get_modifier_state (event),
|
||||
@@ -961,6 +971,7 @@ rewrite_event_for_surface (GdkEvent *event,
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
gdk_touchpad_event_get_deltas (event, &dx, &dy);
|
||||
return gdk_touchpad_event_new_pinch (new_surface,
|
||||
gdk_event_get_event_sequence (event),
|
||||
gdk_event_get_device (event),
|
||||
gdk_event_get_time (event),
|
||||
gdk_event_get_modifier_state (event),
|
||||
|
||||
@@ -45,8 +45,7 @@
|
||||
*
|
||||
* widgets = gtk_widget_observe_children (widget);
|
||||
*
|
||||
* controllers = gtk_map_list_model_new (G_TYPE_LIST_MODEL,
|
||||
* widgets,
|
||||
* controllers = gtk_map_list_model_new (widgets,
|
||||
* map_to_controllers,
|
||||
* NULL, NULL);
|
||||
*
|
||||
|
||||
+4
-2
@@ -1028,6 +1028,7 @@ gtk_menu_button_set_icon_name (GtkMenuButton *menu_button,
|
||||
*/
|
||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (menu_button->button),
|
||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, menu_button, NULL,
|
||||
GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, menu_button, NULL,
|
||||
-1);
|
||||
|
||||
image_widget = g_object_new (GTK_TYPE_IMAGE,
|
||||
@@ -1059,7 +1060,7 @@ gtk_menu_button_set_icon_name (GtkMenuButton *menu_button,
|
||||
*
|
||||
* Gets the name of the icon shown in the button.
|
||||
*
|
||||
* Returns: the name of the icon shown in the button
|
||||
* Returns: (nullable): the name of the icon shown in the button
|
||||
*/
|
||||
const char *
|
||||
gtk_menu_button_get_icon_name (GtkMenuButton *menu_button)
|
||||
@@ -1164,6 +1165,7 @@ gtk_menu_button_set_label (GtkMenuButton *menu_button,
|
||||
|
||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (menu_button->button),
|
||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, menu_button->label_widget, NULL,
|
||||
GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, menu_button->label_widget, NULL,
|
||||
-1);
|
||||
|
||||
menu_button->image_widget = NULL;
|
||||
@@ -1182,7 +1184,7 @@ gtk_menu_button_set_label (GtkMenuButton *menu_button,
|
||||
*
|
||||
* Gets the label shown in the button
|
||||
*
|
||||
* Returns: the label shown in the button
|
||||
* Returns: (nullable): the label shown in the button
|
||||
*/
|
||||
const char *
|
||||
gtk_menu_button_get_label (GtkMenuButton *menu_button)
|
||||
|
||||
@@ -1873,7 +1873,7 @@ gtk_mount_operation_set_parent (GtkMountOperation *op,
|
||||
*
|
||||
* Gets the transient parent used by the `GtkMountOperation`.
|
||||
*
|
||||
* Returns: (transfer none): the transient parent for windows shown by @op
|
||||
* Returns: (transfer none) (nullable): the transient parent for windows shown by @op
|
||||
*/
|
||||
GtkWindow *
|
||||
gtk_mount_operation_get_parent (GtkMountOperation *op)
|
||||
|
||||
@@ -396,7 +396,7 @@ gtk_multi_selection_new (GListModel *model)
|
||||
*
|
||||
* Returns the underlying model of @self.
|
||||
*
|
||||
* Returns: (transfer none): the underlying model
|
||||
* Returns: (transfer none) (nullable): the underlying model
|
||||
*/
|
||||
GListModel *
|
||||
gtk_multi_selection_get_model (GtkMultiSelection *self)
|
||||
|
||||
+1
-1
@@ -267,7 +267,7 @@ gtk_native_get_surface_transform (GtkNative *self,
|
||||
*
|
||||
* Finds the `GtkNative` associated with the surface.
|
||||
*
|
||||
* Returns: (transfer none): the `GtkNative` that is associated with @surface
|
||||
* Returns: (transfer none) (nullable): the `GtkNative` that is associated with @surface
|
||||
*/
|
||||
GtkNative *
|
||||
gtk_native_get_for_surface (GdkSurface *surface)
|
||||
|
||||
@@ -242,7 +242,7 @@ gtk_no_selection_new (GListModel *model)
|
||||
*
|
||||
* Gets the model that @self is wrapping.
|
||||
*
|
||||
* Returns: (transfer none): The model being wrapped
|
||||
* Returns: (transfer none) (nullable): The model being wrapped
|
||||
*/
|
||||
GListModel *
|
||||
gtk_no_selection_get_model (GtkNoSelection *self)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
*
|
||||
* These buttons and sensors have no implicit meaning, and by default they
|
||||
* perform no action. `GtkPadController` is provided to map those to
|
||||
* `GAction` objects, thus letting the application give them a more
|
||||
* [iface@Gio.Action] objects, thus letting the application give them a more
|
||||
* semantic meaning.
|
||||
*
|
||||
* Buttons and sensors are not constrained to triggering a single action,
|
||||
@@ -41,10 +41,10 @@
|
||||
* different modes. See [method@Gdk.DevicePad.get_n_groups] and
|
||||
* [method@Gdk.DevicePad.get_group_n_modes].
|
||||
*
|
||||
* Each of the actions that a given button/strip/ring performs for a given
|
||||
* mode is defined by a [struct@Gtk.PadActionEntry]. It contains an action
|
||||
* name that will be looked up in the given `GActionGroup` and activated
|
||||
* whenever the specified input element and mode are triggered.
|
||||
* Each of the actions that a given button/strip/ring performs for a given mode
|
||||
* is defined by a [struct@Gtk.PadActionEntry]. It contains an action name that
|
||||
* will be looked up in the given [iface@Gio.ActionGroup] and activated whenever
|
||||
* the specified input element and mode are triggered.
|
||||
*
|
||||
* A simple example of `GtkPadController` usage: Assigning button 1 in all
|
||||
* modes and pad devices to an "invert-selection" action:
|
||||
|
||||
@@ -729,7 +729,7 @@ gtk_password_entry_set_extra_menu (GtkPasswordEntry *entry,
|
||||
*
|
||||
* Gets the menu model set with gtk_password_entry_set_extra_menu().
|
||||
*
|
||||
* Returns: (transfer none): (nullable): the menu model
|
||||
* Returns: (transfer none) (nullable): the menu model
|
||||
*/
|
||||
GMenuModel *
|
||||
gtk_password_entry_get_extra_menu (GtkPasswordEntry *entry)
|
||||
|
||||
+1
-1
@@ -2103,7 +2103,7 @@ gtk_popover_buildable_init (GtkBuildableIface *iface)
|
||||
/**
|
||||
* gtk_popover_set_pointing_to: (attributes org.gtk.Method.set_property=pointing-to)
|
||||
* @popover: a `GtkPopover`
|
||||
* @rect: rectangle to point to
|
||||
* @rect: (nullable): rectangle to point to
|
||||
*
|
||||
* Sets the rectangle that @popover points to.
|
||||
*
|
||||
|
||||
@@ -819,7 +819,7 @@ gtk_popover_menu_set_menu_model (GtkPopoverMenu *popover,
|
||||
*
|
||||
* Returns the menu model used to populate the popover.
|
||||
*
|
||||
* Returns: (transfer none): the menu model of @popover
|
||||
* Returns: (transfer none) (nullable): the menu model of @popover
|
||||
*/
|
||||
GMenuModel *
|
||||
gtk_popover_menu_get_menu_model (GtkPopoverMenu *popover)
|
||||
|
||||
@@ -746,7 +746,7 @@ gtk_popover_menu_bar_set_menu_model (GtkPopoverMenuBar *bar,
|
||||
*
|
||||
* Returns the model from which the contents of @bar are taken.
|
||||
*
|
||||
* Returns: (transfer none): a `GMenuModel`
|
||||
* Returns: (transfer none) (nullable): a `GMenuModel`
|
||||
*/
|
||||
GMenuModel *
|
||||
gtk_popover_menu_bar_get_menu_model (GtkPopoverMenuBar *bar)
|
||||
|
||||
@@ -154,7 +154,7 @@ gtk_print_settings_copy (GtkPrintSettings *other)
|
||||
*
|
||||
* Looks up the string value associated with @key.
|
||||
*
|
||||
* Returns: the string value for @key
|
||||
* Returns: (nullable): the string value for @key
|
||||
*/
|
||||
const char *
|
||||
gtk_print_settings_get (GtkPrintSettings *settings,
|
||||
@@ -480,7 +480,7 @@ gtk_print_settings_foreach (GtkPrintSettings *settings,
|
||||
* Convenience function to obtain the value of
|
||||
* %GTK_PRINT_SETTINGS_PRINTER.
|
||||
*
|
||||
* Returns: the printer name
|
||||
* Returns: (nullable): the printer name
|
||||
*/
|
||||
const char *
|
||||
gtk_print_settings_get_printer (GtkPrintSettings *settings)
|
||||
@@ -574,7 +574,7 @@ gtk_print_settings_set_orientation (GtkPrintSettings *settings,
|
||||
* Gets the value of %GTK_PRINT_SETTINGS_PAPER_FORMAT,
|
||||
* converted to a `GtkPaperSize`.
|
||||
*
|
||||
* Returns: the paper size
|
||||
* Returns: (nullable): the paper size
|
||||
*/
|
||||
GtkPaperSize *
|
||||
gtk_print_settings_get_paper_size (GtkPrintSettings *settings)
|
||||
@@ -779,7 +779,7 @@ gtk_print_settings_set_collate (GtkPrintSettings *settings,
|
||||
*
|
||||
* Gets the value of %GTK_PRINT_SETTINGS_REVERSE.
|
||||
*
|
||||
* Returns: whether to reverse the order of the printed pages
|
||||
* Returns: whether to reverse the order of the printed pages
|
||||
*/
|
||||
gboolean
|
||||
gtk_print_settings_get_reverse (GtkPrintSettings *settings)
|
||||
@@ -1415,7 +1415,7 @@ gtk_print_settings_set_page_ranges (GtkPrintSettings *settings,
|
||||
*
|
||||
* Gets the value of %GTK_PRINT_SETTINGS_DEFAULT_SOURCE.
|
||||
*
|
||||
* Returns: the default source
|
||||
* Returns: (nullable): the default source
|
||||
*/
|
||||
const char *
|
||||
gtk_print_settings_get_default_source (GtkPrintSettings *settings)
|
||||
@@ -1445,7 +1445,7 @@ gtk_print_settings_set_default_source (GtkPrintSettings *settings,
|
||||
*
|
||||
* The set of media types is defined in PWG 5101.1-2002 PWG.
|
||||
*
|
||||
* Returns: the media type
|
||||
* Returns: (nullable): the media type
|
||||
*/
|
||||
const char *
|
||||
gtk_print_settings_get_media_type (GtkPrintSettings *settings)
|
||||
@@ -1475,7 +1475,7 @@ gtk_print_settings_set_media_type (GtkPrintSettings *settings,
|
||||
*
|
||||
* Gets the value of %GTK_PRINT_SETTINGS_DITHER.
|
||||
*
|
||||
* Returns: the dithering that is used
|
||||
* Returns: (nullable): the dithering that is used
|
||||
*/
|
||||
const char *
|
||||
gtk_print_settings_get_dither (GtkPrintSettings *settings)
|
||||
@@ -1503,7 +1503,7 @@ gtk_print_settings_set_dither (GtkPrintSettings *settings,
|
||||
*
|
||||
* Gets the value of %GTK_PRINT_SETTINGS_FINISHINGS.
|
||||
*
|
||||
* Returns: the finishings
|
||||
* Returns: (nullable): the finishings
|
||||
*/
|
||||
const char *
|
||||
gtk_print_settings_get_finishings (GtkPrintSettings *settings)
|
||||
@@ -1531,7 +1531,7 @@ gtk_print_settings_set_finishings (GtkPrintSettings *settings,
|
||||
*
|
||||
* Gets the value of %GTK_PRINT_SETTINGS_OUTPUT_BIN.
|
||||
*
|
||||
* Returns: the output bin
|
||||
* Returns: (nullable): the output bin
|
||||
*/
|
||||
const char *
|
||||
gtk_print_settings_get_output_bin (GtkPrintSettings *settings)
|
||||
|
||||
@@ -1025,6 +1025,7 @@ gtk_progress_bar_set_inverted (GtkProgressBar *pbar,
|
||||
|
||||
pbar->inverted = inverted;
|
||||
|
||||
gtk_widget_queue_allocate (pbar->trough_widget);
|
||||
update_node_classes (pbar);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (pbar), progress_props[PROP_INVERTED]);
|
||||
|
||||
+2
-2
@@ -130,7 +130,7 @@ gtk_scrollable_default_init (GtkScrollableInterface *iface)
|
||||
*
|
||||
* Retrieves the `GtkAdjustment` used for horizontal scrolling.
|
||||
*
|
||||
* Returns: (transfer none): horizontal `GtkAdjustment`.
|
||||
* Returns: (transfer none) (nullable): horizontal `GtkAdjustment`.
|
||||
*/
|
||||
GtkAdjustment *
|
||||
gtk_scrollable_get_hadjustment (GtkScrollable *scrollable)
|
||||
@@ -174,7 +174,7 @@ gtk_scrollable_set_hadjustment (GtkScrollable *scrollable,
|
||||
*
|
||||
* Retrieves the `GtkAdjustment` used for vertical scrolling.
|
||||
*
|
||||
* Returns: (transfer none): vertical `GtkAdjustment`.
|
||||
* Returns: (transfer none) (nullable): vertical `GtkAdjustment`.
|
||||
*/
|
||||
GtkAdjustment *
|
||||
gtk_scrollable_get_vadjustment (GtkScrollable *scrollable)
|
||||
|
||||
+1
-1
@@ -663,7 +663,7 @@ gtk_search_bar_set_key_capture_widget (GtkSearchBar *bar,
|
||||
*
|
||||
* Gets the widget that @bar is capturing key events from.
|
||||
*
|
||||
* Returns: (transfer none): The key capture widget.
|
||||
* Returns: (nullable) (transfer none): The key capture widget.
|
||||
**/
|
||||
GtkWidget *
|
||||
gtk_search_bar_get_key_capture_widget (GtkSearchBar *bar)
|
||||
|
||||
@@ -763,7 +763,7 @@ gtk_search_entry_set_key_capture_widget (GtkSearchEntry *entry,
|
||||
*
|
||||
* Gets the widget that @entry is capturing key events from.
|
||||
*
|
||||
* Returns: (transfer none): The key capture widget.
|
||||
* Returns: (nullable) (transfer none): The key capture widget.
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_search_entry_get_key_capture_widget (GtkSearchEntry *entry)
|
||||
|
||||
@@ -461,9 +461,9 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
* @minimum: (out) (optional): location to store the minimum size
|
||||
* @natural: (out) (optional): location to store the natural size
|
||||
* @minimum_baseline: (out) (optional): location to store the baseline
|
||||
* position for the minimum size
|
||||
* position for the minimum size, or -1 to report no baseline
|
||||
* @natural_baseline: (out) (optional): location to store the baseline
|
||||
* position for the natural size
|
||||
* position for the natural size, or -1 to report no baseline
|
||||
*
|
||||
* Measures @widget in the orientation @orientation and for the given @for_size.
|
||||
*
|
||||
@@ -493,11 +493,7 @@ gtk_widget_measure (GtkWidget *widget,
|
||||
int min_opposite_size;
|
||||
gtk_widget_measure (widget, OPPOSITE_ORIENTATION (orientation), -1, &min_opposite_size, NULL, NULL, NULL);
|
||||
if (for_size < min_opposite_size)
|
||||
{
|
||||
g_critical ("gtk_widget_measure: assertion 'for_size >= minimum opposite size' failed: %u >= %u",
|
||||
for_size, min_opposite_size);
|
||||
for_size = min_opposite_size;
|
||||
}
|
||||
for_size = min_opposite_size;
|
||||
}
|
||||
|
||||
/* This is the main function that checks for a cached size and
|
||||
|
||||
@@ -36,7 +36,7 @@ typedef struct _GtkRequestedSize GtkRequestedSize;
|
||||
*
|
||||
* Represents a request of a screen object in a given orientation. These
|
||||
* are primarily used in container implementations when allocating a natural
|
||||
* size for children calling. See gtk_distribute_natural_allocation().
|
||||
* size for children calling. See [func@distribute_natural_allocation].
|
||||
*/
|
||||
struct _GtkRequestedSize
|
||||
{
|
||||
|
||||
+29
-34
@@ -46,14 +46,14 @@
|
||||
/**
|
||||
* GtkSnapshot:
|
||||
*
|
||||
* `GtkSnapshot` assists in creating `GskRenderNodes` for widgets.
|
||||
* `GtkSnapshot` assists in creating [class@Gsk.RenderNode]s for widgets.
|
||||
*
|
||||
* It functions in a similar way to a cairo context, and maintains a stack
|
||||
* of render nodes and their associated transformations.
|
||||
*
|
||||
* The node at the top of the stack is the one that gtk_snapshot_append_…
|
||||
* functions operate on. Use the gtk_snapshot_push_… functions and
|
||||
* gtk_snapshot_pop() to change the current node.
|
||||
* The node at the top of the stack is the one that `gtk_snapshot_append_…()`
|
||||
* functions operate on. Use the `gtk_snapshot_push_…()` functions and
|
||||
* [method@Snapshot.pop] to change the current node.
|
||||
*
|
||||
* The typical way to obtain a `GtkSnapshot` object is as an argument to
|
||||
* the [vfunc@Gtk.Widget.snapshot] vfunc. If you need to create your own
|
||||
@@ -302,7 +302,7 @@ gtk_snapshot_new (void)
|
||||
* Returns the node that was constructed by @snapshot
|
||||
* and frees @snapshot.
|
||||
*
|
||||
* Returns: (transfer full): a newly-created `GskRenderNode`
|
||||
* Returns: (transfer full): a newly-created [class@Gsk.RenderNode]
|
||||
*/
|
||||
GskRenderNode *
|
||||
gtk_snapshot_free_to_node (GtkSnapshot *snapshot)
|
||||
@@ -324,7 +324,7 @@ gtk_snapshot_free_to_node (GtkSnapshot *snapshot)
|
||||
* Returns a paintable for the node that was
|
||||
* constructed by @snapshot and frees @snapshot.
|
||||
*
|
||||
* Returns: (transfer full): a newly-created `GdkPaintable`
|
||||
* Returns: (transfer full): a newly-created [iface@Gdk.Paintable]
|
||||
*/
|
||||
GdkPaintable *
|
||||
gtk_snapshot_free_to_paintable (GtkSnapshot *snapshot,
|
||||
@@ -955,11 +955,11 @@ gtk_snapshot_collect_gl_shader_texture (GtkSnapshot *snapshot,
|
||||
* @bounds: the rectangle to render into
|
||||
* @take_args: (transfer full): Data block with arguments for the shader.
|
||||
*
|
||||
* Push a `GskGLShaderNode`.
|
||||
* Push a [class@Gsk.GLShaderNode].
|
||||
*
|
||||
* The node uses the given [class@Gsk.GLShader] and uniform values
|
||||
* Additionally this takes a list of @n_children other nodes
|
||||
* which will be passed to the `GskGLShaderNode`.
|
||||
* which will be passed to the [class@Gsk.GLShaderNode].
|
||||
*
|
||||
* The @take_args argument is a block of data to use for uniform
|
||||
* arguments, as per types and offsets defined by the @shader.
|
||||
@@ -1495,7 +1495,7 @@ gtk_snapshot_pop_collect (GtkSnapshot *snapshot)
|
||||
*
|
||||
* After calling this function, it is no longer possible to
|
||||
* add more nodes to @snapshot. The only function that should
|
||||
* be called after this is g_object_unref().
|
||||
* be called after this is [method@GObject.Object.unref].
|
||||
*
|
||||
* Returns: (transfer full): the constructed `GskRenderNode`
|
||||
*/
|
||||
@@ -1530,7 +1530,7 @@ gtk_snapshot_to_node (GtkSnapshot *snapshot)
|
||||
*
|
||||
* After calling this function, it is no longer possible to
|
||||
* add more nodes to @snapshot. The only function that should
|
||||
* be called after this is g_object_unref().
|
||||
* be called after this is [method@GObject.Object.unref].
|
||||
*
|
||||
* Returns: (transfer full): a new `GdkPaintable`
|
||||
*/
|
||||
@@ -1585,7 +1585,7 @@ gtk_snapshot_pop (GtkSnapshot *snapshot)
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
*
|
||||
* Removes the top element from the stack of render nodes and
|
||||
* adds it to the nearest `GskGLShaderNode` below it.
|
||||
* adds it to the nearest [class@Gsk.GLShaderNode] below it.
|
||||
*
|
||||
* This must be called the same number of times as the number
|
||||
* of textures is needed for the shader in
|
||||
@@ -1610,12 +1610,12 @@ gtk_snapshot_gl_shader_pop_texture (GtkSnapshot *snapshot)
|
||||
*
|
||||
* When [method@Gtk.Snapshot.restore] is called, @snapshot will
|
||||
* be restored to the saved state. Multiple calls to
|
||||
* gtk_snapshot_save() and gtk_snapshot_restore() can be nested;
|
||||
* each call to gtk_snapshot_restore() restores the state from
|
||||
* the matching paired gtk_snapshot_save().
|
||||
* [method@Snapshot.save] and [class@Snapshot.restore] can be nested;
|
||||
* each call to `gtk_snapshot_restore()` restores the state from
|
||||
* the matching paired `gtk_snapshot_save()`.
|
||||
*
|
||||
* It is necessary to clear all saved states with corresponding
|
||||
* calls to gtk_snapshot_restore().
|
||||
* calls to `gtk_snapshot_restore()`.
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_save (GtkSnapshot *snapshot)
|
||||
@@ -1633,7 +1633,7 @@ gtk_snapshot_save (GtkSnapshot *snapshot)
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
*
|
||||
* Restores @snapshot to the state saved by a preceding call to
|
||||
* gtk_snapshot_save() and removes that state from the stack of
|
||||
* [method@Snapshot.save] and removes that state from the stack of
|
||||
* saved states.
|
||||
*/
|
||||
void
|
||||
@@ -1882,7 +1882,7 @@ gtk_snapshot_append_node (GtkSnapshot *snapshot,
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @bounds: the bounds for the new node
|
||||
*
|
||||
* Creates a new `GskCairoNode` and appends it to the current
|
||||
* Creates a new [class@Gsk.CairoNode] and appends it to the current
|
||||
* render node of @snapshot, without changing the current node.
|
||||
*
|
||||
* Returns: a `cairo_t` suitable for drawing the contents of
|
||||
@@ -1918,7 +1918,7 @@ gtk_snapshot_append_cairo (GtkSnapshot *snapshot,
|
||||
/**
|
||||
* gtk_snapshot_append_texture:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @texture: the `GdkTexture` to render
|
||||
* @texture: the texture to render
|
||||
* @bounds: the bounds for the new node
|
||||
*
|
||||
* Creates a new render node drawing the @texture
|
||||
@@ -1948,7 +1948,7 @@ gtk_snapshot_append_texture (GtkSnapshot *snapshot,
|
||||
/**
|
||||
* gtk_snapshot_append_color:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @color: the `GdkRGBA` to draw
|
||||
* @color: the color to draw
|
||||
* @bounds: the bounds for the new node
|
||||
*
|
||||
* Creates a new render node drawing the @color into the
|
||||
@@ -1982,7 +1982,7 @@ gtk_snapshot_append_color (GtkSnapshot *snapshot,
|
||||
/**
|
||||
* gtk_snapshot_render_background:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @context: the `GtkStyleContext` to use
|
||||
* @context: the style context that defines the background
|
||||
* @x: X origin of the rectangle
|
||||
* @y: Y origin of the rectangle
|
||||
* @width: rectangle width
|
||||
@@ -2014,7 +2014,7 @@ gtk_snapshot_render_background (GtkSnapshot *snapshot,
|
||||
/**
|
||||
* gtk_snapshot_render_frame:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @context: the `GtkStyleContext` to use
|
||||
* @context: the style context that defines the frame
|
||||
* @x: X origin of the rectangle
|
||||
* @y: Y origin of the rectangle
|
||||
* @width: rectangle width
|
||||
@@ -2046,7 +2046,7 @@ gtk_snapshot_render_frame (GtkSnapshot *snapshot,
|
||||
/**
|
||||
* gtk_snapshot_render_focus:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @context: the `GtkStyleContext` to use
|
||||
* @context: the style context that defines the focus ring
|
||||
* @x: X origin of the rectangle
|
||||
* @y: Y origin of the rectangle
|
||||
* @width: rectangle width
|
||||
@@ -2078,7 +2078,7 @@ gtk_snapshot_render_focus (GtkSnapshot *snapshot,
|
||||
/**
|
||||
* gtk_snapshot_render_layout:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @context: the `GtkStyleContext` to use
|
||||
* @context: the style context that defines the text
|
||||
* @x: X origin of the rectangle
|
||||
* @y: Y origin of the rectangle
|
||||
* @layout: the `PangoLayout` to render
|
||||
@@ -2152,8 +2152,7 @@ gtk_snapshot_append_text (GtkSnapshot *snapshot,
|
||||
* @bounds: the rectangle to render the linear gradient into
|
||||
* @start_point: the point at which the linear gradient will begin
|
||||
* @end_point: the point at which the linear gradient will finish
|
||||
* @stops: (array length=n_stops): a pointer to an array of `GskColorStop`
|
||||
* defining the gradient
|
||||
* @stops: (array length=n_stops): the color stops defining the gradient
|
||||
* @n_stops: the number of elements in @stops
|
||||
*
|
||||
* Appends a linear gradient node with the given stops to @snapshot.
|
||||
@@ -2220,8 +2219,7 @@ gtk_snapshot_append_linear_gradient (GtkSnapshot *snapshot,
|
||||
* @bounds: the rectangle to render the linear gradient into
|
||||
* @start_point: the point at which the linear gradient will begin
|
||||
* @end_point: the point at which the linear gradient will finish
|
||||
* @stops: (array length=n_stops): a pointer to an array of `GskColorStop`
|
||||
* defining the gradient
|
||||
* @stops: (array length=n_stops): the color stops defining the gradient
|
||||
* @n_stops: the number of elements in @stops
|
||||
*
|
||||
* Appends a repeating linear gradient node with the given stops to @snapshot.
|
||||
@@ -2289,8 +2287,7 @@ gtk_snapshot_append_repeating_linear_gradient (GtkSnapshot *snapshot,
|
||||
* @center: the center point of the conic gradient
|
||||
* @rotation: the clockwise rotation in degrees of the starting angle.
|
||||
* 0 means the starting angle is the top.
|
||||
* @stops: (array length=n_stops): a pointer to an array of `GskColorStop`
|
||||
* defining the gradient
|
||||
* @stops: (array length=n_stops): the color stops defining the gradient
|
||||
* @n_stops: the number of elements in @stops
|
||||
*
|
||||
* Appends a conic gradient node with the given stops to @snapshot.
|
||||
@@ -2352,8 +2349,7 @@ gtk_snapshot_append_conic_gradient (GtkSnapshot *snapshot,
|
||||
* @vradius: the vertical radius
|
||||
* @start: the start position (on the horizontal axis)
|
||||
* @end: the end position (on the horizontal axis)
|
||||
* @stops: (array length=n_stops): a pointer to an array of `GskColorStop`
|
||||
* defining the gradient
|
||||
* @stops: (array length=n_stops): the color stops defining the gradient
|
||||
* @n_stops: the number of elements in @stops
|
||||
*
|
||||
* Appends a radial gradient node with the given stops to @snapshot.
|
||||
@@ -2426,8 +2422,7 @@ gtk_snapshot_append_radial_gradient (GtkSnapshot *snapshot,
|
||||
* @vradius: the vertical radius
|
||||
* @start: the start position (on the horizontal axis)
|
||||
* @end: the end position (on the horizontal axis)
|
||||
* @stops: (array length=n_stops): a pointer to an array of `GskColorStop`
|
||||
* defining the gradient
|
||||
* @stops: (array length=n_stops): the color stops defining the gradient
|
||||
* @n_stops: the number of elements in @stops
|
||||
*
|
||||
* Appends a repeating radial gradient node with the given stops to @snapshot.
|
||||
@@ -2493,7 +2488,7 @@ gtk_snapshot_append_repeating_radial_gradient (GtkSnapshot *snapshot,
|
||||
/**
|
||||
* gtk_snapshot_append_border:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @outline: a `GskRoundedRect` describing the outline of the border
|
||||
* @outline: the outline of the border
|
||||
* @border_width: (array fixed-size=4): the stroke width of the border on
|
||||
* the top, right, bottom and left side respectively.
|
||||
* @border_color: (array fixed-size=4): the color used on the top, right,
|
||||
|
||||
@@ -981,11 +981,8 @@ gtk_text_history_selection_changed (GtkTextHistory *self,
|
||||
return_if_applying (self);
|
||||
return_if_irreversible (self);
|
||||
|
||||
if (self->in_user == 0 && self->irreversible == 0)
|
||||
{
|
||||
self->selection.insert = CLAMP (selection_insert, -1, G_MAXINT);
|
||||
self->selection.bound = CLAMP (selection_bound, -1, G_MAXINT);
|
||||
}
|
||||
self->selection.insert = CLAMP (selection_insert, -1, G_MAXINT);
|
||||
self->selection.bound = CLAMP (selection_bound, -1, G_MAXINT);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+3
-23
@@ -1157,7 +1157,6 @@ totally_invisible_line (GtkTextLayout *layout,
|
||||
GtkTextIter *iter)
|
||||
{
|
||||
GtkTextLineSegment *seg;
|
||||
int bytes = 0;
|
||||
|
||||
/* Check if the first char is visible, if so we are partially visible.
|
||||
* Note that we have to check this since we don't know the current
|
||||
@@ -1168,22 +1167,12 @@ totally_invisible_line (GtkTextLayout *layout,
|
||||
if (!_gtk_text_btree_char_is_invisible (iter))
|
||||
return FALSE;
|
||||
|
||||
bytes = 0;
|
||||
seg = line->segments;
|
||||
|
||||
while (seg != NULL)
|
||||
{
|
||||
if (seg->byte_count > 0)
|
||||
bytes += seg->byte_count;
|
||||
|
||||
/* Note that these two tests can cause us to bail out
|
||||
* when we shouldn't, because a higher-priority tag
|
||||
* may override these settings. However the important
|
||||
* thing is to only invisible really-invisible lines, rather
|
||||
* than to invisible all really-invisible lines.
|
||||
*/
|
||||
|
||||
else if (seg->type == >k_text_toggle_on_type)
|
||||
if (seg->byte_count <= 0 &&
|
||||
seg->type == >k_text_toggle_on_type)
|
||||
{
|
||||
invalidate_cached_style (layout);
|
||||
|
||||
@@ -2297,7 +2286,7 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
|
||||
char *text;
|
||||
int text_pixel_width;
|
||||
PangoAttrList *attrs;
|
||||
int text_allocated, layout_byte_offset, buffer_byte_offset;
|
||||
int text_allocated, layout_byte_offset;
|
||||
PangoRectangle extents;
|
||||
gboolean para_values_set = FALSE;
|
||||
GSList *cursor_byte_offsets = NULL;
|
||||
@@ -2356,7 +2345,6 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
|
||||
|
||||
/* Iterate over segments, creating display chunks for them, and updating the tags array. */
|
||||
layout_byte_offset = 0; /* current length of layout text (includes preedit, does not include invisible text) */
|
||||
buffer_byte_offset = 0; /* position in the buffer line */
|
||||
seg = _gtk_text_iter_get_any_segment (&iter);
|
||||
tags = _gtk_text_btree_get_tags (&iter);
|
||||
initial_toggle_segments = TRUE;
|
||||
@@ -2406,7 +2394,6 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
|
||||
{
|
||||
memcpy (text + layout_byte_offset, seg->body.chars, seg->byte_count);
|
||||
layout_byte_offset += seg->byte_count;
|
||||
buffer_byte_offset += seg->byte_count;
|
||||
bytes += seg->byte_count;
|
||||
}
|
||||
else if (seg->type == >k_text_right_mark_type ||
|
||||
@@ -2458,7 +2445,6 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
|
||||
memcpy (text + layout_byte_offset, _gtk_text_unknown_char_utf8,
|
||||
seg->byte_count);
|
||||
layout_byte_offset += seg->byte_count;
|
||||
buffer_byte_offset += seg->byte_count;
|
||||
}
|
||||
else if (seg->type == >k_text_child_type)
|
||||
{
|
||||
@@ -2473,7 +2459,6 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
|
||||
memcpy (text + layout_byte_offset, gtk_text_child_anchor_get_replacement (seg->body.child.obj),
|
||||
seg->byte_count);
|
||||
layout_byte_offset += seg->byte_count;
|
||||
buffer_byte_offset += seg->byte_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2482,11 +2467,6 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
|
||||
}
|
||||
|
||||
} /* if (segment was visible) */
|
||||
else
|
||||
{
|
||||
/* Invisible segment */
|
||||
buffer_byte_offset += seg->byte_count;
|
||||
}
|
||||
|
||||
release_style (layout, style);
|
||||
}
|
||||
|
||||
+1
-1
@@ -346,7 +346,7 @@ gtk_text_mark_get_deleted (GtkTextMark *mark)
|
||||
*
|
||||
* Returns %NULL if the mark is deleted.
|
||||
*
|
||||
* Returns: (transfer none): the mark’s `GtkTextBuffer`
|
||||
* Returns: (transfer none) (nullable): the mark’s `GtkTextBuffer`
|
||||
*/
|
||||
GtkTextBuffer*
|
||||
gtk_text_mark_get_buffer (GtkTextMark *mark)
|
||||
|
||||
+48
-4
@@ -231,8 +231,13 @@ struct _GtkTextViewPrivate
|
||||
guint first_validate_idle; /* Idle to revalidate onscreen portion, runs before resize */
|
||||
guint incremental_validate_idle; /* Idle to revalidate offscreen portions, runs after redraw */
|
||||
|
||||
/* Mark for drop target */
|
||||
GtkTextMark *dnd_mark;
|
||||
|
||||
/* Mark for selection of drag source */
|
||||
GtkTextMark *dnd_drag_begin_mark;
|
||||
GtkTextMark *dnd_drag_end_mark;
|
||||
|
||||
GtkIMContext *im_context;
|
||||
GtkWidget *popup_menu;
|
||||
GMenuModel *extra_menu;
|
||||
@@ -8056,8 +8061,26 @@ static void
|
||||
dnd_finished_cb (GdkDrag *drag,
|
||||
GtkTextView *self)
|
||||
{
|
||||
if (gdk_drag_get_selected_action (drag) == GDK_ACTION_MOVE)
|
||||
gtk_text_buffer_delete_selection (self->priv->buffer, TRUE, self->priv->editable);
|
||||
GtkTextBuffer *buffer = self->priv->buffer;
|
||||
|
||||
if (self->priv->dnd_drag_begin_mark)
|
||||
{
|
||||
if (gdk_drag_get_selected_action (drag) == GDK_ACTION_MOVE)
|
||||
{
|
||||
{
|
||||
GtkTextIter begin, end;
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &begin, self->priv->dnd_drag_begin_mark);
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &end, self->priv->dnd_drag_end_mark);
|
||||
gtk_text_buffer_delete (buffer, &begin, &end);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_text_buffer_delete_mark (buffer, self->priv->dnd_drag_begin_mark);
|
||||
gtk_text_buffer_delete_mark (buffer, self->priv->dnd_drag_end_mark);
|
||||
self->priv->dnd_drag_begin_mark = NULL;
|
||||
self->priv->dnd_drag_end_mark = NULL;
|
||||
}
|
||||
|
||||
self->priv->drag = NULL;
|
||||
}
|
||||
@@ -8067,6 +8090,16 @@ dnd_cancel_cb (GdkDrag *drag,
|
||||
GdkDragCancelReason reason,
|
||||
GtkTextView *self)
|
||||
{
|
||||
GtkTextBuffer *buffer = self->priv->buffer;
|
||||
|
||||
if (self->priv->dnd_drag_begin_mark)
|
||||
{
|
||||
gtk_text_buffer_delete_mark (buffer, self->priv->dnd_drag_begin_mark);
|
||||
gtk_text_buffer_delete_mark (buffer, self->priv->dnd_drag_end_mark);
|
||||
self->priv->dnd_drag_begin_mark = NULL;
|
||||
self->priv->dnd_drag_end_mark = NULL;
|
||||
}
|
||||
|
||||
self->priv->drag = NULL;
|
||||
}
|
||||
|
||||
@@ -8108,6 +8141,9 @@ gtk_text_view_start_selection_dnd (GtkTextView *text_view,
|
||||
paintable = gtk_text_util_create_rich_drag_icon (widget, buffer, &start, &end);
|
||||
gtk_drag_icon_set_from_paintable (drag, paintable, 0, 0);
|
||||
g_object_unref (paintable);
|
||||
|
||||
text_view->priv->dnd_drag_begin_mark = gtk_text_buffer_create_mark (buffer, NULL, &start, TRUE);
|
||||
text_view->priv->dnd_drag_end_mark = gtk_text_buffer_create_mark (buffer, NULL, &end, TRUE);
|
||||
}
|
||||
|
||||
text_view->priv->drag = drag;
|
||||
@@ -10101,7 +10137,11 @@ gtk_text_view_real_undo (GtkWidget *widget,
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
if (gtk_text_view_get_editable (text_view))
|
||||
gtk_text_buffer_undo (text_view->priv->buffer);
|
||||
{
|
||||
gtk_text_buffer_undo (text_view->priv->buffer);
|
||||
gtk_text_view_scroll_mark_onscreen (text_view,
|
||||
gtk_text_buffer_get_insert (text_view->priv->buffer));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -10112,7 +10152,11 @@ gtk_text_view_real_redo (GtkWidget *widget,
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
if (gtk_text_view_get_editable (text_view))
|
||||
gtk_text_buffer_redo (text_view->priv->buffer);
|
||||
{
|
||||
gtk_text_buffer_redo (text_view->priv->buffer);
|
||||
gtk_text_view_scroll_mark_onscreen (text_view,
|
||||
gtk_text_buffer_get_insert (text_view->priv->buffer));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+14
-9
@@ -19,7 +19,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -55,7 +55,7 @@
|
||||
* To simply switch the state of a toggle button, use
|
||||
* [method@Gtk.ToggleButton.toggled].
|
||||
*
|
||||
* # Grouping
|
||||
* ## Grouping
|
||||
*
|
||||
* Toggle buttons can be grouped together, to form mutually exclusive
|
||||
* groups - only one of the buttons can be toggled at a time, and toggling
|
||||
@@ -63,20 +63,25 @@
|
||||
*
|
||||
* To add a `GtkToggleButton` to a group, use [method@Gtk.ToggleButton.set_group].
|
||||
*
|
||||
* # CSS nodes
|
||||
* ## CSS nodes
|
||||
*
|
||||
* `GtkToggleButton` has a single CSS node with name button. To differentiate
|
||||
* it from a plain `GtkButton`, it gets the .toggle style class.
|
||||
* it from a plain `GtkButton`, it gets the `.toggle` style class.
|
||||
*
|
||||
* ## Creating two `GtkToggleButton` widgets.
|
||||
*
|
||||
* ```c
|
||||
* static void output_state (GtkToggleButton *source, gpointer user_data)
|
||||
* static void
|
||||
* output_state (GtkToggleButton *source,
|
||||
* gpointer user_data)
|
||||
* {
|
||||
* printf ("Active: %d\n", gtk_toggle_button_get_active (source));
|
||||
* g_print ("Toggle button "%s" is active: %s",
|
||||
* gtk_button_get_label (GTK_BUTTON (source)),
|
||||
* gtk_toggle_button_get_active (source) ? "Yes" : "No");
|
||||
* }
|
||||
*
|
||||
* void make_toggles (void)
|
||||
* static void
|
||||
* make_toggles (void)
|
||||
* {
|
||||
* GtkWidget *window, *toggle1, *toggle2;
|
||||
* GtkWidget *box;
|
||||
@@ -85,7 +90,7 @@
|
||||
* window = gtk_window_new ();
|
||||
* box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
*
|
||||
* text = "Hi, I’m a toggle button.";
|
||||
* text = "Hi, I’m toggle button one";
|
||||
* toggle1 = gtk_toggle_button_new_with_label (text);
|
||||
*
|
||||
* g_signal_connect (toggle1, "toggled",
|
||||
@@ -93,7 +98,7 @@
|
||||
* NULL);
|
||||
* gtk_box_append (GTK_BOX (box), toggle1);
|
||||
*
|
||||
* text = "Hi, I’m a toggle button.";
|
||||
* text = "Hi, I’m toggle button two";
|
||||
* toggle2 = gtk_toggle_button_new_with_label (text);
|
||||
* g_signal_connect (toggle2, "toggled",
|
||||
* G_CALLBACK (output_state),
|
||||
|
||||
+5
-5
@@ -36,7 +36,7 @@ G_BEGIN_DECLS
|
||||
/**
|
||||
* GTK_MAJOR_VERSION:
|
||||
*
|
||||
* Like gtk_get_major_version(), but from the headers used at
|
||||
* Like [func@get_major_version], but from the headers used at
|
||||
* application compile time, rather than from the library linked
|
||||
* against at application run time.
|
||||
*/
|
||||
@@ -45,7 +45,7 @@ G_BEGIN_DECLS
|
||||
/**
|
||||
* GTK_MINOR_VERSION:
|
||||
*
|
||||
* Like gtk_get_minor_version(), but from the headers used at
|
||||
* Like [func@get_minor_version], but from the headers used at
|
||||
* application compile time, rather than from the library linked
|
||||
* against at application run time.
|
||||
*/
|
||||
@@ -54,7 +54,7 @@ G_BEGIN_DECLS
|
||||
/**
|
||||
* GTK_MICRO_VERSION:
|
||||
*
|
||||
* Like gtk_get_micro_version(), but from the headers used at
|
||||
* Like [func@get_micro_version], but from the headers used at
|
||||
* application compile time, rather than from the library linked
|
||||
* against at application run time.
|
||||
*/
|
||||
@@ -63,7 +63,7 @@ G_BEGIN_DECLS
|
||||
/**
|
||||
* GTK_BINARY_AGE:
|
||||
*
|
||||
* Like gtk_get_binary_age(), but from the headers used at
|
||||
* Like [func@get_binary_age], but from the headers used at
|
||||
* application compile time, rather than from the library linked
|
||||
* against at application run time.
|
||||
*/
|
||||
@@ -72,7 +72,7 @@ G_BEGIN_DECLS
|
||||
/**
|
||||
* GTK_INTERFACE_AGE:
|
||||
*
|
||||
* Like gtk_get_interface_age(), but from the headers used at
|
||||
* Like [func@get_interface_age], but from the headers used at
|
||||
* application compile time, rather than from the library linked
|
||||
* against at application run time.
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user