Compare commits

..

181 Commits

Author SHA1 Message Date
Matthias Clasen 39c8db124d Don't show cursor handles without a cursor
A non-editable textview may or may not have a cursor.
Take that into account when showing handles.
2012-09-02 19:56:28 -04:00
Carlos Garnacho 1c11f6ed1a entry: switch handles correctly on rtl
MIN/MAX of pixel values don't cut it, so compare
selection/cursor indexes.
2012-09-02 23:38:14 +02:00
Matthias Clasen 291ff93a6b Fix calculation of selection_bound location
_gtk_entry_get_selection_bound_location was not converting
priv->selection_bound to an index before feeding it to pango.
This was showing up as wrong handle positions when dragging
selections in password entries.
2012-09-02 17:15:18 -04:00
Matthias Clasen ccc4f0f133 Ignore select_words when updating handle positions
This fixes problems where the handles can appear stuck when
double-click selecting and then dragging the handles.
2012-09-02 16:05:28 -04:00
Matthias Clasen eecd228493 Minor fix for handle updates
Use a position that matches the mode, when updating handles.
2012-09-02 15:55:46 -04:00
Matthias Clasen f69179b562 Remove an unused variable 2012-09-02 11:25:42 -04:00
Matthias Clasen b79946956b Correct some editability/sensitivity checks
I was getting touch handles when double-clicking with a mouse.
And I was not getting touch handles when clicking around in a
textview that is sensitive, but not editable.

Correct these checks: A editable text view can have a cursor
and selections, and when in touchscreen mode, we need to show
handles for them.
2012-09-02 11:25:32 -04:00
Carlos Garnacho 1b5615df75 entry: If a recompute is pending, wait before updating handles
This avoids redundant window visibility and position changes
2012-08-29 16:04:54 +02:00
Carlos Garnacho adce361ec5 textview: Unset handles when the buffer changes below these
On the situations where a different buffer is set, or the current
one is clobbered, the handles are unset. More effort could be indeed
done on setting those after the view has revalidated the contents
and the markers have valid coordinates again, although it's a bit of
a corner case.

Fixes the "hypertext" textview demo leaving handles at odd positions
after the buffer changed.
2012-08-27 17:18:21 +02:00
Carlos Garnacho 209e39ab8a textview: revert the code preventing initial backwards selection
With the handles being invariably set to the min/max selection positions,
it's no longer necessary to keep this invariant when starting a selection.

Note that dragging from the text handles themselves will still disallow
both handles from crossing.
2012-08-27 14:50:42 +02:00
Carlos Garnacho 3158630a68 entry: revert the code preventing initial backwards selection
With the handles being invariably set to the min/max selection positions,
it's no longer necessary to keep this invariant when starting a selection.

Note that dragging from the text handles themselves will still disallow
both handles from crossing.
2012-08-27 14:47:06 +02:00
Carlos Garnacho 2b02d97a93 textview: Update to new GtkTextHandlePosition values 2012-08-27 14:38:15 +02:00
Carlos Garnacho f194d499c3 entry: update to new GtkTextHandlePosition values 2012-08-27 14:37:17 +02:00
Carlos Garnacho 3fd45e0267 GtkTextHandle: change selection semantics to start/end
Given text widgets don't behave consitently wrt cursor/selection
bound, nor are really expected to do so, change GtkTextHandle
positions to represent selection start/end. Text widgets are
expected to match buffer iters/positions with handle positions.
2012-08-27 14:29:53 +02:00
Carlos Garnacho 2a537b5b8b textview: Optionally update handles on focus in
This is so toplevels being moved/resized don't leave a selection
with no possibility of being further manipulated
2012-08-24 19:13:31 +02:00
Carlos Garnacho 89e420b390 entry: Optionally update handles on focus in
This is so toplevels being moved/resized don't leave a selection
with no possibility of being further manipulated
2012-08-24 19:12:27 +02:00
Carlos Garnacho 426e8c8c97 entry: Don't unset handles' mode on text DnD 2012-08-24 18:30:51 +02:00
Carlos Garnacho 78a8782b13 text: Set up envvar to test touch features
The GTK_TEST_TOUCHSCREEN_FEATURES envvar is now checked in entries
and textviews to allow testing of text handles with other kinds of
devices.
2012-08-24 17:02:53 +02:00
Carlos Garnacho da8de20928 entry: Fix warnings on backwards touch selection from the last position
It shouldn't allow backwards selection, but still shouldn't go off bounds
trying to keep a minimum selection.
2012-08-24 17:02:52 +02:00
Carlos Garnacho 2eaabf5ad3 textview: Don't apply selection clamping on handle cursor mode 2012-08-24 17:02:52 +02:00
Carlos Garnacho e299dfa462 entry: Don't apply selection clamping on handle cursor mode 2012-08-24 17:02:51 +02:00
Carlos Garnacho edd21e61f2 scrolledwindow: don't capture events meant for non-child windows
GtkTextHandle creates temporary override redirect windows, but still
hook to the text widget for events, so those are effectively captured
by GtkScrolledWindow if a text widget is within it
2012-08-24 17:02:51 +02:00
Carlos Garnacho 80a89c5245 Implement touch text selection in GtkTextView
GtkTextHandle is used to indicate both the cursor position
and the selection bound, dragging the handles will modify
the selection and scroll if necessary.

Backwards text selection is also blocked for touch devices,
so the handles don't get inverted positions and possibly
obscure portions of the selected text.
2012-08-24 17:02:51 +02:00
Carlos Garnacho 739b6e1862 Implement touch text selection in GtkEntry
GtkTextHandle is used to indicate both the cursor position
and the selection bound, dragging the handles will modify
the selection and scroll if necessary.

Backwards text selection is also blocked for touch devices,
so the handles don't get inverted positions (This is more
important though on GtkTextView, as inverted handles may
obscure portions of the selected text, good for consistence
though)
2012-08-24 17:02:50 +02:00
Carlos Garnacho 03a7331c5c Add GtkTextHandle
This is a helper object to allow text widgets to implement
text selection on touch devices. It allows for both cursor
placement and text selection, displaying draggable handles
on/around the cursor and selection bound positions.
2012-08-24 17:02:50 +02:00
Daniel Mustieles b078b9af86 Updated Spanish translation 2012-08-23 17:42:22 +02:00
Alexander Larsson 29a42085c6 Remove gdk_window_flush_if_exposing as its not needed anymore
We no longer support modifying GdkWindow hierarchies during
expose events. This is not working anymore anyway as the
flush operation now does not push already rendered pixels
in the flushed window from the double buffer to the window.

https://bugzilla.gnome.org/show_bug.cgi?id=679144
2012-08-23 16:31:31 +02:00
Alexander Larsson e112cdacd4 Fix flashing in non-double-buffered widgets
Avoid copying back partially drawn double-buffer data
when flushing to avoid flicker. This means non double
buffered widgets must draw opaque pixels in its expose
handlers, and that you are not allowed to use direct
rendering (or modify GdkWindow pos/size/order) from
inside the expose handler of a double buffered widget.

See https://bugzilla.gnome.org/show_bug.cgi?id=679144 for more
details
2012-08-23 16:31:30 +02:00
Ryan Lortie 828a97d773 GtkWidget: fix insert_action_group(NULL)
gtk_widget_insert_action_group (widget, "foo", NULL) is valid, but
g_action_muxer_insert (muxer, "foo", NULL) is not.  Use
g_action_muxer_remove() for that case.
2012-08-23 08:18:11 -04:00
Alexander Larsson 820b0cafe0 gdkwindow.c: Fix up window debug code
Make this build and fully print clip regions.
2012-08-23 12:16:43 +02:00
Alexander Larsson 04811d9483 Avoid unnecessary window flushes
The code was calling _gdk_window_ref_cairo_surface in a few places
where the intent was not to read/write to the surface, but just look
at its type (to e.g. create a similar surface). This is bad, as that
operation causes a flush which may cause unnecessary work and/or
flashing. Instead we just get the impl surface in these cases.
2012-08-23 12:16:43 +02:00
Chao-Hsiung Liao 8946cd70e1 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2012-08-23 15:40:42 +08:00
Michael Natterer 78506bd604 quartz: add evil casting to make sure time wraps correctly on 32bit machines
get_time_from_ns_event(): apply patch from Michael Hutchinson which
makes sure the returned guint32 wraps correctly on 32 bit machines
when the uptime exceeds 2^32 ms.
2012-08-23 09:31:12 +02:00
Piotr Drąg e486fb8118 Updated Polish translation 2012-08-23 00:02:01 +02:00
John Ralls d6a559216f Protect pasteboard GtkTargetPair flag values from being out of range 2012-08-22 14:43:20 -07:00
John Ralls 2cb739a2d5 Implement gdk_quartz_keymap_lookup_key 2012-08-22 14:39:11 -07:00
John Ralls 398dc1cf27 Copy in annotations missing from gtkdnd-quartz and gtkclipboard-quartz 2012-08-22 14:39:11 -07:00
Alexandre Franke fc364e8a98 Update French translation 2012-08-22 16:22:06 +02:00
Alexandre Franke ae867568b8 Fix French translation 2012-08-22 15:37:11 +02:00
Kjartan Maraas 59d632c458 Updated Norwegian bokmål translation 2012-08-22 10:29:59 +02:00
Ryan Lortie 81e76746ff GtkActionHelper: two small fixups in _set_target_value()
First, ensure we always consume floating values, as documented.

Second (and more serious), don't try to query the action if the
action name is not set yet.  This will cause crashes...
2012-08-22 00:54:57 -04:00
Nguyễn Thái Ngọc Duy c5f1dede79 Updated Vietnamese translation 2012-08-22 09:02:05 +07:00
Nguyễn Thái Ngọc Duy 8c45c8b53c po/vi: imported from Damned Lies 2012-08-22 08:59:12 +07:00
William Jon McCann 515e211d0b Don't left align label in check buttons when they have no indicator
Because they should be normal buttons in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=681617
2012-08-21 07:09:14 -04:00
Cosimo Cecchi de3cfa6034 modelmenu: fix a GCC warning
This should not be a const string, since the caller is supposed to free
it.
2012-08-21 11:15:32 +02:00
Cosimo Cecchi 4e9f4fbc77 textview: fix a typo in method gtk-doc annotation
This was causing a warning from the introspection scanner.
2012-08-21 11:14:46 +02:00
Cosimo Cecchi f6079f6406 menubutton: use consistent parameter names
Or the introspection scanner will emit a warning.
2012-08-21 11:14:16 +02:00
Andika Triwidada 411321212b Updated Indonesian translation for Property Nicks 2012-08-21 12:22:06 +07:00
Dirgita 1ade42bf21 Updated Indonesian translation 2012-08-21 12:22:06 +07:00
Matthias Clasen c8b32350be Bump version 2012-08-21 00:50:07 -04:00
Matthias Clasen b2ec723262 3.5.12 2012-08-20 23:38:03 -04:00
Matthias Clasen 79eeb78c46 Fix the doc build 2012-08-20 23:38:03 -04:00
Matthias Clasen ed04b879c0 Fix exports for new symbols 2012-08-20 23:38:00 -04:00
Matthias Clasen 0101a735a3 Add documentation
Document the new API and properties, and their interaction with
existing properties.

https://bugzilla.gnome.org/show_bug.cgi?id=651244
2012-08-20 18:54:22 -04:00
Matthias Clasen 7d1c1a8d20 GtkTextView: Add input purpose and hints
Add input-purpose and input-hints properties and pass these through
to the GtkIMContext.

https://bugzilla.gnome.org/show_bug.cgi?id=651244
2012-08-20 18:54:22 -04:00
Matthias Clasen eaaee081b1 GtkEntry: Add input purpose and hints
Add input-purpose and input-hints properties to GtkEntry,
and pass these on to GtkIMContext.

https://bugzilla.gnome.org/show_bug.cgi?id=651244
2012-08-20 18:54:21 -04:00
Matthias Clasen 3cb4aa44b3 GtkIMContext: Add purpose and hints
Add input-purpose and input-hints properties to GtkIMContext.

https://bugzilla.gnome.org/show_bug.cgi?id=651244
2012-08-20 18:54:21 -04:00
Krzesimir Nowak 8a8c434737 enums: Add purpose enum and hints flags.
This commit adds two enumerations that will be used
to pass additional information to input methods, in
the subsequent commits.

https://bugzilla.gnome.org/show_bug.cgi?id=651244
2012-08-20 18:54:20 -04:00
Ryan Lortie 0244dc8017 GtkMenuButton: rename _set_menu() to _set_popup()
It's too close to the release so we'll keep _set_menu() around, but
deprecate it, pointing to the new API.  It will be removed (and the name
reused) before the 3.6.0 release.

https://bugzilla.gnome.org/show_bug.cgi?id=682235
2012-08-20 17:04:14 -04:00
Aurimas Černius fb6d4c2f3d Updated Lithuanian translation 2012-08-20 23:26:17 +03:00
Piotr Drąg 8cbdd527f3 Updated POTFILES.skip 2012-08-20 21:53:00 +02:00
Daniel Mustieles b53f8ce0c9 Updated Spanish translation 2012-08-20 20:05:05 +02:00
William Jon McCann c5c46a125e icon-view: emit selection-changed when changing the model
Only if there was a selection active.

https://bugzilla.gnome.org/show_bug.cgi?id=681613
2012-08-20 13:59:09 -04:00
Cosimo Cecchi a28e1a22a6 visuals: add a visual test for suggested-action buttons
And selection-mode toolbars.
2012-08-20 19:25:08 +02:00
Lars Uebernickel 710674720e gtkmodelmenu: add support for action namespaces
If a section or submenu item has a "action-namespace" attribute, the
action names of the created GtkModelMenuItems will be prefixed with that
namespace.  Namespaces can be cascaded.
2012-08-20 13:13:50 -04:00
Ryan Lortie 5634eb226f GtkApplicationWindow: drop GActionMuxer use
There are no remaining users of the GActionMuxer in GtkApplicationWindow
because they've all been ported over to using the one on GtkWidget (via
GtkActionHelper, for the most part).
2012-08-20 13:13:50 -04:00
Ryan Lortie 4dd7de2e68 Drop GSimpleActionObserver
The only place that this was being created was in GtkApplicationWindow
and the last commit dropped that code.
2012-08-20 13:13:49 -04:00
Ryan Lortie 315d43e8a9 Remove private appwindow observer creation API
There are no remaining users of the GtkApplicationWindow API to create
GSimpleActionObserver or to get the GActionObservable (ie: muxer) for
the appwindow.  Drop those APIs.
2012-08-20 13:13:49 -04:00
Lars Uebernickel 86d7c9d5b5 ApplicationWindow: setup accels with widget muxer
Use the muxer from GtkWidget to setup the accels rather than our own
local muxer (which will soon be removed).
2012-08-20 13:13:49 -04:00
Ryan Lortie fd9b7bbfac Remove #include for muxer from gtkapplication.c 2012-08-20 13:13:49 -04:00
William Hua fe48e077bd Action helper support in Mac OS menus. 2012-08-20 13:13:49 -04:00
Ryan Lortie dd45862a06 gtkmodelmenu: move to new action regime
Drop the explicit passing of GActionGroup into the GtkMenu(Bar)
constructors and operate from the action context instead.

With GtkMenuItem implementing GtkActionable, this turns out to be pretty
easy (and most of the code can be removed from GtkModelMenuItem,
including the GActionObserver implementation).
2012-08-20 13:13:49 -04:00
Ryan Lortie ea5a56dacf GtkMenuItem: implement GtkActionable
...using the new GtkActionHelper
2012-08-20 13:13:45 -04:00
Ryan Lortie 694be447e3 port GtkButton to GtkActionHelper 2012-08-20 13:11:02 -04:00
Ryan Lortie fbb38e95ac port GtkSwitch to GtkActionHelper 2012-08-20 13:11:01 -04:00
Lars Uebernickel ab3b41374a Add two users of gtk_widget_insert_action_group
Each GtkWindow with an associated GtkApplication should add this as
"app" to its action context.  Each GtkApplicationWindow is its own
GActionGroup, and it should add itself to itself with the prefix "win".

There is now some duplication here because we have the new GActionMuxer
hierarchy managed by GtkWidget, but GtkApplicationWindow still carries
its own muxer.  The redundancy will be removed in a future patch.
2012-08-20 13:11:01 -04:00
Ryan Lortie 652f16dd98 introduce private GtkActionHelper
The current process of implementing GActionObserver is annoying and the
GSimpleActionObserver interface leaves a lot to be desired.  Introduce a
new class, GtkActionHelper that gives you pretty much everything you'd
want to do as an implementor of GtkActionable.

The GtkActionHelper also features an "application" mode that is not
associated with a particular GtkWidget but rather with whatever widget
happens to be the active window of the given GtkApplication at a
particular point in time.  This will be useful for the Mac OS menubar.
2012-08-20 13:11:01 -04:00
Lars Uebernickel d30d56452c GtkWidget: Add gtk_widget_insert_action_group()
This allows adding a GActionGroup with a given name at an arbitrary
point in the widget tree.

This patch also adds an internal _get_action_muxer() API.  Calling this
will create a GActionMuxer associated with the widget.  The parent of
the muxer will be the muxer of the widget's conceptual parent.  For
non-menus, that is the normal parent.  For menus, it is the attach
widget.

In this way, we end up with a hierarchy of GActionMuxer that largely
reflects the hierarchy of GtkWidget, but only in places that the action
context has been requested.  These muxers are the ones on which the
inserted actions groups are installed.

A following patch will add a user of this API.
2012-08-20 13:09:04 -04:00
Ryan Lortie 2e57819477 GtkApplication: add 'active-window' property 2012-08-20 13:08:17 -04:00
Lars Uebernickel d1c458f9e1 GActionMuxer: add support for parent muxers
If a muxer does not contain an action group with the given prefix, chain
up to the "parent" muxer to look for it.

This initial implementation is rather inefficient.  It will lead to
changes on action groups associated with parent muxers being broadcast
to all children (regardless of if anybody there is interested or not).
An optimised version will follow soon.
2012-08-20 13:08:17 -04:00
Alexander Larsson 6b7eaf86ed GtkMountOperation: Return the right password_save
If the buttons were never sent we returned the wrong
default value (i.e. not what the UI displayed).
2012-08-20 17:07:54 +02:00
Emmanuele Bassi 78107b1a7d docs: Fix up the RadioButton example in the description 2012-08-20 11:03:17 +01:00
Duarte Loreto f3177aff04 Updated Portuguese translation 2012-08-19 23:40:49 +01:00
Duarte Loreto 3ab16d7b54 Updated Portuguese translation 2012-08-19 23:33:26 +01:00
Frédéric Péters 9399275089 doc: fix location of ATK documentation (GNOME bug 682193) 2012-08-19 19:07:22 +02:00
YunQiang Su 983a24cbcc fix an typo in zh_CN translation 2012-08-18 11:16:59 +08:00
Fran Diéguez 81222237c5 Updated Galician translations 2012-08-17 23:20:36 +02:00
Sandeep Sheshrao Shedmake 4fa2f7a52e Updated Marathi Translations 2012-08-17 14:45:54 +05:30
Sandeep Sheshrao Shedmake f26123277f Updated Marathi Translations 2012-08-17 14:34:04 +05:30
Мирослав Николић 6eef2de682 Updated Serbian translation 2012-08-17 10:34:24 +02:00
Fran Diéguez 21727b809c Updated Galician translations 2012-08-16 23:30:07 +02:00
Colin Walters 9ca355b460 GtkEntryAccessible: Remove unused variable 2012-08-16 10:37:05 -04:00
Daniel Mustieles 106be0c5c9 Updated Spanish translation 2012-08-16 16:10:50 +02:00
Chun-wei Fan 628892bce8 gtk/gtklevelbar.c: Fix build on non-C99 compilers
-Include fallback-c89.c for the usage of round(), where an implementation
 of round() is provided for compilers that don't have it
-Use g_ascii_strtod() instead of strtof as strtof() may not be universally
 available.
2012-08-16 13:42:13 +08:00
Chun-wei Fan c88a969d13 Update Visual C++ 2010 project files
-Turn on Whole Program Optimization for all Release builds.
-Disable Incremental Linking for all Release builds.
-Use MultiByte character set for all configurations for consistency.
2012-08-15 15:48:15 +08:00
Chun-wei Fan 72d11631db Update Visual C++ 2008 projects
-Enhance optimization by turning on WholeProgramOptimization for all
 Release builds
-Disable IncrementalLinking for all Release builds
-Make sure we are using MultiByte character set, to be consistent across
 the board for all configurations
2012-08-15 15:07:15 +08:00
Colin Walters 8ac04de2aa Fix _gtk_entry_get_borders() declaration
Regression introduced by https://bugzilla.gnome.org/show_bug.cgi?id=681591
2012-08-14 19:47:28 -04:00
David King 9d11da702b docs: Clarify GtkToggleButton action documentation
https://bugzilla.gnome.org/show_bug.cgi?id=373279
2012-08-14 12:43:39 +01:00
Stef Walter 094fcd6fb7 Allow building with CFLAGS=-Werror
Allow building using:

$ CFLAGS=-Werror sh autogen.sh --prefix=/xxx
2012-08-11 03:12:39 +09:00
William Jon McCann 374d48c37b Fix typo in documentation 2012-08-10 13:03:10 -04:00
Mario Sanchez Prada 45ecba2ea0 Update accessibility unit tests to consider password fields.
Updated test/a11y/entries.ui to include a new GtkEntry with
'visibility' set to FALSE, and update expectations.

https://bugzilla.gnome.org/show_bug.cgi?id=681591
2012-08-10 18:09:06 +02:00
Mario Sanchez Prada 63e2a0ff0c Expose the masked string for password fields to assistive technologies.
Call _gtk_entry_get_display_text()from gtkentryaccessible.c to make
sure we always consider the actual text being displayed when
implementing the functions from the AtkTet interface.

https://bugzilla.gnome.org/show_bug.cgi?id=681591
2012-08-10 18:09:06 +02:00
Mario Sanchez Prada 58a9244518 Export gtk_entry_get_display_text() as a private function through
gtkentryprivate.h, so we can use it from gtkentryaccessible.c

https://bugzilla.gnome.org/show_bug.cgi?id=681591
2012-08-10 18:09:06 +02:00
Nilamdyuti Goswami 66810c1e7f Assamese translation updated 2012-08-10 20:58:01 +05:30
Cosimo Cecchi 319bb2641b appchooserdialog: add a missing label mnemonic
https://bugzilla.gnome.org/show_bug.cgi?id=681577
2012-08-10 13:28:01 +02:00
Ryan Lortie 73bca14f74 po/eo.po: fix translations for GtkSwitch
Translating "ON" as "EK" (verb prefix for beginning of an action) and
"OFF" as "FOR" (away) is suboptimal.  Just use the suggested 1/0 glpyhs
instead.

The previous translator was clearly insane.
2012-08-09 22:48:31 -04:00
Nilamdyuti Goswami 08a7257349 Assamese translation updated 2012-08-08 21:00:11 +05:30
Nilamdyuti Goswami 9c43f671c1 Assamese translation updated 2012-08-08 18:12:14 +05:30
Nilamdyuti Goswami 3da26f5c2f Assamese translation updated 2012-08-08 18:00:28 +05:30
Claudio Saavedra 560952d3c0 Chain up relevant GObjectClass:notify vfuncs
These widgets have ancestors other than GObject which could eventually
implement the notify vfunc for their properties. For correctness, they
should chain up the notify vfunc.

https://bugzilla.gnome.org/show_bug.cgi?id=673478
2012-08-07 18:14:56 +03:00
Cosimo Cecchi 8062e471d1 toolbar: deprecate shadow-type style property
While shadow-type *properties* can make sense, to opt-out of the
padding/border machinery programmatically, having it as a style
property doesn't make any sense, since we have a better way to change
the bevel style from the theme already.
This commit deprecates the shadow-type style property in GtkToolbar.
2012-08-07 16:08:45 +02:00
Cosimo Cecchi 1ec6329f18 toolbar: don't request CSS padding twice
This is a regression from commit
d0d21a4f00.

We are requesting the CSS padding twice: once unconditionally and
another time if SHADOW_TYPE != NONE, which is usually the case.
2012-08-07 16:05:30 +02:00
Cosimo Cecchi 512fee6363 toolbar: deprecate internal-padding style property
This is equivalent to a regular CSS padding, and that's what people
should use.
2012-08-07 12:55:37 +02:00
Chao-Hsiung Liao 2d7c23730c Updated Traditional Chinese translation(Hong Kong and Taiwan) 2012-08-07 13:41:47 +08:00
Matthias Clasen 78ad6f8b71 Bump version 2012-08-07 01:37:59 -04:00
Matthias Clasen e3aa565bbb 3.5.10 2012-08-07 01:21:17 -04:00
Matthias Clasen 5f28b7c114 Update expected dump output for color choooser 2012-08-07 01:17:51 -04:00
Matthias Clasen 7dff6800e5 Updates 2012-08-07 00:58:46 -04:00
Matthias Clasen f89d5c8280 Optimize gtk_widget_path_copy() by preallocating "elems" array
gtk_widget_path_copy() currently calls g_array_append_val() in a loop,
which is inefficient due to reallocating the array's memory. Calling
g_array_set_size() before entering the loop reduces the number of CPU
cycles used by roughly 30%.

Patch by John Lindgren,
https://bugzilla.gnome.org/show_bug.cgi?id=679978
2012-08-07 00:38:48 -04:00
Matthias Clasen e2c15e2791 Fix a memory leak
As Pavel Vesin pointed out in bug 681064, we were leaking
the container_restyle_queue.
2012-08-06 23:37:36 -04:00
Matthias Clasen 2661403f88 Fix DND keyboard control with XI2
We are using XI2 to grab the key events, but we did not do the
necessary extra work to make GDK deliver root window events to us.

https://bugzilla.gnome.org/show_bug.cgi?id=681006
2012-08-06 22:56:59 -04:00
Matthias Clasen 5a3442bf9c Improve GtkMenuButton menu positioning
Take the menu halign/valign into consideration when positioning
the menu. Also, document the various combinations.

https://bugzilla.gnome.org/show_bug.cgi?id=680988
2012-08-06 22:27:48 -04:00
Matthias Clasen 4942b6f5e4 Remove references to deprecated functions
This inconsistency of the docs was pointed out by
Pierre-Yves Luyten in bug 680949.
2012-08-06 22:27:48 -04:00
Javier Jardón 351c1ab149 gtk/gtkadjustment.c: Improve docs
Refer to #GtkAdjustment properties instead fields
2012-08-07 03:20:50 +09:00
Matthias Clasen 6fe0fbd4e2 Leave GDK_THREADS_ENTER/LEAVE visible for now
Not defining these macros at all causes harsh build breakages.
Better to leave them defined (but documented as deprecated) for now.
Everybody will still get the deprecation warnings for the underlying
gdk_threads_enter/leave.

We can hide the macros again later on when the world has had some
time to port off GDK threads.
2012-08-06 08:34:46 -04:00
Paolo Borelli d0d21a4f00 Make GtkToolbar honour css border and padding
The widget is already calling gtk_render_frame, but is not measuring css
border and padding when negotiating its size. This patch replaces the
already existing get_internal_padding static helper with a function that
sums the old internal-padding value with the values specified via css.
2012-08-05 12:52:36 +02:00
Rico Tzschichholz e8dcfad441 cups: Use IPP api when necessary with CUPS 1.6 2012-08-05 09:56:58 +02:00
Matthias Clasen 1067627131 Add labels to some visual index images 2012-08-04 19:11:43 -04:00
Matthias Clasen 71d95cecd7 Add GtkLevelBar to the visual index 2012-08-04 19:10:58 -04:00
Matthias Clasen c549047474 Sync man page configury with GLib 2012-08-04 16:14:32 -04:00
Matthias Clasen c069267c42 Cosmetic improvements to man pages 2012-08-04 16:14:32 -04:00
Matthias Clasen bdbd47818f docs: Add examples for use of GDK_VERSION_MIN_REQUIRED
I had to work this out for myself, so better document it.
2012-08-04 16:14:31 -04:00
Matthias Clasen d1091c8bda docs: Improve man page generation
Use $(AM_V_GEN) for generating man pages, and set some parameters
for the XSL stylesheets. Among other things, don't generate AUTHORS
and COPYRIGHT sections.
2012-08-04 16:14:31 -04:00
Arash Mousavi 357a2bb926 Updated Persian translations 2012-08-04 23:50:20 +04:30
Michael Natterer 13ad089bdf gtk: ref the action around gtk_action_emit_activate()
for the same reason we already ref the action's group in the function.
(cherry picked from commit ebe50bbecb)
2012-08-03 23:28:05 +02:00
Sweta Kothari 1c90f6b6c6 Updated gujarati file 2012-08-03 15:29:51 +05:30
Sweta Kothari bb2ebce5af Updated gujarati file 2012-08-03 15:16:32 +05:30
René Stadler e5269ebbcd iconview: fix get_tooltip_context transfer annotation
Just like treeview.

https://bugzilla.gnome.org/show_bug.cgi?id=681005
2012-08-01 19:00:36 +02:00
Jiro Matsuzawa 4a7d830780 [l10n] Update Japanese translation
Modify the About label
2012-08-01 22:19:19 +09:00
Matthias Clasen 8f55b2775a Expand the thread deprecation documentation
The story is slightly different for applications vs libraries;
make it clear that libraries should continue using the lock so
we don't break applications that haven't been ported to the
'single thread' model yet.
2012-08-01 10:26:17 +02:00
Funda Wang 3941a80798 fix bug#680901: translations of "even sheet" and "odd sheet" are wrong 2012-07-31 22:05:24 +00:00
Cosimo Cecchi c1218f964a notebook: restore previous behaviour wrt. unparenting of tab labels
When the tab label gets removed from the notebook on widget
desctruction, we should still unconditionally unparent it from the
notebook, since failing to do so will keep a stray reference alive.

In case applications rely on the tab label being destroyed to release
other references (e.g. because the tab label is a custom object, or
another object's lifecycle is tied to it using g_object_set_data_full()),
this will also possibly cause other references to get leaked.
In Nautilus, the result was we were failing to release the reference to
a NautilusWindowSlot, and other parts of the application relied
on it being destroyed at a specific time instead, causing the
application to crash when closing a window.

This is a regression from commit
325cf071d1.

This commit restores the previous unparenting behavior in case we're not
in a DnD operation.

https://bugzilla.gnome.org/show_bug.cgi?id=680349
2012-07-31 20:17:54 +02:00
Jasper St. Pierre 844e793246 menubutton: Clear references in dispose, not finalize
We need to do this here so that an explicit gtk_widget_destroy
on either the widget or a container that holds it will kill the
reference to the menu or model.

https://bugzilla.gnome.org/show_bug.cgi?id=680803
2012-07-31 12:09:05 -03:00
Matthias Clasen b936666b52 Improve threading documentation
This commit just adds a small section to the threading documentation
about the deprecation. More is needed here, including a migration
example.
2012-07-30 18:01:47 +02:00
Matthias Clasen 0ac56e9dcc gdk: Deprecate thread functions
This commit deprecates gdk_threads_init, gdk_threads_enter,
gdk_threads_leave and gdk_threads_set_lock_functions. Using GTK+
from multiple threads does not work at all on Windows, and is
problematic on other platforms as well. We want to move to a world
where all GTK+ calls are made from the main thread.
Use g_main_context_invoke, g_idle_add and related functions if you
need to schedule GTK+ calls from other threads.

http://bugzilla.gnome.org/show_bug.cgi?id=680754
2012-07-30 18:01:47 +02:00
Matthias Clasen 746b9d7c41 demos: Don't use GDK_THREADS_ENTER/LEAVE macros
We don't use threads here, so no need to use them.
2012-07-30 18:01:47 +02:00
Matthias Clasen 3e78324501 modules: Don't use GDK_THREADS_ENTER/LEAVE macros internally
These are just wrappers for the functions, and we want to
deprecate them. Stopping to use them internally is a good
first step. Also define GTK_COMPILATION so we can keep using
gdk_threads_enter/leave without causing deprecation warnings.
2012-07-30 18:01:47 +02:00
Matthias Clasen 8d0e88bac7 gtk: Don't use GDK_THREADS_ENTER/LEAVE macros internally
These are just wrappers for the functions, and we want to
deprecate them. Stopping to use them internally is a good
first step.
2012-07-30 18:01:47 +02:00
Matthias Clasen 144a5687c9 gdk: Don't use GDK_THREADS_ENTER/LEAVE macros internally
These are just wrappers for the functions, and we want to
deprecate them. Stopping to use them internally is a good
first step.
2012-07-30 18:01:47 +02:00
Philip Withnall f92a092bac Bug 680822 — Document return value of GtkWidget::draw
Document the boolean accumulator used by GtkWidget::draw and a few other
GtkWidget signals.

Closes: https://bugzilla.gnome.org/show_bug.cgi?id=680822
2012-07-30 16:12:06 +02:00
Fran Diéguez 9d3a49bbb6 Updated Galician translations 2012-07-30 02:32:03 +02:00
Rob Bradford f061990bd5 window: Update _gtk_window_set_is_active API comment
The comment referenced GTK_TOPLEVEL which has been replaced by
GTK_WINDOW_TOPLEVEL.
2012-07-28 15:19:28 +01:00
Praveen Illa ce74104198 Updated Telugu Translation 2012-07-26 23:09:14 +05:30
Chun-wei Fan 488baeef98 Visual C++ property sheets: Remove wrong "install" line
We have gailutil-3.0.lib, not gailutil.lib
2012-07-26 18:04:22 +08:00
Chun-wei Fan 84d28bac66 Visual C++ projects: Update .dll/.lib naming
Remove the "-win32-" from the output file names for the GDK and GTK+ DLLs,
like what is now done for quite a while on other platforms
(and MinGW builds), for consistency reasons.  This is due to GDK/GTK+
are buildable with multiple backends.

Note: For references, the Windows build only builds the Win32 backend
for the time being.
2012-07-26 15:39:51 +08:00
Baurzhan Muftakhidinov 114267c867 Updated Kazakh translation 2012-07-26 09:14:33 +06:00
Мирослав Николић 7ce11d1521 Updated Serbian translation 2012-07-25 23:29:24 +02:00
Мирослав Николић 68c5c24289 Updated Serbian translation 2012-07-25 23:26:48 +02:00
Tom Tryfonidis 4e41a6659f Updated Greek translations 2012-07-24 18:14:05 +03:00
Kjartan Maraas 2cf924117a Updated Norwegian bokmål translation 2012-07-23 11:46:43 +02:00
Matthias Clasen ae81246512 Add an example for handling app menu fallback
The example shows how to use a menu button instead of the default
menubar when the shell doesn't show the app menu.
2012-07-22 21:01:15 -04:00
Wolfgang Stoeggl 9613cf68bd Updated German translation 2012-07-22 21:43:49 +02:00
Daniel Mustieles fcfbafc9fe Updated Spanish translation 2012-07-21 18:49:57 +02:00
Frédéric Péters c2681d585e widget-factory: add two GtkLevelBar (continuous and discrete) 2012-07-19 16:46:05 +02:00
Matej Urbančič 8ded24fbf7 Updated Slovenian translation 2012-07-19 10:11:16 +02:00
Piotr Drąg 44da798055 Updated POTFILES.in 2012-07-18 23:10:30 +02:00
Rob Bradford 7c51d67e7c wayland: Fallback to setting transient windows if no seat available
If we don't have a wl_seat - because a grab hasn't been initialised by GTK+
then fallback to making the shell surface transient to the parent rather than
a popup surface.
2012-07-18 16:16:56 +01:00
Rob Bradford 8a39d2269e wayland: Don't compare against GdkWindowTypeHint as a bitmask
The hint was being compared as a bitmask which means types that were not in
the list were being erroneously matched
2012-07-18 16:08:36 +01:00
Chao-Hsiung Liao 1a0a8e112e Updated Traditional Chinese translation(Hong Kong and Taiwan) 2012-07-18 19:33:41 +08:00
José Dapena Paz c5ef4e660b wayland: Add default settings implementation for Wayland backend.
Signed-off-by: Rob Bradford <rob@linux.intel.com>
2012-07-17 11:31:54 +01:00
José Dapena Paz 0ea892069b wayland: don't wipe clipboard on any change coming from the same owner.
We now support independent selection and primary clipboards, and avoid
wiping clipboard on modifying its contents from the same owner. This fixes
most of the interaction issues with clipboard and selection.

Signed-off-by: Rob Bradford <rob@linux.intel.com>
2012-07-17 11:24:54 +01:00
Daniel Mustieles c195421a4e Updated Spanish translation 2012-07-17 12:04:56 +02:00
Rui Matos eaddf70a43 GtkTreeModelFilter: Fix _iter_previous() when iter points at 2nd node
GSequence iterators point at the position between two elements so an
iterator pointing at the N tree model node is actually between the N-1
and N sequence elements. This means that asking for the previous
sequence iterator first and then checking if it is the begin iterator
would yeld true for an iterator pointing at the 2nd tree model node
and make us return FALSE mistakenly.

https://bugzilla.gnome.org/show_bug.cgi?id=679910
2012-07-17 10:50:48 +02:00
Rui Matos 96c19108fc tests/filtermodel: Add test for bug 679910 2012-07-17 10:49:00 +02:00
José Dapena Paz 33e928e472 wayland: Initial version of keyboard key event handling
Review comment: I think the implementation of the vfuncs in gdkkeys-wayland.c
depend on that we're using the keysysm as the hardware keycode. I think that
needs to be evaluated for the future. But for now this patch gives reasonably
complete keyboard input.

Signed-off-by: Rob Bradford <rob@linux.intel.com>
2012-07-16 20:11:41 +01:00
José Dapena Paz d2c66e5afd wayland: Hook up _get_num_lock / _get_caps_lock to read from XKB state
Signed-off-by: Rob Bradford <rob@linux.intel.com>
2012-07-16 20:11:41 +01:00
Rob Bradford bef037f5d2 wayland: Remove unused function declaration 2012-07-16 20:11:41 +01:00
Rob Bradford b5773b89cf wayland: Remove annoying whitespace 2012-07-16 20:11:41 +01:00
José Dapena Paz a4c80bd9cb wayland: Create and expose an xkb_state on the keymap object
This is then logically associated with the input device since each (keyboard)
input device has its own keymap.

Signed-off-by: Rob Bradford <rob@linux.intel.com>
2012-07-16 20:11:41 +01:00
José Dapena Paz d2267824b3 wayland: Refactor the keymap handling so it is associated with device
Although GDK expects the keymap to be associated with the display under
Wayland this is really associated with the input device so expose this by
finding the first keyboard device.

Signed-off-by: Rob Bradford <rob@linux.intel.com>
2012-07-16 20:11:41 +01:00
Matthias Clasen fb76a0a000 Bump version 2012-07-16 15:08:17 -04:00
194 changed files with 29835 additions and 30014 deletions
+82
View File
@@ -1,3 +1,85 @@
Overview of Changes in GTK+ 3.5.12
==================================
* GtkApplication:
- Add gtk_application_get_active_window to get the active window
- Add gtk_widget_insert_action_group to allow more flexibility
when associating widgets with actions
* GtkMenuButton:
- The gtk_menu_button_set_menu function is getting renamed
to gtk_menu_button_set_popup. The old name is still available
for now, but will be removed before 3.6
* GtkToolbar:
- use CSS properties instead of style properties for padding
* Input method support:
- GtkEntry and GtkTextView now have input-purpose and input-hints
properties that let applications provide useful hints to
input methods, like 'this entry is for a phone nr'.
* Bugs:
373279 Toggling a GtkToggleButton emits "clicked", not "toggled"
651244 Add a "purpose" tag for GtkEntries
673478 Chain up notify implementations
681577 Missing mnemonic in "Find applications online"
681591 Masked string for password fields is not exposed to accessibility
681613 icon view doesn't emit selection changed when the model changes
682193 404 in GTK+ docs for duplicated "stable" URL suffix to ATK link
682235 gtkmenubutton: repurpose set_menu for GMenuModel
* Translation updates:
Assamese
Esperanto
Galician
Lithuanian
Marathi
Portuguese
Serbian
Spanish
Traditional Chinese
Overview of Changes in GTK+ 3.5.10
==================================
* Wayland:
- Add keyboard handling
- Improve clipboard handling
- Add default settings implementation
* GDK thread support has been deprecated
* Bugs fixed:
679910 GtkTreeModelFilter: Fix _iter_previous() when iter...
679978 Optimize gtk_widget_path_copy() by preallocating "...
680754 deprecate gdk thread functions
680803 menubutton: Clear references in dispose, not finalize
680822 Document return value of GtkWidget::draw
680901 GTK+: The chinese translations of "even sheet" and...
680949 GtkColorButton documentation seems self-contradictory
680988 GtkMenuButton down direction positioning suboptimal
681005 [IconView] wrong transfer annotation for get_toolt...
681006 Escape should cancel DnD operation
681064 container: restyle queue leaks
* Updated translations
Galician
German
Greek
Gujarati
Japanese
Kazakh
Norwegian bokmål
Persian
Serbian
Slovenian
Spanish
Telugu
Traditional Chinese
Overview of Changes in GTK+ 3.5.8
=================================
+4 -4
View File
@@ -26,16 +26,17 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -62,11 +63,10 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
+2
View File
@@ -27,6 +27,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -35,6 +36,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
+12 -10
View File
@@ -27,6 +27,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -35,6 +36,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -62,9 +64,9 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -81,11 +83,11 @@
</ClCompile>
<Link>
<AdditionalDependencies>imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
<ModuleDefinitionFile>$(IntDir)gdk.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
@@ -101,13 +103,13 @@
</ClCompile>
<Link>
<AdditionalDependencies>imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
<ModuleDefinitionFile>$(IntDir)gdk.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
@@ -126,11 +128,11 @@
</ClCompile>
<Link>
<AdditionalDependencies>imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
<ModuleDefinitionFile>$(IntDir)gdk.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
@@ -146,13 +148,13 @@
</ClCompile>
<Link>
<AdditionalDependencies>imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
<ModuleDefinitionFile>$(IntDir)gdk.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
-2
View File
@@ -591,8 +591,6 @@ copy ..\..\..\gdk\gdkconfig.h $(CopyDir)\include\gtk-3.0\gdk
copy $(Configuration)\$(Platform)\bin\*-$(GtkApiVersion).lib $(CopyDir)\lib
copy $(Configuration)\$(Platform)\bin\gailutil.lib $(CopyDir)\lib
mkdir $(CopyDir)\share\glib-2.0\schemas
+12 -10
View File
@@ -12,10 +12,12 @@
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
@@ -62,9 +64,9 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -81,11 +83,11 @@
</ClCompile>
<Link>
<AdditionalDependencies>atk-1.0.lib;pangowin32-1.0.lib;imm32.lib;winspool.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
<ModuleDefinitionFile>$(IntDir)gtk.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
@@ -101,13 +103,13 @@
</ClCompile>
<Link>
<AdditionalDependencies>atk-1.0.lib;pangowin32-1.0.lib;imm32.lib;winspool.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
<ModuleDefinitionFile>$(IntDir)gtk.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
@@ -126,11 +128,11 @@
</ClCompile>
<Link>
<AdditionalDependencies>atk-1.0.lib;pangowin32-1.0.lib;imm32.lib;winspool.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
<ModuleDefinitionFile>$(IntDir)gtk.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
@@ -146,13 +148,13 @@
</ClCompile>
<Link>
<AdditionalDependencies>atk-1.0.lib;pangowin32-1.0.lib;imm32.lib;winspool.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
<ModuleDefinitionFile>$(IntDir)gtk.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
+3 -2
View File
@@ -26,16 +26,17 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
+6 -5
View File
@@ -23,7 +23,7 @@
Name="Debug|Win32"
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="2"
CharacterSet="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
@@ -42,7 +42,7 @@
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
LinkIncremental="1"
AdditionalDependencies="atk-1.0.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
GenerateDebugInformation="true"
@@ -77,7 +77,7 @@
Name="VCLinkerTool"
AdditionalDependencies="atk-1.0.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="2"
LinkIncremental="1"
ModuleDefinitionFile="..\..\..\libgail-util\gailutil.def"
GenerateDebugInformation="true"
SubSystem="2"
@@ -89,7 +89,7 @@
Name="Release|Win32"
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="2"
CharacterSet="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
@@ -126,6 +126,7 @@
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -143,7 +144,7 @@
Name="VCLinkerTool"
AdditionalDependencies="atk-1.0.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="2"
LinkIncremental="1"
ModuleDefinitionFile="..\..\..\libgail-util\gailutil.def"
GenerateDebugInformation="true"
SubSystem="2"
+2
View File
@@ -46,6 +46,7 @@
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -87,6 +88,7 @@
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
+14 -12
View File
@@ -43,12 +43,12 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="imm32.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
LinkIncremental="2"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="1"
ModuleDefinitionFile="$(IntDir)\gdk.def"
GenerateDebugInformation="true"
SubSystem="2"
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
TargetMachine="1"
/>
</Configuration>
@@ -57,6 +57,7 @@
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -73,14 +74,14 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="imm32.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
LinkIncremental="2"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="1"
ModuleDefinitionFile="$(IntDir)\gdk.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
TargetMachine="1"
/>
</Configuration>
@@ -108,12 +109,12 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="imm32.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
LinkIncremental="2"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="1"
ModuleDefinitionFile="$(IntDir)\gdk.def"
GenerateDebugInformation="true"
SubSystem="2"
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
TargetMachine="17"
/>
</Configuration>
@@ -122,6 +123,7 @@
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -138,14 +140,14 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="imm32.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
LinkIncremental="2"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="1"
ModuleDefinitionFile="$(IntDir)\gdk.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
TargetMachine="17"
/>
</Configuration>
-1
View File
@@ -361,7 +361,6 @@ copy ..\..\..\libgail-util\gailtextutil.h $(CopyDir)\include\gail-$(GtkApiVersio
copy ..\..\..\gdk\gdkconfig.h $(CopyDir)\include\gtk-3.0\gdk&#x0D;&#x0A;
copy $(ConfigurationName)\$(PlatformName)\bin\*-$(GtkApiVersion).lib $(CopyDir)\lib&#x0D;&#x0A;
copy $(ConfigurationName)\$(PlatformName)\bin\gailutil.lib $(CopyDir)\lib&#x0D;&#x0A;
mkdir $(CopyDir)\share\glib-2.0\schemas&#x0D;&#x0A;
copy ..\..\..\gtk\org.gtk.Settings.FileChooser.gschema.xml $(CopyDir)\share\glib-2.0\schemas&#x0D;&#x0A;
+14 -12
View File
@@ -43,12 +43,12 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="atk-1.0.lib pangowin32-1.0.lib imm32.lib winspool.lib comctl32.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
LinkIncremental="2"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="1"
ModuleDefinitionFile="$(IntDir)\gtk.def"
GenerateDebugInformation="true"
SubSystem="2"
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
TargetMachine="1"
/>
</Configuration>
@@ -57,6 +57,7 @@
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -73,14 +74,14 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="atk-1.0.lib pangowin32-1.0.lib imm32.lib winspool.lib comctl32.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
LinkIncremental="2"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="1"
ModuleDefinitionFile="$(IntDir)\gtk.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
TargetMachine="1"
/>
</Configuration>
@@ -108,12 +109,12 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="atk-1.0.lib pangowin32-1.0.lib imm32.lib winspool.lib comctl32.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
LinkIncremental="2"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="1"
ModuleDefinitionFile="$(IntDir)\gtk.def"
GenerateDebugInformation="true"
SubSystem="2"
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
TargetMachine="17"
/>
</Configuration>
@@ -122,6 +123,7 @@
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -138,14 +140,14 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="atk-1.0.lib pangowin32-1.0.lib imm32.lib winspool.lib comctl32.lib"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
LinkIncremental="2"
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
LinkIncremental="1"
ModuleDefinitionFile="$(IntDir)\gtk.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
TargetMachine="17"
/>
</Configuration>
+2 -2
View File
@@ -44,7 +44,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies=""
LinkIncremental="2"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
@@ -77,7 +77,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies=""
LinkIncremental="2"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
RandomizedBaseAddress="1"
+3 -2
View File
@@ -23,7 +23,7 @@
Name="Debug|Win32"
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="4"
CharacterSet="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
@@ -67,7 +67,7 @@
Name="Release|Win32"
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="4"
CharacterSet="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
@@ -91,6 +91,7 @@
InheritedPropertySheets=".\gtk+.vsprops"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
+42 -20
View File
@@ -10,7 +10,7 @@
m4_define([gtk_major_version], [3])
m4_define([gtk_minor_version], [5])
m4_define([gtk_micro_version], [8])
m4_define([gtk_micro_version], [13])
m4_define([gtk_interface_age], [0])
m4_define([gtk_binary_age],
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
@@ -987,11 +987,13 @@ if test "x$enable_x11_backend" = xyes; then
AC_MSG_CHECKING([if <X11/extensions/XIproto.h> is needed for xReply])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/Xlibint.h>]],
[[xReply *rep;]])],
[[xReply *rep = NULL;
rep = rep;]])],
[AC_MSG_RESULT([no])],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/extensions/XIproto.h>
#include <X11/Xlibint.h>]],
[[xReply *rep;]])],
[[xReply *rep = NULL;
rep = rep;]])],
[AC_MSG_RESULT([yes])
AC_DEFINE([NEED_XIPROTO_H_FOR_XREPLY], [1],
[Define if <X11/extensions/XIproto.h> needed for xReply])],
@@ -1603,33 +1605,53 @@ AM_CONDITIONAL(HAVE_COLORD, test "x$have_colord" = "xyes")
GTK_DOC_CHECK([1.11],[--flavour no-tmpl])
AC_CHECK_PROG(DB2HTML, db2html, true, false)
AM_CONDITIONAL(HAVE_DOCBOOK, $DB2HTML)
AC_ARG_ENABLE(man,
[AS_HELP_STRING([--enable-man],
[regenerate man pages from Docbook [default=no]])],
[enable_man=yes],
[enable_man=no])
[generate man pages [default=auto]])],,
enable_man=maybe)
if test "${enable_man}" != no; then
dnl
dnl Check for xsltproc
dnl
if test "$enable_man" != no; then
AC_PATH_PROG([XSLTPROC], [xsltproc])
if test -z "$XSLTPROC"; then
if test "$enable_man" = yes ; then
AC_MSG_ERROR([xsltproc is required for --enable-man])
fi
enable_man=no
fi
dnl check for DocBook DTD and stylesheets in the local catalog.
JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.1.2//EN],
[DocBook XML DTD V4.1.2],,enable_man=no)
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
[DocBook XSL Stylesheets],,enable_man=no)
fi
AM_CONDITIONAL(ENABLE_MAN, test x$enable_man != xno)
if test "$enable_man" != no; then
dnl check for DocBook DTD in the local catalog
JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.1.2//EN],
[DocBook XML DTD V4.1.2], [have_docbook_dtd=yes], [have_docbook_dtd=no])
if test "$have_docbook_dtd" != yes; then
if test "$enable_man" = yes ; then
AC_MSG_ERROR([DocBook DTD is required for --enable-man])
fi
enable_man=no
fi
fi
if test "$enable_man" != no; then
dnl check for DocBook XSL stylesheets in the local catalog
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
[DocBook XSL Stylesheets], [have_docbook_style=yes],[have_docbook_style=no])
if test "$have_docbook_dtd" != yes; then
if test "$enable_man" = yes ; then
AC_MSG_ERROR([DocBook XSL Stylesheets are required for --enable-man])
fi
enable_man=no
fi
fi
AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no)
AC_MSG_CHECKING([whether to generate man pages])
if test "$enable_man" != no; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
##################################################
# Output commands
-2
View File
@@ -175,9 +175,7 @@ timeout (gpointer data)
: MAX (127, fabs (255 * cos (f * 2.0 * G_PI)))));
}
GDK_THREADS_ENTER ();
gtk_widget_queue_draw (da);
GDK_THREADS_LEAVE ();
frame_num++;
return G_SOURCE_CONTINUE;
+27
View File
@@ -1136,6 +1136,33 @@ Suspendisse feugiat quam quis dolor accumsan cursus. </property>
<property name="position">8</property>
</packing>
</child>
<child>
<object class="GtkLevelBar" id="levelbar1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="value">0.6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">9</property>
</packing>
</child>
<child>
<object class="GtkLevelBar" id="levelbar2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="min-value">0</property>
<property name="max-value">5</property>
<property name="value">2</property>
<property name="mode">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">10</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
+23 -2
View File
@@ -309,6 +309,7 @@ HTML_IMAGES = \
$(srcdir)/images/icon-view.png \
$(srcdir)/images/image.png \
$(srcdir)/images/label.png \
$(srcdir)/images/levelbar.png \
$(srcdir)/images/link-button.png \
$(srcdir)/images/list-and-tree.png \
$(srcdir)/images/lock-button.png \
@@ -381,7 +382,19 @@ HTML_IMAGES = \
$(srcdir)/images/numerableicon2.png \
$(srcdir)/images/bloatpad-osx.png \
$(srcdir)/images/bloatpad-gnome.png \
$(srcdir)/images/bloatpad-xfce.png
$(srcdir)/images/bloatpad-xfce.png \
$(srcdir)/images/down-center.png \
$(srcdir)/images/down-end.png \
$(srcdir)/images/down-start.png \
$(srcdir)/images/left-center.png \
$(srcdir)/images/left-end.png \
$(srcdir)/images/left-start.png \
$(srcdir)/images/right-center.png \
$(srcdir)/images/right-end.png \
$(srcdir)/images/right-start.png \
$(srcdir)/images/up-center.png \
$(srcdir)/images/up-end.png \
$(srcdir)/images/up-start.png
# Extra options to supply to gtkdoc-fixref
FIXXREF_OPTIONS=--extra-dir=../gdk/html \
@@ -406,8 +419,16 @@ man_MANS = \
if ENABLE_MAN
XSLTPROC_FLAGS = \
--nonet \
--stringparam man.output.quietly 1 \
--stringparam funcsynopsis.style ansi \
--stringparam man.th.extra1.suppress 1 \
--stringparam man.authors.section.enabled 0 \
--stringparam man.copyright.section.enabled 0
.xml.1:
@XSLTPROC@ -nonet http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
$(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
dist-local-check-mans-enabled:
if grep "Man generation disabled" $(man_MANS) >/dev/null; then $(RM) $(man_MANS); fi
+16
View File
@@ -63,6 +63,22 @@ to use. APIs that were deprecated before or introduced after
this range will trigger compiler warnings.
</para>
<para>
Here is how you would compile hello.c if you want to allow it
to use symbols that were not deprecated in 3.2:
<programlisting>
$ cc -DGDK_VERSION_MIN_REQIRED=GDK_VERSION_3_2 `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
</programlisting>
</para>
<para>
And here is how you would compile hello.c if you don't want
it to use any symbols that were introduced after 3.4:
<programlisting>
$ cc -DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_3_4 `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
</programlisting>
</para>
<para>
The older deprecation mechanism of hiding deprecated interfaces
entirely from the compiler by using the preprocessor symbol
+4 -9
View File
@@ -6,7 +6,7 @@
<refentryinfo>
<title>gtk-launch</title>
<productname>gtk+</productname>
<productname>GTK+</productname>
<authorgroup>
<author>
<contrib>Developer</contrib>
@@ -48,8 +48,9 @@ the application to launch. The name should match application desktop file name,
as residing in /usr/share/application, with or without the '.desktop' suffix.
</para>
<para>
If called with more than one argument, the rest of them besides the application name
are considered URI locations and are passed as arguments to the launched application.
If called with more than one argument, the rest of them besides the application
name are considered URI locations and are passed as arguments to the launched
application.
</para>
</refsect1>
@@ -63,10 +64,4 @@ are considered URI locations and are passed as arguments to the launched applica
</variablelist>
</refsect1>
<refsect1><title>Bugs</title>
<para>
None known yet.
</para>
</refsect1>
</refentry>
+38 -15
View File
@@ -4,6 +4,18 @@
]>
<refentry id="gtk-query-immodules-3.0">
<refentryinfo>
<title>gtk-query-immodules-3.0</title>
<productname>GTK+</productname>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>Matthias</firstname>
<surname>Clasen</surname>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>gtk-query-immodules-3.0</refentrytitle>
<manvolnum>1</manvolnum>
@@ -19,7 +31,7 @@
<cmdsynopsis>
<command>gtk-query-immodules-3.0</command>
<arg choice="opt">--update-cache</arg>
<arg choice="opt" rep="repeat">module</arg>
<arg choice="opt" rep="repeat">MODULE</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -37,11 +49,13 @@ module path.
If called with arguments, it looks for the specified modules. The arguments
may be absolute or relative paths.
</para>
<para>
Normally, the output of <command>gtk-query-immodules-3.0</command> is written
to <filename><replaceable>libdir</replaceable>/gtk-3.0/3.0.0/immodules.cache</filename>, where GTK+ looks for it by default. If it is written to some other
location, the environment variable <link linkend="gtk-im-module-file"><envar>GTK_IM_MODULE_FILE</envar></link>
can be set to point GTK+ at the file.
to <filename><replaceable>libdir</replaceable>/gtk-3.0/3.0.0/immodules.cache</filename>,
where GTK+ looks for it by default. If it is written to some other location,
the <envar>GTK_IM_MODULE_FILE</envar> environment variable can be set to point
GTK+ at the file.
</para>
</refsect1>
@@ -55,19 +69,28 @@ can be set to point GTK+ at the file.
</variablelist>
</refsect1>
<refsect1><title>Environment</title>
<para>
The environment variable <link linkend="gtk-path"><envar>GTK_PATH</envar></link>
can be used to prepend directories to the input method module path.
</para>
<refsect1><title>Files</title>
<variablelist>
<varlistentry>
<term><filename><replaceable>libdir</replaceable>/gtk-3.0/3.0.0/immodules.cache</filename></term>
<listitem><para>The default im cache file used by GTK+ applications</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Bugs</title>
<para>
None known yet.
</para>
<refsect1><title>Environment</title>
<variablelist>
<varlistentry>
<term><link linkend="gtk-path"><envar>GTK_PATH</envar></link></term>
<listitem><para>Prepends directories to the input method module path</para></listitem>
</varlistentry>
<varlistentry>
<term><link linkend="gtk-im-module-file"><envar>GTK_IM_MODULE_FILE</envar></link></term>
<listitem><para>Specifies an alternative im module cache for GTK+
applications</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
+12 -6
View File
@@ -4,6 +4,18 @@
]>
<refentry id="gtk-update-icon-cache">
<refentryinfo>
<title>gtk-update-icon-cache</title>
<productname>GTK+</productname>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>Matthias</firstname>
<surname>Clasen</surname>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>gtk-update-icon-cache</refentrytitle>
<manvolnum>1</manvolnum>
@@ -99,10 +111,4 @@
</variablelist>
</refsect1>
<refsect1><title>Bugs</title>
<para>
None known yet.
</para>
</refsect1>
</refentry>
+13 -2
View File
@@ -1081,6 +1081,12 @@ gtk_entry_get_icon_tooltip_markup
gtk_entry_set_icon_drag_source
gtk_entry_get_current_icon_drag_source
gtk_entry_get_icon_area
GtkInputPurpose
gtk_entry_set_input_purpose
gtk_entry_get_input_purpose
GtkInputHints
gtk_entry_set_input_hints
gtk_entry_get_input_hints
<SUBSECTION Standard>
GTK_ENTRY
@@ -2130,8 +2136,8 @@ gtk_menu_bar_get_type
<TITLE>GtkMenuButton</TITLE>
GtkMenuButton
gtk_menu_button_new
gtk_menu_button_set_menu
gtk_menu_button_get_menu
gtk_menu_button_set_popup
gtk_menu_button_get_popup
gtk_menu_button_set_menu_model
gtk_menu_button_get_menu_model
gtk_menu_button_set_direction
@@ -3672,6 +3678,10 @@ gtk_text_view_get_accepts_tab
gtk_text_view_get_default_attributes
gtk_text_view_im_context_filter_keypress
gtk_text_view_reset_im_context
gtk_text_view_set_input_purpose
gtk_text_view_get_input_purpose
gtk_text_view_set_input_hints
gtk_text_view_get_input_hints
GTK_TEXT_VIEW_PRIORITY_VALIDATE
<SUBSECTION Standard>
GTK_TEXT_VIEW
@@ -5291,6 +5301,7 @@ gtk_widget_get_mapped
gtk_widget_get_requisition
gtk_widget_device_is_shadowed
gtk_widget_get_modifier_mask
gtk_widget_insert_action_group
<SUBSECTION>
gtk_widget_get_path
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

+3
View File
@@ -48,6 +48,9 @@
<link linkend="GtkLabel">
<inlinegraphic fileref="label.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkLevelBar">
<inlinegraphic fileref="levelbar.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkLinkButton">
<inlinegraphic fileref="link-button.png" format="PNG"></inlinegraphic>
</link>
+39 -9
View File
@@ -228,20 +228,25 @@ static WidgetInfo *
create_menu_button (void)
{
GtkWidget *widget;
GtkWidget *align;
GtkWidget *image;
GtkWidget *menu;
GtkWidget *vbox;
widget = gtk_menu_button_new ();
image = gtk_image_new ();
gtk_image_set_from_icon_name (GTK_IMAGE (image), "emblem-system-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (widget), image);
menu = gtk_menu_new ();
gtk_menu_button_set_menu (GTK_MENU_BUTTON (widget), menu);
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_add (GTK_CONTAINER (align), widget);
gtk_menu_button_set_popup (GTK_MENU_BUTTON (widget), menu);
return new_widget_info ("menu-button", align, SMALL);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("Menu Button"), TRUE, TRUE, 0);
return new_widget_info ("menu-button", vbox, SMALL);
}
#define G_TYPE_TEST_PERMISSION (g_test_permission_get_type ())
@@ -282,14 +287,20 @@ g_test_permission_class_init (GTestPermissionClass *class)
static WidgetInfo *
create_lockbutton (void)
{
GtkWidget *vbox;
GtkWidget *widget;
GtkWidget *align;
widget = gtk_lock_button_new (g_object_new (G_TYPE_TEST_PERMISSION, NULL));
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_add (GTK_CONTAINER (align), widget);
return new_widget_info ("lock-button", align, SMALL);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox),
gtk_label_new ("Lock Button"),
FALSE, FALSE, 0);
gtk_widget_set_halign (vbox, GTK_ALIGN_CENTER);
gtk_widget_set_valign (vbox, GTK_ALIGN_CENTER);
return new_widget_info ("lock-button", vbox, SMALL);
}
static WidgetInfo *
@@ -987,6 +998,24 @@ create_progressbar (void)
return new_widget_info ("progressbar", vbox, SMALL);
}
static WidgetInfo *
create_level_bar (void)
{
GtkWidget *vbox;
GtkWidget *widget;
widget = gtk_level_bar_new ();
gtk_level_bar_set_value (GTK_LEVEL_BAR (widget), 0.333);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox),
gtk_label_new ("Level Bar"),
FALSE, FALSE, 0);
return new_widget_info ("levelbar", vbox, SMALL);
}
static WidgetInfo *
create_scrolledwindow (void)
{
@@ -1269,6 +1298,7 @@ get_all_widgets (void)
retval = g_list_prepend (retval, create_colorchooserdialog ());
retval = g_list_prepend (retval, create_menu_button ());
retval = g_list_prepend (retval, create_search_entry ());
retval = g_list_prepend (retval, create_level_bar ());
return retval;
}
+2 -1
View File
@@ -53,7 +53,8 @@ noinst_PROGRAMS = \
hello-world \
window-default \
bloatpad \
plugman \
plugman \
sunny \
grid-packing \
drawing \
builder
+213
View File
@@ -0,0 +1,213 @@
#include <stdlib.h>
#include <gtk/gtk.h>
static void
new_window (GApplication *app,
GFile *file)
{
GtkWidget *window, *scrolled, *view, *overlay;
GtkSettings *settings;
gboolean appmenu;
window = gtk_application_window_new (GTK_APPLICATION (app));
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), FALSE);
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
gtk_window_set_title (GTK_WINDOW (window), "Sunny");
overlay = gtk_overlay_new ();
gtk_container_add (GTK_CONTAINER (window), overlay);
settings = gtk_settings_get_default ();
g_object_get (settings, "gtk-shell-shows-app-menu", &appmenu, NULL);
if (!appmenu)
{
GMenuModel *model;
GtkWidget *menu;
GtkWidget *image;
model = gtk_application_get_app_menu (GTK_APPLICATION (app));
menu = gtk_menu_button_new ();
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menu), model);
gtk_widget_set_halign (menu, GTK_ALIGN_END);
gtk_widget_set_valign (menu, GTK_ALIGN_START);
image = gtk_image_new ();
gtk_image_set_from_icon_name (GTK_IMAGE (image),
"sunny",
GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (menu), image);
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), menu);
}
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new ();
gtk_container_add (GTK_CONTAINER (scrolled), view);
gtk_container_add (GTK_CONTAINER (overlay), scrolled);
if (file != NULL)
{
gchar *contents;
gsize length;
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
{
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_text (buffer, contents, length);
g_free (contents);
}
}
gtk_widget_show_all (GTK_WIDGET (window));
}
static void
activate (GApplication *application)
{
new_window (application, NULL);
}
static void
open (GApplication *application,
GFile **files,
gint n_files,
const gchar *hint)
{
gint i;
for (i = 0; i < n_files; i++)
new_window (application, files[i]);
}
typedef GtkApplication MenuButton;
typedef GtkApplicationClass MenuButtonClass;
G_DEFINE_TYPE (MenuButton, menu_button, GTK_TYPE_APPLICATION)
static void
show_about (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
gtk_show_about_dialog (NULL,
"program-name", "Sunny",
"title", "About Sunny",
"logo-icon-name", "sunny",
"comments", "A cheap Bloatpad clone.",
NULL);
}
static void
quit_app (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GList *list, *next;
GtkWindow *win;
g_print ("Going down...\n");
list = gtk_application_get_windows (GTK_APPLICATION (g_application_get_default ()));
while (list)
{
win = list->data;
next = list->next;
gtk_widget_destroy (GTK_WIDGET (win));
list = next;
}
}
static void
new_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GApplication *app = user_data;
g_application_activate (app);
}
static GActionEntry app_entries[] = {
{ "about", show_about, NULL, NULL, NULL },
{ "quit", quit_app, NULL, NULL, NULL },
{ "new", new_activated, NULL, NULL, NULL }
};
static void
startup (GApplication *application)
{
GtkBuilder *builder;
G_APPLICATION_CLASS (menu_button_parent_class)->startup (application);
g_action_map_add_action_entries (G_ACTION_MAP (application), app_entries, G_N_ELEMENTS (app_entries), application);
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder,
"<interface>"
" <menu id='app-menu'>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_New Window</attribute>"
" <attribute name='action'>app.new</attribute>"
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_About Sunny</attribute>"
" <attribute name='action'>app.about</attribute>"
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_Quit</attribute>"
" <attribute name='action'>app.quit</attribute>"
" <attribute name='accel'>&lt;Primary&gt;q</attribute>"
" </item>"
" </section>"
" </menu>"
"</interface>", -1, NULL);
gtk_application_set_app_menu (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
g_object_unref (builder);
}
static void
menu_button_init (MenuButton *app)
{
}
static void
menu_button_class_init (MenuButtonClass *class)
{
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
application_class->startup = startup;
application_class->activate = activate;
application_class->open = open;
}
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,
NULL);
}
int
main (int argc, char **argv)
{
MenuButton *menu_button;
int status;
menu_button = menu_button_new ();
status = g_application_run (G_APPLICATION (menu_button), argc, argv);
g_object_unref (menu_button);
return status;
}
+6 -6
View File
@@ -58,12 +58,12 @@ gdk_event_source_prepare (GSource *source,
GdkDisplay *display = ((GdkEventSource*) source)->display;
gboolean retval;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
*timeout = -1;
retval = (_gdk_event_queue_find_first (display) != NULL);
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return retval;
}
@@ -74,14 +74,14 @@ gdk_event_source_check (GSource *source)
GdkEventSource *event_source = (GdkEventSource*) source;
gboolean retval;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
if (event_source->event_poll_fd.revents & G_IO_IN)
retval = (_gdk_event_queue_find_first (event_source->display) != NULL);
else
retval = FALSE;
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return retval;
}
@@ -353,7 +353,7 @@ gdk_event_source_dispatch (GSource *source,
GdkDisplay *display = ((GdkEventSource*) source)->display;
GdkEvent *event;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
event = gdk_display_get_event (display);
@@ -364,7 +364,7 @@ gdk_event_source_dispatch (GSource *source,
gdk_event_free (event);
}
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return TRUE;
}
+31 -6
View File
@@ -24,6 +24,8 @@
#include "config.h"
#define GDK_DISABLE_DEPRECATION_WARNINGS 1
#include "gdkmain.h"
#include "gdkinternals.h"
@@ -446,10 +448,6 @@ gdk_init (int *argc, char ***argv)
* which protects all use of GTK+. That is, only one thread can use GTK+
* at any given time.
*
* Unfortunately the above holds with the X11 backend only. With the
* Win32 backend, GDK calls should not be attempted from multiple threads
* at all.
*
* You must call gdk_threads_init() before executing any other GTK+ or
* GDK functions in a threaded GTK+ program.
*
@@ -651,6 +649,21 @@ gdk_init (int *argc, char ***argv)
* }
* </programlisting>
* </informalexample>
*
* Unfortunately, all of the above documentation holds with the X11
* backend only. With the Win32 backend, GDK and GTK+ calls should not
* be attempted from multiple threads at all. Combining the GDK lock
* with other locks such as the Python global interpreter lock can be
* complicated.
*
* For these reason, the threading support has been deprecated in
* GTK+ 3.6. Instead of calling GTK+ directly from multiple threads,
* it is recommended to use g_idle_add(), g_main_context_invoke()
* and similar functions to make these calls from the main thread
* instead. The main thread is the thread which has called gtk_init()
* and is running the GTK+ mainloop. GTK+ itself will continue to
* use the GDK lock internally as long as the deprecated functionality
* is still available, and other libraries should probably do the same.
*/
@@ -661,6 +674,9 @@ gdk_init (int *argc, char ***argv)
* GDK and GTK+ functions can be called safely and without causing race
* conditions. Only one thread at a time can be in such a critial
* section.
*
* Deprecated:3.6: All GDK and GTK+ calls should be made from the main
* thread
*/
void
gdk_threads_enter (void)
@@ -673,6 +689,9 @@ gdk_threads_enter (void)
* gdk_threads_leave:
*
* Leaves a critical region begun with gdk_threads_enter().
*
* Deprecated:3.6: All GDK and GTK+ calls should be made from the main
* thread
*/
void
gdk_threads_leave (void)
@@ -701,6 +720,9 @@ gdk_threads_impl_unlock (void)
*
* This call must be made before any use of the main loop from
* GTK+; to be safe, call it before gtk_init().
*
* Deprecated:3.6: All GDK and GTK+ calls should be made from the main
* thread
*/
void
gdk_threads_init (void)
@@ -738,6 +760,9 @@ gdk_threads_init (void)
* This method must be called before gdk_threads_init(), and cannot
* be called multiple times.
*
* Deprecated:3.6: All GDK and GTK+ calls should be made from the main
* thread
*
* Since: 2.4
**/
void
@@ -757,12 +782,12 @@ gdk_threads_dispatch (gpointer data)
GdkThreadsDispatch *dispatch = data;
gboolean ret = FALSE;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
if (!g_source_is_destroyed (g_main_current_source ()))
ret = dispatch->func (dispatch->data);
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return ret;
}
+18
View File
@@ -33,9 +33,19 @@
G_BEGIN_DECLS
#if defined(GDK_COMPILATION) || defined(GTK_COMPILATION)
#define GDK_THREADS_DEPRECATED
#else
#define GDK_THREADS_DEPRECATED GDK_DEPRECATED_IN_3_6
#endif
GDK_THREADS_DEPRECATED
void gdk_threads_init (void);
GDK_THREADS_DEPRECATED
void gdk_threads_enter (void);
GDK_THREADS_DEPRECATED
void gdk_threads_leave (void);
GDK_THREADS_DEPRECATED
void gdk_threads_set_lock_functions (GCallback enter_fn,
GCallback leave_fn);
@@ -62,6 +72,7 @@ guint gdk_threads_add_timeout_seconds (guint interval,
GSourceFunc function,
gpointer data);
/**
* GDK_THREADS_ENTER:
*
@@ -71,6 +82,9 @@ guint gdk_threads_add_timeout_seconds (guint interval,
* section. The macro expands to a no-op if #G_THREADS_ENABLED has not
* been defined. Typically gdk_threads_enter() should be used instead of
* this macro.
*
* Deprecated:3.6: Use g_main_context_invoke(), g_idle_add() and related
* functions if you need to schedule GTK+ calls from other threads.
*/
#define GDK_THREADS_ENTER() gdk_threads_enter()
@@ -79,9 +93,13 @@ guint gdk_threads_add_timeout_seconds (guint interval,
*
* This macro marks the end of a critical section
* begun with #GDK_THREADS_ENTER.
*
* Deprecated:3.6: Deprecated in 3.6.
*/
#define GDK_THREADS_LEAVE() gdk_threads_leave()
#undef GDK_THREADS_DEPRECATED
G_END_DECLS
#endif /* __GDK_THREADS_H__ */
+77 -75
View File
@@ -254,6 +254,7 @@ static void gdk_window_invalidate_rect_full (GdkWindow *window,
gboolean invalidate_children,
ClearBg clear_bg);
static void _gdk_window_propagate_has_alpha_background (GdkWindow *window);
static cairo_surface_t *gdk_window_ref_impl_surface (GdkWindow *window);
static guint signals[LAST_SIGNAL] = { 0 };
@@ -263,6 +264,42 @@ static const cairo_user_data_key_t gdk_window_cairo_key;
G_DEFINE_ABSTRACT_TYPE (GdkWindow, gdk_window, G_TYPE_OBJECT)
#ifdef DEBUG_WINDOW_PRINTING
char *
print_region (cairo_region_t *region)
{
GString *s = g_string_new ("{");
if (cairo_region_is_empty (region))
{
g_string_append (s, "empty");
}
else
{
int num = cairo_region_num_rectangles (region);
cairo_rectangle_int_t r;
if (num == 1)
{
cairo_region_get_rectangle (region, 0, &r);
g_string_append_printf (s, "%dx%d @%d,%d", r.width, r.height, r.x, r.y);
}
else
{
cairo_region_get_extents (region, &r);
g_string_append_printf (s, "extent: %dx%d @%d,%d, details: ", r.width, r.height, r.x, r.y);
for (int i = 0; i < num; i++)
{
g_string_append_printf (s, "[%dx%d @%d,%d]", r.width, r.height, r.x, r.y);
if (i != num -1)
g_string_append (s, ", ");
}
}
}
g_string_append (s, "}");
return g_string_free (s, FALSE);
}
#endif
GType
_gdk_paintable_get_type (void)
{
@@ -2671,7 +2708,7 @@ gdk_window_get_content (GdkWindow *window)
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
surface = _gdk_window_ref_cairo_surface (window);
surface = gdk_window_ref_impl_surface (window);
content = cairo_surface_get_content (surface);
cairo_surface_destroy (surface);
@@ -2746,60 +2783,55 @@ gdk_cairo_create_for_impl (GdkWindow *window)
return cr;
}
/* Ensure that all content related to this (sub)window is pushed to the
native region. If there is an active paint then that area is not
pushed, in order to not show partially finished double buffers. */
/* This is called whenever something is drawing directly to the
* window, bypassing the double buffering. When this happens we
* need to mark any the currently drawn data in the double buffer
* as invalid to avoid later drawing it back over the directly
* rendered pixels. We also need to mark this region as "flushed"
* so that if we later try to paint on it double-buffered we need
* to read back the on-window pixels rather than relying on what
* is in the current double-buffer pixmap.
*
* Note that this doesn't correctly handle the case where the
* non-double buffered drawing uses transparency and relies on
* what the windows below it draws. A fix for that would require
* drawing the existing double-buffered background to the window,
* but that causes ugly flashes. Non-double buffered drawing is
* typically only used in old code or when the drawed widget
* already has a double-buffering layer, and in these cases the
* pixels are opaque anyway. If you need transparency, don't
* disable double buffering.
*/
static void
gdk_window_flush_implicit_paint (GdkWindow *window)
{
GdkWindow *impl_window;
GdkWindowPaint *paint;
cairo_region_t *region;
GSList *list;
impl_window = gdk_window_get_impl_window (window);
if (impl_window->implicit_paint == NULL)
return;
paint = impl_window->implicit_paint;
region = cairo_region_copy (window->clip_region_with_children);
region = cairo_region_copy (window->clip_region_with_children);
cairo_region_translate (region, window->abs_x, window->abs_y);
/* Anything in the whole flushed window that was drawn is now
considered unpainted, so that we don't push it back at the
end of the implicit paint overwriting the directly rendered
pixels. */
cairo_region_subtract (paint->region, region);
/* Save flushed area so we can read it back if we draw over it later */
if (paint->flushed == NULL)
paint->flushed = cairo_region_copy (region);
paint->flushed = region;
else
cairo_region_union (paint->flushed, region);
cairo_region_intersect (region, paint->region);
/* Don't flush active double buffers, as that may show partially done
* rendering */
for (list = window->paint_stack; list != NULL; list = list->next)
{
GdkWindowPaint *tmp_paint = list->data;
cairo_region_subtract (region, tmp_paint->region);
cairo_region_union (paint->flushed, region);
cairo_region_destroy (region);
}
if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
{
cairo_t *cr;
/* Remove flushed region from the implicit paint */
cairo_region_subtract (paint->region, region);
/* Some regions are valid, push these to window now */
cr = gdk_cairo_create_for_impl (window);
gdk_cairo_region (cr, region);
cairo_clip (cr);
cairo_set_source_surface (cr, paint->surface, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
cairo_destroy (cr);
}
cairo_region_destroy (region);
}
/* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
@@ -3412,28 +3444,6 @@ gdk_window_flush (GdkWindow *window)
gdk_window_flush_implicit_paint (window);
}
/* If we're about to move/resize or otherwise change the
* hierarchy of a client side window in an impl and we're
* called from an expose event handler then we need to
* flush any already painted parts of the implicit paint
* that are not part of the current paint, as these may
* be used when scrolling or may overdraw the changes
* caused by the hierarchy change.
*/
static void
gdk_window_flush_if_exposing (GdkWindow *window)
{
GdkWindow *impl_window;
impl_window = gdk_window_get_impl_window (window);
/* If we're in an implicit paint (i.e. in an expose handler, flush
all the already finished exposes to get things to an uptodate state. */
if (impl_window->implicit_paint)
gdk_window_flush (window);
}
static void
gdk_window_flush_recursive_helper (GdkWindow *window,
GdkWindowImpl *impl)
@@ -5334,8 +5344,6 @@ gdk_window_raise (GdkWindow *window)
if (window->destroyed)
return;
gdk_window_flush_if_exposing (window);
/* Keep children in (reverse) stacking order */
gdk_window_raise_internal (window);
@@ -5456,8 +5464,6 @@ gdk_window_lower (GdkWindow *window)
if (window->destroyed)
return;
gdk_window_flush_if_exposing (window);
/* Keep children in (reverse) stacking order */
gdk_window_lower_internal (window);
@@ -5513,8 +5519,6 @@ gdk_window_restack (GdkWindow *window,
return;
}
gdk_window_flush_if_exposing (window);
if (gdk_window_is_toplevel (window))
{
g_return_if_fail (gdk_window_is_toplevel (sibling));
@@ -6070,8 +6074,6 @@ gdk_window_move_resize_internal (GdkWindow *window,
window->y == y)))
return;
gdk_window_flush_if_exposing (window);
/* Handle child windows */
expose = FALSE;
@@ -6356,8 +6358,6 @@ gdk_window_scroll (GdkWindow *window,
if (window->destroyed)
return;
gdk_window_flush_if_exposing (window);
old_layered_area = cairo_region_copy (window->layered_region);
old_native_child_region = collect_native_child_region (window, FALSE);
if (old_native_child_region)
@@ -9812,11 +9812,16 @@ proxy_button_event (GdkEvent *source_event,
}
#ifdef DEBUG_WINDOW_PRINTING
#ifdef GDK_WINDOWING_X11
#include "x11/gdkx.h"
#endif
static void
gdk_window_print (GdkWindow *window,
int indent)
{
GdkRectangle r;
char *s;
const char *window_types[] = {
"root",
"toplevel",
@@ -9855,11 +9860,8 @@ gdk_window_print (GdkWindow *window,
g_print (" abs[%d,%d]",
window->abs_x, window->abs_y);
cairo_region_get_extents (window->clip_region, &r);
if (cairo_region_is_empty (window->clip_region))
g_print (" clipbox[empty]");
else
g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
s = print_region (window->clip_region);
g_print (" clipbox[%s]", s);
g_print ("\n");
}
@@ -10129,7 +10131,7 @@ gdk_window_create_similar_surface (GdkWindow * window,
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
window_surface = _gdk_window_ref_cairo_surface (window);
window_surface = gdk_window_ref_impl_surface (window);
switch (_gdk_rendering_mode)
{
+6 -6
View File
@@ -616,14 +616,14 @@ gdk_event_prepare (GSource *source,
{
gboolean retval;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
*timeout = -1;
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
_gdk_quartz_event_loop_check_pending ());
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return retval;
}
@@ -633,7 +633,7 @@ gdk_event_check (GSource *source)
{
gboolean retval;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
/* Refresh the autorelease pool if we're at the base CFRunLoop level
* (indicated by current_loop_level) and the base g_main_loop level
@@ -653,7 +653,7 @@ gdk_event_check (GSource *source)
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
_gdk_quartz_event_loop_check_pending ());
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return retval;
}
@@ -665,7 +665,7 @@ gdk_event_dispatch (GSource *source,
{
GdkEvent *event;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
_gdk_quartz_display_queue_events (_gdk_display);
@@ -678,7 +678,7 @@ gdk_event_dispatch (GSource *source,
gdk_event_free (event);
}
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return TRUE;
}
+7 -4
View File
@@ -172,8 +172,11 @@ static guint32
get_time_from_ns_event (NSEvent *event)
{
double time = [event timestamp];
return time * 1000.0;
/* cast via double->uint64 conversion to make sure that it is
* wrapped on 32-bit machines when it overflows
*/
return (guint32) (guint64) (time * 1000.0);
}
static int
@@ -1478,9 +1481,9 @@ _gdk_quartz_display_queue_events (GdkDisplay *display)
g_list_free_1 (node);
gdk_event_free (event);
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
[NSApp sendEvent:nsevent];
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
_gdk_quartz_event_loop_release_event (nsevent);
+3 -5
View File
@@ -629,17 +629,15 @@ gdk_quartz_keymap_get_entries_for_keycode (GdkKeymap *keymap,
return *n_entries > 0;
}
#define GET_KEYVAL(keycode, group, level) (keyval_array[(keycode * KEYVALS_PER_KEYCODE + group * 2 + level)])
static guint
gdk_quartz_keymap_lookup_key (GdkKeymap *keymap,
const GdkKeymapKey *key)
{
/* FIXME: Implement */
return 0;
return GET_KEYVAL (key->keycode, key->group, key->level);
}
#define GET_KEYVAL(keycode, group, level) (keyval_array[(keycode * KEYVALS_PER_KEYCODE + group * 2 + level)])
static guint
translate_keysym (guint hardware_keycode,
gint group,
+199 -30
View File
@@ -65,6 +65,8 @@ struct _GdkWaylandDevice
GdkDevice *pointer;
GdkDevice *keyboard;
GdkKeymap *keymap;
GdkModifierType modifiers;
GdkWindow *pointer_focus;
GdkWindow *keyboard_focus;
@@ -376,6 +378,12 @@ _gdk_wayland_device_get_wl_keyboard (GdkDevice *device)
return GDK_DEVICE_CORE (device)->device->wl_keyboard;
}
GdkKeymap *
_gdk_wayland_device_get_keymap (GdkDevice *device)
{
return GDK_DEVICE_CORE (device)->device->keymap;
}
#if 0
static void
input_handle_motion(void *data, struct wl_input_device *input_device,
@@ -1157,36 +1165,10 @@ keyboard_handle_keymap (void *data,
uint32_t size)
{
GdkWaylandDevice *device = data;
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
GdkKeymap *gdk_keymap;
gchar *keymap_data;
struct xkb_keymap *keymap;
if (device->keymap)
g_object_unref (device->keymap);
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
{
g_critical (G_STRLOC ": Unknown keymap format");
close (fd);
return;
}
keymap_data = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (keymap_data == MAP_FAILED)
{
g_critical (G_STRLOC ": Unable to map fd for keymap %s", g_strerror (errno));
close (fd);
return;
}
keymap = xkb_map_new_from_string (display->xkb_context,
keymap_data,
format,
0);
munmap (keymap_data, size);
close (fd);
gdk_keymap = _gdk_wayland_display_get_keymap (device->display);
_gdk_wayland_keymap_update_keymap (gdk_keymap, keymap);
device->keymap = _gdk_wayland_keymap_new_from_fd (format, fd, size);
}
static void
@@ -1196,7 +1178,6 @@ keyboard_handle_enter (void *data,
struct wl_surface *surface,
struct wl_array *keys)
{
GdkWaylandDevice *device = data;
GdkEvent *event;
GdkWaylandDisplay *wayland_display =
@@ -1252,6 +1233,177 @@ keyboard_handle_leave (void *data,
_gdk_wayland_display_deliver_event (device->display, event);
}
static gboolean
keyboard_repeat (gpointer data);
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;
return modifiers;
}
static void
translate_keyboard_string (GdkEventKey *event)
{
gunichar c = 0;
gchar buf[7];
/* Fill in event->string crudely, since various programs
* depend on it.
*/
event->string = NULL;
if (event->keyval != GDK_KEY_VoidSymbol)
c = gdk_keyval_to_unicode (event->keyval);
if (c)
{
gsize bytes_written;
gint len;
/* Apply the control key - Taken from Xlib
*/
if (event->state & GDK_CONTROL_MASK)
{
if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
else if (c == '2')
{
event->string = g_memdup ("\0\0", 2);
event->length = 1;
buf[0] = '\0';
return;
}
else if (c >= '3' && c <= '7') c -= ('3' - '\033');
else if (c == '8') c = '\177';
else if (c == '/') c = '_' & 0x1F;
}
len = g_unichar_to_utf8 (c, buf);
buf[len] = '\0';
event->string = g_locale_from_utf8 (buf, len,
NULL, &bytes_written,
NULL);
if (event->string)
event->length = bytes_written;
}
else if (event->keyval == GDK_KEY_Escape)
{
event->length = 1;
event->string = g_strdup ("\033");
}
else if (event->keyval == GDK_KEY_Return ||
event->keyval == GDK_KEY_KP_Enter)
{
event->length = 1;
event->string = g_strdup ("\r");
}
if (!event->string)
{
event->length = 0;
event->string = g_strdup ("");
}
}
static gboolean
deliver_key_event(GdkWaylandDevice *device,
uint32_t time, uint32_t key, uint32_t state)
{
GdkEvent *event;
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];
device->time = time;
device->modifiers = get_modifier (xkb_state);
event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
event->key.window = device->keyboard_focus?g_object_ref (device->keyboard_focus):NULL;
gdk_event_set_device (event, device->keyboard);
event->button.time = time;
event->key.state = device->modifiers;
event->key.group = 0;
event->key.hardware_keycode = sym;
event->key.keyval = sym;
event->key.is_modifier = device->modifiers > 0;
translate_keyboard_string (&event->key);
_gdk_wayland_display_deliver_event (device->display, event);
GDK_NOTE (EVENTS,
g_message ("keyboard event, code %d, sym %d, "
"string %s, mods 0x%x",
event->key.hardware_keycode, event->key.keyval,
event->key.string, event->key.state));
device->repeat_count++;
device->repeat_key = key;
if (state == 0)
{
if (device->repeat_timer)
{
g_source_remove (device->repeat_timer);
device->repeat_timer = 0;
}
return FALSE;
}
else if (device->modifiers)
{
return FALSE;
}
else switch (device->repeat_count)
{
case 1:
if (device->repeat_timer)
{
g_source_remove (device->repeat_timer);
device->repeat_timer = 0;
}
device->repeat_timer =
gdk_threads_add_timeout (400, keyboard_repeat, device);
return TRUE;
case 2:
device->repeat_timer =
gdk_threads_add_timeout (80, keyboard_repeat, device);
return FALSE;
default:
return TRUE;
}
}
static gboolean
keyboard_repeat (gpointer data)
{
GdkWaylandDevice *device = data;
return deliver_key_event (device, device->time, device->repeat_key, 1);
}
static void
keyboard_handle_key (void *data,
struct wl_keyboard *keyboard,
@@ -1260,6 +1412,13 @@ keyboard_handle_key (void *data,
uint32_t key,
uint32_t state_w)
{
GdkWaylandDevice *device = data;
GdkWaylandDisplay *wayland_display =
GDK_WAYLAND_DISPLAY (device->display);
device->repeat_count = 0;
_gdk_wayland_display_update_serial (wayland_display, serial);
deliver_key_event (data, time, key + 8, state_w);
}
static void
@@ -1271,6 +1430,15 @@ keyboard_handle_modifiers (void *data,
uint32_t mods_locked,
uint32_t group)
{
GdkWaylandDevice *device = data;
GdkKeymap *keymap;
struct xkb_state *xkb_state;
keymap = device->keymap;
xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap);
device->modifiers = mods_depressed | mods_latched | mods_locked;
xkb_state_update_mask (xkb_state, mods_depressed, mods_latched, mods_locked, group, 0, 0);
}
static const struct wl_pointer_listener pointer_listener = {
@@ -1386,6 +1554,7 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
display_wayland = GDK_WAYLAND_DISPLAY (display);
device = g_new0 (GdkWaylandDevice, 1);
device->keymap = _gdk_wayland_keymap_new ();
device->display = display;
device->device_manager = device_manager;
+17 -6
View File
@@ -536,15 +536,26 @@ gdk_wayland_display_event_data_free (GdkDisplay *display,
GdkKeymap *
_gdk_wayland_display_get_keymap (GdkDisplay *display)
{
GdkWaylandDisplay *display_wayland;
GdkDeviceManager *device_manager;
GList *list, *l;
GdkDevice *core_keyboard = NULL;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
display_wayland = GDK_WAYLAND_DISPLAY (display);
device_manager = gdk_display_get_device_manager (display);
list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
if (!display_wayland->keymap)
display_wayland->keymap = _gdk_wayland_keymap_new (display);
for (l = list; l; l = l->next)
{
GdkDevice *device;
device = list->data;
return display_wayland->keymap;
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
continue;
core_keyboard = device;
break;
}
return core_keyboard?_gdk_wayland_device_get_keymap (core_keyboard):NULL;
}
static void
+2 -2
View File
@@ -68,7 +68,7 @@ gdk_event_source_dispatch(GSource *base,
GdkDisplay *display = source->display;
GdkEvent *event;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
event = gdk_display_get_event (display);
@@ -79,7 +79,7 @@ gdk_event_source_dispatch(GSource *base,
gdk_event_free (event);
}
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return TRUE;
}
+59 -491
View File
@@ -30,13 +30,13 @@
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <sys/mman.h>
#include "gdk.h"
#include "gdkwayland.h"
#include "gdkprivate-wayland.h"
#include "gdkinternals.h"
#include "gdkdisplay-wayland.h"
#include "gdkkeysprivate.h"
#include <xkbcommon/xkbcommon.h>
@@ -47,13 +47,9 @@ typedef struct _GdkWaylandKeymapClass GdkWaylandKeymapClass;
struct _GdkWaylandKeymap
{
GdkKeymap parent_instance;
GdkModifierType modmap[8];
struct xkb_desc *xkb;
struct xkb_keymap *keymap;
struct xkb_state *state;
xkb_mod_mask_t control_mask;
xkb_mod_mask_t alt_mask;
xkb_mod_mask_t shift_mask;
struct xkb_keymap *xkb_keymap;
struct xkb_state *xkb_state;
};
struct _GdkWaylandKeymapClass
@@ -88,13 +84,15 @@ gdk_wayland_keymap_have_bidi_layouts (GdkKeymap *keymap)
static gboolean
gdk_wayland_keymap_get_caps_lock_state (GdkKeymap *keymap)
{
return FALSE;
return xkb_state_led_name_is_active (GDK_WAYLAND_KEYMAP (keymap)->xkb_state,
XKB_LED_NAME_CAPS);
}
static gboolean
gdk_wayland_keymap_get_num_lock_state (GdkKeymap *keymap)
{
return FALSE;
return xkb_state_led_name_is_active (GDK_WAYLAND_KEYMAP (keymap)->xkb_state,
XKB_LED_NAME_NUM);
}
static gboolean
@@ -103,68 +101,15 @@ gdk_wayland_keymap_get_entries_for_keyval (GdkKeymap *keymap,
GdkKeymapKey **keys,
gint *n_keys)
{
#if 0
GArray *retval;
uint32_t keycode;
struct xkb_desc *xkb;
xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
keycode = xkb->min_key_code;
retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++)
if (n_keys)
*n_keys = 1;
if (keys)
{
gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode);
gint group = 0;
gint level = 0;
gint total_syms = XkbKeyNumSyms (xkb, keycode);
gint i = 0;
uint32_t *entry;
/* entry is an array with all syms for group 0, all
* syms for group 1, etc. and for each group the
* shift level syms are in order
*/
entry = XkbKeySymsPtr (xkb, keycode);
for (i = 0; i < total_syms; i++)
{
/* check out our cool loop invariant */
g_assert (i == (group * max_shift_levels + level));
if (entry[i] == keyval)
{
/* Found a match */
GdkKeymapKey key;
key.keycode = keycode;
key.group = group;
key.level = level;
g_array_append_val (retval, key);
g_assert (XkbKeySymEntry (xkb, keycode, level, group) ==
keyval);
}
level++;
if (level == max_shift_levels)
{
level = 0;
group++;
}
}
*keys = g_new0 (GdkKeymapKey, 1);
(*keys)->keycode = keyval;
}
*n_keys = retval->len;
*keys = (GdkKeymapKey *) g_array_free (retval, FALSE);
return *n_keys > 0;
#endif
return FALSE;
return TRUE;
}
static gboolean
@@ -174,247 +119,28 @@ gdk_wayland_keymap_get_entries_for_keycode (GdkKeymap *keymap,
guint **keyvals,
gint *n_entries)
{
#if 0
GArray *key_array;
GArray *keyval_array;
struct xkb_desc *xkb;
gint max_shift_levels;
gint group = 0;
gint level = 0;
gint total_syms;
gint i;
uint32_t *entry;
g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
g_return_val_if_fail (n_entries != NULL, FALSE);
xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
if (hardware_keycode < xkb->min_key_code ||
hardware_keycode > xkb->max_key_code)
{
if (keys)
*keys = NULL;
if (keyvals)
*keyvals = NULL;
*n_entries = 0;
return FALSE;
}
if (keys)
key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
else
key_array = NULL;
if (keyvals)
keyval_array = g_array_new (FALSE, FALSE, sizeof (guint));
else
keyval_array = NULL;
/* See sec 15.3.4 in XKB docs */
max_shift_levels = XkbKeyGroupsWidth (xkb, hardware_keycode);
total_syms = XkbKeyNumSyms (xkb, hardware_keycode);
/* entry is an array with all syms for group 0, all
* syms for group 1, etc. and for each group the
* shift level syms are in order
*/
entry = XkbKeySymsPtr (xkb, hardware_keycode);
for (i = 0; i < total_syms; i++)
{
/* check out our cool loop invariant */
g_assert (i == (group * max_shift_levels + level));
if (key_array)
{
GdkKeymapKey key;
key.keycode = hardware_keycode;
key.group = group;
key.level = level;
g_array_append_val (key_array, key);
}
if (keyval_array)
g_array_append_val (keyval_array, entry[i]);
++level;
if (level == max_shift_levels)
{
level = 0;
++group;
}
}
*n_entries = 0;
if (n_entries)
*n_entries = 1;
if (keys)
{
*n_entries = key_array->len;
*keys = (GdkKeymapKey*) g_array_free (key_array, FALSE);
*keys = g_new0 (GdkKeymapKey, 1);
(*keys)->keycode = hardware_keycode;
}
if (keyvals)
{
*n_entries = keyval_array->len;
*keyvals = (guint*) g_array_free (keyval_array, FALSE);
*keyvals = g_new0 (guint, 1);
(*keyvals)[0] = hardware_keycode;
}
return *n_entries > 0;
#endif
return FALSE;
return TRUE;
}
static guint
gdk_wayland_keymap_lookup_key (GdkKeymap *keymap,
const GdkKeymapKey *key)
{
#if 0
struct xkb_desc *xkb;
xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
return XkbKeySymEntry (xkb, key->keycode, key->level, key->group);
#endif
return 0;
return key->keycode;
}
#if 0
/* This is copied straight from XFree86 Xlib, to:
* - add the group and level return.
* - change the interpretation of mods_rtrn as described
* in the docs for gdk_keymap_translate_keyboard_state()
* It's unchanged for ease of diff against the Xlib sources; don't
* reformat it.
*/
static int
MyEnhancedXkbTranslateKeyCode(struct xkb_desc * xkb,
KeyCode key,
unsigned int mods,
unsigned int * mods_rtrn,
uint32_t * keysym_rtrn,
int * group_rtrn,
int * level_rtrn)
{
struct xkb_key_type *type;
int col,nKeyGroups;
unsigned preserve,effectiveGroup;
uint32_t *syms;
if (mods_rtrn!=NULL)
*mods_rtrn = 0;
nKeyGroups= XkbKeyNumGroups(xkb,key);
if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
if (keysym_rtrn!=NULL)
*keysym_rtrn = 0;
return 0;
}
syms = XkbKeySymsPtr(xkb,key);
/* find the offset of the effective group */
col = 0;
effectiveGroup= XkbGroupForCoreState(mods);
if ( effectiveGroup>=nKeyGroups ) {
unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
switch (XkbOutOfRangeGroupAction(groupInfo)) {
default:
effectiveGroup %= nKeyGroups;
break;
case XkbClampIntoRange:
effectiveGroup = nKeyGroups-1;
break;
case XkbRedirectIntoRange:
effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
if (effectiveGroup>=nKeyGroups)
effectiveGroup= 0;
break;
}
}
col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
type = XkbKeyKeyType(xkb,key,effectiveGroup);
preserve= 0;
if (type->map) { /* find the column (shift level) within the group */
register int i;
struct xkb_kt_map_entry *entry;
/* ---- Begin section modified for GDK ---- */
int found = 0;
for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
if (mods_rtrn) {
int bits = 0;
unsigned long tmp = entry->mods.mask;
while (tmp) {
if ((tmp & 1) == 1)
bits++;
tmp >>= 1;
}
/* We always add one-modifiers levels to mods_rtrn since
* they can't wipe out bits in the state unless the
* level would be triggered. But return other modifiers
*
*/
if (bits == 1 || (mods&type->mods.mask)==entry->mods.mask)
*mods_rtrn |= entry->mods.mask;
}
if (!found&&entry->active&&((mods&type->mods.mask)==entry->mods.mask)) {
col+= entry->level;
if (type->preserve)
preserve= type->preserve[i].mask;
if (level_rtrn)
*level_rtrn = entry->level;
found = 1;
}
}
/* ---- End section modified for GDK ---- */
}
if (keysym_rtrn!=NULL)
*keysym_rtrn= syms[col];
if (mods_rtrn) {
/* ---- Begin section modified for GDK ---- */
*mods_rtrn &= ~preserve;
/* ---- End section modified for GDK ---- */
/* ---- Begin stuff GDK comments out of the original Xlib version ---- */
/* This is commented out because xkb_info is a private struct */
#if 0
/* The Motif VTS doesn't get the help callback called if help
* is bound to Shift+<whatever>, and it appears as though it
* is XkbTranslateKeyCode that is causing the problem. The
* core X version of XTranslateKey always OR's in ShiftMask
* and LockMask for mods_rtrn, so this "fix" keeps this behavior
* and solves the VTS problem.
*/
if ((xkb->dpy)&&(xkb->dpy->xkb_info)&&
(xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) { *mods_rtrn|= (ShiftMask|LockMask);
}
#endif
/* ---- End stuff GDK comments out of the original Xlib version ---- */
}
/* ---- Begin stuff GDK adds to the original Xlib version ---- */
if (group_rtrn)
*group_rtrn = effectiveGroup;
/* ---- End stuff GDK adds to the original Xlib version ---- */
return (syms[col] != 0);
}
#endif
static gboolean
gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap,
guint hardware_keycode,
@@ -425,20 +151,11 @@ gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap,
gint *level,
GdkModifierType *consumed_modifiers)
{
#if 0
GdkWaylandKeymap *wayland_keymap;
uint32_t tmp_keyval = 0;
guint tmp_modifiers;
struct xkb_desc *xkb;
g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
g_return_val_if_fail (group < 4, FALSE);
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
xkb = wayland_keymap->xkb;
if (keyval)
*keyval = 0;
*keyval = hardware_keycode;
if (effective_group)
*effective_group = 0;
if (level)
@@ -446,138 +163,21 @@ gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap,
if (consumed_modifiers)
*consumed_modifiers = 0;
if (hardware_keycode < xkb->min_key_code ||
hardware_keycode > xkb->max_key_code)
return FALSE;
/* replace bits 13 and 14 with the provided group */
state &= ~(1 << 13 | 1 << 14);
state |= group << 13;
MyEnhancedXkbTranslateKeyCode (xkb,
hardware_keycode,
state,
&tmp_modifiers,
&tmp_keyval,
effective_group,
level);
if (state & ~tmp_modifiers & XKB_COMMON_LOCK_MASK)
tmp_keyval = gdk_keyval_to_upper (tmp_keyval);
/* We need to augment the consumed modifiers with LockMask, since
* we handle that ourselves, and also with the group bits
*/
tmp_modifiers |= XKB_COMMON_LOCK_MASK | 1 << 13 | 1 << 14;
if (consumed_modifiers)
*consumed_modifiers = tmp_modifiers;
if (keyval)
*keyval = tmp_keyval;
return tmp_keyval != 0;
#endif
return FALSE;
return TRUE;
}
#if 0
static void
update_modmap (GdkWaylandKeymap *wayland_keymap)
{
static struct {
const gchar *name;
uint32_t atom;
GdkModifierType mask;
} vmods[] = {
{ "Meta", 0, GDK_META_MASK },
{ "Super", 0, GDK_SUPER_MASK },
{ "Hyper", 0, GDK_HYPER_MASK },
{ NULL, 0, 0 }
};
gint i, j, k;
if (!vmods[0].atom)
for (i = 0; vmods[i].name; i++)
vmods[i].atom = xkb_atom(vmods[i].name);
for (i = 0; i < 8; i++)
wayland_keymap->modmap[i] = 1 << i;
for (i = 0; i < XkbNumVirtualMods; i++)
{
for (j = 0; vmods[j].atom; j++)
{
if (wayland_keymap->xkb->names->vmods[i] == vmods[j].atom)
{
for (k = 0; k < 8; k++)
{
if (wayland_keymap->xkb->server->vmods[i] & (1 << k))
wayland_keymap->modmap[k] |= vmods[j].mask;
}
}
}
}
}
#endif
static void
gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap,
GdkModifierType *state)
{
GdkWaylandKeymap *wayland_keymap;
int i;
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
for (i = 4; i < 8; i++)
{
if ((1 << i) & *state)
{
if (wayland_keymap->modmap[i] & GDK_SUPER_MASK)
*state |= GDK_SUPER_MASK;
if (wayland_keymap->modmap[i] & GDK_HYPER_MASK)
*state |= GDK_HYPER_MASK;
if (wayland_keymap->modmap[i] & GDK_META_MASK)
*state |= GDK_META_MASK;
}
}
return;
}
static gboolean
gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
GdkModifierType *state)
{
const guint vmods[] = {
GDK_SUPER_MASK, GDK_HYPER_MASK, GDK_META_MASK
};
int i, j;
GdkWaylandKeymap *wayland_keymap;
gboolean retval = TRUE;
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
for (j = 0; j < 3; j++)
{
if (*state & vmods[j])
{
for (i = 4; i < 8; i++)
{
if (wayland_keymap->modmap[i] & vmods[j])
{
if (*state & (1 << i))
retval = FALSE;
else
*state |= 1 << i;
}
}
}
}
return retval;
return TRUE;
}
static void
@@ -605,94 +205,62 @@ _gdk_wayland_keymap_init (GdkWaylandKeymap *keymap)
{
}
#if 0
static void
update_keymaps (GdkWaylandKeymap *keymap)
{
struct xkb_desc *xkb = keymap->xkb;
gint keycode, total_syms, i, modifier;
uint32_t *entry;
guint mask;
for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++)
{
total_syms = XkbKeyNumSyms (xkb, keycode);
entry = XkbKeySymsPtr (xkb, keycode);
mask = 0;
for (i = 0; i < total_syms; i++)
{
switch (entry[i]) {
case GDK_KEY_Meta_L:
case GDK_KEY_Meta_R:
mask |= GDK_META_MASK;
break;
case GDK_KEY_Hyper_L:
case GDK_KEY_Hyper_R:
mask |= GDK_HYPER_MASK;
break;
case GDK_KEY_Super_L:
case GDK_KEY_Super_R:
mask |= GDK_SUPER_MASK;
break;
}
}
modifier = g_bit_nth_lsf(xkb->map->modmap[keycode], -1);
keymap->modmap[modifier] |= mask;
}
}
#endif
GdkKeymap *
_gdk_wayland_keymap_new (GdkDisplay *display)
_gdk_wayland_keymap_new ()
{
GdkWaylandKeymap *keymap;
struct xkb_context *context;
struct xkb_rule_names names;
keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL);
GDK_KEYMAP (keymap)->display = display;
#if 0
context = xkb_context_new (0);
names.rules = "evdev";
names.model = "pc105";
names.layout = "us";
names.variant = "";
names.options = "";
keymap->xkb = xkb_compile_keymap_from_rules(&names);
update_modmap (keymap);
update_keymaps (keymap);
#endif
keymap->xkb_keymap = xkb_map_new_from_names(context, &names, XKB_MAP_COMPILE_PLACEHOLDER);
keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
xkb_context_unref (context);
return GDK_KEYMAP (keymap);
}
void
_gdk_wayland_keymap_update_keymap (GdkKeymap *gdk_keymap,
struct xkb_keymap *xkb_keymap)
GdkKeymap *
_gdk_wayland_keymap_new_from_fd (uint32_t format,
uint32_t fd, uint32_t size)
{
GdkWaylandKeymap *keymap;
struct xkb_context *context;
char *map_str;
keymap = GDK_WAYLAND_KEYMAP (gdk_keymap);
keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL);
if (keymap->keymap)
xkb_map_unref (keymap->keymap);
context = xkb_context_new (0);
keymap->keymap = xkb_keymap;
map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (map_str == MAP_FAILED) {
close(fd);
return NULL;
}
if (keymap->state)
xkb_state_unref (keymap->state);
keymap->xkb_keymap = xkb_map_new_from_string (context, map_str, format, XKB_MAP_COMPILE_PLACEHOLDER);
munmap (map_str, size);
close (fd);
keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
xkb_context_unref (context);
keymap->state = xkb_state_new (keymap->keymap);
keymap->control_mask =
1 << xkb_map_mod_get_index(keymap->keymap, "Control");
keymap->alt_mask =
1 << xkb_map_mod_get_index(keymap->keymap, "Mod1");
keymap->shift_mask =
1 << xkb_map_mod_get_index(keymap->keymap, "Shift");
return GDK_KEYMAP (keymap);
}
struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap)
struct xkb_keymap *_gdk_wayland_keymap_get_xkb_keymap (GdkKeymap *keymap)
{
return GDK_WAYLAND_KEYMAP (keymap)->xkb;
return GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
}
struct xkb_state *_gdk_wayland_keymap_get_xkb_state (GdkKeymap *keymap)
{
return GDK_WAYLAND_KEYMAP (keymap)->xkb_state;
}
+6 -6
View File
@@ -48,8 +48,10 @@ GType _gdk_wayland_window_get_type (void);
void _gdk_wayland_window_add_focus (GdkWindow *window);
void _gdk_wayland_window_remove_focus (GdkWindow *window);
GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display);
struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap);
GdkKeymap *_gdk_wayland_keymap_new (void);
GdkKeymap *_gdk_wayland_keymap_new_from_fd (uint32_t format,
uint32_t fd, uint32_t size);
struct xkb_state *_gdk_wayland_keymap_get_xkb_state (GdkKeymap *keymap);
GdkCursor *_gdk_wayland_display_get_cursor_for_type (GdkDisplay *display,
GdkCursorType cursor_type);
@@ -90,10 +92,6 @@ void _gdk_wayland_display_create_window_impl (GdkDisplay *display,
GdkWindowAttr *attributes,
gint attributes_mask);
GdkKeymap *_gdk_wayland_display_get_keymap (GdkDisplay *display);
void _gdk_wayland_keymap_update_keymap (GdkKeymap *gdk_keymap,
struct xkb_keymap *xkb_keymap);
GdkWindow *_gdk_wayland_display_get_selection_owner (GdkDisplay *display,
GdkAtom selection);
gboolean _gdk_wayland_display_set_selection_owner (GdkDisplay *display,
@@ -134,6 +132,8 @@ struct wl_seat *_gdk_wayland_device_get_wl_seat (GdkDevice *device);
struct wl_pointer *_gdk_wayland_device_get_wl_pointer (GdkDevice *device);
struct wl_keyboard *_gdk_wayland_device_get_wl_keyboard (GdkDevice *device);
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);
+68 -2
View File
@@ -77,6 +77,9 @@ struct _GdkWaylandMonitor
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
#define MM_PER_INCH 25
#define DEFAULT_DPI 96
static void
init_monitor_geometry (GdkWaylandMonitor *monitor,
int x, int y, int width, int height)
@@ -86,8 +89,8 @@ init_monitor_geometry (GdkWaylandMonitor *monitor,
monitor->geometry.width = width;
monitor->geometry.height = height;
monitor->width_mm = -1;
monitor->height_mm = -1;
monitor->width_mm = width/DEFAULT_DPI*MM_PER_INCH;
monitor->height_mm = height/DEFAULT_DPI*MM_PER_INCH;
monitor->output_name = NULL;
monitor->manufacturer = NULL;
}
@@ -297,6 +300,69 @@ gdk_wayland_screen_get_setting (GdkScreen *screen,
const gchar *name,
GValue *value)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
if (strcmp ("gtk-theme-name", name) == 0)
{
const gchar *s = "Adwaita";
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
g_value_set_string (value, s);
return TRUE;
}
else if (strcmp ("gtk-icon-theme-name", name) == 0)
{
const gchar *s = "gnome";
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
g_value_set_string (value, s);
return TRUE;
}
else if (strcmp ("gtk-double-click-time", name) == 0)
{
gint i = 250;
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
g_value_set_int (value, i);
return TRUE;
}
else if (strcmp ("gtk-double-click-distance", name) == 0)
{
gint i = 5;
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
g_value_set_int (value, i);
return TRUE;
}
else if (strcmp ("gtk-dnd-drag-threshold", name) == 0)
{
gint i = 8;
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
g_value_set_int (value, i);
return TRUE;
}
else if (strcmp ("gtk-split-cursor", name) == 0)
{
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : FALSE\n", name));
g_value_set_boolean (value, FALSE);
return TRUE;
}
else if (strcmp ("gtk-alternative-button-order", name) == 0)
{
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
g_value_set_boolean (value, TRUE);
return TRUE;
}
else if (strcmp ("gtk-alternative-sort-arrows", name) == 0)
{
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
g_value_set_boolean (value, TRUE);
return TRUE;
}
else if (strcmp ("gtk-xft-dpi", name) == 0)
{
gint i = 96*1024;
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
g_value_set_int (value, i);
return TRUE;
}
return FALSE;
}
+16 -14
View File
@@ -633,23 +633,25 @@ gdk_wayland_window_map (GdkWindow *window)
{
if (impl->transient_for)
{
struct wl_seat *grab_input_seat = NULL;
parent = GDK_WINDOW_IMPL_WAYLAND (impl->transient_for->impl);
if (impl->hint & GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
impl->hint & GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
impl->hint & GDK_WINDOW_TYPE_HINT_COMBO)
/* Use the device that was used for the grab as the device for
* the popup window setup - so this relies on GTK+ taking the
* grab before showing the popup window.
*/
if (impl->grab_input_seat)
grab_input_seat = impl->grab_input_seat;
if (!grab_input_seat)
grab_input_seat = parent->grab_input_seat;
if (grab_input_seat &&
(impl->hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
impl->hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
impl->hint == GDK_WINDOW_TYPE_HINT_COMBO))
{
struct wl_seat *grab_input_seat = NULL;
/* Use the device that was used for the grab as the device for
* the popup window setup - so this relies on GTK+ taking the
* grab before showing the popup window.
*/
if (impl->grab_input_seat)
grab_input_seat = impl->grab_input_seat;
if (!grab_input_seat)
grab_input_seat = parent->grab_input_seat;
wl_shell_surface_set_popup (impl->shell_surface,
grab_input_seat,
+6 -6
View File
@@ -3326,7 +3326,7 @@ gdk_event_prepare (GSource *source,
{
gboolean retval;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
*timeout = -1;
@@ -3334,7 +3334,7 @@ gdk_event_prepare (GSource *source,
(modal_win32_dialog == NULL &&
GetQueueStatus (QS_ALLINPUT) != 0));
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return retval;
}
@@ -3344,7 +3344,7 @@ gdk_event_check (GSource *source)
{
gboolean retval;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
if (event_poll_fd.revents & G_IO_IN)
{
@@ -3357,7 +3357,7 @@ gdk_event_check (GSource *source)
retval = FALSE;
}
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return retval;
}
@@ -3369,7 +3369,7 @@ gdk_event_dispatch (GSource *source,
{
GdkEvent *event;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
_gdk_win32_display_queue_events (_gdk_display);
event = _gdk_event_unqueue (_gdk_display);
@@ -3389,7 +3389,7 @@ gdk_event_dispatch (GSource *source,
}
}
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return TRUE;
}
+2 -2
View File
@@ -1483,11 +1483,11 @@ process_internal_connection (GIOChannel *gioc,
{
GdkInternalConnection *connection = (GdkInternalConnection *)data;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
XProcessInternalConnection ((Display*)connection->display, connection->fd);
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return TRUE;
}
+6 -6
View File
@@ -273,13 +273,13 @@ gdk_event_source_prepare (GSource *source,
GdkDisplay *display = ((GdkEventSource*) source)->display;
gboolean retval;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
*timeout = -1;
retval = (_gdk_event_queue_find_first (display) != NULL ||
gdk_check_xpending (display));
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return retval;
}
@@ -290,7 +290,7 @@ gdk_event_source_check (GSource *source)
GdkEventSource *event_source = (GdkEventSource*) source;
gboolean retval;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
if (event_source->event_poll_fd.revents & G_IO_IN)
retval = (_gdk_event_queue_find_first (event_source->display) != NULL ||
@@ -298,7 +298,7 @@ gdk_event_source_check (GSource *source)
else
retval = FALSE;
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return retval;
}
@@ -349,7 +349,7 @@ gdk_event_source_dispatch (GSource *source,
GdkDisplay *display = ((GdkEventSource*) source)->display;
GdkEvent *event;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
event = gdk_display_get_event (display);
@@ -360,7 +360,7 @@ gdk_event_source_dispatch (GSource *source,
gdk_event_free (event);
}
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return TRUE;
}
+7 -4
View File
@@ -394,19 +394,20 @@ gtk_appchooser_impl_c_sources = \
gtkappchooseronlinepk.c
endif
gtk_private_type_h_sources = \
gtkcsstypesprivate.h
gtk_private_type_h_sources = \
gtkcsstypesprivate.h \
gtktexthandleprivate.h
# GTK+ header files that don't get installed
gtk_private_h_sources = \
gactionmuxer.h \
gsimpleactionobserver.h \
gactionobserver.h \
gactionobservable.h \
gtkapplicationprivate.h \
gtkaccelgroupprivate.h \
gtkaccelmapprivate.h \
gtkactionhelper.h \
gtkallocatedbitmaskprivate.h \
gtkappchooserprivate.h \
gtkappchoosermodule.h \
@@ -525,6 +526,7 @@ gtk_private_h_sources = \
gtktextbtree.h \
gtktextbufferserialize.h \
gtktextchildprivate.h \
gtktexthandleprivate.h \
gtktextiterprivate.h \
gtktextmarkprivate.h \
gtktextsegment.h \
@@ -571,7 +573,6 @@ deprecated_c_sources = \
gtk_base_c_sources = \
$(deprecated_c_sources) \
gactionmuxer.c \
gsimpleactionobserver.c \
gactionobserver.c \
gactionobservable.c \
gtkactionable.c \
@@ -586,6 +587,7 @@ gtk_base_c_sources = \
gtkaccelmap.c \
gtkaccessible.c \
gtkaction.c \
gtkactionhelper.c \
gtkactiongroup.c \
gtkactivatable.c \
gtkadjustment.c \
@@ -821,6 +823,7 @@ gtk_base_c_sources = \
gtktextbufferserialize.c \
gtktextchild.c \
gtktextdisplay.c \
gtktexthandle.c \
gtktextiter.c \
gtktextlayout.c \
gtktextmark.c \
+2 -2
View File
@@ -26,13 +26,13 @@ G_DEFINE_TYPE (GailMisc, _gail_misc, ATK_TYPE_MISC)
static void
gail_misc_threads_enter (AtkMisc *misc)
{
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
static void
gail_misc_threads_leave (AtkMisc *misc)
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
}
static void
+39 -44
View File
@@ -20,6 +20,7 @@
#include <gtk/gtk.h>
#include "gtkpango.h"
#include "gtkentryaccessible.h"
#include "gtkentryprivate.h"
#include "gtkcomboboxaccessible.h"
/* Callbacks */
@@ -213,22 +214,12 @@ gtk_entry_accessible_get_text (AtkText *atk_text,
gint end_pos)
{
GtkWidget *widget;
const gchar *text;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
if (widget == NULL)
return NULL;
/* FIXME: is this acceptable ? */
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
return g_strdup ("");
text = gtk_entry_get_text (GTK_ENTRY (widget));
if (text)
return g_utf8_substring (text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (text, -1));
return NULL;
return _gtk_entry_get_display_text (GTK_ENTRY (widget), start_pos, end_pos);
}
static gchar *
@@ -244,10 +235,6 @@ gtk_entry_accessible_get_text_before_offset (AtkText *text,
if (widget == NULL)
return NULL;
/* FIXME: is this acceptable ? */
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
return g_strdup ("");
return _gtk_pango_get_text_before (gtk_entry_get_layout (GTK_ENTRY (widget)),
boundary_type, offset,
start_offset, end_offset);
@@ -266,10 +253,6 @@ gtk_entry_accessible_get_text_at_offset (AtkText *text,
if (widget == NULL)
return NULL;
/* FIXME: is this acceptable ? */
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
return g_strdup ("");
return _gtk_pango_get_text_at (gtk_entry_get_layout (GTK_ENTRY (widget)),
boundary_type, offset,
start_offset, end_offset);
@@ -288,10 +271,6 @@ gtk_entry_accessible_get_text_after_offset (AtkText *text,
if (widget == NULL)
return NULL;
/* FIXME: is this acceptable ? */
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
return g_strdup ("");
return _gtk_pango_get_text_after (gtk_entry_get_layout (GTK_ENTRY (widget)),
boundary_type, offset,
start_offset, end_offset);
@@ -301,18 +280,23 @@ static gint
gtk_entry_accessible_get_character_count (AtkText *atk_text)
{
GtkWidget *widget;
const gchar *text;
gchar *text;
glong char_count;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
if (widget == NULL)
return 0;
text = gtk_entry_get_text (GTK_ENTRY (widget));
text = _gtk_entry_get_display_text (GTK_ENTRY (widget), 0, -1);
char_count = 0;
if (text)
return g_utf8_strlen (text, -1);
{
char_count = g_utf8_strlen (text, -1);
g_free (text);
}
return 0;
return char_count;
}
static gint
@@ -415,7 +399,7 @@ gtk_entry_accessible_get_character_extents (AtkText *text,
GtkWidget *widget;
GtkEntry *entry;
PangoRectangle char_rect;
const gchar *entry_text;
gchar *entry_text;
gint index, x_layout, y_layout;
GdkWindow *window;
gint x_window, y_window;
@@ -427,8 +411,10 @@ gtk_entry_accessible_get_character_extents (AtkText *text,
entry = GTK_ENTRY (widget);
gtk_entry_get_layout_offsets (entry, &x_layout, &y_layout);
entry_text = gtk_entry_get_text (entry);
entry_text = _gtk_entry_get_display_text (entry, 0, -1);
index = g_utf8_offset_to_pointer (entry_text, offset) - entry_text;
g_free (entry_text);
pango_layout_index_to_pos (gtk_entry_get_layout (entry), index, &char_rect);
pango_extents_to_pixels (&char_rect, NULL);
@@ -458,11 +444,12 @@ gtk_entry_accessible_get_offset_at_point (AtkText *atk_text,
{
GtkWidget *widget;
GtkEntry *entry;
const gchar *text;
gchar *text;
gint index, x_layout, y_layout;
gint x_window, y_window;
gint x_local, y_local;
GdkWindow *window;
glong offset;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
if (widget == NULL)
@@ -497,13 +484,15 @@ gtk_entry_accessible_get_offset_at_point (AtkText *atk_text,
index = -1;
}
offset = -1;
if (index != -1)
{
text = gtk_entry_get_text (entry);
return g_utf8_pointer_to_offset (text, text + index);
text = _gtk_entry_get_display_text (entry, 0, -1);
offset = g_utf8_pointer_to_offset (text, text + index);
g_free (text);
}
return -1;
return offset;
}
static gint
@@ -620,23 +609,28 @@ gtk_entry_accessible_get_character_at_offset (AtkText *atk_text,
gint offset)
{
GtkWidget *widget;
const gchar *text;
gchar *text;
gchar *index;
gunichar result;
result = '\0';
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
if (widget == NULL)
return '\0';
return result;
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
return '\0';
return result;
text = gtk_entry_get_text (GTK_ENTRY (widget));
if (offset >= g_utf8_strlen (text, -1))
return '\0';
text = _gtk_entry_get_display_text (GTK_ENTRY (widget), 0, -1);
if (offset < g_utf8_strlen (text, -1))
{
index = g_utf8_offset_to_pointer (text, offset);
result = g_utf8_get_char (index);
g_free (text);
}
index = g_utf8_offset_to_pointer (text, offset);
return g_utf8_get_char (index);
return result;
}
static void
@@ -870,10 +864,11 @@ delete_text_cb (GtkEditable *editable,
if (end < 0)
{
const gchar *text;
gchar *text;
text = gtk_entry_get_text (GTK_ENTRY (editable));
text = _gtk_entry_get_display_text (GTK_ENTRY (editable), 0, -1);
end = g_utf8_strlen (text, -1);
g_free (text);
}
if (end == start)
+367 -97
View File
@@ -63,14 +63,24 @@ struct _GActionMuxer
{
GObject parent_instance;
GHashTable *actions;
GHashTable *observed_actions;
GHashTable *groups;
GActionMuxer *parent;
};
G_DEFINE_TYPE_WITH_CODE (GActionMuxer, g_action_muxer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_action_muxer_group_iface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVABLE, g_action_muxer_observable_iface_init))
enum
{
PROP_0,
PROP_PARENT,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES];
typedef struct
{
GActionMuxer *muxer;
@@ -86,147 +96,243 @@ typedef struct
gulong handler_ids[4];
} Group;
static void
g_action_muxer_append_group_actions (gpointer key,
gpointer value,
gpointer user_data)
{
const gchar *prefix = key;
Group *group = value;
GArray *actions = user_data;
gchar **group_actions;
gchar **action;
group_actions = g_action_group_list_actions (group->group);
for (action = group_actions; *action; action++)
{
gchar *fullname;
fullname = g_strconcat (prefix, ".", *action, NULL);
g_array_append_val (actions, fullname);
}
g_strfreev (group_actions);
}
static gchar **
g_action_muxer_list_actions (GActionGroup *action_group)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
GHashTableIter iter;
gchar *key;
gchar **keys;
gsize i;
GArray *actions;
keys = g_new (gchar *, g_hash_table_size (muxer->actions) + 1);
actions = g_array_new (TRUE, FALSE, sizeof (gchar *));
i = 0;
g_hash_table_iter_init (&iter, muxer->actions);
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
keys[i++] = g_strdup (key);
keys[i] = NULL;
for ( ; muxer != NULL; muxer = muxer->parent)
{
g_hash_table_foreach (muxer->groups,
g_action_muxer_append_group_actions,
actions);
}
return keys;
return (gchar **) g_array_free (actions, FALSE);
}
static Group *
g_action_muxer_find_group (GActionMuxer *muxer,
const gchar **name)
const gchar *full_name,
const gchar **action_name)
{
const gchar *dot;
gchar *prefix;
Group *group;
dot = strchr (*name, '.');
dot = strchr (full_name, '.');
if (!dot)
return NULL;
prefix = g_strndup (*name, dot - *name);
prefix = g_strndup (full_name, dot - full_name);
group = g_hash_table_lookup (muxer->groups, prefix);
g_free (prefix);
*name = dot + 1;
if (action_name)
*action_name = dot + 1;
return group;
}
static Action *
g_action_muxer_lookup_action (GActionMuxer *muxer,
const gchar *prefix,
const gchar *action_name,
gchar **fullname)
{
Action *action;
*fullname = g_strconcat (prefix, ".", action_name, NULL);
action = g_hash_table_lookup (muxer->actions, *fullname);
return action;
}
static void
g_action_muxer_action_enabled_changed (GActionGroup *action_group,
g_action_muxer_action_enabled_changed (GActionMuxer *muxer,
const gchar *action_name,
gboolean enabled,
gpointer user_data)
gboolean enabled)
{
Group *group = user_data;
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
action = g_hash_table_lookup (muxer->observed_actions, action_name);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_enabled_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, enabled);
g_action_group_action_enabled_changed (G_ACTION_GROUP (group->muxer), fullname, enabled);
g_action_observer_action_enabled_changed (node->data, G_ACTION_OBSERVABLE (muxer), action_name, enabled);
g_action_group_action_enabled_changed (G_ACTION_GROUP (muxer), action_name, enabled);
}
static void
g_action_muxer_group_action_enabled_changed (GActionGroup *action_group,
const gchar *action_name,
gboolean enabled,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
g_action_muxer_action_enabled_changed (group->muxer, fullname, enabled);
g_free (fullname);
}
static void
g_action_muxer_action_state_changed (GActionGroup *action_group,
g_action_muxer_parent_action_enabled_changed (GActionGroup *action_group,
const gchar *action_name,
gboolean enabled,
gpointer user_data)
{
GActionMuxer *muxer = user_data;
g_action_muxer_action_enabled_changed (muxer, action_name, enabled);
}
static void
g_action_muxer_action_state_changed (GActionMuxer *muxer,
const gchar *action_name,
GVariant *state,
gpointer user_data)
GVariant *state)
{
Group *group = user_data;
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
action = g_hash_table_lookup (muxer->observed_actions, action_name);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_state_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, state);
g_action_group_action_state_changed (G_ACTION_GROUP (group->muxer), fullname, state);
g_action_observer_action_state_changed (node->data, G_ACTION_OBSERVABLE (muxer), action_name, state);
g_action_group_action_state_changed (G_ACTION_GROUP (muxer), action_name, state);
}
static void
g_action_muxer_group_action_state_changed (GActionGroup *action_group,
const gchar *action_name,
GVariant *state,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
g_action_muxer_action_state_changed (group->muxer, fullname, state);
g_free (fullname);
}
static void
g_action_muxer_action_added (GActionGroup *action_group,
g_action_muxer_parent_action_state_changed (GActionGroup *action_group,
const gchar *action_name,
GVariant *state,
gpointer user_data)
{
GActionMuxer *muxer = user_data;
g_action_muxer_action_state_changed (muxer, action_name, state);
}
static void
g_action_muxer_action_added (GActionMuxer *muxer,
const gchar *action_name,
gpointer user_data)
GActionGroup *original_group,
const gchar *orignal_action_name)
{
const GVariantType *parameter_type;
Group *group = user_data;
gboolean enabled;
GVariant *state;
Action *action;
if (g_action_group_query_action (group->group, action_name, &enabled, &parameter_type, NULL, NULL, &state))
action = g_hash_table_lookup (muxer->observed_actions, action_name);
if (action && action->watchers &&
g_action_group_query_action (original_group, orignal_action_name,
&enabled, &parameter_type, NULL, NULL, &state))
{
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
for (node = action->watchers; node; node = node->next)
g_action_observer_action_added (node->data,
G_ACTION_OBSERVABLE (group->muxer),
fullname, parameter_type, enabled, state);
g_action_group_action_added (G_ACTION_GROUP (group->muxer), fullname);
G_ACTION_OBSERVABLE (muxer),
action_name, parameter_type, enabled, state);
if (state)
g_variant_unref (state);
g_free (fullname);
}
g_action_group_action_added (G_ACTION_GROUP (muxer), action_name);
}
static void
g_action_muxer_action_removed (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
g_action_muxer_action_added_to_group (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
g_action_muxer_action_added (group->muxer, fullname, action_group, action_name);
g_free (fullname);
}
static void
g_action_muxer_action_added_to_parent (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
GActionMuxer *muxer = user_data;
g_action_muxer_action_added (muxer, action_name, action_group, action_name);
}
static void
g_action_muxer_action_removed (GActionMuxer *muxer,
const gchar *action_name)
{
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
action = g_hash_table_lookup (muxer->observed_actions, action_name);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_removed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname);
g_action_group_action_removed (G_ACTION_GROUP (group->muxer), fullname);
g_action_observer_action_removed (node->data, G_ACTION_OBSERVABLE (muxer), action_name);
g_action_group_action_removed (G_ACTION_GROUP (muxer), action_name);
}
static void
g_action_muxer_action_removed_from_group (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
g_action_muxer_action_removed (group->muxer, fullname);
g_free (fullname);
}
static void
g_action_muxer_action_removed_from_parent (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
GActionMuxer *muxer = user_data;
g_action_muxer_action_removed (muxer, action_name);
}
static gboolean
g_action_muxer_query_action (GActionGroup *action_group,
const gchar *action_name,
@@ -238,14 +344,20 @@ g_action_muxer_query_action (GActionGroup *action_group,
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
const gchar *unprefixed_name;
group = g_action_muxer_find_group (muxer, &action_name);
group = g_action_muxer_find_group (muxer, action_name, &unprefixed_name);
if (!group)
return FALSE;
if (group)
return g_action_group_query_action (group->group, unprefixed_name, enabled,
parameter_type, state_type, state_hint, state);
return g_action_group_query_action (group->group, action_name, enabled,
parameter_type, state_type, state_hint, state);
if (muxer->parent)
return g_action_group_query_action (G_ACTION_GROUP (muxer->parent), action_name,
enabled, parameter_type,
state_type, state_hint, state);
return FALSE;
}
static void
@@ -255,11 +367,14 @@ g_action_muxer_activate_action (GActionGroup *action_group,
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
const gchar *unprefixed_name;
group = g_action_muxer_find_group (muxer, &action_name);
group = g_action_muxer_find_group (muxer, action_name, &unprefixed_name);
if (group)
g_action_group_activate_action (group->group, action_name, parameter);
g_action_group_activate_action (group->group, unprefixed_name, parameter);
else if (muxer->parent)
g_action_group_activate_action (G_ACTION_GROUP (muxer->parent), action_name, parameter);
}
static void
@@ -269,11 +384,14 @@ g_action_muxer_change_action_state (GActionGroup *action_group,
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
const gchar *unprefixed_name;
group = g_action_muxer_find_group (muxer, &action_name);
group = g_action_muxer_find_group (muxer, action_name, &unprefixed_name);
if (group)
g_action_group_change_action_state (group->group, action_name, state);
g_action_group_change_action_state (group->group, unprefixed_name, state);
else if (muxer->parent)
g_action_group_change_action_state (G_ACTION_GROUP (muxer->parent), action_name, state);
}
static void
@@ -289,14 +407,7 @@ g_action_muxer_unregister_internal (Action *action,
*ptr = g_slist_remove (*ptr, observer);
if (action->watchers == NULL)
{
g_hash_table_remove (muxer->actions, action->fullname);
g_free (action->fullname);
g_slice_free (Action, action);
g_object_unref (muxer);
}
g_hash_table_remove (muxer->observed_actions, action->fullname);
break;
}
@@ -319,16 +430,16 @@ g_action_muxer_register_observer (GActionObservable *observable,
GActionMuxer *muxer = G_ACTION_MUXER (observable);
Action *action;
action = g_hash_table_lookup (muxer->actions, name);
action = g_hash_table_lookup (muxer->observed_actions, name);
if (action == NULL)
{
action = g_slice_new (Action);
action->muxer = g_object_ref (muxer);
action->muxer = muxer;
action->fullname = g_strdup (name);
action->watchers = NULL;
g_hash_table_insert (muxer->actions, action->fullname, action);
g_hash_table_insert (muxer->observed_actions, action->fullname, action);
}
action->watchers = g_slist_prepend (action->watchers, observer);
@@ -343,7 +454,7 @@ g_action_muxer_unregister_observer (GActionObservable *observable,
GActionMuxer *muxer = G_ACTION_MUXER (observable);
Action *action;
action = g_hash_table_lookup (muxer->actions, name);
action = g_hash_table_lookup (muxer->observed_actions, name);
g_object_weak_unref (G_OBJECT (observer), g_action_muxer_weak_notify, action);
g_action_muxer_unregister_internal (action, observer);
}
@@ -364,23 +475,97 @@ g_action_muxer_free_group (gpointer data)
g_slice_free (Group, group);
}
static void
g_action_muxer_free_action (gpointer data)
{
Action *action = data;
GSList *it;
for (it = action->watchers; it; it = it->next)
g_object_weak_unref (G_OBJECT (it->data), g_action_muxer_weak_notify, action);
g_slist_free (action->watchers);
g_free (action->fullname);
g_slice_free (Action, action);
}
static void
g_action_muxer_finalize (GObject *object)
{
GActionMuxer *muxer = G_ACTION_MUXER (object);
g_assert_cmpint (g_hash_table_size (muxer->actions), ==, 0);
g_hash_table_unref (muxer->actions);
g_assert_cmpint (g_hash_table_size (muxer->observed_actions), ==, 0);
g_hash_table_unref (muxer->observed_actions);
g_hash_table_unref (muxer->groups);
G_OBJECT_CLASS (g_action_muxer_parent_class)
->finalize (object);
}
static void
g_action_muxer_dispose (GObject *object)
{
GActionMuxer *muxer = G_ACTION_MUXER (object);
if (muxer->parent)
{
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_action_added_to_parent, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_action_removed_from_parent, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_parent_action_enabled_changed, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_parent_action_state_changed, muxer);
g_clear_object (&muxer->parent);
}
g_hash_table_remove_all (muxer->observed_actions);
G_OBJECT_CLASS (g_action_muxer_parent_class)
->dispose (object);
}
static void
g_action_muxer_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GActionMuxer *muxer = G_ACTION_MUXER (object);
switch (property_id)
{
case PROP_PARENT:
g_value_set_object (value, g_action_muxer_get_parent (muxer));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
g_action_muxer_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GActionMuxer *muxer = G_ACTION_MUXER (object);
switch (property_id)
{
case PROP_PARENT:
g_action_muxer_set_parent (muxer, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
g_action_muxer_init (GActionMuxer *muxer)
{
muxer->actions = g_hash_table_new (g_str_hash, g_str_equal);
muxer->observed_actions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_action_muxer_free_action);
muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_action_muxer_free_group);
}
@@ -403,7 +588,18 @@ g_action_muxer_group_iface_init (GActionGroupInterface *iface)
static void
g_action_muxer_class_init (GObjectClass *class)
{
class->get_property = g_action_muxer_get_property;
class->set_property = g_action_muxer_set_property;
class->finalize = g_action_muxer_finalize;
class->dispose = g_action_muxer_dispose;
properties[PROP_PARENT] = g_param_spec_object ("parent", "Parent",
"The parent muxer",
G_TYPE_ACTION_MUXER,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (class, NUM_PROPERTIES, properties);
}
/*
@@ -447,17 +643,17 @@ g_action_muxer_insert (GActionMuxer *muxer,
actions = g_action_group_list_actions (group->group);
for (i = 0; actions[i]; i++)
g_action_muxer_action_added (group->group, actions[i], group);
g_action_muxer_action_added_to_group (group->group, actions[i], group);
g_strfreev (actions);
group->handler_ids[0] = g_signal_connect (group->group, "action-added",
G_CALLBACK (g_action_muxer_action_added), group);
G_CALLBACK (g_action_muxer_action_added_to_group), group);
group->handler_ids[1] = g_signal_connect (group->group, "action-removed",
G_CALLBACK (g_action_muxer_action_removed), group);
G_CALLBACK (g_action_muxer_action_removed_from_group), group);
group->handler_ids[2] = g_signal_connect (group->group, "action-enabled-changed",
G_CALLBACK (g_action_muxer_action_enabled_changed), group);
G_CALLBACK (g_action_muxer_group_action_enabled_changed), group);
group->handler_ids[3] = g_signal_connect (group->group, "action-state-changed",
G_CALLBACK (g_action_muxer_action_state_changed), group);
G_CALLBACK (g_action_muxer_group_action_state_changed), group);
}
/*
@@ -487,7 +683,7 @@ g_action_muxer_remove (GActionMuxer *muxer,
actions = g_action_group_list_actions (group->group);
for (i = 0; actions[i]; i++)
g_action_muxer_action_removed (group->group, actions[i], group);
g_action_muxer_action_removed_from_group (group->group, actions[i], group);
g_strfreev (actions);
g_action_muxer_free_group (group);
@@ -504,3 +700,77 @@ g_action_muxer_new (void)
{
return g_object_new (G_TYPE_ACTION_MUXER, NULL);
}
/* g_action_muxer_get_parent:
* @muxer: a #GActionMuxer
*
* Returns: (transfer-none): the parent of @muxer, or NULL.
*/
GActionMuxer *
g_action_muxer_get_parent (GActionMuxer *muxer)
{
g_return_val_if_fail (G_IS_ACTION_MUXER (muxer), NULL);
return muxer->parent;
}
/* g_action_muxer_set_parent:
* @muxer: a #GActionMuxer
* @parent: (allow-none): the new parent #GActionMuxer
*
* Sets the parent of @muxer to @parent.
*/
void
g_action_muxer_set_parent (GActionMuxer *muxer,
GActionMuxer *parent)
{
g_return_if_fail (G_IS_ACTION_MUXER (muxer));
g_return_if_fail (parent == NULL || G_IS_ACTION_MUXER (parent));
if (muxer->parent == parent)
return;
if (muxer->parent != NULL)
{
gchar **actions;
gchar **it;
actions = g_action_group_list_actions (G_ACTION_GROUP (muxer->parent));
for (it = actions; *it; it++)
g_action_muxer_action_removed (muxer, *it);
g_strfreev (actions);
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_action_added_to_parent, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_action_removed_from_parent, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_parent_action_enabled_changed, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_parent_action_state_changed, muxer);
g_object_unref (muxer->parent);
}
muxer->parent = parent;
if (muxer->parent != NULL)
{
gchar **actions;
gchar **it;
g_object_ref (muxer->parent);
actions = g_action_group_list_actions (G_ACTION_GROUP (muxer->parent));
for (it = actions; *it; it++)
g_action_muxer_action_added (muxer, *it, G_ACTION_GROUP (muxer->parent), *it);
g_strfreev (actions);
g_signal_connect (muxer->parent, "action-added",
G_CALLBACK (g_action_muxer_action_added_to_parent), muxer);
g_signal_connect (muxer->parent, "action-removed",
G_CALLBACK (g_action_muxer_action_removed_from_parent), muxer);
g_signal_connect (muxer->parent, "action-enabled-changed",
G_CALLBACK (g_action_muxer_parent_action_enabled_changed), muxer);
g_signal_connect (muxer->parent, "action-state-changed",
G_CALLBACK (g_action_muxer_parent_action_state_changed), muxer);
}
g_object_notify_by_pspec (G_OBJECT (muxer), properties[PROP_PARENT]);
}
+7
View File
@@ -46,6 +46,13 @@ G_GNUC_INTERNAL
void g_action_muxer_remove (GActionMuxer *muxer,
const gchar *prefix);
G_GNUC_INTERNAL
GActionMuxer * g_action_muxer_get_parent (GActionMuxer *muxer);
G_GNUC_INTERNAL
void g_action_muxer_set_parent (GActionMuxer *muxer,
GActionMuxer *parent);
G_END_DECLS
#endif /* __G_ACTION_MUXER_H__ */
-286
View File
@@ -1,286 +0,0 @@
/*
* Copyright © 2012 Canonical Limited
*
* 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
* licence 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/>.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gsimpleactionobserver.h"
#include "gactionobservable.h"
typedef GObjectClass GSimpleActionObserverClass;
struct _GSimpleActionObserver
{
GObject parent_instance;
GActionGroup *action_group;
gchar *action_name;
GVariant *target;
gboolean can_activate;
gboolean active;
gboolean enabled;
gint reporting;
};
static void g_simple_action_observer_init_iface (GActionObserverInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GSimpleActionObserver, g_simple_action_observer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVER, g_simple_action_observer_init_iface));
enum
{
PROP_0,
PROP_ACTIVE,
PROP_ENABLED,
N_PROPS
};
static GParamSpec *g_simple_action_observer_pspecs[N_PROPS];
static void
g_simple_action_observer_action_added (GActionObserver *g_observer,
GActionObservable *observable,
const gchar *action_name,
const GVariantType *parameter_type,
gboolean enabled,
GVariant *state)
{
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (g_observer);
gboolean active;
/* we can only activate if we have the correct type of parameter */
observer->can_activate = (observer->target == NULL && parameter_type == NULL) ||
(observer->target != NULL && parameter_type != NULL &&
g_variant_is_of_type (observer->target, parameter_type));
if (observer->can_activate)
{
if (observer->target != NULL && state != NULL)
active = g_variant_equal (state, observer->target);
else if (state != NULL && g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
active = g_variant_get_boolean (state);
else
active = FALSE;
if (active != observer->active)
{
observer->active = active;
observer->reporting++;
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ACTIVE]);
observer->reporting--;
}
if (enabled != observer->enabled)
{
observer->enabled = enabled;
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ENABLED]);
}
}
}
static void
g_simple_action_observer_action_enabled_changed (GActionObserver *g_observer,
GActionObservable *observable,
const gchar *action_name,
gboolean enabled)
{
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (g_observer);
if (!observer->can_activate)
return;
if (enabled != observer->enabled)
{
observer->enabled = enabled;
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ENABLED]);
}
}
static void
g_simple_action_observer_action_state_changed (GActionObserver *g_observer,
GActionObservable *observable,
const gchar *action_name,
GVariant *state)
{
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (g_observer);
gboolean active = FALSE;
if (!observer->can_activate)
return;
if (observer->target)
active = g_variant_equal (state, observer->target);
else if (g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
active = g_variant_get_boolean (state);
if (active != observer->active)
{
observer->active = active;
observer->reporting++;
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ACTIVE]);
observer->reporting--;
}
}
static void
g_simple_action_observer_action_removed (GActionObserver *g_observer,
GActionObservable *observable,
const gchar *action_name)
{
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (g_observer);
if (!observer->can_activate)
return;
observer->can_activate = FALSE;
if (observer->active)
{
observer->active = FALSE;
observer->reporting++;
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ACTIVE]);
observer->reporting--;
}
if (observer->enabled)
{
observer->enabled = FALSE;
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ENABLED]);
}
}
static void
g_simple_action_observer_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (object);
switch (prop_id)
{
case PROP_ACTIVE:
g_value_set_boolean (value, observer->active);
break;
case PROP_ENABLED:
g_value_set_boolean (value, observer->enabled);
break;
default:
g_assert_not_reached ();
}
}
static void
g_simple_action_observer_finalize (GObject *object)
{
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (object);
g_object_unref (observer->action_group);
g_free (observer->action_name);
if (observer->target)
g_variant_unref (observer->target);
G_OBJECT_CLASS (g_simple_action_observer_parent_class)
->finalize (object);
}
static void
g_simple_action_observer_init (GSimpleActionObserver *observer)
{
}
static void
g_simple_action_observer_init_iface (GActionObserverInterface *iface)
{
iface->action_added = g_simple_action_observer_action_added;
iface->action_enabled_changed = g_simple_action_observer_action_enabled_changed;
iface->action_state_changed = g_simple_action_observer_action_state_changed;
iface->action_removed = g_simple_action_observer_action_removed;
}
static void
g_simple_action_observer_class_init (GObjectClass *class)
{
class->get_property = g_simple_action_observer_get_property;
class->finalize = g_simple_action_observer_finalize;
g_simple_action_observer_pspecs[PROP_ACTIVE] = g_param_spec_boolean ("active", "active", "active", FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_simple_action_observer_pspecs[PROP_ENABLED] = g_param_spec_boolean ("enabled", "enabled", "enabled", FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (class, N_PROPS, g_simple_action_observer_pspecs);
}
GSimpleActionObserver *
g_simple_action_observer_new (GActionObservable *observable,
const gchar *action_name,
GVariant *target)
{
GSimpleActionObserver *observer;
const GVariantType *type;
gboolean enabled;
GVariant *state;
observer = g_object_new (G_TYPE_SIMPLE_ACTION_OBSERVER, NULL);
observer->action_group = g_object_ref (observable);
observer->action_name = g_strdup (action_name);
if (target)
observer->target = g_variant_ref_sink (target);
g_action_observable_register_observer (observable, action_name, G_ACTION_OBSERVER (observer));
if (g_action_group_query_action (observer->action_group, action_name, &enabled, &type, NULL, NULL, &state))
{
g_simple_action_observer_action_added (G_ACTION_OBSERVER (observer), observable,
action_name, type, enabled, state);
if (state)
g_variant_unref (state);
}
return observer;
}
void
g_simple_action_observer_activate (GSimpleActionObserver *observer)
{
g_return_if_fail (G_IS_SIMPLE_ACTION_OBSERVER (observer));
if (observer->can_activate && !observer->reporting)
g_action_group_activate_action (G_ACTION_GROUP (observer->action_group),
observer->action_name, observer->target);
}
gboolean
g_simple_action_observer_get_active (GSimpleActionObserver *observer)
{
g_return_val_if_fail (G_IS_SIMPLE_ACTION_OBSERVER (observer), FALSE);
return observer->active;
}
gboolean
g_simple_action_observer_get_enabled (GSimpleActionObserver *observer)
{
g_return_val_if_fail (G_IS_SIMPLE_ACTION_OBSERVER (observer), FALSE);
return observer->enabled;
}
-51
View File
@@ -1,51 +0,0 @@
/*
* Copyright © 2012 Canonical Limited
*
* 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
* licence 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/>.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __G_SIMPLE_ACTION_OBSERVER_H__
#define __G_SIMPLE_ACTION_OBSERVER_H__
#include "gactionobserver.h"
G_BEGIN_DECLS
#define G_TYPE_SIMPLE_ACTION_OBSERVER (g_simple_action_observer_get_type ())
#define G_SIMPLE_ACTION_OBSERVER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_SIMPLE_ACTION_OBSERVER, \
GSimpleActionObserver))
#define G_IS_SIMPLE_ACTION_OBSERVER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_SIMPLE_ACTION_OBSERVER))
typedef struct _GSimpleActionObserver GSimpleActionObserver;
G_GNUC_INTERNAL
GType g_simple_action_observer_get_type (void);
G_GNUC_INTERNAL
GSimpleActionObserver * g_simple_action_observer_new (GActionObservable *observable,
const gchar *action_name,
GVariant *target);
G_GNUC_INTERNAL
void g_simple_action_observer_activate (GSimpleActionObserver *observer);
G_GNUC_INTERNAL
gboolean g_simple_action_observer_get_active (GSimpleActionObserver *observer);
G_GNUC_INTERNAL
gboolean g_simple_action_observer_get_enabled (GSimpleActionObserver *observer);
G_END_DECLS
#endif /* __G_SIMPLE_ACTION_OBSERVER_H__ */
+16 -2
View File
@@ -246,6 +246,7 @@ gtk_application_window_get_type
gtk_application_window_get_id
gtk_application_window_new
gtk_application_window_set_show_menubar
gtk_application_get_active_window
gtk_arrow_get_type
gtk_arrow_new
gtk_arrow_placement_get_type
@@ -907,6 +908,8 @@ gtk_entry_get_icon_storage_type
gtk_entry_get_icon_tooltip_markup
gtk_entry_get_icon_tooltip_text
gtk_entry_get_inner_border
gtk_entry_get_input_hints
gtk_entry_get_input_purpose
gtk_entry_get_invisible_char
gtk_entry_get_layout
gtk_entry_get_layout_offsets
@@ -944,6 +947,8 @@ gtk_entry_set_icon_sensitive
gtk_entry_set_icon_tooltip_markup
gtk_entry_set_icon_tooltip_text
gtk_entry_set_inner_border
gtk_entry_set_input_hints
gtk_entry_set_input_purpose
gtk_entry_set_invisible_char
gtk_entry_set_max_length
gtk_entry_set_overwrite_mode
@@ -1436,6 +1441,8 @@ gtk_init_abi_check
gtk_init_check_abi_check
#endif
gtk_init_with_args
gtk_input_hints_get_type
gtk_input_purpose_get_type
gtk_invisible_get_screen
gtk_invisible_get_type
gtk_invisible_new
@@ -1550,16 +1557,18 @@ gtk_menu_bar_new
gtk_menu_bar_new_from_model
gtk_menu_bar_set_child_pack_direction
gtk_menu_bar_set_pack_direction
gtk_menu_button_get_type
gtk_menu_button_new
gtk_menu_button_get_align_widget
gtk_menu_button_get_direction
gtk_menu_button_get_menu
gtk_menu_button_get_menu_model
gtk_menu_button_get_popup
gtk_menu_button_get_type
gtk_menu_button_new
gtk_menu_button_set_align_widget
gtk_menu_button_set_direction
gtk_menu_button_set_menu
gtk_menu_button_set_menu_model
gtk_menu_button_set_popup
gtk_menu_detach
gtk_menu_direction_type_get_type
gtk_menu_get_accel_group
@@ -3003,6 +3012,8 @@ gtk_text_view_get_default_attributes
gtk_text_view_get_editable
gtk_text_view_get_hadjustment
gtk_text_view_get_indent
gtk_text_view_get_input_hints
gtk_text_view_get_input_purpose
gtk_text_view_get_iter_at_location
gtk_text_view_get_iter_at_position
gtk_text_view_get_iter_location
@@ -3039,6 +3050,8 @@ gtk_text_view_set_buffer
gtk_text_view_set_cursor_visible
gtk_text_view_set_editable
gtk_text_view_set_indent
gtk_text_view_set_input_hints
gtk_text_view_set_input_purpose
gtk_text_view_set_justification
gtk_text_view_set_left_margin
gtk_text_view_set_overwrite
@@ -3827,6 +3840,7 @@ gtk_widget_unmap
gtk_widget_unparent
gtk_widget_unrealize
gtk_widget_unset_state_flags
gtk_widget_insert_action_group
#ifdef GDK_WINDOWING_WIN32
gtk_win32_embed_widget_get_type
#endif
+5 -3
View File
@@ -791,18 +791,20 @@ _gtk_action_emit_activate (GtkAction *action)
{
GtkActionGroup *group = action->private_data->action_group;
if (group != NULL)
if (group != NULL)
{
g_object_ref (action);
g_object_ref (group);
_gtk_action_group_emit_pre_activate (group, action);
}
g_signal_emit (action, action_signals[ACTIVATE], 0);
g_signal_emit (action, action_signals[ACTIVATE], 0);
if (group != NULL)
if (group != NULL)
{
_gtk_action_group_emit_post_activate (group, action);
g_object_unref (group);
g_object_unref (action);
}
}
+638
View File
@@ -0,0 +1,638 @@
/*
* Copyright © 2012 Canonical Limited
*
* 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
* licence 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/>.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include "gtkactionhelper.h"
#include "gactionobservable.h"
#include "gtkwidget.h"
#include "gtkwidgetprivate.h"
#include <string.h>
typedef struct
{
GActionGroup *group;
GHashTable *watchers;
} GtkActionHelperGroup;
static void gtk_action_helper_action_added (GtkActionHelper *helper,
gboolean enabled,
const GVariantType *parameter_type,
GVariant *state,
gboolean should_emit_signals);
static void gtk_action_helper_action_removed (GtkActionHelper *helper);
static void gtk_action_helper_action_enabled_changed (GtkActionHelper *helper,
gboolean enabled);
static void gtk_action_helper_action_state_changed (GtkActionHelper *helper,
GVariant *new_state);
typedef GObjectClass GtkActionHelperClass;
struct _GtkActionHelper
{
GObject parent_instance;
GtkApplication *application;
GtkWidget *widget;
GtkActionHelperGroup *group;
GActionMuxer *action_context;
gchar *action_name;
GVariant *target;
GtkActionHelperRole role;
gboolean can_activate;
gboolean enabled;
gboolean active;
gint reporting;
};
enum
{
PROP_0,
PROP_ENABLED,
PROP_ACTIVE,
PROP_ROLE,
N_PROPS
};
static GParamSpec *gtk_action_helper_pspecs[N_PROPS];
static void gtk_action_helper_observer_iface_init (GActionObserverInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkActionHelper, gtk_action_helper, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVER, gtk_action_helper_observer_iface_init))
static void
gtk_action_helper_report_change (GtkActionHelper *helper,
guint prop_id)
{
helper->reporting++;
if (!helper->application)
{
switch (prop_id)
{
case PROP_ENABLED:
gtk_widget_set_sensitive (GTK_WIDGET (helper->widget), helper->enabled);
break;
case PROP_ACTIVE:
{
GParamSpec *pspec;
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "active");
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)
g_object_set (G_OBJECT (helper->widget), "active", helper->active, NULL);
}
break;
case PROP_ROLE:
{
GParamSpec *pspec;
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "action-role");
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_UINT)
g_object_set (G_OBJECT (helper->widget), "action-role", helper->role, NULL);
}
break;
default:
g_assert_not_reached ();
}
}
g_object_notify_by_pspec (G_OBJECT (helper), gtk_action_helper_pspecs[prop_id]);
helper->reporting--;
}
static void
gtk_action_helper_action_added (GtkActionHelper *helper,
gboolean enabled,
const GVariantType *parameter_type,
GVariant *state,
gboolean should_emit_signals)
{
/* we can only activate if we have the correct type of parameter */
helper->can_activate = (helper->target == NULL && parameter_type == NULL) ||
(helper->target != NULL && parameter_type != NULL &&
g_variant_is_of_type (helper->target, parameter_type));
if (!helper->can_activate)
return;
helper->enabled = enabled;
if (helper->target != NULL && state != NULL)
{
helper->active = g_variant_equal (state, helper->target);
helper->role = GTK_ACTION_HELPER_ROLE_RADIO;
}
else if (state != NULL && g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
{
helper->active = g_variant_get_boolean (state);
helper->role = GTK_ACTION_HELPER_ROLE_TOGGLE;
}
if (should_emit_signals)
{
if (helper->enabled)
gtk_action_helper_report_change (helper, PROP_ENABLED);
if (helper->active)
gtk_action_helper_report_change (helper, PROP_ACTIVE);
if (helper->role)
gtk_action_helper_report_change (helper, PROP_ROLE);
}
}
static void
gtk_action_helper_action_removed (GtkActionHelper *helper)
{
if (!helper->can_activate)
return;
helper->can_activate = FALSE;
if (helper->enabled)
{
helper->enabled = FALSE;
gtk_action_helper_report_change (helper, PROP_ENABLED);
}
if (helper->active)
{
helper->enabled = FALSE;
gtk_action_helper_report_change (helper, PROP_ACTIVE);
}
if (helper->role)
{
helper->role = GTK_ACTION_HELPER_ROLE_NORMAL;
gtk_action_helper_report_change (helper, PROP_ROLE);
}
}
static void
gtk_action_helper_action_enabled_changed (GtkActionHelper *helper,
gboolean enabled)
{
if (!helper->can_activate)
return;
if (helper->enabled == enabled)
return;
helper->enabled = enabled;
gtk_action_helper_report_change (helper, PROP_ENABLED);
}
static void
gtk_action_helper_action_state_changed (GtkActionHelper *helper,
GVariant *new_state)
{
gboolean was_active;
if (!helper->can_activate)
return;
was_active = helper->active;
if (helper->target)
helper->active = g_variant_equal (new_state, helper->target);
else if (g_variant_is_of_type (new_state, G_VARIANT_TYPE_BOOLEAN))
helper->active = g_variant_get_boolean (new_state);
else
helper->active = FALSE;
if (helper->active != was_active)
gtk_action_helper_report_change (helper, PROP_ACTIVE);
}
static void
gtk_action_helper_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
GtkActionHelper *helper = GTK_ACTION_HELPER (object);
switch (prop_id)
{
case PROP_ENABLED:
g_value_set_boolean (value, helper->enabled);
break;
case PROP_ACTIVE:
g_value_set_boolean (value, helper->active);
break;
case PROP_ROLE:
g_value_set_uint (value, helper->role);
break;
default:
g_assert_not_reached ();
}
}
static void
gtk_action_helper_finalize (GObject *object)
{
GtkActionHelper *helper = GTK_ACTION_HELPER (object);
if (helper->application)
{
g_signal_handlers_disconnect_by_data (helper->application, helper);
g_object_unref (helper->action_context);
g_object_unref (helper->application);
if (helper->widget)
g_object_unref (helper->widget);
}
g_free (helper->action_name);
if (helper->target)
g_variant_unref (helper->target);
G_OBJECT_CLASS (gtk_action_helper_parent_class)
->finalize (object);
}
static void
gtk_action_helper_observer_action_added (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
const GVariantType *parameter_type,
gboolean enabled,
GVariant *state)
{
gtk_action_helper_action_added (GTK_ACTION_HELPER (observer), enabled, parameter_type, state, TRUE);
}
static void
gtk_action_helper_observer_action_enabled_changed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
gboolean enabled)
{
gtk_action_helper_action_enabled_changed (GTK_ACTION_HELPER (observer), enabled);
}
static void
gtk_action_helper_observer_action_state_changed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
GVariant *state)
{
gtk_action_helper_action_state_changed (GTK_ACTION_HELPER (observer), state);
}
static void
gtk_action_helper_observer_action_removed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name)
{
gtk_action_helper_action_removed (GTK_ACTION_HELPER (observer));
}
static void
gtk_action_helper_init (GtkActionHelper *helper)
{
}
static void
gtk_action_helper_class_init (GtkActionHelperClass *class)
{
class->get_property = gtk_action_helper_get_property;
class->finalize = gtk_action_helper_finalize;
gtk_action_helper_pspecs[PROP_ENABLED] = g_param_spec_boolean ("enabled", "enabled", "enabled", FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
gtk_action_helper_pspecs[PROP_ACTIVE] = g_param_spec_boolean ("active", "active", "active", FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
gtk_action_helper_pspecs[PROP_ROLE] = g_param_spec_uint ("role", "role", "role", 0, 2, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (class, N_PROPS, gtk_action_helper_pspecs);
}
static void
gtk_action_helper_observer_iface_init (GActionObserverInterface *iface)
{
iface->action_added = gtk_action_helper_observer_action_added;
iface->action_enabled_changed = gtk_action_helper_observer_action_enabled_changed;
iface->action_state_changed = gtk_action_helper_observer_action_state_changed;
iface->action_removed = gtk_action_helper_observer_action_removed;
}
/*< private >
* gtk_action_helper_new:
* @widget: a #GtkWidget implementing #GtkActionable
*
* Creates a helper to track the state of a named action. This will
* usually be used by widgets implementing #GtkActionable.
*
* This helper class is usually used by @widget itself. In order to
* avoid reference cycles, the helper does not hold a reference on
* @widget, but will assume that it continues to exist for the duration
* of the life of the helper. If you are using the helper from outside
* of the widget, you should take a ref on @widget for each ref you hold
* on the helper.
*
* Returns: a new #GtkActionHelper
*/
GtkActionHelper *
gtk_action_helper_new (GtkActionable *widget)
{
GtkActionHelper *helper;
g_return_val_if_fail (GTK_IS_ACTIONABLE (widget), NULL);
helper = g_object_new (GTK_TYPE_ACTION_HELPER, NULL);
helper->widget = GTK_WIDGET (widget);
if (helper->widget)
{
GParamSpec *pspec;
helper->enabled = gtk_widget_get_sensitive (GTK_WIDGET (helper->widget));
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "active");
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)
g_object_get (G_OBJECT (helper->widget), "active", &helper->active, NULL);
}
helper->action_context = _gtk_widget_get_action_muxer (GTK_WIDGET (widget));
return helper;
}
static void
gtk_action_helper_active_window_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
GtkActionHelper *helper = user_data;
GActionMuxer *parent;
if (helper->widget)
g_object_unref (helper->widget);
helper->widget = GTK_WIDGET (gtk_application_get_active_window (helper->application));
if (helper->widget)
{
parent = g_object_ref (_gtk_widget_get_action_muxer (GTK_WIDGET (helper->widget)));
g_object_ref (helper->widget);
}
else
{
parent = g_action_muxer_new ();
g_action_muxer_insert (parent, "app", G_ACTION_GROUP (helper->application));
}
g_action_muxer_set_parent (helper->action_context, parent);
g_object_unref (parent);
}
GtkActionHelper *
gtk_action_helper_new_with_application (GtkApplication *application)
{
GtkActionHelper *helper;
g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
helper = g_object_new (GTK_TYPE_ACTION_HELPER, NULL);
helper->application = g_object_ref (application);
helper->action_context = g_action_muxer_new ();
g_signal_connect (application, "notify::active-window", G_CALLBACK (gtk_action_helper_active_window_changed), helper);
gtk_action_helper_active_window_changed (NULL, NULL, helper);
return helper;
}
void
gtk_action_helper_set_action_name (GtkActionHelper *helper,
const gchar *action_name)
{
gboolean was_enabled, was_active;
GtkActionHelperRole old_role;
const GVariantType *parameter_type;
gboolean enabled;
GVariant *state;
if (g_strcmp0 (action_name, helper->action_name) == 0)
return;
if (helper->action_name)
{
g_action_observable_unregister_observer (G_ACTION_OBSERVABLE (helper->action_context),
helper->action_name,
G_ACTION_OBSERVER (helper));
g_free (helper->action_name);
}
helper->action_name = g_strdup (action_name);
g_action_observable_register_observer (G_ACTION_OBSERVABLE (helper->action_context),
helper->action_name,
G_ACTION_OBSERVER (helper));
/* Start by recording the current state of our properties so we know
* what notify signals we will need to send.
*/
was_enabled = helper->enabled;
was_active = helper->active;
old_role = helper->role;
if (g_action_group_query_action (G_ACTION_GROUP (helper->action_context), helper->action_name,
&enabled, &parameter_type, NULL, NULL, &state))
{
gtk_action_helper_action_added (helper, enabled, parameter_type, state, FALSE);
if (state)
g_variant_unref (state);
}
else
{
helper->enabled = FALSE;
}
/* Send the notifies for the properties that changed.
*
* When called during construction, widget is NULL. We don't need to
* report in that case.
*/
if (helper->enabled != was_enabled)
gtk_action_helper_report_change (helper, PROP_ENABLED);
if (helper->active != was_active)
gtk_action_helper_report_change (helper, PROP_ACTIVE);
if (helper->role != old_role)
gtk_action_helper_report_change (helper, PROP_ROLE);
if (!helper->application)
g_object_notify (G_OBJECT (helper->widget), "action-name");
}
/*< private >
* gtk_action_helper_set_action_target_value:
* @helper: a #GtkActionHelper
* @target_value: an action target, as per #GtkActionable
*
* This function consumes @action_target if it is floating.
*/
void
gtk_action_helper_set_action_target_value (GtkActionHelper *helper,
GVariant *target_value)
{
gboolean was_enabled;
gboolean was_active;
if (target_value == helper->target)
return;
if (target_value && helper->target && g_variant_equal (target_value, helper->target))
{
g_variant_unref (g_variant_ref_sink (target_value));
return;
}
if (helper->target)
{
g_variant_unref (helper->target);
helper->target = NULL;
}
if (target_value)
helper->target = g_variant_ref_sink (target_value);
/* The action_name has not yet been set. Don't do anything yet. */
if (helper->action_name == NULL)
return;
was_enabled = helper->enabled;
was_active = helper->active;
/* If we are attached to an action group then it is possible that this
* change of the target value could impact our properties (including
* changes to 'can_activate' and therefore 'enabled', due to resolving
* a parameter type mismatch).
*
* Start over again by pretending the action gets re-added.
*/
helper->can_activate = FALSE;
helper->enabled = FALSE;
helper->active = FALSE;
if (helper->action_context)
{
const GVariantType *parameter_type;
gboolean enabled;
GVariant *state;
if (g_action_group_query_action (G_ACTION_GROUP (helper->action_context),
helper->action_name, &enabled, &parameter_type,
NULL, NULL, &state))
{
gtk_action_helper_action_added (helper, enabled, parameter_type, state, FALSE);
if (state)
g_variant_unref (state);
}
}
if (helper->enabled != was_enabled)
gtk_action_helper_report_change (helper, PROP_ENABLED);
if (helper->active != was_active)
gtk_action_helper_report_change (helper, PROP_ACTIVE);
if (!helper->application)
g_object_notify (G_OBJECT (helper->widget), "action-target");
}
const gchar *
gtk_action_helper_get_action_name (GtkActionHelper *helper)
{
if (helper == NULL)
return NULL;
return helper->action_name;
}
GVariant *
gtk_action_helper_get_action_target_value (GtkActionHelper *helper)
{
if (helper == NULL)
return NULL;
return helper->target;
}
GtkActionHelperRole
gtk_action_helper_get_role (GtkActionHelper *helper)
{
if (helper == NULL)
return GTK_ACTION_HELPER_ROLE_NORMAL;
return helper->role;
}
gboolean
gtk_action_helper_get_enabled (GtkActionHelper *helper)
{
g_return_val_if_fail (GTK_IS_ACTION_HELPER (helper), FALSE);
return helper->enabled;
}
gboolean
gtk_action_helper_get_active (GtkActionHelper *helper)
{
g_return_val_if_fail (GTK_IS_ACTION_HELPER (helper), FALSE);
return helper->active;
}
void
gtk_action_helper_activate (GtkActionHelper *helper)
{
g_return_if_fail (GTK_IS_ACTION_HELPER (helper));
if (!helper->can_activate || helper->reporting)
return;
g_action_group_activate_action (G_ACTION_GROUP (helper->action_context),
helper->action_name, helper->target);
}
+71
View File
@@ -0,0 +1,71 @@
/*
* Copyright © 2012 Canonical Limited
*
* 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
* licence 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/>.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __GTK_ACTION_HELPER_H__
#define __GTK_ACTION_HELPER_H__
#include <gtk/gtkapplication.h>
#include <gtk/gtkactionable.h>
#define GTK_TYPE_ACTION_HELPER (gtk_action_helper_get_type ())
#define GTK_ACTION_HELPER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
GTK_TYPE_ACTION_HELPER, GtkActionHelper))
#define GTK_IS_ACTION_HELPER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
GTK_TYPE_ACTION_HELPER))
typedef struct _GtkActionHelper GtkActionHelper;
typedef enum
{
GTK_ACTION_HELPER_ROLE_NORMAL,
GTK_ACTION_HELPER_ROLE_TOGGLE,
GTK_ACTION_HELPER_ROLE_RADIO
} GtkActionHelperRole;
G_GNUC_INTERNAL
GType gtk_action_helper_get_type (void);
G_GNUC_INTERNAL
GtkActionHelper * gtk_action_helper_new (GtkActionable *widget);
G_GNUC_INTERNAL
GtkActionHelper * gtk_action_helper_new_with_application (GtkApplication *application);
G_GNUC_INTERNAL
void gtk_action_helper_set_action_name (GtkActionHelper *helper,
const gchar *action_name);
G_GNUC_INTERNAL
void gtk_action_helper_set_action_target_value (GtkActionHelper *helper,
GVariant *action_target);
G_GNUC_INTERNAL
const gchar * gtk_action_helper_get_action_name (GtkActionHelper *helper);
G_GNUC_INTERNAL
GVariant * gtk_action_helper_get_action_target_value (GtkActionHelper *helper);
G_GNUC_INTERNAL
GtkActionHelperRole gtk_action_helper_get_role (GtkActionHelper *helper);
G_GNUC_INTERNAL
gboolean gtk_action_helper_get_enabled (GtkActionHelper *helper);
G_GNUC_INTERNAL
gboolean gtk_action_helper_get_active (GtkActionHelper *helper);
G_GNUC_INTERNAL
void gtk_action_helper_activate (GtkActionHelper *helper);
#endif /* __GTK_ACTION_HELPER_H__ */
+17 -17
View File
@@ -220,8 +220,8 @@ gtk_adjustment_class_init (GtkAdjustmentClass *class)
* GtkAdjustment::changed:
* @adjustment: the object which received the signal.
*
* Emitted when one or more of the #GtkAdjustment fields have been changed,
* other than the value field.
* Emitted when one or more of the #GtkAdjustment properties have been
* changed, other than the #GtkAdjustment:value property.
*/
adjustment_signals[CHANGED] =
g_signal_new (I_("changed"),
@@ -236,7 +236,7 @@ gtk_adjustment_class_init (GtkAdjustmentClass *class)
* GtkAdjustment::value-changed:
* @adjustment: the object which received the signal.
*
* Emitted when the #GtkAdjustment value field has been changed.
* Emitted when the #GtkAdjustment:value property has been changed.
*/
adjustment_signals[VALUE_CHANGED] =
g_signal_new (I_("value-changed"),
@@ -470,16 +470,16 @@ gtk_adjustment_get_lower (GtkAdjustment *adjustment)
* Sets the minimum value of the adjustment.
*
* When setting multiple adjustment properties via their individual
* setters, multiple "changed" signals will be emitted. However, since
* the emission of the "changed" signal is tied to the emission of the
* "GObject::notify" signals of the changed properties, it's possible
* to compress the "changed" signals into one by calling
* setters, multiple #GtkAdjustment::changed signals will be emitted. However, since
* the emission of the #GtkAdjustment::changed signal is tied to the emission of the
* #GObject::notify signals of the changed properties, it's possible
* to compress the #GtkAdjustment::changed signals into one by calling
* g_object_freeze_notify() and g_object_thaw_notify() around the
* calls to the individual setters.
*
* Alternatively, using a single g_object_set() for all the properties
* to change, or using gtk_adjustment_configure() has the same effect
* of compressing "changed" emissions.
* of compressing #GtkAdjustment::changed emissions.
*
* Since: 2.14
**/
@@ -523,7 +523,7 @@ gtk_adjustment_get_upper (GtkAdjustment *adjustment)
* property is nonzero.
*
* See gtk_adjustment_set_lower() about how to compress multiple
* emissions of the "changed" signal when setting multiple adjustment
* emissions of the #GtkAdjustment::changed signal when setting multiple adjustment
* properties.
*
* Since: 2.14
@@ -564,7 +564,7 @@ gtk_adjustment_get_step_increment (GtkAdjustment *adjustment)
* Sets the step increment of the adjustment.
*
* See gtk_adjustment_set_lower() about how to compress multiple
* emissions of the "changed" signal when setting multiple adjustment
* emissions of the #GtkAdjustment::changed signal when setting multiple adjustment
* properties.
*
* Since: 2.14
@@ -605,7 +605,7 @@ gtk_adjustment_get_page_increment (GtkAdjustment *adjustment)
* Sets the page increment of the adjustment.
*
* See gtk_adjustment_set_lower() about how to compress multiple
* emissions of the "changed" signal when setting multiple adjustment
* emissions of the #GtkAdjustment::changed signal when setting multiple adjustment
* properties.
*
* Since: 2.14
@@ -646,7 +646,7 @@ gtk_adjustment_get_page_size (GtkAdjustment *adjustment)
* Sets the page size of the adjustment.
*
* See gtk_adjustment_set_lower() about how to compress multiple
* emissions of the "changed" signal when setting multiple adjustment
* emissions of the GtkAdjustment::changed signal when setting multiple adjustment
* properties.
*
* Since: 2.14
@@ -673,9 +673,9 @@ gtk_adjustment_set_page_size (GtkAdjustment *adjustment,
*
* Sets all properties of the adjustment at once.
*
* Use this function to avoid multiple emissions of the "changed"
* Use this function to avoid multiple emissions of the #GtkAdjustment::changed
* signal. See gtk_adjustment_set_lower() for an alternative way
* of compressing multiple emissions of "changed" into one.
* of compressing multiple emissions of #GtkAdjustment::changed into one.
*
* Since: 2.14
**/
@@ -736,7 +736,7 @@ gtk_adjustment_configure (GtkAdjustment *adjustment,
*
* Emits a #GtkAdjustment::changed signal from the #GtkAdjustment.
* This is typically called by the owner of the #GtkAdjustment after it has
* changed any of the #GtkAdjustment fields other than the value.
* changed any of the #GtkAdjustment properties other than the value.
*/
void
gtk_adjustment_changed (GtkAdjustment *adjustment)
@@ -752,7 +752,7 @@ gtk_adjustment_changed (GtkAdjustment *adjustment)
*
* Emits a #GtkAdjustment::value_changed signal from the #GtkAdjustment.
* This is typically called by the owner of the #GtkAdjustment after it has
* changed the #GtkAdjustment value field.
* changed the #GtkAdjustment:value property.
*/
void
gtk_adjustment_value_changed (GtkAdjustment *adjustment)
@@ -769,7 +769,7 @@ gtk_adjustment_value_changed (GtkAdjustment *adjustment)
* @lower: the lower value.
* @upper: the upper value.
*
* Updates the #GtkAdjustment #GtkAdjustment:value to ensure that the range
* Updates the #GtkAdjustment:value property to ensure that the range
* between @lower and @upper is in the current page (i.e. between
* #GtkAdjustment:value and #GtkAdjustment:value + #GtkAdjustment:page_size).
* If the range is larger than the page size, then only the start of it will
+1 -1
View File
@@ -185,7 +185,7 @@ app_chooser_online_get_default_ready_cb (GObject *source,
GtkWidget *action_area;
action_area = gtk_dialog_get_action_area (GTK_DIALOG (self));
self->priv->online_button = gtk_button_new_with_label (_("Find applications online"));
self->priv->online_button = gtk_button_new_with_mnemonic (_("_Find applications online"));
gtk_box_pack_start (GTK_BOX (action_area), self->priv->online_button,
FALSE, FALSE, 0);
gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), self->priv->online_button,
+46 -23
View File
@@ -33,7 +33,6 @@
#include "gtkmain.h"
#include "gtkrecentmanager.h"
#include "gtkaccelmapprivate.h"
#include "gactionmuxer.h"
#include "gtkintl.h"
#ifdef GDK_WINDOWING_QUARTZ
@@ -132,7 +131,8 @@ enum {
PROP_ZERO,
PROP_REGISTER_SESSION,
PROP_APP_MENU,
PROP_MENUBAR
PROP_MENUBAR,
PROP_ACTIVE_WINDOW
};
G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
@@ -166,7 +166,6 @@ struct _GtkApplicationPrivate
#endif
#ifdef GDK_WINDOWING_QUARTZ
GActionMuxer *muxer;
GMenu *combined;
GSList *inhibitors;
@@ -345,7 +344,9 @@ gtk_application_menu_changed_quartz (GObject *object,
g_menu_append_submenu (combined, "Application", gtk_application_get_app_menu (application));
g_menu_append_section (combined, NULL, gtk_application_get_menubar (application));
gtk_quartz_set_main_menu (G_MENU_MODEL (combined), G_ACTION_OBSERVABLE (application->priv->muxer));
gtk_quartz_set_main_menu (G_MENU_MODEL (combined), application);
g_object_unref (combined);
}
static void gtk_application_startup_session_quartz (GtkApplication *app);
@@ -355,9 +356,6 @@ gtk_application_startup_quartz (GtkApplication *application)
{
[NSApp finishLaunching];
application->priv->muxer = g_action_muxer_new ();
g_action_muxer_insert (application->priv->muxer, "app", G_ACTION_GROUP (application));
g_signal_connect (application, "notify::app-menu", G_CALLBACK (gtk_application_menu_changed_quartz), NULL);
g_signal_connect (application, "notify::menubar", G_CALLBACK (gtk_application_menu_changed_quartz), NULL);
gtk_application_menu_changed_quartz (G_OBJECT (application), NULL, NULL);
@@ -368,25 +366,14 @@ gtk_application_startup_quartz (GtkApplication *application)
static void
gtk_application_shutdown_quartz (GtkApplication *application)
{
g_signal_handlers_disconnect_by_func (application, gtk_application_menu_changed_quartz, NULL);
gtk_quartz_clear_main_menu ();
g_object_unref (application->priv->muxer);
application->priv->muxer = NULL;
g_signal_handlers_disconnect_by_func (application, gtk_application_menu_changed_quartz, NULL);
g_slist_free_full (application->priv->inhibitors,
(GDestroyNotify) gtk_application_quartz_inhibitor_free);
application->priv->inhibitors = NULL;
}
static void
gtk_application_focus_changed (GtkApplication *application,
GtkWindow *window)
{
if (G_IS_ACTION_GROUP (window))
g_action_muxer_insert (application->priv->muxer, "win", G_ACTION_GROUP (window));
else
g_action_muxer_remove (application->priv->muxer, "win");
}
#endif
static gboolean
@@ -405,9 +392,7 @@ gtk_application_focus_in_event_cb (GtkWindow *window,
priv->windows = g_list_concat (link, priv->windows);
}
#ifdef GDK_WINDOWING_QUARTZ
gtk_application_focus_changed (application, window);
#endif
g_object_notify (G_OBJECT (application), "active-window");
return FALSE;
}
@@ -529,6 +514,8 @@ gtk_application_window_added (GtkApplication *application,
#ifdef GDK_WINDOWING_X11
gtk_application_window_added_x11 (application, window);
#endif
g_object_notify (G_OBJECT (application), "active-window");
}
static void
@@ -536,6 +523,9 @@ gtk_application_window_removed (GtkApplication *application,
GtkWindow *window)
{
GtkApplicationPrivate *priv = application->priv;
gpointer old_active;
old_active = priv->windows;
#ifdef GDK_WINDOWING_X11
gtk_application_window_removed_x11 (application, window);
@@ -548,6 +538,9 @@ gtk_application_window_removed (GtkApplication *application,
g_application_release (G_APPLICATION (application));
priv->windows = g_list_remove (priv->windows, window);
gtk_window_set_application (window, NULL);
if (priv->windows != old_active)
g_object_notify (G_OBJECT (application), "active-window");
}
static void
@@ -755,6 +748,13 @@ gtk_application_class_init (GtkApplicationClass *class)
P_("The GMenuModel for the menubar"),
G_TYPE_MENU_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_ACTIVE_WINDOW,
g_param_spec_object ("active-window",
P_("Active window"),
P_("The window which most recently had focus"),
GTK_TYPE_WINDOW,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}
/**
@@ -915,6 +915,29 @@ gtk_application_get_window_by_id (GtkApplication *application,
return NULL;
}
/**
* gtk_application_get_active_window:
* @application: a #GtkApplication
*
* Gets the "active" window for the application.
*
* The active window is the one that was most recently focused (within
* the application). This window may not have the focus at the moment
* if another application has it -- this is just the most
* recently-focused window within this application.
*
* Returns: (transfer none): the active window
*
* Since: 3.6
**/
GtkWindow *
gtk_application_get_active_window (GtkApplication *application)
{
g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
return application->priv->windows ? application->priv->windows->data : NULL;
}
/**
* gtk_application_add_accelerator:
* @application: a #GtkApplication
+3
View File
@@ -119,6 +119,9 @@ GDK_AVAILABLE_IN_3_6
GtkWindow * gtk_application_get_window_by_id (GtkApplication *application,
guint id);
GDK_AVAILABLE_IN_3_6
GtkWindow * gtk_application_get_active_window (GtkApplication *application);
G_END_DECLS
#endif /* __GTK_APPLICATION_H__ */
-9
View File
@@ -21,7 +21,6 @@
#ifndef __GTK_APPLICATION_PRIVATE_H__
#define __GTK_APPLICATION_PRIVATE_H__
#include "gsimpleactionobserver.h"
#include "gtkapplicationwindow.h"
G_GNUC_INTERNAL
@@ -33,14 +32,6 @@ gboolean gtk_application_window_publish (GtkAppl
G_GNUC_INTERNAL
void gtk_application_window_unpublish (GtkApplicationWindow *window);
G_GNUC_INTERNAL
GSimpleActionObserver * gtk_application_window_create_observer (GtkApplicationWindow *window,
const gchar *action_name,
GVariant *target);
G_GNUC_INTERNAL
GActionObservable * gtk_application_window_get_observable (GtkApplicationWindow *window);
G_GNUC_INTERNAL
GtkAccelGroup * gtk_application_window_get_accel_group (GtkApplicationWindow *window);
+16 -45
View File
@@ -22,9 +22,9 @@
#include "gtkapplicationwindow.h"
#include "gtkapplicationprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkwindowprivate.h"
#include "gtkmodelmenu.h"
#include "gactionmuxer.h"
#include "gtkaccelgroup.h"
#include "gtkaccelmap.h"
#include "gtkintl.h"
@@ -107,6 +107,14 @@
* </programlisting>
* </example>
*
* <example><title>Handling fallback yourself</title>
* <programlisting>
* <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../examples/sunny.c">
* <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
* </xi:include>
* </programlisting>
* </example>
*
* The XML format understood by #GtkBuilder for #GMenuModel consists
* of a toplevel <tag class="starttag">menu</tag> element, which contains
* one or more <tag class="starttag">item</tag> elements. Each
@@ -205,8 +213,6 @@ gtk_application_window_actions_new (GtkApplicationWindow *window)
struct _GtkApplicationWindowPrivate
{
GSimpleActionGroup *actions;
GActionObservable *muxer;
gboolean muxer_initialised;
GtkWidget *menubar;
GtkAccelGroup *accels;
GSList *accel_closures;
@@ -250,7 +256,7 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined), window->priv->muxer, window->priv->accels);
window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined), window->priv->accels);
gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
gtk_widget_show_all (window->priv->menubar);
g_object_unref (combined);
@@ -412,11 +418,6 @@ free_accel_closures (GtkApplicationWindow *window)
window->priv->accel_closures = NULL;
}
typedef struct {
GtkApplicationWindow *window;
GActionGroup *actions;
} AccelData;
/* Hack. We iterate over the accel map instead of the actions,
* in order to pull the parameters out of accel map entries
*/
@@ -427,9 +428,8 @@ add_accel_closure (gpointer data,
GdkModifierType accel_mods,
gboolean changed)
{
AccelData *d = data;
GtkApplicationWindow *window = d->window;
GActionGroup *actions = d->actions;
GtkApplicationWindow *window = data;
GActionGroup *actions;
const gchar *path;
const gchar *p;
gchar *action_name;
@@ -457,6 +457,7 @@ add_accel_closure (gpointer data,
parameter = NULL;
}
actions = G_ACTION_GROUP (_gtk_widget_get_action_muxer (GTK_WIDGET (window)));
if (g_action_group_has_action (actions, action_name))
{
closure = (AccelClosure*) g_closure_new_object (sizeof (AccelClosure), g_object_ref (actions));
@@ -477,14 +478,9 @@ add_accel_closure (gpointer data,
static void
gtk_application_window_update_accels (GtkApplicationWindow *window)
{
AccelData data;
free_accel_closures (window);
data.window = window;
data.actions = G_ACTION_GROUP (window->priv->muxer);
gtk_accel_map_foreach (&data, add_accel_closure);
gtk_accel_map_foreach (window, add_accel_closure);
}
static void
@@ -749,13 +745,6 @@ gtk_application_window_real_realize (GtkWidget *widget)
g_signal_connect (settings, "notify::gtk-shell-shows-menubar",
G_CALLBACK (gtk_application_window_shell_shows_menubar_changed), window);
if (!window->priv->muxer_initialised)
{
g_action_muxer_insert (G_ACTION_MUXER (window->priv->muxer), "app", G_ACTION_GROUP (application));
g_action_muxer_insert (G_ACTION_MUXER (window->priv->muxer), "win", G_ACTION_GROUP (window));
window->priv->muxer_initialised = TRUE;
}
gtk_application_window_update_shell_shows_app_menu (window, settings);
gtk_application_window_update_shell_shows_menubar (window, settings);
gtk_application_window_update_menubar (window);
@@ -878,7 +867,6 @@ gtk_application_window_real_forall_internal (GtkContainer *container,
->forall (container, include_internal, callback, user_data);
}
static void
gtk_application_window_get_property (GObject *object,
guint prop_id,
@@ -934,7 +922,6 @@ gtk_application_window_dispose (GObject *object)
g_clear_object (&window->priv->menubar_section);
g_clear_object (&window->priv->actions);
g_clear_object (&window->priv->accels);
g_clear_object (&window->priv->muxer);
G_OBJECT_CLASS (gtk_application_window_parent_class)
->dispose (object);
@@ -951,6 +938,8 @@ gtk_application_window_init (GtkApplicationWindow *window)
window->priv->accels = gtk_accel_group_new ();
gtk_window_add_accel_group (GTK_WINDOW (window), window->priv->accels);
gtk_widget_insert_action_group (GTK_WIDGET (window), "win", G_ACTION_GROUP (window->priv->actions));
/* window->priv->actions is the one and only ref on the group, so when
* we dispose, the action group will die, disconnecting all signals.
*/
@@ -962,8 +951,6 @@ gtk_application_window_init (GtkApplicationWindow *window)
G_CALLBACK (g_action_group_action_state_changed), window);
g_signal_connect_swapped (window->priv->actions, "action-removed",
G_CALLBACK (g_action_group_action_removed), window);
window->priv->muxer = G_ACTION_OBSERVABLE (g_action_muxer_new ());
}
static void
@@ -1072,22 +1059,6 @@ gtk_application_window_set_show_menubar (GtkApplicationWindow *window,
}
}
GSimpleActionObserver *
gtk_application_window_create_observer (GtkApplicationWindow *window,
const gchar *action_name,
GVariant *target)
{
g_return_val_if_fail (GTK_IS_APPLICATION_WINDOW (window), NULL);
return g_simple_action_observer_new (window->priv->muxer, action_name, target);
}
GActionObservable *
gtk_application_window_get_observable (GtkApplicationWindow *window)
{
return G_ACTION_OBSERVABLE (window->priv->muxer);
}
GtkAccelGroup *
gtk_application_window_get_accel_group (GtkApplicationWindow *window)
{
+18 -95
View File
@@ -57,7 +57,7 @@
#include "gtkintl.h"
#include "a11y/gtkbuttonaccessible.h"
#include "gtkapplicationprivate.h"
#include "gtkactionable.h"
#include "gtkactionhelper.h"
static const GtkBorder default_default_border = { 1, 1, 1, 1 };
static const GtkBorder default_default_outside_border = { 0, 0, 0, 0 };
@@ -151,9 +151,6 @@ static void gtk_button_state_changed (GtkWidget *widget,
GtkStateType previous_state);
static void gtk_button_grab_notify (GtkWidget *widget,
gboolean was_grabbed);
static void gtk_button_hierarchy_changed (GtkWidget *widget,
GtkWidget *previous_toplevel);
static void gtk_button_actionable_iface_init (GtkActionableInterface *iface);
static void gtk_button_activatable_interface_init(GtkActivatableIface *iface);
@@ -217,7 +214,6 @@ gtk_button_class_init (GtkButtonClass *klass)
widget_class->leave_notify_event = gtk_button_leave_notify;
widget_class->state_changed = gtk_button_state_changed;
widget_class->grab_notify = gtk_button_grab_notify;
widget_class->hierarchy_changed = gtk_button_hierarchy_changed;
container_class->child_type = gtk_button_child_type;
container_class->add = gtk_button_add;
@@ -616,12 +612,6 @@ gtk_button_destroy (GtkWidget *widget)
priv->label_text = NULL;
}
if (priv->action_name)
{
g_free (priv->action_name);
priv->action_name = NULL;
}
GTK_WIDGET_CLASS (gtk_button_parent_class)->destroy (widget);
}
@@ -704,7 +694,7 @@ gtk_button_dispose (GObject *object)
GtkButton *button = GTK_BUTTON (object);
GtkButtonPrivate *priv = button->priv;
g_clear_object (&priv->action_observer);
g_clear_object (&priv->action_helper);
if (priv->action)
{
@@ -714,53 +704,22 @@ gtk_button_dispose (GObject *object)
G_OBJECT_CLASS (gtk_button_parent_class)->dispose (object);
}
static void
gtk_button_update_action_observer (GtkButton *button)
{
GtkWidget *window;
g_signal_handlers_disconnect_by_func (button, gtk_real_button_clicked, NULL);
/* we are the only owner so this will clear all the signals */
g_clear_object (&button->priv->action_observer);
window = gtk_widget_get_toplevel (GTK_WIDGET (button));
if (GTK_IS_APPLICATION_WINDOW (window) && button->priv->action_name)
{
GSimpleActionObserver *observer;
observer = gtk_application_window_create_observer (GTK_APPLICATION_WINDOW (window),
button->priv->action_name,
button->priv->action_target);
_gtk_button_set_depressed (button, g_simple_action_observer_get_active (observer));
if (g_object_class_find_property (G_OBJECT_GET_CLASS (button), "active"))
g_object_bind_property (observer, "active", button, "active", G_BINDING_SYNC_CREATE);
g_object_bind_property (observer, "enabled", button, "sensitive", G_BINDING_SYNC_CREATE);
button->priv->action_observer = observer;
g_signal_connect_after (button, "clicked", G_CALLBACK (gtk_real_button_clicked), NULL);
}
}
static void
gtk_button_set_action_name (GtkActionable *actionable,
const gchar *action_name)
{
GtkButton *button = GTK_BUTTON (actionable);
g_return_if_fail (GTK_IS_BUTTON (button));
g_return_if_fail (button->priv->action == NULL);
g_free (button->priv->action_name);
button->priv->action_name = g_strdup (action_name);
if (!button->priv->action_helper)
button->priv->action_helper = gtk_action_helper_new (actionable);
gtk_button_update_action_observer (button);
g_signal_handlers_disconnect_by_func (button, gtk_real_button_clicked, NULL);
if (action_name)
g_signal_connect_after (button, "clicked", G_CALLBACK (gtk_real_button_clicked), NULL);
g_object_notify (G_OBJECT (button), "action-name");
gtk_action_helper_set_action_name (button->priv->action_helper, action_name);
}
static void
@@ -769,24 +728,10 @@ gtk_button_set_action_target_value (GtkActionable *actionable,
{
GtkButton *button = GTK_BUTTON (actionable);
g_return_if_fail (GTK_IS_BUTTON (button));
if (!button->priv->action_helper)
button->priv->action_helper = gtk_action_helper_new (actionable);
if (action_target != button->priv->action_target &&
(!action_target || !button->priv->action_target ||
!g_variant_equal (action_target, button->priv->action_target)))
{
if (button->priv->action_target)
g_variant_unref (button->priv->action_target);
button->priv->action_target = NULL;
if (action_target)
button->priv->action_target = g_variant_ref_sink (action_target);
gtk_button_update_action_observer (button);
g_object_notify (G_OBJECT (button), "action-target");
}
gtk_action_helper_set_action_target_value (button->priv->action_helper, action_target);
}
static void
@@ -896,10 +841,10 @@ gtk_button_get_property (GObject *object,
g_value_set_boolean (value, priv->use_action_appearance);
break;
case PROP_ACTION_NAME:
g_value_set_string (value, priv->action_name);
g_value_set_string (value, gtk_action_helper_get_action_name (priv->action_helper));
break;
case PROP_ACTION_TARGET:
g_value_set_variant (value, priv->action_target);
g_value_set_variant (value, gtk_action_helper_get_action_target_value (priv->action_helper));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -912,7 +857,7 @@ gtk_button_get_action_name (GtkActionable *actionable)
{
GtkButton *button = GTK_BUTTON (actionable);
return button->priv->action_name;
return gtk_action_helper_get_action_name (button->priv->action_helper);
}
static GVariant *
@@ -920,7 +865,7 @@ gtk_button_get_action_target_value (GtkActionable *actionable)
{
GtkButton *button = GTK_BUTTON (actionable);
return button->priv->action_target;
return gtk_action_helper_get_action_target_value (button->priv->action_helper);
}
static void
@@ -1069,7 +1014,7 @@ gtk_button_set_related_action (GtkButton *button,
{
GtkButtonPrivate *priv = button->priv;
g_return_if_fail (button->priv->action_name == NULL);
g_return_if_fail (gtk_action_helper_get_action_name (button->priv->action_helper) == NULL);
if (priv->action == action)
return;
@@ -2027,8 +1972,8 @@ gtk_real_button_clicked (GtkButton *button)
{
GtkButtonPrivate *priv = button->priv;
if (priv->action_observer)
g_simple_action_observer_activate (priv->action_observer);
if (priv->action_helper)
gtk_action_helper_activate (priv->action_helper);
if (priv->action)
gtk_action_activate (priv->action);
@@ -2624,28 +2569,6 @@ gtk_button_grab_notify (GtkWidget *widget,
}
}
static void
gtk_button_hierarchy_changed (GtkWidget *widget,
GtkWidget *previous_toplevel)
{
GtkButton *button = GTK_BUTTON (widget);
GtkWidgetClass *parent_class;
parent_class = GTK_WIDGET_CLASS (gtk_button_parent_class);
if (parent_class->hierarchy_changed)
parent_class->hierarchy_changed (widget, previous_toplevel);
if (button->priv->action_name)
{
GtkWidget *toplevel;
toplevel = gtk_widget_get_toplevel (widget);
if (toplevel != previous_toplevel)
gtk_button_update_action_observer (button);
}
}
/**
* gtk_button_set_image:
* @button: a #GtkButton
+2 -5
View File
@@ -19,7 +19,7 @@
#ifndef __GTK_BUTTON_PRIVATE_H__
#define __GTK_BUTTON_PRIVATE_H__
#include "gsimpleactionobserver.h"
#include "gtkactionhelper.h"
#include "gtkaction.h"
G_BEGIN_DECLS
@@ -29,10 +29,7 @@ struct _GtkButtonPrivate
{
GtkAction *action;
GtkWidget *image;
gchar *action_name;
GVariant *action_target;
GSimpleActionObserver *action_observer;
GtkActionHelper *action_helper;
GdkDevice *grab_keyboard;
GdkWindow *event_window;
+14 -1
View File
@@ -105,12 +105,25 @@ gtk_check_button_class_init (GtkCheckButtonClass *class)
GTK_PARAM_READABLE));
}
static void
draw_indicator_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
GtkButton *button = GTK_BUTTON (object);
if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (button)))
gtk_button_set_alignment (button, 0.0, 0.5);
else
gtk_button_set_alignment (button, 0.5, 0.5);
}
static void
gtk_check_button_init (GtkCheckButton *check_button)
{
gtk_widget_set_receives_default (GTK_WIDGET (check_button), FALSE);
g_signal_connect (check_button, "notify::draw-indicator", G_CALLBACK (draw_indicator_changed), NULL);
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (check_button), TRUE);
gtk_button_set_alignment (GTK_BUTTON (check_button), 0.0, 0.5);
}
/**
+169
View File
@@ -247,6 +247,11 @@ clipboard_display_closed (GdkDisplay *display,
g_object_unref (clipboard);
}
/**
* gtk_clipboard_get_for_display:
* @display: the display for which the clipboard is to be retrieved or created
* @selection: a #GdkAtom which identifies the clipboard to use.
*/
GtkClipboard *
gtk_clipboard_get_for_display (GdkDisplay *display,
GdkAtom selection)
@@ -257,6 +262,10 @@ gtk_clipboard_get_for_display (GdkDisplay *display,
return clipboard_peek (display, selection, FALSE);
}
/**
* gtk_clipboard_get:
* @selection: a #GdkAtom which identifies the clipboard to use
*/
GtkClipboard *
gtk_clipboard_get (GdkAtom selection)
{
@@ -380,6 +389,18 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
return TRUE;
}
/**
* gtk_clipboard_set_with_data: (skip)
* @clipboard: a #GtkClipboard
* @targets: (array length=n_targets): array containing information
* about the available forms for the clipboard data
* @n_targets: number of elements in @targets
* @get_func: (scope async): function to call to get the actual clipboard data
* @clear_func: (scope async): when the clipboard contents are set again,
* this function will be called, and @get_func will not be subsequently
* called.
* @user_data: user data to pass to @get_func and @clear_func.
*/
gboolean
gtk_clipboard_set_with_data (GtkClipboard *clipboard,
const GtkTargetEntry *targets,
@@ -397,6 +418,19 @@ gtk_clipboard_set_with_data (GtkClipboard *clipboard,
FALSE);
}
/**
* gtk_clipboard_set_with_owner: (skip)
* @clipboard: a #GtkClipboard
* @targets: (array length=n_targets): array containing information
* about the available forms for the clipboard data
* @n_targets: number of elements in @targets
* @get_func: (scope async): function to call to get the actual clipboard data
* @clear_func: (scope async): when the clipboard contents are set again,
* this function will be called, and @get_func will not be subsequently
* called
* @owner: an object that "owns" the data. This object will be passed
* to the callbacks when called
*/
gboolean
gtk_clipboard_set_with_owner (GtkClipboard *clipboard,
const GtkTargetEntry *targets,
@@ -415,6 +449,10 @@ gtk_clipboard_set_with_owner (GtkClipboard *clipboard,
TRUE);
}
/**
* gtk_clipboard_get_owner:
* @clipboard: a #GtkClipboard
*/
GObject *
gtk_clipboard_get_owner (GtkClipboard *clipboard)
{
@@ -470,6 +508,10 @@ clipboard_unset (GtkClipboard *clipboard)
g_object_unref (old_data);
}
/**
* gtk_clipboard_clear:
* @clipboard: a #GtkClipboard
*/
void
gtk_clipboard_clear (GtkClipboard *clipboard)
{
@@ -492,6 +534,13 @@ text_clear_func (GtkClipboard *clipboard,
g_free (data);
}
/**
* gtk_clipboard_set_text:
* @clipboard: a #GtkClipboard object
* @text: a UTF-8 string.
* @len: length of @text, in bytes, or -1, in which case
* the length will be determined with <function>strlen()</function>.
*/
void
gtk_clipboard_set_text (GtkClipboard *clipboard,
const gchar *text,
@@ -529,6 +578,11 @@ pixbuf_clear_func (GtkClipboard *clipboard,
g_object_unref (data);
}
/**
* gtk_clipboard_set_image:
* @clipboard: a #GtkClipboard object
* @pixbuf: a #GdkPixbuf
*/
void
gtk_clipboard_set_image (GtkClipboard *clipboard,
GdkPixbuf *pixbuf)
@@ -564,6 +618,16 @@ gtk_clipboard_set_image (GtkClipboard *clipboard,
gtk_target_list_unref (list);
}
/**
* gtk_clipboard_request_contents:
* @clipboard: a #GtkClipboard
* @target: an atom representing the form into which the clipboard
* owner should convert the selection.
* @callback: (scope async): A function to call when the results are received
* (or the retrieval fails). If the retrieval fails the length field of
* @selection_data will be negative.
* @user_data: user data to pass to @callback
*/
void
gtk_clipboard_request_contents (GtkClipboard *clipboard,
GdkAtom target,
@@ -579,6 +643,13 @@ gtk_clipboard_request_contents (GtkClipboard *clipboard,
gtk_selection_data_free (data);
}
/**
* gtk_clipboard_request_text:
* @clipboard: a #GtkClipboard
* @callback: (scope async): a function to call when the text is received,
* or the retrieval fails. (It will always be called one way or the other.)
* @user_data: user data to pass to @callback.
*/
void
gtk_clipboard_request_text (GtkClipboard *clipboard,
GtkClipboardTextReceivedFunc callback,
@@ -591,6 +662,14 @@ gtk_clipboard_request_text (GtkClipboard *clipboard,
g_free (data);
}
/**
* gtk_clipboard_request_rich_text:
* @clipboard: a #GtkClipboard
* @buffer: a #GtkTextBuffer
* @callback: (scope async): a function to call when the text is received,
* or the retrieval fails. (It will always be called one way or the other.)
* @user_data: user data to pass to @callback.
*/
void
gtk_clipboard_request_rich_text (GtkClipboard *clipboard,
GtkTextBuffer *buffer,
@@ -611,6 +690,13 @@ gtk_clipboard_wait_for_rich_text (GtkClipboard *clipboard,
return NULL;
}
/**
* gtk_clipboard_request_image:
* @clipboard: a #GtkClipboard
* @callback: (scope async): a function to call when the image is received,
* or the retrieval fails. (It will always be called one way or the other.)
* @user_data: user data to pass to @callback.
*/
void
gtk_clipboard_request_image (GtkClipboard *clipboard,
GtkClipboardImageReceivedFunc callback,
@@ -624,6 +710,13 @@ gtk_clipboard_request_image (GtkClipboard *clipboard,
g_object_unref (pixbuf);
}
/**
* gtk_clipboard_request_uris:
* @clipboard: a #GtkClipboard
* @callback: (scope async): a function to call when the URIs are received,
* or the retrieval fails. (It will always be called one way or the other.)
* @user_data: user data to pass to @callback.
*/
void
gtk_clipboard_request_uris (GtkClipboard *clipboard,
GtkClipboardURIReceivedFunc callback,
@@ -636,6 +729,14 @@ gtk_clipboard_request_uris (GtkClipboard *clipboard,
g_strfreev (uris);
}
/**
* gtk_clipboard_request_targets:
* @clipboard: a #GtkClipboard
* @callback: (scope async): a function to call when the targets are
* received, or the retrieval fails. (It will always be called
* one way or the other.)
* @user_data: user data to pass to @callback.
*/
void
gtk_clipboard_request_targets (GtkClipboard *clipboard,
GtkClipboardTargetsReceivedFunc callback,
@@ -650,6 +751,12 @@ gtk_clipboard_request_targets (GtkClipboard *clipboard,
}
/**
* gtk_clipboard_wait_for_contents:
* @clipboard: a #GtkClipboard
* @target: an atom representing the form into which the clipboard
* owner should convert the selection.
*/
GtkSelectionData *
gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
GdkAtom target)
@@ -695,6 +802,10 @@ gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
return selection_data;
}
/**
* gtk_clipboard_wait_for_text:
* @clipboard: a #GtkClipboard
*/
gchar *
gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
{
@@ -711,6 +822,10 @@ gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
return result;
}
/**
* gtk_clipboard_wait_for_image:
* @clipboard: a #GtkClipboard
*/
GdkPixbuf *
gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
{
@@ -735,6 +850,10 @@ gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
return NULL;
}
/**
* gtk_clipboard_wait_for_uris:
* @clipboard: a #GtkClipboard
*/
gchar **
gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
{
@@ -754,6 +873,10 @@ gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
return NULL;
}
/**
* gtk_clipboard_get_display:
* @clipboard: a #GtkClipboard
*/
GdkDisplay *
gtk_clipboard_get_display (GtkClipboard *clipboard)
{
@@ -762,6 +885,10 @@ gtk_clipboard_get_display (GtkClipboard *clipboard)
return clipboard->display;
}
/**
* gtk_clipboard_wait_is_text_available:
* @clipboard: a #GtkClipboard
*/
gboolean
gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
{
@@ -778,6 +905,11 @@ gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
return result;
}
/**
* gtk_clipboard_wait_is_rich_text_available:
* @clipboard: a #GtkClipboard
* @buffer: a #GtkTextBuffer
*/
gboolean
gtk_clipboard_wait_is_rich_text_available (GtkClipboard *clipboard,
GtkTextBuffer *buffer)
@@ -798,6 +930,10 @@ gtk_clipboard_wait_is_rich_text_available (GtkClipboard *clipboard,
return result;
}
/**
* gtk_clipboard_wait_is_image_available:
* @clipboard: a #GtkClipboard
*/
gboolean
gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
{
@@ -815,6 +951,10 @@ gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
return result;
}
/**
* gtk_clipboard_wait_is_uris_available:
* @clipboard: a #GtkClipboard
*/
gboolean
gtk_clipboard_wait_is_uris_available (GtkClipboard *clipboard)
{
@@ -832,6 +972,14 @@ gtk_clipboard_wait_is_uris_available (GtkClipboard *clipboard)
return result;
}
/**
* gtk_clipboard_wait_for_targets:
* @clipboard: a #GtkClipboard
* @targets: (out) (array length=n_targets) (transfer container): location
* to store an array of targets. The result stored here must
* be freed with g_free().
* @n_targets: location to store number of items in @targets.
*/
gboolean
gtk_clipboard_wait_for_targets (GtkClipboard *clipboard,
GdkAtom **targets,
@@ -962,6 +1110,11 @@ gtk_clipboard_owner_change (GtkClipboard *clipboard,
}
}
/**
* gtk_clipboard_wait_is_target_available:
* @clipboard: a #GtkClipboard
* @target: A #GdkAtom indicating which target to look for.
*/
gboolean
gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
GdkAtom target)
@@ -987,11 +1140,23 @@ gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
return retval;
}
/**
* _gtk_clipboard_handle_event:
* @event: a owner change event
*/
void
_gtk_clipboard_handle_event (GdkEventOwnerChange *event)
{
}
/**
* gtk_clipboard_set_can_store:
* @clipboard: a #GtkClipboard
* @targets: (allow-none) (array length=n_targets): array containing
* information about which forms should be stored or %NULL
* to indicate that all forms should be stored.
* @n_targets: number of elements in @targets
*/
void
gtk_clipboard_set_can_store (GtkClipboard *clipboard,
const GtkTargetEntry *targets,
@@ -1000,6 +1165,10 @@ gtk_clipboard_set_can_store (GtkClipboard *clipboard,
/* FIXME: Implement */
}
/**
* gtk_clipboard_store:
* @clipboard: a #GtkClipboard
*/
void
gtk_clipboard_store (GtkClipboard *clipboard)
{
+101 -31
View File
@@ -48,6 +48,8 @@ struct _GtkClipboard
GObject *owner;
GdkDisplay *display;
GdkAtom selection;
SetContentClosure *last_closure;
};
@@ -122,36 +124,70 @@ gtk_clipboard_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
GtkClipboard *
gtk_clipboard_get_for_display (GdkDisplay *display,
GdkAtom selection)
static void
clipboard_display_closed (GdkDisplay *display,
gboolean is_error,
GtkClipboard *clipboard)
{
GtkClipboard *clipboard;
GSList *clipboards;
clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
g_object_run_dispose (G_OBJECT (clipboard));
clipboards = g_slist_remove (clipboards, clipboard);
g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
g_object_unref (clipboard);
}
static GtkClipboard *
clipboard_peek (GdkDisplay *display,
GdkAtom selection,
gboolean only_if_exists)
{
GtkClipboard *clipboard = NULL;
GSList *clipboards;
GSList *tmp_list;
if (selection == GDK_NONE)
selection = GDK_SELECTION_CLIPBOARD;
if (selection != GDK_SELECTION_CLIPBOARD)
clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
tmp_list = clipboards;
while (tmp_list)
{
g_warning (G_STRLOC ": Only able to create clipboard for CLIPBOARD");
clipboard = tmp_list->data;
if (clipboard->selection == selection)
break;
tmp_list = tmp_list->next;
}
selection = GDK_SELECTION_CLIPBOARD;
if (!tmp_list && !only_if_exists)
{
clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
clipboard->selection = selection;
clipboard->display = display;
clipboard = g_object_get_data (G_OBJECT (display), "gtk-clipboard");
if (clipboard)
return clipboard;
clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
clipboard->display = display;
g_object_set_data (G_OBJECT (display), "gtk-clipboard", clipboard);
/* TODO: Need to connect to display closed to free this */
clipboards = g_slist_prepend (clipboards, clipboard);
g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
g_signal_connect (display, "closed",
G_CALLBACK (clipboard_display_closed), clipboard);
gdk_display_request_selection_notification (display, selection);
}
return clipboard;
}
GtkClipboard *
gtk_clipboard_get_for_display (GdkDisplay *display,
GdkAtom selection)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
g_return_val_if_fail (!gdk_display_is_closed (display), NULL);
return clipboard_peek (display, selection, FALSE);
}
GtkClipboard *
gtk_clipboard_get (GdkAtom selection)
{
@@ -164,6 +200,7 @@ struct _SetContentClosure {
GtkClipboardGetFunc get_func;
GtkClipboardClearFunc clear_func;
guint info;
gboolean have_owner;
gpointer userdata;
GtkTargetPair *targets;
gint n_targets;
@@ -203,6 +240,21 @@ _offer_cb (GdkDevice *device,
return (gchar *)selection_data.data;
}
static void
clipboard_owner_destroyed (gpointer data,
GObject *owner)
{
GtkClipboard *clipboard = (GtkClipboard *) data;
SetContentClosure *last_closure = clipboard->last_closure;
last_closure->userdata = NULL;
last_closure->get_func = NULL;
last_closure->clear_func = NULL;
last_closure->have_owner = FALSE;
gtk_clipboard_clear (clipboard);
}
static gboolean
gtk_clipboard_set_contents (GtkClipboard *clipboard,
const GtkTargetEntry *targets,
@@ -216,21 +268,34 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
GdkDevice *device;
gint i;
gchar **mimetypes;
SetContentClosure *closure;
SetContentClosure *closure, *last_closure;
gtk_clipboard_clear (clipboard);
last_closure = clipboard->last_closure;
if (!last_closure ||
(!last_closure->have_owner && have_owner) ||
(last_closure->userdata != user_data)) {
gtk_clipboard_clear (clipboard);
closure = g_new0 (SetContentClosure, 1);
closure->clipboard = clipboard;
closure->userdata = user_data;
closure->have_owner = have_owner;
if (have_owner)
g_object_weak_ref (G_OBJECT (user_data), clipboard_owner_destroyed, clipboard);
} else {
closure = last_closure;
g_free (closure->targets);
}
closure->get_func = get_func;
closure->clear_func = clear_func;
closure->targets = g_new0 (GtkTargetPair, n_targets);
closure->n_targets = n_targets;
device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
device = gdk_device_manager_get_client_pointer (device_manager);
closure = g_new0 (SetContentClosure, 1);
closure->clipboard = clipboard;
closure->get_func = get_func;
closure->clear_func = clear_func;
closure->userdata = user_data;
closure->targets = g_new0 (GtkTargetPair, n_targets);
closure->n_targets = n_targets;
mimetypes = g_new (gchar *, n_targets);
for (i = 0; i < n_targets; i++)
@@ -318,7 +383,12 @@ gtk_clipboard_clear (GtkClipboard *clipboard)
clipboard->last_closure->userdata);
}
/* TODO: Free last closure */
if (clipboard->last_closure->have_owner)
g_object_weak_unref (G_OBJECT (clipboard->last_closure->userdata),
clipboard_owner_destroyed, clipboard);
g_free (clipboard->last_closure->targets);
g_free (clipboard->last_closure);
clipboard->last_closure = NULL;
}
@@ -604,9 +674,9 @@ gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
if (g_main_loop_is_running (closure->loop))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (closure->loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
g_main_loop_unref (closure->loop);
+12 -12
View File
@@ -1410,9 +1410,9 @@ gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
if (g_main_loop_is_running (results.loop))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (results.loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
g_main_loop_unref (results.loop);
@@ -1463,9 +1463,9 @@ gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
if (g_main_loop_is_running (results.loop))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (results.loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
g_main_loop_unref (results.loop);
@@ -1531,9 +1531,9 @@ gtk_clipboard_wait_for_rich_text (GtkClipboard *clipboard,
if (g_main_loop_is_running (results.loop))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (results.loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
g_main_loop_unref (results.loop);
@@ -1591,9 +1591,9 @@ gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
if (g_main_loop_is_running (results.loop))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (results.loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
g_main_loop_unref (results.loop);
@@ -1646,9 +1646,9 @@ gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
if (g_main_loop_is_running (results.loop))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (results.loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
g_main_loop_unref (results.loop);
@@ -2132,9 +2132,9 @@ gtk_clipboard_store (GtkClipboard *clipboard)
if (g_main_loop_is_running (clipboard->store_loop))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (clipboard->store_loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
}
g_main_loop_unref (clipboard->store_loop);
+1 -2
View File
@@ -241,8 +241,7 @@ gtk_color_button_class_init (GtkColorButtonClass *klass)
* @widget: the object which received the signal.
*
* The ::color-set signal is emitted when the user selects a color.
* When handling this signal, use gtk_color_button_get_color() and
* gtk_color_button_get_alpha() (or gtk_color_button_get_rgba()) to
* When handling this signal, use gtk_color_button_get_rgba() to
* find out which color was just selected.
*
* Note that this signal is only emitted when the <emphasis>user</emphasis>
+5 -1
View File
@@ -1648,14 +1648,18 @@ gtk_container_idle_sizer (gpointer data)
current_time = g_get_monotonic_time ();
slist = container_restyle_queue;
container_restyle_queue = NULL;
for (; slist; slist = slist->next)
while (slist)
{
GSList *next = slist->next;
GtkContainer *container = slist->data;
container->priv->restyle_pending = FALSE;
_gtk_style_context_validate (gtk_widget_get_style_context (GTK_WIDGET (container)),
current_time,
0);
g_slist_free_1 (slist);
slist = next;
}
/* we may be invoked with a container_resize_queue of NULL, because
+2 -2
View File
@@ -1106,9 +1106,9 @@ gtk_dialog_run (GtkDialog *dialog)
ri.loop = g_main_loop_new (NULL, FALSE);
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (ri.loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
g_main_loop_unref (ri.loop);
+145 -25
View File
@@ -177,6 +177,16 @@ struct _GtkDragFindData
@end
/**
* gtk_drag_get_data: (method)
* @widget: the widget that will receive the
* #GtkWidget::drag-data-received signal.
* @context: the drag context
* @target: the target (form of the data) to retrieve.
* @time_: a timestamp for retrieving the data. This will
* generally be the time received in a #GtkWidget::drag-motion"
* or #GtkWidget::drag-drop" signal.
*/
void
gtk_drag_get_data (GtkWidget *widget,
GdkDragContext *context,
@@ -233,6 +243,14 @@ gtk_drag_get_data (GtkWidget *widget,
}
}
/**
* gtk_drag_finish: (method)
* @context: the drag context.
* @success: a flag indicating whether the drop was successful
* @del: a flag indicating whether the source should delete the
* original data. (This should be %TRUE for a move)
* @time_: the timestamp from the #GtkWidget::drag-drop signal.
*/
void
gtk_drag_finish (GdkDragContext *context,
gboolean success,
@@ -312,6 +330,10 @@ gtk_drag_clear_source_info (GdkDragContext *context)
g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL);
}
/**
* gtk_drag_get_source_widget: (method)
* @context: a (destination side) drag context
*/
GtkWidget *
gtk_drag_get_source_widget (GdkDragContext *context)
{
@@ -364,14 +386,10 @@ gtk_drag_highlight_draw (GtkWidget *widget,
return FALSE;
}
/*************************************************************
* gtk_drag_highlight:
* Highlight the given widget in the default manner.
* arguments:
* widget:
* results:
*************************************************************/
/**
* gtk_drag_highlight: (method)
* @widget: a widget to highlight
*/
void
gtk_drag_highlight (GtkWidget *widget)
{
@@ -384,14 +402,10 @@ gtk_drag_highlight (GtkWidget *widget)
gtk_widget_queue_draw (widget);
}
/*************************************************************
* gtk_drag_unhighlight:
* Refresh the given widget to remove the highlight.
* arguments:
* widget:
* results:
*************************************************************/
/**
* gtk_drag_unhighlight: (method)
* @widget: a widget to remove the highlight from.
*/
void
gtk_drag_unhighlight (GtkWidget *widget)
{
@@ -468,6 +482,17 @@ gtk_drag_dest_site_destroy (gpointer data)
g_free (site);
}
/**
* gtk_drag_dest_set: (method)
* @widget: a #GtkWidget
* @flags: which types of default drag behavior to use
* @targets: (allow-none) (array length=n_targets): a pointer to an array of #GtkTargetEntry<!-- -->s
* indicating the drop types that this @widget will accept, or %NULL.
* Later you can access the list with gtk_drag_dest_get_target_list()
* and gtk_drag_dest_find_target().
* @n_targets: the number of entries in @targets
* @actions: a bitmask of possible actions for a drop onto this @widget.
*/
void
gtk_drag_dest_set (GtkWidget *widget,
GtkDestDefaults flags,
@@ -509,6 +534,16 @@ gtk_drag_dest_set (GtkWidget *widget,
site, gtk_drag_dest_site_destroy);
}
/**
* gtk_drag_dest_set_proxy: (method)
* @widget: a #GtkWidget
* @proxy_window: the window to which to forward drag events
* @protocol: the drag protocol which the @proxy_window accepts
* (You can use gdk_drag_get_protocol() to determine this)
* @use_coordinates: If %TRUE, send the same coordinates to the
* destination, because it is an embedded
* subwindow.
*/
void
gtk_drag_dest_set_proxy (GtkWidget *widget,
GdkWindow *proxy_window,
@@ -518,6 +553,10 @@ gtk_drag_dest_set_proxy (GtkWidget *widget,
g_warning ("gtk_drag_dest_set_proxy is not supported on Mac OS X.");
}
/**
* gtk_drag_dest_unset: (method)
* @widget: a #GtkWidget
*/
void
gtk_drag_dest_unset (GtkWidget *widget)
{
@@ -539,6 +578,10 @@ gtk_drag_dest_unset (GtkWidget *widget)
g_object_set_data (G_OBJECT (widget), I_("gtk-drag-dest"), NULL);
}
/**
* gtk_drag_dest_get_target_list: (method)
* @widget: a #GtkWidget
*/
GtkTargetList*
gtk_drag_dest_get_target_list (GtkWidget *widget)
{
@@ -551,6 +594,11 @@ gtk_drag_dest_get_target_list (GtkWidget *widget)
return site ? site->target_list : NULL;
}
/**
* gtk_drag_dest_set_target_list: (method)
* @widget: a #GtkWidget that's a drag destination
* @target_list: (allow-none): list of droppable targets, or %NULL for none
*/
void
gtk_drag_dest_set_target_list (GtkWidget *widget,
GtkTargetList *target_list)
@@ -579,6 +627,10 @@ gtk_drag_dest_set_target_list (GtkWidget *widget,
register_types (widget, site);
}
/**
* gtk_drag_dest_add_text_targets: (method)
* @widget: a #GtkWidget that's a drag destination
*/
void
gtk_drag_dest_add_text_targets (GtkWidget *widget)
{
@@ -594,6 +646,11 @@ gtk_drag_dest_add_text_targets (GtkWidget *widget)
gtk_target_list_unref (target_list);
}
/**
* gtk_drag_dest_add_image_targets: (method)
* @widget: a #GtkWidget that's a drag destination
*/
void
gtk_drag_dest_add_image_targets (GtkWidget *widget)
{
@@ -609,6 +666,10 @@ gtk_drag_dest_add_image_targets (GtkWidget *widget)
gtk_target_list_unref (target_list);
}
/**
* gtk_drag_dest_add_uri_targets: (method)
* @widget: a #GtkWidget that's a drag destination
*/
void
gtk_drag_dest_add_uri_targets (GtkWidget *widget)
{
@@ -876,6 +937,11 @@ gtk_drag_dest_drop (GtkWidget *widget,
return (site->flags & GTK_DEST_DEFAULT_DROP) ? TRUE : retval;
}
/**
* gtk_drag_dest_set_track_motion: (method)
* @widget: a #GtkWidget that's a drag destination
* @track_motion: whether to accept all targets
*/
void
gtk_drag_dest_set_track_motion (GtkWidget *widget,
gboolean track_motion)
@@ -891,6 +957,10 @@ gtk_drag_dest_set_track_motion (GtkWidget *widget,
site->track_motion = track_motion != FALSE;
}
/**
* gtk_drag_dest_get_track_motion: (method)
* @widget: a #GtkWidget that's a drag destination
*/
gboolean
gtk_drag_dest_get_track_motion (GtkWidget *widget)
{
@@ -989,6 +1059,13 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel,
}
/**
* gtk_drag_dest_find_target: (method)
* @widget: drag destination widget
* @context: drag context
* @target_list: (allow-none): list of droppable targets, or %NULL to use
* gtk_drag_dest_get_target_list (@widget).
*/
GdkAtom
gtk_drag_dest_find_target (GtkWidget *widget,
GdkDragContext *context,
@@ -1231,6 +1308,15 @@ gtk_drag_begin_internal (GtkWidget *widget,
return context;
}
/**
* gtk_drag_begin: (method)
* @widget: the source widget.
* @targets: The targets (data formats) in which the
* source can provide the data.
* @actions: A bitmask of the allowed drag actions for this drag.
* @button: The button the user clicked to start the drag.
* @event: The event that triggered the start of the drag.
*/
GdkDragContext *
gtk_drag_begin (GtkWidget *widget,
GtkTargetList *targets,
@@ -1306,6 +1392,15 @@ gtk_drag_source_event_cb (GtkWidget *widget,
return retval;
}
/**
* gtk_drag_source_set: (method)
* @widget: a #GtkWidget
* @start_button_mask: the bitmask of buttons that can start the drag
* @targets: (allow-none) (array length=n_targets): the table of targets that the drag will support,
* may be %NULL
* @n_targets: the number of items in @targets
* @actions: the bitmask of possible actions for a drag from this widget
*/
void
gtk_drag_source_set (GtkWidget *widget,
GdkModifierType start_button_mask,
@@ -1357,14 +1452,10 @@ gtk_drag_source_set (GtkWidget *widget,
site->actions = actions;
}
/*************************************************************
* gtk_drag_source_unset
* Unregister this widget as a drag source.
* arguments:
* widget:
* results:
*************************************************************/
/**
* gtk_drag_source_unset: (method)
* @widget: a #GtkWidget
*/
void
gtk_drag_source_unset (GtkWidget *widget)
{
@@ -1383,6 +1474,10 @@ gtk_drag_source_unset (GtkWidget *widget)
}
}
/**
* gtk_drag_source_get_target_list: (method)
* @widget: a #GtkWidget
*/
GtkTargetList *
gtk_drag_source_get_target_list (GtkWidget *widget)
{
@@ -1396,6 +1491,11 @@ gtk_drag_source_get_target_list (GtkWidget *widget)
}
/**
* gtk_drag_source_set_target_list: (method)
* @widget: a #GtkWidget that's a drag source
* @target_list: (allow-none): list of draggable targets, or %NULL for none
*/
void
gtk_drag_source_set_target_list (GtkWidget *widget,
GtkTargetList *target_list)
@@ -1448,6 +1548,10 @@ gtk_drag_source_add_text_targets (GtkWidget *widget)
gtk_target_list_unref (target_list);
}
/**
* gtk_drag_source_add_image_targets: (method)
* @widget: a #GtkWidget that's is a drag source
*/
void
gtk_drag_source_add_image_targets (GtkWidget *widget)
{
@@ -1463,6 +1567,10 @@ gtk_drag_source_add_image_targets (GtkWidget *widget)
gtk_target_list_unref (target_list);
}
/**
* gtk_drag_source_add_uri_targets: (method)
* @widget: a #GtkWidget that's is a drag source
*/
void
gtk_drag_source_add_uri_targets (GtkWidget *widget)
{
@@ -1513,6 +1621,11 @@ gtk_drag_source_site_destroy (gpointer data)
g_free (site);
}
/**
* gtk_drag_source_set_icon_pixbuf: (method)
* @widget: a #GtkWidget
* @pixbuf: the #GdkPixbuf for the drag icon
*/
void
gtk_drag_source_set_icon_pixbuf (GtkWidget *widget,
GdkPixbuf *pixbuf)
@@ -1925,7 +2038,14 @@ _gtk_drag_source_handle_event (GtkWidget *widget,
}
}
/**
* gtk_drag_check_threshold: (method)
* @widget: a #GtkWidget
* @start_x: X coordinate of start of drag
* @start_y: Y coordinate of start of drag
* @current_x: current X coordinate
* @current_y: current Y coordinate
*/
gboolean
gtk_drag_check_threshold (GtkWidget *widget,
gint start_x,
+12
View File
@@ -411,6 +411,18 @@ root_key_filter (GdkXEvent *xevent,
if ((ev->type == KeyPress || ev->type == KeyRelease) &&
ev->xkey.root == ev->xkey.window)
ev->xkey.window = (Window)data;
else if (ev->type == GenericEvent)
{
XGenericEventCookie *cookie;
XIDeviceEvent *dev;
cookie = &ev->xcookie;
dev = (XIDeviceEvent *) cookie->data;
if (dev->evtype == XI_KeyPress ||
dev->evtype == XI_KeyRelease)
dev->event = (Window)data;
}
return GDK_FILTER_CONTINUE;
}
+477 -37
View File
@@ -65,6 +65,7 @@
#include "gtkicontheme.h"
#include "gtkwidgetprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtktexthandleprivate.h"
#include "a11y/gtkentryaccessible.h"
@@ -160,6 +161,8 @@ struct _GtkEntryPrivate
gchar *placeholder_text;
GtkTextHandle *text_handle;
gfloat xalign;
gint ascent; /* font ascent in pango units */
@@ -215,6 +218,7 @@ struct _GtkEntryPrivate
guint select_words : 1;
guint select_lines : 1;
guint truncate_multiline : 1;
guint update_handles_on_focus : 1;
};
struct _EntryIconInfo
@@ -308,10 +312,13 @@ enum {
PROP_IM_MODULE,
PROP_EDITING_CANCELED,
PROP_PLACEHOLDER_TEXT,
PROP_COMPLETION
PROP_COMPLETION,
PROP_INPUT_PURPOSE,
PROP_INPUT_HINTS
};
static guint signals[LAST_SIGNAL] = { 0 };
static gboolean test_touchscreen = FALSE;
typedef enum {
CURSOR_STANDARD,
@@ -574,6 +581,13 @@ static GdkPixbuf * gtk_entry_ensure_pixbuf (GtkEntry *en
static void gtk_entry_update_cached_style_values(GtkEntry *entry);
static gboolean get_middle_click_paste (GtkEntry *entry);
/* GtkTextHandle handlers */
static void gtk_entry_handle_dragged (GtkTextHandle *handle,
GtkTextHandlePosition pos,
gint x,
gint y,
GtkEntry *entry);
/* Completion */
static gint gtk_entry_completion_timeout (gpointer data);
static gboolean gtk_entry_completion_key_press (GtkWidget *widget,
@@ -1359,6 +1373,47 @@ gtk_entry_class_init (GtkEntryClass *class)
GTK_TYPE_ENTRY_COMPLETION,
GTK_PARAM_READWRITE));
/**
* GtkEntry:input-purpose:
*
* The purpose of this text field.
*
* This property can be used by on-screen keyboards and other input
* methods to adjust their behaviour.
*
* Note that setting the purpose to %GTK_INPUT_PURPOSE_PASSWORD or
* %GTK_INPUT_PURPOSE_PIN is independent from setting
* #GtkEntry:visibility.
*
* Since: 3.6
*/
g_object_class_install_property (gobject_class,
PROP_INPUT_PURPOSE,
g_param_spec_enum ("input-purpose",
P_("Purpose"),
P_("Purpose of the text field"),
GTK_TYPE_INPUT_PURPOSE,
GTK_INPUT_PURPOSE_FREE_FORM,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GtkEntry:input-hints:
*
* Additional hints (beyond #GtkEntry:input-purpose) that
* allow input methods to fine-tune their behaviour.
*
* Since: 3.6
*/
g_object_class_install_property (gobject_class,
PROP_INPUT_HINTS,
g_param_spec_flags ("input-hints",
P_("hints"),
P_("Hints for the text field behaviour"),
GTK_TYPE_INPUT_HINTS,
GTK_INPUT_HINT_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GtkEntry:icon-prelight:
*
@@ -1892,6 +1947,7 @@ gtk_entry_class_init (GtkEntryClass *class)
G_PARAM_DEPRECATED));
g_type_class_add_private (gobject_class, sizeof (GtkEntryPrivate));
test_touchscreen = g_getenv ("GTK_TEST_TOUCHSCREEN_FEATURES") != NULL;
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
}
@@ -2162,6 +2218,14 @@ gtk_entry_set_property (GObject *object,
gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (g_value_get_object (value)));
break;
case PROP_INPUT_PURPOSE:
gtk_entry_set_input_purpose (entry, g_value_get_enum (value));
break;
case PROP_INPUT_HINTS:
gtk_entry_set_input_hints (entry, g_value_get_flags (value));
break;
case PROP_SCROLL_OFFSET:
case PROP_CURSOR_POSITION:
default:
@@ -2386,6 +2450,14 @@ gtk_entry_get_property (GObject *object,
g_value_set_object (value, G_OBJECT (gtk_entry_get_completion (entry)));
break;
case PROP_INPUT_PURPOSE:
g_value_set_enum (value, gtk_entry_get_input_purpose (entry));
break;
case PROP_INPUT_HINTS:
g_value_set_flags (value, gtk_entry_get_input_hints (entry));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -2493,6 +2565,10 @@ gtk_entry_init (GtkEntry *entry)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY);
gtk_entry_update_cached_style_values (entry);
priv->text_handle = _gtk_text_handle_new (GTK_WIDGET (entry));
g_signal_connect (priv->text_handle, "handle-dragged",
G_CALLBACK (gtk_entry_handle_dragged), entry);
}
static void
@@ -2730,6 +2806,7 @@ gtk_entry_finalize (GObject *object)
if (priv->recompute_idle)
g_source_remove (priv->recompute_idle);
g_object_unref (priv->text_handle);
g_free (priv->placeholder_text);
g_free (priv->im_module);
@@ -2750,10 +2827,10 @@ gtk_entry_get_display_mode (GtkEntry *entry)
return DISPLAY_INVISIBLE;
}
static gchar*
gtk_entry_get_display_text (GtkEntry *entry,
gint start_pos,
gint end_pos)
gchar*
_gtk_entry_get_display_text (GtkEntry *entry,
gint start_pos,
gint end_pos)
{
GtkEntryPasswordHint *password_hint;
GtkEntryPrivate *priv;
@@ -2951,6 +3028,9 @@ gtk_entry_unmap (GtkWidget *widget)
EntryIconInfo *icon_info = NULL;
gint i;
_gtk_text_handle_set_mode (priv->text_handle,
GTK_TEXT_HANDLE_MODE_NONE);
for (i = 0; i < MAX_ICONS; i++)
{
if ((icon_info = priv->icons[i]) != NULL)
@@ -3024,7 +3104,7 @@ gtk_entry_realize (GtkWidget *widget)
gtk_entry_adjust_scroll (entry);
gtk_entry_update_primary_selection (entry);
_gtk_text_handle_set_relative_to (priv->text_handle, priv->text_area);
/* If the icon positions are already setup, create their windows.
* Otherwise if they don't exist yet, then construct_icon_info()
@@ -3052,6 +3132,7 @@ gtk_entry_unrealize (GtkWidget *widget)
gtk_entry_reset_layout (entry);
gtk_im_context_set_client_window (priv->im_context, NULL);
_gtk_text_handle_set_relative_to (priv->text_handle, NULL);
clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_PRIMARY);
if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry))
@@ -3793,7 +3874,108 @@ in_selection (GtkEntry *entry,
g_free (ranges);
return retval;
}
static void
_gtk_entry_move_handle (GtkEntry *entry,
GtkTextHandlePosition pos,
gint x,
gint y,
gint height)
{
GtkEntryPrivate *priv = entry->priv;
if (!_gtk_text_handle_get_is_dragged (priv->text_handle, pos) &&
(x < 0 || x > gdk_window_get_width (priv->text_area)))
{
/* Hide the handle if it's not being manipulated
* and fell outside of the visible text area.
*/
_gtk_text_handle_set_visible (priv->text_handle, pos, FALSE);
}
else
{
GdkRectangle rect;
rect.x = CLAMP (x, 0, gdk_window_get_width (priv->text_area));
rect.y = y;
rect.width = 1;
rect.height = height;
_gtk_text_handle_set_visible (priv->text_handle, pos, TRUE);
_gtk_text_handle_set_position (priv->text_handle, pos, &rect);
}
}
static gint
_gtk_entry_get_selection_bound_location (GtkEntry *entry)
{
GtkEntryPrivate *priv = entry->priv;
PangoLayout *layout;
PangoRectangle pos;
gint x;
const gchar *text;
gint index;
layout = gtk_entry_ensure_layout (entry, FALSE);
text = pango_layout_get_text (layout);
index = g_utf8_offset_to_pointer (text, priv->selection_bound) - text;
pango_layout_index_to_pos (layout, index, &pos);
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
x = (pos.x + pos.width) / PANGO_SCALE;
else
x = pos.x / PANGO_SCALE;
return x;
}
static void
_gtk_entry_update_handles (GtkEntry *entry,
GtkTextHandleMode mode)
{
GtkEntryPrivate *priv = entry->priv;
gint strong_x, height;
gint cursor, bound;
_gtk_text_handle_set_mode (priv->text_handle, mode);
/* Wait for recomputation before repositioning */
if (priv->recompute_idle != 0)
return;
height = gdk_window_get_height (priv->text_area);
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL);
cursor = strong_x - priv->scroll_offset;
if (mode == GTK_TEXT_HANDLE_MODE_SELECTION)
{
gint start, end;
bound = _gtk_entry_get_selection_bound_location (entry) - priv->scroll_offset;
if (priv->selection_bound > priv->current_pos)
{
start = cursor;
end = bound;
}
else
{
start = bound;
end = cursor;
}
/* Update start selection bound */
_gtk_entry_move_handle (entry, GTK_TEXT_HANDLE_POSITION_SELECTION_START,
start, 0, height);
_gtk_entry_move_handle (entry, GTK_TEXT_HANDLE_POSITION_SELECTION_END,
end, 0, height);
}
else
_gtk_entry_move_handle (entry, GTK_TEXT_HANDLE_POSITION_CURSOR,
cursor, 0, height);
}
static gint
gtk_entry_button_press (GtkWidget *widget,
GdkEventButton *event)
@@ -3861,7 +4043,14 @@ gtk_entry_button_press (GtkWidget *widget,
else if (event->button == GDK_BUTTON_PRIMARY)
{
gboolean have_selection = gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end);
gboolean is_touchscreen;
GdkDevice *source;
source = gdk_event_get_source_device ((GdkEvent *) event);
is_touchscreen = test_touchscreen ||
gdk_device_get_source (source) == GDK_SOURCE_TOUCHSCREEN;
priv->update_handles_on_focus = is_touchscreen;
priv->select_words = FALSE;
priv->select_lines = FALSE;
@@ -3939,7 +4128,12 @@ gtk_entry_button_press (GtkWidget *widget,
priv->drag_start_y = event->y;
}
else
gtk_editable_set_position (editable, tmp_pos);
{
gtk_editable_set_position (editable, tmp_pos);
if (is_touchscreen)
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_CURSOR);
}
break;
case GDK_2BUTTON_PRESS:
@@ -3950,6 +4144,9 @@ gtk_entry_button_press (GtkWidget *widget,
priv->in_drag = FALSE;
priv->select_words = TRUE;
gtk_entry_select_word (entry);
if (is_touchscreen)
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_SELECTION);
break;
case GDK_3BUTTON_PRESS:
@@ -3960,6 +4157,8 @@ gtk_entry_button_press (GtkWidget *widget,
priv->in_drag = FALSE;
priv->select_lines = TRUE;
gtk_entry_select_line (entry);
if (is_touchscreen)
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_SELECTION);
break;
default:
@@ -4029,9 +4228,16 @@ gtk_entry_button_release (GtkWidget *widget,
if (priv->in_drag)
{
gint tmp_pos = gtk_entry_find_position (entry, priv->drag_start_x);
GdkDevice *source;
gtk_editable_set_position (GTK_EDITABLE (entry), tmp_pos);
source = gdk_event_get_source_device ((GdkEvent *) event);
if (test_touchscreen ||
gdk_device_get_source (source) == GDK_SOURCE_TOUCHSCREEN)
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_CURSOR);
priv->in_drag = 0;
}
@@ -4153,13 +4359,22 @@ gtk_entry_motion_notify (GtkWidget *widget,
}
else
{
GdkInputSource input_source;
GdkDevice *source;
guint length;
length = gtk_entry_buffer_get_length (get_buffer (entry));
if (event->y < 0)
tmp_pos = 0;
else if (event->y >= gdk_window_get_height (priv->text_area))
tmp_pos = gtk_entry_buffer_get_length (get_buffer (entry));
tmp_pos = length;
else
tmp_pos = gtk_entry_find_position (entry, event->x + priv->scroll_offset);
source = gdk_event_get_source_device ((GdkEvent *) event);
input_source = gdk_device_get_source (source);
if (priv->select_words)
{
gint min, max;
@@ -4195,13 +4410,20 @@ gtk_entry_motion_notify (GtkWidget *widget,
if (priv->current_pos != max)
pos = min;
}
gtk_entry_set_positions (entry, pos, bound);
}
else
gtk_entry_set_positions (entry, tmp_pos, -1);
/* Update touch handles' position */
if (test_touchscreen || input_source == GDK_SOURCE_TOUCHSCREEN)
_gtk_entry_update_handles (entry,
(priv->current_pos == priv->selection_bound) ?
GTK_TEXT_HANDLE_MODE_CURSOR :
GTK_TEXT_HANDLE_MODE_SELECTION);
}
return TRUE;
}
@@ -4241,6 +4463,8 @@ gtk_entry_key_press (GtkWidget *widget,
gtk_entry_reset_blink_time (entry);
gtk_entry_pend_cursor_blink (entry);
_gtk_text_handle_set_mode (priv->text_handle,
GTK_TEXT_HANDLE_MODE_NONE);
if (priv->editable)
{
@@ -4333,6 +4557,10 @@ gtk_entry_focus_in (GtkWidget *widget,
gtk_entry_check_cursor_blink (entry);
}
if (priv->update_handles_on_focus &&
gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), NULL, NULL))
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_SELECTION);
return FALSE;
}
@@ -4345,6 +4573,9 @@ gtk_entry_focus_out (GtkWidget *widget,
GtkEntryCompletion *completion;
GdkKeymap *keymap;
_gtk_text_handle_set_mode (priv->text_handle,
GTK_TEXT_HANDLE_MODE_NONE);
gtk_widget_queue_draw (widget);
keymap = gdk_keymap_get_for_display (gtk_widget_get_display (widget));
@@ -5170,8 +5401,8 @@ gtk_entry_backspace (GtkEntry *entry)
gchar *normalized_text;
glong len;
cluster_text = gtk_entry_get_display_text (entry, prev_pos,
priv->current_pos);
cluster_text = _gtk_entry_get_display_text (entry, prev_pos,
priv->current_pos);
normalized_text = g_utf8_normalize (cluster_text,
strlen (cluster_text),
G_NORMALIZE_NFD);
@@ -5222,7 +5453,7 @@ gtk_entry_copy_clipboard (GtkEntry *entry)
return;
}
str = gtk_entry_get_display_text (entry, start, end);
str = _gtk_entry_get_display_text (entry, start, end);
gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (entry),
GDK_SELECTION_CLIPBOARD),
str, -1);
@@ -5380,7 +5611,7 @@ gtk_entry_retrieve_surrounding_cb (GtkIMContext *context,
gchar *text;
/* XXXX ??? does this even make sense when text is not visible? Should we return FALSE? */
text = gtk_entry_get_display_text (entry, 0, -1);
text = _gtk_entry_get_display_text (entry, 0, -1);
gtk_im_context_set_surrounding (context, text, strlen (text), /* Length in bytes */
g_utf8_offset_to_pointer (text, priv->current_pos) - text);
g_free (text);
@@ -5526,10 +5757,17 @@ recompute_idle_func (gpointer data)
if (gtk_widget_has_screen (GTK_WIDGET (entry)))
{
GtkTextHandleMode handle_mode;
gtk_entry_adjust_scroll (entry);
gtk_widget_queue_draw (GTK_WIDGET (entry));
update_im_cursor_location (entry);
handle_mode = _gtk_text_handle_get_mode (priv->text_handle);
if (handle_mode != GTK_TEXT_HANDLE_MODE_NONE)
_gtk_entry_update_handles (entry, handle_mode);
}
return FALSE;
@@ -5598,7 +5836,7 @@ gtk_entry_create_layout (GtkEntry *entry,
pango_layout_set_single_paragraph_mode (layout, TRUE);
display = placeholder_layout ? g_strdup (priv->placeholder_text) : gtk_entry_get_display_text (entry, 0, -1);
display = placeholder_layout ? g_strdup (priv->placeholder_text) : _gtk_entry_get_display_text (entry, 0, -1);
n_bytes = strlen (display);
if (!placeholder_layout && include_preedit)
@@ -5961,6 +6199,70 @@ gtk_entry_draw_cursor (GtkEntry *entry,
}
}
static void
gtk_entry_handle_dragged (GtkTextHandle *handle,
GtkTextHandlePosition pos,
gint x,
gint y,
GtkEntry *entry)
{
gint cursor_pos, selection_bound_pos, tmp_pos;
GtkEntryPrivate *priv = entry->priv;
GtkTextHandleMode mode;
gint *min, *max;
cursor_pos = priv->current_pos;
selection_bound_pos = priv->selection_bound;
mode = _gtk_text_handle_get_mode (handle);
tmp_pos = gtk_entry_find_position (entry, x + priv->scroll_offset);
if (mode == GTK_TEXT_HANDLE_MODE_CURSOR ||
cursor_pos >= selection_bound_pos)
{
max = &cursor_pos;
min = &selection_bound_pos;
}
else
{
max = &selection_bound_pos;
min = &cursor_pos;
}
if (pos == GTK_TEXT_HANDLE_POSITION_SELECTION_END)
{
if (mode == GTK_TEXT_HANDLE_MODE_SELECTION)
{
gint min_pos;
min_pos = MAX (*min + 1, 0);
tmp_pos = MAX (tmp_pos, min_pos);
}
*max = tmp_pos;
}
else
{
if (mode == GTK_TEXT_HANDLE_MODE_SELECTION)
{
gint max_pos;
max_pos = *max - 1;
*min = MIN (tmp_pos, max_pos);
}
}
if (cursor_pos != priv->current_pos ||
selection_bound_pos != priv->selection_bound)
{
if (mode == GTK_TEXT_HANDLE_MODE_CURSOR)
gtk_entry_set_positions (entry, cursor_pos, cursor_pos);
else
gtk_entry_set_positions (entry, cursor_pos, selection_bound_pos);
_gtk_entry_update_handles (entry, mode);
}
}
void
_gtk_entry_reset_im_context (GtkEntry *entry)
{
@@ -6123,6 +6425,23 @@ gtk_entry_get_cursor_locations (GtkEntry *entry,
}
}
static gboolean
_gtk_entry_get_is_selection_handle_dragged (GtkEntry *entry)
{
GtkEntryPrivate *priv = entry->priv;
GtkTextHandlePosition pos;
if (_gtk_text_handle_get_mode (priv->text_handle) != GTK_TEXT_HANDLE_MODE_SELECTION)
return FALSE;
if (priv->current_pos >= priv->selection_bound)
pos = GTK_TEXT_HANDLE_POSITION_SELECTION_START;
else
pos = GTK_TEXT_HANDLE_POSITION_SELECTION_END;
return _gtk_text_handle_get_is_dragged (priv->text_handle, pos);
}
static void
gtk_entry_adjust_scroll (GtkEntry *entry)
{
@@ -6135,6 +6454,7 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
PangoLayout *layout;
PangoLayoutLine *line;
PangoRectangle logical_rect;
GtkTextHandleMode handle_mode;
if (!gtk_widget_get_realized (GTK_WIDGET (entry)))
return;
@@ -6171,22 +6491,33 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
priv->scroll_offset = CLAMP (priv->scroll_offset, min_offset, max_offset);
/* And make sure cursors are on screen. Note that the cursor is
* actually drawn one pixel into the INNER_BORDER space on
* the right, when the scroll is at the utmost right. This
* looks better to to me than confining the cursor inside the
* border entirely, though it means that the cursor gets one
* pixel closer to the edge of the widget on the right than
* on the left. This might need changing if one changed
* INNER_BORDER from 2 to 1, as one would do on a
* small-screen-real-estate display.
*
* We always make sure that the strong cursor is on screen, and
* put the weak cursor on screen if possible.
*/
if (_gtk_entry_get_is_selection_handle_dragged (entry))
{
/* The text handle corresponding to the selection bound is
* being dragged, ensure it stays onscreen even if we scroll
* cursors away, this is so both handles can cause content
* to scroll.
*/
strong_x = weak_x = _gtk_entry_get_selection_bound_location (entry);
}
else
{
/* And make sure cursors are on screen. Note that the cursor is
* actually drawn one pixel into the INNER_BORDER space on
* the right, when the scroll is at the utmost right. This
* looks better to to me than confining the cursor inside the
* border entirely, though it means that the cursor gets one
* pixel closer to the edge of the widget on the right than
* on the left. This might need changing if one changed
* INNER_BORDER from 2 to 1, as one would do on a
* small-screen-real-estate display.
*
* We always make sure that the strong cursor is on screen, and
* put the weak cursor on screen if possible.
*/
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, &weak_x);
}
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, &weak_x);
strong_xoffset = strong_x - priv->scroll_offset;
if (strong_xoffset < 0)
@@ -6213,6 +6544,11 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
}
g_object_notify (G_OBJECT (entry), "scroll-offset");
handle_mode = _gtk_text_handle_get_mode (priv->text_handle);
if (handle_mode != GTK_TEXT_HANDLE_MODE_NONE)
_gtk_entry_update_handles (entry, handle_mode);
}
static void
@@ -6235,7 +6571,7 @@ gtk_entry_move_adjustments (GtkEntry *entry)
gtk_widget_get_allocation (widget, &allocation);
/* Cursor position, layout offset, border width, and widget allocation */
/* Cursor/char position, layout offset, border width, and widget allocation */
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &x, NULL);
get_layout_position (entry, &layout_x, NULL);
_gtk_entry_get_borders (entry, &borders);
@@ -6563,7 +6899,7 @@ primary_get_cb (GtkClipboard *clipboard,
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
{
gchar *str = gtk_entry_get_display_text (entry, start, end);
gchar *str = _gtk_entry_get_display_text (entry, start, end);
gtk_selection_data_set_text (selection_data, str, -1);
g_free (str);
}
@@ -6904,14 +7240,19 @@ gtk_entry_set_text (GtkEntry *entry,
* @visible: %TRUE if the contents of the entry are displayed
* as plaintext
*
* Sets whether the contents of the entry are visible or not.
* When visibility is set to %FALSE, characters are displayed
* as the invisible char, and will also appear that way when
* Sets whether the contents of the entry are visible or not.
* When visibility is set to %FALSE, characters are displayed
* as the invisible char, and will also appear that way when
* the text in the entry widget is copied elsewhere.
*
* By default, GTK+ picks the best invisible character available
* in the current font, but it can be changed with
* gtk_entry_set_invisible_char().
*
* Note that you probably want to set #GtkEntry:input-purpose
* to %GTK_INPUT_PURPOSE_PASSWORD or %GTK_INPUT_PURPOSE_PIN to
* inform input methods about the purpose of this entry,
* in addition to setting visibility to %FALSE.
*/
void
gtk_entry_set_visibility (GtkEntry *entry,
@@ -9102,7 +9443,7 @@ gtk_entry_drag_data_get (GtkWidget *widget,
if (gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end))
{
gchar *str = gtk_entry_get_display_text (GTK_ENTRY (widget), sel_start, sel_end);
gchar *str = _gtk_entry_get_display_text (GTK_ENTRY (widget), sel_start, sel_end);
gtk_selection_data_set_text (selection_data, str, -1);
@@ -10295,3 +10636,102 @@ _gtk_entry_set_is_cell_renderer (GtkEntry *entry,
{
entry->priv->is_cell_renderer = is_cell_renderer;
}
/**
* gtk_entry_set_input_purpose:
* @entry: a #GtkEntry
* @purpose: the purpose
*
* Sets the #GtkEntry:input-purpose property which
* can be used by on-screen keyboards and other input
* methods to adjust their behaviour.
*
* Since: 3.6
*/
void
gtk_entry_set_input_purpose (GtkEntry *entry,
GtkInputPurpose purpose)
{
g_return_if_fail (GTK_IS_ENTRY (entry));
if (gtk_entry_get_input_purpose (entry) != purpose)
{
g_object_set (G_OBJECT (entry->priv->im_context),
"input-purpose", purpose,
NULL);
g_object_notify (G_OBJECT (entry), "input-purpose");
}
}
/**
* gtk_entry_get_input_purpose:
* @entry: a #GtkEntry
*
* Gets the value of the #GtkEntry:input-purpose property.
*
* Since: 3.6
*/
GtkInputPurpose
gtk_entry_get_input_purpose (GtkEntry *entry)
{
GtkInputPurpose purpose;
g_return_val_if_fail (GTK_IS_ENTRY (entry), GTK_INPUT_PURPOSE_FREE_FORM);
g_object_get (G_OBJECT (entry->priv->im_context),
"input-purpose", &purpose,
NULL);
return purpose;
}
/**
* gtk_entry_set_input_hints:
* @entry: a #GtkEntry
* @hints: the hints
*
* Sets the #GtkEntry:input-hints property, which
* allows input methods to fine-tune their behaviour.
*
* Since: 3.6
*/
void
gtk_entry_set_input_hints (GtkEntry *entry,
GtkInputHints hints)
{
g_return_if_fail (GTK_IS_ENTRY (entry));
if (gtk_entry_get_input_hints (entry) != hints)
{
g_object_set (G_OBJECT (entry->priv->im_context),
"input-hints", hints,
NULL);
g_object_notify (G_OBJECT (entry), "input-hints");
}
}
/**
* gtk_entry_get_input_hints:
* @entry: a #GtkEntry
*
* Gets the value of the #GtkEntry:input-hints property.
*
* Since: 3.6
*/
GtkInputHints
gtk_entry_get_input_hints (GtkEntry *entry)
{
GtkInputHints hints;
g_return_val_if_fail (GTK_IS_ENTRY (entry), GTK_INPUT_HINT_NONE);
g_object_get (G_OBJECT (entry->priv->im_context),
"input-hints", &hints,
NULL);
return hints;
}
+12
View File
@@ -277,6 +277,18 @@ gboolean gtk_entry_im_context_filter_keypress (GtkEntry *
GdkEventKey *event);
void gtk_entry_reset_im_context (GtkEntry *entry);
GDK_AVAILABLE_IN_3_6
void gtk_entry_set_input_purpose (GtkEntry *entry,
GtkInputPurpose purpose);
GDK_AVAILABLE_IN_3_6
GtkInputPurpose gtk_entry_get_input_purpose (GtkEntry *entry);
GDK_AVAILABLE_IN_3_6
void gtk_entry_set_input_hints (GtkEntry *entry,
GtkInputHints hints);
GDK_AVAILABLE_IN_3_6
GtkInputHints gtk_entry_get_input_hints (GtkEntry *entry);
G_END_DECLS
+5 -2
View File
@@ -77,8 +77,11 @@ void _gtk_entry_completion_popup (GtkEntryCompletion *completion,
GdkDevice *device);
void _gtk_entry_completion_popdown (GtkEntryCompletion *completion);
void _gtk_entry_get_borders (GtkEntry *entry,
GtkBorder *borders);
gchar* _gtk_entry_get_display_text (GtkEntry *entry,
gint start_pos,
gint end_pos);
void _gtk_entry_get_borders (GtkEntry *entry,
GtkBorder *borders);
void _gtk_entry_reset_im_context (GtkEntry *entry);
GtkIMContext* _gtk_entry_get_im_context (GtkEntry *entry);
void _gtk_entry_set_is_cell_renderer (GtkEntry *entry,
+84
View File
@@ -950,5 +950,89 @@ typedef enum {
G_END_DECLS
/**
* GtkInputPurpose:
* @GTK_INPUT_PURPOSE_FREE_FORM: Allow any character
* @GTK_INPUT_PURPOSE_ALPHA: Allow only alphabetic characters
* @GTK_INPUT_PURPOSE_DIGITS: Allow only digits
* @GTK_INPUT_PURPOSE_NUMBER: Edited field expects numbers
* @GTK_INPUT_PURPOSE_PHONE: Edited field expects phone number
* @GTK_INPUT_PURPOSE_URL: Edited field expects URL
* @GTK_INPUT_PURPOSE_EMAIL: Edited field expects email address
* @GTK_INPUT_PURPOSE_NAME: Edited field expects the name of a person
* @GTK_INPUT_PURPOSE_PASSWORD: Like @GTK_INPUT_PURPOSE_FREE_FORM, but characters are hidden
* @GTK_INPUT_PURPOSE_PIN: Like @GTK_INPUT_PURPOSE_DIGITS, but characters are hidden
*
* Describes primary purpose of the input widget. This information is
* useful for on-screen keyboards and similar input methods to decide
* which keys should be presented to the user.
*
* Note that the purpose is not meant to impose a totally strict rule
* about allowed characters, and does not replace input validation.
* It is fine for an on-screen keyboard to let the user override the
* character set restriction that is expressed by the purpose. The
* application is expected to validate the entry contents, even if
* it specified a purpose.
*
* The difference between @GTK_INPUT_PURPOSE_DIGITS and
* @GTK_INPUT_PURPOSE_NUMBER is that the former accepts only digits
* while the latter also some punctuation (like commas or points, plus,
* minus) and 'e' or 'E' as in 3.14E+000.
*
* This enumeration may be extended in the future; input methods should
* interpret unknown values as 'free form'.
*
* Since: 3.6
*/
typedef enum
{
GTK_INPUT_PURPOSE_FREE_FORM,
GTK_INPUT_PURPOSE_ALPHA,
GTK_INPUT_PURPOSE_DIGITS,
GTK_INPUT_PURPOSE_NUMBER,
GTK_INPUT_PURPOSE_PHONE,
GTK_INPUT_PURPOSE_URL,
GTK_INPUT_PURPOSE_EMAIL,
GTK_INPUT_PURPOSE_NAME,
GTK_INPUT_PURPOSE_PASSWORD,
GTK_INPUT_PURPOSE_PIN
} GtkInputPurpose;
/**
* GtkInputHints:
* @GDK_INPUT_HINT_NONE: No special behaviour suggested
* @GTK_INPUT_HINT_SPELLCHECK: Suggest checking for typos
* @GTK_INPUT_HINT_NO_SPELLCHECK: Suggest not checking for typos
* @GTK_INPUT_HINT_WORD_COMPLETION: Suggest word completion
* @GTK_INPUT_HINT_LOWERCASE: Suggest to convert all text to lowercase
* @GTK_INPUT_HINT_UPPERCASE_CHARS: Suggest to capitalize all text
* @GTK_INPUT_HINT_UPPERCASE_WORDS: Suggest to capitalize the first
* character of each word
* @GTK_INPUT_HINT_UPPERCASE_SENTENCES: Suggest to capitalize the
* first word of each sentence
*
* Describes hints that might be taken into account by input methods
* or applications. Note that input methods may already tailor their
* behaviour according to the #GtkInputPurpose of the entry.
*
* Some common sense is expected when using these flags - mixing
* @GTK_INPUT_HINT_LOWERCASE with any of the uppercase hints makes no sense.
*
* This enumeration may be extended in the future; input methods should
* ignore unknown values.
*
* Since: 3.6
*/
typedef enum
{
GTK_INPUT_HINT_NONE = 0,
GTK_INPUT_HINT_SPELLCHECK = 1 << 0,
GTK_INPUT_HINT_NO_SPELLCHECK = 1 << 1,
GTK_INPUT_HINT_WORD_COMPLETION = 1 << 2,
GTK_INPUT_HINT_LOWERCASE = 1 << 3,
GTK_INPUT_HINT_UPPERCASE_CHARS = 1 << 4,
GTK_INPUT_HINT_UPPERCASE_WORDS = 1 << 5,
GTK_INPUT_HINT_UPPERCASE_SENTENCES = 1 << 6
} GtkInputHints;
#endif /* __GTK_ENUMS_H__ */
+7 -7
View File
@@ -2249,7 +2249,7 @@ add_idle_while_impl_is_alive (GtkFileChooserDefault *impl, GCallback callback)
static gboolean
edited_idle_cb (GtkFileChooserDefault *impl)
{
GDK_THREADS_ENTER ();
gdk_threads_enter ();
g_source_destroy (impl->edited_idle);
impl->edited_idle = NULL;
@@ -2287,7 +2287,7 @@ edited_idle_cb (GtkFileChooserDefault *impl)
impl->edited_new_text = NULL;
}
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return FALSE;
}
@@ -6779,14 +6779,14 @@ file_system_model_got_thumbnail (GObject *object, GAsyncResult *res, gpointer da
if (queried == NULL)
return;
GDK_THREADS_ENTER ();
gdk_threads_enter ();
/* now we know model is valid */
/* file was deleted */
if (!_gtk_file_system_model_get_iter_for_file (model, &iter, file))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return;
}
@@ -6800,7 +6800,7 @@ file_system_model_got_thumbnail (GObject *object, GAsyncResult *res, gpointer da
g_object_unref (info);
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
}
static gboolean
@@ -9333,7 +9333,7 @@ search_entry_activate_cb (GtkEntry *entry,
static gboolean
focus_entry_idle_cb (GtkFileChooserDefault *impl)
{
GDK_THREADS_ENTER ();
gdk_threads_enter ();
g_source_destroy (impl->focus_entry_idle);
impl->focus_entry_idle = NULL;
@@ -9341,7 +9341,7 @@ focus_entry_idle_cb (GtkFileChooserDefault *impl)
if (impl->search_entry)
gtk_widget_grab_focus (impl->search_entry);
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
return FALSE;
}
+10 -2
View File
@@ -4575,7 +4575,8 @@ gtk_icon_view_set_tooltip_cell (GtkIconView *icon_view,
* @x: (inout): the x coordinate (relative to widget coordinates)
* @y: (inout): the y coordinate (relative to widget coordinates)
* @keyboard_tip: whether this is a keyboard tooltip or not
* @model: (out) (allow-none): a pointer to receive a #GtkTreeModel or %NULL
* @model: (out) (allow-none) (transfer none): a pointer to receive a
* #GtkTreeModel or %NULL
* @path: (out) (allow-none): a pointer to receive a #GtkTreePath or %NULL
* @iter: (out) (allow-none): a pointer to receive a #GtkTreeIter or %NULL
*
@@ -4900,6 +4901,8 @@ void
gtk_icon_view_set_model (GtkIconView *icon_view,
GtkTreeModel *model)
{
gboolean dirty;
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
@@ -4916,6 +4919,8 @@ gtk_icon_view_set_model (GtkIconView *icon_view,
if (icon_view->priv->cell_area)
gtk_cell_area_stop_editing (icon_view->priv->cell_area, TRUE);
dirty = gtk_icon_view_unselect_all_internal (icon_view);
if (model)
{
GType column_type;
@@ -5000,6 +5005,9 @@ gtk_icon_view_set_model (GtkIconView *icon_view,
g_object_notify (G_OBJECT (icon_view), "model");
if (dirty)
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
gtk_widget_queue_resize (GTK_WIDGET (icon_view));
}
@@ -5371,7 +5379,7 @@ gtk_icon_view_unselect_path (GtkIconView *icon_view,
*
* To free the return value, use:
* |[
* g_list_free_full (list, (GDestroyNotify) gtk_tree_patch_free);
* g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
* ]|
*
* Return value: (element-type GtkTreePath) (transfer full): A #GList containing a #GtkTreePath for each selected row.
+93 -1
View File
@@ -19,6 +19,7 @@
#include <string.h>
#include "gtkimcontext.h"
#include "gtkprivate.h"
#include "gtktypebuiltins.h"
#include "gtkmarshalers.h"
#include "gtkintl.h"
@@ -107,7 +108,20 @@ enum {
LAST_SIGNAL
};
static guint im_context_signals[LAST_SIGNAL] = { 0 };
enum {
PROP_INPUT_PURPOSE = 1,
PROP_INPUT_HINTS,
LAST_PROPERTY
};
static guint im_context_signals[LAST_SIGNAL] = { 0, };
static GParamSpec *properties[LAST_PROPERTY] = { NULL, };
typedef struct _GtkIMContextPrivate GtkIMContextPrivate;
struct _GtkIMContextPrivate {
GtkInputPurpose purpose;
GtkInputHints hints;
};
static void gtk_im_context_real_get_preedit_string (GtkIMContext *context,
gchar **str,
@@ -123,6 +137,16 @@ static void gtk_im_context_real_set_surrounding (GtkIMContext *context,
gint len,
gint cursor_index);
static void gtk_im_context_get_property (GObject *obj,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gtk_im_context_set_property (GObject *obj,
guint property_id,
const GValue *value,
GParamSpec *pspec);
G_DEFINE_ABSTRACT_TYPE (GtkIMContext, gtk_im_context, G_TYPE_OBJECT)
/**
@@ -185,6 +209,11 @@ G_DEFINE_ABSTRACT_TYPE (GtkIMContext, gtk_im_context, G_TYPE_OBJECT)
static void
gtk_im_context_class_init (GtkIMContextClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gtk_im_context_get_property;
object_class->set_property = gtk_im_context_set_property;
klass->get_preedit_string = gtk_im_context_real_get_preedit_string;
klass->filter_keypress = gtk_im_context_real_filter_keypress;
klass->get_surrounding = gtk_im_context_real_get_surrounding;
@@ -297,6 +326,25 @@ gtk_im_context_class_init (GtkIMContextClass *klass)
G_TYPE_BOOLEAN, 2,
G_TYPE_INT,
G_TYPE_INT);
properties[PROP_INPUT_PURPOSE] =
g_param_spec_enum ("input-purpose",
P_("Purpose"),
P_("Purpose of the text field"),
GTK_TYPE_INPUT_PURPOSE,
GTK_INPUT_PURPOSE_FREE_FORM,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
properties[PROP_INPUT_HINTS] =
g_param_spec_flags ("input-hints",
P_("hints"),
P_("Hints for the text field behaviour"),
GTK_TYPE_INPUT_HINTS,
GTK_INPUT_HINT_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_type_class_add_private (klass, sizeof (GtkIMContextPrivate));
g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
}
static void
@@ -706,3 +754,47 @@ gtk_im_context_delete_surrounding (GtkIMContext *context,
return result;
}
static void
gtk_im_context_get_property (GObject *obj,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkIMContextPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (obj, GTK_TYPE_IM_CONTEXT, GtkIMContextPrivate);
switch (property_id)
{
case PROP_INPUT_PURPOSE:
g_value_set_enum (value, priv->purpose);
break;
case PROP_INPUT_HINTS:
g_value_set_flags (value, priv->hints);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
break;
}
}
static void
gtk_im_context_set_property (GObject *obj,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkIMContextPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (obj, GTK_TYPE_IM_CONTEXT, GtkIMContextPrivate);
switch (property_id)
{
case PROP_INPUT_PURPOSE:
priv->purpose = g_value_get_enum (value);
break;
case PROP_INPUT_HINTS:
priv->hints = g_value_get_flags (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
break;
}
}
+3 -1
View File
@@ -97,6 +97,8 @@
#include <math.h>
#include <stdlib.h>
#include "fallback-c89.c"
#define DEFAULT_BLOCK_SIZE 3
/* these don't make sense outside of GtkLevelBar, so we don't add
@@ -647,7 +649,7 @@ offset_start_element (GMarkupParseContext *context,
if (name && value_str)
{
offset = gtk_level_bar_offset_new (name, strtof (value_str, NULL));
offset = gtk_level_bar_offset_new (name, g_ascii_strtod (value_str, NULL));
parser_data->offsets = g_list_prepend (parser_data->offsets, offset);
}
}
+8 -8
View File
@@ -1158,9 +1158,9 @@ gtk_main (void)
if (g_main_loop_is_running (main_loops->data))
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_loop_run (loop);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
gdk_flush ();
}
@@ -1235,9 +1235,9 @@ gtk_events_pending (void)
{
gboolean result;
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
result = g_main_context_pending (NULL);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
return result;
}
@@ -1258,9 +1258,9 @@ gtk_events_pending (void)
gboolean
gtk_main_iteration (void)
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_context_iteration (NULL, TRUE);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
if (main_loops)
return !g_main_loop_is_running (main_loops->data);
@@ -1282,9 +1282,9 @@ gtk_main_iteration (void)
gboolean
gtk_main_iteration_do (gboolean blocking)
{
GDK_THREADS_LEAVE ();
gdk_threads_leave ();
g_main_context_iteration (NULL, blocking);
GDK_THREADS_ENTER ();
gdk_threads_enter ();
if (main_loops)
return !g_main_loop_is_running (main_loops->data);
+1
View File
@@ -69,6 +69,7 @@ VOID:ENUM,FLOAT
VOID:ENUM,FLOAT,BOOLEAN
VOID:ENUM,INT
VOID:ENUM,INT,BOOLEAN
VOID:ENUM,INT,INT
VOID:ENUM,BOXED
VOID:ENUM,STRING
VOID:FLAGS
+4
View File
@@ -1220,6 +1220,8 @@ gtk_menu_attach_to_widget (GtkMenu *menu,
/* Attach the widget to the toplevel window. */
gtk_window_set_attached_to (GTK_WINDOW (menu->priv->toplevel), attach_widget);
_gtk_widget_update_parent_muxer (GTK_WIDGET (menu));
/* Fallback title for menu comes from attach widget */
gtk_menu_update_title (menu);
@@ -1294,6 +1296,8 @@ gtk_menu_detach (GtkMenu *menu)
g_slice_free (GtkMenuAttachData, data);
_gtk_widget_update_parent_muxer (GTK_WIDGET (menu));
/* Fallback title for menu comes from attach widget */
gtk_menu_update_title (menu);
+247 -136
View File
@@ -26,9 +26,118 @@
* The #GtkMenuButton widget is used to display a menu when clicked on.
* This menu can be provided either as a #GtkMenu, or an abstract #GMenuModel.
*
* The #GtkMenuButton widget can hold any valid child widget. That is, it can hold
* almost any other standard #GtkWidget. The most commonly used child is the
* provided #GtkArrow.
* The #GtkMenuButton widget can hold any valid child widget. That is, it
* can hold almost any other standard #GtkWidget. The most commonly used
* child is the provided #GtkArrow.
*
* The positioning of the menu is determined by the #GtkMenuButton:direction
* property of the menu button and the #GtkWidget:halign or #GtkWidget:valign
* properties of the menu. For example, when the direction is %GTK_ARROW_DOWN
* and the horizontal alignment is %GTK_ALIGN_START, the menu will be
* positioned below the button, with the starting edge (depending on the
* text direction) of the menu aligned with the starting edge of the button.
* If there is not enough space below the button, the menu is popped up above
* the button instead. If the alignment would move part of the menu offscreen,
* it is 'pushed in'.
*
* <informaltable>
* <tgroup cols="4">
* <tbody>
* <row>
* <entry></entry>
* <entry>halign = start</entry>
* <entry>halign = center</entry>
* <entry>halign = end</entry>
* </row>
* <row>
* <entry>direction = down</entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="down-start.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="down-center.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="down-end.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* </row>
* <row>
* <entry>direction = up</entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="up-start.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="up-center.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="up-end.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* </row>
* </tbody>
* </tgroup>
* </informaltable>
* <informaltable>
* <tgroup cols="3">
* <tbody>
* <row>
* <entry></entry>
* <entry>direction = left</entry>
* <entry>direction = right</entry>
* </row>
* <row>
* <entry>valign = start</entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="left-start.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="right-start.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* </row>
* <row>
* <entry>valign = center</entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="left-center.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="right-center.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* </row>
* <row>
* <entry>valign = end</entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="left-end.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* <entry>
* <inlinemediaobject>
* <imageobject><imagedata fileref="right-end.png" format="PNG"/></imageobject>
* </inlinemediaobject>
* </entry>
* </row>
* </tbody>
* </tgroup>
* </informaltable>
*/
#include "config.h"
@@ -42,7 +151,7 @@
struct _GtkMenuButtonPrivate
{
GtkWidget *menu;
GtkWidget *popup;
GMenuModel *model;
GtkMenuButtonShowMenuCallback func;
@@ -56,7 +165,7 @@ struct _GtkMenuButtonPrivate
enum
{
PROP_0,
PROP_MENU,
PROP_POPUP,
PROP_MODEL,
PROP_ALIGN_WIDGET,
PROP_DIRECTION
@@ -64,7 +173,7 @@ enum
G_DEFINE_TYPE(GtkMenuButton, gtk_menu_button, GTK_TYPE_TOGGLE_BUTTON)
static void gtk_menu_button_finalize (GObject *object);
static void gtk_menu_button_dispose (GObject *object);
static void
gtk_menu_button_set_property (GObject *object,
@@ -76,8 +185,8 @@ gtk_menu_button_set_property (GObject *object,
switch (property_id)
{
case PROP_MENU:
gtk_menu_button_set_menu (self, g_value_get_object (value));
case PROP_POPUP:
gtk_menu_button_set_popup (self, g_value_get_object (value));
break;
case PROP_MODEL:
gtk_menu_button_set_menu_model (self, g_value_get_object (value));
@@ -103,8 +212,8 @@ gtk_menu_button_get_property (GObject *object,
switch (property_id)
{
case PROP_MENU:
g_value_set_object (value, priv->menu);
case PROP_POPUP:
g_value_set_object (value, priv->popup);
break;
case PROP_MODEL:
g_value_set_object (value, priv->model);
@@ -127,16 +236,16 @@ gtk_menu_button_state_flags_changed (GtkWidget *widget,
GtkMenuButton *button = GTK_MENU_BUTTON (widget);
GtkMenuButtonPrivate *priv = button->priv;
if (!gtk_widget_is_sensitive (widget) && priv->menu)
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
if (!gtk_widget_is_sensitive (widget) && priv->popup)
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->popup));
}
static void
menu_position_down_func (GtkMenu *menu,
gint *x,
gint *y,
gboolean *push_in,
GtkMenuButton *menu_button)
menu_position_up_down_func (GtkMenu *menu,
gint *x,
gint *y,
gboolean *push_in,
GtkMenuButton *menu_button)
{
GtkMenuButtonPrivate *priv = menu_button->priv;
GtkWidget *widget = GTK_WIDGET (menu_button);
@@ -147,14 +256,12 @@ menu_position_down_func (GtkMenu *menu,
GdkScreen *screen;
GdkWindow *window;
GtkAllocation allocation, arrow_allocation;
GtkWidget *toplevel;
GtkAlign align;
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (priv->menu));
gtk_window_set_type_hint (GTK_WINDOW (toplevel), GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU);
gtk_widget_get_preferred_size (GTK_WIDGET (priv->menu),
gtk_widget_get_preferred_size (GTK_WIDGET (priv->popup),
&menu_req, NULL);
align = gtk_widget_get_halign (GTK_WIDGET (priv->popup));
direction = gtk_widget_get_direction (widget);
window = gtk_widget_get_window (priv->align_widget ? priv->align_widget : widget);
@@ -171,71 +278,32 @@ menu_position_down_func (GtkMenu *menu,
*x += allocation.x;
*y += allocation.y;
if (direction == GTK_TEXT_DIR_LTR)
/* treat the default align value like START */
if (align == GTK_ALIGN_FILL)
align = GTK_ALIGN_START;
if (align == GTK_ALIGN_CENTER)
*x -= (menu_req.width - allocation.width) / 2;
else if ((align == GTK_ALIGN_START && direction == GTK_TEXT_DIR_LTR) ||
(align == GTK_ALIGN_END && direction == GTK_TEXT_DIR_RTL))
*x += MAX (allocation.width - menu_req.width, 0);
else if (menu_req.width > allocation.width)
*x -= menu_req.width - allocation.width;
if ((*y + arrow_allocation.height + menu_req.height) <= monitor.y + monitor.height)
*y += arrow_allocation.height;
else if ((*y - menu_req.height) >= monitor.y)
*y -= menu_req.height;
else if (monitor.y + monitor.height - (*y + arrow_allocation.height) > *y)
*y += arrow_allocation.height;
else
*y -= menu_req.height;
*push_in = FALSE;
}
static void
menu_position_up_func (GtkMenu *menu,
gint *x,
gint *y,
gboolean *push_in,
GtkMenuButton *menu_button)
{
GtkMenuButtonPrivate *priv = menu_button->priv;
GtkWidget *widget = GTK_WIDGET (menu_button);
GtkRequisition menu_req;
GtkTextDirection direction;
GdkRectangle monitor;
gint monitor_num;
GdkScreen *screen;
GdkWindow *window;
GtkAllocation allocation, arrow_allocation;
gtk_widget_get_preferred_size (GTK_WIDGET (priv->menu),
&menu_req, NULL);
direction = gtk_widget_get_direction (widget);
window = gtk_widget_get_window (priv->align_widget ? priv->align_widget : widget);
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
if (monitor_num < 0)
monitor_num = 0;
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
gtk_widget_get_allocation (priv->align_widget ? priv->align_widget : widget, &allocation);
gtk_widget_get_allocation (widget, &arrow_allocation);
gdk_window_get_origin (window, x, y);
*x += allocation.x;
*y += allocation.y;
if (direction == GTK_TEXT_DIR_LTR)
*x += MAX (allocation.width - menu_req.width, 0);
else if (menu_req.width > allocation.width)
*x -= menu_req.width - allocation.width;
*y -= menu_req.height;
/* If we're going to clip the top, pop down instead */
if (*y < monitor.y)
if (priv->arrow_type == GTK_ARROW_UP && *y - menu_req.height >= monitor.y)
{
menu_position_down_func (menu, x, y, push_in, menu_button);
return;
*y -= menu_req.height;
}
else
{
if ((*y + arrow_allocation.height + menu_req.height) <= monitor.y + monitor.height)
*y += arrow_allocation.height;
else if ((*y - menu_req.height) >= monitor.y)
*y -= menu_req.height;
else if (monitor.y + monitor.height - (*y + arrow_allocation.height) > *y)
*y += arrow_allocation.height;
else
*y -= menu_req.height;
}
*push_in = FALSE;
@@ -249,19 +317,21 @@ menu_position_side_func (GtkMenu *menu,
GtkMenuButton *menu_button)
{
GtkMenuButtonPrivate *priv = menu_button->priv;
GtkAllocation toggle_allocation;
GtkAllocation allocation;
GtkWidget *widget = GTK_WIDGET (menu_button);
GtkRequisition menu_req;
GdkRectangle monitor;
gint monitor_num;
GdkScreen *screen;
GdkWindow *window;
GtkAlign align;
gtk_widget_get_preferred_size (GTK_WIDGET (priv->menu),
gtk_widget_get_preferred_size (GTK_WIDGET (priv->popup),
&menu_req, NULL);
window = gtk_widget_get_window (widget);
align = gtk_widget_get_valign (GTK_WIDGET (menu));
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
if (monitor_num < 0)
@@ -270,16 +340,31 @@ menu_position_side_func (GtkMenu *menu,
gdk_window_get_origin (gtk_button_get_event_window (GTK_BUTTON (menu_button)), x, y);
gtk_widget_get_allocation (widget, &toggle_allocation);
gtk_widget_get_allocation (widget, &allocation);
if (priv->arrow_type == GTK_ARROW_RIGHT)
*x += toggle_allocation.width;
{
if (*x + allocation.width + menu_req.width <= monitor.x + monitor.width)
*x += allocation.width;
else
*x -= menu_req.width;
}
else
*x -= menu_req.width;
{
if (*x - menu_req.width >= monitor.x)
*x -= menu_req.width;
else
*x += allocation.width;
}
if (*y + menu_req.height > monitor.y + monitor.height &&
*y + toggle_allocation.height - monitor.y > monitor.y + monitor.height - *y)
*y += toggle_allocation.height - menu_req.height;
/* treat the default align value like START */
if (align == GTK_ALIGN_FILL)
align = GTK_ALIGN_START;
if (align == GTK_ALIGN_CENTER)
*y -= (menu_req.height - allocation.height) / 2;
else if (align == GTK_ALIGN_END)
*y -= menu_req.height - allocation.height;
*push_in = FALSE;
}
@@ -294,24 +379,21 @@ popup_menu (GtkMenuButton *menu_button,
if (priv->func)
priv->func (priv->user_data);
if (!priv->menu)
if (!priv->popup)
return;
switch (priv->arrow_type)
{
case GTK_ARROW_UP:
func = (GtkMenuPositionFunc) menu_position_up_func;
break;
case GTK_ARROW_LEFT:
case GTK_ARROW_RIGHT:
func = (GtkMenuPositionFunc) menu_position_side_func;
break;
default:
func = (GtkMenuPositionFunc) menu_position_down_func;
func = (GtkMenuPositionFunc) menu_position_up_down_func;
break;
}
gtk_menu_popup_for_device (GTK_MENU (priv->menu),
gtk_menu_popup_for_device (GTK_MENU (priv->popup),
event ? event->device : NULL,
NULL, NULL,
func,
@@ -327,17 +409,17 @@ gtk_menu_button_toggled (GtkToggleButton *button)
GtkMenuButton *menu_button = GTK_MENU_BUTTON (button);
GtkMenuButtonPrivate *priv = menu_button->priv;
if (!priv->menu)
if (!priv->popup)
return;
if (gtk_toggle_button_get_active (button) &&
!gtk_widget_get_visible (GTK_WIDGET (priv->menu)))
!gtk_widget_get_visible (GTK_WIDGET (priv->popup)))
{
/* we get here only when the menu is activated by a key
* press, so that we can select the first menu item
*/
popup_menu (menu_button, NULL);
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->popup), FALSE);
}
}
@@ -367,7 +449,7 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
gobject_class->set_property = gtk_menu_button_set_property;
gobject_class->get_property = gtk_menu_button_get_property;
gobject_class->finalize = gtk_menu_button_finalize;
gobject_class->dispose = gtk_menu_button_dispose;
widget_class->state_flags_changed = gtk_menu_button_state_flags_changed;
widget_class->button_press_event = gtk_menu_button_button_press_event;
@@ -375,19 +457,35 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
toggle_button_class->toggled = gtk_menu_button_toggled;
/**
* GtkMenuButton:menu:
* GtkMenuButton:popup:
*
* The #GtkMenu that will be popped up when the button is clicked.
*
* Since: 3.6
*/
g_object_class_install_property (gobject_class,
PROP_MENU,
PROP_POPUP,
g_param_spec_object ("popup",
P_("popup"),
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_READWRITE));
G_PARAM_DEPRECATED | G_PARAM_READWRITE));
/**
* GtkMenuButton:menu-model:
*
@@ -497,9 +595,9 @@ menu_detacher (GtkWidget *widget,
{
GtkMenuButtonPrivate *priv = GTK_MENU_BUTTON (widget)->priv;
g_return_if_fail (priv->menu == (GtkWidget *) menu);
g_return_if_fail (priv->popup == (GtkWidget *) menu);
priv->menu = NULL;
priv->popup = NULL;
}
/* This function is used in GtkMenuToolButton, the call back will
@@ -507,10 +605,10 @@ menu_detacher (GtkWidget *widget,
* signal.
*/
void
_gtk_menu_button_set_menu_with_func (GtkMenuButton *menu_button,
GtkWidget *menu,
GtkMenuButtonShowMenuCallback func,
gpointer user_data)
_gtk_menu_button_set_popup_with_func (GtkMenuButton *menu_button,
GtkWidget *menu,
GtkMenuButtonShowMenuCallback func,
gpointer user_data)
{
GtkMenuButtonPrivate *priv;
@@ -521,33 +619,33 @@ _gtk_menu_button_set_menu_with_func (GtkMenuButton *menu_button,
priv->func = func;
priv->user_data = user_data;
if (priv->menu == GTK_WIDGET (menu))
if (priv->popup == GTK_WIDGET (menu))
return;
if (priv->menu)
if (priv->popup)
{
if (gtk_widget_get_visible (GTK_WIDGET (priv->menu)))
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
if (gtk_widget_get_visible (GTK_WIDGET (priv->popup)))
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->popup));
}
if (priv->menu)
if (priv->popup)
{
g_signal_handlers_disconnect_by_func (priv->menu,
g_signal_handlers_disconnect_by_func (priv->popup,
menu_deactivate_cb,
menu_button);
gtk_menu_detach (GTK_MENU (priv->menu));
gtk_menu_detach (GTK_MENU (priv->popup));
}
priv->menu = menu;
priv->popup = menu;
if (priv->menu)
if (priv->popup)
{
gtk_menu_attach_to_widget (GTK_MENU (priv->menu), GTK_WIDGET (menu_button),
gtk_menu_attach_to_widget (GTK_MENU (priv->popup), GTK_WIDGET (menu_button),
menu_detacher);
gtk_widget_set_sensitive (GTK_WIDGET (menu_button), TRUE);
g_signal_connect (priv->menu, "deactivate",
g_signal_connect (priv->popup, "deactivate",
G_CALLBACK (menu_deactivate_cb), menu_button);
}
else
@@ -560,9 +658,9 @@ _gtk_menu_button_set_menu_with_func (GtkMenuButton *menu_button,
}
/**
* gtk_menu_button_set_menu:
* gtk_menu_button_set_popup:
* @menu_button: a #GtkMenuButton
* @menu: (allow-none): a #GtkMenu
* @popup: (allow-none): a #GtkMenu
*
* Sets the #GtkMenu that will be popped up when the button is clicked,
* or %NULL to disable the button. If #GtkMenuButton:menu-model is set,
@@ -571,22 +669,22 @@ _gtk_menu_button_set_menu_with_func (GtkMenuButton *menu_button,
* Since: 3.6
*/
void
gtk_menu_button_set_menu (GtkMenuButton *menu_button,
GtkWidget *menu)
gtk_menu_button_set_popup (GtkMenuButton *menu_button,
GtkWidget *popup)
{
GtkMenuButtonPrivate *priv;
g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
g_return_if_fail (GTK_IS_MENU (popup) || popup == NULL);
priv = menu_button->priv;
g_clear_object (&priv->model);
_gtk_menu_button_set_menu_with_func (menu_button, menu, NULL, NULL);
_gtk_menu_button_set_popup_with_func (menu_button, popup, NULL, NULL);
}
/**
* gtk_menu_button_get_menu:
* gtk_menu_button_get_popup:
* @menu_button: a #GtkMenuButton
*
* Returns the #GtkMenu that pops out of the button.
@@ -596,11 +694,24 @@ gtk_menu_button_set_menu (GtkMenuButton *menu_button,
* Since: 3.6
*/
GtkMenu *
gtk_menu_button_get_menu (GtkMenuButton *menu_button)
gtk_menu_button_get_popup (GtkMenuButton *menu_button)
{
g_return_val_if_fail (GTK_IS_MENU_BUTTON (menu_button), NULL);
return GTK_MENU (menu_button->priv->menu);
return GTK_MENU (menu_button->priv->popup);
}
void
gtk_menu_button_set_menu (GtkMenuButton *menu_button,
GtkWidget *menu)
{
gtk_menu_button_set_popup (menu_button, menu);
}
GtkMenu *
gtk_menu_button_get_menu (GtkMenuButton *menu_button)
{
return gtk_menu_button_get_popup (menu_button);
}
/**
@@ -634,14 +745,14 @@ gtk_menu_button_set_menu_model (GtkMenuButton *menu_button,
if (menu_model == NULL)
{
gtk_menu_button_set_menu (menu_button, NULL);
gtk_menu_button_set_popup (menu_button, NULL);
return;
}
priv->model = g_object_ref (menu_model);
menu = gtk_menu_new_from_model (menu_model);
gtk_widget_show_all (menu);
gtk_menu_button_set_menu (menu_button, menu);
gtk_menu_button_set_popup (menu_button, menu);
}
/**
@@ -772,19 +883,19 @@ gtk_menu_button_get_direction (GtkMenuButton *menu_button)
}
static void
gtk_menu_button_finalize (GObject *object)
gtk_menu_button_dispose (GObject *object)
{
GtkMenuButtonPrivate *priv = GTK_MENU_BUTTON (object)->priv;
if (priv->menu)
if (priv->popup)
{
g_signal_handlers_disconnect_by_func (priv->menu,
g_signal_handlers_disconnect_by_func (priv->popup,
menu_deactivate_cb,
object);
gtk_menu_detach (GTK_MENU (priv->menu));
gtk_menu_detach (GTK_MENU (priv->popup));
}
g_clear_object (&priv->model);
G_OBJECT_CLASS (gtk_menu_button_parent_class)->finalize (object);
G_OBJECT_CLASS (gtk_menu_button_parent_class)->dispose (object);
}
+7 -1
View File
@@ -65,9 +65,15 @@ GDK_AVAILABLE_IN_3_6
GtkWidget *gtk_menu_button_new (void);
GDK_AVAILABLE_IN_3_6
void gtk_menu_button_set_popup (GtkMenuButton *menu_button,
GtkWidget *popup);
GDK_AVAILABLE_IN_3_6
GtkMenu *gtk_menu_button_get_popup (GtkMenuButton *menu_button);
GDK_DEPRECATED_IN_3_6_FOR(gtk_menu_button_set_popup)
void gtk_menu_button_set_menu (GtkMenuButton *menu_button,
GtkWidget *menu);
GDK_AVAILABLE_IN_3_6
GDK_DEPRECATED_IN_3_6_FOR(gtk_menu_button_get_popup)
GtkMenu *gtk_menu_button_get_menu (GtkMenuButton *menu_button);
GDK_AVAILABLE_IN_3_6

Some files were not shown because too many files have changed in this diff Show More