Compare commits
223 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 90bcb52293 | |||
| 3b48e562dd | |||
| fc12246758 | |||
| ae194d14d1 | |||
| c55a492ad3 | |||
| b70d8c477d | |||
| 73c436f43e | |||
| c627b22126 | |||
| e677cee28f | |||
| 2927383b5f | |||
| 2d9454363f | |||
| eb7bf0a2f4 | |||
| 4f6e1fdf16 | |||
| ddceddaa84 | |||
| da09447914 | |||
| d0af25f12c | |||
| 6e3d687386 | |||
| 6333cd8e83 | |||
| 8d28e2d8e9 | |||
| e5948f5713 | |||
| d967500c92 | |||
| 4be82195e4 | |||
| 455a0ecc1c | |||
| 2d5ad5f54e | |||
| 352c7f5120 | |||
| c3f3a82db9 | |||
| b55724e3a7 | |||
| f2e05e2b41 | |||
| bfbb9a58ae | |||
| 870657d57b | |||
| 4bc264a514 | |||
| 18fdc975be | |||
| ed5d7fed89 | |||
| 2f8c2a3244 | |||
| 5671a869c2 | |||
| f9b2edff39 | |||
| 53262cf7a6 | |||
| 6d3b4d9382 | |||
| d3143779d2 | |||
| 43fc428cf0 | |||
| 70ba973d1d | |||
| fd6ea42319 | |||
| 0e0ee480d3 | |||
| 78d0ef1d0b | |||
| 14c8e33ab9 | |||
| c08efb2b32 | |||
| c98ee1ec39 | |||
| 4366f80aab | |||
| 15570dd63d | |||
| 10c47c0226 | |||
| 0a1a2ac148 | |||
| aa989a637a | |||
| 50a09957a4 | |||
| e57ecafb6b | |||
| b7743430aa | |||
| 77c0f9d8e6 | |||
| 872097603f | |||
| 5e01a05b30 | |||
| a08eb4d58a | |||
| 8449e05865 | |||
| b0f3aa82b7 | |||
| 4950f68a87 | |||
| 5f20d909e6 | |||
| c59e8de533 | |||
| e8f2eeac92 | |||
| aae2bf91cb | |||
| 10c3a66e40 | |||
| 42fc6ab5d3 | |||
| c8de9abe98 | |||
| e60c9219f1 | |||
| 1c4158a649 | |||
| 55d65571f3 | |||
| 77912a65e2 | |||
| 8a40d8fe2a | |||
| c94002f8c0 | |||
| f4438a1ffc | |||
| 3563d11fc6 | |||
| 7b950944b0 | |||
| ffeef28dbc | |||
| 0d9a45d460 | |||
| 947fed0961 | |||
| ba88174614 | |||
| 598f86eaf3 | |||
| 3cb6ae3df3 | |||
| bd31bd6d63 | |||
| e3f407a71d | |||
| 1a213679bd | |||
| e063a0fdf1 | |||
| cff4718e91 | |||
| ffa42cb5bb | |||
| f9db800713 | |||
| 178e072e8a | |||
| b42a4e2276 | |||
| 5e59033eb3 | |||
| 58021c9e98 | |||
| e9dc0e391d | |||
| 9876fc4f17 | |||
| aa534812f5 | |||
| 959bfbb66e | |||
| debe81b1ea | |||
| cdadbb069f | |||
| 9ebeb4e68a | |||
| 8bdc2aa228 | |||
| 075667e927 | |||
| a46368dede | |||
| 1beb9db7b0 | |||
| 5830363787 | |||
| 7f870abf17 | |||
| 7501f9770f | |||
| 8bdff7a564 | |||
| 1ef057f983 | |||
| 756ebea036 | |||
| dd6931d1ba | |||
| c3148a81d2 | |||
| aba0c5cc3b | |||
| f55fe7e20b | |||
| 035e55d1ab | |||
| f48b30c13a | |||
| 02bc589583 | |||
| 1d6e896fef | |||
| 62f5414742 | |||
| be1bde9111 | |||
| 48ff2fc7ed | |||
| 9f6067a804 | |||
| c8f2328337 | |||
| dbbdefe4e0 | |||
| dfea266e1f | |||
| a1f6887f17 | |||
| 8796fe6d1c | |||
| 8710d97945 | |||
| 9c6e560819 | |||
| ea3a750f13 | |||
| 94e3d7faf1 | |||
| 1cee5ff0dd | |||
| 0306278145 | |||
| 4067a45aff | |||
| 625f8a6dd3 | |||
| 0bfbf39306 | |||
| f39f574914 | |||
| 281c592ea9 | |||
| 86ecf54139 | |||
| 2e287576b4 | |||
| 762e2d9322 | |||
| fd73c1f8d9 | |||
| 1e08fe8646 | |||
| 6821a8f7b2 | |||
| 5e7949c47b | |||
| ba96c34787 | |||
| 12dec5279e | |||
| e9dbfc0e06 | |||
| 0ccb7db245 | |||
| ccaf1c2c67 | |||
| ce56248930 | |||
| 016647edb1 | |||
| a68e76e058 | |||
| 67302c5ee0 | |||
| 16677bb85a | |||
| c13efbf8b0 | |||
| 73fe9a2acf | |||
| b1ad5c8abc | |||
| b41215bdea | |||
| 738b453c66 | |||
| 9c9d82f1a9 | |||
| bae55eaa80 | |||
| beb02a5b4b | |||
| 840855d401 | |||
| c9d035bde3 | |||
| 128437cc76 | |||
| e903ff8f86 | |||
| 21cf5a7e00 | |||
| 3338f6cb5b | |||
| 249d2a8030 | |||
| dc85125737 | |||
| 11825afc3e | |||
| 99e194e7cc | |||
| 63c75a2384 | |||
| 0eb09ac0f2 | |||
| f6952ceb82 | |||
| 237e984a52 | |||
| 41f29032d2 | |||
| 019bb37dd3 | |||
| ca0662dba4 | |||
| 5aff66f391 | |||
| 6245362a52 | |||
| 2b7ebd93f2 | |||
| b5495cd7da | |||
| bec6b260b4 | |||
| c51157d437 | |||
| 4e42bd055d | |||
| f67273c579 | |||
| 5a497e9fb8 | |||
| 288ed1f920 | |||
| 852d4d618c | |||
| 42da600eb1 | |||
| 67fec32d27 | |||
| ad22a1faf6 | |||
| ef027c93d4 | |||
| 247bc3ad69 | |||
| aa81b0db2c | |||
| c2032dec6d | |||
| f8c81ad788 | |||
| 488e124f6a | |||
| f0a211a1df | |||
| e5b88f1bdd | |||
| 7151b1a28a | |||
| f75498d8e1 | |||
| eda0d9ba10 | |||
| 15fe3038be | |||
| 9d1b576af6 | |||
| 2ad31feaaa | |||
| 2216a6f658 | |||
| fa2ed6b8a2 | |||
| 4c9db15212 | |||
| 5e55bf1d53 | |||
| e5de18cbf9 | |||
| 0f36b16733 | |||
| 7c6454246e | |||
| a021b72c71 | |||
| 6b3416a2d7 | |||
| 17760bd2eb | |||
| 97f49c681b | |||
| 6fb66261ca | |||
| 3b7e390484 |
@@ -1,3 +1,90 @@
|
||||
Overview of Changes in GTK+ 3.7.2
|
||||
=================================
|
||||
|
||||
* Theming:
|
||||
- Improve touch text handle theming
|
||||
- Always draw background of menuitems
|
||||
|
||||
* Geometry management
|
||||
- Size groups now handle height-for-width
|
||||
- Fix corner cases in label size allocation
|
||||
|
||||
* Accessibility
|
||||
- Make entry icons accessible
|
||||
|
||||
* Filechooser
|
||||
- Don't add duplicate bookmarks
|
||||
- Remember sidebar width
|
||||
|
||||
* Wayland: Build against wayland-client 1.0
|
||||
|
||||
* Bugs fixed:
|
||||
524295 remember the file chooser side pane's position
|
||||
577806 gtk_file_chooser_add_shortcut_folder adds duplicates...
|
||||
677609 GtkSizeGroup regression in GTK+ 3.3.20
|
||||
683896 Clean up global resources when the display is closed
|
||||
686021 spinner animation should not be subject to enable-an...
|
||||
686347 Clickable icons are not accessible as children of te...
|
||||
687059 icon-theme: support loading symbolic GFileIcons from...
|
||||
687196 filesystemmodel: invalidate nodes on file remove
|
||||
687467 Commit "Implement proper cross-fades for gradients" ...
|
||||
687842 Support partially transparent widgets
|
||||
687872 Segfault when attempting to get character extents fo...
|
||||
687977 icon-theme: Add some preconditions for NULL arguments
|
||||
|
||||
* Translation updates:
|
||||
Assamese
|
||||
Brazilian Portuguese
|
||||
Estonian
|
||||
Galician
|
||||
German
|
||||
Greek
|
||||
Gujarati
|
||||
Indonesian
|
||||
Latvian
|
||||
Lithuanian
|
||||
Marathi
|
||||
Norwegian bokmål
|
||||
Serbian
|
||||
Slovenian
|
||||
Spanish
|
||||
Traditional Chinese
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.7.0
|
||||
=================================
|
||||
|
||||
* Add an "inverted" property to GtkLevelBar
|
||||
|
||||
* Support RTL flipping in GtkLevelBar
|
||||
|
||||
* Various memory leak fixes
|
||||
|
||||
* Wayland: Update for protocol changes
|
||||
|
||||
* Bugs fixed:
|
||||
684288 level-bar: add an "inverted" property like GtkProgr...
|
||||
684415 Fix drag-motion event handling
|
||||
684980 Improve the appearance of the dragged header
|
||||
686013 CSS: crash drawing a GtkEntry in gedit
|
||||
686152 Calls gdk_window_get_frame_extents with a potential...
|
||||
686209 memleak with "text-shadow" css
|
||||
686265 scrolledwindow: set GDK_EXPOSURE_MASK on the oversh...
|
||||
686280 GtkScrollbar and GtkScale rendering broken in gtk 3.6
|
||||
686366 Use named union for _GtkSymbolicColor in gtk/gtksym...
|
||||
|
||||
* Translation updates:
|
||||
Czech
|
||||
Estonian
|
||||
Galician
|
||||
Indonesian
|
||||
Lithuanian
|
||||
Serbian
|
||||
Slovak
|
||||
Slovenian
|
||||
Spanish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.6.1
|
||||
=================================
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<CopyDir>$(GlibEtcInstallRoot)</CopyDir>
|
||||
<DefDir>$(SolutionDir)$(Configuration)\$(Platform)\obj\$(ProjectName)</DefDir>
|
||||
<GtkApiVersion>3.0</GtkApiVersion>
|
||||
<GtkBinaryVersion>2.10.0</GtkBinaryVersion>
|
||||
<GtkBinaryVersion>3.0.0</GtkBinaryVersion>
|
||||
<GtkDummyPrefix>\"/dummy\"</GtkDummyPrefix>
|
||||
<GtkPrefixDefine>GTK_PREFIX="\"$(GtkDummyPrefix)\""</GtkPrefixDefine>
|
||||
<GdkDefines>GDK_COMPILATION;G_LOG_DOMAIN="\"Gdk\""</GdkDefines>
|
||||
|
||||
@@ -41,7 +41,7 @@ copy ..\..\..\gdk\gdkconfig.h.win32 ..\..\..\gdk\gdkconfig.h

|
||||
/>
|
||||
<UserMacro
|
||||
Name="GtkBinaryVersion"
|
||||
Value="2.10.0"
|
||||
Value="3.0.0"
|
||||
/>
|
||||
<UserMacro
|
||||
Name="GtkDummyPrefix"
|
||||
|
||||
+18
-6
@@ -9,9 +9,9 @@
|
||||
# set GTK_BINARY_AGE and GTK_INTERFACE_AGE to 0.
|
||||
|
||||
m4_define([gtk_major_version], [3])
|
||||
m4_define([gtk_minor_version], [6])
|
||||
m4_define([gtk_micro_version], [2])
|
||||
m4_define([gtk_interface_age], [2])
|
||||
m4_define([gtk_minor_version], [7])
|
||||
m4_define([gtk_micro_version], [3])
|
||||
m4_define([gtk_interface_age], [0])
|
||||
m4_define([gtk_binary_age],
|
||||
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
|
||||
m4_define([gtk_version],
|
||||
@@ -39,7 +39,7 @@ AC_CONFIG_AUX_DIR([build-aux])
|
||||
m4_define([gtk_binary_version], [3.0.0])
|
||||
|
||||
# required versions of other packages
|
||||
m4_define([glib_required_version], [2.33.1])
|
||||
m4_define([glib_required_version], [2.35.0])
|
||||
m4_define([pango_required_version], [1.30.0])
|
||||
m4_define([atk_required_version], [2.5.3])
|
||||
m4_define([cairo_required_version], [1.10.0])
|
||||
@@ -407,7 +407,7 @@ if test "x$enable_wayland_backend" = "xyes"; then
|
||||
have_gio_unix=yes
|
||||
GDK_WINDOWING="$GDK_WINDOWING
|
||||
#define GDK_WINDOWING_WAYLAND"
|
||||
WAYLAND_PACKAGES="wayland-client xkbcommon wayland-cursor"
|
||||
WAYLAND_PACKAGES="wayland-client >= 1.0.0 xkbcommon >= 0.2.0 wayland-cursor"
|
||||
if test "x$enable_wayland_cairo_gl" = "xyes"; then
|
||||
WAYLAND_PACKAGES="$WAYLAND_PACKAGES wayland-egl egl"
|
||||
fi
|
||||
@@ -714,7 +714,6 @@ AM_PATH_GLIB_2_0(glib_required_version, :,
|
||||
*** GLIB is always available from ftp://ftp.gtk.org/pub/gtk/.]),
|
||||
gobject gmodule-no-export)
|
||||
|
||||
dnl
|
||||
dnl Check for bind_textdomain_codeset, including -lintl if GLib brings it in.
|
||||
dnl
|
||||
gtk_save_LIBS=$LIBS
|
||||
@@ -748,6 +747,19 @@ else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
#
|
||||
# Disable deprecation checks for all libraries we depend on on stable branches.
|
||||
# This is so newer versions of those libraries don't cause more warnings with
|
||||
# a stable GTK version.
|
||||
# We don't ever want to turn off deprecation warnings for master however, because
|
||||
# that's where we get rid of deprecated API we use.
|
||||
#
|
||||
if test m4_eval(gtk_minor_version % 2) = 0 ; then
|
||||
AC_DEFINE_UNQUOTED(GLIB_DISABLE_DEPRECATION_WARNINGS, 1,
|
||||
[Disable deprecation warnings from glib])
|
||||
fi
|
||||
|
||||
dnl
|
||||
saved_cflags="$CFLAGS"
|
||||
saved_ldflags="$LDFLAGS"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<chapter id="gtk-getting-started" xmlns:xi="http://www.w3.org/2003/XInclude">
|
||||
<title>Getting Started with GTK+</title>
|
||||
|
||||
<para>This chapter is contains some tutorial information to get you
|
||||
<para>This chapter contains some tutorial information to get you
|
||||
started with GTK+ programming. It assumes that you have GTK+, its
|
||||
dependencies and a C compiler installed and ready to use. If you
|
||||
need to build GTK+ itself first, refer to the
|
||||
|
||||
@@ -3281,6 +3281,8 @@ gtk_level_bar_set_min_value
|
||||
gtk_level_bar_get_min_value
|
||||
gtk_level_bar_set_max_value
|
||||
gtk_level_bar_get_max_value
|
||||
gtk_level_bar_set_inverted
|
||||
gtk_level_bar_get_inverted
|
||||
gtk_level_bar_add_offset_value
|
||||
gtk_level_bar_remove_offset_value
|
||||
gtk_level_bar_get_offset_value
|
||||
@@ -5289,6 +5291,7 @@ gtk_widget_get_sensitive
|
||||
gtk_widget_is_sensitive
|
||||
gtk_widget_get_state
|
||||
gtk_widget_get_visible
|
||||
gtk_widget_is_visible
|
||||
gtk_widget_set_visible
|
||||
gtk_widget_set_state_flags
|
||||
gtk_widget_unset_state_flags
|
||||
@@ -5777,6 +5780,7 @@ GTK_STYLE_CLASS_ARROW
|
||||
GTK_STYLE_CLASS_OSD
|
||||
GTK_STYLE_CLASS_LEVEL_BAR
|
||||
GTK_STYLE_CLASS_CURSOR_HANDLE
|
||||
GTK_STYLE_CLASS_INSERTION_CURSOR
|
||||
GTK_STYLE_REGION_COLUMN
|
||||
GTK_STYLE_REGION_COLUMN_HEADER
|
||||
GTK_STYLE_REGION_ROW
|
||||
|
||||
@@ -411,8 +411,6 @@ bloat_pad_new (void)
|
||||
{
|
||||
BloatPad *bloat_pad;
|
||||
|
||||
g_type_init ();
|
||||
|
||||
g_set_application_name ("Bloatpad");
|
||||
|
||||
bloat_pad = g_object_new (bloat_pad_get_type (),
|
||||
|
||||
@@ -465,8 +465,6 @@ plug_man_class_init (PlugManClass *class)
|
||||
PlugMan *
|
||||
plug_man_new (void)
|
||||
{
|
||||
g_type_init ();
|
||||
|
||||
return g_object_new (plug_man_get_type (),
|
||||
"application-id", "org.gtk.Test.plugman",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
|
||||
@@ -191,8 +191,6 @@ menu_button_class_init (MenuButtonClass *class)
|
||||
MenuButton *
|
||||
menu_button_new (void)
|
||||
{
|
||||
g_type_init ();
|
||||
|
||||
return g_object_new (menu_button_get_type (),
|
||||
"application-id", "org.gtk.Test.Sunny",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
|
||||
@@ -31,12 +31,12 @@ libbroadway_la_SOURCES = \
|
||||
broadway.c
|
||||
|
||||
clienthtml.h: client.html
|
||||
$(PERL) ./toarray.pl client.html client_html > $@
|
||||
$(PERL) $(srcdir)/toarray.pl $(srcdir)/client.html client_html > $@
|
||||
|
||||
EXTRA_DIST += client.html
|
||||
|
||||
broadwayjs.h: broadway.js
|
||||
$(PERL) ./toarray.pl broadway.js broadway_js > $@
|
||||
$(PERL) $(srcdir)/toarray.pl $(srcdir)/broadway.js broadway_js > $@
|
||||
|
||||
EXTRA_DIST += broadway.js
|
||||
|
||||
|
||||
@@ -274,8 +274,6 @@ gdk_pre_parse_libgtk_only (void)
|
||||
_gdk_rendering_mode = GDK_RENDERING_MODE_RECORDING;
|
||||
}
|
||||
|
||||
g_type_init ();
|
||||
|
||||
/* Do any setup particular to the windowing system */
|
||||
gdk_display_manager_get ();
|
||||
}
|
||||
|
||||
@@ -90,6 +90,16 @@
|
||||
*/
|
||||
#define GDK_VERSION_3_6 (G_ENCODE_VERSION (3, 6))
|
||||
|
||||
/**
|
||||
* GDK_VERSION_3_8:
|
||||
*
|
||||
* A macro that evaluates to the 3.8 version of GDK, in a format
|
||||
* that can be used by the C pre-processor.
|
||||
*
|
||||
* Since: 3.8
|
||||
*/
|
||||
#define GDK_VERSION_3_8 (G_ENCODE_VERSION (3, 8))
|
||||
|
||||
|
||||
/* evaluates to the current stable version; for development cycles,
|
||||
* this means the next stable target
|
||||
@@ -217,4 +227,18 @@
|
||||
# define GDK_AVAILABLE_IN_3_6
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_3_8
|
||||
# define GDK_DEPRECATED_IN_3_8 GDK_DEPRECATED
|
||||
# define GDK_DEPRECATED_IN_3_8_FOR(f) GDK_DEPRECATED_FOR(f)
|
||||
#else
|
||||
# define GDK_DEPRECATED_IN_3_8
|
||||
# define GDK_DEPRECATED_IN_3_8_FOR(f)
|
||||
#endif
|
||||
|
||||
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_3_8
|
||||
# define GDK_AVAILABLE_IN_3_8 GDK_UNAVAILABLE(3, 8)
|
||||
#else
|
||||
# define GDK_AVAILABLE_IN_3_8
|
||||
#endif
|
||||
|
||||
#endif /* __GDK_VERSION_MACROS_H__ */
|
||||
|
||||
+13
-7
@@ -668,6 +668,13 @@ gdk_window_has_no_impl (GdkWindow *window)
|
||||
return window->impl_window != window;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_window_has_alpha (GdkWindow *window)
|
||||
{
|
||||
return !gdk_window_has_impl (window) &&
|
||||
window->has_alpha_background;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_layered_child_area (GdkWindow *window,
|
||||
cairo_region_t *region)
|
||||
@@ -695,7 +702,7 @@ remove_layered_child_area (GdkWindow *window,
|
||||
continue;
|
||||
|
||||
/* Only non-impl children with alpha add to the layered region */
|
||||
if (!child->has_alpha_background && gdk_window_has_impl (child))
|
||||
if (!gdk_window_has_alpha (child))
|
||||
continue;
|
||||
|
||||
r.x = child->x;
|
||||
@@ -797,7 +804,7 @@ remove_child_area (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
if (child->has_alpha_background)
|
||||
if (gdk_window_has_alpha (child))
|
||||
{
|
||||
if (layered_region != NULL)
|
||||
cairo_region_union (layered_region, child_region);
|
||||
@@ -2989,8 +2996,7 @@ gdk_window_begin_paint_region (GdkWindow *window,
|
||||
by being drawn in back to front order. However, if implicit paints are not used, for
|
||||
instance if it was flushed due to a non-double-buffered paint in the middle of the
|
||||
expose we need to copy in the existing data here. */
|
||||
if (!gdk_window_has_impl (window) &&
|
||||
window->has_alpha_background &&
|
||||
if (gdk_window_has_alpha (window) &&
|
||||
(!implicit_paint ||
|
||||
(implicit_paint && implicit_paint->flushed != NULL && !cairo_region_is_empty (implicit_paint->flushed))))
|
||||
{
|
||||
@@ -6161,7 +6167,7 @@ gdk_window_move_resize_internal (GdkWindow *window,
|
||||
* Everything in the old and new regions that is not copied must be
|
||||
* invalidated (including children) as this is newly exposed
|
||||
*/
|
||||
if (window->has_alpha_background)
|
||||
if (gdk_window_has_alpha (window))
|
||||
copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
|
||||
else
|
||||
copy_area = cairo_region_copy (new_region);
|
||||
@@ -6385,7 +6391,7 @@ gdk_window_scroll (GdkWindow *window,
|
||||
impl_window = gdk_window_get_impl_window (window);
|
||||
|
||||
/* Calculate the area that can be gotten by copying the old area */
|
||||
if (window->has_alpha_background)
|
||||
if (gdk_window_has_alpha (window))
|
||||
copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
|
||||
else
|
||||
copy_area = cairo_region_copy (window->clip_region);
|
||||
@@ -6473,7 +6479,7 @@ gdk_window_move_region (GdkWindow *window,
|
||||
impl_window = gdk_window_get_impl_window (window);
|
||||
|
||||
/* compute source regions */
|
||||
if (window->has_alpha_background)
|
||||
if (gdk_window_has_alpha (window))
|
||||
copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
|
||||
else
|
||||
copy_area = cairo_region_copy (region);
|
||||
|
||||
@@ -141,6 +141,38 @@
|
||||
return inMove;
|
||||
}
|
||||
|
||||
-(void)checkSendEnterNotify
|
||||
{
|
||||
GdkWindow *window = [[self contentView] gdkWindow];
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
|
||||
|
||||
/* When a new window has been created, and the mouse
|
||||
* is in the window area, we will not receive an NSMouseEntered
|
||||
* event. Therefore, we synthesize an enter notify event manually.
|
||||
*/
|
||||
if (!initialPositionKnown)
|
||||
{
|
||||
initialPositionKnown = YES;
|
||||
|
||||
if (NSPointInRect ([NSEvent mouseLocation], [self frame]))
|
||||
{
|
||||
NSEvent *event;
|
||||
|
||||
event = [NSEvent enterExitEventWithType: NSMouseEntered
|
||||
location: [self mouseLocationOutsideOfEventStream]
|
||||
modifierFlags: 0
|
||||
timestamp: [[NSApp currentEvent] timestamp]
|
||||
windowNumber: [impl->toplevel windowNumber]
|
||||
context: NULL
|
||||
eventNumber: 0
|
||||
trackingNumber: [impl->view trackingRect]
|
||||
userData: nil];
|
||||
|
||||
[NSApp postEvent:event atStart:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)windowDidMove:(NSNotification *)aNotification
|
||||
{
|
||||
GdkWindow *window = [[self contentView] gdkWindow];
|
||||
@@ -157,6 +189,8 @@
|
||||
event->configure.height = window->height;
|
||||
|
||||
_gdk_event_queue_append (gdk_display_get_default (), event);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowDidResize:(NSNotification *)aNotification
|
||||
@@ -186,6 +220,8 @@
|
||||
event->configure.height = window->height;
|
||||
|
||||
_gdk_event_queue_append (gdk_display_get_default (), event);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
|
||||
@@ -283,6 +319,8 @@
|
||||
[impl->toplevel orderFront:nil];
|
||||
|
||||
inShowOrHide = NO;
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
- (void)hide
|
||||
@@ -293,6 +331,8 @@
|
||||
inShowOrHide = YES;
|
||||
[impl->toplevel orderOut:nil];
|
||||
inShowOrHide = NO;
|
||||
|
||||
initialPositionKnown = NO;
|
||||
}
|
||||
|
||||
- (BOOL)trackManualMove
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
@interface GdkQuartzNSWindow : NSWindow {
|
||||
BOOL inMove;
|
||||
BOOL inShowOrHide;
|
||||
BOOL initialPositionKnown;
|
||||
|
||||
/* Manually triggered move/resize (not by the window manager) */
|
||||
BOOL inManualMove;
|
||||
|
||||
@@ -167,15 +167,6 @@
|
||||
owner:self
|
||||
userData:nil
|
||||
assumeInside:NO];
|
||||
|
||||
if (NSPointInRect ([[self window] convertScreenToBase:[NSEvent mouseLocation]], rect))
|
||||
{
|
||||
/* When a new window (and thus view) has been created, and the mouse
|
||||
* is in the window area, we will not receive an NSMouseEntered
|
||||
* event. Therefore, we synthesize an enter notify event manually.
|
||||
*/
|
||||
_gdk_quartz_events_send_enter_notify_event (gdk_window);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)viewDidMoveToWindow
|
||||
|
||||
@@ -401,34 +401,89 @@ get_window_point_from_screen_point (GdkWindow *window,
|
||||
*y = window->height - point.y;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_mouse_button_press_event (NSEventType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NSLeftMouseDown:
|
||||
case NSRightMouseDown:
|
||||
case NSOtherMouseDown:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GdkWindow *
|
||||
get_toplevel_from_ns_event (NSEvent *nsevent,
|
||||
NSPoint *screen_point,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
GdkWindow *toplevel;
|
||||
GdkWindow *toplevel = NULL;
|
||||
|
||||
if ([nsevent window])
|
||||
{
|
||||
GdkQuartzView *view;
|
||||
NSPoint point;
|
||||
NSPoint point, view_point;
|
||||
NSRect view_frame;
|
||||
|
||||
view = (GdkQuartzView *)[[nsevent window] contentView];
|
||||
|
||||
toplevel = [view gdkWindow];
|
||||
|
||||
point = [nsevent locationInWindow];
|
||||
*screen_point = [[nsevent window] convertBaseToScreen:point];
|
||||
view_point = [view convertPoint:point fromView:nil];
|
||||
view_frame = [view frame];
|
||||
|
||||
*x = point.x;
|
||||
*y = toplevel->height - point.y;
|
||||
/* NSEvents come in with a window set, but with window coordinates
|
||||
* out of window bounds. For e.g. moved events this is fine, we use
|
||||
* this information to properly handle enter/leave notify and motion
|
||||
* events. For mouse button press/release, we want to avoid forwarding
|
||||
* these events however, because the window they relate to is not the
|
||||
* window set in the event. This situation appears to occur when button
|
||||
* presses come in just before (or just after?) a window is resized and
|
||||
* also when a button press occurs on the OS X window titlebar.
|
||||
*
|
||||
* By setting toplevel to NULL, we do another attempt to get the right
|
||||
* toplevel window below.
|
||||
*/
|
||||
if (is_mouse_button_press_event ([nsevent type]) &&
|
||||
(view_point.x < view_frame.origin.x ||
|
||||
view_point.x >= view_frame.origin.x + view_frame.size.width ||
|
||||
view_point.y < view_frame.origin.y ||
|
||||
view_point.y >= view_frame.origin.y + view_frame.size.height))
|
||||
{
|
||||
toplevel = NULL;
|
||||
|
||||
/* This is a hack for button presses to break all grabs. E.g. if
|
||||
* a menu is open and one clicks on the title bar (or anywhere
|
||||
* out of window bounds), we really want to pop down the menu (by
|
||||
* breaking the grabs) before OS X handles the action of the title
|
||||
* bar button.
|
||||
*
|
||||
* Because we cannot ingest this event into GDK, we have to do it
|
||||
* here, not very nice.
|
||||
*/
|
||||
_gdk_quartz_events_break_all_grabs (get_time_from_ns_event (nsevent));
|
||||
}
|
||||
else
|
||||
{
|
||||
*screen_point = [[nsevent window] convertBaseToScreen:point];
|
||||
|
||||
*x = point.x;
|
||||
*y = toplevel->height - point.y;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (!toplevel)
|
||||
{
|
||||
/* Fallback used when no NSWindow set. This happens e.g. when
|
||||
* we allow motion events without a window set in gdk_event_translate()
|
||||
* that occur immediately after the main menu bar was clicked/used.
|
||||
* This fallback will not return coordinates contained in a window's
|
||||
* titlebar.
|
||||
*/
|
||||
*screen_point = [NSEvent mouseLocation];
|
||||
toplevel = find_toplevel_under_pointer (_gdk_display,
|
||||
@@ -475,7 +530,7 @@ generate_motion_event (GdkWindow *window)
|
||||
|
||||
event->any.type = GDK_MOTION_NOTIFY;
|
||||
event->motion.window = window;
|
||||
event->motion.time = GDK_CURRENT_TIME;
|
||||
event->motion.time = get_time_from_ns_event ([NSApp currentEvent]);
|
||||
event->motion.x = x;
|
||||
event->motion.y = y;
|
||||
event->motion.x_root = x_root;
|
||||
@@ -534,39 +589,6 @@ _gdk_quartz_events_update_focus_window (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_events_send_enter_notify_event (GdkWindow *window)
|
||||
{
|
||||
NSPoint screen_point;
|
||||
GdkEvent *event;
|
||||
gint x, y, x_root, y_root;
|
||||
|
||||
event = gdk_event_new (GDK_ENTER_NOTIFY);
|
||||
event->any.window = NULL;
|
||||
event->any.send_event = FALSE;
|
||||
|
||||
screen_point = [NSEvent mouseLocation];
|
||||
|
||||
_gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &x_root, &y_root);
|
||||
get_window_point_from_screen_point (window, screen_point, &x, &y);
|
||||
|
||||
event->crossing.window = window;
|
||||
event->crossing.subwindow = NULL;
|
||||
event->crossing.time = GDK_CURRENT_TIME;
|
||||
event->crossing.x = x;
|
||||
event->crossing.y = y;
|
||||
event->crossing.x_root = x_root;
|
||||
event->crossing.y_root = y_root;
|
||||
event->crossing.mode = GDK_CROSSING_NORMAL;
|
||||
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
|
||||
event->crossing.state = _gdk_quartz_events_get_current_keyboard_modifiers () |
|
||||
_gdk_quartz_events_get_current_mouse_modifiers ();
|
||||
|
||||
gdk_event_set_device (event, _gdk_display->core_pointer);
|
||||
|
||||
append_event (event, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_events_send_map_event (GdkWindow *window)
|
||||
{
|
||||
@@ -600,6 +622,18 @@ find_toplevel_under_pointer (GdkDisplay *display,
|
||||
if (toplevel && WINDOW_IS_TOPLEVEL (toplevel))
|
||||
get_window_point_from_screen_point (toplevel, screen_point, x, y);
|
||||
|
||||
if (toplevel)
|
||||
{
|
||||
/* If the coordinates are out of window bounds, this toplevel is not
|
||||
* under the pointer and we thus return NULL. This can occur when
|
||||
* toplevel under pointer has not yet been updated due to a very recent
|
||||
* window resize. Alternatively, we should no longer be relying on
|
||||
* the toplevel_under_pointer value which is maintained in gdkwindow.c.
|
||||
*/
|
||||
if (*x < 0 || *y < 0 || *x >= toplevel->width || *y >= toplevel->height)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return toplevel;
|
||||
}
|
||||
|
||||
@@ -772,6 +806,8 @@ find_window_for_ns_event (NSEvent *nsevent,
|
||||
view = (GdkQuartzView *)[[nsevent window] contentView];
|
||||
|
||||
toplevel = get_toplevel_from_ns_event (nsevent, &screen_point, x, y);
|
||||
if (!toplevel)
|
||||
return NULL;
|
||||
_gdk_quartz_window_nspoint_to_gdk_xy (screen_point, x_root, y_root);
|
||||
|
||||
event_type = [nsevent type];
|
||||
@@ -1085,8 +1121,9 @@ synthesize_crossing_event (GdkWindow *window,
|
||||
switch ([nsevent type])
|
||||
{
|
||||
case NSMouseEntered:
|
||||
/* Enter events are considered always to be from the root window as we
|
||||
* can't know for sure from what window we enter.
|
||||
/* Enter events are considered always to be from another toplevel
|
||||
* window, this shouldn't negatively affect any app or gtk code,
|
||||
* and is the only way to make GtkMenu work. EEK EEK EEK.
|
||||
*/
|
||||
if (!(window->event_mask & GDK_ENTER_NOTIFY_MASK))
|
||||
return FALSE;
|
||||
@@ -1096,14 +1133,11 @@ synthesize_crossing_event (GdkWindow *window,
|
||||
x_root, y_root,
|
||||
GDK_ENTER_NOTIFY,
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
return TRUE;
|
||||
|
||||
case NSMouseExited:
|
||||
/* Exited always is to the root window as far as we are concerned,
|
||||
* since there is no way to reliably get information about what new
|
||||
* window is entered when exiting one.
|
||||
*/
|
||||
/* See above */
|
||||
if (!(window->event_mask & GDK_LEAVE_NOTIFY_MASK))
|
||||
return FALSE;
|
||||
|
||||
@@ -1112,7 +1146,7 @@ synthesize_crossing_event (GdkWindow *window,
|
||||
x_root, y_root,
|
||||
GDK_LEAVE_NOTIFY,
|
||||
GDK_CROSSING_NORMAL,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
GDK_NOTIFY_NONLINEAR);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
@@ -1309,9 +1343,9 @@ gdk_event_translate (GdkEvent *event,
|
||||
}
|
||||
|
||||
/* Also when in a manual resize, we ignore events so that these are
|
||||
* pushed to GdkQuartzWindow's sendEvent handler.
|
||||
* pushed to GdkQuartzNSWindow's sendEvent handler.
|
||||
*/
|
||||
if ([(GdkQuartzWindow *)nswindow isInManualResize])
|
||||
if ([(GdkQuartzNSWindow *)nswindow isInManualResize])
|
||||
return FALSE;
|
||||
|
||||
/* Find the right GDK window to send the event to, taking grabs and
|
||||
@@ -1439,7 +1473,8 @@ gdk_event_translate (GdkEvent *event,
|
||||
if (dx != 0.0 || dy != 0.0)
|
||||
{
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
if (gdk_quartz_osx_version() >= GDK_OSX_LION &[nsevent hasPreciseScrollingDeltas])
|
||||
if (gdk_quartz_osx_version() >= GDK_OSX_LION &&
|
||||
[nsevent hasPreciseScrollingDeltas])
|
||||
{
|
||||
GdkEvent *emulated_event;
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ const static struct {
|
||||
{ 67, GDK_KEY_asterisk, GDK_KEY_KP_Multiply },
|
||||
{ 69, GDK_KEY_plus, GDK_KEY_KP_Add },
|
||||
{ 75, GDK_KEY_slash, GDK_KEY_KP_Divide },
|
||||
{ 76, 0x01000003, GDK_KEY_KP_Enter },
|
||||
{ 76, GDK_KEY_Return, GDK_KEY_KP_Enter },
|
||||
{ 78, GDK_KEY_minus, GDK_KEY_KP_Subtract },
|
||||
{ 81, GDK_KEY_equal, GDK_KEY_KP_Equal },
|
||||
{ 82, GDK_KEY_0, GDK_KEY_KP_0 },
|
||||
|
||||
@@ -64,7 +64,6 @@ void _gdk_quartz_events_send_map_event (GdkWindow *window);
|
||||
GdkModifierType _gdk_quartz_events_get_current_keyboard_modifiers (void);
|
||||
GdkModifierType _gdk_quartz_events_get_current_mouse_modifiers (void);
|
||||
|
||||
void _gdk_quartz_events_send_enter_notify_event (GdkWindow *window);
|
||||
void _gdk_quartz_events_break_all_grabs (guint32 time);
|
||||
|
||||
/* Event loop */
|
||||
|
||||
@@ -2315,28 +2315,31 @@ gdk_quartz_window_focus (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
gint window_type_hint_to_level (GdkWindowTypeHint hint)
|
||||
static gint
|
||||
window_type_hint_to_level (GdkWindowTypeHint hint)
|
||||
{
|
||||
/* the order in this switch statement corresponds to the actual
|
||||
* stacking order: the first group is top, the last group is bottom
|
||||
*/
|
||||
switch (hint)
|
||||
{
|
||||
case GDK_WINDOW_TYPE_HINT_DOCK:
|
||||
case GDK_WINDOW_TYPE_HINT_UTILITY:
|
||||
return NSFloatingWindowLevel;
|
||||
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
|
||||
case GDK_WINDOW_TYPE_HINT_COMBO:
|
||||
case GDK_WINDOW_TYPE_HINT_DND:
|
||||
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
|
||||
return NSPopUpMenuWindowLevel;
|
||||
|
||||
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
|
||||
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
|
||||
return NSStatusWindowLevel;
|
||||
|
||||
case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
|
||||
case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
|
||||
return NSTornOffMenuWindowLevel;
|
||||
|
||||
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
|
||||
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
|
||||
return NSStatusWindowLevel;
|
||||
|
||||
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
|
||||
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
|
||||
case GDK_WINDOW_TYPE_HINT_COMBO:
|
||||
case GDK_WINDOW_TYPE_HINT_DND:
|
||||
return NSPopUpMenuWindowLevel;
|
||||
case GDK_WINDOW_TYPE_HINT_DOCK:
|
||||
case GDK_WINDOW_TYPE_HINT_UTILITY:
|
||||
return NSFloatingWindowLevel;
|
||||
|
||||
case GDK_WINDOW_TYPE_HINT_NORMAL: /* Normal toplevel window */
|
||||
case GDK_WINDOW_TYPE_HINT_DIALOG: /* Dialog window */
|
||||
@@ -2351,7 +2354,7 @@ gint window_type_hint_to_level (GdkWindowTypeHint hint)
|
||||
return NSNormalWindowLevel;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static gboolean
|
||||
window_type_hint_to_shadow (GdkWindowTypeHint hint)
|
||||
{
|
||||
switch (hint)
|
||||
@@ -2381,13 +2384,31 @@ window_type_hint_to_shadow (GdkWindowTypeHint hint)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_type_hint_to_hides_on_deactivate (GdkWindowTypeHint hint)
|
||||
{
|
||||
switch (hint)
|
||||
{
|
||||
case GDK_WINDOW_TYPE_HINT_UTILITY:
|
||||
case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
|
||||
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
|
||||
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
|
||||
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_window_set_type_hint (GdkWindow *window,
|
||||
GdkWindowTypeHint hint)
|
||||
{
|
||||
GdkWindowImplQuartz *impl;
|
||||
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window) ||
|
||||
!WINDOW_IS_TOPLEVEL (window))
|
||||
return;
|
||||
@@ -2402,6 +2423,7 @@ gdk_quartz_window_set_type_hint (GdkWindow *window,
|
||||
|
||||
[impl->toplevel setHasShadow: window_type_hint_to_shadow (hint)];
|
||||
[impl->toplevel setLevel: window_type_hint_to_level (hint)];
|
||||
[impl->toplevel setHidesOnDeactivate: window_type_hint_to_hides_on_deactivate (hint)];
|
||||
}
|
||||
|
||||
static GdkWindowTypeHint
|
||||
@@ -2619,6 +2641,7 @@ gdk_quartz_window_set_decorations (GdkWindow *window,
|
||||
defer:NO];
|
||||
[impl->toplevel setHasShadow: window_type_hint_to_shadow (impl->type_hint)];
|
||||
[impl->toplevel setLevel: window_type_hint_to_level (impl->type_hint)];
|
||||
[impl->toplevel setHidesOnDeactivate: window_type_hint_to_hides_on_deactivate (impl->type_hint)];
|
||||
[impl->toplevel setContentView:old_view];
|
||||
}
|
||||
|
||||
|
||||
@@ -183,6 +183,7 @@ gdk_device_core_set_window_cursor (GdkDevice *device,
|
||||
x, y);
|
||||
wl_surface_attach (wd->pointer_surface, buffer, 0, 0);
|
||||
wl_surface_damage (wd->pointer_surface, 0, 0, w, h);
|
||||
wl_surface_commit(wd->pointer_surface);
|
||||
|
||||
g_object_unref (cursor);
|
||||
}
|
||||
@@ -1240,14 +1241,14 @@ static GdkModifierType
|
||||
get_modifier (struct xkb_state *state)
|
||||
{
|
||||
GdkModifierType modifiers = 0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_SHIFT, XKB_STATE_EFFECTIVE) > 0)?GDK_SHIFT_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_CAPS, XKB_STATE_EFFECTIVE) > 0)?GDK_LOCK_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_CTRL, XKB_STATE_EFFECTIVE) > 0)?GDK_CONTROL_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_ALT, XKB_STATE_EFFECTIVE) > 0)?GDK_MOD1_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod2", XKB_STATE_EFFECTIVE) > 0)?GDK_MOD2_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod3", XKB_STATE_EFFECTIVE) > 0)?GDK_MOD3_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_LOGO, XKB_STATE_EFFECTIVE) > 0)?GDK_MOD4_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod5", XKB_STATE_EFFECTIVE) > 0)?GDK_MOD5_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) > 0)?GDK_SHIFT_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_EFFECTIVE) > 0)?GDK_LOCK_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) > 0)?GDK_CONTROL_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) > 0)?GDK_MOD1_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod2", XKB_STATE_MODS_EFFECTIVE) > 0)?GDK_MOD2_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod3", XKB_STATE_MODS_EFFECTIVE) > 0)?GDK_MOD3_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) > 0)?GDK_MOD4_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod5", XKB_STATE_MODS_EFFECTIVE) > 0)?GDK_MOD5_MASK:0;
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
@@ -1324,16 +1325,11 @@ deliver_key_event(GdkWaylandDevice *device,
|
||||
struct xkb_state *xkb_state;
|
||||
GdkKeymap *keymap;
|
||||
xkb_keysym_t sym;
|
||||
uint32_t num_syms;
|
||||
const xkb_keysym_t *syms;
|
||||
|
||||
keymap = device->keymap;
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap);
|
||||
|
||||
num_syms = xkb_key_get_syms (xkb_state, key, &syms);
|
||||
sym = XKB_KEY_NoSymbol;
|
||||
if (num_syms == 1)
|
||||
sym = syms[0];
|
||||
sym = xkb_state_key_get_one_sym (xkb_state, key);
|
||||
|
||||
device->time = time;
|
||||
device->modifiers = get_modifier (xkb_state);
|
||||
|
||||
@@ -96,7 +96,8 @@ static void
|
||||
output_handle_geometry(void *data,
|
||||
struct wl_output *wl_output,
|
||||
int x, int y, int physical_width, int physical_height,
|
||||
int subpixel, const char *make, const char *model)
|
||||
int subpixel, const char *make, const char *model,
|
||||
int32_t transform)
|
||||
{
|
||||
/*
|
||||
g_signal_emit_by_name (screen, "monitors-changed");
|
||||
@@ -119,8 +120,8 @@ static const struct wl_output_listener output_listener = {
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_display_handle_global(struct wl_display *display, uint32_t id,
|
||||
const char *interface, uint32_t version, void *data)
|
||||
gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
||||
const char *interface, uint32_t version)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = data;
|
||||
GdkDisplay *gdk_display = GDK_DISPLAY_OBJECT (data);
|
||||
@@ -128,27 +129,29 @@ gdk_display_handle_global(struct wl_display *display, uint32_t id,
|
||||
|
||||
if (strcmp(interface, "wl_compositor") == 0) {
|
||||
display_wayland->compositor =
|
||||
wl_display_bind(display, id, &wl_compositor_interface);
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_compositor_interface, 1);
|
||||
} else if (strcmp(interface, "wl_shm") == 0) {
|
||||
display_wayland->shm = wl_display_bind(display, id, &wl_shm_interface);
|
||||
display_wayland->shm =
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_shm_interface, 1);
|
||||
|
||||
/* SHM interface is prerequisite */
|
||||
_gdk_wayland_display_load_cursor_theme(display_wayland);
|
||||
} else if (strcmp(interface, "wl_shell") == 0) {
|
||||
display_wayland->shell = wl_display_bind(display, id, &wl_shell_interface);
|
||||
display_wayland->shell =
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_shell_interface, 1);
|
||||
} else if (strcmp(interface, "wl_output") == 0) {
|
||||
display_wayland->output =
|
||||
wl_display_bind(display, id, &wl_output_interface);
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 1);
|
||||
wl_output_add_listener(display_wayland->output,
|
||||
&output_listener, display_wayland);
|
||||
} else if (strcmp(interface, "wl_seat") == 0) {
|
||||
seat = wl_display_bind (display, id, &wl_seat_interface);
|
||||
seat = wl_registry_bind(display_wayland->wl_registry, id, &wl_seat_interface, 1);
|
||||
_gdk_wayland_device_manager_add_device (gdk_display->device_manager,
|
||||
seat);
|
||||
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
|
||||
display_wayland->data_device_manager =
|
||||
wl_display_bind(display, id,
|
||||
&wl_data_device_manager_interface);
|
||||
wl_registry_bind(display_wayland->wl_registry, id,
|
||||
&wl_data_device_manager_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +213,10 @@ gdk_display_init_egl(GdkDisplay *display)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
gdk_registry_handle_global
|
||||
};
|
||||
|
||||
GdkDisplay *
|
||||
_gdk_wayland_display_open (const gchar *display_name)
|
||||
{
|
||||
@@ -231,14 +238,13 @@ _gdk_wayland_display_open (const gchar *display_name)
|
||||
display->device_manager = _gdk_wayland_device_manager_new (display);
|
||||
|
||||
/* Set up listener so we'll catch all events. */
|
||||
wl_display_add_global_listener(display_wayland->wl_display,
|
||||
gdk_display_handle_global, display_wayland);
|
||||
display_wayland->wl_registry = wl_display_get_registry(display_wayland->wl_display);
|
||||
wl_registry_add_listener(display_wayland->wl_registry, ®istry_listener, display_wayland);
|
||||
|
||||
#ifdef GDK_WAYLAND_USE_EGL
|
||||
gdk_display_init_egl(display);
|
||||
#else
|
||||
wl_display_iterate(wl_display, WL_DISPLAY_READABLE);
|
||||
wl_display_roundtrip(wl_display);
|
||||
wl_display_dispatch(display_wayland->wl_display);
|
||||
#endif
|
||||
|
||||
display_wayland->event_source =
|
||||
@@ -351,8 +357,7 @@ gdk_wayland_display_flush (GdkDisplay *display)
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
if (!display->closed)
|
||||
_gdk_wayland_display_flush (display,
|
||||
GDK_WAYLAND_DISPLAY (display)->event_source);
|
||||
wl_display_flush(GDK_WAYLAND_DISPLAY (display)->wl_display);;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -76,6 +76,7 @@ struct _GdkWaylandDisplay
|
||||
|
||||
/* Wayland fields below */
|
||||
struct wl_display *wl_display;
|
||||
struct wl_registry *wl_registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shm *shm;
|
||||
struct wl_shell *shell;
|
||||
|
||||
@@ -136,7 +136,7 @@ gdk_wayland_display_manager_lookup_keyval (GdkDisplayManager *manager,
|
||||
{
|
||||
g_return_val_if_fail (keyval_name != NULL, 0);
|
||||
|
||||
return xkb_keysym_from_name(keyval_name);
|
||||
return xkb_keysym_from_name (keyval_name, 0);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
||||
@@ -44,8 +44,7 @@ gdk_event_source_prepare(GSource *base, gint *timeout)
|
||||
if (_gdk_event_queue_find_first (source->display) != NULL)
|
||||
return TRUE;
|
||||
|
||||
while (source->mask & WL_DISPLAY_WRITABLE)
|
||||
wl_display_iterate(display->wl_display, WL_DISPLAY_WRITABLE);
|
||||
wl_display_flush(display->wl_display);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -97,16 +96,6 @@ static GSourceFuncs wl_glib_source_funcs = {
|
||||
gdk_event_source_finalize
|
||||
};
|
||||
|
||||
static int
|
||||
gdk_event_source_update(uint32_t mask, void *data)
|
||||
{
|
||||
GdkWaylandEventSource *source = data;
|
||||
|
||||
source->mask = mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event)
|
||||
{
|
||||
@@ -134,8 +123,7 @@ _gdk_wayland_display_event_source_new (GdkDisplay *display)
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
wl_source->display = display;
|
||||
wl_source->pfd.fd = wl_display_get_fd(display_wayland->wl_display,
|
||||
gdk_event_source_update, source);
|
||||
wl_source->pfd.fd = wl_display_get_fd(display_wayland->wl_display);
|
||||
wl_source->pfd.events = G_IO_IN | G_IO_ERR;
|
||||
g_source_add_poll(source, &wl_source->pfd);
|
||||
|
||||
@@ -148,16 +136,6 @@ _gdk_wayland_display_event_source_new (GdkDisplay *display)
|
||||
return source;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_flush (GdkDisplay *display, GSource *source)
|
||||
{
|
||||
GdkWaylandEventSource *wayland_source = (GdkWaylandEventSource *) source;
|
||||
|
||||
while (wayland_source->mask & WL_DISPLAY_WRITABLE)
|
||||
wl_display_iterate(GDK_WAYLAND_DISPLAY (display)->wl_display,
|
||||
WL_DISPLAY_WRITABLE);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_display_queue_events (GdkDisplay *display)
|
||||
{
|
||||
@@ -166,10 +144,9 @@ _gdk_wayland_display_queue_events (GdkDisplay *display)
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
source = (GdkWaylandEventSource *) display_wayland->event_source;
|
||||
|
||||
if (source->pfd.revents)
|
||||
{
|
||||
wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_READABLE);
|
||||
source->pfd.revents = 0;
|
||||
wl_display_dispatch(display_wayland->wl_display);
|
||||
source->pfd.revents = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ _gdk_wayland_keymap_new ()
|
||||
names.layout = "us";
|
||||
names.variant = "";
|
||||
names.options = "";
|
||||
keymap->xkb_keymap = xkb_map_new_from_names(context, &names, XKB_MAP_COMPILE_PLACEHOLDER);
|
||||
keymap->xkb_keymap = xkb_keymap_new_from_names (context, &names, 0);
|
||||
keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
|
||||
xkb_context_unref (context);
|
||||
|
||||
@@ -246,7 +246,7 @@ _gdk_wayland_keymap_new_from_fd (uint32_t format,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
keymap->xkb_keymap = xkb_map_new_from_string (context, map_str, format, XKB_MAP_COMPILE_PLACEHOLDER);
|
||||
keymap->xkb_keymap = xkb_keymap_new_from_string (context, map_str, format, 0);
|
||||
munmap (map_str, size);
|
||||
close (fd);
|
||||
keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
|
||||
|
||||
@@ -137,7 +137,6 @@ GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device);
|
||||
void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event);
|
||||
GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display);
|
||||
void _gdk_wayland_display_queue_events (GdkDisplay *display);
|
||||
void _gdk_wayland_display_flush (GdkDisplay *display, GSource *source);
|
||||
|
||||
GdkAppLaunchContext *_gdk_wayland_display_get_app_launch_context (GdkDisplay *display);
|
||||
|
||||
|
||||
@@ -1563,6 +1563,7 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window,
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
wl_surface_damage (impl->surface,
|
||||
rect.x, rect.y, rect.width, rect.height);
|
||||
wl_surface_commit(impl->surface);
|
||||
}
|
||||
|
||||
_gdk_window_process_updates_recurse (window, region);
|
||||
|
||||
@@ -431,6 +431,7 @@ gtk_private_h_sources = \
|
||||
gtkcssarrayvalueprivate.h \
|
||||
gtkcssbgsizevalueprivate.h \
|
||||
gtkcssbordervalueprivate.h \
|
||||
gtkcsscolorvalueprivate.h \
|
||||
gtkcsscomputedvaluesprivate.h \
|
||||
gtkcsscornervalueprivate.h \
|
||||
gtkcsscustompropertyprivate.h \
|
||||
@@ -478,6 +479,7 @@ gtk_private_h_sources = \
|
||||
gtkfontchooserprivate.h \
|
||||
gtkfontchooserutils.h \
|
||||
gtkgradientprivate.h \
|
||||
gtkhslaprivate.h \
|
||||
gtkiconcache.h \
|
||||
gtkiconhelperprivate.h \
|
||||
gtkiconviewprivate.h \
|
||||
@@ -517,6 +519,7 @@ gtk_private_h_sources = \
|
||||
gtkselectionprivate.h \
|
||||
gtksettingsprivate.h \
|
||||
gtksizegroup-private.h \
|
||||
gtksizerequestcacheprivate.h \
|
||||
gtksocketprivate.h \
|
||||
gtkstyleanimationprivate.h \
|
||||
gtkstylecascadeprivate.h \
|
||||
@@ -653,6 +656,7 @@ gtk_base_c_sources = \
|
||||
gtkcssarrayvalue.c \
|
||||
gtkcssbgsizevalue.c \
|
||||
gtkcssbordervalue.c \
|
||||
gtkcsscolorvalue.c \
|
||||
gtkcsscomputedvalues.c \
|
||||
gtkcsscornervalue.c \
|
||||
gtkcsscustomproperty.c \
|
||||
@@ -719,6 +723,7 @@ gtk_base_c_sources = \
|
||||
gtkframe.c \
|
||||
gtkgradient.c \
|
||||
gtkgrid.c \
|
||||
gtkhsla.c \
|
||||
gtkiconcache.c \
|
||||
gtkiconcachevalidator.c \
|
||||
gtkiconfactory.c \
|
||||
@@ -804,6 +809,7 @@ gtk_base_c_sources = \
|
||||
gtksettings.c \
|
||||
gtksizegroup.c \
|
||||
gtksizerequest.c \
|
||||
gtksizerequestcache.c \
|
||||
gtkshow.c \
|
||||
gtkspinbutton.c \
|
||||
gtkspinner.c \
|
||||
|
||||
@@ -6,7 +6,6 @@ gail_c_sources = \
|
||||
gail.c \
|
||||
gtkarrowaccessible.c \
|
||||
gtkbooleancellaccessible.c \
|
||||
gtkboxaccessible.c \
|
||||
gtkbuttonaccessible.c \
|
||||
gtkcellaccessible.c \
|
||||
gtkcellaccessibleparent.c \
|
||||
@@ -57,7 +56,6 @@ gail_private_h_sources = \
|
||||
gail.h \
|
||||
gtkarrowaccessible.h \
|
||||
gtkbooleancellaccessible.h \
|
||||
gtkboxaccessible.h \
|
||||
gtkbuttonaccessible.h \
|
||||
gtkcellaccessible.h \
|
||||
gtkcellaccessibleparent.h \
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/* GAIL - The GNOME Accessibility Implementation Library
|
||||
* Copyright 2004 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 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 <gtk/gtk.h>
|
||||
#include "gtkboxaccessible.h"
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GtkBoxAccessible, _gtk_box_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE)
|
||||
|
||||
static void
|
||||
gtk_box_accessible_initialize (AtkObject *accessible,
|
||||
gpointer data)
|
||||
{
|
||||
ATK_OBJECT_CLASS (_gtk_box_accessible_parent_class)->initialize (accessible, data);
|
||||
accessible->role = ATK_ROLE_FILLER;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_box_accessible_class_init (GtkBoxAccessibleClass *klass)
|
||||
{
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
|
||||
class->initialize = gtk_box_accessible_initialize;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_box_accessible_init (GtkBoxAccessible *scale)
|
||||
{
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/* GAIL - The GNOME Accessibility Implementation Library
|
||||
* Copyright 2004 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_BOX_ACCESSIBLE_H__
|
||||
#define __GTK_BOX_ACCESSIBLE_H__
|
||||
|
||||
#include "gtkcontaineraccessible.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_BOX_ACCESSIBLE (_gtk_box_accessible_get_type ())
|
||||
#define GTK_BOX_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_BOX_ACCESSIBLE, GtkBoxAccessible))
|
||||
#define GTK_BOX_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_BOX_ACCESSIBLE, GtkBoxAccessibleClass))
|
||||
#define GTK_IS_BOX_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_BOX_ACCESSIBLE))
|
||||
#define GTK_IS_BOX_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_BOX_ACCESSIBLE))
|
||||
#define GTK_BOX_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_BOX_ACCESSIBLE, GtkBoxAccessibleClass))
|
||||
|
||||
typedef struct _GtkBoxAccessible GtkBoxAccessible;
|
||||
typedef struct _GtkBoxAccessibleClass GtkBoxAccessibleClass;
|
||||
typedef struct _GtkBoxAccessiblePrivate GtkBoxAccessiblePrivate;
|
||||
|
||||
struct _GtkBoxAccessible
|
||||
{
|
||||
GtkContainerAccessible parent;
|
||||
|
||||
GtkBoxAccessiblePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkBoxAccessibleClass
|
||||
{
|
||||
GtkContainerAccessibleClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_box_accessible_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_BOX_ACCESSIBLE_H__ */
|
||||
@@ -17,18 +17,351 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtkpango.h"
|
||||
#include "gtkentryaccessible.h"
|
||||
#include "gtkentryprivate.h"
|
||||
#include "gtkcomboboxaccessible.h"
|
||||
|
||||
#define GTK_TYPE_ENTRY_ICON_ACCESSIBLE (_gtk_entry_icon_accessible_get_type ())
|
||||
#define GTK_ENTRY_ICON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ENTRY_ICON_ACCESSIBLE, GtkEntryIconAccessible))
|
||||
#define GTK_IS_ENTRY_ICON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ENTRY_ICON_ACCESSIBLE))
|
||||
|
||||
struct _GtkEntryAccessiblePrivate
|
||||
{
|
||||
gint cursor_position;
|
||||
gint selection_bound;
|
||||
AtkObject *icons[2];
|
||||
};
|
||||
|
||||
typedef struct _GtkEntryIconAccessible GtkEntryIconAccessible;
|
||||
typedef struct _GtkEntryIconAccessibleClass GtkEntryIconAccessibleClass;
|
||||
|
||||
struct _GtkEntryIconAccessible
|
||||
{
|
||||
AtkObject parent;
|
||||
|
||||
GtkEntryAccessible *entry;
|
||||
GtkEntryIconPosition pos;
|
||||
};
|
||||
|
||||
struct _GtkEntryIconAccessibleClass
|
||||
{
|
||||
AtkObjectClass parent_class;
|
||||
};
|
||||
|
||||
static void atk_action_interface_init (AtkActionIface *iface);
|
||||
|
||||
static void icon_atk_action_interface_init (AtkActionIface *iface);
|
||||
static void icon_atk_component_interface_init (AtkComponentIface *iface);
|
||||
|
||||
GType _gtk_entry_icon_accessible_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkEntryIconAccessible, _gtk_entry_icon_accessible, ATK_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, icon_atk_action_interface_init)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, icon_atk_component_interface_init))
|
||||
|
||||
static void
|
||||
gtk_entry_icon_accessible_remove_entry (gpointer data, GObject *obj)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = data;
|
||||
|
||||
if (icon->entry)
|
||||
{
|
||||
icon->entry = NULL;
|
||||
g_object_notify (G_OBJECT (icon), "accessible-parent");
|
||||
atk_object_notify_state_change (ATK_OBJECT (icon), ATK_STATE_DEFUNCT, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
gtk_entry_icon_accessible_new (GtkEntryAccessible *entry,
|
||||
GtkEntryIconPosition pos)
|
||||
{
|
||||
GtkEntryIconAccessible *icon;
|
||||
AtkObject *accessible;
|
||||
|
||||
icon = g_object_new (_gtk_entry_icon_accessible_get_type (), NULL);
|
||||
icon->entry = entry;
|
||||
g_object_weak_ref (G_OBJECT (entry),
|
||||
gtk_entry_icon_accessible_remove_entry,
|
||||
icon);
|
||||
icon->pos = pos;
|
||||
|
||||
accessible = ATK_OBJECT (icon);
|
||||
atk_object_initialize (accessible, NULL);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_entry_icon_accessible_init (GtkEntryIconAccessible *icon)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_icon_accessible_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (obj);
|
||||
GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (icon->entry));
|
||||
GtkEntry *gtk_entry = GTK_ENTRY (widget);
|
||||
const gchar *name;
|
||||
gchar *text;
|
||||
|
||||
ATK_OBJECT_CLASS (_gtk_entry_icon_accessible_parent_class)->initialize (obj, data);
|
||||
atk_object_set_role (obj, ATK_ROLE_ICON);
|
||||
|
||||
name = gtk_entry_get_icon_name (gtk_entry, icon->pos);
|
||||
if (name)
|
||||
atk_object_set_name (obj, name);
|
||||
|
||||
text = gtk_entry_get_icon_tooltip_text (gtk_entry, icon->pos);
|
||||
if (text)
|
||||
{
|
||||
atk_object_set_description (obj, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
atk_object_set_parent (obj, ATK_OBJECT (icon->entry));
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
gtk_entry_icon_accessible_get_parent (AtkObject *accessible)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (accessible);
|
||||
|
||||
return ATK_OBJECT (icon->entry);
|
||||
}
|
||||
|
||||
static AtkStateSet *
|
||||
gtk_entry_icon_accessible_ref_state_set (AtkObject *accessible)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (accessible);
|
||||
AtkStateSet *set = atk_state_set_new ();
|
||||
AtkStateSet *entry_set;
|
||||
GtkWidget *widget;
|
||||
GtkEntry *gtk_entry;
|
||||
|
||||
if (!icon->entry)
|
||||
{
|
||||
atk_state_set_add_state (set, ATK_STATE_DEFUNCT);
|
||||
return set;
|
||||
}
|
||||
|
||||
entry_set = atk_object_ref_state_set (ATK_OBJECT (icon->entry));
|
||||
if (!entry_set || atk_state_set_contains_state (entry_set, ATK_STATE_DEFUNCT))
|
||||
{
|
||||
atk_state_set_add_state (set, ATK_STATE_DEFUNCT);
|
||||
g_clear_object (&entry_set);
|
||||
return set;
|
||||
}
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (icon->entry));
|
||||
gtk_entry = GTK_ENTRY (widget);
|
||||
|
||||
if (atk_state_set_contains_state (entry_set, ATK_STATE_ENABLED))
|
||||
atk_state_set_add_state (set, ATK_STATE_ENABLED);
|
||||
if (atk_state_set_contains_state (entry_set, ATK_STATE_SENSITIVE))
|
||||
atk_state_set_add_state (set, ATK_STATE_SENSITIVE);
|
||||
if (atk_state_set_contains_state (entry_set, ATK_STATE_SHOWING))
|
||||
atk_state_set_add_state (set, ATK_STATE_SHOWING);
|
||||
if (atk_state_set_contains_state (entry_set, ATK_STATE_VISIBLE))
|
||||
atk_state_set_add_state (set, ATK_STATE_VISIBLE);
|
||||
|
||||
if (!gtk_entry_get_icon_sensitive (gtk_entry, icon->pos))
|
||||
atk_state_set_remove_state (set, ATK_STATE_SENSITIVE);
|
||||
if (!gtk_entry_get_icon_activatable (gtk_entry, icon->pos))
|
||||
atk_state_set_remove_state (set, ATK_STATE_ENABLED);
|
||||
|
||||
g_object_unref (entry_set);
|
||||
return set;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_icon_accessible_invalidate (GtkEntryIconAccessible *icon)
|
||||
{
|
||||
if (!icon->entry)
|
||||
return;
|
||||
g_object_weak_unref (G_OBJECT (icon->entry),
|
||||
gtk_entry_icon_accessible_remove_entry,
|
||||
icon);
|
||||
gtk_entry_icon_accessible_remove_entry (icon, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_icon_accessible_finalize (GObject *object)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (object);
|
||||
|
||||
gtk_entry_icon_accessible_invalidate (icon);
|
||||
|
||||
G_OBJECT_CLASS (_gtk_entry_icon_accessible_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_entry_icon_accessible_class_init (GtkEntryIconAccessibleClass *klass)
|
||||
{
|
||||
AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
atk_class->initialize = gtk_entry_icon_accessible_initialize;
|
||||
atk_class->get_parent = gtk_entry_icon_accessible_get_parent;
|
||||
atk_class->ref_state_set = gtk_entry_icon_accessible_ref_state_set;
|
||||
|
||||
gobject_class->finalize = gtk_entry_icon_accessible_finalize;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_icon_accessible_do_action (AtkAction *action,
|
||||
gint i)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = (GtkEntryIconAccessible *)action;
|
||||
GtkWidget *widget;
|
||||
GtkEntry *gtk_entry;
|
||||
GdkEvent event;
|
||||
GdkRectangle icon_area;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (icon->entry));
|
||||
if (widget == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (i != 0)
|
||||
return FALSE;
|
||||
|
||||
if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
|
||||
return FALSE;
|
||||
|
||||
gtk_entry = GTK_ENTRY (widget);
|
||||
|
||||
if (!gtk_entry_get_icon_sensitive (gtk_entry, icon->pos) ||
|
||||
!gtk_entry_get_icon_activatable (gtk_entry, icon->pos))
|
||||
return FALSE;
|
||||
|
||||
gtk_entry_get_icon_area (gtk_entry, icon->pos, &icon_area);
|
||||
memset (&event, 0, sizeof (event));
|
||||
event.button.type = GDK_BUTTON_PRESS;
|
||||
event.button.window = gtk_widget_get_window (widget);
|
||||
event.button.button = 1;
|
||||
event.button.send_event = TRUE;
|
||||
event.button.time = GDK_CURRENT_TIME;
|
||||
event.button.x = icon_area.x;
|
||||
event.button.y = icon_area.y;
|
||||
|
||||
g_signal_emit_by_name (widget, "icon-press", 0, icon->pos, &event);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_entry_icon_accessible_get_n_actions (AtkAction *action)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (action);
|
||||
GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (icon->entry));
|
||||
GtkEntry *gtk_entry = GTK_ENTRY (widget);
|
||||
|
||||
return (gtk_entry_get_icon_activatable (gtk_entry, icon->pos) ? 1 : 0);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gtk_entry_icon_accessible_get_name (AtkAction *action,
|
||||
gint i)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (action);
|
||||
GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (icon->entry));
|
||||
GtkEntry *gtk_entry = GTK_ENTRY (widget);
|
||||
|
||||
if (i != 0)
|
||||
return NULL;
|
||||
if (!gtk_entry_get_icon_activatable (gtk_entry, icon->pos))
|
||||
return NULL;
|
||||
|
||||
return "activate";
|
||||
}
|
||||
|
||||
static void
|
||||
icon_atk_action_interface_init (AtkActionIface *iface)
|
||||
{
|
||||
iface->do_action = gtk_entry_icon_accessible_do_action;
|
||||
iface->get_n_actions = gtk_entry_icon_accessible_get_n_actions;
|
||||
iface->get_name = gtk_entry_icon_accessible_get_name;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_icon_accessible_get_extents (AtkComponent *component,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height,
|
||||
AtkCoordType coord_type)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (component);
|
||||
GdkRectangle icon_area;
|
||||
GtkEntry *gtk_entry;
|
||||
GtkWidget *widget;
|
||||
|
||||
*x = G_MININT;
|
||||
atk_component_get_extents (ATK_COMPONENT (icon->entry), x, y, width, height,
|
||||
coord_type);
|
||||
if (*x == G_MININT)
|
||||
return;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (icon->entry));
|
||||
gtk_entry = GTK_ENTRY (widget);
|
||||
gtk_entry_get_icon_area (gtk_entry, icon->pos, &icon_area);
|
||||
*width = icon_area.width;
|
||||
*height = icon_area.height;
|
||||
*x += icon_area.x;
|
||||
*y += icon_area.y;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_icon_accessible_get_position (AtkComponent *component,
|
||||
gint *x,
|
||||
gint *y,
|
||||
AtkCoordType coord_type)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (component);
|
||||
GdkRectangle icon_area;
|
||||
GtkEntry *gtk_entry;
|
||||
GtkWidget *widget;
|
||||
|
||||
*x = G_MININT;
|
||||
atk_component_get_position (ATK_COMPONENT (icon->entry), x, y, coord_type);
|
||||
if (*x == G_MININT)
|
||||
return;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (icon->entry));
|
||||
gtk_entry = GTK_ENTRY (widget);
|
||||
gtk_entry_get_icon_area (gtk_entry, icon->pos, &icon_area);
|
||||
*x += icon_area.x;
|
||||
*y += icon_area.y;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_icon_accessible_get_size (AtkComponent *component,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
GtkEntryIconAccessible *icon = GTK_ENTRY_ICON_ACCESSIBLE (component);
|
||||
GdkRectangle icon_area;
|
||||
GtkEntry *gtk_entry;
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (icon->entry));
|
||||
gtk_entry = GTK_ENTRY (widget);
|
||||
gtk_entry_get_icon_area (gtk_entry, icon->pos, &icon_area);
|
||||
*width = icon_area.width;
|
||||
*height = icon_area.height;
|
||||
}
|
||||
|
||||
static void
|
||||
icon_atk_component_interface_init (AtkComponentIface *iface)
|
||||
{
|
||||
iface->get_extents = gtk_entry_icon_accessible_get_extents;
|
||||
iface->get_size = gtk_entry_icon_accessible_get_size;
|
||||
iface->get_position = gtk_entry_icon_accessible_get_position;
|
||||
}
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
static void insert_text_cb (GtkEditable *editable,
|
||||
@@ -137,11 +470,13 @@ gtk_entry_accessible_notify_gtk (GObject *obj,
|
||||
AtkObject* atk_obj;
|
||||
GtkEntry* gtk_entry;
|
||||
GtkEntryAccessible* entry;
|
||||
GtkEntryAccessiblePrivate *priv;
|
||||
|
||||
widget = GTK_WIDGET (obj);
|
||||
atk_obj = gtk_widget_get_accessible (widget);
|
||||
gtk_entry = GTK_ENTRY (widget);
|
||||
entry = GTK_ENTRY_ACCESSIBLE (atk_obj);
|
||||
priv = entry->priv;
|
||||
|
||||
if (g_strcmp0 (pspec->name, "cursor-position") == 0)
|
||||
{
|
||||
@@ -174,6 +509,119 @@ gtk_entry_accessible_notify_gtk (GObject *obj,
|
||||
new_role = visibility ? ATK_ROLE_TEXT : ATK_ROLE_PASSWORD_TEXT;
|
||||
atk_object_set_role (atk_obj, new_role);
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "primary-icon-storage-type") == 0)
|
||||
{
|
||||
if (gtk_entry_get_icon_storage_type (gtk_entry, GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY && !priv->icons[GTK_ENTRY_ICON_PRIMARY])
|
||||
{
|
||||
priv->icons[GTK_ENTRY_ICON_PRIMARY] = gtk_entry_icon_accessible_new (entry, GTK_ENTRY_ICON_PRIMARY);
|
||||
g_signal_emit_by_name (entry, "children-changed::add", 0,
|
||||
priv->icons[GTK_ENTRY_ICON_PRIMARY], NULL);
|
||||
}
|
||||
else if (gtk_entry_get_icon_storage_type (gtk_entry, GTK_ENTRY_ICON_PRIMARY) == GTK_IMAGE_EMPTY && priv->icons[GTK_ENTRY_ICON_PRIMARY])
|
||||
{
|
||||
gtk_entry_icon_accessible_invalidate (GTK_ENTRY_ICON_ACCESSIBLE (priv->icons[GTK_ENTRY_ICON_PRIMARY]));
|
||||
g_signal_emit_by_name (entry, "children-changed::remove", 0,
|
||||
priv->icons[GTK_ENTRY_ICON_PRIMARY], NULL);
|
||||
g_clear_object (&priv->icons[GTK_ENTRY_ICON_PRIMARY]);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "secondary-icon-storage-type") == 0)
|
||||
{
|
||||
gint index = (priv->icons[GTK_ENTRY_ICON_PRIMARY] ? 1 : 0);
|
||||
if (gtk_entry_get_icon_storage_type (gtk_entry, GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY && !priv->icons[GTK_ENTRY_ICON_SECONDARY])
|
||||
{
|
||||
priv->icons[GTK_ENTRY_ICON_SECONDARY] = gtk_entry_icon_accessible_new (entry, GTK_ENTRY_ICON_SECONDARY);
|
||||
g_signal_emit_by_name (entry, "children-changed::add", index,
|
||||
priv->icons[GTK_ENTRY_ICON_SECONDARY], NULL);
|
||||
}
|
||||
else if (gtk_entry_get_icon_storage_type (gtk_entry, GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY && priv->icons[GTK_ENTRY_ICON_SECONDARY])
|
||||
{
|
||||
gtk_entry_icon_accessible_invalidate (GTK_ENTRY_ICON_ACCESSIBLE (priv->icons[GTK_ENTRY_ICON_SECONDARY]));
|
||||
g_signal_emit_by_name (entry, "children-changed::remove", index,
|
||||
priv->icons[GTK_ENTRY_ICON_SECONDARY], NULL);
|
||||
g_clear_object (&priv->icons[GTK_ENTRY_ICON_SECONDARY]);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "primary-icon-name") == 0)
|
||||
{
|
||||
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
|
||||
{
|
||||
const gchar *name;
|
||||
name = gtk_entry_get_icon_name (gtk_entry,
|
||||
GTK_ENTRY_ICON_PRIMARY);
|
||||
atk_object_set_name (priv->icons[GTK_ENTRY_ICON_PRIMARY], name);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "secondary-icon-name") == 0)
|
||||
{
|
||||
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
|
||||
{
|
||||
const gchar *name;
|
||||
name = gtk_entry_get_icon_name (gtk_entry,
|
||||
GTK_ENTRY_ICON_SECONDARY);
|
||||
atk_object_set_name (priv->icons[GTK_ENTRY_ICON_SECONDARY], name);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "primary-icon-tooltip-text") == 0)
|
||||
{
|
||||
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
|
||||
{
|
||||
gchar *text;
|
||||
text = gtk_entry_get_icon_tooltip_text (gtk_entry,
|
||||
GTK_ENTRY_ICON_PRIMARY);
|
||||
atk_object_set_description (priv->icons[GTK_ENTRY_ICON_PRIMARY],
|
||||
text);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "secondary-icon-tooltip-text") == 0)
|
||||
{
|
||||
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
|
||||
{
|
||||
gchar *text;
|
||||
text = gtk_entry_get_icon_tooltip_text (gtk_entry,
|
||||
GTK_ENTRY_ICON_SECONDARY);
|
||||
atk_object_set_description (priv->icons[GTK_ENTRY_ICON_SECONDARY],
|
||||
text);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "primary-icon-activatable") == 0)
|
||||
{
|
||||
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
|
||||
{
|
||||
gboolean on = gtk_entry_get_icon_activatable (gtk_entry, GTK_ENTRY_ICON_PRIMARY);
|
||||
atk_object_notify_state_change (priv->icons[GTK_ENTRY_ICON_PRIMARY],
|
||||
ATK_STATE_ENABLED, on);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "secondary-icon-activatable") == 0)
|
||||
{
|
||||
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
|
||||
{
|
||||
gboolean on = gtk_entry_get_icon_activatable (gtk_entry, GTK_ENTRY_ICON_SECONDARY);
|
||||
atk_object_notify_state_change (priv->icons[GTK_ENTRY_ICON_SECONDARY],
|
||||
ATK_STATE_ENABLED, on);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "primary-icon-sensitive") == 0)
|
||||
{
|
||||
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
|
||||
{
|
||||
gboolean on = gtk_entry_get_icon_sensitive (gtk_entry, GTK_ENTRY_ICON_PRIMARY);
|
||||
atk_object_notify_state_change (priv->icons[GTK_ENTRY_ICON_PRIMARY],
|
||||
ATK_STATE_SENSITIVE, on);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "secondary-icon-sensitive") == 0)
|
||||
{
|
||||
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
|
||||
{
|
||||
gboolean on = gtk_entry_get_icon_sensitive (gtk_entry, GTK_ENTRY_ICON_SECONDARY);
|
||||
atk_object_notify_state_change (priv->icons[GTK_ENTRY_ICON_SECONDARY],
|
||||
ATK_STATE_SENSITIVE, on);
|
||||
}
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_entry_accessible_parent_class)->notify_gtk (obj, pspec);
|
||||
}
|
||||
@@ -192,19 +640,98 @@ gtk_entry_accessible_get_index_in_parent (AtkObject *accessible)
|
||||
return ATK_OBJECT_CLASS (_gtk_entry_accessible_parent_class)->get_index_in_parent (accessible);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_entry_accessible_get_n_children (AtkObject* obj)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkEntry *entry;
|
||||
gint count = 0;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
|
||||
if (widget == NULL)
|
||||
return 0;
|
||||
|
||||
entry = GTK_ENTRY (widget);
|
||||
|
||||
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY)
|
||||
count++;
|
||||
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
gtk_entry_accessible_ref_child (AtkObject *obj,
|
||||
gint i)
|
||||
{
|
||||
GtkEntryAccessible *accessible = GTK_ENTRY_ACCESSIBLE (obj);
|
||||
GtkEntryAccessiblePrivate *priv = accessible->priv;
|
||||
GtkWidget *widget;
|
||||
GtkEntry *entry;
|
||||
GtkEntryIconPosition pos;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
|
||||
if (widget == NULL)
|
||||
return NULL;
|
||||
|
||||
entry = GTK_ENTRY (widget);
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_PRIMARY) != GTK_IMAGE_EMPTY)
|
||||
pos = GTK_ENTRY_ICON_PRIMARY;
|
||||
else if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) != GTK_IMAGE_EMPTY)
|
||||
pos = GTK_ENTRY_ICON_SECONDARY;
|
||||
else
|
||||
return NULL;
|
||||
break;
|
||||
case 1:
|
||||
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_PRIMARY) == GTK_IMAGE_EMPTY)
|
||||
return NULL;
|
||||
if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY)
|
||||
return NULL;
|
||||
pos = GTK_ENTRY_ICON_SECONDARY;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!priv->icons[pos])
|
||||
priv->icons[pos] = gtk_entry_icon_accessible_new (accessible, pos);
|
||||
return g_object_ref (priv->icons[pos]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_accessible_finalize (GObject *object)
|
||||
{
|
||||
GtkEntryAccessible *entry = GTK_ENTRY_ACCESSIBLE (object);
|
||||
GtkEntryAccessiblePrivate *priv = entry->priv;
|
||||
|
||||
g_clear_object (&priv->icons[GTK_ENTRY_ICON_PRIMARY]);
|
||||
g_clear_object (&priv->icons[GTK_ENTRY_ICON_SECONDARY]);
|
||||
|
||||
G_OBJECT_CLASS (_gtk_entry_accessible_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_entry_accessible_class_init (GtkEntryAccessibleClass *klass)
|
||||
{
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
class->ref_state_set = gtk_entry_accessible_ref_state_set;
|
||||
class->get_index_in_parent = gtk_entry_accessible_get_index_in_parent;
|
||||
class->initialize = gtk_entry_accessible_initialize;
|
||||
class->get_attributes = gtk_entry_accessible_get_attributes;
|
||||
class->get_n_children = gtk_entry_accessible_get_n_children;
|
||||
class->ref_child = gtk_entry_accessible_ref_child;
|
||||
|
||||
widget_class->notify_gtk = gtk_entry_accessible_notify_gtk;
|
||||
|
||||
gobject_class->finalize = gtk_entry_accessible_finalize;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkEntryAccessiblePrivate));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "gtkstatusbaraccessible.h"
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GtkStatusbarAccessible, _gtk_statusbar_accessible, GTK_TYPE_BOX_ACCESSIBLE)
|
||||
G_DEFINE_TYPE (GtkStatusbarAccessible, _gtk_statusbar_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE)
|
||||
|
||||
static void
|
||||
text_changed (GtkStatusbar *statusbar,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef __GTK_STATUSBAR_ACCESSIBLE_H__
|
||||
#define __GTK_STATUSBAR_ACCESSIBLE_H__
|
||||
|
||||
#include "gtkboxaccessible.h"
|
||||
#include "gtkcontaineraccessible.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -35,14 +35,14 @@ typedef struct _GtkStatusbarAccessiblePrivate GtkStatusbarAccessiblePrivate;
|
||||
|
||||
struct _GtkStatusbarAccessible
|
||||
{
|
||||
GtkBoxAccessible parent;
|
||||
GtkContainerAccessible parent;
|
||||
|
||||
GtkStatusbarAccessiblePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkStatusbarAccessibleClass
|
||||
{
|
||||
GtkBoxAccessibleClass parent_class;
|
||||
GtkContainerAccessibleClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_statusbar_accessible_get_type (void);
|
||||
|
||||
@@ -552,7 +552,6 @@ gtk_text_cell_accessible_get_character_extents (AtkText *text,
|
||||
gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
|
||||
g_object_get (gail_renderer, "renderer", >k_renderer, NULL);
|
||||
g_object_get (gtk_renderer, "text", &renderer_text, NULL);
|
||||
g_object_unref (gtk_renderer);
|
||||
if (renderer_text == NULL)
|
||||
{
|
||||
g_object_unref (gtk_renderer);
|
||||
|
||||
@@ -262,7 +262,7 @@ gtk_window_accessible_ref_state_set (AtkObject *accessible)
|
||||
atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
|
||||
|
||||
gdk_window = gtk_widget_get_window (widget);
|
||||
if (window)
|
||||
if (gdk_window)
|
||||
{
|
||||
state = gdk_window_get_state (gdk_window);
|
||||
if (state & GDK_WINDOW_STATE_ICONIFIED)
|
||||
@@ -307,6 +307,7 @@ gtk_window_accessible_get_extents (AtkComponent *component,
|
||||
AtkCoordType coord_type)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GdkWindow *window;
|
||||
GdkRectangle rect;
|
||||
gint x_toplevel, y_toplevel;
|
||||
|
||||
@@ -323,7 +324,11 @@ gtk_window_accessible_get_extents (AtkComponent *component,
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
|
||||
window = gtk_widget_get_window (widget);
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
gdk_window_get_frame_extents (window, &rect);
|
||||
|
||||
*width = rect.width;
|
||||
*height = rect.height;
|
||||
@@ -338,8 +343,7 @@ gtk_window_accessible_get_extents (AtkComponent *component,
|
||||
*y = rect.y;
|
||||
if (coord_type == ATK_XY_WINDOW)
|
||||
{
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget),
|
||||
&x_toplevel, &y_toplevel);
|
||||
gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
|
||||
*x -= x_toplevel;
|
||||
*y -= y_toplevel;
|
||||
}
|
||||
@@ -351,6 +355,7 @@ gtk_window_accessible_get_size (AtkComponent *component,
|
||||
gint *height)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GdkWindow *window;
|
||||
GdkRectangle rect;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
|
||||
@@ -366,7 +371,11 @@ gtk_window_accessible_get_size (AtkComponent *component,
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
|
||||
window = gtk_widget_get_window (widget);
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
gdk_window_get_frame_extents (window, &rect);
|
||||
|
||||
*width = rect.width;
|
||||
*height = rect.height;
|
||||
|
||||
@@ -715,5 +715,17 @@ GtkCalendar.button:hover {
|
||||
}
|
||||
|
||||
.spinner:active {
|
||||
background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.916667)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.833333)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.75)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.666667)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.583333)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.5)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.416667)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.333333)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.25)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.166667)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.0833333)), to(transparent)),
|
||||
-gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent));
|
||||
animation: spinner 1s infinite linear;
|
||||
}
|
||||
|
||||
+12
-5
@@ -28,7 +28,9 @@
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
#ifdef G_OS_UNIX
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#endif
|
||||
#include <gtk.h>
|
||||
|
||||
static gchar **args = NULL;
|
||||
@@ -45,8 +47,10 @@ main (int argc, char *argv[])
|
||||
GOptionContext *context = NULL;
|
||||
gchar *summary;
|
||||
gchar *app_name;
|
||||
#ifdef G_OS_UNIX
|
||||
gchar *desktop_file_name;
|
||||
GDesktopAppInfo *info;
|
||||
#endif
|
||||
GAppInfo *info = NULL;
|
||||
GAppLaunchContext *launch_context;
|
||||
GList *l;
|
||||
GFile *f;
|
||||
@@ -61,8 +65,6 @@ main (int argc, char *argv[])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
g_type_init ();
|
||||
|
||||
/* Translators: this message will appear immediately after the */
|
||||
/* usage string - Usage: COMMAND [OPTION]... <THIS_MESSAGE> */
|
||||
context =
|
||||
@@ -107,12 +109,17 @@ main (int argc, char *argv[])
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
app_name = *args;
|
||||
#ifdef G_OS_UNIX
|
||||
if (g_str_has_suffix (app_name, ".desktop"))
|
||||
desktop_file_name = g_strdup (app_name);
|
||||
else
|
||||
desktop_file_name = g_strconcat (app_name, ".desktop", NULL);
|
||||
info = g_desktop_app_info_new (desktop_file_name);
|
||||
info = G_APP_INFO (g_desktop_app_info_new (desktop_file_name));
|
||||
g_free (desktop_file_name);
|
||||
#else
|
||||
#warning Please add support for creating AppInfo from id for your OS
|
||||
g_printerr (_("Creating AppInfo from id not supported on non unix operating systems"));
|
||||
#endif
|
||||
args++;
|
||||
|
||||
if (!info)
|
||||
@@ -133,7 +140,7 @@ main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
launch_context = (GAppLaunchContext*) gdk_display_get_app_launch_context (gdk_display_get_default ());
|
||||
if (!g_app_info_launch (G_APP_INFO (info), l, launch_context, &error))
|
||||
if (!g_app_info_launch (info, l, launch_context, &error))
|
||||
{
|
||||
/* Translators: the first %s is the program name, the second one */
|
||||
/* is the error message. */
|
||||
|
||||
@@ -2589,6 +2589,8 @@ gtk_level_bar_set_min_value
|
||||
gtk_level_bar_get_min_value
|
||||
gtk_level_bar_set_max_value
|
||||
gtk_level_bar_get_max_value
|
||||
gtk_level_bar_set_inverted
|
||||
gtk_level_bar_get_inverted
|
||||
gtk_level_bar_add_offset_value
|
||||
gtk_level_bar_remove_offset_value
|
||||
gtk_level_bar_get_offset_value
|
||||
@@ -3706,6 +3708,7 @@ gtk_widget_is_composited
|
||||
gtk_widget_is_drawable
|
||||
gtk_widget_is_focus
|
||||
gtk_widget_is_sensitive
|
||||
gtk_widget_is_visible
|
||||
gtk_widget_is_toplevel
|
||||
gtk_widget_keynav_failed
|
||||
gtk_widget_list_accel_closures
|
||||
|
||||
@@ -2664,7 +2664,7 @@ gtk_about_dialog_get_license_type (GtkAboutDialog *about)
|
||||
* gtk_about_dialog_add_credit_section:
|
||||
* @about: A #GtkAboutDialog
|
||||
* @section_name: The name of the section
|
||||
* @people: The people who belong to that section
|
||||
* @people: (array zero-terminated=1): The people who belong to that section
|
||||
*
|
||||
* Creates a new section in the Credits page.
|
||||
*
|
||||
|
||||
@@ -768,8 +768,9 @@ gtk_application_class_init (GtkApplicationClass *class)
|
||||
*
|
||||
* Creates a new #GtkApplication instance.
|
||||
*
|
||||
* This function calls g_type_init() for you. gtk_init() is called
|
||||
* as soon as the application gets registered as the primary instance.
|
||||
* When using #GtkApplication, it is not necessary to call gtk_init()
|
||||
* manually. It is called as soon as the application gets registered as
|
||||
* the primary instance.
|
||||
*
|
||||
* Concretely, gtk_init() is called in the default handler for the
|
||||
* #GApplication::startup signal. Therefore, #GtkApplication subclasses should
|
||||
@@ -800,8 +801,6 @@ gtk_application_new (const gchar *application_id,
|
||||
{
|
||||
g_return_val_if_fail (application_id == NULL || g_application_id_is_valid (application_id), NULL);
|
||||
|
||||
g_type_init ();
|
||||
|
||||
return g_object_new (GTK_TYPE_APPLICATION,
|
||||
"application-id", application_id,
|
||||
"flags", flags,
|
||||
|
||||
+102
-58
@@ -56,7 +56,12 @@ static void gtk_bin_forall (GtkContainer *container,
|
||||
gpointer callback_data);
|
||||
static GType gtk_bin_child_type (GtkContainer *container);
|
||||
|
||||
|
||||
static void gtk_bin_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width);
|
||||
static void gtk_bin_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
static void gtk_bin_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
@@ -65,6 +70,8 @@ static void gtk_bin_get_preferred_height_for_width (GtkWidget
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height);
|
||||
static void gtk_bin_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GtkBin, gtk_bin, GTK_TYPE_CONTAINER)
|
||||
|
||||
@@ -74,8 +81,11 @@ gtk_bin_class_init (GtkBinClass *class)
|
||||
GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
|
||||
GtkContainerClass *container_class = (GtkContainerClass*) class;
|
||||
|
||||
widget_class->get_preferred_width = gtk_bin_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_bin_get_preferred_height;
|
||||
widget_class->get_preferred_width_for_height = gtk_bin_get_preferred_width_for_height;
|
||||
widget_class->get_preferred_height_for_width = gtk_bin_get_preferred_height_for_width;
|
||||
widget_class->size_allocate = gtk_bin_size_allocate;
|
||||
|
||||
container_class->add = gtk_bin_add;
|
||||
container_class->remove = gtk_bin_remove;
|
||||
@@ -170,43 +180,59 @@ gtk_bin_forall (GtkContainer *container,
|
||||
(* callback) (priv->child, callback_data);
|
||||
}
|
||||
|
||||
|
||||
/* GtkBin widgets define the padding and borders independantly so
|
||||
* we cannot provide a generic get_size() for the same reason
|
||||
* we never implemented size_request() here.
|
||||
*
|
||||
* But for cases where the GtkBin class's padding is constant and
|
||||
* does not vary based on allocation (most cases), we can at least
|
||||
* deduce a common code path for the get_width_for_height()/get_height_for_width()
|
||||
* cases by using the delta of the base size requsts.
|
||||
*/
|
||||
static void
|
||||
get_child_padding_delta (GtkBin *bin,
|
||||
gint *delta_h,
|
||||
gint *delta_v)
|
||||
static int
|
||||
gtk_bin_get_effective_border_width (GtkBin *bin)
|
||||
{
|
||||
if (GTK_CONTAINER_CLASS (GTK_BIN_GET_CLASS (bin))->_handle_border_width)
|
||||
return 0;
|
||||
|
||||
return gtk_container_get_border_width (GTK_CONTAINER (bin));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_bin_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
GtkBin *bin = GTK_BIN (widget);
|
||||
GtkBinPrivate *priv = bin->priv;
|
||||
gint hmin, vmin, hnat, vnat, child_hmin, child_vmin;
|
||||
gint border_width;
|
||||
|
||||
/* we can't use gtk_widget_get_preferred_width() wrapper
|
||||
* because we want our "original" request, not any external
|
||||
* adjustments from set_size_request() or whatever. we have
|
||||
* to ask for natural also because NULL isn't allowed for the
|
||||
* direct vfuncs
|
||||
*/
|
||||
GTK_WIDGET_GET_CLASS (bin)->get_preferred_width (GTK_WIDGET (bin), &hmin, &hnat);
|
||||
GTK_WIDGET_GET_CLASS (bin)->adjust_size_request (GTK_WIDGET (bin),
|
||||
GTK_ORIENTATION_HORIZONTAL, &hmin, &hnat);
|
||||
if (priv->child && gtk_widget_get_visible (priv->child))
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
gtk_widget_get_preferred_width (priv->child,
|
||||
&child_min, &child_nat);
|
||||
*minimum_width = child_min;
|
||||
*natural_width = child_nat;
|
||||
}
|
||||
|
||||
GTK_WIDGET_GET_CLASS (bin)->get_preferred_height (GTK_WIDGET (bin), &vmin, &vnat);
|
||||
GTK_WIDGET_GET_CLASS (bin)->adjust_size_request (GTK_WIDGET (bin),
|
||||
GTK_ORIENTATION_VERTICAL, &vmin, &vnat);
|
||||
border_width = gtk_bin_get_effective_border_width (bin);
|
||||
*minimum_width += 2 * border_width;
|
||||
*natural_width += 2 * border_width;
|
||||
}
|
||||
|
||||
gtk_widget_get_preferred_width (priv->child, &child_hmin, NULL);
|
||||
gtk_widget_get_preferred_height (priv->child, &child_vmin, NULL);
|
||||
static void
|
||||
gtk_bin_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
GtkBin *bin = GTK_BIN (widget);
|
||||
GtkBinPrivate *priv = bin->priv;
|
||||
gint border_width;
|
||||
|
||||
*delta_h = hmin - child_hmin;
|
||||
*delta_v = vmin - child_vmin;
|
||||
if (priv->child && gtk_widget_get_visible (priv->child))
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
gtk_widget_get_preferred_height (priv->child,
|
||||
&child_min, &child_nat);
|
||||
*minimum_height = child_min;
|
||||
*natural_height = child_nat;
|
||||
}
|
||||
|
||||
border_width = gtk_bin_get_effective_border_width (bin);
|
||||
*minimum_height += 2 * border_width;
|
||||
*natural_height += 2 * border_width;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -217,24 +243,22 @@ gtk_bin_get_preferred_width_for_height (GtkWidget *widget,
|
||||
{
|
||||
GtkBin *bin = GTK_BIN (widget);
|
||||
GtkBinPrivate *priv = bin->priv;
|
||||
gint hdelta, vdelta, child_min, child_nat;
|
||||
gint border_width;
|
||||
|
||||
if (priv->child)
|
||||
border_width = gtk_bin_get_effective_border_width (bin);
|
||||
|
||||
if (priv->child && gtk_widget_get_visible (priv->child))
|
||||
{
|
||||
get_child_padding_delta (bin, &hdelta, &vdelta);
|
||||
|
||||
gtk_widget_get_preferred_width_for_height (priv->child,
|
||||
height - vdelta,
|
||||
gint child_min, child_nat;
|
||||
gtk_widget_get_preferred_width_for_height (priv->child, height - 2 * border_width,
|
||||
&child_min, &child_nat);
|
||||
|
||||
if (minimum_width)
|
||||
*minimum_width = child_min + hdelta;
|
||||
|
||||
if (natural_width)
|
||||
*natural_width = child_nat + hdelta;
|
||||
*minimum_width = child_min;
|
||||
*natural_width = child_nat;
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
|
||||
|
||||
*minimum_width += 2 * border_width;
|
||||
*natural_width += 2 * border_width;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -245,26 +269,46 @@ gtk_bin_get_preferred_height_for_width (GtkWidget *widget,
|
||||
{
|
||||
GtkBin *bin = GTK_BIN (widget);
|
||||
GtkBinPrivate *priv = bin->priv;
|
||||
gint hdelta, vdelta, child_min, child_nat;
|
||||
gint border_width;
|
||||
|
||||
if (priv->child)
|
||||
border_width = gtk_bin_get_effective_border_width (bin);
|
||||
|
||||
if (priv->child && gtk_widget_get_visible (priv->child))
|
||||
{
|
||||
get_child_padding_delta (bin, &hdelta, &vdelta);
|
||||
|
||||
gtk_widget_get_preferred_height_for_width (priv->child,
|
||||
width - hdelta,
|
||||
gint child_min, child_nat;
|
||||
gtk_widget_get_preferred_height_for_width (priv->child, width - 2 * border_width,
|
||||
&child_min, &child_nat);
|
||||
|
||||
if (minimum_height)
|
||||
*minimum_height = child_min + vdelta;
|
||||
|
||||
if (natural_height)
|
||||
*natural_height = child_nat + vdelta;
|
||||
*minimum_height = child_min;
|
||||
*natural_height = child_nat;
|
||||
}
|
||||
else
|
||||
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
|
||||
|
||||
*minimum_height += 2 * border_width;
|
||||
*natural_height += 2 * border_width;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_bin_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkBin *bin = GTK_BIN (widget);
|
||||
GtkBinPrivate *priv = bin->priv;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
if (priv->child && gtk_widget_get_visible (priv->child))
|
||||
{
|
||||
GtkAllocation child_allocation;
|
||||
gint border_width = gtk_bin_get_effective_border_width (bin);
|
||||
|
||||
child_allocation.x = allocation->x + border_width;
|
||||
child_allocation.y = allocation->y + border_width;
|
||||
child_allocation.width = allocation->width - 2 * border_width;
|
||||
child_allocation.height = allocation->height - 2 * border_width;
|
||||
|
||||
gtk_widget_size_allocate (priv->child, &child_allocation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_bin_get_child:
|
||||
|
||||
@@ -159,9 +159,9 @@ static inline gboolean
|
||||
_gtk_bitmask_intersects (const GtkBitmask *mask,
|
||||
const GtkBitmask *other)
|
||||
{
|
||||
if (!_gtk_bitmask_is_allocated (mask) ||
|
||||
!_gtk_bitmask_is_allocated (other))
|
||||
if (_gtk_bitmask_is_allocated (mask) ||
|
||||
_gtk_bitmask_is_allocated (other))
|
||||
return _gtk_allocated_bitmask_intersects (mask, other);
|
||||
else
|
||||
return _gtk_bitmask_to_bits (mask) & _gtk_bitmask_to_bits (other);
|
||||
return _gtk_bitmask_to_bits (mask) & _gtk_bitmask_to_bits (other) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ static void
|
||||
gtk_border_image_compute_border_size (GtkBorderImageSliceSize sizes[3],
|
||||
double offset,
|
||||
double area_size,
|
||||
int start_border_width,
|
||||
int end_border_width,
|
||||
double start_border_width,
|
||||
double end_border_width,
|
||||
const GtkCssValue *start_border,
|
||||
const GtkCssValue *end_border)
|
||||
{
|
||||
@@ -235,7 +235,7 @@ gtk_border_image_compute_slice_size (GtkBorderImageSliceSize sizes[3],
|
||||
|
||||
void
|
||||
_gtk_border_image_render (GtkBorderImage *image,
|
||||
GtkBorder *border_width,
|
||||
const double border_width[4],
|
||||
cairo_t *cr,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
@@ -270,15 +270,15 @@ _gtk_border_image_render (GtkBorderImage *image,
|
||||
gtk_border_image_compute_border_size (horizontal_border,
|
||||
x,
|
||||
width,
|
||||
border_width->left,
|
||||
border_width->right,
|
||||
border_width[GTK_CSS_LEFT],
|
||||
border_width[GTK_CSS_RIGHT],
|
||||
_gtk_css_border_value_get_left (image->width),
|
||||
_gtk_css_border_value_get_right (image->width));
|
||||
gtk_border_image_compute_border_size (vertical_border,
|
||||
y,
|
||||
height,
|
||||
border_width->top,
|
||||
border_width->bottom,
|
||||
border_width[GTK_CSS_TOP],
|
||||
border_width[GTK_CSS_BOTTOM],
|
||||
_gtk_css_border_value_get_top (image->width),
|
||||
_gtk_css_border_value_get_bottom(image->width));
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ gboolean _gtk_border_image_init (GtkBorderImage *imag
|
||||
GtkThemingEngine *engine);
|
||||
|
||||
void _gtk_border_image_render (GtkBorderImage *image,
|
||||
GtkBorder *border_width,
|
||||
const double border_width[4],
|
||||
cairo_t *cr,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
|
||||
+2
-2
@@ -87,7 +87,7 @@
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtkwidgetpath.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "a11y/gtkboxaccessible.h"
|
||||
#include "a11y/gtkcontaineraccessible.h"
|
||||
|
||||
|
||||
enum {
|
||||
@@ -317,7 +317,7 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GtkBoxPrivate));
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_BOX_ACCESSIBLE);
|
||||
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_FILLER);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+14
-45
@@ -42,6 +42,7 @@
|
||||
#include "gtkmain.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtksizerequestcacheprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtkassistant.h"
|
||||
@@ -1753,8 +1754,7 @@ _gtk_container_queue_resize_internal (GtkContainer *container,
|
||||
do
|
||||
{
|
||||
_gtk_widget_set_alloc_needed (widget, TRUE);
|
||||
_gtk_widget_set_width_request_needed (widget, TRUE);
|
||||
_gtk_widget_set_height_request_needed (widget, TRUE);
|
||||
_gtk_size_request_cache_clear (_gtk_widget_peek_request_cache (widget));
|
||||
|
||||
if (GTK_IS_RESIZE_CONTAINER (widget))
|
||||
break;
|
||||
@@ -1918,32 +1918,11 @@ gtk_container_adjust_size_allocation (GtkWidget *widget,
|
||||
|
||||
container = GTK_CONTAINER (widget);
|
||||
|
||||
if (!GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width)
|
||||
if (GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width)
|
||||
{
|
||||
parent_class->adjust_size_allocation (widget, orientation,
|
||||
minimum_size, natural_size, allocated_pos,
|
||||
allocated_size);
|
||||
return;
|
||||
}
|
||||
border_width = container->priv->border_width;
|
||||
|
||||
border_width = container->priv->border_width;
|
||||
|
||||
*allocated_size -= border_width * 2;
|
||||
|
||||
/* If we get a pathological too-small allocation to hold
|
||||
* even the border width, leave all allocation to the actual
|
||||
* widget, and leave x,y unchanged. (GtkWidget's min size is
|
||||
* 1x1 if you're wondering why <1 and not <0)
|
||||
*
|
||||
* As long as we have space, set x,y properly.
|
||||
*/
|
||||
|
||||
if (*allocated_size < 1)
|
||||
{
|
||||
*allocated_size += border_width * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*allocated_size -= border_width * 2;
|
||||
*allocated_pos += border_width;
|
||||
*minimum_size -= border_width * 2;
|
||||
*natural_size -= border_width * 2;
|
||||
@@ -1989,27 +1968,17 @@ count_request_modes (GtkWidget *widget,
|
||||
static GtkSizeRequestMode
|
||||
gtk_container_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
GtkContainer *container = GTK_CONTAINER (widget);
|
||||
GtkContainerPrivate *priv = container->priv;
|
||||
GtkContainer *container = GTK_CONTAINER (widget);
|
||||
RequestModeCount count = { 0, 0 };
|
||||
|
||||
/* Recalculate the request mode of the children by majority
|
||||
* vote whenever the internal content changes */
|
||||
if (_gtk_widget_get_width_request_needed (widget) ||
|
||||
_gtk_widget_get_height_request_needed (widget))
|
||||
{
|
||||
RequestModeCount count = { 0, 0 };
|
||||
gtk_container_forall (container, (GtkCallback)count_request_modes, &count);
|
||||
|
||||
gtk_container_forall (container, (GtkCallback)count_request_modes, &count);
|
||||
|
||||
if (!count.hfw && !count.wfh)
|
||||
priv->request_mode = GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
else
|
||||
priv->request_mode = count.wfh > count.hfw ?
|
||||
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT :
|
||||
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
return priv->request_mode;
|
||||
if (!count.hfw && !count.wfh)
|
||||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
else
|
||||
return count.wfh > count.hfw ?
|
||||
GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT :
|
||||
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+27
-10
@@ -261,16 +261,33 @@ _gtk_css_bg_size_value_compute_size (const GtkCssValue *value,
|
||||
g_return_if_fail (value->class == >K_CSS_VALUE_BG_SIZE);
|
||||
|
||||
if (value->contain || value->cover)
|
||||
gtk_css_bg_size_compute_size_for_cover_contain (value->cover,
|
||||
image,
|
||||
area_width, area_height,
|
||||
out_width, out_height);
|
||||
{
|
||||
gtk_css_bg_size_compute_size_for_cover_contain (value->cover,
|
||||
image,
|
||||
area_width, area_height,
|
||||
out_width, out_height);
|
||||
}
|
||||
else
|
||||
_gtk_css_image_get_concrete_size (image,
|
||||
/* note: 0 does the right thing here for 'auto' */
|
||||
value->x ? _gtk_css_number_value_get (value->x, area_width) : 0,
|
||||
value->y ? _gtk_css_number_value_get (value->y, area_height) : 0,
|
||||
area_width, area_height,
|
||||
out_width, out_height);
|
||||
{
|
||||
double x, y;
|
||||
|
||||
/* note: 0 does the right thing later for 'auto' */
|
||||
x = value->x ? _gtk_css_number_value_get (value->x, area_width) : 0;
|
||||
y = value->y ? _gtk_css_number_value_get (value->y, area_height) : 0;
|
||||
|
||||
if ((x <= 0 && value->x) ||
|
||||
(y <= 0 && value->y))
|
||||
{
|
||||
*out_width = 0;
|
||||
*out_height = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_image_get_concrete_size (image,
|
||||
x, y,
|
||||
area_width, area_height,
|
||||
out_width, out_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,848 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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 "gtkcsscolorvalueprivate.h"
|
||||
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkhslaprivate.h"
|
||||
#include "gtkstylepropertyprivate.h"
|
||||
#include "gtkstyleproperties.h"
|
||||
#include "gtksymboliccolorprivate.h"
|
||||
#include "gtkwin32themeprivate.h"
|
||||
|
||||
typedef enum {
|
||||
COLOR_TYPE_LITERAL,
|
||||
COLOR_TYPE_NAME,
|
||||
COLOR_TYPE_SHADE,
|
||||
COLOR_TYPE_ALPHA,
|
||||
COLOR_TYPE_MIX,
|
||||
COLOR_TYPE_WIN32,
|
||||
COLOR_TYPE_CURRENT_COLOR
|
||||
} ColorType;
|
||||
|
||||
struct _GtkCssValue
|
||||
{
|
||||
GTK_CSS_VALUE_BASE
|
||||
ColorType type;
|
||||
GtkCssValue *last_value;
|
||||
|
||||
union
|
||||
{
|
||||
gchar *name;
|
||||
|
||||
struct
|
||||
{
|
||||
GtkCssValue *color;
|
||||
gdouble factor;
|
||||
} shade, alpha;
|
||||
|
||||
struct
|
||||
{
|
||||
GtkCssValue *color1;
|
||||
GtkCssValue *color2;
|
||||
gdouble factor;
|
||||
} mix;
|
||||
|
||||
struct
|
||||
{
|
||||
gchar *theme_class;
|
||||
gint id;
|
||||
} win32;
|
||||
} sym_col;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_css_value_color_free (GtkCssValue *color)
|
||||
{
|
||||
if (color->last_value)
|
||||
_gtk_css_value_unref (color->last_value);
|
||||
|
||||
switch (color->type)
|
||||
{
|
||||
case COLOR_TYPE_NAME:
|
||||
g_free (color->sym_col.name);
|
||||
break;
|
||||
case COLOR_TYPE_SHADE:
|
||||
_gtk_css_value_unref (color->sym_col.shade.color);
|
||||
break;
|
||||
case COLOR_TYPE_ALPHA:
|
||||
_gtk_css_value_unref (color->sym_col.alpha.color);
|
||||
break;
|
||||
case COLOR_TYPE_MIX:
|
||||
_gtk_css_value_unref (color->sym_col.mix.color1);
|
||||
_gtk_css_value_unref (color->sym_col.mix.color2);
|
||||
break;
|
||||
case COLOR_TYPE_WIN32:
|
||||
g_free (color->sym_col.win32.theme_class);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_slice_free (GtkCssValue, color);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_color_get_fallback (guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values)
|
||||
{
|
||||
static const GdkRGBA transparent = { 0, 0, 0, 0 };
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case GTK_CSS_PROPERTY_BACKGROUND_IMAGE:
|
||||
case GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE:
|
||||
case GTK_CSS_PROPERTY_TEXT_SHADOW:
|
||||
case GTK_CSS_PROPERTY_ICON_SHADOW:
|
||||
case GTK_CSS_PROPERTY_BOX_SHADOW:
|
||||
return _gtk_css_rgba_value_new_from_rgba (&transparent);
|
||||
case GTK_CSS_PROPERTY_COLOR:
|
||||
case GTK_CSS_PROPERTY_BACKGROUND_COLOR:
|
||||
case GTK_CSS_PROPERTY_BORDER_TOP_COLOR:
|
||||
case GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR:
|
||||
case GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR:
|
||||
case GTK_CSS_PROPERTY_BORDER_LEFT_COLOR:
|
||||
case GTK_CSS_PROPERTY_OUTLINE_COLOR:
|
||||
return _gtk_css_value_compute (_gtk_css_style_property_get_initial_value (_gtk_css_style_property_lookup_by_id (property_id)),
|
||||
property_id,
|
||||
provider,
|
||||
values,
|
||||
parent_values,
|
||||
NULL);
|
||||
default:
|
||||
if (property_id < GTK_CSS_PROPERTY_N_PROPERTIES)
|
||||
g_warning ("No fallback color defined for property '%s'",
|
||||
_gtk_style_property_get_name (GTK_STYLE_PROPERTY (_gtk_css_style_property_lookup_by_id (property_id))));
|
||||
return _gtk_css_rgba_value_new_from_rgba (&transparent);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_color_value_resolve_full (GtkCssValue *color,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
GtkCssValue *current,
|
||||
GtkCssDependencies current_deps,
|
||||
GtkCssDependencies *dependencies)
|
||||
{
|
||||
GtkCssDependencies unused;
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (color != NULL, FALSE);
|
||||
g_return_val_if_fail (provider == NULL || GTK_IS_STYLE_PROVIDER_PRIVATE (provider), FALSE);
|
||||
g_return_val_if_fail (current != NULL, FALSE);
|
||||
|
||||
if (dependencies == NULL)
|
||||
dependencies = &unused;
|
||||
*dependencies = 0;
|
||||
|
||||
value = NULL;
|
||||
switch (color->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
return _gtk_css_value_ref (color->last_value);
|
||||
case COLOR_TYPE_NAME:
|
||||
{
|
||||
GtkSymbolicColor *symbolic;
|
||||
|
||||
symbolic = _gtk_style_provider_private_get_color (provider, color->sym_col.name);
|
||||
|
||||
if (!symbolic)
|
||||
return NULL;
|
||||
|
||||
value = _gtk_symbolic_color_resolve_full (symbolic, provider, current, current_deps, dependencies);
|
||||
}
|
||||
|
||||
break;
|
||||
case COLOR_TYPE_SHADE:
|
||||
{
|
||||
GtkCssValue *val;
|
||||
GtkHSLA hsla;
|
||||
GdkRGBA shade;
|
||||
|
||||
val = gtk_css_color_value_resolve_full (color->sym_col.shade.color, provider, current, current_deps, dependencies);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, 0);
|
||||
|
||||
_gtk_hsla_init_from_rgba (&hsla, _gtk_css_rgba_value_get_rgba (val));
|
||||
|
||||
hsla.lightness *= color->sym_col.shade.factor;
|
||||
hsla.lightness = CLAMP (hsla.lightness, 0.0, 1.0);
|
||||
|
||||
hsla.saturation *= color->sym_col.shade.factor;
|
||||
hsla.saturation = CLAMP (hsla.saturation, 0.0, 1.0);
|
||||
|
||||
_gdk_rgba_init_from_hsla (&shade, &hsla);
|
||||
|
||||
_gtk_css_value_unref (val);
|
||||
|
||||
value = _gtk_css_rgba_value_new_from_rgba (&shade);
|
||||
}
|
||||
|
||||
break;
|
||||
case COLOR_TYPE_ALPHA:
|
||||
{
|
||||
GtkCssValue *val;
|
||||
GdkRGBA alpha;
|
||||
|
||||
val = gtk_css_color_value_resolve_full (color->sym_col.alpha.color, provider, current, current_deps, dependencies);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, 0);
|
||||
alpha = *_gtk_css_rgba_value_get_rgba (val);
|
||||
alpha.alpha = CLAMP (alpha.alpha * color->sym_col.alpha.factor, 0, 1);
|
||||
|
||||
_gtk_css_value_unref (val);
|
||||
|
||||
value = _gtk_css_rgba_value_new_from_rgba (&alpha);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_MIX:
|
||||
{
|
||||
GtkCssValue *val;
|
||||
GdkRGBA color1, color2, res;
|
||||
GtkCssDependencies dep1, dep2;
|
||||
|
||||
val = gtk_css_color_value_resolve_full (color->sym_col.mix.color1, provider, current, current_deps, &dep1);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
color1 = *_gtk_css_rgba_value_get_rgba (val);
|
||||
_gtk_css_value_unref (val);
|
||||
|
||||
val = gtk_css_color_value_resolve_full (color->sym_col.mix.color2, provider, current, current_deps, &dep2);
|
||||
if (val == NULL)
|
||||
return NULL;
|
||||
color2 = *_gtk_css_rgba_value_get_rgba (val);
|
||||
_gtk_css_value_unref (val);
|
||||
|
||||
*dependencies = _gtk_css_dependencies_union (dep1, dep2);
|
||||
res.red = CLAMP (color1.red + ((color2.red - color1.red) * color->sym_col.mix.factor), 0, 1);
|
||||
res.green = CLAMP (color1.green + ((color2.green - color1.green) * color->sym_col.mix.factor), 0, 1);
|
||||
res.blue = CLAMP (color1.blue + ((color2.blue - color1.blue) * color->sym_col.mix.factor), 0, 1);
|
||||
res.alpha = CLAMP (color1.alpha + ((color2.alpha - color1.alpha) * color->sym_col.mix.factor), 0, 1);
|
||||
|
||||
value =_gtk_css_rgba_value_new_from_rgba (&res);
|
||||
}
|
||||
|
||||
break;
|
||||
case COLOR_TYPE_WIN32:
|
||||
{
|
||||
GdkRGBA res;
|
||||
|
||||
if (!_gtk_win32_theme_color_resolve (color->sym_col.win32.theme_class,
|
||||
color->sym_col.win32.id,
|
||||
&res))
|
||||
return NULL;
|
||||
|
||||
value = _gtk_css_rgba_value_new_from_rgba (&res);
|
||||
}
|
||||
|
||||
break;
|
||||
case COLOR_TYPE_CURRENT_COLOR:
|
||||
if (current)
|
||||
{
|
||||
*dependencies = current_deps;
|
||||
return _gtk_css_value_ref (current);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
if (color->last_value != NULL &&
|
||||
_gtk_css_value_equal (color->last_value, value))
|
||||
{
|
||||
_gtk_css_value_unref (value);
|
||||
value = _gtk_css_value_ref (color->last_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (color->last_value != NULL)
|
||||
_gtk_css_value_unref (color->last_value);
|
||||
color->last_value = _gtk_css_value_ref (value);
|
||||
}
|
||||
}
|
||||
|
||||
_gtk_css_rgba_value_get_rgba (value);
|
||||
return value;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_color_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProviderPrivate *provider,
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies)
|
||||
{
|
||||
GtkCssValue *resolved, *current;
|
||||
GtkCssDependencies current_deps;
|
||||
|
||||
/* The computed value of the ‘currentColor’ keyword is the computed
|
||||
* value of the ‘color’ property. If the ‘currentColor’ keyword is
|
||||
* set on the ‘color’ property itself, it is treated as ‘color: inherit’.
|
||||
*/
|
||||
if (property_id == GTK_CSS_PROPERTY_COLOR)
|
||||
{
|
||||
if (parent_values)
|
||||
{
|
||||
current = _gtk_css_computed_values_get_value (parent_values, GTK_CSS_PROPERTY_COLOR);
|
||||
current_deps = GTK_CSS_EQUALS_PARENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = _gtk_css_style_property_get_initial_value (_gtk_css_style_property_lookup_by_id (GTK_CSS_PROPERTY_COLOR));
|
||||
current_deps = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
current = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR);
|
||||
current_deps = GTK_CSS_DEPENDS_ON_COLOR;
|
||||
}
|
||||
|
||||
resolved = gtk_css_color_value_resolve_full (value,
|
||||
provider,
|
||||
current,
|
||||
current_deps,
|
||||
dependencies);
|
||||
|
||||
if (resolved == NULL)
|
||||
return gtk_css_value_color_get_fallback (property_id, provider, values, parent_values);
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_value_color_equal (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2)
|
||||
{
|
||||
if (value1->type != value2->type)
|
||||
return FALSE;
|
||||
|
||||
switch (value1->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
return _gtk_css_value_equal (value1->last_value, value2->last_value);
|
||||
case COLOR_TYPE_NAME:
|
||||
return g_str_equal (value1->sym_col.name, value2->sym_col.name);
|
||||
case COLOR_TYPE_SHADE:
|
||||
return value1->sym_col.shade.factor == value2->sym_col.shade.factor &&
|
||||
_gtk_css_value_equal (value1->sym_col.shade.color,
|
||||
value2->sym_col.shade.color);
|
||||
case COLOR_TYPE_ALPHA:
|
||||
return value1->sym_col.alpha.factor == value2->sym_col.alpha.factor &&
|
||||
_gtk_css_value_equal (value1->sym_col.alpha.color,
|
||||
value2->sym_col.alpha.color);
|
||||
case COLOR_TYPE_MIX:
|
||||
return value1->sym_col.mix.factor == value2->sym_col.mix.factor &&
|
||||
_gtk_css_value_equal (value1->sym_col.mix.color1,
|
||||
value2->sym_col.mix.color1) &&
|
||||
_gtk_css_value_equal (value1->sym_col.mix.color2,
|
||||
value2->sym_col.mix.color2);
|
||||
case COLOR_TYPE_WIN32:
|
||||
return g_str_equal (value1->sym_col.win32.theme_class, value2->sym_col.win32.theme_class) &&
|
||||
value1->sym_col.win32.id == value2->sym_col.win32.id;
|
||||
case COLOR_TYPE_CURRENT_COLOR:
|
||||
return TRUE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_color_transition (GtkCssValue *start,
|
||||
GtkCssValue *end,
|
||||
guint property_id,
|
||||
double progress)
|
||||
{
|
||||
return _gtk_css_color_value_new_mix (start, end, progress);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_value_color_print (const GtkCssValue *value,
|
||||
GString *string)
|
||||
{
|
||||
switch (value->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
_gtk_css_value_print (value->last_value, string);
|
||||
break;
|
||||
case COLOR_TYPE_NAME:
|
||||
g_string_append (string, "@");
|
||||
g_string_append (string, value->sym_col.name);
|
||||
break;
|
||||
case COLOR_TYPE_SHADE:
|
||||
{
|
||||
char factor[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_string_append (string, "shade(");
|
||||
_gtk_css_value_print (value->sym_col.shade.color, string);
|
||||
g_string_append (string, ", ");
|
||||
g_ascii_dtostr (factor, sizeof (factor), value->sym_col.shade.factor);
|
||||
g_string_append (string, factor);
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
break;
|
||||
case COLOR_TYPE_ALPHA:
|
||||
{
|
||||
char factor[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_string_append (string, "alpha(");
|
||||
_gtk_css_value_print (value->sym_col.alpha.color, string);
|
||||
g_string_append (string, ", ");
|
||||
g_ascii_dtostr (factor, sizeof (factor), value->sym_col.alpha.factor);
|
||||
g_string_append (string, factor);
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
break;
|
||||
case COLOR_TYPE_MIX:
|
||||
{
|
||||
char factor[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_string_append (string, "mix(");
|
||||
_gtk_css_value_print (value->sym_col.mix.color1, string);
|
||||
g_string_append (string, ", ");
|
||||
_gtk_css_value_print (value->sym_col.mix.color2, string);
|
||||
g_string_append (string, ", ");
|
||||
g_ascii_dtostr (factor, sizeof (factor), value->sym_col.mix.factor);
|
||||
g_string_append (string, factor);
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
break;
|
||||
case COLOR_TYPE_WIN32:
|
||||
{
|
||||
g_string_append_printf (string, GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME"(%s, %d)",
|
||||
value->sym_col.win32.theme_class, value->sym_col.win32.id);
|
||||
}
|
||||
break;
|
||||
case COLOR_TYPE_CURRENT_COLOR:
|
||||
g_string_append (string, "currentColor");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_COLOR = {
|
||||
gtk_css_value_color_free,
|
||||
gtk_css_value_color_compute,
|
||||
gtk_css_value_color_equal,
|
||||
gtk_css_value_color_transition,
|
||||
gtk_css_value_color_print
|
||||
};
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_literal (const GdkRGBA *color)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (color != NULL, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_LITERAL;
|
||||
value->last_value = _gtk_css_rgba_value_new_from_rgba (color);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_rgba (double red,
|
||||
double green,
|
||||
double blue,
|
||||
double alpha)
|
||||
{
|
||||
GdkRGBA rgba = { red, green, blue, alpha };
|
||||
|
||||
return _gtk_css_color_value_new_literal (&rgba);
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_name (const gchar *name)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_NAME;
|
||||
value->sym_col.name = g_strdup (name);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_shade (GtkCssValue *color,
|
||||
gdouble factor)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (color->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_SHADE;
|
||||
value->sym_col.shade.color = _gtk_css_value_ref (color);
|
||||
value->sym_col.shade.factor = factor;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_alpha (GtkCssValue *color,
|
||||
gdouble factor)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (color->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_ALPHA;
|
||||
value->sym_col.alpha.color = _gtk_css_value_ref (color);
|
||||
value->sym_col.alpha.factor = factor;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
GtkCssValue *color2,
|
||||
gdouble factor)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (color1->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
g_return_val_if_fail (color2->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_MIX;
|
||||
value->sym_col.mix.color1 = _gtk_css_value_ref (color1);
|
||||
value->sym_col.mix.color2 = _gtk_css_value_ref (color2);
|
||||
value->sym_col.mix.factor = factor;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_win32 (const gchar *theme_class,
|
||||
gint id)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (theme_class != NULL, NULL);
|
||||
|
||||
value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_WIN32;
|
||||
value->sym_col.win32.theme_class = g_strdup (theme_class);
|
||||
value->sym_col.win32.id = id;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_new_current_color (void)
|
||||
{
|
||||
static GtkCssValue current_color = { >K_CSS_VALUE_COLOR, 1, COLOR_TYPE_CURRENT_COLOR, NULL, };
|
||||
|
||||
return _gtk_css_value_ref (¤t_color);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
COLOR_RGBA,
|
||||
COLOR_RGB,
|
||||
COLOR_LIGHTER,
|
||||
COLOR_DARKER,
|
||||
COLOR_SHADE,
|
||||
COLOR_ALPHA,
|
||||
COLOR_MIX,
|
||||
COLOR_WIN32
|
||||
} ColorParseType;
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_color_parse_win32 (GtkCssParser *parser)
|
||||
{
|
||||
GtkCssValue *color;
|
||||
char *class;
|
||||
int id;
|
||||
|
||||
class = _gtk_css_parser_try_name (parser, TRUE);
|
||||
if (class == NULL)
|
||||
{
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected name as first argument to '-gtk-win32-color'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (! _gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
g_free (class);
|
||||
_gtk_css_parser_error (parser,
|
||||
"Expected ','");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try_int (parser, &id))
|
||||
{
|
||||
g_free (class);
|
||||
_gtk_css_parser_error (parser, "Expected a valid integer value");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
color = _gtk_css_color_value_new_win32 (class, id);
|
||||
g_free (class);
|
||||
return color;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
_gtk_css_color_value_parse_function (GtkCssParser *parser,
|
||||
ColorParseType color)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
GtkCssValue *child1, *child2;
|
||||
double d;
|
||||
|
||||
if (!_gtk_css_parser_try (parser, "(", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Missing opening bracket in color definition");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (color == COLOR_RGB || color == COLOR_RGBA)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
double tmp;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ',' in color definition");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &tmp))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid number for color value");
|
||||
return NULL;
|
||||
}
|
||||
if (_gtk_css_parser_try (parser, "%", TRUE))
|
||||
tmp /= 100.0;
|
||||
else
|
||||
tmp /= 255.0;
|
||||
if (i == 0)
|
||||
rgba.red = tmp;
|
||||
else if (i == 1)
|
||||
rgba.green = tmp;
|
||||
else if (i == 2)
|
||||
rgba.blue = tmp;
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (color == COLOR_RGBA)
|
||||
{
|
||||
if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ',' in color definition");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &rgba.alpha))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid number for alpha value");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
rgba.alpha = 1.0;
|
||||
|
||||
value = _gtk_css_color_value_new_literal (&rgba);
|
||||
}
|
||||
else if (color == COLOR_WIN32)
|
||||
{
|
||||
value = gtk_css_color_parse_win32 (parser);
|
||||
if (value == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
child1 = _gtk_css_color_value_parse (parser);
|
||||
if (child1 == NULL)
|
||||
return NULL;
|
||||
|
||||
if (color == COLOR_MIX)
|
||||
{
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ',' in color definition");
|
||||
_gtk_css_value_unref (child1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
child2 = _gtk_css_color_value_parse (parser);
|
||||
if (child2 == NULL)
|
||||
{
|
||||
_gtk_css_value_unref (child1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
child2 = NULL;
|
||||
|
||||
if (color == COLOR_LIGHTER)
|
||||
d = 1.3;
|
||||
else if (color == COLOR_DARKER)
|
||||
d = 0.7;
|
||||
else
|
||||
{
|
||||
if (!_gtk_css_parser_try (parser, ",", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ',' in color definition");
|
||||
_gtk_css_value_unref (child1);
|
||||
if (child2)
|
||||
_gtk_css_value_unref (child2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &d))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected number in color definition");
|
||||
_gtk_css_value_unref (child1);
|
||||
if (child2)
|
||||
_gtk_css_value_unref (child2);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (color)
|
||||
{
|
||||
case COLOR_LIGHTER:
|
||||
case COLOR_DARKER:
|
||||
case COLOR_SHADE:
|
||||
value = _gtk_css_color_value_new_shade (child1, d);
|
||||
break;
|
||||
case COLOR_ALPHA:
|
||||
value = _gtk_css_color_value_new_alpha (child1, d);
|
||||
break;
|
||||
case COLOR_MIX:
|
||||
value = _gtk_css_color_value_new_mix (child1, child2, d);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
_gtk_css_value_unref (child1);
|
||||
if (child2)
|
||||
_gtk_css_value_unref (child2);
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try (parser, ")", TRUE))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Expected ')' in color definition");
|
||||
_gtk_css_value_unref (value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
GdkRGBA rgba;
|
||||
guint color;
|
||||
const char *names[] = {"rgba", "rgb", "lighter", "darker", "shade", "alpha", "mix",
|
||||
GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME};
|
||||
char *name;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "currentColor", TRUE))
|
||||
return _gtk_css_color_value_new_current_color ();
|
||||
|
||||
if (_gtk_css_parser_try (parser, "transparent", TRUE))
|
||||
{
|
||||
GdkRGBA transparent = { 0, 0, 0, 0 };
|
||||
|
||||
return _gtk_css_color_value_new_literal (&transparent);
|
||||
}
|
||||
|
||||
if (_gtk_css_parser_try (parser, "@", FALSE))
|
||||
{
|
||||
name = _gtk_css_parser_try_name (parser, TRUE);
|
||||
|
||||
if (name)
|
||||
{
|
||||
value = _gtk_css_color_value_new_name (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'%s' is not a valid color color name", name);
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
return value;
|
||||
}
|
||||
|
||||
for (color = 0; color < G_N_ELEMENTS (names); color++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, names[color], TRUE))
|
||||
break;
|
||||
}
|
||||
|
||||
if (color < G_N_ELEMENTS (names))
|
||||
return _gtk_css_color_value_parse_function (parser, color);
|
||||
|
||||
if (_gtk_css_parser_try_hash_color (parser, &rgba))
|
||||
return _gtk_css_color_value_new_literal (&rgba);
|
||||
|
||||
name = _gtk_css_parser_try_name (parser, TRUE);
|
||||
if (name)
|
||||
{
|
||||
if (gdk_rgba_parse (&rgba, name))
|
||||
{
|
||||
value = _gtk_css_color_value_new_literal (&rgba);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_parser_error (parser, "'%s' is not a valid color name", name);
|
||||
value = NULL;
|
||||
}
|
||||
g_free (name);
|
||||
return value;
|
||||
}
|
||||
|
||||
_gtk_css_parser_error (parser, "Not a color definition");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_COLOR_VALUE_PRIVATE_H__
|
||||
#define __GTK_CSS_COLOR_VALUE_PRIVATE_H__
|
||||
|
||||
#include "gtkcssparserprivate.h"
|
||||
#include "gtkcssvalueprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GtkCssValue * _gtk_css_color_value_new_literal (const GdkRGBA *color);
|
||||
GtkCssValue * _gtk_css_color_value_new_rgba (double red,
|
||||
double green,
|
||||
double blue,
|
||||
double alpha);
|
||||
GtkCssValue * _gtk_css_color_value_new_name (const gchar *name);
|
||||
GtkCssValue * _gtk_css_color_value_new_shade (GtkCssValue *color,
|
||||
gdouble factor);
|
||||
GtkCssValue * _gtk_css_color_value_new_alpha (GtkCssValue *color,
|
||||
gdouble factor);
|
||||
GtkCssValue * _gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
GtkCssValue *color2,
|
||||
gdouble factor);
|
||||
GtkCssValue * _gtk_css_color_value_new_win32 (const gchar *theme_class,
|
||||
gint id);
|
||||
GtkCssValue * _gtk_css_color_value_new_current_color (void);
|
||||
|
||||
GtkCssValue * _gtk_css_color_value_parse (GtkCssParser *parser);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_COLOR_VALUE_PRIVATE_H__ */
|
||||
@@ -499,6 +499,7 @@ gtk_css_computed_values_create_css_animations (GtkCssComputedValues *values,
|
||||
_gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)),
|
||||
_gtk_css_fill_mode_value_get (_gtk_css_array_value_get_nth (fill_modes, i)),
|
||||
_gtk_css_number_value_get (_gtk_css_array_value_get_nth (iteration_counts, i), 100));
|
||||
_gtk_css_keyframes_unref (keyframes);
|
||||
}
|
||||
values->animations = g_slist_prepend (values->animations, animation);
|
||||
}
|
||||
@@ -603,3 +604,21 @@ _gtk_css_computed_values_cancel_animations (GtkCssComputedValues *values)
|
||||
values->animations = NULL;
|
||||
}
|
||||
|
||||
GtkBitmask *
|
||||
_gtk_css_computed_values_compute_dependencies (GtkCssComputedValues *values,
|
||||
const GtkBitmask *parent_changes)
|
||||
{
|
||||
GtkBitmask *changes;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), _gtk_bitmask_new ());
|
||||
|
||||
changes = _gtk_bitmask_copy (parent_changes);
|
||||
changes = _gtk_bitmask_intersect (changes, values->depends_on_parent);
|
||||
if (_gtk_bitmask_get (changes, GTK_CSS_PROPERTY_COLOR))
|
||||
changes = _gtk_bitmask_union (changes, values->depends_on_color);
|
||||
if (_gtk_bitmask_get (changes, GTK_CSS_PROPERTY_FONT_SIZE))
|
||||
changes = _gtk_bitmask_union (changes, values->depends_on_font_size);
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,8 @@ GtkCssValue * _gtk_css_computed_values_get_intrinsic_value (GtkCssCom
|
||||
guint id);
|
||||
GtkBitmask * _gtk_css_computed_values_get_difference (GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *other);
|
||||
GtkBitmask * _gtk_css_computed_values_compute_dependencies (GtkCssComputedValues *values,
|
||||
const GtkBitmask *parent_changes);
|
||||
|
||||
void _gtk_css_computed_values_create_animations (GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
|
||||
@@ -69,6 +69,13 @@ gtk_css_image_real_compute (GtkCssImage *image,
|
||||
return g_object_ref (image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_real_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkCssImage *
|
||||
gtk_css_image_real_transition (GtkCssImage *start,
|
||||
GtkCssImage *end,
|
||||
@@ -90,6 +97,7 @@ _gtk_css_image_class_init (GtkCssImageClass *klass)
|
||||
klass->get_height = gtk_css_image_real_get_height;
|
||||
klass->get_aspect_ratio = gtk_css_image_real_get_aspect_ratio;
|
||||
klass->compute = gtk_css_image_real_compute;
|
||||
klass->equal = gtk_css_image_real_equal;
|
||||
klass->transition = gtk_css_image_real_transition;
|
||||
}
|
||||
|
||||
@@ -188,6 +196,29 @@ _gtk_css_image_transition (GtkCssImage *start,
|
||||
return klass->transition (start, end, property_id, progress);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_image_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2)
|
||||
{
|
||||
GtkCssImageClass *klass;
|
||||
|
||||
g_return_val_if_fail (image1 == NULL || GTK_IS_CSS_IMAGE (image1), FALSE);
|
||||
g_return_val_if_fail (image2 == NULL || GTK_IS_CSS_IMAGE (image2), FALSE);
|
||||
|
||||
if (image1 == image2)
|
||||
return TRUE;
|
||||
|
||||
if (image1 == NULL || image2 == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (G_OBJECT_TYPE (image1) != G_OBJECT_TYPE (image2))
|
||||
return FALSE;
|
||||
|
||||
klass = GTK_CSS_IMAGE_GET_CLASS (image1);
|
||||
|
||||
return klass->equal (image1, image2);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_image_draw (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
@@ -198,6 +229,8 @@ _gtk_css_image_draw (GtkCssImage *image,
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_IMAGE (image));
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (width > 0);
|
||||
g_return_if_fail (height > 0);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
|
||||
@@ -86,6 +86,18 @@ gtk_css_image_cross_fade_get_height (GtkCssImage *image)
|
||||
return start_height + (end_height - start_height) * cross_fade->progress;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_cross_fade_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2)
|
||||
{
|
||||
GtkCssImageCrossFade *cross_fade1 = GTK_CSS_IMAGE_CROSS_FADE (image1);
|
||||
GtkCssImageCrossFade *cross_fade2 = GTK_CSS_IMAGE_CROSS_FADE (image2);
|
||||
|
||||
return cross_fade1->progress == cross_fade2->progress &&
|
||||
_gtk_css_image_equal (cross_fade1->start, cross_fade2->start) &&
|
||||
_gtk_css_image_equal (cross_fade1->end, cross_fade2->end);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_cross_fade_draw (GtkCssImage *image,
|
||||
cairo_t *cr,
|
||||
@@ -234,6 +246,7 @@ _gtk_css_image_cross_fade_class_init (GtkCssImageCrossFadeClass *klass)
|
||||
|
||||
image_class->get_width = gtk_css_image_cross_fade_get_width;
|
||||
image_class->get_height = gtk_css_image_cross_fade_get_height;
|
||||
image_class->equal = gtk_css_image_cross_fade_equal;
|
||||
image_class->draw = gtk_css_image_cross_fade_draw;
|
||||
image_class->parse = gtk_css_image_cross_fade_parse;
|
||||
image_class->print = gtk_css_image_cross_fade_print;
|
||||
|
||||
@@ -79,7 +79,7 @@ fade_pattern (cairo_pattern_t *pattern,
|
||||
cairo_pattern_add_color_stop_rgba (result, o, r, g, b, a * opacity);
|
||||
}
|
||||
|
||||
return pattern;
|
||||
return result;
|
||||
}
|
||||
|
||||
static cairo_pattern_t *
|
||||
@@ -102,7 +102,7 @@ transition_pattern (cairo_pattern_t *start,
|
||||
{
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
cairo_pattern_get_linear_points (start, &sx0, &sy0, &sx1, &sy1);
|
||||
cairo_pattern_get_linear_points (start, &ex0, &ey0, &ex1, &ey1);
|
||||
cairo_pattern_get_linear_points (end, &ex0, &ey0, &ex1, &ey1);
|
||||
result = cairo_pattern_create_linear ((1 - progress) * sx0 + progress * ex0,
|
||||
(1 - progress) * sx1 + progress * ex1,
|
||||
(1 - progress) * sy0 + progress * ey0,
|
||||
@@ -110,7 +110,7 @@ transition_pattern (cairo_pattern_t *start,
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
cairo_pattern_get_radial_circles (start, &sx0, &sy0, &sr0, &sx1, &sy1, &sr1);
|
||||
cairo_pattern_get_radial_circles (start, &ex0, &ey0, &er0, &ex1, &ey1, &er1);
|
||||
cairo_pattern_get_radial_circles (end, &ex0, &ey0, &er0, &ex1, &ey1, &er1);
|
||||
result = cairo_pattern_create_radial ((1 - progress) * sx0 + progress * ex0,
|
||||
(1 - progress) * sy0 + progress * ey0,
|
||||
(1 - progress) * sr0 + progress * er0,
|
||||
@@ -128,7 +128,7 @@ transition_pattern (cairo_pattern_t *start,
|
||||
double so, sr, sg, sb, sa, eo, er, eg, eb, ea;
|
||||
|
||||
cairo_pattern_get_color_stop_rgba (start, i, &so, &sr, &sg, &sb, &sa);
|
||||
cairo_pattern_get_color_stop_rgba (start, i, &eo, &er, &eg, &eb, &ea);
|
||||
cairo_pattern_get_color_stop_rgba (end, i, &eo, &er, &eg, &eb, &ea);
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (result,
|
||||
(1 - progress) * so + progress * eo,
|
||||
|
||||
+31
-2
@@ -23,10 +23,10 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcssprovider.h"
|
||||
#include "gtksymboliccolorprivate.h"
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageLinear, _gtk_css_image_linear, GTK_TYPE_CSS_IMAGE)
|
||||
|
||||
@@ -323,7 +323,7 @@ gtk_css_image_linear_parse (GtkCssImage *image,
|
||||
do {
|
||||
GtkCssImageLinearColorStop stop;
|
||||
|
||||
stop.color = _gtk_css_symbolic_value_new (parser);
|
||||
stop.color = _gtk_css_color_value_parse (parser);
|
||||
if (stop.color == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -533,6 +533,34 @@ fail:
|
||||
return GTK_CSS_IMAGE_CLASS (_gtk_css_image_linear_parent_class)->transition (start_image, end_image, property_id, progress);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_linear_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2)
|
||||
{
|
||||
GtkCssImageLinear *linear1 = GTK_CSS_IMAGE_LINEAR (image1);
|
||||
GtkCssImageLinear *linear2 = GTK_CSS_IMAGE_LINEAR (image2);
|
||||
guint i;
|
||||
|
||||
if (linear1->repeating != linear2->repeating ||
|
||||
!_gtk_css_value_equal (linear1->angle, linear2->angle) ||
|
||||
linear1->stops->len != linear2->stops->len)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < linear1->stops->len; i++)
|
||||
{
|
||||
GtkCssImageLinearColorStop *stop1, *stop2;
|
||||
|
||||
stop1 = &g_array_index (linear1->stops, GtkCssImageLinearColorStop, i);
|
||||
stop2 = &g_array_index (linear2->stops, GtkCssImageLinearColorStop, i);
|
||||
|
||||
if (!_gtk_css_value_equal0 (stop1->offset, stop2->offset) ||
|
||||
!_gtk_css_value_equal (stop1->color, stop2->color))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_linear_dispose (GObject *object)
|
||||
{
|
||||
@@ -563,6 +591,7 @@ _gtk_css_image_linear_class_init (GtkCssImageLinearClass *klass)
|
||||
image_class->parse = gtk_css_image_linear_parse;
|
||||
image_class->print = gtk_css_image_linear_print;
|
||||
image_class->compute = gtk_css_image_linear_compute;
|
||||
image_class->equal = gtk_css_image_linear_equal;
|
||||
image_class->transition = gtk_css_image_linear_transition;
|
||||
|
||||
object_class->dispose = gtk_css_image_linear_dispose;
|
||||
|
||||
@@ -61,6 +61,9 @@ struct _GtkCssImageClass
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies);
|
||||
/* compare two images for equality */
|
||||
gboolean (* equal) (GtkCssImage *image1,
|
||||
GtkCssImage *image2);
|
||||
/* transition between start and end image (end may be NULL), returns new reference */
|
||||
GtkCssImage *(* transition) (GtkCssImage *start,
|
||||
GtkCssImage *end,
|
||||
@@ -95,6 +98,8 @@ GtkCssImage * _gtk_css_image_compute (GtkCssImage *
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values,
|
||||
GtkCssDependencies *dependencies);
|
||||
gboolean _gtk_css_image_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2);
|
||||
GtkCssImage * _gtk_css_image_transition (GtkCssImage *start,
|
||||
GtkCssImage *end,
|
||||
guint property_id,
|
||||
|
||||
@@ -63,7 +63,7 @@ static gboolean
|
||||
gtk_css_value_image_equal (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2)
|
||||
{
|
||||
return value1->image == value2->image;
|
||||
return _gtk_css_image_equal (value1->image, value2->image);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
|
||||
+13
-2
@@ -36,6 +36,8 @@ struct _GtkCssKeyframes {
|
||||
GtkCssValue **values; /* 2D array: n_keyframes * n_properties of (value or NULL) for all the keyframes */
|
||||
};
|
||||
|
||||
#define KEYFRAMES_VALUE(keyframes, k, p) ((keyframes)->values[(k) * (keyframes)->n_properties + (p)])
|
||||
|
||||
GtkCssKeyframes *
|
||||
_gtk_css_keyframes_ref (GtkCssKeyframes *keyframes)
|
||||
{
|
||||
@@ -49,6 +51,8 @@ _gtk_css_keyframes_ref (GtkCssKeyframes *keyframes)
|
||||
void
|
||||
_gtk_css_keyframes_unref (GtkCssKeyframes *keyframes)
|
||||
{
|
||||
guint k, p;
|
||||
|
||||
g_return_if_fail (keyframes != NULL);
|
||||
|
||||
keyframes->ref_count--;
|
||||
@@ -57,13 +61,20 @@ _gtk_css_keyframes_unref (GtkCssKeyframes *keyframes)
|
||||
|
||||
g_free (keyframes->keyframe_progress);
|
||||
g_free (keyframes->property_ids);
|
||||
|
||||
for (k = 0; k < keyframes->n_keyframes; k++)
|
||||
{
|
||||
for (p = 0; p < keyframes->n_properties; p++)
|
||||
{
|
||||
_gtk_css_value_unref (KEYFRAMES_VALUE (keyframes, k, p));
|
||||
KEYFRAMES_VALUE (keyframes, k, p) = NULL;
|
||||
}
|
||||
}
|
||||
g_free (keyframes->values);
|
||||
|
||||
g_slice_free (GtkCssKeyframes, keyframes);
|
||||
}
|
||||
|
||||
#define KEYFRAMES_VALUE(keyframes, k, p) ((keyframes)->values[(k) * (keyframes)->n_properties + (p)])
|
||||
|
||||
static guint
|
||||
gtk_css_keyframes_add_keyframe (GtkCssKeyframes *keyframes,
|
||||
double progress)
|
||||
|
||||
@@ -24,17 +24,6 @@
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkstylepropertiesprivate.h"
|
||||
|
||||
typedef struct {
|
||||
GtkCssSection *section;
|
||||
GtkCssValue *value;
|
||||
GtkCssValue *computed;
|
||||
} GtkCssLookupValue;
|
||||
|
||||
struct _GtkCssLookup {
|
||||
GtkBitmask *missing;
|
||||
GtkCssLookupValue values[1];
|
||||
};
|
||||
|
||||
GtkCssLookup *
|
||||
_gtk_css_lookup_new (const GtkBitmask *relevant)
|
||||
{
|
||||
@@ -65,14 +54,6 @@ _gtk_css_lookup_free (GtkCssLookup *lookup)
|
||||
g_free (lookup);
|
||||
}
|
||||
|
||||
const GtkBitmask *
|
||||
_gtk_css_lookup_get_missing (const GtkCssLookup *lookup)
|
||||
{
|
||||
g_return_val_if_fail (lookup != NULL, NULL);
|
||||
|
||||
return lookup->missing;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_lookup_is_missing (const GtkCssLookup *lookup,
|
||||
guint id)
|
||||
|
||||
@@ -28,10 +28,21 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkCssLookup GtkCssLookup;
|
||||
|
||||
typedef struct {
|
||||
GtkCssSection *section;
|
||||
GtkCssValue *value;
|
||||
GtkCssValue *computed;
|
||||
} GtkCssLookupValue;
|
||||
|
||||
struct _GtkCssLookup {
|
||||
GtkBitmask *missing;
|
||||
GtkCssLookupValue values[1];
|
||||
};
|
||||
|
||||
GtkCssLookup * _gtk_css_lookup_new (const GtkBitmask *relevant);
|
||||
void _gtk_css_lookup_free (GtkCssLookup *lookup);
|
||||
|
||||
const GtkBitmask * _gtk_css_lookup_get_missing (const GtkCssLookup *lookup);
|
||||
static inline const GtkBitmask *_gtk_css_lookup_get_missing (const GtkCssLookup *lookup);
|
||||
gboolean _gtk_css_lookup_is_missing (const GtkCssLookup *lookup,
|
||||
guint id);
|
||||
void _gtk_css_lookup_set (GtkCssLookup *lookup,
|
||||
@@ -47,6 +58,13 @@ void _gtk_css_lookup_resolve (GtkCssLookup
|
||||
GtkCssComputedValues *values,
|
||||
GtkCssComputedValues *parent_values);
|
||||
|
||||
static inline const GtkBitmask *
|
||||
_gtk_css_lookup_get_missing (const GtkCssLookup *lookup)
|
||||
{
|
||||
return lookup->missing;
|
||||
}
|
||||
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+573
-108
@@ -994,6 +994,37 @@ struct GtkCssRuleset
|
||||
guint owns_widget_style : 1;
|
||||
};
|
||||
|
||||
enum RulesetsTreeType {
|
||||
RULESETS_TREE_TYPE_STATE,
|
||||
RULESETS_TREE_TYPE_CLASS,
|
||||
RULESETS_TREE_TYPE_RULES
|
||||
};
|
||||
|
||||
typedef struct _GtkCssRulesetList GtkCssRulesetList;
|
||||
typedef struct _GtkCssRulesetsTree GtkCssRulesetsTree;
|
||||
|
||||
struct _GtkCssRulesetList {
|
||||
guint *rules;
|
||||
guint num_rules;
|
||||
};
|
||||
|
||||
struct _GtkCssRulesetsTree
|
||||
{
|
||||
enum RulesetsTreeType type;
|
||||
union {
|
||||
GtkCssRulesetList rules;
|
||||
struct {
|
||||
GtkCssRulesetsTree *matched;
|
||||
GtkStateFlags state;
|
||||
} state;
|
||||
struct {
|
||||
GtkCssRulesetsTree *matched;
|
||||
GQuark class;
|
||||
} class;
|
||||
} u;
|
||||
GtkCssRulesetsTree *next;
|
||||
};
|
||||
|
||||
struct _GtkCssScanner
|
||||
{
|
||||
GtkCssProvider *provider;
|
||||
@@ -1011,6 +1042,8 @@ struct _GtkCssProviderPrivate
|
||||
GHashTable *keyframes;
|
||||
|
||||
GArray *rulesets;
|
||||
guint *rulesets_refs;
|
||||
GtkCssRulesetsTree *rulesets_tree;
|
||||
GResource *resource;
|
||||
};
|
||||
|
||||
@@ -1027,6 +1060,7 @@ static void gtk_css_provider_finalize (GObject *object);
|
||||
static void gtk_css_style_provider_iface_init (GtkStyleProviderIface *iface);
|
||||
static void gtk_css_style_provider_private_iface_init (GtkStyleProviderPrivateInterface *iface);
|
||||
static void widget_property_value_list_free (WidgetPropertyValue *head);
|
||||
static void gtk_css_rulesets_tree_free (GtkCssRulesetsTree *tree);
|
||||
|
||||
static gboolean
|
||||
gtk_css_provider_load_internal (GtkCssProvider *css_provider,
|
||||
@@ -1561,6 +1595,117 @@ gtk_css_style_provider_get_keyframes (GtkStyleProviderPrivate *provider,
|
||||
return g_hash_table_lookup (css_provider->priv->keyframes, name);
|
||||
}
|
||||
|
||||
static void
|
||||
collect_possible_rules (GPtrArray *rules_lists,
|
||||
GtkCssRulesetsTree *tree,
|
||||
const GtkCssMatcher *matcher)
|
||||
{
|
||||
if (tree == NULL)
|
||||
return;
|
||||
|
||||
switch (tree->type)
|
||||
{
|
||||
case RULESETS_TREE_TYPE_RULES:
|
||||
g_ptr_array_add (rules_lists, &tree->u.rules);
|
||||
break;
|
||||
case RULESETS_TREE_TYPE_STATE:
|
||||
if ((_gtk_css_matcher_get_state (matcher) & tree->u.state.state) == tree->u.state.state)
|
||||
collect_possible_rules (rules_lists,
|
||||
tree->u.state.matched,
|
||||
matcher);
|
||||
break;
|
||||
case RULESETS_TREE_TYPE_CLASS:
|
||||
if (_gtk_css_matcher_has_class (matcher, tree->u.class.class))
|
||||
collect_possible_rules (rules_lists,
|
||||
tree->u.class.matched,
|
||||
matcher);
|
||||
break;
|
||||
}
|
||||
|
||||
collect_possible_rules (rules_lists,
|
||||
tree->next,
|
||||
matcher);
|
||||
}
|
||||
|
||||
/* Merged two pre-sorted arrays of uints, assumes enough space in destination to fit a_len + b_len */
|
||||
static void
|
||||
merge_uints (guint *dest, const guint *a, int a_len, const guint* b, int b_len)
|
||||
{
|
||||
const guint *a_end = a + a_len;
|
||||
const guint *b_end = b + b_len;
|
||||
|
||||
while (a != a_end ||
|
||||
b != b_end)
|
||||
{
|
||||
if (a == a_end)
|
||||
{
|
||||
memcpy (dest, b, sizeof (guint) * (b_end - b));
|
||||
break;
|
||||
}
|
||||
else if (b == b_end)
|
||||
{
|
||||
memcpy (dest, a, sizeof (guint) * (a_end - a));
|
||||
break;
|
||||
}
|
||||
else if (*a <= *b)
|
||||
*dest++ = *a++;
|
||||
else
|
||||
*dest++ = *b++;
|
||||
}
|
||||
}
|
||||
|
||||
static guint *
|
||||
find_possible_rules (GtkCssRulesetsTree *tree,
|
||||
const GtkCssMatcher *matcher,
|
||||
guint *num_refs_out)
|
||||
{
|
||||
GPtrArray *rules_lists;
|
||||
gint i;
|
||||
guint *merged, *tmp_refs, *swap_ptr;
|
||||
guint merged_size;
|
||||
guint num_refs;
|
||||
|
||||
/* Collect all possible rules from the tree */
|
||||
rules_lists = g_ptr_array_new ();
|
||||
collect_possible_rules (rules_lists, tree, matcher);
|
||||
|
||||
/* Merge the separate sorted lists into one list */
|
||||
num_refs = 0;
|
||||
for (i = 0; i < rules_lists->len; i++)
|
||||
{
|
||||
GtkCssRulesetList *list = (GtkCssRulesetList *)rules_lists->pdata[i];
|
||||
num_refs += list->num_rules;
|
||||
}
|
||||
|
||||
merged = g_new (guint, num_refs);
|
||||
merged_size = 0;
|
||||
tmp_refs = g_new (guint, num_refs);
|
||||
|
||||
/* Merge the already sorted refs list */
|
||||
for (i = 0; i < rules_lists->len; i++)
|
||||
{
|
||||
GtkCssRulesetList *list = (GtkCssRulesetList *)rules_lists->pdata[i];
|
||||
|
||||
if (i == 0)
|
||||
memcpy (merged, list->rules, sizeof (*list->rules) * list->num_rules);
|
||||
else
|
||||
{
|
||||
merge_uints (tmp_refs, merged, merged_size, list->rules, list->num_rules);
|
||||
swap_ptr = merged;
|
||||
merged = tmp_refs;
|
||||
tmp_refs = swap_ptr;
|
||||
}
|
||||
|
||||
merged_size += list->num_rules;
|
||||
}
|
||||
|
||||
g_free (tmp_refs);
|
||||
g_ptr_array_free (rules_lists, TRUE);
|
||||
|
||||
*num_refs_out = num_refs;
|
||||
return merged;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
|
||||
const GtkCssMatcher *matcher,
|
||||
@@ -1568,17 +1713,25 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
|
||||
{
|
||||
GtkCssProvider *css_provider;
|
||||
GtkCssProviderPrivate *priv;
|
||||
int i;
|
||||
GtkCssRuleset *ruleset;
|
||||
guint j;
|
||||
gint i;
|
||||
guint *refs;
|
||||
guint num_refs;
|
||||
|
||||
css_provider = GTK_CSS_PROVIDER (provider);
|
||||
priv = css_provider->priv;
|
||||
|
||||
for (i = priv->rulesets->len - 1; i >= 0; i--)
|
||||
{
|
||||
GtkCssRuleset *ruleset;
|
||||
if (priv->rulesets->len == 0)
|
||||
return;
|
||||
|
||||
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
|
||||
refs = find_possible_rules (priv->rulesets_tree, matcher, &num_refs);
|
||||
if (num_refs == 0)
|
||||
return;
|
||||
|
||||
for (i = num_refs - 1; i >= 0; i--)
|
||||
{
|
||||
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, refs[i]);
|
||||
|
||||
if (ruleset->styles == NULL)
|
||||
continue;
|
||||
@@ -1603,7 +1756,12 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
|
||||
ruleset->styles[j].section,
|
||||
ruleset->styles[j].value);
|
||||
}
|
||||
|
||||
if (_gtk_bitmask_is_empty (_gtk_css_lookup_get_missing (lookup)))
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (refs);
|
||||
}
|
||||
|
||||
static GtkCssChange
|
||||
@@ -1614,15 +1772,21 @@ gtk_css_style_provider_get_change (GtkStyleProviderPrivate *provider,
|
||||
GtkCssProviderPrivate *priv;
|
||||
GtkCssChange change = 0;
|
||||
int i;
|
||||
guint *refs;
|
||||
guint num_refs;
|
||||
|
||||
css_provider = GTK_CSS_PROVIDER (provider);
|
||||
priv = css_provider->priv;
|
||||
|
||||
for (i = priv->rulesets->len - 1; i >= 0; i--)
|
||||
refs = find_possible_rules (priv->rulesets_tree, matcher, &num_refs);
|
||||
if (num_refs == 0)
|
||||
return change;
|
||||
|
||||
for (i = num_refs - 1; i >= 0; i--)
|
||||
{
|
||||
GtkCssRuleset *ruleset;
|
||||
|
||||
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
|
||||
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, refs[i]);
|
||||
|
||||
if (ruleset->styles == NULL)
|
||||
continue;
|
||||
@@ -1633,6 +1797,8 @@ gtk_css_style_provider_get_change (GtkStyleProviderPrivate *provider,
|
||||
change |= gtk_css_ruleset_get_change (ruleset);
|
||||
}
|
||||
|
||||
g_free (refs);
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
@@ -1659,6 +1825,8 @@ gtk_css_provider_finalize (GObject *object)
|
||||
gtk_css_ruleset_clear (&g_array_index (priv->rulesets, GtkCssRuleset, i));
|
||||
|
||||
g_array_free (priv->rulesets, TRUE);
|
||||
g_free (priv->rulesets_refs);
|
||||
gtk_css_rulesets_tree_free (priv->rulesets_tree);
|
||||
|
||||
g_hash_table_destroy (priv->symbolic_colors);
|
||||
g_hash_table_destroy (priv->keyframes);
|
||||
@@ -1793,6 +1961,11 @@ gtk_css_provider_reset (GtkCssProvider *css_provider)
|
||||
g_hash_table_remove_all (priv->symbolic_colors);
|
||||
g_hash_table_remove_all (priv->keyframes);
|
||||
|
||||
g_free (priv->rulesets_refs);
|
||||
priv->rulesets_refs = NULL;
|
||||
gtk_css_rulesets_tree_free (priv->rulesets_tree);
|
||||
priv->rulesets_tree = NULL;
|
||||
|
||||
for (i = 0; i < priv->rulesets->len; i++)
|
||||
gtk_css_ruleset_clear (&g_array_index (priv->rulesets, GtkCssRuleset, i));
|
||||
g_array_set_size (priv->rulesets, 0);
|
||||
@@ -1821,9 +1994,12 @@ gtk_css_provider_propagate_error (GtkCssProvider *provider,
|
||||
return;
|
||||
|
||||
*propagate_to = g_error_copy (error);
|
||||
s = _gtk_css_section_to_string (section);
|
||||
g_prefix_error (propagate_to, "%s", s);
|
||||
g_free (s);
|
||||
if (section)
|
||||
{
|
||||
s = _gtk_css_section_to_string (section);
|
||||
g_prefix_error (propagate_to, "%s", s);
|
||||
g_free (s);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2423,12 +2599,274 @@ gtk_css_provider_compare_rule (gconstpointer a_,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_rulesets_tree_free (GtkCssRulesetsTree *tree)
|
||||
{
|
||||
if (tree == NULL)
|
||||
return;
|
||||
|
||||
switch (tree->type)
|
||||
{
|
||||
case RULESETS_TREE_TYPE_RULES:
|
||||
break;
|
||||
case RULESETS_TREE_TYPE_STATE:
|
||||
gtk_css_rulesets_tree_free (tree->u.state.matched);
|
||||
break;
|
||||
case RULESETS_TREE_TYPE_CLASS:
|
||||
gtk_css_rulesets_tree_free (tree->u.class.matched);
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_css_rulesets_tree_free (tree->next);
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_refs_by_val (gconstpointer pa,
|
||||
gconstpointer pb,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint a = *(guint *)pa;
|
||||
guint b = *(guint *)pb;
|
||||
|
||||
return a - b;
|
||||
}
|
||||
|
||||
static GtkCssRulesetsTree *
|
||||
subdivide_by_none (GtkCssProviderPrivate *priv, guint *refs, guint start, guint end)
|
||||
{
|
||||
GtkCssRulesetsTree *tree;
|
||||
|
||||
tree = g_new0 (GtkCssRulesetsTree, 1);
|
||||
tree->type = RULESETS_TREE_TYPE_RULES;
|
||||
tree->u.rules.rules = refs + start;
|
||||
tree->u.rules.num_rules = end - start;
|
||||
tree->next = NULL;
|
||||
|
||||
/* Sort by rule index (i.e. css prio order) */
|
||||
g_qsort_with_data (tree->u.rules.rules,
|
||||
tree->u.rules.num_rules,
|
||||
sizeof (guint),
|
||||
compare_refs_by_val,
|
||||
NULL);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GQuark class;
|
||||
guint count;
|
||||
} GtkCssPseudoClassCount;
|
||||
|
||||
static gint
|
||||
compare_class_count (gconstpointer pa,
|
||||
gconstpointer pb,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkCssPseudoClassCount *a = (GtkCssPseudoClassCount *)pa;
|
||||
GtkCssPseudoClassCount *b = (GtkCssPseudoClassCount *)pb;
|
||||
|
||||
return b->count - a->count;
|
||||
}
|
||||
|
||||
static GtkCssRulesetsTree *
|
||||
subdivide_by_class (GtkCssProviderPrivate *priv, guint *refs, guint start, guint end)
|
||||
{
|
||||
GHashTable *count_ht;
|
||||
GHashTableIter iter;
|
||||
guint i, j, n_classes;
|
||||
gpointer key, value;
|
||||
GtkCssPseudoClassCount *class_count;
|
||||
GtkCssRulesetsTree *tree;
|
||||
GtkCssRulesetsTree *trees = NULL;
|
||||
|
||||
count_ht = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
for (i = start; i < end; i++)
|
||||
{
|
||||
GtkCssSelector *selector = g_array_index (priv->rulesets, GtkCssRuleset, refs[i]).selector;
|
||||
GQuark *classes = _gtk_css_selector_get_primary_classes (selector);
|
||||
|
||||
for (j = 0; classes[j] != 0; j++)
|
||||
{
|
||||
guint count = GPOINTER_TO_INT (g_hash_table_lookup (count_ht, GUINT_TO_POINTER (classes[j])));
|
||||
g_hash_table_replace (count_ht, GUINT_TO_POINTER (classes[j]), GUINT_TO_POINTER (count + 1));
|
||||
}
|
||||
g_free (classes);
|
||||
}
|
||||
|
||||
n_classes = 0;
|
||||
class_count = g_new (GtkCssPseudoClassCount, g_hash_table_size (count_ht));
|
||||
|
||||
g_hash_table_iter_init (&iter, count_ht);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
guint count = GPOINTER_TO_UINT (value);
|
||||
/* Random cuttoff point here. Obviously if any given class has only one item
|
||||
with it, then adding a check doesn't help, and it uses memory. Where
|
||||
is the inflexion point? Lets make it 3... */
|
||||
if (count >= 3)
|
||||
{
|
||||
class_count[n_classes].class = GPOINTER_TO_UINT (key);
|
||||
class_count[n_classes].count = count;
|
||||
n_classes++;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_destroy (count_ht);
|
||||
|
||||
/* Sort largest class counts first */
|
||||
g_qsort_with_data (class_count,
|
||||
n_classes,
|
||||
sizeof (*class_count),
|
||||
compare_class_count,
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < n_classes; i++)
|
||||
{
|
||||
guint split = start;
|
||||
for (j = start; j < end; j++)
|
||||
{
|
||||
GtkCssSelector *selector = g_array_index (priv->rulesets, GtkCssRuleset, refs[j]).selector;
|
||||
|
||||
if (_gtk_css_selector_has_primary_class (selector, class_count[i].class))
|
||||
{
|
||||
guint tmp = refs[split];
|
||||
refs[split] = refs[j];
|
||||
refs[j] = tmp;
|
||||
split++;
|
||||
}
|
||||
}
|
||||
/* Check size again sice nodes may have been used in other trees */
|
||||
if (split - start > 3)
|
||||
{
|
||||
tree = g_new (GtkCssRulesetsTree, 1);
|
||||
tree->type = RULESETS_TREE_TYPE_CLASS;
|
||||
tree->u.class.matched = subdivide_by_none (priv, refs, start, split);
|
||||
tree->u.class.class = class_count[i].class;
|
||||
|
||||
tree->next = trees;
|
||||
trees = tree;
|
||||
start = split;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (class_count);
|
||||
|
||||
if (start != end)
|
||||
{
|
||||
tree = subdivide_by_none (priv, refs, start, end);
|
||||
tree->next = trees;
|
||||
trees = tree;
|
||||
}
|
||||
|
||||
return trees;
|
||||
}
|
||||
|
||||
|
||||
static GtkCssRulesetsTree *
|
||||
subdivide_by_state (GtkCssProviderPrivate *priv, guint *refs, guint start, guint end, guint state)
|
||||
{
|
||||
GtkCssRulesetsTree *tree;
|
||||
guint i;
|
||||
|
||||
if (end == start)
|
||||
return NULL;
|
||||
|
||||
if (state == 0)
|
||||
return subdivide_by_class (priv, refs, start, end);
|
||||
|
||||
// Find first non-set flag
|
||||
for (i = start; i < end; i++)
|
||||
{
|
||||
GtkCssSelector *selector = g_array_index (priv->rulesets, GtkCssRuleset, refs[i]).selector;
|
||||
if ((_gtk_css_selector_get_primary_state_flags (selector) & state) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == start || i == end) /* All or none set, no use subdividing by this */
|
||||
return subdivide_by_state (priv, refs, start, end, state >> 1);
|
||||
|
||||
tree = g_new (GtkCssRulesetsTree, 1);
|
||||
tree->type = RULESETS_TREE_TYPE_STATE;
|
||||
tree->u.state.matched = subdivide_by_state (priv, refs, start, i, state >> 1);
|
||||
tree->u.state.state = state;
|
||||
|
||||
tree->next = subdivide_by_state (priv, refs, i, end, state >> 1);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_refs_by_flags (gconstpointer pa,
|
||||
gconstpointer pb,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint a = *(guint *)pa;
|
||||
guint b = *(guint *)pb;
|
||||
GArray *rulesets = user_data;
|
||||
GtkCssSelector *selector_a, *selector_b;
|
||||
guint32 flags_a, flags_b;
|
||||
|
||||
selector_a = g_array_index (rulesets, GtkCssRuleset, a).selector;
|
||||
selector_b = g_array_index (rulesets, GtkCssRuleset, b).selector;
|
||||
|
||||
flags_a = _gtk_css_selector_get_primary_state_flags (selector_a);
|
||||
flags_b = _gtk_css_selector_get_primary_state_flags (selector_b);
|
||||
|
||||
return flags_b - flags_a;
|
||||
}
|
||||
|
||||
static void
|
||||
print_tree (GtkCssRulesetsTree *tree, int indent)
|
||||
{
|
||||
if (tree == NULL)
|
||||
return;
|
||||
|
||||
switch (tree->type)
|
||||
{
|
||||
case RULESETS_TREE_TYPE_RULES:
|
||||
printf ("%*sCheck rules %p len %d\n", indent, "", tree->u.rules.rules, tree->u.rules.num_rules);
|
||||
break;
|
||||
case RULESETS_TREE_TYPE_STATE:
|
||||
printf ("%*sMatch state 0x%x ->\n", indent, "", tree->u.state.state);
|
||||
print_tree (tree->u.state.matched, indent + 4);
|
||||
break;
|
||||
case RULESETS_TREE_TYPE_CLASS:
|
||||
printf ("%*sMatch class %s ->\n", indent, "", g_quark_to_string (tree->u.class.class));
|
||||
print_tree (tree->u.class.matched, indent + 4);
|
||||
break;
|
||||
}
|
||||
|
||||
print_tree (tree->next, indent);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
||||
{
|
||||
GtkCssProviderPrivate *priv = css_provider->priv;
|
||||
guint *refs, i;
|
||||
|
||||
g_array_sort (priv->rulesets, gtk_css_provider_compare_rule);
|
||||
|
||||
refs = g_new (guint, priv->rulesets->len);
|
||||
priv->rulesets_refs = refs;
|
||||
|
||||
for (i = 0; i < priv->rulesets->len; i++)
|
||||
refs[i] = i;
|
||||
|
||||
/* Sort by flags, so that high bits set is sorted first at each level */
|
||||
g_qsort_with_data (refs,
|
||||
priv->rulesets->len,
|
||||
sizeof (guint),
|
||||
compare_refs_by_flags,
|
||||
priv->rulesets);
|
||||
|
||||
priv->rulesets_tree = subdivide_by_state (priv, refs, 0, priv->rulesets->len, GTK_STATE_FLAG_BACKDROP);
|
||||
if (g_getenv ("GTK_CSS_DEBUG_TREE"))
|
||||
{
|
||||
g_print ("Rulesets tree for proviced %p (%d rules)\n", css_provider, priv->rulesets->len);
|
||||
print_tree (priv->rulesets_tree, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2692,6 +3130,124 @@ _gtk_css_provider_get_theme_dir (void)
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_css_provider_load_named:
|
||||
* @provider: a #GtkCssProvider
|
||||
* @name: A theme name
|
||||
* @variant: (allow-none): variant to load, for example, "dark", or
|
||||
* %NULL for the default
|
||||
*
|
||||
* Loads a theme from the usual theme paths. The actual process of
|
||||
* finding the theme might change between releases, but it is
|
||||
* guaranteed that this function uses the same mechanism to load the
|
||||
* theme than GTK uses for loading its own theme.
|
||||
**/
|
||||
void
|
||||
_gtk_css_provider_load_named (GtkCssProvider *provider,
|
||||
const gchar *name,
|
||||
const gchar *variant)
|
||||
{
|
||||
gchar *subpath, *path;
|
||||
gchar *resource_path;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_PROVIDER (provider));
|
||||
g_return_if_fail (name != NULL);
|
||||
|
||||
gtk_css_provider_reset (provider);
|
||||
|
||||
/* try loading the resource for the theme. This is mostly meant for built-in
|
||||
* themes.
|
||||
*/
|
||||
if (variant)
|
||||
resource_path = g_strdup_printf ("/org/gtk/libgtk/%s-%s.css", name, variant);
|
||||
else
|
||||
resource_path = g_strdup_printf ("/org/gtk/libgtk/%s.css", name);
|
||||
|
||||
if (g_resources_get_info (resource_path, 0, NULL, NULL, NULL))
|
||||
{
|
||||
gtk_css_provider_load_from_resource (provider, resource_path);
|
||||
g_free (resource_path);
|
||||
return;
|
||||
}
|
||||
g_free (resource_path);
|
||||
|
||||
|
||||
/* Next try looking for files in the various theme directories.
|
||||
*/
|
||||
if (variant)
|
||||
subpath = g_strdup_printf ("gtk-3.0" G_DIR_SEPARATOR_S "gtk-%s.css", variant);
|
||||
else
|
||||
subpath = g_strdup ("gtk-3.0" G_DIR_SEPARATOR_S "gtk.css");
|
||||
|
||||
/* First look in the user's config directory
|
||||
*/
|
||||
path = g_build_filename (g_get_user_data_dir (), "themes", name, subpath, NULL);
|
||||
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (path);
|
||||
/* Next look in the user's home directory
|
||||
*/
|
||||
path = g_build_filename (g_get_home_dir (), ".themes", name, subpath, NULL);
|
||||
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
gchar *theme_dir;
|
||||
|
||||
g_free (path);
|
||||
|
||||
/* Finally, try in the default theme directory */
|
||||
theme_dir = _gtk_css_provider_get_theme_dir ();
|
||||
path = g_build_filename (theme_dir, name, subpath, NULL);
|
||||
g_free (theme_dir);
|
||||
|
||||
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (path);
|
||||
path = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free (subpath);
|
||||
|
||||
if (path)
|
||||
{
|
||||
char *dir, *resource_file;
|
||||
GResource *resource;
|
||||
|
||||
dir = g_path_get_dirname (path);
|
||||
resource_file = g_build_filename (dir, "gtk.gresource", NULL);
|
||||
resource = g_resource_load (resource_file, NULL);
|
||||
g_free (resource_file);
|
||||
|
||||
if (resource != NULL)
|
||||
g_resources_register (resource);
|
||||
|
||||
gtk_css_provider_load_from_path (provider, path, NULL);
|
||||
|
||||
/* Only set this after load, as load_from_path will clear it */
|
||||
provider->priv->resource = resource;
|
||||
|
||||
g_free (path);
|
||||
g_free (dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Things failed! Fall back! Fall back! */
|
||||
|
||||
if (variant)
|
||||
{
|
||||
/* If there was a variant, try without */
|
||||
_gtk_css_provider_load_named (provider, name, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Worst case, fall back to Raleigh */
|
||||
g_return_if_fail (!g_str_equal (name, "Raleigh")); /* infloop protection */
|
||||
_gtk_css_provider_load_named (provider, "Raleigh", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_provider_get_named:
|
||||
* @name: A theme name
|
||||
@@ -2712,113 +3268,22 @@ gtk_css_provider_get_named (const gchar *name,
|
||||
gchar *key;
|
||||
|
||||
if (variant == NULL)
|
||||
key = (gchar *)name;
|
||||
key = g_strdup (name);
|
||||
else
|
||||
key = g_strconcat (name, "-", variant, NULL);
|
||||
if (G_UNLIKELY (!themes))
|
||||
themes = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
provider = g_hash_table_lookup (themes, key);
|
||||
|
||||
|
||||
if (!provider)
|
||||
{
|
||||
gchar *resource_path = NULL;
|
||||
|
||||
if (variant)
|
||||
resource_path = g_strdup_printf ("/org/gtk/libgtk/%s-%s.css", name, variant);
|
||||
else
|
||||
resource_path = g_strdup_printf ("/org/gtk/libgtk/%s.css", name);
|
||||
|
||||
if (g_resources_get_info (resource_path, 0, NULL, NULL, NULL))
|
||||
{
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, resource_path);
|
||||
}
|
||||
g_free (resource_path);
|
||||
provider = gtk_css_provider_new ();
|
||||
_gtk_css_provider_load_named (provider, name, variant);
|
||||
g_hash_table_insert (themes, g_strdup (key), provider);
|
||||
}
|
||||
|
||||
if (!provider)
|
||||
{
|
||||
gchar *subpath, *path = NULL;
|
||||
|
||||
if (variant)
|
||||
subpath = g_strdup_printf ("gtk-3.0" G_DIR_SEPARATOR_S "gtk-%s.css", variant);
|
||||
else
|
||||
subpath = g_strdup ("gtk-3.0" G_DIR_SEPARATOR_S "gtk.css");
|
||||
|
||||
/* First look in the user's config directory
|
||||
*/
|
||||
path = g_build_filename (g_get_user_data_dir (), "themes", name, subpath, NULL);
|
||||
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (path);
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
/* Next look in the user's home directory
|
||||
*/
|
||||
if (!path)
|
||||
{
|
||||
const gchar *home_dir;
|
||||
|
||||
home_dir = g_get_home_dir ();
|
||||
if (home_dir)
|
||||
{
|
||||
path = g_build_filename (home_dir, ".themes", name, subpath, NULL);
|
||||
|
||||
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (path);
|
||||
path = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!path)
|
||||
{
|
||||
gchar *theme_dir;
|
||||
|
||||
theme_dir = _gtk_css_provider_get_theme_dir ();
|
||||
path = g_build_filename (theme_dir, name, subpath, NULL);
|
||||
g_free (theme_dir);
|
||||
|
||||
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (path);
|
||||
path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (subpath);
|
||||
|
||||
if (path)
|
||||
{
|
||||
char *dir, *resource_file;
|
||||
GResource *resource;
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
|
||||
dir = g_path_get_dirname (path);
|
||||
resource_file = g_build_filename (dir, "gtk.gresource", NULL);
|
||||
resource = g_resource_load (resource_file, NULL);
|
||||
g_free (resource_file);
|
||||
|
||||
if (resource != NULL)
|
||||
g_resources_register (resource);
|
||||
|
||||
gtk_css_provider_load_from_path (provider, path, NULL);
|
||||
|
||||
/* Only set this after load, as load_from_path will clear it */
|
||||
provider->priv->resource = resource;
|
||||
g_hash_table_insert (themes, g_strdup (key), provider);
|
||||
|
||||
g_free (path);
|
||||
g_free (dir);
|
||||
}
|
||||
}
|
||||
|
||||
if (key != name)
|
||||
g_free (key);
|
||||
|
||||
g_free (key);
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@ G_BEGIN_DECLS
|
||||
|
||||
gchar *_gtk_css_provider_get_theme_dir (void);
|
||||
|
||||
void _gtk_css_provider_load_named (GtkCssProvider *provider,
|
||||
const gchar *name,
|
||||
const gchar *variant);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_PROVIDER_PRIVATE_H__ */
|
||||
|
||||
+69
-18
@@ -38,6 +38,7 @@ struct _GtkCssSelectorClass {
|
||||
guint increase_id_specificity :1;
|
||||
guint increase_class_specificity :1;
|
||||
guint increase_element_specificity :1;
|
||||
guint is_simple :1;
|
||||
};
|
||||
|
||||
struct _GtkCssSelector
|
||||
@@ -112,7 +113,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_DESCENDANT = {
|
||||
gtk_css_selector_descendant_print,
|
||||
gtk_css_selector_descendant_match,
|
||||
gtk_css_selector_descendant_get_change,
|
||||
FALSE, FALSE, FALSE
|
||||
FALSE, FALSE, FALSE, FALSE
|
||||
};
|
||||
|
||||
/* CHILD */
|
||||
@@ -147,7 +148,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
|
||||
gtk_css_selector_child_print,
|
||||
gtk_css_selector_child_match,
|
||||
gtk_css_selector_child_get_change,
|
||||
FALSE, FALSE, FALSE
|
||||
FALSE, FALSE, FALSE, FALSE
|
||||
};
|
||||
|
||||
/* SIBLING */
|
||||
@@ -187,7 +188,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_SIBLING = {
|
||||
gtk_css_selector_sibling_print,
|
||||
gtk_css_selector_sibling_match,
|
||||
gtk_css_selector_sibling_get_change,
|
||||
FALSE, FALSE, FALSE
|
||||
FALSE, FALSE, FALSE, FALSE
|
||||
};
|
||||
|
||||
/* ADJACENT */
|
||||
@@ -222,7 +223,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
|
||||
gtk_css_selector_adjacent_print,
|
||||
gtk_css_selector_adjacent_match,
|
||||
gtk_css_selector_adjacent_get_change,
|
||||
FALSE, FALSE, FALSE
|
||||
FALSE, FALSE, FALSE, FALSE
|
||||
};
|
||||
|
||||
/* ANY */
|
||||
@@ -262,7 +263,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ANY = {
|
||||
gtk_css_selector_any_print,
|
||||
gtk_css_selector_any_match,
|
||||
gtk_css_selector_any_get_change,
|
||||
FALSE, FALSE, FALSE
|
||||
FALSE, FALSE, FALSE, TRUE
|
||||
};
|
||||
|
||||
/* NAME */
|
||||
@@ -295,7 +296,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_NAME = {
|
||||
gtk_css_selector_name_print,
|
||||
gtk_css_selector_name_match,
|
||||
gtk_css_selector_name_get_change,
|
||||
FALSE, FALSE, TRUE
|
||||
FALSE, FALSE, TRUE, TRUE
|
||||
};
|
||||
|
||||
/* REGION */
|
||||
@@ -341,7 +342,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_REGION = {
|
||||
gtk_css_selector_region_print,
|
||||
gtk_css_selector_region_match,
|
||||
gtk_css_selector_region_get_change,
|
||||
FALSE, FALSE, TRUE
|
||||
FALSE, FALSE, TRUE, TRUE
|
||||
};
|
||||
|
||||
/* CLASS */
|
||||
@@ -375,7 +376,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_CLASS = {
|
||||
gtk_css_selector_class_print,
|
||||
gtk_css_selector_class_match,
|
||||
gtk_css_selector_class_get_change,
|
||||
FALSE, TRUE, FALSE
|
||||
FALSE, TRUE, FALSE, TRUE
|
||||
};
|
||||
|
||||
/* ID */
|
||||
@@ -409,7 +410,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ID = {
|
||||
gtk_css_selector_id_print,
|
||||
gtk_css_selector_id_match,
|
||||
gtk_css_selector_id_get_change,
|
||||
TRUE, FALSE, FALSE
|
||||
TRUE, FALSE, FALSE, TRUE
|
||||
};
|
||||
|
||||
/* PSEUDOCLASS FOR STATE */
|
||||
@@ -430,18 +431,15 @@ gtk_css_selector_pseudoclass_state_print (const GtkCssSelector *selector,
|
||||
guint i, state;
|
||||
|
||||
state = GPOINTER_TO_UINT (selector->data);
|
||||
g_string_append_c (string, ':');
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (state_names); i++)
|
||||
{
|
||||
if (state == (1 << i))
|
||||
{
|
||||
g_string_append_c (string, ':');
|
||||
g_string_append (string, state_names[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -467,7 +465,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_STATE = {
|
||||
gtk_css_selector_pseudoclass_state_print,
|
||||
gtk_css_selector_pseudoclass_state_match,
|
||||
gtk_css_selector_pseudoclass_state_get_change,
|
||||
FALSE, TRUE, FALSE
|
||||
FALSE, TRUE, FALSE, TRUE
|
||||
};
|
||||
|
||||
/* PSEUDOCLASS FOR POSITION */
|
||||
@@ -708,7 +706,7 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_POSITION = {
|
||||
gtk_css_selector_pseudoclass_position_print,
|
||||
gtk_css_selector_pseudoclass_position_match,
|
||||
gtk_css_selector_pseudoclass_position_get_change,
|
||||
FALSE, TRUE, FALSE
|
||||
FALSE, TRUE, FALSE, TRUE
|
||||
};
|
||||
|
||||
/* API */
|
||||
@@ -950,9 +948,16 @@ parse_selector_pseudo_class (GtkCssParser *parser,
|
||||
if (_gtk_css_parser_try (parser, pseudo_classes[i].name, FALSE))
|
||||
{
|
||||
if (pseudo_classes[i].state_flag)
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector,
|
||||
GUINT_TO_POINTER (pseudo_classes[i].state_flag));
|
||||
{
|
||||
/* Piggy back on previous pseudoclass if any */
|
||||
if (selector && selector->class == >K_CSS_SELECTOR_PSEUDOCLASS_STATE)
|
||||
selector->data = GUINT_TO_POINTER (GPOINTER_TO_UINT (selector->data) |
|
||||
pseudo_classes[i].state_flag);
|
||||
else
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector,
|
||||
GUINT_TO_POINTER (pseudo_classes[i].state_flag));
|
||||
}
|
||||
else
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector,
|
||||
@@ -1172,3 +1177,49 @@ _gtk_css_selector_get_state_flags (const GtkCssSelector *selector)
|
||||
return state;
|
||||
}
|
||||
|
||||
GtkStateFlags
|
||||
_gtk_css_selector_get_primary_state_flags (const GtkCssSelector *selector)
|
||||
{
|
||||
GtkStateFlags state = 0;
|
||||
|
||||
g_return_val_if_fail (selector != NULL, 0);
|
||||
|
||||
for (; selector && selector->class->is_simple; selector = gtk_css_selector_previous (selector))
|
||||
{
|
||||
if (selector->class == >K_CSS_SELECTOR_PSEUDOCLASS_STATE)
|
||||
state |= GPOINTER_TO_UINT (selector->data);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
GQuark *
|
||||
_gtk_css_selector_get_primary_classes (const GtkCssSelector *selector)
|
||||
{
|
||||
GArray *array = g_array_new (TRUE, FALSE, sizeof (GQuark));
|
||||
|
||||
g_return_val_if_fail (selector != NULL, 0);
|
||||
|
||||
for (; selector && selector->class->is_simple; selector = gtk_css_selector_previous (selector))
|
||||
{
|
||||
if (selector->class == >K_CSS_SELECTOR_CLASS)
|
||||
g_array_append_val (array, selector->data);
|
||||
}
|
||||
|
||||
return (GQuark *)g_array_free (array, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_selector_has_primary_class (const GtkCssSelector *selector, GQuark class)
|
||||
{
|
||||
g_return_val_if_fail (selector != NULL, 0);
|
||||
|
||||
for (; selector && selector->class->is_simple; selector = gtk_css_selector_previous (selector))
|
||||
{
|
||||
if (selector->class == >K_CSS_SELECTOR_CLASS)
|
||||
if (GPOINTER_TO_UINT (selector->data) == class)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,11 @@ gboolean _gtk_css_selector_matches (const GtkCssSelector *sel
|
||||
int _gtk_css_selector_compare (const GtkCssSelector *a,
|
||||
const GtkCssSelector *b);
|
||||
|
||||
GtkStateFlags _gtk_css_selector_get_primary_state_flags (const GtkCssSelector *selector);
|
||||
GQuark * _gtk_css_selector_get_primary_classes (const GtkCssSelector *selector);
|
||||
gboolean _gtk_css_selector_has_primary_class (const GtkCssSelector *selector,
|
||||
GQuark class);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_SELECTOR_PRIVATE_H__ */
|
||||
|
||||
+32
-10
@@ -98,42 +98,64 @@ gtk_css_value_shadows_transition (GtkCssValue *start,
|
||||
guint property_id,
|
||||
double progress)
|
||||
{
|
||||
GtkCssValue *result;
|
||||
guint i;
|
||||
guint i, len;
|
||||
GtkCssValue **values;
|
||||
|
||||
/* catches the important case of 2 none values */
|
||||
if (start == end)
|
||||
return _gtk_css_value_ref (start);
|
||||
|
||||
if (start->len > end->len)
|
||||
result = gtk_css_shadows_value_new (start->values, start->len);
|
||||
len = start->len;
|
||||
else
|
||||
result = gtk_css_shadows_value_new (end->values, end->len);
|
||||
len = end->len;
|
||||
|
||||
values = g_newa (GtkCssValue *, len);
|
||||
|
||||
for (i = 0; i < MIN (start->len, end->len); i++)
|
||||
{
|
||||
result->values[i] = _gtk_css_value_transition (start->values[i], end->values[i], property_id, progress);
|
||||
values[i] = _gtk_css_value_transition (start->values[i], end->values[i], property_id, progress);
|
||||
if (values[i] == NULL)
|
||||
{
|
||||
while (i--)
|
||||
_gtk_css_value_unref (values[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (start->len > end->len)
|
||||
{
|
||||
for (; i < result->len; i++)
|
||||
for (; i < len; i++)
|
||||
{
|
||||
GtkCssValue *fill = _gtk_css_shadow_value_new_for_transition (start->values[i]);
|
||||
result->values[i] = _gtk_css_value_transition (start->values[i], fill, property_id, progress);
|
||||
values[i] = _gtk_css_value_transition (start->values[i], fill, property_id, progress);
|
||||
_gtk_css_value_unref (fill);
|
||||
|
||||
if (values[i] == NULL)
|
||||
{
|
||||
while (i--)
|
||||
_gtk_css_value_unref (values[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; i < result->len; i++)
|
||||
for (; i < len; i++)
|
||||
{
|
||||
GtkCssValue *fill = _gtk_css_shadow_value_new_for_transition (end->values[i]);
|
||||
result->values[i] = _gtk_css_value_transition (fill, end->values[i], property_id, progress);
|
||||
values[i] = _gtk_css_value_transition (fill, end->values[i], property_id, progress);
|
||||
_gtk_css_value_unref (fill);
|
||||
|
||||
if (values[i] == NULL)
|
||||
{
|
||||
while (i--)
|
||||
_gtk_css_value_unref (values[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return gtk_css_shadows_value_new (values, len);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
|
||||
#include "gtkcairoblurprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtksymboliccolorprivate.h"
|
||||
#include "gtkthemingengineprivate.h"
|
||||
#include "gtkpango.h"
|
||||
|
||||
@@ -271,7 +271,7 @@ _gtk_css_shadow_value_parse (GtkCssParser *parser)
|
||||
}
|
||||
else if (values[COLOR] == NULL)
|
||||
{
|
||||
values[COLOR] = _gtk_css_symbolic_value_new (parser);
|
||||
values[COLOR] = _gtk_css_color_value_parse (parser);
|
||||
|
||||
if (values[COLOR] == NULL)
|
||||
goto fail;
|
||||
@@ -287,9 +287,7 @@ _gtk_css_shadow_value_parse (GtkCssParser *parser)
|
||||
while (values[HOFFSET] == NULL || !value_is_done_parsing (parser));
|
||||
|
||||
if (values[COLOR] == NULL)
|
||||
values[COLOR] = _gtk_css_symbolic_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_ref (
|
||||
_gtk_symbolic_color_get_current_color ()));
|
||||
values[COLOR] = _gtk_css_color_value_new_current_color ();
|
||||
|
||||
return gtk_css_shadow_value_new (values[HOFFSET], values[VOFFSET],
|
||||
values[RADIUS], values[SPREAD],
|
||||
@@ -363,6 +361,7 @@ gtk_css_shadow_value_finish_drawing (const GtkCssValue *shadow,
|
||||
cairo_paint (original_cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
return original_cr;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "gtkcssarrayvalueprivate.h"
|
||||
#include "gtkcssbgsizevalueprivate.h"
|
||||
#include "gtkcssbordervalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcsscornervalueprivate.h"
|
||||
#include "gtkcsseasevalueprivate.h"
|
||||
#include "gtkcssenumvalueprivate.h"
|
||||
@@ -39,7 +40,6 @@
|
||||
#include "gtkcssstylefuncsprivate.h"
|
||||
#include "gtkcssvalueprivate.h"
|
||||
#include "gtkstylepropertiesprivate.h"
|
||||
#include "gtksymboliccolorprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
/* this is in case round() is not provided by the compiler,
|
||||
@@ -217,7 +217,7 @@ parse_border_color (GtkCssShorthandProperty *shorthand,
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
values[i] = _gtk_css_symbolic_value_new (parser);
|
||||
values[i] = _gtk_css_color_value_parse (parser);
|
||||
if (values[i] == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -349,7 +349,7 @@ parse_border_side (GtkCssShorthandProperty *shorthand,
|
||||
}
|
||||
else if (values[2] == NULL)
|
||||
{
|
||||
values[2] = _gtk_css_symbolic_value_new (parser);
|
||||
values[2] = _gtk_css_color_value_parse (parser);
|
||||
if (values[2] == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
@@ -388,7 +388,7 @@ parse_border (GtkCssShorthandProperty *shorthand,
|
||||
}
|
||||
else if (!G_IS_VALUE (&values[8]))
|
||||
{
|
||||
values[8] = _gtk_css_symbolic_value_new (parser);
|
||||
values[8] = _gtk_css_color_value_parse (parser);
|
||||
if (values[8] == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -516,7 +516,7 @@ parse_one_background (GtkCssShorthandProperty *shorthand,
|
||||
}
|
||||
else if (values[6] == NULL)
|
||||
{
|
||||
value = _gtk_css_symbolic_value_new (parser);
|
||||
value = _gtk_css_color_value_parse (parser);
|
||||
if (value == NULL)
|
||||
values[6] = _gtk_css_value_ref (_gtk_css_style_property_get_initial_value
|
||||
(_gtk_css_shorthand_property_get_subproperty (shorthand, 6)));
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "gtkcssarrayvalueprivate.h"
|
||||
#include "gtkcssbgsizevalueprivate.h"
|
||||
#include "gtkcssbordervalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcsscornervalueprivate.h"
|
||||
#include "gtkcsseasevalueprivate.h"
|
||||
#include "gtkcssenginevalueprivate.h"
|
||||
@@ -55,7 +56,6 @@
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssstringvalueprivate.h"
|
||||
#include "gtksymboliccolorprivate.h"
|
||||
#include "gtkthemingengine.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwin32themeprivate.h"
|
||||
@@ -171,7 +171,7 @@ static GtkCssValue *
|
||||
color_parse (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
return _gtk_css_symbolic_value_new (parser);
|
||||
return _gtk_css_color_value_parse (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -853,17 +853,6 @@ background_position_parse (GtkCssStyleProperty *property,
|
||||
|
||||
/*** REGISTRATION ***/
|
||||
|
||||
static GtkSymbolicColor *
|
||||
gtk_symbolic_color_new_rgba (double red,
|
||||
double green,
|
||||
double blue,
|
||||
double alpha)
|
||||
{
|
||||
GdkRGBA rgba = { red, green, blue, alpha };
|
||||
|
||||
return gtk_symbolic_color_new_literal (&rgba);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_style_property_init_properties (void)
|
||||
{
|
||||
@@ -878,8 +867,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
color_parse,
|
||||
color_query,
|
||||
color_assign,
|
||||
_gtk_css_symbolic_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_new_rgba (1, 1, 1, 1)));
|
||||
_gtk_css_color_value_new_rgba (1, 1, 1, 1));
|
||||
gtk_css_style_property_register ("font-size",
|
||||
GTK_CSS_PROPERTY_FONT_SIZE,
|
||||
G_TYPE_DOUBLE,
|
||||
@@ -899,8 +887,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
color_parse,
|
||||
color_query,
|
||||
color_assign,
|
||||
_gtk_css_symbolic_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_new_rgba (0, 0, 0, 0)));
|
||||
_gtk_css_color_value_new_rgba (0, 0, 0, 0));
|
||||
|
||||
gtk_css_style_property_register ("font-family",
|
||||
GTK_CSS_PROPERTY_FONT_FAMILY,
|
||||
@@ -1197,9 +1184,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
color_parse,
|
||||
color_query,
|
||||
color_assign,
|
||||
_gtk_css_symbolic_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_ref (
|
||||
_gtk_symbolic_color_get_current_color ())));
|
||||
_gtk_css_color_value_new_current_color ());
|
||||
gtk_css_style_property_register ("border-right-color",
|
||||
GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR,
|
||||
GDK_TYPE_RGBA,
|
||||
@@ -1207,9 +1192,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
color_parse,
|
||||
color_query,
|
||||
color_assign,
|
||||
_gtk_css_symbolic_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_ref (
|
||||
_gtk_symbolic_color_get_current_color ())));
|
||||
_gtk_css_color_value_new_current_color ());
|
||||
gtk_css_style_property_register ("border-bottom-color",
|
||||
GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR,
|
||||
GDK_TYPE_RGBA,
|
||||
@@ -1217,9 +1200,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
color_parse,
|
||||
color_query,
|
||||
color_assign,
|
||||
_gtk_css_symbolic_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_ref (
|
||||
_gtk_symbolic_color_get_current_color ())));
|
||||
_gtk_css_color_value_new_current_color ());
|
||||
gtk_css_style_property_register ("border-left-color",
|
||||
GTK_CSS_PROPERTY_BORDER_LEFT_COLOR,
|
||||
GDK_TYPE_RGBA,
|
||||
@@ -1227,9 +1208,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
color_parse,
|
||||
color_query,
|
||||
color_assign,
|
||||
_gtk_css_symbolic_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_ref (
|
||||
_gtk_symbolic_color_get_current_color ())));
|
||||
_gtk_css_color_value_new_current_color ());
|
||||
gtk_css_style_property_register ("outline-color",
|
||||
GTK_CSS_PROPERTY_OUTLINE_COLOR,
|
||||
GDK_TYPE_RGBA,
|
||||
@@ -1237,9 +1216,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
color_parse,
|
||||
color_query,
|
||||
color_assign,
|
||||
_gtk_css_symbolic_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_ref (
|
||||
_gtk_symbolic_color_get_current_color ())));
|
||||
_gtk_css_color_value_new_current_color ());
|
||||
|
||||
gtk_css_style_property_register ("background-repeat",
|
||||
GTK_CSS_PROPERTY_BACKGROUND_REPEAT,
|
||||
|
||||
@@ -49,10 +49,11 @@ typedef enum { /*< skip >*/
|
||||
GTK_CSS_CHANGE_PARENT_SIBLING_STATE = (1 << 15),
|
||||
/* add more */
|
||||
GTK_CSS_CHANGE_SOURCE = (1 << 16),
|
||||
GTK_CSS_CHANGE_ANIMATE = (1 << 17)
|
||||
GTK_CSS_CHANGE_ANIMATE = (1 << 17),
|
||||
GTK_CSS_CHANGE_FORCE_INVALIDATE = (1 << 18)
|
||||
} GtkCssChange;
|
||||
|
||||
#define GTK_CSS_CHANGE_ANY ((1 << 18) - 1)
|
||||
#define GTK_CSS_CHANGE_ANY ((1 << 19) - 1)
|
||||
#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)
|
||||
#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_SIBLING_CLASS | GTK_CSS_CHANGE_SIBLING_NAME | \
|
||||
GTK_CSS_CHANGE_SIBLING_POSITION | GTK_CSS_CHANGE_SIBLING_STATE)
|
||||
|
||||
@@ -8807,6 +8807,9 @@ gtk_entry_set_icon_tooltip_text (GtkEntry *entry,
|
||||
icon_info->tooltip = tooltip ? g_markup_escape_text (tooltip, -1) : NULL;
|
||||
|
||||
ensure_has_tooltip (entry);
|
||||
|
||||
g_object_notify (G_OBJECT (entry),
|
||||
icon_pos == GTK_ENTRY_ICON_PRIMARY ? "primary-icon-tooltip-text" : "secondary-icon-tooltip-text");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -656,8 +656,7 @@ gtk_entry_completion_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_TEXT_COLUMN:
|
||||
gtk_entry_completion_set_text_column (completion,
|
||||
g_value_get_int (value));
|
||||
priv->text_column = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_INLINE_COMPLETION:
|
||||
|
||||
@@ -803,6 +803,23 @@ typedef enum
|
||||
GTK_DRAG_RESULT_ERROR
|
||||
} GtkDragResult;
|
||||
|
||||
/**
|
||||
* GtkSizeGroupMode:
|
||||
* @GTK_SIZE_GROUP_NONE: group has no effect
|
||||
* @GTK_SIZE_GROUP_HORIZONTAL: group affects horizontal requisition
|
||||
* @GTK_SIZE_GROUP_VERTICAL: group affects vertical requisition
|
||||
* @GTK_SIZE_GROUP_BOTH: group affects both horizontal and vertical requisition
|
||||
*
|
||||
* The mode of the size group determines the directions in which the size
|
||||
* group affects the requested sizes of its component widgets.
|
||||
**/
|
||||
typedef enum {
|
||||
GTK_SIZE_GROUP_NONE,
|
||||
GTK_SIZE_GROUP_HORIZONTAL,
|
||||
GTK_SIZE_GROUP_VERTICAL,
|
||||
GTK_SIZE_GROUP_BOTH
|
||||
} GtkSizeGroupMode;
|
||||
|
||||
/**
|
||||
* GtkSizeRequestMode:
|
||||
* @GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH: Prefer height-for-width geometry management
|
||||
|
||||
@@ -264,6 +264,7 @@ typedef enum {
|
||||
#define SETTINGS_KEY_SORT_ORDER "sort-order"
|
||||
#define SETTINGS_KEY_WINDOW_POSITION "window-position"
|
||||
#define SETTINGS_KEY_WINDOW_SIZE "window-size"
|
||||
#define SETTINGS_KEY_SIDEBAR_WIDTH "sidebar-width"
|
||||
|
||||
static void gtk_file_chooser_default_iface_init (GtkFileChooserIface *iface);
|
||||
static void gtk_file_chooser_embed_default_iface_init (GtkFileChooserEmbedIface *iface);
|
||||
@@ -5057,7 +5058,7 @@ browse_widgets_create (GtkFileChooserDefault *impl)
|
||||
|
||||
/* Paned widget */
|
||||
|
||||
hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
hpaned = impl->browse_widgets_hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_widget_show (hpaned);
|
||||
gtk_box_pack_start (GTK_BOX (impl->browse_widgets_box), hpaned, TRUE, TRUE, 0);
|
||||
|
||||
@@ -5065,7 +5066,6 @@ browse_widgets_create (GtkFileChooserDefault *impl)
|
||||
gtk_paned_pack1 (GTK_PANED (hpaned), widget, FALSE, FALSE);
|
||||
widget = file_pane_create (impl, size_group);
|
||||
gtk_paned_pack2 (GTK_PANED (hpaned), widget, TRUE, FALSE);
|
||||
gtk_paned_set_position (GTK_PANED (hpaned), 148);
|
||||
g_object_unref (size_group);
|
||||
}
|
||||
|
||||
@@ -6037,6 +6037,7 @@ settings_load (GtkFileChooserDefault *impl)
|
||||
gboolean show_size_column;
|
||||
gint sort_column;
|
||||
GtkSortType sort_order;
|
||||
gint sidebar_width;
|
||||
|
||||
settings_ensure (impl);
|
||||
|
||||
@@ -6045,6 +6046,7 @@ settings_load (GtkFileChooserDefault *impl)
|
||||
show_size_column = g_settings_get_boolean (impl->settings, SETTINGS_KEY_SHOW_SIZE_COLUMN);
|
||||
sort_column = g_settings_get_enum (impl->settings, SETTINGS_KEY_SORT_COLUMN);
|
||||
sort_order = g_settings_get_enum (impl->settings, SETTINGS_KEY_SORT_ORDER);
|
||||
sidebar_width = g_settings_get_int (impl->settings, SETTINGS_KEY_SIDEBAR_WIDTH);
|
||||
|
||||
location_mode_set (impl, location_mode, TRUE);
|
||||
|
||||
@@ -6059,6 +6061,8 @@ settings_load (GtkFileChooserDefault *impl)
|
||||
* created yet. The individual functions that create and set the models will
|
||||
* call set_sort_column() themselves.
|
||||
*/
|
||||
|
||||
gtk_paned_set_position (GTK_PANED (impl->browse_widgets_hpaned), sidebar_width);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6106,6 +6110,8 @@ settings_save (GtkFileChooserDefault *impl)
|
||||
g_settings_set_boolean (impl->settings, SETTINGS_KEY_SHOW_SIZE_COLUMN, impl->show_size_column);
|
||||
g_settings_set_enum (impl->settings, SETTINGS_KEY_SORT_COLUMN, impl->sort_column);
|
||||
g_settings_set_enum (impl->settings, SETTINGS_KEY_SORT_ORDER, impl->sort_order);
|
||||
g_settings_set_int (impl->settings, SETTINGS_KEY_SIDEBAR_WIDTH,
|
||||
gtk_paned_get_position (GTK_PANED (impl->browse_widgets_hpaned)));
|
||||
|
||||
save_dialog_geometry (impl);
|
||||
|
||||
@@ -6798,7 +6804,7 @@ file_system_model_got_thumbnail (GObject *object, GAsyncResult *res, gpointer da
|
||||
copy_attribute (info, queried, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED);
|
||||
copy_attribute (info, queried, G_FILE_ATTRIBUTE_STANDARD_ICON);
|
||||
|
||||
_gtk_file_system_model_update_file (model, file, info, FALSE);
|
||||
_gtk_file_system_model_update_file (model, file, info);
|
||||
|
||||
g_object_unref (info);
|
||||
|
||||
@@ -7978,6 +7984,9 @@ add_shortcut_get_info_cb (GCancellable *cancellable,
|
||||
|
||||
shortcuts_insert_file (data->impl, pos, SHORTCUT_TYPE_FILE, NULL, data->file, NULL, FALSE, SHORTCUTS_SHORTCUTS);
|
||||
|
||||
/* need to call shortcuts_add_bookmarks to flush out any duplicates bug #577806 */
|
||||
shortcuts_add_bookmarks (data->impl);
|
||||
|
||||
out:
|
||||
g_object_unref (data->impl);
|
||||
g_object_unref (data->file);
|
||||
|
||||
@@ -166,6 +166,7 @@ struct _GtkFileChooserDefault
|
||||
|
||||
/* The file browsing widgets */
|
||||
GtkWidget *browse_widgets_box;
|
||||
GtkWidget *browse_widgets_hpaned;
|
||||
GtkWidget *browse_header_box;
|
||||
GtkWidget *browse_shortcuts_tree_view;
|
||||
GtkWidget *browse_shortcuts_add_button;
|
||||
|
||||
+94
-36
@@ -42,6 +42,9 @@
|
||||
* the special kind of usage for "search" and "recent-files", where the file chooser gives the model the
|
||||
* files to be displayed.
|
||||
*
|
||||
* Internal data structure
|
||||
* -----------------------
|
||||
*
|
||||
* Each file is kept in a FileModelNode structure. Each FileModelNode holds a GFile* and other data. All the
|
||||
* node structures have the same size, determined at runtime, depending on the number of columns that were passed
|
||||
* to _gtk_file_system_model_new() or _gtk_file_system_model_new_for_directory() (that is, the size of a node is
|
||||
@@ -66,7 +69,14 @@
|
||||
*
|
||||
* Each FileModelNode has a node->visible field, which indicates whether the node is visible in the GtkTreeView.
|
||||
* A node may be invisible if, for example, it corresponds to a hidden file and the file chooser is not showing
|
||||
* hidden files.
|
||||
* hidden files. Also, a file filter may be explicitly set onto the model, for example, to only show files that
|
||||
* match "*.jpg". In this case, node->filtered_out says whether the node failed the filter. The ultimate
|
||||
* decision on whether a node is visible or not in the treeview is distilled into the node->visible field.
|
||||
* The reason for having a separate node->filtered_out field is so that the file chooser can query whether
|
||||
* a (filtered-out) folder should be made sensitive in the GUI.
|
||||
*
|
||||
* Visible rows vs. possibly-invisible nodes
|
||||
* -----------------------------------------
|
||||
*
|
||||
* Since not all nodes in the model->files array may be visible, we need a way to map visible row indexes from
|
||||
* the treeview to array indexes in our array of files. And thus we introduce a bit of terminology:
|
||||
@@ -95,6 +105,16 @@
|
||||
*
|
||||
* You never access a node->row directly. Instead, call node_get_tree_row(). That function will validate the nodes
|
||||
* up to the sought one if the node is not valid yet, and it will return a proper 0-based row.
|
||||
*
|
||||
* Sorting
|
||||
* -------
|
||||
*
|
||||
* The model implements the GtkTreeSortable interface. To avoid re-sorting
|
||||
* every time a node gets added (which would lead to O(n^2) performance during
|
||||
* the initial population of the model), the model can freeze itself (with
|
||||
* freeze_updates()) during the intial population process. When the model is
|
||||
* frozen, sorting will not happen. The model will sort itself when the freeze
|
||||
* count goes back to zero, via corresponding calls to thaw_updates().
|
||||
*/
|
||||
|
||||
/*** DEFINES ***/
|
||||
@@ -184,6 +204,12 @@ struct _GtkFileSystemModelClass
|
||||
void (*finished_loading) (GtkFileSystemModel *model, GError *error);
|
||||
};
|
||||
|
||||
static void freeze_updates (GtkFileSystemModel *model);
|
||||
static void thaw_updates (GtkFileSystemModel *model);
|
||||
|
||||
static guint node_get_for_file (GtkFileSystemModel *model,
|
||||
GFile *file);
|
||||
|
||||
static void add_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info);
|
||||
@@ -263,13 +289,13 @@ node_invalidate_index (GtkFileSystemModel *model, guint id)
|
||||
}
|
||||
|
||||
static GtkTreePath *
|
||||
gtk_tree_path_new_from_node (GtkFileSystemModel *model, guint id)
|
||||
tree_path_new_from_node (GtkFileSystemModel *model, guint id)
|
||||
{
|
||||
guint i = node_get_tree_row (model, id);
|
||||
guint r = node_get_tree_row (model, id);
|
||||
|
||||
g_assert (i < model->files->len);
|
||||
g_assert (r < model->files->len);
|
||||
|
||||
return gtk_tree_path_new_from_indices (i, -1);
|
||||
return gtk_tree_path_new_from_indices (r, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -278,7 +304,7 @@ emit_row_inserted_for_node (GtkFileSystemModel *model, guint id)
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter iter;
|
||||
|
||||
path = gtk_tree_path_new_from_node (model, id);
|
||||
path = tree_path_new_from_node (model, id);
|
||||
ITER_INIT_FROM_INDEX (model, &iter, id);
|
||||
gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter);
|
||||
gtk_tree_path_free (path);
|
||||
@@ -290,7 +316,7 @@ emit_row_changed_for_node (GtkFileSystemModel *model, guint id)
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter iter;
|
||||
|
||||
path = gtk_tree_path_new_from_node (model, id);
|
||||
path = tree_path_new_from_node (model, id);
|
||||
ITER_INIT_FROM_INDEX (model, &iter, id);
|
||||
gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
|
||||
gtk_tree_path_free (path);
|
||||
@@ -570,7 +596,7 @@ gtk_file_system_model_get_path (GtkTreeModel *tree_model,
|
||||
|
||||
g_return_val_if_fail (ITER_IS_VALID (model, iter), NULL);
|
||||
|
||||
return gtk_tree_path_new_from_node (model, ITER_INDEX (iter));
|
||||
return tree_path_new_from_node (model, ITER_INDEX (iter));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1097,7 +1123,7 @@ thaw_func (gpointer data)
|
||||
{
|
||||
GtkFileSystemModel *model = data;
|
||||
|
||||
_gtk_file_system_model_thaw_updates (model);
|
||||
thaw_updates (model);
|
||||
model->dir_thaw_source = 0;
|
||||
|
||||
return FALSE;
|
||||
@@ -1119,7 +1145,7 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
|
||||
{
|
||||
if (model->dir_thaw_source == 0)
|
||||
{
|
||||
_gtk_file_system_model_freeze_updates (model);
|
||||
freeze_updates (model);
|
||||
model->dir_thaw_source = gdk_threads_add_timeout_full (IO_PRIORITY + 1,
|
||||
50,
|
||||
thaw_func,
|
||||
@@ -1168,7 +1194,7 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
|
||||
{
|
||||
g_source_remove (model->dir_thaw_source);
|
||||
model->dir_thaw_source = 0;
|
||||
_gtk_file_system_model_thaw_updates (model);
|
||||
thaw_updates (model);
|
||||
}
|
||||
|
||||
g_signal_emit (model, file_system_model_signals[FINISHED_LOADING], 0, error);
|
||||
@@ -1189,13 +1215,19 @@ gtk_file_system_model_query_done (GObject * object,
|
||||
GtkFileSystemModel *model = data; /* only a valid pointer if not cancelled */
|
||||
GFile *file = G_FILE (object);
|
||||
GFileInfo *info;
|
||||
guint id;
|
||||
|
||||
info = g_file_query_info_finish (file, res, NULL);
|
||||
if (info == NULL)
|
||||
return;
|
||||
|
||||
gdk_threads_enter ();
|
||||
_gtk_file_system_model_update_file (model, file, info, TRUE);
|
||||
|
||||
_gtk_file_system_model_update_file (model, file, info);
|
||||
|
||||
id = node_get_for_file (model, file);
|
||||
gtk_file_system_model_sort_node (model, id);
|
||||
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
||||
@@ -1433,14 +1465,14 @@ gtk_file_system_model_refilter_all (GtkFileSystemModel *model)
|
||||
return;
|
||||
}
|
||||
|
||||
_gtk_file_system_model_freeze_updates (model);
|
||||
freeze_updates (model);
|
||||
|
||||
/* start at index 1, don't change the editable */
|
||||
for (i = 1; i < model->files->len; i++)
|
||||
node_compute_visibility_and_filters (model, i);
|
||||
|
||||
model->filter_on_thaw = FALSE;
|
||||
_gtk_file_system_model_thaw_updates (model);
|
||||
thaw_updates (model);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1775,6 +1807,33 @@ _gtk_file_system_model_get_iter_for_file (GtkFileSystemModel *model,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* When an element is added or removed to the model->files array, we need to
|
||||
* update the model->file_lookup mappings of (node, index), as the indexes
|
||||
* change. This function adds the specified increment to the index in that pair
|
||||
* if the index is equal or after the specified id. We use this to slide the
|
||||
* mappings up or down when a node is added or removed, respectively.
|
||||
*/
|
||||
static void
|
||||
adjust_file_lookup (GtkFileSystemModel *model, guint id, int increment)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
gpointer value;
|
||||
|
||||
g_hash_table_iter_init (&iter, model->file_lookup);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
guint index = GPOINTER_TO_UINT (value);
|
||||
|
||||
if (index >= id)
|
||||
{
|
||||
index += increment;
|
||||
g_hash_table_iter_replace (&iter, GUINT_TO_POINTER (index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_file:
|
||||
* @model: the model
|
||||
@@ -1825,6 +1884,7 @@ remove_file (GtkFileSystemModel *model,
|
||||
{
|
||||
FileModelNode *node;
|
||||
guint id;
|
||||
guint row;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
@@ -1834,17 +1894,22 @@ remove_file (GtkFileSystemModel *model,
|
||||
return;
|
||||
|
||||
node = get_node (model, id);
|
||||
node_set_visible_and_filtered_out (model, id, FALSE, FALSE);
|
||||
row = node_get_tree_row (model, id);
|
||||
|
||||
node_invalidate_index (model, id);
|
||||
|
||||
g_hash_table_remove (model->file_lookup, file);
|
||||
g_object_unref (node->file);
|
||||
adjust_file_lookup (model, id, -1);
|
||||
|
||||
if (node->info)
|
||||
g_object_unref (node->info);
|
||||
|
||||
g_array_remove_index (model->files, id);
|
||||
g_hash_table_remove_all (model->file_lookup);
|
||||
/* We don't need to resort, as removing a row doesn't change the sorting order */
|
||||
|
||||
/* We don't need to resort, as removing a row doesn't change the sorting order of the other rows */
|
||||
|
||||
emit_row_deleted_for_row (model, row);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1852,7 +1917,6 @@ remove_file (GtkFileSystemModel *model,
|
||||
* @model: the model
|
||||
* @file: the file
|
||||
* @info: the new file info
|
||||
* @requires_resort: FIXME: get rid of this argument
|
||||
*
|
||||
* Tells the file system model that the file changed and that the
|
||||
* new @info should be used for it now. If the file is not part of
|
||||
@@ -1861,8 +1925,7 @@ remove_file (GtkFileSystemModel *model,
|
||||
void
|
||||
_gtk_file_system_model_update_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info,
|
||||
gboolean requires_resort)
|
||||
GFileInfo *info)
|
||||
{
|
||||
FileModelNode *node;
|
||||
guint i, id;
|
||||
@@ -1894,9 +1957,6 @@ _gtk_file_system_model_update_file (GtkFileSystemModel *model,
|
||||
|
||||
if (node->visible)
|
||||
emit_row_changed_for_node (model, id);
|
||||
|
||||
if (requires_resort)
|
||||
gtk_file_system_model_sort_node (model, id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1967,17 +2027,16 @@ _gtk_file_system_model_remove_editable (GtkFileSystemModel *model)
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_freeze_updates:
|
||||
* freeze_updates:
|
||||
* @model: a #GtkFileSystemModel
|
||||
*
|
||||
* Freezes most updates on the model, so that performing multiple
|
||||
* operations on the files in the model do not cause any events.
|
||||
* Use _gtk_file_system_model_thaw_updates() to resume proper
|
||||
* operations. It is fine to call this function multiple times as
|
||||
* long as freeze and thaw calls are balanced.
|
||||
* Freezes most updates on the model, so that performing multiple operations on
|
||||
* the files in the model do not cause any events. Use thaw_updates() to resume
|
||||
* proper operations. It is fine to call this function multiple times as long as
|
||||
* freeze and thaw calls are balanced.
|
||||
**/
|
||||
void
|
||||
_gtk_file_system_model_freeze_updates (GtkFileSystemModel *model)
|
||||
static void
|
||||
freeze_updates (GtkFileSystemModel *model)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
|
||||
@@ -1985,14 +2044,13 @@ _gtk_file_system_model_freeze_updates (GtkFileSystemModel *model)
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_thaw_updates:
|
||||
* thaw_updates:
|
||||
* @model: a #GtkFileSystemModel
|
||||
*
|
||||
* Undoes the effect of a previous call to
|
||||
* _gtk_file_system_model_freeze_updates()
|
||||
* Undoes the effect of a previous call to freeze_updates()
|
||||
**/
|
||||
void
|
||||
_gtk_file_system_model_thaw_updates (GtkFileSystemModel *model)
|
||||
static void
|
||||
thaw_updates (GtkFileSystemModel *model)
|
||||
{
|
||||
gboolean stuff_added;
|
||||
|
||||
|
||||
@@ -71,8 +71,7 @@ void _gtk_file_system_model_add_and_query_file (GtkFileSystemMode
|
||||
const char *attributes);
|
||||
void _gtk_file_system_model_update_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info,
|
||||
gboolean requires_resort);
|
||||
GFileInfo *info);
|
||||
|
||||
void _gtk_file_system_model_set_show_hidden (GtkFileSystemModel *model,
|
||||
gboolean show_hidden);
|
||||
@@ -82,8 +81,6 @@ void _gtk_file_system_model_set_show_files (GtkFileSystemModel
|
||||
gboolean show_files);
|
||||
void _gtk_file_system_model_set_filter_folders (GtkFileSystemModel *model,
|
||||
gboolean show_folders);
|
||||
void _gtk_file_system_model_freeze_updates (GtkFileSystemModel *model);
|
||||
void _gtk_file_system_model_thaw_updates (GtkFileSystemModel *model);
|
||||
void _gtk_file_system_model_clear_cache (GtkFileSystemModel *model,
|
||||
int column);
|
||||
|
||||
|
||||
+2
-1
@@ -327,6 +327,7 @@ _gtk_gradient_resolve_full (GtkGradient *gradient,
|
||||
{
|
||||
rgba = *_gtk_css_rgba_value_get_rgba (val);
|
||||
*dependencies = _gtk_css_dependencies_union (*dependencies, stop_deps);
|
||||
_gtk_css_value_unref (val);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -467,7 +468,7 @@ gtk_gradient_fade (GtkGradient *gradient,
|
||||
|
||||
stop = &g_array_index (gradient->stops, ColorStop, i);
|
||||
color = gtk_symbolic_color_new_alpha (stop->color, opacity);
|
||||
gtk_gradient_add_color_stop (gradient, stop->offset, color);
|
||||
gtk_gradient_add_color_stop (faded, stop->offset, color);
|
||||
gtk_symbolic_color_unref (color);
|
||||
}
|
||||
|
||||
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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 "gtkhslaprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
void
|
||||
_gtk_hsla_init (GtkHSLA *hsla,
|
||||
double hue,
|
||||
double saturation,
|
||||
double lightness,
|
||||
double alpha)
|
||||
{
|
||||
g_return_if_fail (hsla != NULL);
|
||||
|
||||
if (hue >= 0)
|
||||
hsla->hue = fmod (hue, 360);
|
||||
else
|
||||
hsla->hue = fmod (hue, 360) + 360;
|
||||
hsla->saturation = CLAMP (saturation, 0, 1);
|
||||
hsla->lightness = CLAMP (lightness, 0, 1);
|
||||
hsla->alpha = CLAMP (alpha, 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_hsla_init_from_rgba (GtkHSLA *hsla,
|
||||
const GdkRGBA *rgba)
|
||||
{
|
||||
gdouble min;
|
||||
gdouble max;
|
||||
gdouble red;
|
||||
gdouble green;
|
||||
gdouble blue;
|
||||
gdouble delta;
|
||||
|
||||
g_return_if_fail (hsla != NULL);
|
||||
g_return_if_fail (rgba != NULL);
|
||||
|
||||
red = rgba->red;
|
||||
green = rgba->green;
|
||||
blue = rgba->blue;
|
||||
|
||||
if (red > green)
|
||||
{
|
||||
if (red > blue)
|
||||
max = red;
|
||||
else
|
||||
max = blue;
|
||||
|
||||
if (green < blue)
|
||||
min = green;
|
||||
else
|
||||
min = blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (green > blue)
|
||||
max = green;
|
||||
else
|
||||
max = blue;
|
||||
|
||||
if (red < blue)
|
||||
min = red;
|
||||
else
|
||||
min = blue;
|
||||
}
|
||||
|
||||
hsla->lightness = (max + min) / 2;
|
||||
hsla->saturation = 0;
|
||||
hsla->hue = 0;
|
||||
hsla->alpha = rgba->alpha;
|
||||
|
||||
if (max != min)
|
||||
{
|
||||
if (hsla->lightness <= 0.5)
|
||||
hsla->saturation = (max - min) / (max + min);
|
||||
else
|
||||
hsla->saturation = (max - min) / (2 - max - min);
|
||||
|
||||
delta = max -min;
|
||||
if (red == max)
|
||||
hsla->hue = (green - blue) / delta;
|
||||
else if (green == max)
|
||||
hsla->hue = 2 + (blue - red) / delta;
|
||||
else if (blue == max)
|
||||
hsla->hue = 4 + (red - green) / delta;
|
||||
|
||||
hsla->hue *= 60;
|
||||
if (hsla->hue < 0.0)
|
||||
hsla->hue += 360;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_rgba_init_from_hsla (GdkRGBA *rgba,
|
||||
const GtkHSLA *hsla)
|
||||
{
|
||||
gdouble hue;
|
||||
gdouble lightness;
|
||||
gdouble saturation;
|
||||
gdouble m1, m2;
|
||||
|
||||
lightness = hsla->lightness;
|
||||
saturation = hsla->saturation;
|
||||
|
||||
if (lightness <= 0.5)
|
||||
m2 = lightness * (1 + saturation);
|
||||
else
|
||||
m2 = lightness + saturation - lightness * saturation;
|
||||
m1 = 2 * lightness - m2;
|
||||
|
||||
rgba->alpha = hsla->alpha;
|
||||
|
||||
if (saturation == 0)
|
||||
{
|
||||
rgba->red = lightness;
|
||||
rgba->green = lightness;
|
||||
rgba->blue = lightness;
|
||||
}
|
||||
else
|
||||
{
|
||||
hue = hsla->hue + 120;
|
||||
while (hue > 360)
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
|
||||
if (hue < 60)
|
||||
rgba->red = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
rgba->red = m2;
|
||||
else if (hue < 240)
|
||||
rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
|
||||
else
|
||||
rgba->red = m1;
|
||||
|
||||
hue = hsla->hue;
|
||||
while (hue > 360)
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
|
||||
if (hue < 60)
|
||||
rgba->green = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
rgba->green = m2;
|
||||
else if (hue < 240)
|
||||
rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
|
||||
else
|
||||
rgba->green = m1;
|
||||
|
||||
hue = hsla->hue - 120;
|
||||
while (hue > 360)
|
||||
hue -= 360;
|
||||
while (hue < 0)
|
||||
hue += 360;
|
||||
|
||||
if (hue < 60)
|
||||
rgba->blue = m1 + (m2 - m1) * hue / 60;
|
||||
else if (hue < 180)
|
||||
rgba->blue = m2;
|
||||
else if (hue < 240)
|
||||
rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
|
||||
else
|
||||
rgba->blue = m1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2012 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_HSLA_PRIVATE_H__
|
||||
#define __GTK_HSLA_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkHSLA GtkHSLA;
|
||||
|
||||
struct _GtkHSLA {
|
||||
double hue;
|
||||
double saturation;
|
||||
double lightness;
|
||||
double alpha;
|
||||
};
|
||||
|
||||
void _gtk_hsla_init (GtkHSLA *hsla,
|
||||
double hue,
|
||||
double saturation,
|
||||
double lightness,
|
||||
double alpha);
|
||||
void _gtk_hsla_init_from_rgba (GtkHSLA *hsla,
|
||||
const GdkRGBA *rgba);
|
||||
/* Yes, I can name that function like this! */
|
||||
void _gdk_rgba_init_from_hsla (GdkRGBA *rgba,
|
||||
const GtkHSLA *hsla);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_HSLA_PRIVATE_H__ */
|
||||
+67
-36
@@ -202,6 +202,7 @@ struct _GtkIconInfo
|
||||
/* Information about the source
|
||||
*/
|
||||
gchar *filename;
|
||||
GFile *icon_file;
|
||||
GLoadableIcon *loadable;
|
||||
GSList *emblem_infos;
|
||||
|
||||
@@ -1409,6 +1410,8 @@ choose_icon (GtkIconTheme *icon_theme,
|
||||
else if (unthemed_icon->no_svg_filename)
|
||||
icon_info->filename = g_strdup (unthemed_icon->no_svg_filename);
|
||||
|
||||
icon_info->icon_file = g_file_new_for_path (icon_info->filename);
|
||||
|
||||
icon_info->dir_type = ICON_THEME_DIR_UNTHEMED;
|
||||
icon_info->dir_size = size;
|
||||
}
|
||||
@@ -2291,11 +2294,13 @@ theme_lookup_icon (IconTheme *theme,
|
||||
{
|
||||
file = g_strconcat (icon_name, string_from_suffix (suffix), NULL);
|
||||
icon_info->filename = g_build_filename (min_dir->dir, file, NULL);
|
||||
icon_info->icon_file = g_file_new_for_path (icon_info->filename);
|
||||
g_free (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
icon_info->filename = NULL;
|
||||
icon_info->icon_file = NULL;
|
||||
}
|
||||
|
||||
if (min_dir->icon_data != NULL)
|
||||
@@ -2732,6 +2737,8 @@ gtk_icon_info_free (GtkIconInfo *icon_info)
|
||||
return;
|
||||
|
||||
g_free (icon_info->filename);
|
||||
g_clear_object (&icon_info->icon_file);
|
||||
|
||||
if (icon_info->loadable)
|
||||
g_object_unref (icon_info->loadable);
|
||||
g_slist_free_full (icon_info->emblem_infos, (GDestroyNotify) gtk_icon_info_free);
|
||||
@@ -2937,14 +2944,8 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
|
||||
/* SVG icons are a special case - we just immediately scale them
|
||||
* to the desired size
|
||||
*/
|
||||
if (icon_info->filename && !icon_info->loadable)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_path (icon_info->filename);
|
||||
icon_info->loadable = G_LOADABLE_ICON (g_file_icon_new (file));
|
||||
g_object_unref (file);
|
||||
}
|
||||
if (icon_info->icon_file && !icon_info->loadable)
|
||||
icon_info->loadable = G_LOADABLE_ICON (g_file_icon_new (icon_info->icon_file));
|
||||
|
||||
is_svg = FALSE;
|
||||
if (G_IS_FILE_ICON (icon_info->loadable))
|
||||
@@ -3173,7 +3174,7 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info,
|
||||
GdkPixbuf *pixbuf;
|
||||
gchar *data;
|
||||
gchar *success, *warning, *err;
|
||||
gchar *width, *height;
|
||||
gchar *width, *height, *uri;
|
||||
|
||||
/* css_fg can't possibly have failed, otherwise
|
||||
* that would mean we have a broken style */
|
||||
@@ -3199,8 +3200,14 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info,
|
||||
|
||||
if (!icon_info->symbolic_pixbuf_size)
|
||||
{
|
||||
stream = G_INPUT_STREAM (g_file_read (icon_info->icon_file, NULL, error));
|
||||
|
||||
if (!stream)
|
||||
return NULL;
|
||||
|
||||
/* Fetch size from the original icon */
|
||||
pixbuf = gdk_pixbuf_new_from_file (icon_info->filename, error);
|
||||
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, error);
|
||||
g_object_unref (stream);
|
||||
|
||||
if (!pixbuf)
|
||||
return NULL;
|
||||
@@ -3213,6 +3220,7 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info,
|
||||
|
||||
width = g_strdup_printf ("%d", icon_info->symbolic_pixbuf_size->width);
|
||||
height = g_strdup_printf ("%d", icon_info->symbolic_pixbuf_size->height);
|
||||
uri = g_file_get_uri (icon_info->icon_file);
|
||||
|
||||
data = g_strconcat ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
|
||||
"<svg version=\"1.1\"\n"
|
||||
@@ -3234,7 +3242,7 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info,
|
||||
" fill: ", css_success ? css_success : success," !important;\n"
|
||||
" }\n"
|
||||
" </style>\n"
|
||||
" <xi:include href=\"", icon_info->filename, "\"/>\n"
|
||||
" <xi:include href=\"", uri, "\"/>\n"
|
||||
"</svg>",
|
||||
NULL);
|
||||
g_free (warning);
|
||||
@@ -3242,6 +3250,7 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info,
|
||||
g_free (success);
|
||||
g_free (width);
|
||||
g_free (height);
|
||||
g_free (uri);
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (data, -1, g_free);
|
||||
pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream,
|
||||
@@ -3306,19 +3315,24 @@ gtk_icon_info_load_symbolic (GtkIconInfo *icon_info,
|
||||
gchar *css_success;
|
||||
gchar *css_warning;
|
||||
gchar *css_error;
|
||||
gchar *icon_uri;
|
||||
gboolean is_symbolic;
|
||||
|
||||
g_return_val_if_fail (icon_info != NULL, NULL);
|
||||
g_return_val_if_fail (fg != NULL, NULL);
|
||||
|
||||
if (!icon_info->filename ||
|
||||
!g_str_has_suffix (icon_info->filename, "-symbolic.svg"))
|
||||
{
|
||||
if (was_symbolic)
|
||||
*was_symbolic = FALSE;
|
||||
return gtk_icon_info_load_icon (icon_info, error);
|
||||
}
|
||||
icon_uri = NULL;
|
||||
if (icon_info->icon_file)
|
||||
icon_uri = g_file_get_uri (icon_info->icon_file);
|
||||
|
||||
is_symbolic = (icon_uri != NULL) && (g_str_has_suffix (icon_uri, "-symbolic.svg"));
|
||||
g_free (icon_uri);
|
||||
|
||||
if (was_symbolic)
|
||||
*was_symbolic = TRUE;
|
||||
*was_symbolic = is_symbolic;
|
||||
|
||||
if (!is_symbolic)
|
||||
return gtk_icon_info_load_icon (icon_info, error);
|
||||
|
||||
css_fg = gdk_rgba_to_css (fg);
|
||||
|
||||
@@ -3382,17 +3396,24 @@ gtk_icon_info_load_symbolic_for_context (GtkIconInfo *icon_info,
|
||||
gchar *css_fg = NULL, *css_success;
|
||||
gchar *css_warning, *css_error;
|
||||
GtkStateFlags state;
|
||||
gchar *icon_uri;
|
||||
gboolean is_symbolic;
|
||||
|
||||
if (!icon_info->filename ||
|
||||
!g_str_has_suffix (icon_info->filename, "-symbolic.svg"))
|
||||
{
|
||||
if (was_symbolic)
|
||||
*was_symbolic = FALSE;
|
||||
return gtk_icon_info_load_icon (icon_info, error);
|
||||
}
|
||||
g_return_val_if_fail (icon_info != NULL, NULL);
|
||||
g_return_val_if_fail (context != NULL, NULL);
|
||||
|
||||
icon_uri = NULL;
|
||||
if (icon_info->icon_file)
|
||||
icon_uri = g_file_get_uri (icon_info->icon_file);
|
||||
|
||||
is_symbolic = (icon_uri != NULL) && (g_str_has_suffix (icon_uri, "-symbolic.svg"));
|
||||
g_free (icon_uri);
|
||||
|
||||
if (was_symbolic)
|
||||
*was_symbolic = TRUE;
|
||||
*was_symbolic = is_symbolic;
|
||||
|
||||
if (!is_symbolic)
|
||||
return gtk_icon_info_load_icon (icon_info, error);
|
||||
|
||||
state = gtk_style_context_get_state (context);
|
||||
gtk_style_context_get (context, state, "color", &color, NULL);
|
||||
@@ -3465,17 +3486,24 @@ gtk_icon_info_load_symbolic_for_style (GtkIconInfo *icon_info,
|
||||
GdkColor *fg;
|
||||
gchar *css_fg, *css_success;
|
||||
gchar *css_warning, *css_error;
|
||||
gchar *icon_uri;
|
||||
gboolean is_symbolic;
|
||||
|
||||
if (!icon_info->filename ||
|
||||
!g_str_has_suffix (icon_info->filename, "-symbolic.svg"))
|
||||
{
|
||||
if (was_symbolic)
|
||||
*was_symbolic = FALSE;
|
||||
return gtk_icon_info_load_icon (icon_info, error);
|
||||
}
|
||||
g_return_val_if_fail (icon_info != NULL, NULL);
|
||||
g_return_val_if_fail (style != NULL, NULL);
|
||||
|
||||
icon_uri = NULL;
|
||||
if (icon_info->icon_file)
|
||||
icon_uri = g_file_get_uri (icon_info->icon_file);
|
||||
|
||||
is_symbolic = (icon_uri != NULL) && (g_str_has_suffix (icon_uri, "-symbolic.svg"));
|
||||
g_free (icon_uri);
|
||||
|
||||
if (was_symbolic)
|
||||
*was_symbolic = TRUE;
|
||||
*was_symbolic = is_symbolic;
|
||||
|
||||
if (!is_symbolic)
|
||||
return gtk_icon_info_load_icon (icon_info, error);
|
||||
|
||||
fg = &style->fg[state];
|
||||
css_fg = gdk_color_to_css (fg);
|
||||
@@ -3889,7 +3917,10 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme,
|
||||
{
|
||||
GFile *file = g_file_icon_get_file (G_FILE_ICON (icon));
|
||||
if (file != NULL)
|
||||
info->filename = g_file_get_path (file);
|
||||
{
|
||||
info->icon_file = g_object_ref (file);
|
||||
info->filename = g_file_get_path (file);
|
||||
}
|
||||
}
|
||||
|
||||
info->dir_type = ICON_THEME_DIR_UNTHEMED;
|
||||
|
||||
+10
-54
@@ -133,9 +133,6 @@ static void gtk_icon_view_get_property (GObject
|
||||
static void gtk_icon_view_destroy (GtkWidget *widget);
|
||||
static void gtk_icon_view_realize (GtkWidget *widget);
|
||||
static void gtk_icon_view_unrealize (GtkWidget *widget);
|
||||
static void gtk_icon_view_style_updated (GtkWidget *widget);
|
||||
static void gtk_icon_view_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state);
|
||||
static GtkSizeRequestMode gtk_icon_view_get_request_mode (GtkWidget *widget);
|
||||
static void gtk_icon_view_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
@@ -352,7 +349,6 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
|
||||
widget_class->destroy = gtk_icon_view_destroy;
|
||||
widget_class->realize = gtk_icon_view_realize;
|
||||
widget_class->unrealize = gtk_icon_view_unrealize;
|
||||
widget_class->style_updated = gtk_icon_view_style_updated;
|
||||
widget_class->get_request_mode = gtk_icon_view_get_request_mode;
|
||||
widget_class->get_preferred_width = gtk_icon_view_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_icon_view_get_preferred_height;
|
||||
@@ -373,7 +369,6 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
|
||||
widget_class->drag_motion = gtk_icon_view_drag_motion;
|
||||
widget_class->drag_drop = gtk_icon_view_drag_drop;
|
||||
widget_class->drag_data_received = gtk_icon_view_drag_data_received;
|
||||
widget_class->state_flags_changed = gtk_icon_view_state_flags_changed;
|
||||
|
||||
container_class->remove = gtk_icon_view_remove;
|
||||
container_class->forall = gtk_icon_view_forall;
|
||||
@@ -974,6 +969,9 @@ gtk_icon_view_init (GtkIconView *icon_view)
|
||||
|
||||
icon_view->priv->row_contexts =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (icon_view)),
|
||||
GTK_STYLE_CLASS_VIEW);
|
||||
}
|
||||
|
||||
/* GObject methods */
|
||||
@@ -1251,7 +1249,6 @@ gtk_icon_view_realize (GtkWidget *widget)
|
||||
GdkWindow *window;
|
||||
GdkWindowAttr attributes;
|
||||
gint attributes_mask;
|
||||
GtkStyleContext *context;
|
||||
|
||||
gtk_widget_set_realized (widget, TRUE);
|
||||
|
||||
@@ -1294,15 +1291,6 @@ gtk_icon_view_realize (GtkWidget *widget)
|
||||
icon_view->priv->bin_window = gdk_window_new (window,
|
||||
&attributes, attributes_mask);
|
||||
gdk_window_set_user_data (icon_view->priv->bin_window, widget);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
|
||||
gtk_style_context_set_background (context, icon_view->priv->bin_window);
|
||||
gtk_style_context_set_background (context, window);
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
gdk_window_show (icon_view->priv->bin_window);
|
||||
}
|
||||
|
||||
@@ -1320,44 +1308,6 @@ gtk_icon_view_unrealize (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_icon_view_update_background (GtkIconView *icon_view)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (icon_view);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
|
||||
|
||||
gtk_style_context_set_background (context, gtk_widget_get_window (widget));
|
||||
gtk_style_context_set_background (context, icon_view->priv->bin_window);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_view_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state)
|
||||
{
|
||||
_gtk_icon_view_update_background (GTK_ICON_VIEW (widget));
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_view_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->style_updated (widget);
|
||||
|
||||
_gtk_icon_view_update_background (GTK_ICON_VIEW (widget));
|
||||
gtk_widget_queue_resize (widget);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_icon_view_get_n_items (GtkIconView *icon_view)
|
||||
{
|
||||
@@ -1823,9 +1773,16 @@ gtk_icon_view_draw (GtkWidget *widget,
|
||||
gint dest_index;
|
||||
GtkIconViewDropPosition dest_pos;
|
||||
GtkIconViewItem *dest_item = NULL;
|
||||
GtkStyleContext *context;
|
||||
|
||||
icon_view = GTK_ICON_VIEW (widget);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_render_background (context, cr,
|
||||
0, 0,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget));
|
||||
|
||||
if (!gtk_cairo_should_draw_window (cr, icon_view->priv->bin_window))
|
||||
return FALSE;
|
||||
|
||||
@@ -3037,7 +2994,6 @@ gtk_icon_view_paint_item (GtkIconView *icon_view,
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
gtk_style_context_save (style_context);
|
||||
gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_VIEW);
|
||||
gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_CELL);
|
||||
|
||||
state &= ~(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_PRELIGHT);
|
||||
|
||||
+57
-98
@@ -3158,7 +3158,6 @@ get_font_metrics (PangoContext *context, GtkWidget *widget)
|
||||
* @label: the label
|
||||
* @existing_layout: %NULL or an existing layout already in use.
|
||||
* @width: the width to measure with in pango units, or -1 for infinite
|
||||
* @height: the height to measure with in pango units, or -1 for infinite
|
||||
*
|
||||
* Gets a layout that can be used for measuring sizes. The returned
|
||||
* layout will be identical to the label's layout except for the
|
||||
@@ -3170,8 +3169,7 @@ get_font_metrics (PangoContext *context, GtkWidget *widget)
|
||||
static PangoLayout *
|
||||
gtk_label_get_measuring_layout (GtkLabel * label,
|
||||
PangoLayout *existing_layout,
|
||||
int width,
|
||||
int height)
|
||||
int width)
|
||||
{
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
PangoRectangle rect;
|
||||
@@ -3182,7 +3180,6 @@ gtk_label_get_measuring_layout (GtkLabel * label,
|
||||
if (existing_layout != priv->layout)
|
||||
{
|
||||
pango_layout_set_width (existing_layout, width);
|
||||
pango_layout_set_height (existing_layout, height);
|
||||
return existing_layout;
|
||||
}
|
||||
|
||||
@@ -3191,8 +3188,7 @@ gtk_label_get_measuring_layout (GtkLabel * label,
|
||||
|
||||
gtk_label_ensure_layout (label);
|
||||
|
||||
if (pango_layout_get_width (priv->layout) == width &&
|
||||
pango_layout_get_height (priv->layout) == height)
|
||||
if (pango_layout_get_width (priv->layout) == width)
|
||||
{
|
||||
g_object_ref (priv->layout);
|
||||
return priv->layout;
|
||||
@@ -3206,7 +3202,6 @@ gtk_label_get_measuring_layout (GtkLabel * label,
|
||||
{
|
||||
g_object_ref (priv->layout);
|
||||
pango_layout_set_width (priv->layout, width);
|
||||
pango_layout_set_height (priv->layout, height);
|
||||
return priv->layout;
|
||||
}
|
||||
|
||||
@@ -3217,7 +3212,6 @@ gtk_label_get_measuring_layout (GtkLabel * label,
|
||||
*/
|
||||
pango_layout_get_extents (priv->layout, NULL, &rect);
|
||||
if ((width == -1 || rect.width <= width) &&
|
||||
(height == -1 || rect.height <= height) &&
|
||||
!pango_layout_is_wrapped (priv->layout) &&
|
||||
!pango_layout_is_ellipsized (priv->layout))
|
||||
{
|
||||
@@ -3227,7 +3221,6 @@ gtk_label_get_measuring_layout (GtkLabel * label,
|
||||
|
||||
copy = pango_layout_copy (priv->layout);
|
||||
pango_layout_set_width (copy, width);
|
||||
pango_layout_set_height (copy, height);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -3258,7 +3251,6 @@ gtk_label_update_layout_width (GtkLabel *label)
|
||||
const gdouble dy = matrix->xy; /* sin (M_PI * angle / 180) */
|
||||
|
||||
pango_layout_set_width (priv->layout, -1);
|
||||
pango_layout_set_height (priv->layout, -1);
|
||||
pango_layout_get_pixel_extents (priv->layout, NULL, &logical);
|
||||
|
||||
if (fabs (dy) < 0.01)
|
||||
@@ -3312,13 +3304,11 @@ gtk_label_update_layout_width (GtkLabel *label)
|
||||
else
|
||||
{
|
||||
pango_layout_set_width (priv->layout, width * PANGO_SCALE);
|
||||
pango_layout_set_height (priv->layout, priv->ellipsize ? height * PANGO_SCALE : -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pango_layout_set_width (priv->layout, -1);
|
||||
pango_layout_set_height (priv->layout, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3449,23 +3439,6 @@ gtk_label_ensure_layout (GtkLabel *label)
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
get_single_line_height (GtkWidget *widget,
|
||||
PangoLayout *layout)
|
||||
{
|
||||
PangoContext *context;
|
||||
PangoFontMetrics *metrics;
|
||||
gint ascent, descent;
|
||||
|
||||
context = pango_layout_get_context (layout);
|
||||
metrics = get_font_metrics (context, widget);
|
||||
ascent = pango_font_metrics_get_ascent (metrics);
|
||||
descent = pango_font_metrics_get_descent (metrics);
|
||||
pango_font_metrics_unref (metrics);
|
||||
|
||||
return ascent + descent;
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_label_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
@@ -3487,11 +3460,10 @@ get_size_for_allocation (GtkLabel *label,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
PangoLayout *layout;
|
||||
gint text_height;
|
||||
|
||||
layout = gtk_label_get_measuring_layout (label, NULL, allocation * PANGO_SCALE, -1);
|
||||
layout = gtk_label_get_measuring_layout (label, NULL, allocation * PANGO_SCALE);
|
||||
|
||||
pango_layout_get_pixel_size (layout, NULL, &text_height);
|
||||
|
||||
@@ -3499,15 +3471,7 @@ get_size_for_allocation (GtkLabel *label,
|
||||
*minimum_size = text_height;
|
||||
|
||||
if (natural_size)
|
||||
{
|
||||
if (priv->ellipsize && priv->wrap)
|
||||
{
|
||||
layout = gtk_label_get_measuring_layout (label, layout, allocation * PANGO_SCALE, G_MAXINT);
|
||||
pango_layout_get_pixel_size (layout, NULL, &text_height);
|
||||
}
|
||||
|
||||
*natural_size = text_height;
|
||||
}
|
||||
*natural_size = text_height;
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
@@ -3531,11 +3495,12 @@ get_char_pixels (GtkWidget *label,
|
||||
|
||||
static void
|
||||
gtk_label_get_preferred_layout_size (GtkLabel *label,
|
||||
PangoRectangle *required,
|
||||
PangoRectangle *natural)
|
||||
PangoRectangle *smallest,
|
||||
PangoRectangle *widest)
|
||||
{
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
PangoLayout *layout;
|
||||
gint char_pixels;
|
||||
|
||||
/* "width-chars" Hard-coded minimum width:
|
||||
* - minimum size should be MAX (width-chars, strlen ("..."));
|
||||
@@ -3554,46 +3519,46 @@ gtk_label_get_preferred_layout_size (GtkLabel *label,
|
||||
*/
|
||||
|
||||
/* Start off with the pixel extents of an as-wide-as-possible layout */
|
||||
layout = gtk_label_get_measuring_layout (label, NULL, -1, -1);
|
||||
layout = gtk_label_get_measuring_layout (label, NULL, -1);
|
||||
|
||||
pango_layout_get_extents (layout, NULL, natural);
|
||||
natural->x = natural->y = 0;
|
||||
|
||||
if (priv->wrap)
|
||||
natural->height = get_single_line_height (GTK_WIDGET (label), layout);
|
||||
if (priv->width_chars > -1 || priv->max_width_chars > -1)
|
||||
char_pixels = get_char_pixels (GTK_WIDGET (label), layout);
|
||||
else
|
||||
char_pixels = 0;
|
||||
|
||||
pango_layout_get_extents (layout, NULL, widest);
|
||||
widest->width = MAX (widest->width, char_pixels * priv->width_chars);
|
||||
widest->x = widest->y = 0;
|
||||
|
||||
if (priv->ellipsize || priv->wrap)
|
||||
{
|
||||
/* a layout with width 0 will be as small as humanly possible */
|
||||
layout = gtk_label_get_measuring_layout (label, layout, 0, -1);
|
||||
layout = gtk_label_get_measuring_layout (label,
|
||||
layout,
|
||||
priv->width_chars > -1 ? char_pixels * priv->width_chars
|
||||
: 0);
|
||||
|
||||
pango_layout_get_extents (layout, NULL, required);
|
||||
pango_layout_get_extents (layout, NULL, smallest);
|
||||
smallest->width = MAX (smallest->width, char_pixels * priv->width_chars);
|
||||
smallest->x = smallest->y = 0;
|
||||
|
||||
/* can happen when Pango decides to ellipsize text */
|
||||
if (required->width > natural->width)
|
||||
required->width = natural->width;
|
||||
|
||||
required->x = required->y = 0;
|
||||
required->height = natural->height;
|
||||
if (priv->max_width_chars > -1 && widest->width > char_pixels * priv->max_width_chars)
|
||||
{
|
||||
layout = gtk_label_get_measuring_layout (label,
|
||||
layout,
|
||||
MAX (smallest->width, char_pixels * priv->max_width_chars));
|
||||
pango_layout_get_extents (layout, NULL, widest);
|
||||
widest->width = MAX (widest->width, char_pixels * priv->width_chars);
|
||||
widest->x = widest->y = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*required = *natural;
|
||||
*smallest = *widest;
|
||||
}
|
||||
|
||||
if (priv->width_chars > -1 || priv->max_width_chars > -1)
|
||||
{
|
||||
gint char_pixels;
|
||||
|
||||
char_pixels = get_char_pixels (GTK_WIDGET (label), layout);
|
||||
|
||||
if (priv->width_chars > -1)
|
||||
required->width = MAX (required->width, char_pixels * priv->width_chars);
|
||||
|
||||
if (priv->max_width_chars > -1)
|
||||
natural->width = MIN (natural->width, priv->max_width_chars * char_pixels);
|
||||
natural->width = MAX (natural->width, required->width);
|
||||
}
|
||||
if (widest->width < smallest->width)
|
||||
*smallest = *widest;
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
@@ -3606,36 +3571,28 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
PangoRectangle required_rect;
|
||||
PangoRectangle natural_rect;
|
||||
PangoRectangle widest_rect;
|
||||
PangoRectangle smallest_rect;
|
||||
GtkBorder border;
|
||||
|
||||
gtk_label_get_preferred_layout_size (label, &required_rect, &natural_rect);
|
||||
gtk_label_get_preferred_layout_size (label, &smallest_rect, &widest_rect);
|
||||
|
||||
/* Now that we have minimum and natural sizes in pango extents, apply a possible transform */
|
||||
if (priv->have_transform)
|
||||
{
|
||||
PangoLayout *copy;
|
||||
PangoContext *context;
|
||||
const PangoMatrix *matrix;
|
||||
|
||||
copy = pango_layout_copy (priv->layout);
|
||||
context = pango_layout_get_context (copy);
|
||||
context = pango_layout_get_context (priv->layout);
|
||||
matrix = pango_context_get_matrix (context);
|
||||
|
||||
pango_layout_set_width (copy, -1);
|
||||
pango_layout_set_ellipsize (copy, PANGO_ELLIPSIZE_NONE);
|
||||
pango_matrix_transform_rectangle (matrix, &widest_rect);
|
||||
pango_matrix_transform_rectangle (matrix, &smallest_rect);
|
||||
|
||||
pango_layout_get_extents (copy, NULL, &natural_rect);
|
||||
g_object_unref (copy);
|
||||
|
||||
pango_matrix_transform_rectangle (matrix, &required_rect);
|
||||
pango_matrix_transform_rectangle (matrix, &natural_rect);
|
||||
|
||||
/* Bump the natural size in case of ellipsize to ensure pango has
|
||||
/* Bump the size in case of ellipsize to ensure pango has
|
||||
* enough space in the angles (note, we could alternatively set the
|
||||
* layout to not ellipsize when we know we have been allocated our
|
||||
* full natural size, or it may be that pango needs a fix here).
|
||||
* full size, or it may be that pango needs a fix here).
|
||||
*/
|
||||
if (priv->ellipsize && priv->angle != 0 && priv->angle != 90 &&
|
||||
priv->angle != 180 && priv->angle != 270 && priv->angle != 360)
|
||||
@@ -3643,16 +3600,18 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
/* For some reason we only need this at about 110 degrees, and only
|
||||
* when gaining in height
|
||||
*/
|
||||
natural_rect.height += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
natural_rect.width += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
widest_rect.height += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
widest_rect.width += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
smallest_rect.height += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
smallest_rect.width += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
required_rect.width = PANGO_PIXELS_CEIL (required_rect.width);
|
||||
required_rect.height = PANGO_PIXELS_CEIL (required_rect.height);
|
||||
widest_rect.width = PANGO_PIXELS_CEIL (widest_rect.width);
|
||||
widest_rect.height = PANGO_PIXELS_CEIL (widest_rect.height);
|
||||
|
||||
natural_rect.width = PANGO_PIXELS_CEIL (natural_rect.width);
|
||||
natural_rect.height = PANGO_PIXELS_CEIL (natural_rect.height);
|
||||
smallest_rect.width = PANGO_PIXELS_CEIL (smallest_rect.width);
|
||||
smallest_rect.height = PANGO_PIXELS_CEIL (smallest_rect.height);
|
||||
|
||||
_gtk_misc_get_padding_and_border (GTK_MISC (label), &border);
|
||||
|
||||
@@ -3669,15 +3628,15 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
*/
|
||||
get_size_for_allocation (label,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
required_rect.height,
|
||||
smallest_rect.height,
|
||||
minimum_size, natural_size);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normal desired width */
|
||||
*minimum_size = required_rect.width;
|
||||
*natural_size = natural_rect.width;
|
||||
*minimum_size = smallest_rect.width;
|
||||
*natural_size = widest_rect.width;
|
||||
}
|
||||
|
||||
*minimum_size += border.left + border.right;
|
||||
@@ -3696,7 +3655,7 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
*/
|
||||
get_size_for_allocation (label,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
required_rect.width,
|
||||
widest_rect.width,
|
||||
minimum_size, natural_size);
|
||||
}
|
||||
else
|
||||
@@ -3704,8 +3663,8 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
/* A vertically rotated label does w4h, so return the base
|
||||
* desired height (text length)
|
||||
*/
|
||||
*minimum_size = required_rect.height;
|
||||
*natural_size = natural_rect.height;
|
||||
*minimum_size = MIN (smallest_rect.height, widest_rect.height);
|
||||
*natural_size = MAX (smallest_rect.height, widest_rect.height);
|
||||
}
|
||||
|
||||
*minimum_size += border.top + border.bottom;
|
||||
|
||||
+127
-8
@@ -120,6 +120,7 @@ enum {
|
||||
PROP_MIN_VALUE,
|
||||
PROP_MAX_VALUE,
|
||||
PROP_MODE,
|
||||
PROP_INVERTED,
|
||||
LAST_PROPERTY,
|
||||
PROP_ORIENTATION /* overridden */
|
||||
};
|
||||
@@ -147,6 +148,8 @@ struct _GtkLevelBarPrivate {
|
||||
GList *offsets;
|
||||
|
||||
GtkLevelBarMode bar_mode;
|
||||
|
||||
guint inverted : 1;
|
||||
};
|
||||
|
||||
static void gtk_level_bar_set_value_internal (GtkLevelBar *self,
|
||||
@@ -303,6 +306,7 @@ gtk_level_bar_get_borders (GtkLevelBar *self,
|
||||
static void
|
||||
gtk_level_bar_draw_fill_continuous (GtkLevelBar *self,
|
||||
cairo_t *cr,
|
||||
gboolean inverted,
|
||||
cairo_rectangle_int_t *fill_area)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
@@ -339,9 +343,19 @@ gtk_level_bar_draw_fill_continuous (GtkLevelBar *self,
|
||||
(self->priv->max_value - self->priv->min_value);
|
||||
|
||||
if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
block_area.width = (gint) floor (block_area.width * fill_percentage);
|
||||
{
|
||||
block_area.width = (gint) floor (block_area.width * fill_percentage);
|
||||
|
||||
if (inverted)
|
||||
block_area.x += base_area.width - block_area.width;
|
||||
}
|
||||
else
|
||||
block_area.height = (gint) floor (block_area.height * fill_percentage);
|
||||
{
|
||||
block_area.height = (gint) floor (block_area.height * fill_percentage);
|
||||
|
||||
if (inverted)
|
||||
block_area.y += base_area.height - block_area.height;
|
||||
}
|
||||
|
||||
gtk_render_background (context, cr, block_area.x, block_area.y,
|
||||
block_area.width, block_area.height);
|
||||
@@ -354,6 +368,7 @@ gtk_level_bar_draw_fill_continuous (GtkLevelBar *self,
|
||||
static void
|
||||
gtk_level_bar_draw_fill_discrete (GtkLevelBar *self,
|
||||
cairo_t *cr,
|
||||
gboolean inverted,
|
||||
cairo_rectangle_int_t *fill_area)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
@@ -387,19 +402,35 @@ gtk_level_bar_draw_fill_discrete (GtkLevelBar *self,
|
||||
{
|
||||
block_draw_height = MAX (block_draw_height, block_area.height - block_margin.top - block_margin.bottom);
|
||||
block_area.y += block_margin.top;
|
||||
|
||||
if (inverted)
|
||||
block_area.x += block_area.width - block_draw_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
block_draw_width = MAX (block_draw_width, block_area.width - block_margin.left - block_margin.right);
|
||||
block_area.x += block_margin.left;
|
||||
|
||||
if (inverted)
|
||||
block_area.y += block_area.height - block_draw_height;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < num_blocks; idx++)
|
||||
{
|
||||
if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
block_area.x += block_margin.left;
|
||||
{
|
||||
if (inverted)
|
||||
block_area.x -= block_margin.right;
|
||||
else
|
||||
block_area.x += block_margin.left;
|
||||
}
|
||||
else
|
||||
block_area.y += block_margin.top;
|
||||
{
|
||||
if (inverted)
|
||||
block_area.y -= block_margin.bottom;
|
||||
else
|
||||
block_area.y += block_margin.top;
|
||||
}
|
||||
|
||||
if (idx > num_filled - 1)
|
||||
gtk_style_context_add_class (context, STYLE_CLASS_EMPTY_FILL_BLOCK);
|
||||
@@ -412,9 +443,19 @@ gtk_level_bar_draw_fill_discrete (GtkLevelBar *self,
|
||||
block_draw_width, block_draw_height);
|
||||
|
||||
if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
block_area.x += block_draw_width + block_margin.right;
|
||||
{
|
||||
if (inverted)
|
||||
block_area.x -= block_draw_width + block_margin.left;
|
||||
else
|
||||
block_area.x += block_draw_width + block_margin.right;
|
||||
}
|
||||
else
|
||||
block_area.y += block_draw_height + block_margin.bottom;
|
||||
{
|
||||
if (inverted)
|
||||
block_area.y -= block_draw_height + block_margin.top;
|
||||
else
|
||||
block_area.y += block_draw_height + block_margin.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
@@ -426,6 +467,7 @@ gtk_level_bar_draw_fill (GtkLevelBar *self,
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GtkBorder trough_borders;
|
||||
gboolean inverted;
|
||||
cairo_rectangle_int_t fill_area;
|
||||
|
||||
gtk_level_bar_get_borders (self, &trough_borders);
|
||||
@@ -437,10 +479,17 @@ gtk_level_bar_draw_fill (GtkLevelBar *self,
|
||||
fill_area.height = gtk_widget_get_allocated_height (widget) -
|
||||
trough_borders.top - trough_borders.bottom;
|
||||
|
||||
inverted = self->priv->inverted;
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
|
||||
{
|
||||
if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
inverted = !inverted;
|
||||
}
|
||||
|
||||
if (self->priv->bar_mode == GTK_LEVEL_BAR_MODE_CONTINUOUS)
|
||||
gtk_level_bar_draw_fill_continuous (self, cr, &fill_area);
|
||||
gtk_level_bar_draw_fill_continuous (self, cr, inverted, &fill_area);
|
||||
else if (self->priv->bar_mode == GTK_LEVEL_BAR_MODE_DISCRETE)
|
||||
gtk_level_bar_draw_fill_discrete (self, cr, &fill_area);
|
||||
gtk_level_bar_draw_fill_discrete (self, cr, inverted, &fill_area);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -769,6 +818,9 @@ gtk_level_bar_get_property (GObject *obj,
|
||||
case PROP_MODE:
|
||||
g_value_set_enum (value, gtk_level_bar_get_mode (self));
|
||||
break;
|
||||
case PROP_INVERTED:
|
||||
g_value_set_boolean (value, gtk_level_bar_get_inverted (self));
|
||||
break;
|
||||
case PROP_ORIENTATION:
|
||||
g_value_set_enum (value, self->priv->orientation);
|
||||
break;
|
||||
@@ -800,6 +852,9 @@ gtk_level_bar_set_property (GObject *obj,
|
||||
case PROP_MODE:
|
||||
gtk_level_bar_set_mode (self, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_INVERTED:
|
||||
gtk_level_bar_set_inverted (self, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_ORIENTATION:
|
||||
gtk_level_bar_set_orientation (self, g_value_get_enum (value));
|
||||
break;
|
||||
@@ -923,6 +978,21 @@ gtk_level_bar_class_init (GtkLevelBarClass *klass)
|
||||
GTK_LEVEL_BAR_MODE_CONTINUOUS,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* GtkLevelBar:inverted:
|
||||
*
|
||||
* Level bars normally grow from top to bottom or left to right.
|
||||
* Inverted level bars grow in the opposite direction.
|
||||
*
|
||||
* Since: 3.8
|
||||
*/
|
||||
properties[PROP_INVERTED] =
|
||||
g_param_spec_boolean ("inverted",
|
||||
P_("Inverted"),
|
||||
P_("Invert the direction in which the level bar grows"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* GtkLevelBar:min-block-height:
|
||||
*
|
||||
@@ -981,6 +1051,8 @@ gtk_level_bar_init (GtkLevelBar *self)
|
||||
self->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (self));
|
||||
|
||||
self->priv->inverted = FALSE;
|
||||
|
||||
gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
|
||||
}
|
||||
|
||||
@@ -1208,6 +1280,53 @@ gtk_level_bar_set_mode (GtkLevelBar *self,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_level_bar_get_inverted:
|
||||
* @self: a #GtkLevelBar
|
||||
*
|
||||
* Return the value of the #GtkLevelBar:inverted property.
|
||||
*
|
||||
* Return value: %TRUE if the level bar is inverted
|
||||
*
|
||||
* Since: 3.8
|
||||
*/
|
||||
gboolean
|
||||
gtk_level_bar_get_inverted (GtkLevelBar *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LEVEL_BAR (self), FALSE);
|
||||
|
||||
return self->priv->inverted;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_level_bar_set_inverted:
|
||||
* @self: a #GtkLevelBar
|
||||
* @inverted: %TRUE to invert the level bar
|
||||
*
|
||||
* Sets the value of the #GtkLevelBar:inverted property.
|
||||
*
|
||||
* Since: 3.8
|
||||
*/
|
||||
void
|
||||
gtk_level_bar_set_inverted (GtkLevelBar *self,
|
||||
gboolean inverted)
|
||||
{
|
||||
GtkLevelBarPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_LEVEL_BAR (self));
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
if (priv->inverted != inverted)
|
||||
{
|
||||
priv->inverted = inverted;
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify (G_OBJECT (self), "inverted");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_level_bar_remove_offset_value:
|
||||
* @self: a #GtkLevelBar
|
||||
|
||||
@@ -110,6 +110,13 @@ void gtk_level_bar_set_max_value (GtkLevelBar *self,
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
gdouble gtk_level_bar_get_max_value (GtkLevelBar *self);
|
||||
|
||||
GDK_AVAILABLE_IN_3_8
|
||||
void gtk_level_bar_set_inverted (GtkLevelBar *self,
|
||||
gboolean inverted);
|
||||
|
||||
GDK_AVAILABLE_IN_3_8
|
||||
gboolean gtk_level_bar_get_inverted (GtkLevelBar *self);
|
||||
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
void gtk_level_bar_add_offset_value (GtkLevelBar *self,
|
||||
const gchar *name,
|
||||
|
||||
+9
-4
@@ -710,9 +710,6 @@ do_post_parse_initialization (int *argc,
|
||||
|
||||
_gtk_register_resource ();
|
||||
|
||||
/* do what the call to gtk_type_init() used to do */
|
||||
g_type_init ();
|
||||
|
||||
_gtk_accel_map_init ();
|
||||
|
||||
/* Set the 'initialized' flag.
|
||||
@@ -2438,7 +2435,15 @@ propagate_event_down (GtkWidget *widget,
|
||||
widget = (GtkWidget *)l->data;
|
||||
|
||||
if (!gtk_widget_is_sensitive (widget))
|
||||
handled_event = TRUE;
|
||||
{
|
||||
/* stop propagating on SCROLL, but don't handle the event, so it
|
||||
* can propagate up again and reach its handling widget
|
||||
*/
|
||||
if (event->type == GDK_SCROLL)
|
||||
break;
|
||||
else
|
||||
handled_event = TRUE;
|
||||
}
|
||||
else
|
||||
handled_event = _gtk_widget_captured_event (widget, event);
|
||||
}
|
||||
|
||||
+23
-21
@@ -516,22 +516,7 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
|
||||
P_("The dropdown menu."),
|
||||
GTK_TYPE_MENU,
|
||||
G_PARAM_READWRITE));
|
||||
/**
|
||||
* GtkMenuButton:menu:
|
||||
*
|
||||
* The #GtkMenu that will be popped up when the button is clicked.
|
||||
* This property has been renamed to "popup". "menu" will be
|
||||
* removed before 3.6.0.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_POPUP, /* [sic] */
|
||||
g_param_spec_object ("menu",
|
||||
P_("menu"),
|
||||
P_("The dropdown menu."),
|
||||
GTK_TYPE_MENU,
|
||||
G_PARAM_DEPRECATED | G_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkMenuButton:menu-model:
|
||||
*
|
||||
@@ -699,7 +684,7 @@ _gtk_menu_button_set_popup_with_func (GtkMenuButton *menu_button
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (menu_button), FALSE);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (menu_button), "menu");
|
||||
g_object_notify (G_OBJECT (menu_button), "popup");
|
||||
g_object_notify (G_OBJECT (menu_button), "menu-model");
|
||||
}
|
||||
|
||||
@@ -806,6 +791,23 @@ gtk_menu_button_get_menu_model (GtkMenuButton *menu_button)
|
||||
return menu_button->priv->model;
|
||||
}
|
||||
|
||||
static void
|
||||
set_align_widget_pointer (GtkMenuButton *menu_button,
|
||||
GtkWidget *align_widget)
|
||||
{
|
||||
GtkMenuButtonPrivate *priv;
|
||||
|
||||
priv = menu_button->priv;
|
||||
|
||||
if (priv->align_widget)
|
||||
g_object_remove_weak_pointer (G_OBJECT (priv->align_widget), (gpointer *) &priv->align_widget);
|
||||
|
||||
priv->align_widget = align_widget;
|
||||
|
||||
if (align_widget)
|
||||
g_object_add_weak_pointer (G_OBJECT (priv->align_widget), (gpointer *) &priv->align_widget);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_menu_button_set_align_widget:
|
||||
* @menu_button: a #GtkMenuButton
|
||||
@@ -832,10 +834,7 @@ gtk_menu_button_set_align_widget (GtkMenuButton *menu_button,
|
||||
if (priv->align_widget == align_widget)
|
||||
return;
|
||||
|
||||
priv->align_widget = align_widget;
|
||||
|
||||
if (priv->align_widget)
|
||||
g_object_add_weak_pointer (G_OBJECT (priv->align_widget), (gpointer *) &priv->align_widget);
|
||||
set_align_widget_pointer (menu_button, align_widget);
|
||||
|
||||
g_object_notify (G_OBJECT (menu_button), "align-widget");
|
||||
}
|
||||
@@ -926,8 +925,11 @@ gtk_menu_button_dispose (GObject *object)
|
||||
menu_deactivate_cb,
|
||||
object);
|
||||
gtk_menu_detach (GTK_MENU (priv->popup));
|
||||
priv->popup = NULL;
|
||||
}
|
||||
|
||||
set_align_widget_pointer (GTK_MENU_BUTTON (object), NULL);
|
||||
|
||||
g_clear_object (&priv->model);
|
||||
|
||||
G_OBJECT_CLASS (gtk_menu_button_parent_class)->dispose (object);
|
||||
|
||||
+2
-5
@@ -1719,11 +1719,8 @@ gtk_menu_item_draw (GtkWidget *widget,
|
||||
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
if (child && (state & GTK_STATE_FLAG_PRELIGHT))
|
||||
{
|
||||
gtk_render_background (context, cr, x, y, w, h);
|
||||
gtk_render_frame (context, cr, x, y, w, h);
|
||||
}
|
||||
gtk_render_background (context, cr, x, y, w, h);
|
||||
gtk_render_frame (context, cr, x, y, w, h);
|
||||
|
||||
if (priv->submenu && !GTK_IS_MENU_BAR (parent))
|
||||
{
|
||||
|
||||
+44
-28
@@ -150,6 +150,7 @@ struct _GtkNotebookPrivate
|
||||
|
||||
guint dnd_timer;
|
||||
guint switch_tab_timer;
|
||||
GList *switch_tab;
|
||||
|
||||
guint32 timer;
|
||||
guint32 timestamp;
|
||||
@@ -1674,6 +1675,18 @@ gtk_notebook_get_property (GObject *object,
|
||||
* gtk_notebook_drag_data_get
|
||||
* gtk_notebook_drag_data_received
|
||||
*/
|
||||
static void
|
||||
remove_switch_tab_timer (GtkNotebook *notebook)
|
||||
{
|
||||
GtkNotebookPrivate *priv = notebook->priv;
|
||||
|
||||
if (priv->switch_tab_timer)
|
||||
{
|
||||
g_source_remove (priv->switch_tab_timer);
|
||||
priv->switch_tab_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_notebook_destroy (GtkWidget *widget)
|
||||
{
|
||||
@@ -1701,11 +1714,7 @@ gtk_notebook_destroy (GtkWidget *widget)
|
||||
priv->source_targets = NULL;
|
||||
}
|
||||
|
||||
if (priv->switch_tab_timer)
|
||||
{
|
||||
g_source_remove (priv->switch_tab_timer);
|
||||
priv->switch_tab_timer = 0;
|
||||
}
|
||||
remove_switch_tab_timer (notebook);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_notebook_parent_class)->destroy (widget);
|
||||
}
|
||||
@@ -3688,20 +3697,20 @@ gtk_notebook_switch_tab_timeout (gpointer data)
|
||||
{
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (data);
|
||||
GtkNotebookPrivate *priv = notebook->priv;
|
||||
GList *tab;
|
||||
gint x, y;
|
||||
GList *switch_tab;
|
||||
|
||||
priv->switch_tab_timer = 0;
|
||||
x = priv->mouse_x;
|
||||
y = priv->mouse_y;
|
||||
|
||||
if ((tab = get_tab_at_pos (notebook, x, y)) != NULL)
|
||||
switch_tab = priv->switch_tab;
|
||||
priv->switch_tab = NULL;
|
||||
|
||||
if (switch_tab)
|
||||
{
|
||||
/* FIXME: hack, we don't want the
|
||||
* focus to move fom the source widget
|
||||
*/
|
||||
priv->child_has_focus = FALSE;
|
||||
gtk_notebook_switch_focus_tab (notebook, tab);
|
||||
gtk_notebook_switch_focus_tab (notebook, switch_tab);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -3722,6 +3731,8 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
GtkNotebookArrow arrow;
|
||||
guint timeout;
|
||||
GdkAtom target, tab_target;
|
||||
GList *tab;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
@@ -3733,7 +3744,9 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
priv->click_child = arrow;
|
||||
gtk_notebook_set_scroll_timer (notebook);
|
||||
gdk_drag_status (context, 0, time);
|
||||
return TRUE;
|
||||
|
||||
retval = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
stop_scrolling (notebook);
|
||||
@@ -3746,6 +3759,8 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
GtkNotebook *source;
|
||||
GtkWidget *source_child;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
source = GTK_NOTEBOOK (gtk_drag_get_source_widget (context));
|
||||
source_child = source->priv->cur_page->child;
|
||||
|
||||
@@ -3757,7 +3772,7 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
gtk_widget_is_ancestor (widget, source_child)))
|
||||
{
|
||||
gdk_drag_status (context, GDK_ACTION_MOVE, time);
|
||||
return TRUE;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3772,11 +3787,19 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
|
||||
if (gtk_notebook_get_event_window_position (notebook, &position) &&
|
||||
x >= position.x && x <= position.x + position.width &&
|
||||
y >= position.y && y <= position.y + position.height)
|
||||
y >= position.y && y <= position.y + position.height &&
|
||||
(tab = get_tab_at_pos (notebook, x, y)))
|
||||
{
|
||||
priv->mouse_x = x;
|
||||
priv->mouse_y = y;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
if (tab != priv->switch_tab)
|
||||
remove_switch_tab_timer (notebook);
|
||||
|
||||
priv->switch_tab = tab;
|
||||
|
||||
if (!priv->switch_tab_timer)
|
||||
{
|
||||
settings = gtk_widget_get_settings (widget);
|
||||
@@ -3789,14 +3812,11 @@ gtk_notebook_drag_motion (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->switch_tab_timer)
|
||||
{
|
||||
g_source_remove (priv->switch_tab_timer);
|
||||
priv->switch_tab_timer = 0;
|
||||
}
|
||||
remove_switch_tab_timer (notebook);
|
||||
}
|
||||
|
||||
return (target == tab_target) ? TRUE : FALSE;
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3805,15 +3825,9 @@ gtk_notebook_drag_leave (GtkWidget *widget,
|
||||
guint time)
|
||||
{
|
||||
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
|
||||
GtkNotebookPrivate *priv = notebook->priv;
|
||||
|
||||
if (priv->switch_tab_timer)
|
||||
{
|
||||
g_source_remove (priv->switch_tab_timer);
|
||||
priv->switch_tab_timer = 0;
|
||||
}
|
||||
|
||||
stop_scrolling (GTK_NOTEBOOK (widget));
|
||||
remove_switch_tab_timer (notebook);
|
||||
stop_scrolling (notebook);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -4978,6 +4992,8 @@ gtk_notebook_real_remove (GtkNotebook *notebook,
|
||||
|
||||
if (priv->detached_tab == list->data)
|
||||
priv->detached_tab = NULL;
|
||||
if (priv->switch_tab == list)
|
||||
priv->switch_tab = NULL;
|
||||
|
||||
if (list == priv->first_tab)
|
||||
priv->first_tab = next_list;
|
||||
|
||||
+17
-12
@@ -221,6 +221,21 @@ gtk_scale_notify (GObject *object,
|
||||
G_OBJECT_CLASS (gtk_scale_parent_class)->notify (object, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scale_update_style (GtkScale *scale)
|
||||
{
|
||||
gint slider_length;
|
||||
GtkRange *range;
|
||||
|
||||
range = GTK_RANGE (scale);
|
||||
|
||||
gtk_widget_style_get (GTK_WIDGET (scale),
|
||||
"slider-length", &slider_length,
|
||||
NULL);
|
||||
|
||||
gtk_range_set_min_slider_size (range, slider_length);
|
||||
_gtk_scale_clear_layout (scale);
|
||||
}
|
||||
|
||||
#define add_slider_binding(binding_set, keyval, mask, scroll) \
|
||||
gtk_binding_entry_add_signal (binding_set, keyval, mask, \
|
||||
@@ -492,6 +507,7 @@ gtk_scale_init (GtkScale *scale)
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (scale));
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SCALE);
|
||||
gtk_scale_update_style (scale);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1020,18 +1036,7 @@ gtk_scale_get_mark_label_size (GtkScale *scale,
|
||||
static void
|
||||
gtk_scale_style_updated (GtkWidget *widget)
|
||||
{
|
||||
gint slider_length;
|
||||
GtkRange *range;
|
||||
|
||||
range = GTK_RANGE (widget);
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"slider-length", &slider_length,
|
||||
NULL);
|
||||
|
||||
gtk_range_set_min_slider_size (range, slider_length);
|
||||
|
||||
_gtk_scale_clear_layout (GTK_SCALE (widget));
|
||||
gtk_scale_update_style (GTK_SCALE (widget));
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_scale_parent_class)->style_updated (widget);
|
||||
}
|
||||
|
||||
+18
-11
@@ -115,21 +115,13 @@ gtk_scrollbar_class_init (GtkScrollbarClass *class)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrollbar_init (GtkScrollbar *scrollbar)
|
||||
gtk_scrollbar_update_style (GtkScrollbar *scrollbar)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (scrollbar));
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SCROLLBAR);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrollbar_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GtkRange *range = GTK_RANGE (widget);
|
||||
gint slider_length;
|
||||
gboolean fixed_size;
|
||||
gboolean has_a, has_b, has_c, has_d;
|
||||
GtkRange *range = GTK_RANGE (scrollbar);
|
||||
GtkWidget *widget = GTK_WIDGET (scrollbar);
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"min-slider-length", &slider_length,
|
||||
@@ -144,7 +136,22 @@ gtk_scrollbar_style_updated (GtkWidget *widget)
|
||||
gtk_range_set_slider_size_fixed (range, fixed_size);
|
||||
_gtk_range_set_steppers (range,
|
||||
has_a, has_b, has_c, has_d);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrollbar_init (GtkScrollbar *scrollbar)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (scrollbar));
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SCROLLBAR);
|
||||
gtk_scrollbar_update_style (scrollbar);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrollbar_style_updated (GtkWidget *widget)
|
||||
{
|
||||
gtk_scrollbar_update_style (GTK_SCROLLBAR (widget));
|
||||
GTK_WIDGET_CLASS (gtk_scrollbar_parent_class)->style_updated (widget);
|
||||
}
|
||||
|
||||
|
||||
+1
-38
@@ -274,9 +274,6 @@ static void gtk_scrolled_window_realize (GtkWidget *wid
|
||||
static void gtk_scrolled_window_unrealize (GtkWidget *widget);
|
||||
static void gtk_scrolled_window_map (GtkWidget *widget);
|
||||
static void gtk_scrolled_window_unmap (GtkWidget *widget);
|
||||
static void gtk_scrolled_window_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state);
|
||||
static void gtk_scrolled_window_style_updated (GtkWidget *widget);
|
||||
|
||||
static void gtk_scrolled_window_grab_notify (GtkWidget *widget,
|
||||
gboolean was_grabbed);
|
||||
@@ -352,8 +349,6 @@ gtk_scrolled_window_class_init (GtkScrolledWindowClass *class)
|
||||
widget_class->unrealize = gtk_scrolled_window_unrealize;
|
||||
widget_class->map = gtk_scrolled_window_map;
|
||||
widget_class->unmap = gtk_scrolled_window_unmap;
|
||||
widget_class->state_flags_changed = gtk_scrolled_window_state_flags_changed;
|
||||
widget_class->style_updated = gtk_scrolled_window_style_updated;
|
||||
widget_class->grab_notify = gtk_scrolled_window_grab_notify;
|
||||
|
||||
container_class->add = gtk_scrolled_window_add;
|
||||
@@ -3379,14 +3374,13 @@ gtk_scrolled_window_realize (GtkWidget *widget)
|
||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
||||
attributes.visual = gtk_widget_get_visual (widget);
|
||||
attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK |
|
||||
GDK_BUTTON_MOTION_MASK | GDK_TOUCH_MASK;
|
||||
GDK_BUTTON_MOTION_MASK | GDK_TOUCH_MASK | GDK_EXPOSURE_MASK;
|
||||
|
||||
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
|
||||
|
||||
scrolled_window->priv->overshoot_window =
|
||||
gdk_window_new (gtk_widget_get_parent_window (widget),
|
||||
&attributes, attributes_mask);
|
||||
|
||||
gdk_window_set_user_data (scrolled_window->priv->overshoot_window, widget);
|
||||
|
||||
child_widget = gtk_bin_get_child (GTK_BIN (widget));
|
||||
@@ -3432,37 +3426,6 @@ gtk_scrolled_window_unmap (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_scrolled_window_update_background (GtkScrolledWindow *scrolled_window)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (scrolled_window);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_set_background (context, scrolled_window->priv->overshoot_window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrolled_window_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state)
|
||||
{
|
||||
_gtk_scrolled_window_update_background (GTK_SCROLLED_WINDOW (widget));
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrolled_window_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->style_updated (widget);
|
||||
|
||||
_gtk_scrolled_window_update_background (GTK_SCROLLED_WINDOW (widget));
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scrolled_window_grab_notify (GtkWidget *widget,
|
||||
gboolean was_grabbed)
|
||||
|
||||
+16
-13
@@ -293,6 +293,8 @@ gtk_settings_init (GtkSettings *settings)
|
||||
g_datalist_init (&priv->queued_settings);
|
||||
object_list = g_slist_prepend (object_list, settings);
|
||||
|
||||
priv->theme_provider = gtk_css_provider_new ();
|
||||
|
||||
/* build up property array for all yet existing properties and queue
|
||||
* notification for them (at least notification for internal properties
|
||||
* will instantly be caught)
|
||||
@@ -1612,6 +1614,10 @@ settings_init_style (GtkSettings *settings)
|
||||
GTK_STYLE_PROVIDER (settings),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
|
||||
|
||||
gtk_style_context_add_provider_for_screen (screen,
|
||||
GTK_STYLE_PROVIDER (settings->priv->theme_provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
|
||||
|
||||
settings_update_theme (settings);
|
||||
settings_update_key_theme (settings);
|
||||
}
|
||||
@@ -1848,6 +1854,9 @@ gtk_settings_notify (GObject *object,
|
||||
if (settings_update_fontconfig (settings))
|
||||
gtk_style_context_reset_widgets (priv->screen);
|
||||
break;
|
||||
case PROP_ENABLE_ANIMATIONS:
|
||||
gtk_style_context_reset_widgets (priv->screen);
|
||||
break;
|
||||
case PROP_CURSOR_THEME_NAME:
|
||||
case PROP_CURSOR_THEME_SIZE:
|
||||
settings_update_cursor_theme (settings);
|
||||
@@ -2915,7 +2924,6 @@ static void
|
||||
settings_update_theme (GtkSettings *settings)
|
||||
{
|
||||
GtkSettingsPrivate *priv = settings->priv;
|
||||
GtkCssProvider *provider = NULL;
|
||||
gboolean prefer_dark_theme;
|
||||
gchar *theme_name;
|
||||
|
||||
@@ -2924,20 +2932,15 @@ settings_update_theme (GtkSettings *settings)
|
||||
"gtk-application-prefer-dark-theme", &prefer_dark_theme,
|
||||
NULL);
|
||||
|
||||
if (theme_name && *theme_name)
|
||||
if (!theme_name || !*theme_name)
|
||||
{
|
||||
if (prefer_dark_theme)
|
||||
provider = gtk_css_provider_get_named (theme_name, "dark");
|
||||
|
||||
if (!provider)
|
||||
provider = gtk_css_provider_get_named (theme_name, NULL);
|
||||
g_free (theme_name);
|
||||
theme_name = g_strdup ("Raleigh");
|
||||
}
|
||||
|
||||
/* If we didn't find the named theme, fall back */
|
||||
if (!provider)
|
||||
provider = gtk_css_provider_get_named ("Raleigh", NULL);
|
||||
|
||||
settings_update_provider (priv->screen, &priv->theme_provider, provider);
|
||||
|
||||
_gtk_css_provider_load_named (priv->theme_provider,
|
||||
theme_name,
|
||||
prefer_dark_theme ? "dark" : NULL);
|
||||
|
||||
if (theme_name && *theme_name)
|
||||
{
|
||||
|
||||
@@ -37,11 +37,9 @@ typedef enum
|
||||
GTK_QUEUE_RESIZE_INVALIDATE_ONLY = 1 << 0
|
||||
} GtkQueueResizeFlags;
|
||||
|
||||
void _gtk_size_group_bump_requisition (GtkWidget *widget,
|
||||
GtkSizeGroupMode mode,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
void _gtk_size_group_queue_resize (GtkWidget *widget,
|
||||
GtkQueueResizeFlags flags);
|
||||
GHashTable * _gtk_size_group_get_widget_peers (GtkWidget *for_widget,
|
||||
GtkOrientation orientation);
|
||||
void _gtk_size_group_queue_resize (GtkWidget *widget,
|
||||
GtkQueueResizeFlags flags);
|
||||
|
||||
#endif /* __GTK_SIZE_GROUP_PRIVATE_H__ */
|
||||
|
||||
+54
-257
@@ -25,6 +25,7 @@
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtksizegroup-private.h"
|
||||
#include "gtksizerequestcacheprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkcontainerprivate.h"
|
||||
|
||||
@@ -110,17 +111,11 @@
|
||||
|
||||
struct _GtkSizeGroupPrivate
|
||||
{
|
||||
GtkRequisition minimum_req;
|
||||
GtkRequisition natural_req;
|
||||
|
||||
GSList *widgets;
|
||||
|
||||
guint8 mode;
|
||||
|
||||
guint have_width : 1;
|
||||
guint have_height : 1;
|
||||
guint ignore_hidden : 1;
|
||||
guint visited : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -138,15 +133,6 @@ static void gtk_size_group_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void add_group_to_closure (GtkSizeGroup *group,
|
||||
GtkSizeGroupMode mode,
|
||||
GSList **groups,
|
||||
GSList **widgets);
|
||||
static void add_widget_to_closure (GtkWidget *widget,
|
||||
GtkSizeGroupMode mode,
|
||||
GSList **groups,
|
||||
GSList **widgets);
|
||||
|
||||
/* GtkBuildable */
|
||||
static void gtk_size_group_buildable_init (GtkBuildableIface *iface);
|
||||
static gboolean gtk_size_group_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
@@ -161,67 +147,53 @@ static void gtk_size_group_buildable_custom_finished (GtkBuildable *buildable,
|
||||
const gchar *tagname,
|
||||
gpointer user_data);
|
||||
|
||||
static void
|
||||
mark_group_unvisited (GtkSizeGroup *group)
|
||||
{
|
||||
group->priv->visited = FALSE;
|
||||
}
|
||||
G_STATIC_ASSERT (GTK_SIZE_GROUP_HORIZONTAL == (1 << GTK_ORIENTATION_HORIZONTAL));
|
||||
G_STATIC_ASSERT (GTK_SIZE_GROUP_VERTICAL == (1 << GTK_ORIENTATION_VERTICAL));
|
||||
G_STATIC_ASSERT (GTK_SIZE_GROUP_BOTH == (GTK_SIZE_GROUP_HORIZONTAL | GTK_SIZE_GROUP_VERTICAL));
|
||||
|
||||
static void
|
||||
mark_widget_unvisited (GtkWidget *widget)
|
||||
add_widget_to_closure (GHashTable *set,
|
||||
GtkWidget *widget,
|
||||
GtkOrientation orientation)
|
||||
{
|
||||
_gtk_widget_set_sizegroup_visited (widget, FALSE);
|
||||
}
|
||||
GSList *tmp_groups, *tmp_widgets;
|
||||
gboolean hidden;
|
||||
|
||||
static void
|
||||
add_group_to_closure (GtkSizeGroup *group,
|
||||
GtkSizeGroupMode mode,
|
||||
GSList **groups,
|
||||
GSList **widgets)
|
||||
{
|
||||
GtkSizeGroupPrivate *priv = group->priv;
|
||||
GSList *tmp_widgets;
|
||||
|
||||
*groups = g_slist_prepend (*groups, group);
|
||||
priv->visited = TRUE;
|
||||
if (g_hash_table_lookup (set, widget))
|
||||
return;
|
||||
|
||||
tmp_widgets = priv->widgets;
|
||||
while (tmp_widgets)
|
||||
{
|
||||
GtkWidget *tmp_widget = tmp_widgets->data;
|
||||
|
||||
if (!_gtk_widget_get_sizegroup_visited (tmp_widget))
|
||||
add_widget_to_closure (tmp_widget, mode, groups, widgets);
|
||||
|
||||
tmp_widgets = tmp_widgets->next;
|
||||
}
|
||||
}
|
||||
g_hash_table_insert (set, widget, widget);
|
||||
hidden = !gtk_widget_is_visible (widget);
|
||||
|
||||
static void
|
||||
add_widget_to_closure (GtkWidget *widget,
|
||||
GtkSizeGroupMode mode,
|
||||
GSList **groups,
|
||||
GSList **widgets)
|
||||
{
|
||||
GSList *tmp_groups;
|
||||
|
||||
*widgets = g_slist_prepend (*widgets, widget);
|
||||
_gtk_widget_set_sizegroup_visited (widget, TRUE);
|
||||
|
||||
tmp_groups = _gtk_widget_get_sizegroups (widget);
|
||||
while (tmp_groups)
|
||||
for (tmp_groups = _gtk_widget_get_sizegroups (widget); tmp_groups; tmp_groups = tmp_groups->next)
|
||||
{
|
||||
GtkSizeGroup *tmp_group = tmp_groups->data;
|
||||
GtkSizeGroupPrivate *tmp_priv = tmp_group->priv;
|
||||
|
||||
if ((tmp_priv->mode == GTK_SIZE_GROUP_BOTH || tmp_priv->mode == mode) &&
|
||||
!tmp_group->priv->visited)
|
||||
add_group_to_closure (tmp_group, mode, groups, widgets);
|
||||
if (tmp_priv->ignore_hidden && hidden)
|
||||
continue;
|
||||
|
||||
tmp_groups = tmp_groups->next;
|
||||
if (!(tmp_priv->mode & (1 << orientation)))
|
||||
continue;
|
||||
|
||||
for (tmp_widgets = tmp_priv->widgets; tmp_widgets; tmp_widgets = tmp_widgets->next)
|
||||
add_widget_to_closure (set, tmp_widgets->data, orientation);
|
||||
}
|
||||
}
|
||||
|
||||
GHashTable *
|
||||
_gtk_size_group_get_widget_peers (GtkWidget *for_widget,
|
||||
GtkOrientation orientation)
|
||||
{
|
||||
GHashTable *result;
|
||||
|
||||
result = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
add_widget_to_closure (result, for_widget, orientation);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
real_queue_resize (GtkWidget *widget,
|
||||
GtkQueueResizeFlags flags)
|
||||
@@ -229,8 +201,7 @@ real_queue_resize (GtkWidget *widget,
|
||||
GtkWidget *container;
|
||||
|
||||
_gtk_widget_set_alloc_needed (widget, TRUE);
|
||||
_gtk_widget_set_width_request_needed (widget, TRUE);
|
||||
_gtk_widget_set_height_request_needed (widget, TRUE);
|
||||
_gtk_size_request_cache_clear (_gtk_widget_peek_request_cache (widget));
|
||||
|
||||
container = gtk_widget_get_parent (widget);
|
||||
if (!container &&
|
||||
@@ -246,35 +217,19 @@ real_queue_resize (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reset_group_sizes (GSList *groups)
|
||||
{
|
||||
GSList *tmp_list = groups;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkSizeGroup *tmp_group = tmp_list->data;
|
||||
GtkSizeGroupPrivate *tmp_priv = tmp_group->priv;
|
||||
|
||||
tmp_priv->have_width = FALSE;
|
||||
tmp_priv->have_height = FALSE;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
queue_resize_on_widget (GtkWidget *widget,
|
||||
gboolean check_siblings,
|
||||
GtkQueueResizeFlags flags)
|
||||
{
|
||||
GtkWidget *parent = widget;
|
||||
GSList *tmp_list;
|
||||
|
||||
while (parent)
|
||||
{
|
||||
GSList *widget_groups;
|
||||
GSList *groups;
|
||||
GSList *widgets;
|
||||
GHashTable *widgets;
|
||||
GHashTableIter iter;
|
||||
gpointer current;
|
||||
|
||||
if (widget == parent && !check_siblings)
|
||||
{
|
||||
@@ -293,65 +248,45 @@ queue_resize_on_widget (GtkWidget *widget,
|
||||
continue;
|
||||
}
|
||||
|
||||
groups = NULL;
|
||||
widgets = NULL;
|
||||
|
||||
add_widget_to_closure (parent, GTK_SIZE_GROUP_HORIZONTAL, &groups, &widgets);
|
||||
g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
|
||||
widgets = _gtk_size_group_get_widget_peers (parent, GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
reset_group_sizes (groups);
|
||||
|
||||
tmp_list = widgets;
|
||||
while (tmp_list)
|
||||
g_hash_table_iter_init (&iter, widgets);
|
||||
while (g_hash_table_iter_next (&iter, ¤t, NULL))
|
||||
{
|
||||
if (tmp_list->data == parent)
|
||||
if (current == parent)
|
||||
{
|
||||
if (widget == parent)
|
||||
real_queue_resize (parent, flags);
|
||||
}
|
||||
else if (tmp_list->data == widget)
|
||||
else if (current == widget)
|
||||
{
|
||||
g_warning ("A container and its child are part of this SizeGroup");
|
||||
}
|
||||
else
|
||||
queue_resize_on_widget (tmp_list->data, FALSE, flags);
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
queue_resize_on_widget (current, FALSE, flags);
|
||||
}
|
||||
|
||||
g_slist_free (widgets);
|
||||
g_slist_free (groups);
|
||||
|
||||
groups = NULL;
|
||||
widgets = NULL;
|
||||
|
||||
add_widget_to_closure (parent, GTK_SIZE_GROUP_VERTICAL, &groups, &widgets);
|
||||
g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
|
||||
g_hash_table_destroy (widgets);
|
||||
|
||||
widgets = _gtk_size_group_get_widget_peers (parent, GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
reset_group_sizes (groups);
|
||||
|
||||
tmp_list = widgets;
|
||||
while (tmp_list)
|
||||
g_hash_table_iter_init (&iter, widgets);
|
||||
while (g_hash_table_iter_next (&iter, ¤t, NULL))
|
||||
{
|
||||
if (tmp_list->data == parent)
|
||||
if (current == parent)
|
||||
{
|
||||
if (widget == parent)
|
||||
real_queue_resize (parent, flags);
|
||||
}
|
||||
else if (tmp_list->data == widget)
|
||||
else if (current == widget)
|
||||
{
|
||||
g_warning ("A container and its child are part of this SizeGroup");
|
||||
}
|
||||
else
|
||||
queue_resize_on_widget (tmp_list->data, FALSE, flags);
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
queue_resize_on_widget (current, FALSE, flags);
|
||||
}
|
||||
|
||||
g_slist_free (widgets);
|
||||
g_slist_free (groups);
|
||||
g_hash_table_destroy (widgets);
|
||||
|
||||
parent = gtk_widget_get_parent (parent);
|
||||
}
|
||||
@@ -415,10 +350,7 @@ gtk_size_group_init (GtkSizeGroup *size_group)
|
||||
|
||||
priv->widgets = NULL;
|
||||
priv->mode = GTK_SIZE_GROUP_HORIZONTAL;
|
||||
priv->have_width = 0;
|
||||
priv->have_height = 0;
|
||||
priv->ignore_hidden = 0;
|
||||
priv->visited = FALSE;
|
||||
priv->ignore_hidden = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -696,141 +628,6 @@ gtk_size_group_get_widgets (GtkSizeGroup *size_group)
|
||||
return size_group->priv->widgets;
|
||||
}
|
||||
|
||||
static void
|
||||
compute_dimension (GtkWidget *widget,
|
||||
GtkSizeGroupMode mode,
|
||||
gint *minimum, /* in-out */
|
||||
gint *natural) /* in-out */
|
||||
{
|
||||
GSList *widgets = NULL;
|
||||
GSList *groups = NULL;
|
||||
GSList *tmp_list;
|
||||
gint min_result = 0, nat_result = 0;
|
||||
|
||||
add_widget_to_closure (widget, mode, &groups, &widgets);
|
||||
g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
|
||||
g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
|
||||
|
||||
g_slist_foreach (widgets, (GFunc)g_object_ref, NULL);
|
||||
|
||||
if (!groups)
|
||||
{
|
||||
min_result = *minimum;
|
||||
nat_result = *natural;
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkSizeGroup *group = groups->data;
|
||||
GtkSizeGroupPrivate *priv = group->priv;
|
||||
|
||||
if (mode == GTK_SIZE_GROUP_HORIZONTAL && priv->have_width)
|
||||
{
|
||||
min_result = priv->minimum_req.width;
|
||||
nat_result = priv->natural_req.width;
|
||||
}
|
||||
else if (mode == GTK_SIZE_GROUP_VERTICAL && priv->have_height)
|
||||
{
|
||||
min_result = priv->minimum_req.height;
|
||||
nat_result = priv->natural_req.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_list = widgets;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkWidget *tmp_widget = tmp_list->data;
|
||||
gint min_dimension, nat_dimension;
|
||||
|
||||
if (tmp_widget == widget)
|
||||
{
|
||||
min_dimension = *minimum;
|
||||
nat_dimension = *natural;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
gtk_widget_get_preferred_width (tmp_widget, &min_dimension, &nat_dimension);
|
||||
else
|
||||
gtk_widget_get_preferred_height (tmp_widget, &min_dimension, &nat_dimension);
|
||||
}
|
||||
|
||||
if (gtk_widget_get_mapped (tmp_widget) || !priv->ignore_hidden)
|
||||
{
|
||||
min_result = MAX (min_result, min_dimension);
|
||||
nat_result = MAX (nat_result, nat_dimension);
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
tmp_list = groups;
|
||||
while (tmp_list)
|
||||
{
|
||||
GtkSizeGroup *tmp_group = tmp_list->data;
|
||||
GtkSizeGroupPrivate *tmp_priv = tmp_group->priv;
|
||||
|
||||
if (mode == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
tmp_priv->have_width = TRUE;
|
||||
tmp_priv->minimum_req.width = min_result;
|
||||
tmp_priv->natural_req.width = nat_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_priv->have_height = TRUE;
|
||||
tmp_priv->minimum_req.height = min_result;
|
||||
tmp_priv->natural_req.height = nat_result;
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_foreach (widgets, (GFunc)g_object_unref, NULL);
|
||||
|
||||
g_slist_free (widgets);
|
||||
g_slist_free (groups);
|
||||
|
||||
*minimum = min_result;
|
||||
*natural = nat_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_size_group_bump_requisition:
|
||||
* @widget: a #GtkWidget
|
||||
* @mode: either %GTK_SIZE_GROUP_HORIZONTAL or %GTK_SIZE_GROUP_VERTICAL, depending
|
||||
* on the dimension in which to bump the size.
|
||||
* @minimum: a pointer to the widget's minimum size
|
||||
* @natural: a pointer to the widget's natural size
|
||||
*
|
||||
* Refreshes the sizegroup while returning the groups requested
|
||||
* value in the dimension @mode.
|
||||
*
|
||||
* This function is used both to update sizegroup minimum and natural size
|
||||
* information and widget minimum and natural sizes in multiple passes from
|
||||
* the size request apis.
|
||||
*/
|
||||
void
|
||||
_gtk_size_group_bump_requisition (GtkWidget *widget,
|
||||
GtkSizeGroupMode mode,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
if (!_gtk_widget_get_sizegroup_bumping (widget))
|
||||
{
|
||||
/* Avoid recursion here */
|
||||
_gtk_widget_set_sizegroup_bumping (widget, TRUE);
|
||||
|
||||
if (_gtk_widget_get_sizegroups (widget))
|
||||
compute_dimension (widget, mode, minimum, natural);
|
||||
|
||||
_gtk_widget_set_sizegroup_bumping (widget, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* _gtk_size_group_queue_resize:
|
||||
* @widget: a #GtkWidget
|
||||
|
||||
@@ -58,23 +58,6 @@ struct _GtkSizeGroupClass
|
||||
void (*_gtk_reserved4) (void);
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkSizeGroupMode:
|
||||
* @GTK_SIZE_GROUP_NONE: group has no effect
|
||||
* @GTK_SIZE_GROUP_HORIZONTAL: group affects horizontal requisition
|
||||
* @GTK_SIZE_GROUP_VERTICAL: group affects vertical requisition
|
||||
* @GTK_SIZE_GROUP_BOTH: group affects both horizontal and vertical requisition
|
||||
*
|
||||
* The mode of the size group determines the directions in which the size
|
||||
* group affects the requested sizes of its component widgets.
|
||||
**/
|
||||
typedef enum {
|
||||
GTK_SIZE_GROUP_NONE,
|
||||
GTK_SIZE_GROUP_HORIZONTAL,
|
||||
GTK_SIZE_GROUP_VERTICAL,
|
||||
GTK_SIZE_GROUP_BOTH
|
||||
} GtkSizeGroupMode;
|
||||
|
||||
GType gtk_size_group_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkSizeGroup * gtk_size_group_new (GtkSizeGroupMode mode);
|
||||
|
||||
+115
-298
@@ -27,6 +27,7 @@
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtksizegroup-private.h"
|
||||
#include "gtksizerequestcacheprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "deprecated/gtkstyle.h"
|
||||
|
||||
@@ -37,7 +38,7 @@ static GQuark recursion_check_quark = 0;
|
||||
|
||||
static void
|
||||
push_recursion_check (GtkWidget *widget,
|
||||
GtkSizeGroupMode orientation,
|
||||
GtkOrientation orientation,
|
||||
gint for_size)
|
||||
{
|
||||
#ifndef G_DISABLE_CHECKS
|
||||
@@ -49,7 +50,7 @@ push_recursion_check (GtkWidget *widget,
|
||||
|
||||
previous_method = g_object_get_qdata (G_OBJECT (widget), recursion_check_quark);
|
||||
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
method = for_size < 0 ? "get_width" : "get_width_for_height";
|
||||
}
|
||||
@@ -75,283 +76,52 @@ push_recursion_check (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
pop_recursion_check (GtkWidget *widget,
|
||||
GtkSizeGroupMode orientation)
|
||||
GtkOrientation orientation)
|
||||
{
|
||||
#ifndef G_DISABLE_CHECKS
|
||||
g_object_set_qdata (G_OBJECT (widget), recursion_check_quark, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clear_cache (SizeRequestCache *cache,
|
||||
GtkSizeGroupMode orientation)
|
||||
{
|
||||
SizeRequest **sizes;
|
||||
gint i;
|
||||
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
sizes = cache->widths;
|
||||
|
||||
cache->widths = NULL;
|
||||
cache->cached_widths = 0;
|
||||
cache->last_cached_width = 0;
|
||||
cache->cached_base_width = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
sizes = cache->heights;
|
||||
|
||||
cache->heights = NULL;
|
||||
cache->cached_heights = 0;
|
||||
cache->last_cached_height = 0;
|
||||
cache->cached_base_height = FALSE;
|
||||
}
|
||||
|
||||
if (sizes)
|
||||
{
|
||||
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
|
||||
g_slice_free (SizeRequest, sizes[i]);
|
||||
|
||||
g_slice_free1 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_widget_free_cached_sizes (GtkWidget *widget)
|
||||
{
|
||||
SizeRequestCache *cache;
|
||||
|
||||
cache = _gtk_widget_peek_request_cache (widget);
|
||||
|
||||
clear_cache (cache, GTK_SIZE_GROUP_HORIZONTAL);
|
||||
clear_cache (cache, GTK_SIZE_GROUP_VERTICAL);
|
||||
}
|
||||
|
||||
/* This function checks if 'request_needed' flag is present
|
||||
* and resets the cache state if a request is needed for
|
||||
* a given orientation.
|
||||
*/
|
||||
static SizeRequestCache *
|
||||
init_cache (GtkWidget *widget)
|
||||
{
|
||||
SizeRequestCache *cache;
|
||||
|
||||
cache = _gtk_widget_peek_request_cache (widget);
|
||||
|
||||
if (_gtk_widget_get_width_request_needed (widget))
|
||||
clear_cache (cache, GTK_SIZE_GROUP_HORIZONTAL);
|
||||
|
||||
if (_gtk_widget_get_height_request_needed (widget))
|
||||
clear_cache (cache, GTK_SIZE_GROUP_VERTICAL);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
/* looks for a cached size request for this for_size. If not
|
||||
* found, returns the oldest entry so it can be overwritten
|
||||
*
|
||||
* Note that this caching code was originally derived from
|
||||
* the Clutter toolkit but has evolved for other GTK+ requirements.
|
||||
*/
|
||||
static gboolean
|
||||
get_cached_size (GtkWidget *widget,
|
||||
GtkSizeGroupMode orientation,
|
||||
gint for_size,
|
||||
CachedSize **result)
|
||||
{
|
||||
SizeRequestCache *cache;
|
||||
SizeRequest **cached_sizes;
|
||||
guint i, n_sizes;
|
||||
|
||||
cache = init_cache (widget);
|
||||
|
||||
if (for_size < 0)
|
||||
{
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
*result = &cache->cached_width;
|
||||
return cache->cached_base_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = &cache->cached_height;
|
||||
return cache->cached_base_height;
|
||||
}
|
||||
}
|
||||
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
cached_sizes = cache->widths;
|
||||
n_sizes = cache->cached_widths;
|
||||
}
|
||||
else
|
||||
{
|
||||
cached_sizes = cache->heights;
|
||||
n_sizes = cache->cached_heights;
|
||||
}
|
||||
|
||||
/* Search for an already cached size */
|
||||
for (i = 0; i < n_sizes; i++)
|
||||
{
|
||||
if (cached_sizes[i]->lower_for_size <= for_size &&
|
||||
cached_sizes[i]->upper_for_size >= for_size)
|
||||
{
|
||||
*result = &cached_sizes[i]->cached_size;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
commit_cached_size (GtkWidget *widget,
|
||||
GtkSizeGroupMode orientation,
|
||||
gint for_size,
|
||||
gint minimum_size,
|
||||
gint natural_size)
|
||||
{
|
||||
SizeRequestCache *cache;
|
||||
SizeRequest **cached_sizes;
|
||||
guint i, n_sizes;
|
||||
|
||||
cache = _gtk_widget_peek_request_cache (widget);
|
||||
|
||||
/* First handle caching of the base requests */
|
||||
if (for_size < 0)
|
||||
{
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
cache->cached_width.minimum_size = minimum_size;
|
||||
cache->cached_width.natural_size = natural_size;
|
||||
cache->cached_base_width = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache->cached_height.minimum_size = minimum_size;
|
||||
cache->cached_height.natural_size = natural_size;
|
||||
cache->cached_base_height = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the minimum_size and natural_size is already
|
||||
* in the cache and if this result can be used to extend
|
||||
* that cache entry
|
||||
*/
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
cached_sizes = cache->widths;
|
||||
n_sizes = cache->cached_widths;
|
||||
}
|
||||
else
|
||||
{
|
||||
cached_sizes = cache->heights;
|
||||
n_sizes = cache->cached_heights;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_sizes; i++)
|
||||
{
|
||||
if (cached_sizes[i]->cached_size.minimum_size == minimum_size &&
|
||||
cached_sizes[i]->cached_size.natural_size == natural_size)
|
||||
{
|
||||
cached_sizes[i]->lower_for_size = MIN (cached_sizes[i]->lower_for_size, for_size);
|
||||
cached_sizes[i]->upper_for_size = MAX (cached_sizes[i]->upper_for_size, for_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not found, pull a new size from the cache, the returned size cache
|
||||
* will immediately be used to cache the new computed size so we go ahead
|
||||
* and increment the last_cached_width/height right away */
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
{
|
||||
if (cache->cached_widths < GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
{
|
||||
cache->cached_widths++;
|
||||
cache->last_cached_width = cache->cached_widths - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++cache->last_cached_width == GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
cache->last_cached_width = 0;
|
||||
}
|
||||
|
||||
if (!cache->widths)
|
||||
cache->widths = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
||||
|
||||
if (!cache->widths[cache->last_cached_width])
|
||||
cache->widths[cache->last_cached_width] = g_slice_new (SizeRequest);
|
||||
|
||||
cache->widths[cache->last_cached_width]->lower_for_size = for_size;
|
||||
cache->widths[cache->last_cached_width]->upper_for_size = for_size;
|
||||
cache->widths[cache->last_cached_width]->cached_size.minimum_size = minimum_size;
|
||||
cache->widths[cache->last_cached_width]->cached_size.natural_size = natural_size;
|
||||
}
|
||||
else /* GTK_SIZE_GROUP_VERTICAL */
|
||||
{
|
||||
if (cache->cached_heights < GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
{
|
||||
cache->cached_heights++;
|
||||
cache->last_cached_height = cache->cached_heights - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++cache->last_cached_height == GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
cache->last_cached_height = 0;
|
||||
}
|
||||
|
||||
if (!cache->heights)
|
||||
cache->heights = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
||||
|
||||
if (!cache->heights[cache->last_cached_height])
|
||||
cache->heights[cache->last_cached_height] = g_slice_new (SizeRequest);
|
||||
|
||||
cache->heights[cache->last_cached_height]->lower_for_size = for_size;
|
||||
cache->heights[cache->last_cached_height]->upper_for_size = for_size;
|
||||
cache->heights[cache->last_cached_height]->cached_size.minimum_size = minimum_size;
|
||||
cache->heights[cache->last_cached_height]->cached_size.natural_size = natural_size;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_vfunc_name (GtkSizeGroupMode orientation,
|
||||
gint for_size)
|
||||
get_vfunc_name (GtkOrientation orientation,
|
||||
gint for_size)
|
||||
{
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
return for_size < 0 ? "get_preferred_width" : "get_preferred_width_for_height";
|
||||
else
|
||||
return for_size < 0 ? "get_preferred_height" : "get_preferred_height_for_width";
|
||||
}
|
||||
|
||||
/* This is the main function that checks for a cached size and
|
||||
* possibly queries the widget class to compute the size if it's
|
||||
* not cached. If the for_size here is -1, then get_preferred_width()
|
||||
* or get_preferred_height() will be used.
|
||||
*/
|
||||
static void
|
||||
compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkSizeGroupMode orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gtk_widget_query_size_for_orientation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
CachedSize *cached_size;
|
||||
gboolean found_in_cache = FALSE;
|
||||
gint min_size = 0;
|
||||
gint nat_size = 0;
|
||||
SizeRequestCache *cache;
|
||||
gint min_size = 0;
|
||||
gint nat_size = 0;
|
||||
gboolean found_in_cache;
|
||||
|
||||
found_in_cache = get_cached_size (widget, orientation, for_size, &cached_size);
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
|
||||
for_size = -1;
|
||||
|
||||
cache = _gtk_widget_peek_request_cache (widget);
|
||||
found_in_cache = _gtk_size_request_cache_lookup (cache,
|
||||
orientation,
|
||||
for_size,
|
||||
&min_size,
|
||||
&nat_size);
|
||||
|
||||
if (!found_in_cache)
|
||||
{
|
||||
gint adjusted_min, adjusted_natural, adjusted_for_size = for_size;
|
||||
|
||||
gtk_widget_ensure_style (widget);
|
||||
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
if (for_size < 0)
|
||||
{
|
||||
@@ -424,17 +194,10 @@ compute_size_for_orientation (GtkWidget *widget,
|
||||
G_OBJECT_TYPE_NAME (widget), widget, min_size, nat_size, get_vfunc_name (orientation, for_size));
|
||||
}
|
||||
|
||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||
_gtk_widget_set_width_request_needed (widget, FALSE);
|
||||
else
|
||||
_gtk_widget_set_height_request_needed (widget, FALSE);
|
||||
|
||||
adjusted_min = min_size;
|
||||
adjusted_natural = nat_size;
|
||||
GTK_WIDGET_GET_CLASS (widget)->adjust_size_request (widget,
|
||||
orientation == GTK_SIZE_GROUP_HORIZONTAL ?
|
||||
GTK_ORIENTATION_HORIZONTAL :
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
orientation,
|
||||
&adjusted_min,
|
||||
&adjusted_natural);
|
||||
|
||||
@@ -443,7 +206,7 @@ compute_size_for_orientation (GtkWidget *widget,
|
||||
{
|
||||
g_warning ("%s %p adjusted size %s min %d natural %d must not decrease below min %d natural %d",
|
||||
G_OBJECT_TYPE_NAME (widget), widget,
|
||||
orientation == GTK_SIZE_GROUP_VERTICAL ? "vertical" : "horizontal",
|
||||
orientation == GTK_ORIENTATION_VERTICAL ? "vertical" : "horizontal",
|
||||
adjusted_min, adjusted_natural,
|
||||
min_size, nat_size);
|
||||
/* don't use the adjustment */
|
||||
@@ -452,7 +215,7 @@ compute_size_for_orientation (GtkWidget *widget,
|
||||
{
|
||||
g_warning ("%s %p adjusted size %s min %d natural %d original min %d natural %d has min greater than natural",
|
||||
G_OBJECT_TYPE_NAME (widget), widget,
|
||||
orientation == GTK_SIZE_GROUP_VERTICAL ? "vertical" : "horizontal",
|
||||
orientation == GTK_ORIENTATION_VERTICAL ? "vertical" : "horizontal",
|
||||
adjusted_min, adjusted_natural,
|
||||
min_size, nat_size);
|
||||
/* don't use the adjustment */
|
||||
@@ -464,20 +227,11 @@ compute_size_for_orientation (GtkWidget *widget,
|
||||
nat_size = adjusted_natural;
|
||||
}
|
||||
|
||||
/* Update size-groups with our request and update our cached requests
|
||||
* with the size-group values in a single pass.
|
||||
*/
|
||||
_gtk_size_group_bump_requisition (widget,
|
||||
orientation,
|
||||
&min_size,
|
||||
&nat_size);
|
||||
|
||||
commit_cached_size (widget, orientation, for_size, min_size, nat_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
min_size = cached_size->minimum_size;
|
||||
nat_size = cached_size->natural_size;
|
||||
_gtk_size_request_cache_commit (cache,
|
||||
orientation,
|
||||
for_size,
|
||||
min_size,
|
||||
nat_size);
|
||||
}
|
||||
|
||||
if (minimum_size)
|
||||
@@ -491,11 +245,60 @@ compute_size_for_orientation (GtkWidget *widget,
|
||||
GTK_NOTE (SIZE_REQUEST,
|
||||
g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d (hit cache: %s)\n",
|
||||
widget, G_OBJECT_TYPE_NAME (widget),
|
||||
orientation == GTK_SIZE_GROUP_HORIZONTAL ?
|
||||
orientation == GTK_ORIENTATION_HORIZONTAL ?
|
||||
"width for height" : "height for width" ,
|
||||
for_size, min_size, nat_size,
|
||||
found_in_cache ? "yes" : "no"));
|
||||
}
|
||||
|
||||
/* This is the main function that checks for a cached size and
|
||||
* possibly queries the widget class to compute the size if it's
|
||||
* not cached. If the for_size here is -1, then get_preferred_width()
|
||||
* or get_preferred_height() will be used.
|
||||
*/
|
||||
void
|
||||
_gtk_widget_compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GHashTable *widgets;
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
gint min_result = 0, nat_result = 0;
|
||||
|
||||
if (G_LIKELY (!_gtk_widget_get_sizegroups (widget)))
|
||||
{
|
||||
gtk_widget_query_size_for_orientation (widget, orientation, for_size, minimum, natural);
|
||||
return;
|
||||
}
|
||||
|
||||
widgets = _gtk_size_group_get_widget_peers (widget, orientation);
|
||||
|
||||
g_hash_table_foreach (widgets, (GHFunc) g_object_ref, NULL);
|
||||
|
||||
g_hash_table_iter_init (&iter, widgets);
|
||||
while (g_hash_table_iter_next (&iter, &key, NULL))
|
||||
{
|
||||
GtkWidget *tmp_widget = key;
|
||||
gint min_dimension, nat_dimension;
|
||||
|
||||
gtk_widget_query_size_for_orientation (tmp_widget, orientation, for_size, &min_dimension, &nat_dimension);
|
||||
|
||||
min_result = MAX (min_result, min_dimension);
|
||||
nat_result = MAX (nat_result, nat_dimension);
|
||||
}
|
||||
|
||||
g_hash_table_foreach (widgets, (GHFunc) g_object_unref, NULL);
|
||||
|
||||
g_hash_table_destroy (widgets);
|
||||
|
||||
if (minimum)
|
||||
*minimum = min_result;
|
||||
|
||||
if (natural)
|
||||
*natural = nat_result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -517,9 +320,19 @@ compute_size_for_orientation (GtkWidget *widget,
|
||||
GtkSizeRequestMode
|
||||
gtk_widget_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
SizeRequestCache *cache;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_SIZE_REQUEST_CONSTANT_SIZE);
|
||||
|
||||
return GTK_WIDGET_GET_CLASS (widget)->get_request_mode (widget);
|
||||
cache = _gtk_widget_peek_request_cache (widget);
|
||||
|
||||
if (!cache->request_mode_valid)
|
||||
{
|
||||
cache->request_mode = GTK_WIDGET_GET_CLASS (widget)->get_request_mode (widget);
|
||||
cache->request_mode_valid = TRUE;
|
||||
}
|
||||
|
||||
return cache->request_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -549,8 +362,11 @@ gtk_widget_get_preferred_width (GtkWidget *widget,
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_width != NULL || natural_width != NULL);
|
||||
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_HORIZONTAL,
|
||||
-1, minimum_width, natural_width);
|
||||
_gtk_widget_compute_size_for_orientation (widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum_width,
|
||||
natural_width);
|
||||
}
|
||||
|
||||
|
||||
@@ -580,8 +396,11 @@ gtk_widget_get_preferred_height (GtkWidget *widget,
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
|
||||
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_VERTICAL,
|
||||
-1, minimum_height, natural_height);
|
||||
_gtk_widget_compute_size_for_orientation (widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum_height,
|
||||
natural_height);
|
||||
}
|
||||
|
||||
|
||||
@@ -614,12 +433,11 @@ gtk_widget_get_preferred_width_for_height (GtkWidget *widget,
|
||||
g_return_if_fail (minimum_width != NULL || natural_width != NULL);
|
||||
g_return_if_fail (height >= 0);
|
||||
|
||||
if (GTK_WIDGET_GET_CLASS (widget)->get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_HORIZONTAL,
|
||||
-1, minimum_width, natural_width);
|
||||
else
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_HORIZONTAL,
|
||||
height, minimum_width, natural_width);
|
||||
_gtk_widget_compute_size_for_orientation (widget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
height,
|
||||
minimum_width,
|
||||
natural_width);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -650,12 +468,11 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
|
||||
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
|
||||
g_return_if_fail (width >= 0);
|
||||
|
||||
if (GTK_WIDGET_GET_CLASS (widget)->get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_VERTICAL,
|
||||
-1, minimum_height, natural_height);
|
||||
else
|
||||
compute_size_for_orientation (widget, GTK_SIZE_GROUP_VERTICAL,
|
||||
width, minimum_height, natural_height);
|
||||
_gtk_widget_compute_size_for_orientation (widget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum_height,
|
||||
natural_height);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/* gtksizerequest.c
|
||||
* Copyright (C) 2007-2010 Openismus GmbH
|
||||
*
|
||||
* Authors:
|
||||
* Mathias Hasselmann <mathias@openismus.com>
|
||||
* Tristan Van Berkom <tristan.van.berkom@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "gtksizerequestcacheprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
_gtk_size_request_cache_init (SizeRequestCache *cache)
|
||||
{
|
||||
memset (cache, 0, sizeof (SizeRequestCache));
|
||||
}
|
||||
|
||||
static void
|
||||
free_sizes (SizeRequest **sizes)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
|
||||
g_slice_free (SizeRequest, sizes[i]);
|
||||
|
||||
g_slice_free1 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_size_request_cache_free (SizeRequestCache *cache)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (cache->requests[i])
|
||||
free_sizes (cache->requests[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_size_request_cache_clear (SizeRequestCache *cache)
|
||||
|
||||
{
|
||||
_gtk_size_request_cache_free (cache);
|
||||
_gtk_size_request_cache_init (cache);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_size_request_cache_commit (SizeRequestCache *cache,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint minimum_size,
|
||||
gint natural_size)
|
||||
{
|
||||
SizeRequest **cached_sizes;
|
||||
SizeRequest *cached_size;
|
||||
guint i, n_sizes;
|
||||
|
||||
/* First handle caching of the base requests */
|
||||
if (for_size < 0)
|
||||
{
|
||||
cache->cached_size[orientation].minimum_size = minimum_size;
|
||||
cache->cached_size[orientation].natural_size = natural_size;
|
||||
cache->flags[orientation].cached_size_valid = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the minimum_size and natural_size is already
|
||||
* in the cache and if this result can be used to extend
|
||||
* that cache entry
|
||||
*/
|
||||
cached_sizes = cache->requests[orientation];
|
||||
n_sizes = cache->flags[orientation].n_cached_requests;
|
||||
|
||||
for (i = 0; i < n_sizes; i++)
|
||||
{
|
||||
if (cached_sizes[i]->cached_size.minimum_size == minimum_size &&
|
||||
cached_sizes[i]->cached_size.natural_size == natural_size)
|
||||
{
|
||||
cached_sizes[i]->lower_for_size = MIN (cached_sizes[i]->lower_for_size, for_size);
|
||||
cached_sizes[i]->upper_for_size = MAX (cached_sizes[i]->upper_for_size, for_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If not found, pull a new size from the cache, the returned size cache
|
||||
* will immediately be used to cache the new computed size so we go ahead
|
||||
* and increment the last_cached_request right away */
|
||||
if (n_sizes < GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
{
|
||||
cache->flags[orientation].n_cached_requests++;
|
||||
cache->flags[orientation].last_cached_request = cache->flags[orientation].n_cached_requests - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||
cache->flags[orientation].last_cached_request = 0;
|
||||
}
|
||||
|
||||
if (cache->requests[orientation] == NULL)
|
||||
cache->requests[orientation] = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
||||
|
||||
if (cache->requests[orientation][cache->flags[orientation].last_cached_request] == NULL)
|
||||
cache->requests[orientation][cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequest);
|
||||
|
||||
cached_size = cache->requests[orientation][cache->flags[orientation].last_cached_request];
|
||||
cached_size->lower_for_size = for_size;
|
||||
cached_size->upper_for_size = for_size;
|
||||
cached_size->cached_size.minimum_size = minimum_size;
|
||||
cached_size->cached_size.natural_size = natural_size;
|
||||
}
|
||||
|
||||
/* looks for a cached size request for this for_size.
|
||||
*
|
||||
* Note that this caching code was originally derived from
|
||||
* the Clutter toolkit but has evolved for other GTK+ requirements.
|
||||
*/
|
||||
gboolean
|
||||
_gtk_size_request_cache_lookup (SizeRequestCache *cache,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
CachedSize *result = NULL;
|
||||
|
||||
if (for_size < 0)
|
||||
{
|
||||
if (cache->flags[orientation].cached_size_valid)
|
||||
result = &cache->cached_size[orientation];
|
||||
}
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
|
||||
/* Search for an already cached size */
|
||||
for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
|
||||
{
|
||||
SizeRequest *cur = cache->requests[orientation][i];
|
||||
|
||||
if (cur->lower_for_size <= for_size &&
|
||||
cur->upper_for_size >= for_size)
|
||||
{
|
||||
result = &cur->cached_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
*minimum = result->minimum_size;
|
||||
*natural = result->natural_size;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SIZE_REQUEST_CACHE_PRIVATE_H__
|
||||
#define __GTK_SIZE_REQUEST_CACHE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Cache as many ranges of height-for-width
|
||||
* (or width-for-height) as can be rational
|
||||
* for a said widget to have, if a label can
|
||||
* only wrap to 3 lines, only 3 caches will
|
||||
* ever be allocated for it.
|
||||
*/
|
||||
#define GTK_SIZE_REQUEST_CACHED_SIZES (5)
|
||||
|
||||
typedef struct {
|
||||
gint minimum_size;
|
||||
gint natural_size;
|
||||
} CachedSize;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint lower_for_size; /* The minimum for_size with the same result */
|
||||
gint upper_for_size; /* The maximum for_size with the same result */
|
||||
CachedSize cached_size;
|
||||
} SizeRequest;
|
||||
|
||||
typedef struct {
|
||||
SizeRequest **requests[2];
|
||||
|
||||
CachedSize cached_size[2];
|
||||
|
||||
GtkSizeRequestMode request_mode : 3;
|
||||
guint request_mode_valid : 1;
|
||||
struct {
|
||||
guint n_cached_requests : 3;
|
||||
guint last_cached_request : 3;
|
||||
guint cached_size_valid : 1;
|
||||
} flags[2];
|
||||
} SizeRequestCache;
|
||||
|
||||
void _gtk_size_request_cache_init (SizeRequestCache *cache);
|
||||
void _gtk_size_request_cache_free (SizeRequestCache *cache);
|
||||
|
||||
void _gtk_size_request_cache_clear (SizeRequestCache *cache);
|
||||
void _gtk_size_request_cache_commit (SizeRequestCache *cache,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint minimum_size,
|
||||
gint natural_size);
|
||||
gboolean _gtk_size_request_cache_lookup (SizeRequestCache *cache,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SIZE_REQUEST_CACHE_PRIVATE_H__ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user