Compare commits

...

223 Commits

Author SHA1 Message Date
Alexander Larsson 90bcb52293 css: Add debug output for the css rules tree 2012-11-23 16:15:29 +01:00
Alexander Larsson 3b48e562dd css: Make gtk_css_style_provider_get_change use the new rules tree 2012-11-23 16:13:27 +01:00
Alexander Larsson fc12246758 css: Make gtk_css_style_provider_lookup use the new rule tree 2012-11-23 16:13:26 +01:00
Alexander Larsson ae194d14d1 css: Calculate tree for faster ruleset matching
When matching a widget against the set of rules we currently iterate
over *all* rules in the theme, trying to match them until we fullfill
our needs. This takes a pretty long time since themes have a lot of rules.

This is the first step towards making this faster. Every time the
ruleset changes we pre-calculate a decision tree where the nodes are either
list of rules to match against, or checks, such that if the check fails
we can ignore a whole subset of the tree.

The tree is built up in two levels, first we check if certain states must
be set, ignoring whole branches if not. Then in the level below we look
for css classes which are used by many rules.

At the leaf nodes we store references to the full list rulesets. These are
stored as array offset, which are sorted in index order, which means css prio
order, as the rulesets are sorted by that.

With this in place we can quickly prune large parts of the tree and then
merge the non-pruned result into a much smaller list of rules that we
need to do full checking on.
2012-11-23 16:13:21 +01:00
Alexander Larsson c55a492ad3 css: Add some methods for getting selector state
This adds the following private methods:
_gtk_css_selector_get_primary_state_flags
_gtk_css_selector_get_primary_classes
_gtk_css_selector_has_primary_class

They get state and classes for the primary selector (i.e. the rightmost
simple selector). This will be used for some css optimizations.
2012-11-23 15:53:49 +01:00
Alexander Larsson b70d8c477d CSS: Join multiple adjacent pseudoclass selectors
Its pretty common to have a selector like :selected:active where
two or more state flags appear in a row. Right now we save
these as multiple GtkCssSelectors, but as state is a bitfield we
can easily join them. We do this in the simple case where the
state matchers are directly adjacent by just piggybacking on
a previous pseudoclass if there is one.
2012-11-23 09:42:10 +01:00
David King 73c436f43e docs: Fix typo in gtk_tree_view_set_tooltip_column comment
https://bugzilla.gnome.org/show_bug.cgi?id=688884
2012-11-22 22:25:51 +00:00
David King c627b22126 docs: Improve GtkTreeModel iteration pattern
Iterating over the model in this way means that use of continue is less
error-prone, as the increment is part of the loop construct.

https://bugzilla.gnome.org/show_bug.cgi?id=548793
2012-11-22 21:36:46 +00:00
David King e677cee28f docs: Correct GtkWidget::scroll-event mask documentation
Since GTK+ 3.3.18, GDK_SCROLL_MASK has been used as the mask for scroll
events. Update the documentation to reflect this.

https://bugzilla.gnome.org/show_bug.cgi?id=677339
2012-11-22 21:36:40 +00:00
Martin Pitt 2927383b5f aboutdialog: Fix add_credit_section() annotations
The people argument is an array.

https://mail.gnome.org/archives/python-hackers-list/2012-November/msg00010.html
2012-11-22 14:51:52 +01:00
Michael Natterer 2d9454363f gtk: don't let insensitive children eat scroll events when bubbling down
When event capturing is enabled, stop propagating scroll events
at insensitive widgets, but don't handle them (don't return TRUE),
so they can bubble up again and reach their handling widgets.
2012-11-22 13:53:33 +01:00
Wouter Bolsterlee eb7bf0a2f4 Updated Dutch translation 2012-11-22 12:04:31 +01:00
Camillo Lugaresi 4f6e1fdf16 Bug 688710 - splashscreen shouldn't be always on top on OS X
Activate the "hides on deactivate" behavior for splashscreens,
torn-off menus, utility windows, tooltips and notifications: when
another application is brought to the front, these windows are hidden
so as not to obscure it. This is the expected behavior for
application-specific floating windows on OS X.
(cherry picked from commit 0596f5591f)
2012-11-20 22:03:40 +01:00
Cosimo Cecchi ddceddaa84 tree-view: don't use gtk_style_context_set_background()
Render a background with gtk_render_background() in draw() instead.
Note that we still use gtk_style_context_set_background() for the header
window.

https://bugzilla.gnome.org/show_bug.cgi?id=688744
2012-11-20 13:41:39 -05:00
Cosimo Cecchi da09447914 iconview: don't use gtk_style_context_set_background()
Render a background with gtk_render_background() during draw instead.

https://bugzilla.gnome.org/show_bug.cgi?id=688744
2012-11-20 13:41:39 -05:00
Michael Natterer d0af25f12c quartz: fix the mapping of GDK_KP_Enter in known_numeric_keys[]
so it will actually be used, instead of delivering GDK_Return
when it should be GDK_KP_Enter.
(cherry picked from commit 27f3fcf12c)
2012-11-20 19:14:43 +01:00
Matthias Clasen 6e3d687386 Post-release version bump 2012-11-20 07:00:53 -05:00
Matthias Clasen 6333cd8e83 Update expected output for the entries a11y test
This change is due to entry icons now being accessible.
2012-11-20 06:28:59 -05:00
Benjamin Otte 8d28e2d8e9 reftests: Fix linear-gradient reftest (again)
Make it so that the repeating vs normal test only uses sharp color
cutoffs instead of real gradients. That removes rounding errors and
makes the test pass.
2012-11-20 12:21:03 +01:00
Benjamin Otte e5948f5713 cssvalue: Fix copy/paste error
Introduced in e3f407a7.
2012-11-20 12:11:07 +01:00
Matthias Clasen d967500c92 Fix parser tests for color changes 2012-11-20 05:54:53 -05:00
Matthias Clasen 4be82195e4 3.7.2 2012-11-20 05:32:19 -05:00
Michael Natterer 455a0ecc1c quartz: always send GDK_NOTIFY_NONLINEAR crossing events
so GtkMenu works properly. This is not right, but not more
wrong than always sending GDK_NOTIFY_ANCESTOR either.
(cherry picked from commit 35a9322e45)
2012-11-20 10:35:40 +01:00
Michael Natterer 2d5ad5f54e Bug 672193 - windows (including menus) shown multiple times don't...
Based on a patch from Paul Davis, inject synthetic enter events directly
into the Quartz event stream, instead of trying to synthesize them in GDK.

This seems to magically fix most combo box popup weirdness, I guess
some code is relying on a specfic order of events, or any other state
imposed by the "proper" code path of events coming in the usual way.

The patch also removes _gdk_quartz_events_send_enter_notify_event()
which is now obsolete.

(sortof cherry-pixked from 979e5061a0
but needed manual editing because GdkQuartzWindow.c was renamed
and apparently earlier patches not picked correctly/completely)
2012-11-20 10:28:58 +01:00
Matthias Clasen 352c7f5120 Avoid infinite recursion in the ime input module 2012-11-19 09:30:44 -05:00
Benjamin Otte c3f3a82db9 stylecontext: Split out a function
The function is used in multiple places, so split it out. In particular
because I'm about to change it.
2012-11-18 21:55:43 +01:00
Michael Natterer b55724e3a7 quartz: use the real current event time for generated motion events
(cherry picked from commit b4a30877a9)
2012-11-18 20:17:22 +01:00
Michael Natterer f2e05e2b41 quartz: move tooltips window to the topmost level
so they can appear on top of popup menus. Also, reorder the switch()
statement in window_type_hint_to_level() so it resembles the stacking
order, to avoid confision like this in the future. Fixes bug 688512.
(cherry picked from commit 1a2509a6ab)
2012-11-18 17:47:33 +01:00
Kjartan Maraas bfbb9a58ae Updated Norwegian bokmål translation 2012-11-17 16:42:44 +01:00
Kjartan Maraas 870657d57b Updated Norwegian bokmål translation 2012-11-17 16:14:38 +01:00
Benjamin Otte 4bc264a514 cssprovider: Handle non-existing section
Otherwise we'll get warnings on errors when CSS debug is disabled.
2012-11-15 19:25:14 +01:00
Michael Natterer 18fdc975be quartz: GdkQuartzWindow -> GdkQuartzNSWindow was forgotten in one place 2012-11-15 13:17:31 +01:00
Michael Natterer ed5d7fed89 quartz: filter out button press events on the window frame
Don't try to handle button press events on the window frame, they
have out-of-window coordinates. Also, break grabs on such events
so popup menus go away.
Patch from Kristian Rietveld, fixes bug 684419.
(cherry picked from commit 43e1354b71)
2012-11-15 12:35:58 +01:00
Jonny Lamb 2f8c2a3244 filechooser: remember sidebar width
https://bugzilla.gnome.org/show_bug.cgi?id=524295

Signed-off-by: Jonny Lamb <jonnylamb@gnome.org>
2012-11-14 20:03:23 -06:00
Benjamin Otte 5671a869c2 Revert parts of "window: Remove useless functions"
This reverts the size_allocate removal from commit
8449e05865. That code was using
_gtk_window_set_allocation() instead of gtk_widget_set_allocation(). And
that broke glade.
2012-11-14 20:12:30 +01:00
Piotr Drąg f9b2edff39 Updated POTFILES.skip 2012-11-14 16:15:27 +01:00
Benjamin Otte 53262cf7a6 sizerequest: Optimize CONSTANT_SIZE better
We can set for_size to -1 earlier than we did. Doing so makes sure we
only cache one value (as we should in the first place). In GTK 3.6, this
worked properly, but with Previously, this check was moved further up to
avoid interacting with size groups. But after recent refactorings, size
groups are handled way earlier anyway.
2012-11-14 14:03:47 +01:00
Benjamin Otte 6d3b4d9382 stylecontext: Add a flag to force style_updated() emission
This is used in gtk_widget_reset_style() (via GTK_CSS_CHANGE_ANY) now,
and that makes GtkSettings font related changes work again.
2012-11-14 13:25:44 +01:00
Benjamin Otte d3143779d2 sizerequestcache: Move rest of code to array
... of orientation. Reduces more duplicate if branches.
2012-11-14 01:55:29 +01:00
Benjamin Otte 43fc428cf0 sizerequestcache: Make code an array
We can use orientation as the index into an array. That way we can
delete half the code. Do it for the base request first in this patch.
2012-11-14 01:55:29 +01:00
Benjamin Otte 70ba973d1d sizegroup: Simplify comparison 2012-11-14 01:55:29 +01:00
Benjamin Otte fd6ea42319 sizerequest: Use GtkOrientation
... instead of GtkSizeGroupMode. Orientation is what we're interested in
after all. When we need a GtkSizeGroupMode, we can do the translation
where we need it.
2012-11-14 01:55:29 +01:00
Benjamin Otte 0e0ee480d3 sizerequestcache: Move lookup function
...and clean up its API.
2012-11-14 01:55:29 +01:00
Benjamin Otte 78d0ef1d0b sizerequestcache: Move commit function 2012-11-14 01:55:28 +01:00
Benjamin Otte 14c8e33ab9 widget: Get rid of unused flags
Now that we clear the cache immediately, there's no need anymore to
track if a request has been queued.
2012-11-14 01:55:28 +01:00
Benjamin Otte c08efb2b32 sizerequest: Cache the request mode
... in the GtkSizeRequestCache. That way, we only need to query it once,
and can remove the caching code from GtkContainer.
2012-11-14 01:55:28 +01:00
Benjamin Otte c98ee1ec39 sizerequestcache: Make clear_cache clear all the cache 2012-11-14 01:55:28 +01:00
Benjamin Otte 4366f80aab sizerequestcache: Move functions
... into the sizerequestcache.c file.
2012-11-14 01:55:28 +01:00
Benjamin Otte 15570dd63d reftests: Turns out, green changed color
What used to be "green" is now "lime"
2012-11-14 01:55:28 +01:00
Benjamin Otte 10c47c0226 reftests: Update named colors reftest
Make reftest conform with correct colors. Pango has been updated to
these colors in commit d2c319b9ded8cce864914d9f1fd704a7aff3112f
2012-11-14 01:55:28 +01:00
Benjamin Otte 0a1a2ac148 sizerequest: Split out size request cache code into separate header 2012-11-14 01:55:28 +01:00
Michael Natterer aa989a637a quartz: move SPLASHSCREEN-hinted windows to NSStatusWindowLevel
which does not really have a different effect than the previously
used NSPopUpMenuWindowLevel, but is what all code examples I found
are using, and it does make more sense.
(cherry picked from commit 47f0e3f1e1)
2012-11-13 20:05:33 +01:00
Timothy Arceri 50a09957a4 Remove bookmark duplicate of shortcut
Application code can set shortcut folders that are already bookmarks.
This code causes the bookmarks to be refreshed after the shortcut is
added removing any possible bookmark duplicates

https://bugzilla.gnome.org/show_bug.cgi?id=577806
2012-11-13 12:54:15 -06:00
Chun-wei Fan e57ecafb6b Visual C++ property sheets: Update GtkBinaryVersion
This should now be 3.0.0 like the autotools builds...
2012-11-13 14:26:08 +08:00
Mike Gorse b7743430aa Add accessibles for GtkEntry icons
Expose GtkEntry icons as child accessibles of a GtkEntry, and provide
actions to simulate clicking them. Also, refactor the a11y children test
slightly to add a test.

https://bugzilla.gnome.org/show_bug.cgi?id=686347
2012-11-12 09:21:27 -06:00
Mike Gorse 77c0f9d8e6 Send a notification when a GtkEntry icon's tooltip text changes 2012-11-12 09:15:46 -06:00
Benjamin Otte 872097603f reftests: Add a test for border-width problems 2012-11-11 20:26:28 +01:00
Benjamin Otte 5e01a05b30 bin: Handle border width if we have to
Some bin subclasses call gtk_container_handle_border_width(), some
don't. So work with both cases.
2012-11-11 20:26:28 +01:00
Benjamin Otte a08eb4d58a container: Simplify code
We will never get allocated a too small size, so no need to handle that
case.
2012-11-11 20:26:28 +01:00
Benjamin Otte 8449e05865 window: Remove useless functions
Now that GtkBin implements sizing functionality, there's no need to do
the same in GtkWindow
2012-11-11 20:26:28 +01:00
Benjamin Otte b0f3aa82b7 bin: Only handle size for the child if it is visible 2012-11-11 20:26:27 +01:00
Piotr Drąg 4950f68a87 Updated POTFILES.skip 2012-11-10 20:21:33 +01:00
Benjamin Otte 5f20d909e6 tests: Add an intersection test for the recent bug
Just using the hardcoded bitmasks triggered the bug fixed in commit
e8f2eeac92 - so just do that as the test.
2012-11-10 18:55:14 +01:00
Benjamin Otte c59e8de533 tests: Add some bitmasks to the hardcoded list
The bitmasks with the 31st, 32nd and 63rd bit set are added. The make up
the largest bitmasks on 32bit/64bit that can be represented without
allocating and the smallest bitmask on 32bit that must be allocated.
2012-11-10 18:53:34 +01:00
Benjamin Otte e8f2eeac92 bitmask: Fix intersection code
With the fix in 77912a65e2, another bug
got visible: booleans are 32 bits, so if the intersection between the 2
bitmasks happened in higher bits, the return value would be truncated to
FALSE.

This actually made slider handles disappear, so it was pretty visible.
2012-11-10 18:35:37 +01:00
Benjamin Otte aae2bf91cb cssvalue: Make shade() work properly again
In a previous commit, I accidentally scaled the hue instead of the
saturation. Ooops.
2012-11-10 14:25:18 +01:00
Benjamin Otte 10c3a66e40 reftests: Add a test for all the color names
BIG NOTE: We fail on some of these to give the colors defined in the CSS
specs. This is not good, but I'm not sure how to best fix it.
For those cases, I've kept the correct color in the CSS file but added
the correct one next to it.
2012-11-10 14:25:17 +01:00
Piotr Drąg 42fc6ab5d3 Updated POTFILES.skip 2012-11-10 00:38:13 +01:00
Stef Walter c8de9abe98 icon-theme: Add some preconditions for NULL arguments
Related to this crash: https://bugzilla.gnome.org/show_bug.cgi?id=687967

https://bugzilla.gnome.org/show_bug.cgi?id=687977
2012-11-09 11:59:09 +01:00
Alexander Larsson e60c9219f1 Make _gtk_css_lookup_get_missing inline
This is called a lot in the loop in gtk_css_style_provider_lookup which
actually showed up on profiles.
2012-11-09 10:16:23 +01:00
Alexander Larsson 1c4158a649 gtk_css_style_provider_lookup: minor loop optimiziation
This is a minor performance improvement but this loop
is run a lot so it actually matters in large state
changes.
2012-11-09 10:16:18 +01:00
Alexander Larsson 55d65571f3 Exit early in gtk_style_context_update_cache codepaths
If lookup->missing is empty we don't need to continue looking.
We short circuit in several places as this can happen
after iteratively makeign lookup->missing smaller.
2012-11-09 10:15:23 +01:00
Alexander Larsson 77912a65e2 Fix cnp bug in _gtk_bitmask_intersects
We need to use the allocated codepath if *any* argument is
allocated, not if one arg is not allocated.
This bug caused unnecessary calls to _gtk_bitmask_is_allocated,
as well as return completely wrong result if both bitmask are
allocated.
2012-11-09 10:11:47 +01:00
Alexander Larsson 8a40d8fe2a gdk: Add gdk_window_has_alpha helper
This centralizes the current checks for has_alpha_bg, which
lets us extend the check later.

https://bugzilla.gnome.org/show_bug.cgi?id=687842
2012-11-09 10:08:22 +01:00
Alexander Larsson c94002f8c0 Add "parent widget" button to test property editor
Without this its hard to access the properties of container
widgets.

https://bugzilla.gnome.org/show_bug.cgi?id=687842
2012-11-09 10:08:22 +01:00
Jasper St. Pierre f4438a1ffc gtkbin: Remove the silliest code on earth
What is this bin doing with all these crazy deltas? Company does:

<Company> that can safely be removed
<Company> in general, code that isn't obvious can either be understood
<Company> with a bit of thinking or it can be removed
<Company> if in doubt, go for the 2nd of those :)

Most GtkBin subclasses override this strange garbage anyway, so it's
not like this code is ever *run*, per se. Just make it proxy directly
to the child, and hope nothing goes wrong.
2012-11-08 19:19:53 -05:00
Jasper St. Pierre 3563d11fc6 gtkbin: Complete more of a base implementation for GtkBin subclasses
Implement get_preferred_width, get_preferred_height, and size_allocate.
This allows GtkBin subclasses to be quick and easy, without the
author doing the subclassing to have to do much work.
2012-11-08 19:19:46 -05:00
Jasper St. Pierre 7b950944b0 gtkversion.h.in: Put the documentation inside the header guards
This fixes a warning with gobject-introspecion scanning
2012-11-08 19:19:00 -05:00
Benjamin Otte ffeef28dbc reftests: Add test for recent fix 2012-11-08 23:34:30 +01:00
Benjamin Otte 0d9a45d460 label: Fix another sizing corner case causing segfaults
If the "wider" label is the smaller one, use the wider size for both
cases. This can happen when ellipsizing a single character, which is
often smaller than the ellipsizing glpyph(s).
2012-11-08 23:34:30 +01:00
Benjamin Otte 947fed0961 stylecontext: Fix a memleak 2012-11-08 23:34:30 +01:00
Benjamin Otte ba88174614 stylecontext: Remove unused function 2012-11-08 23:34:29 +01:00
Benjamin Otte 598f86eaf3 cssvalue: Convert shadows to GtkCssColorValue 2012-11-08 23:34:29 +01:00
Benjamin Otte 3cb6ae3df3 cssimage: Use GtkCssColorValue 2012-11-08 23:34:29 +01:00
Benjamin Otte bd31bd6d63 cssstyleproperty: Replace symbolic colors with GtkCssColorValue 2012-11-08 23:34:29 +01:00
Benjamin Otte e3f407a71d cssvalue: Add GtkCssColorValue
This is mostly copy/paste from GtkSymbolicColor and is indeed intended
to replace it.
2012-11-08 23:34:06 +01:00
Benjamin Otte 1a213679bd symboliccolor: Change the print output
Functions should not have a space before the opening parenthesis. So
change output like
  alpha (@color, 0.5)
to
  alpha(@color, 0.5)
and do the same for "shade" and "mix".

Tests have been updated accordingly.
2012-11-08 23:34:06 +01:00
Benjamin Otte e063a0fdf1 symboliccolor: Split out HSLA code 2012-11-08 23:34:05 +01:00
Matthias Clasen cff4718e91 Update a11y test results
These are expected changes, since a11y class name show up in the
dumps.
2012-11-07 20:21:50 -05:00
Matthias Clasen ffa42cb5bb Nuke GtkBoxAccessible
It didn't contain anything useful.
2012-11-07 20:17:30 -05:00
Cosimo Cecchi f9db800713 text-cell-accessible: fix a double unref
We're unreffing the GtkCellRenderer object twice, causing the
application to crash when trying to access the renderer later.

https://bugzilla.gnome.org/show_bug.cgi?id=687872
2012-11-07 15:46:16 -05:00
Cheng-Chia Tseng 178e072e8a Updated Traditional Chinese translation(Hong Kong and Taiwan) 2012-11-07 02:35:44 +08:00
Benjamin Otte b42a4e2276 gradient: Add color stops to the right gradient
This was causing an infinite loop happily eating up memory.

https://bugzilla.gnome.org/show_bug.cgi?id=687467
2012-11-06 21:29:58 +01:00
Benjamin Otte 5e59033eb3 tests: Include config.h 2012-11-06 21:29:58 +01:00
Benjamin Otte 58021c9e98 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.

Note that only glib allows use to easily do this, so nothing is done for
Pango, gdk-pixbuf or Cairo here.
2012-11-06 21:29:58 +01:00
Benjamin Otte e9dc0e391d cssimage: Fix huge memleak
When transitioning gradients, we were leaking the gradient structs. Not
good.

https://bugzilla.gnome.org/show_bug.cgi?id=687467
2012-11-06 18:04:10 +01:00
Cosimo Cecchi 9876fc4f17 css: Fix copy/paste error
Benjamin replaced start with end in a bunch of locations, but not all of
them apparently.
2012-11-06 18:04:10 +01:00
Piotr Drąg aa534812f5 Updated POTFILES.skip 2012-11-05 23:04:55 +01:00
Benjamin Otte 959bfbb66e reftests: Add a reftest for latest fix 2012-11-05 19:34:23 +01:00
Benjamin Otte debe81b1ea label: Handle crazy corner cases
With ellipsizing, the ellipsized text can have a smaller height than the
non-ellipsized text. So the wider text is also higher. Example:
  .<big>TEXT</big>
will ellipsize to the small text.

Reported-By: Rico Tzschichholz <ricotz@t-online.de>
2012-11-05 19:34:23 +01:00
Adorilson Bezerra cdadbb069f Fixed Brazilian Portuguese Translation 2012-11-05 12:12:32 -02:00
Matthias Clasen 9ebeb4e68a Bump GLib dependency to 2.35
And drop deprecated g_type_init() calls.
2012-11-04 13:01:38 -05:00
Benjamin Otte 8bdc2aa228 reftests: Add test for recent fix
This test checks the fix in a46368dede
2012-11-04 17:58:18 +01:00
Benjamin Otte 075667e927 reftests: Mark windows as popup
This makes the tests run faster and should always be done.
2012-11-04 17:58:06 +01:00
Stefano Facchini a46368dede sizerequest: do not derefence NULL pointers 2012-11-04 17:48:02 +01:00
Paolo Borelli 1beb9db7b0 gtkmenubutton: remove weak pointer when needed
We must make sure to remove the weak pointer when disposing the widget
or when resetting the align widget otherwise glib will try to nullify
invalid memory.
2012-11-04 17:12:14 +01:00
Paolo Borelli 5830363787 gtkmenubutton: set menu to NULL in dispose.
Prevent menu to be detached multiple times.
2012-11-04 17:12:14 +01:00
Benjamin Otte 7f870abf17 sizerequest: Restructure code
Make the compute_size_request() function take into account size groups
itself instead of doing a weird "bump_requisition" call.
2012-11-04 16:10:20 +01:00
Benjamin Otte 7501f9770f sizerequest: Move sizegroups function to different source file 2012-11-04 16:02:14 +01:00
Benjamin Otte 8bdff7a564 sizegroup: Construct the set of sizegroup peers as a hash table
This way we don't need a marker on GtkWidgetParivate that needs to be
unset later, so we have all our data in the same place and can avoid
problems with reentrancy and shenanigans like that.

But the main reason I wrote that is cleaner code.
2012-11-04 15:47:03 +01:00
Benjamin Otte 1ef057f983 reftests: Add a test from evolution
This was used in a bug report.

https://bugzilla.gnome.org/show_bug.cgi?id=677609
2012-11-04 15:28:43 +01:00
Benjamin Otte 756ebea036 reftests: Add a test for all the recent sizegroup hackery 2012-11-04 15:28:43 +01:00
Benjamin Otte dd6931d1ba sizegroup: Use _gtk_widget_compute_size_for_orientation()
With this function now available, we can do size computation in 2
ways:
(1) Compute size with size groups
(2) Compute size without size groups

And have (1) use (2) instead of setting flags on widgets. This patch
does exactly that.
2012-11-04 15:28:43 +01:00
Benjamin Otte c3148a81d2 sizerequest: Move optimization
With size groups now doing hfw, doing the optimization for CONSTANT_SIZE
was done too early. Size groups need to know that it's a hfw request, so
the other widgets in the size group get the correct behavior.
2012-11-04 15:28:43 +01:00
Benjamin Otte aba0c5cc3b label: Redo get_preferred_width/height()
This is important for size groups mostly, but also has some small fixes.
The label-sizing reftest as been updated accordingly.
2012-11-04 15:28:43 +01:00
Benjamin Otte f55fe7e20b label: Fix ellipsize and wrap being set
The label code assumed that Pango treats this as "wrap to as much space
as possible and then ellipsize all the lines", but for Pango, ellipsize
takes precedence over wrap. So do the same thing in GtkLabel.

Also updated is the reftest that checked this behavior.
2012-11-04 15:28:43 +01:00
Benjamin Otte 035e55d1ab reftests: Improve reftest performance
Get rid of all the event boxes in this test. Event boxes need GDK
windows which cost a lot of performance when running the test and they
clip the label output.

Getting rid of the clipping also shows 2 bugs in this test that weren't
visible before. Those will be fixed in a followup patch.
2012-11-04 15:28:42 +01:00
Benjamin Otte f48b30c13a reftests: Make label-sizing tests use better CSS
ow that labels can have backgrounds, just use label backgrounds
2012-11-04 15:28:42 +01:00
Benjamin Otte 02bc589583 sizerequest: Export _gtk_widget_compute_size_for_orientation()
and add an "ignore_size_groups" flag to it. This way we can use it for
size group shenanigans.
2012-11-04 15:24:18 +01:00
Benjamin Otte 1d6e896fef sizegroup: Move GtkSizeGroupMode to gtkenums.h
This is in preparation for the next patch, which would otherwise lead to
conflicts.
2012-11-04 15:24:18 +01:00
Benjamin Otte 62f5414742 sizerequest: Cache sizes without size groups
We compute on-demand for size groups anyway, so we can (in theory, this
patch doesn't do that yet) get around costly cache blowing when
invalidating single widgets of a size group this way.
2012-11-04 15:24:17 +01:00
Benjamin Otte be1bde9111 sizegroups: Use is_visible() instead of get_mapped() for visibility
The current approach of using gtk_widget_get_mapped() is broken:
The usual steps taken when showing a window are:
(1) request the sizes
(2) allocate the sizes
(3) show the window in the allocated size

Showing the window with a random size between steps (1) and (2) would of
course
result in extra work and potential flickering when the widgets get
resized to
their proper sizes.

However, as GtkSizeGroup::ignore-hidden uses gtk_widget_get_mapped() to
determine visibility for a widget, the following will happen:
(1) the widget will request a 0 size
(2) the widget will be allocated a 0 size
(3) the widget will be too small when it is shown

gtk_widget_get_visible() however is set in advance. Note that toggling
visibility also causes a gtk-widget_queue_resize() call already so we
take care of changes in here automatically.
2012-11-04 15:24:17 +01:00
Benjamin Otte 48ff2fc7ed API: Add gtk_widget_is_visible()
This is a recursive gtk_widget_get_visible(): Returns TRUE if the widget
and all its parents are visible.
2012-11-04 15:24:17 +01:00
Benjamin Otte 9f6067a804 sizegroup: Handle hfw in size groups 2012-11-04 15:24:17 +01:00
Benjamin Otte c8f2328337 sizegroup: Add a function for clarity
... and restructure code to accomodate that function.
2012-11-04 15:24:17 +01:00
Benjamin Otte dbbdefe4e0 sizegroup: Don't keep groups around everywhere
The code is only interested in the actual widgets that belong together,
not in the groups. So just don't return the groups.
2012-11-04 15:24:17 +01:00
Benjamin Otte dfea266e1f sizegroup: Check ignore_hidden flag when adding groups
Instead of only checking the ignore_hidden flag when getting the
preferred sizes, respect it already when constructing the list of
widgets. This way, widgets don't queue resizes for groups they're
ignored in anyway.
2012-11-04 15:24:17 +01:00
Benjamin Otte a1f6887f17 sizegroup: Use for loops
For loops to loop over lists look nicer and actually do the right thing
with "break" and "continue" statements. So they are vastly preferred to
while loops.
2012-11-04 15:24:17 +01:00
Benjamin Otte 8796fe6d1c sizegroups: Restructure code
This way, we do the checks at the start of the effected function, not
before calling it.
2012-11-04 15:24:16 +01:00
Benjamin Otte 8710d97945 sizegroup: Don't cache the sizes anymore
This simplifies code and because sizes are cached by the widgets
themselves, it's not a large performance problem (unless people use huge
amounts of widgets in a single size group, but who does that?
2012-11-04 15:24:16 +01:00
Federico Mena Quintero 9c6e560819 Merge branch 'bgo687196-filesystemmodel-crash' 2012-11-02 14:13:02 -06:00
Federico Mena Quintero ea3a750f13 bgo#687196 - Fix model corruption during file removal
The main problem is that we were emitting the row-deleted signal for the model in the middle
of the process that actually deletes the row from the model (remove the row from the array,
update the model->file_lookup hash table, etc.).  In the model's caller, one of the row-deleted
callbacks was requesting an iter, which caused the model to revalidate itself - but it did
this while it was in an inconsistent state.  This led to an assertion failure later when the
model resorted itself.

The fix in remove_file() is like this:

* The filteredness/visibility of the deleted node is not updated.  The
  node will simply be gone; we don't need to update those values at
  all.

* We invalidate just the node that is being deleted.

* The model->file_lookup hash table is not completely nuked; instead,
  we carefully adjust its indices.

* The row-deleted signal is only emitted at the very end, when
  deletion is complete and the model is consistent.

Many thanks to William Hua for doing the detective work on this bug!

Signed-off-by: Federico Mena Quintero <federico@gnome.org>
2012-11-02 14:09:01 -06:00
Federico Mena Quintero 94e3d7faf1 Make freeze_updates() and thaw_updates() static functions
They were in the semi-public API of GtkFileSystemModel, but never actually used outside of it.

Signed-off-by: Federico Mena Quintero <federico@gnome.org>
2012-11-01 17:21:47 -06:00
Federico Mena Quintero 1cee5ff0dd Comments on how the filtering and sorting processes work
Signed-off-by: Federico Mena Quintero <federico@gnome.org>
2012-11-01 17:19:10 -06:00
Benjamin Otte 0306278145 sizegroup: Always at least use widget's size
When widgets were hidden, they were otherwise assigned a 0 size.
2012-11-01 20:22:35 +01:00
Benjamin Otte 4067a45aff settings: Reset all styles when the enable-animations settings changes
https://bugzilla.gnome.org/show_bug.cgi?id=686021
2012-11-01 12:27:31 +01:00
Benjamin Otte 625f8a6dd3 Raleigh: Fix spinners with disabled animations
When animations are disabled, active and inactive spinners should look
different.

https://bugzilla.gnome.org/show_bug.cgi?id=686021
2012-11-01 12:27:31 +01:00
Benjamin Otte 0bfbf39306 cssimage: Implement some equal functions 2012-11-01 12:27:31 +01:00
Federico Mena Quintero f39f574914 Remove argument to _gtk_file_system_model_update_file() that should not be part of the internal API
Signed-off-by: Federico Mena Quintero <federico@gnome.org>
2012-10-31 20:54:02 -06:00
Federico Mena Quintero 281c592ea9 Rename gtk_tree_path_new_from_node() to tree_path_new_from_node()
This is a function internal to the file system model; let's not pollute the gtk_tree_path namespace.

Also, make the 'i' variable into 'r' as it refers to a row index, not a file-array index (for
consistency with the docs and the rest of the code).

Signed-off-by: Federico Mena Quintero <federico@gnome.org>
2012-10-31 20:21:47 -06:00
Cosimo Cecchi 86ecf54139 icon-theme: support loading symbolic GFileIcons from generic URIs
Right now we support loading and recoloring symbolic GFileIcons, but
only if the underlying GFile has a local path. This breaks when the
GFileIcon is loaded from a GResource, which is a reasonable option for an
application that wants to ship a custom symbolic icon.

This patch changes GtkIconInfo to store a GFile together with the file
path, and changes the symbolic icon lookup code to use the GFile URI,
which transparently makes the code work also for GResources.

https://bugzilla.gnome.org/show_bug.cgi?id=687059
2012-10-31 11:53:50 -04:00
Benjamin Otte 2e287576b4 themingbackground: Remove struct members
... and put them in the only function they are used in.
2012-10-31 11:09:12 +01:00
Benjamin Otte 762e2d9322 reftests: Add reftest for fractional border sizes 2012-10-31 11:09:12 +01:00
Benjamin Otte fd73c1f8d9 themingengine: Draw fradctional border sizes 2012-10-31 11:09:12 +01:00
Benjamin Otte 1e08fe8646 reftests: Fix linear-gradient reftest
... and add it to the Makefile
2012-10-31 11:09:12 +01:00
Benjamin Otte 6821a8f7b2 themingbackground: Remove GtkThemingBackgroundLayer
The struct was just the index. So just pass the index around instead of
a full struct.
2012-10-31 11:09:11 +01:00
Benjamin Otte 5e7949c47b themingbackground: Use get_box() for background image size 2012-10-31 11:09:11 +01:00
Benjamin Otte ba96c34787 themingbackground: Introduce gtk_theming_background_get_box()
to query the different clip boxes used by the background drawing code.
Use this function to query these boxes when clipping.
2012-10-31 11:09:11 +01:00
Benjamin Otte 12dec5279e themingbackground: Add content_box variable
... to go with border_box and padding_box.
2012-10-31 11:09:11 +01:00
Benjamin Otte e9dbfc0e06 themingbackground: Get rid of flags variable 2012-10-31 11:09:11 +01:00
Benjamin Otte 0ccb7db245 themingbackground: Move image variable
... from the Layer struct onto the stack of the only function using it.
2012-10-31 11:09:11 +01:00
Benjamin Otte ccaf1c2c67 themingbackground: Restructure code some more
Move variable initialization outside the first code with side effects.
This allows adding some more early returns, including one for code that
used to trigger g_return_if_fail() in certain corner cases.
2012-10-31 11:09:11 +01:00
Benjamin Otte ce56248930 themingbackground: Restructure code
Make if statements encompassing the whole function into early returns.
The rest of the diff is reindenting.
2012-10-31 11:09:11 +01:00
Benjamin Otte 016647edb1 cssimage: Add a warning for drawing empty images
width and height of an image must be > 0 for the image to get drawn.
It's up to the code further up to ensure that this is not happening.
2012-10-31 11:09:10 +01:00
Benjamin Otte a68e76e058 reftests: Add a reftest for recent commit
Check that a computed background-size of 0 is treated as 0.
2012-10-31 11:09:10 +01:00
Benjamin Otte 67302c5ee0 cssvalue: Compute "background-size: 0 0" properly
Previously a computed value of 0 was treated as "auto", which is wrong.
2012-10-31 11:09:10 +01:00
Benjamin Otte 16677bb85a stylecontext: Don't use bg image in gtk_style_context_set_background()
Old code tried to use the "background-image" proeprty for setting the
default image background. While this used to work in the early days of
GTK3, today it is grossly misleading as the backgronud image may be
resized, repositioned and semi-translucent which causes very weird
artifacts when rendering.

So we use the background-color only instead.
2012-10-31 11:09:10 +01:00
Benjamin Otte c13efbf8b0 cssimage: Add an equal vfunc
No implementations for it exist yet.
2012-10-31 11:09:10 +01:00
Benjamin Otte 73fe9a2acf menuitem: Draw background unconditionally 2012-10-31 11:09:10 +01:00
Benjamin Otte b1ad5c8abc settings: Use _gtk_css_provider_load_named()
This way we create one provider per settings object instead of stuffing
it into a global unchanging never-deleting hash table.
Also, we now reload the theme when instructed instead of keeping the old
loaded (and possibly stale) data forever.

https://bugzilla.gnome.org/show_bug.cgi?id=683896
2012-10-31 11:09:10 +01:00
Benjamin Otte b41215bdea cssprovider: Move fallback code into _gtk_css_provider_load_named()
This makes sure the full theme loading logic resides in one function and
isn't scattered around.

As a side-effect, the hash table kept by gtk_css_provider_get_named()
will now be populated with fallback themes. This will not be a problem
after the next commit though.
2012-10-31 11:09:09 +01:00
Benjamin Otte 738b453c66 cssprovider: Export gtk_css_provider_load_named) function
... and document it.
For now, the function is only exported internally.
2012-10-31 11:09:09 +01:00
Benjamin Otte 9c9d82f1a9 cssprovider: Split out theme loading function
Split maintaining the global themes hash table and the theme loading
code into two functions.
This also fixes leaking the provider when loading a theme from a builtin
resource.
2012-10-31 11:09:09 +01:00
Fran Diéguez bae55eaa80 Updated Galician translations 2012-10-31 10:52:47 +01:00
Sandeep Sheshrao Shedmake beb02a5b4b Updated Marathi Translations 2012-10-31 10:39:01 +05:30
Wolfgang Stoeggl 840855d401 Updated German translation 2012-10-30 19:45:59 +01:00
Mattias Põldaru c9d035bde3 [l10n] Updated Estonian translation 2012-10-30 15:38:09 +02:00
Matej Urbančič 128437cc76 Updated Slovenian translation 2012-10-29 22:33:43 +01:00
Aurimas Černius e903ff8f86 Updated Lithuanian translation 2012-10-29 22:07:22 +02:00
Ran Benita 21cf5a7e00 wayland: update to work with stable libxkbcommon
libxkbcommon has had some changes to its API. However, it now has a
stable release (0.2.0), so this makes the necessary changes, and
replaces all uses of the deprecated API.

Signed-off-by: Ran Benita <ran234@gmail.com>
2012-10-29 15:45:31 +00:00
Daniel Mustieles 3338f6cb5b Updated Spanish translation 2012-10-29 13:07:29 +01:00
Andika Triwidada 249d2a8030 Updated Indonesian translation 2012-10-29 18:45:22 +07:00
Sweta Kothari dc85125737 Updated gujarati file 2012-10-29 16:28:55 +05:30
Мирослав Николић 11825afc3e Updated Serbian translation 2012-10-29 11:48:33 +01:00
Hib Eris 99e194e7cc Fix compiling for win32
https://bugzilla.gnome.org/show_bug.cgi?id=687066
2012-10-29 09:36:41 +01:00
Carlos Garnacho 63c75a2384 texthandles: Add an extra style class to the cursor-mode handle
Themes may want to render handles differently depending on whether
the widget is in selection mode (2 handles enclosing a selection) or
cursor mode (one handle pointing out the insertion cursor).
2012-10-26 18:38:38 +02:00
Carlos Garnacho 0eb09ac0f2 texthandles: set input shape on handles' window
This improves both interaction and theming, as it allows
arbitrary handle shapes while just being draggable from
the visible areas.

This way themes can set up handles with the hotspot visually
displaced from the horizontal center, as long as the hotspot
lies centered in the image/svg asset.
2012-10-26 18:35:24 +02:00
Carlos Garnacho f6952ceb82 texthandle: Fix shape setup on non-composited environments
The check on the handle to be drawn on the mask was based on the yet to
be set priv->windows pointers, pass explicitly the handle position to
have the shape correctly initialized on non-composited environments
2012-10-26 17:46:40 +02:00
Nilamdyuti Goswami 237e984a52 Assamese translation updatedas.po 2012-10-26 14:23:33 +05:30
John Ralls 41f29032d2 Fix typo from f2ab3af 2012-10-25 10:58:56 -07:00
Rūdolfs Mazurs 019bb37dd3 Updated Latvian translation 2012-10-24 15:14:37 +03:00
Kristian Høgsberg ca0662dba4 configure.ac: Look for wayland-client 1.0.0 2012-10-23 22:37:02 -04:00
Matthias Clasen 5aff66f391 Add GDK_VERSION_3_8
This macro is needed for the new AVAILABLE_IN and DEPRECATED_IN
macros.
2012-10-23 17:36:17 -04:00
Tom Tryfonidis 6245362a52 Updated Greek translation 2012-10-23 19:54:51 +03:00
Matthias Clasen 2b7ebd93f2 Bump version 2012-10-22 20:45:25 -04:00
Matthias Clasen b5495cd7da 3.7.0 2012-10-22 20:44:24 -04:00
Matthias Clasen bec6b260b4 Be robust against unrealized windows in GtkWindowAccessible
Based on a patch by Albert Astals Cid,
https://bugzilla.gnome.org/show_bug.cgi?id=686152
2012-10-22 19:42:41 -04:00
Matthias Clasen c51157d437 Forgotten fixup
This was meant to be included in the previous commit :-(
2012-10-22 19:41:14 -04:00
Stefano Facchini 4e42bd055d treeview: Add support for styling the dragged header
https://bugzilla.gnome.org/show_bug.cgi?id=684980
2012-10-22 19:05:00 -04:00
Stefano Facchini f67273c579 treeview: Move the dragged header in the headers window
https://bugzilla.gnome.org/show_bug.cgi?id=684980
2012-10-22 19:04:12 -04:00
Matthias Clasen 5a497e9fb8 Use named union for _GtkSymbolicColor in gtk/gtksymboliccolor.c
Patch by Richard Lloyd,
https://bugzilla.gnome.org/show_bug.cgi?id=686366
2012-10-22 18:59:42 -04:00
Cosimo Cecchi 288ed1f920 scrollbar: remove unused variable
My bad.
2012-10-22 18:41:00 -04:00
Cosimo Cecchi 852d4d618c notebook: return TRUE for drag-motion event when over tabs
The GtkNotebook drag-motion event handler may install a timeout when
hovering over a tab, in order to switch to it.
On the other hand it's desirable for applications to use the empty tab
area as a drop target, so the drag-motion handler returns FALSE
(also in case it installs the switch tab timeout), as explained in
https://bugzilla.gnome.org/show_bug.cgi?id=350665.

Unfortunately, applications can use the tab label widget (or a child
of it) as a different drop target area, and install their own
drag-motion handler there.
In this scenario, the timeout will still be installed by GtkNotebook's
handler, but since it returns FALSE, it will never get the matching
drag-leave event, causing it to trigger also when the mouse pointer
moved elsewhere before it expired.

Fix this by returning TRUE from drag-motion when the event is over a
tab. Note that this makes automatic tab switching not work anymore when
drag and drop is handled in the tab label widget; applications are
expected to also handle tab switching if desired in such a case.

https://bugzilla.gnome.org/show_bug.cgi?id=684415
2012-10-22 18:39:37 -04:00
Cosimo Cecchi 42da600eb1 notebook: consolidate code to remove the switch tab timer
https://bugzilla.gnome.org/show_bug.cgi?id=684415
2012-10-22 18:37:47 -04:00
Mattias Põldaru 67fec32d27 [l10n] Updated Estonian translation 2012-10-22 22:01:01 +03:00
Cosimo Cecchi ad22a1faf6 scale: update style properties on GtkRange at init
Same fix as in ef027c93d4, but for
the GtkScale subclass of GtkRange.

https://bugzilla.gnome.org/show_bug.cgi?id=686280
2012-10-22 13:13:11 -04:00
Cosimo Cecchi ef027c93d4 scrollbar: update style properties on GtkRange at init
GtkScrollbar used to rely on style-updated being emitted every time
after the widget was created in order to set the right values from its
style properties on GtkRange.
Nowadays we try to be smarter and avoid emitting style-updated at
creation time, so we need to manually initialize the GtkRange values.

This fixes a regression from 35e36b9fe5.

https://bugzilla.gnome.org/show_bug.cgi?id=686280
2012-10-22 11:48:04 -04:00
Jean Parpaillon 247bc3ad69 Fix out of source tree building for gdk/broadway
This patch fix compilation when building out of source tree (gdk/broadway dir).

Signed-off-by: Colin Walters <walters@verbum.org>
2012-10-22 11:30:37 -04:00
Pavol Šimo aa81b0db2c Updated Slovak translation 2012-10-20 19:46:03 +01:00
Fran Diéguez c2032dec6d Updated Galician translations 2012-10-20 13:09:24 +02:00
Tim-Philipp Müller f8c81ad788 docs: fix typo on 'Getting Started with Gtk+' page 2012-10-20 11:25:02 +01:00
Aurimas Černius 488e124f6a Updated Lithuanian translation 2012-10-19 20:45:59 +03:00
Petr Kovar f0a211a1df Update Czech translation 2012-10-19 13:26:21 +02:00
Scott Moreau e5b88f1bdd wayland: Update to reflect protocol changes 2012-10-19 12:21:35 +01:00
Fran Diéguez 7151b1a28a Update Galician translations 2012-10-18 10:53:55 +02:00
Matej Urbančič f75498d8e1 Updated Slovenian translation 2012-10-18 08:16:39 +02:00
Matthias Clasen eda0d9ba10 Fix duplicate columns in filechooser entry completion
This partically reverts commit
331bba1ad6, which broke documented
behaviour.
2012-10-17 21:27:26 -04:00
Cosimo Cecchi 15fe3038be menubutton: don't refer to the non-existant menu property
7c6454246e removed the property, but
forgot to change the name in a g_object_notify().
2012-10-17 17:05:22 -04:00
Мирослав Николић 9d1b576af6 Updated Serbian translation 2012-10-17 22:24:36 +02:00
Andika Triwidada 2ad31feaaa Updated Indonesian translation 2012-10-17 23:53:50 +07:00
Daniel Mustieles 2216a6f658 Updated Spanish translation 2012-10-17 18:05:57 +02:00
Stefano Facchini fa2ed6b8a2 level-bar: Fix typo 2012-10-17 16:09:22 +02:00
Cosimo Cecchi 4c9db15212 scrolledwindow: set GDK_EXPOSURE_MASK on the overshoot window
Currently we use gtk_style_context_set_background() when the state flags
change in order to propagate the background color to the overshoot
window, but this is actually only needed because the window doesn't get
expose events, since we always draw a full background in draw().
This also fixes some problems when the GdkWindow of the scrolled
window's child is composited, as seen in oxygen-gtk3.

https://bugzilla.gnome.org/show_bug.cgi?id=686265
2012-10-17 09:56:49 -04:00
Stefano Facchini 5e55bf1d53 level-bar: add support for RTL locales
https://bugzilla.gnome.org/show_bug.cgi?id=684288
2012-10-17 14:12:57 +02:00
Stefano Facchini e5de18cbf9 level-bar: add an "inverted" property like GtkProgressBar
https://bugzilla.gnome.org/show_bug.cgi?id=684288
2012-10-17 14:12:57 +02:00
Stefano Facchini 0f36b16733 Add gdk version macros for 3.8
https://bugzilla.gnome.org/show_bug.cgi?id=684288
2012-10-17 14:12:57 +02:00
Ignacio Casal Quinteiro 7c6454246e GtkMenuButton: remove menu property as it is replaced by popup.
See that it was already announced to be removed before 3.6.0
but we forgot.
2012-10-17 14:07:31 +02:00
Cosimo Cecchi a021b72c71 cssshadowsvalue: handle gtk_css_value_transition returning NULL
The implementation of transition for GtkCssShadowValue can return NULL
at least when the two values have a different inset; all other parts of
the GTK/CSS machinery (e.g. GtkCssArrayValue) handle this by returning
NULL too. Instead, GtkCssShadowsValue was returning an invalid value,
where "len" was set, but some values in the array were NULL, which would
lead to a segfault when this value is later evaluated by the compute
function.

Fix this by making GtkCssShadowsValue return NULL if a shadow transition
fails, like GtkCssArrayValue does.

https://bugzilla.gnome.org/show_bug.cgi?id=686013
2012-10-16 14:22:24 -04:00
Cosimo Cecchi 6b3416a2d7 reftests: fix the linear-gradient reftest
Don't use a repeating linear gradient, since it can't be easily
reftested against a non-repeating one for the reasons described in the
test header.
Instead, add a separate test for repeating gradients (against another
repeating gradient).

This makes the test pass, so it can be added to the Makefile now.
2012-10-16 13:12:00 -04:00
Cosimo Cecchi 17760bd2eb cssshadow: plug a cairo_surface_t leak
We were never destroying the cairo surface we use for blurring, which
would lead to a huge leak.

https://bugzilla.gnome.org/show_bug.cgi?id=686209
2012-10-16 13:07:51 -04:00
Cosimo Cecchi 97f49c681b csskeyframes: unref GtkCssValues when free-ing
We assume a reference to all the GtkCssValues we store, so we need to
release it when free-ing.
2012-10-16 13:07:51 -04:00
Cosimo Cecchi 6fb66261ca gradient: plug a GtkCssValue refleak
Since _gtk_symbolic_color_resolve_full() returns a reference to a
GtkCssValue.
2012-10-16 13:07:51 -04:00
Cosimo Cecchi 3b7e390484 csscomputedvalues: plug a refleak
_gtk_css_keyframes_compute() returns a reference to a GtkCssKeyframes,
and _gtk_css_animation_new() takes another reference.
2012-10-16 13:07:50 -04:00
234 changed files with 27709 additions and 22104 deletions
+87
View File
@@ -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
=================================
+1 -1
View File
@@ -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>
+1 -1
View File
@@ -41,7 +41,7 @@ copy ..\..\..\gdk\gdkconfig.h.win32 ..\..\..\gdk\gdkconfig.h&#x0D;&#x0A;
/>
<UserMacro
Name="GtkBinaryVersion"
Value="2.10.0"
Value="3.0.0"
/>
<UserMacro
Name="GtkDummyPrefix"
+18 -6
View File
@@ -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"
+1 -1
View File
@@ -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
+4
View File
@@ -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
-2
View File
@@ -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 (),
-2
View File
@@ -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,
-2
View File
@@ -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,
+2 -2
View File
@@ -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
-2
View File
@@ -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 ();
}
+24
View File
@@ -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
View File
@@ -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);
+40
View File
@@ -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
+1
View File
@@ -23,6 +23,7 @@
@interface GdkQuartzNSWindow : NSWindow {
BOOL inMove;
BOOL inShowOrHide;
BOOL initialPositionKnown;
/* Manually triggered move/resize (not by the window manager) */
BOOL inManualMove;
-9
View File
@@ -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
+86 -51
View File
@@ -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;
+1 -1
View File
@@ -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 },
-1
View File
@@ -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 */
+39 -16
View File
@@ -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];
}
+10 -14
View File
@@ -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);
+21 -16
View File
@@ -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, &registry_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
+1
View File
@@ -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;
+1 -1
View File
@@ -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 *
+4 -27
View File
@@ -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;
}
}
+2 -2
View File
@@ -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);
-1
View File
@@ -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);
+1
View File
@@ -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);
+6
View File
@@ -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 \
-2
View File
@@ -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 \
-45
View File
@@ -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)
{
}
-52
View File
@@ -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__ */
+527
View File
@@ -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));
}
+1 -1
View File
@@ -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,
+3 -3
View File
@@ -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);
-1
View File
@@ -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", &gtk_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);
+14 -5
View File
@@ -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;
+12
View File
@@ -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
View File
@@ -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. */
+3
View File
@@ -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
+1 -1
View File
@@ -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.
*
+3 -4
View File
@@ -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
View File
@@ -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:
+3 -3
View File
@@ -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;
}
+7 -7
View File
@@ -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));
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -261,16 +261,33 @@ _gtk_css_bg_size_value_compute_size (const GtkCssValue *value,
g_return_if_fail (value->class == &GTK_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);
}
}
}
+848
View File
@@ -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, &GTK_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, &GTK_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 == &GTK_CSS_VALUE_COLOR, NULL);
value = _gtk_css_value_new (GtkCssValue, &GTK_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 == &GTK_CSS_VALUE_COLOR, NULL);
value = _gtk_css_value_new (GtkCssValue, &GTK_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 == &GTK_CSS_VALUE_COLOR, NULL);
g_return_val_if_fail (color2->class == &GTK_CSS_VALUE_COLOR, NULL);
value = _gtk_css_value_new (GtkCssValue, &GTK_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, &GTK_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 = { &GTK_CSS_VALUE_COLOR, 1, COLOR_TYPE_CURRENT_COLOR, NULL, };
return _gtk_css_value_ref (&current_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;
}
+49
View File
@@ -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__ */
+19
View File
@@ -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;
}
+2
View File
@@ -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,
+33
View File
@@ -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);
+13
View File
@@ -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;
+4 -4
View File
@@ -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
View File
@@ -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;
+5
View File
@@ -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,
+1 -1
View File
@@ -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
View File
@@ -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)
-19
View File
@@ -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)
+19 -1
View File
@@ -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
View File
@@ -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;
}
+4
View File
@@ -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
View File
@@ -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 (&GTK_CSS_SELECTOR_PSEUDOCLASS_STATE,
selector,
GUINT_TO_POINTER (pseudo_classes[i].state_flag));
{
/* Piggy back on previous pseudoclass if any */
if (selector && selector->class == &GTK_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 (&GTK_CSS_SELECTOR_PSEUDOCLASS_STATE,
selector,
GUINT_TO_POINTER (pseudo_classes[i].state_flag));
}
else
selector = gtk_css_selector_new (&GTK_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 == &GTK_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 == &GTK_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 == &GTK_CSS_SELECTOR_CLASS)
if (GPOINTER_TO_UINT (selector->data) == class)
return TRUE;
}
return FALSE;
}
+5
View File
@@ -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
View File
@@ -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
+4 -5
View File
@@ -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;
}
+5 -5
View File
@@ -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)));
+9 -32
View File
@@ -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,
+3 -2
View File
@@ -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)
+3
View File
@@ -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");
}
/**
+1 -2
View File
@@ -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:
+17
View File
@@ -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
+12 -3
View File
@@ -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);
+1
View 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
View File
@@ -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;
+1 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
}
+47
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
{
+4 -6
View File
@@ -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
View File
@@ -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, &current, 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, &current, 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
-17
View File
@@ -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
View File
@@ -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);
}
/**
+176
View File
@@ -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;
}
+84
View File
@@ -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