Compare commits

..

190 Commits

Author SHA1 Message Date
Alexander Larsson 4ab2f28f8e GtkPixelCache: Free cache if not used in 20 seconds
No need to keep a performance enhancing cache around if its not
actually in use.
2013-05-07 14:27:17 +02:00
Alexander Larsson da0cf5fbff gdkwindow: Expose all native windows
We need to send exposes for all native windows, even the ones
without an exposure mask set, because otherwise non-native
children of the native window with an exposure mask will
not be drawn.
2013-05-07 11:46:50 +02:00
Alexander Larsson c60395cfc9 GtkStack: Fix double-draw in crossfade
We should only draw the cross-fade on the bin window, not doing this
was causing us to draw it multiple times using ADD which resulted
in weird colors.
2013-05-07 09:28:30 +02:00
Alexander Larsson cb2ba0abc0 gdkwindow: Avoid some unnecessary typechecks
This removes the typechecks in GDK_WINDOW_TYPE and GDK_WINDOW_DESTROYED. These
are only used internally in gdkwindow.c and gdkdisplay.c anyway,  and these
functions check for typesafety of arguments on function entry.
2013-05-03 10:44:44 +02:00
Alexander Larsson e8e21e7012 GtkWidget: Use gdk_window_get_children_for_user_data
This makes iterating over the children a lot faster, as we're
not doing lots of intra-library calls and type checks. We're still
in some sence O(n^2) since we iterate over each child window for each
widget, but the profiles look much better.
2013-05-03 10:42:40 +02:00
Alexander Larsson 97ad2d7897 Add gdk_window_get_children_with_user_data
This function returns all the children that has a specific user_data set.
This is used a lot in the new GtkWidget drawing code and doing
it this way is faster than getting every child and calling get_user_data
on each (which was a non-neglible part of the profiles). Additionally it
also allows use to use some kind of hashtable to make this operation even
faster if needed in the future.
2013-05-03 10:39:24 +02:00
Alexander Larsson f9592e3c9a GtkTreeView: port to PixelCache
We register an invalidate handler on the bin window to get told
of child widget invalidations, although we manually need to discard
invalidates from the scroll operation.

Additionally we invalidate all of the pixel cache whenever
the TreeView itself is queue_draw()n to handle e.g. style (bg)
changes, or changes due to model changes causing queue_draw() in
the tree view.
2013-05-02 19:03:12 +02:00
Alexander Larsson fdd57076eb Make GtkViewport use GtkPixelCache
Since gdk_window_move() no longer uses XCopyArea all scrolling
now re-renders everything in the window. To get performance
back we use a GtkPixelCache to store already drawn children,
and we when we expose the viewport we just blit the
offscreen to the right place.
2013-05-02 19:03:12 +02:00
Alexander Larsson 994a1bc016 GtkPixelCache: Add debug feature to track redraws
Each time we redraw we tint it in a different color so that
you can see which regions are redrawn.
2013-05-02 19:03:12 +02:00
Alexander Larsson 1d178b5464 Add GtkPixelCache
GtkPixelCache is a helper utility that lets you implement
faster scrolling of a viewport of a canvas by using an
offscreen pixmap cache.

You call _gtk_pixel_cache_draw with a callback function that
does the drawing, and additionally you specify the size and the
position of the viewport in the widget, and the position and size
of the canvas wrt the viewport. The callback will be called to
draw on an offscreen surface, and the surface will be drawn
on the window. The next time you do the same, any already drawn
pieces of the surface are re-used from the offscreen and need
not be rendered again.

If things inside the canvas change you need to call
_gtk_pixel_cache_invalidate to tell the cache about this.

Some other details:

* The offscreen surface is generally a bit larger than
  the viewport, so scrolling a small amount can often
  be done without redrawing children.
* If the canvas is not larger than the viewport no
  offscreen surface is used.

GtkPixelCache: Make sure we always copy using SOURCE

We were using OVER for the first copy (from source to group surface.

GtkPixelCache: Fix x/y typos

GtkPixelCache: Allow NULL for invalidate region

gtkpixelcache: Use CONTENT_COLOR for solid bg windows
2013-05-02 19:03:12 +02:00
Alexander Larsson fe6aa38522 GtkWidget: Add a vfunc for queue_draw_region
Since widgets now cache drawn state we allow them to override
queue_draw_region to detect when some region of the widget
should be redrawn. For instance, if a widget draws the
background color in a pixel cache we will need to invalidate
that when the style context changes which queues a repaint.
2013-05-02 19:03:12 +02:00
Alexander Larsson b2e7ebf6b9 Add gdk_window_set_invalidate_handler
This lets you register callbacks for when child widgets invalidate
areas of the window read it and/or change it.

For instance, this lets you do rendering effects and keeping offscreen
caches uptodate.
2013-05-02 19:03:00 +02:00
Alexander Larsson d4968d8140 wayland: Don't use double buffers for wayland when not needed
If we got the release event for the last buffer then we're
fine with writing directly to the window surface, as wayland
will not be looing at it. This saves us from allocating
and copying more data.
2013-05-02 19:02:09 +02:00
Alexander Larsson adc4f0cdd9 gdkwindow: Make GdkPaintable normal GdkWindowImpl vfuncs
There is no need for this to be a separate interface, its just looking
weird.
2013-05-02 19:02:08 +02:00
Alexander Larsson 9c0bf55a17 gdkwindow: Change how paints work
First of all, we now only do paints on native windows, as there is
really no reason anymore to do it for subwindows. Secondly, we
keep track of the paints even for GtkPaintable windows, but for
that case we don't create the offscreen surface, but rather
assume the windowing system does the backing store.
2013-05-02 19:02:08 +02:00
Alexander Larsson 5fc83197dd GtkWindow: Move cairo_save/restore from marshaller
We do the save/restore when emitting ::draw rather than in a custom
marshaller, as this saves an extra stack frame, which is helpfull now
that we do painting fully recursive. This is also likely to save a few
cycles.
2013-05-02 19:02:08 +02:00
Alexander Larsson c2c976cb6a gdkframeclock: Loop the layout phase if needed
In the case where the layout phase queued a layout we don't
want to progress to the paint phase with invalid allocations, so
we loop the layout. This shouldn't normally happen, but it may
happen in some edge cases like if user/wm resizes clash with
natural window size changes from a gtk widget. This should not
generally loop though, so we detect this after 4 cycles and
print a warning.

This was detected because of an issue in GtkWindow where it
seems to incorrectly handle the case of a user interactive resize.
It seems gtk_window_move_resize() believes that configure_request_size_changed
changed due to hitting some corner case so it calls
gtk_widget_queue_resize_no_redraw(), marking the window as need_alloc
after the layout phase. This commit fixes the issue, but we should
also look into if we can fix that.
2013-05-02 19:02:08 +02:00
Alexander Larsson b1a59dad5e gdkwindow: Simplify invalidation
Now that all windows are non-opaque we can simplify the invalidation
a lot. There is no need to clip the invalidate area to child regions,
because we will always redraw everything under all the children.
We only have to handle native childen specially.
2013-05-02 17:18:12 +02:00
Alexander Larsson 5fef6ed4dc gdkwindow: Remove implicit paints
We now only do one expose event per native window, so there will
only be one begin/end_paint() call. This means all the work with
implicit paints to combine the paints on a single double buffer
surface is unnecessary, so we can just delete it.
2013-05-02 17:18:12 +02:00
Alexander Larsson 6a11e0545d Only handle exposes on native window, propagate to children via draw()
We now consider non-native windows non-opaque, which means any invalid
area in a subwindow will also be invalid all the way up to the nearest
native windows. We take advantage of this by ignoring all expose events
on non-native windows (which typically means just the toplevel) and instead
propagating down the draw() calls to children directly via
gtk_container_propagate_draw.

This is nice as it means we always draw widgets the same way, and it
will let us do some interesting ways in the future.

We also clean up the GtkWidget opacity handling as we can now always
rely on the draing happening via cairo.

We can't really just draw by walking down the widget hierarchy, as
this doesn't get the clipping right (so e.g. widgets doing cairo_paint
may draw outside the expected gdkwindow subarea) nor does it let
us paint window backgrounds.

So, we now do multiple draws for each widget, once for each GdkWindow,
although we still do it on the same base cairo_t that we get for the
toplevel native window. The difference is only the clipping, the rendering
order, and which other widgets we propagate into.

We also collect all the windows of a widget so we can expose them inside
the same opacity group if needed.

NOTE: This change neuters gtk_widget_set_double_buffered for
widgets without native windows. Its impossible to disable
the double buffering in this model.
2013-05-02 17:18:03 +02:00
Alexander Larsson 456321c2d7 gdkwindow: Remove ancient USE_BACKING_STORE define
This is always set anyway.
2013-05-02 16:09:09 +02:00
Alexander Larsson 14a63693de gdkwindow: Simplify clip region calculations
Since we no longer make overlapping siblings affect clip_region we
can further simplify the clip region calculation and updating.
2013-05-02 16:09:09 +02:00
Alexander Larsson 6f32b6fadc gdkwindow: Simplify clip region handling
Since we dropped the move region optimization there is really no need
to try carefully keep track of opaque non-overlapped regions, as we
don't use this information to trigger the optimization anymore.

So, by assuming that all windows are non-opaque we can vastly simplify
the clip region stuff. First of all, we don't need clip_region_with_children,
as each window will need to draw under all children anyway. Secondly, we
don't remove overlapping sibling areas from clip_region, as these are
all non-opaque anyway and we need to draw under them

Finally, we don't need to track the layered region anymore as its
essentially unused. The few times something like it is needed we can
compute it explicitly.

For the case of native children of widgets we may cause a repaint
under native windows that are guaranteed to be opaque, but these
will be clipped by the native child anyway.
2013-05-02 16:09:09 +02:00
Alexander Larsson 3431a5346d gdkwindow: Remove translate vfunc
This is not used anymore
2013-05-02 16:09:09 +02:00
Alexander Larsson 1dd823f6f6 gdkwindow: Remove outstanding_moves stuff
Since we now never move regions directly on the window we can
remove all the stuff that track outstanding moves and flushes then.
2013-05-02 16:09:08 +02:00
Alexander Larsson 479b69a8bf gdk: Don't ever do copies from the window
This basically neuters gdk_window_move_region, gdk_window_scroll
and gdk_window_move_resize, in that they now never copy any bits but
just invalidate the source and destination regions. This is a performance
loss, but the hope is that the simplifications it later allows will let
us recover this performance loss (which mainly affects scrolling).
2013-05-02 16:09:08 +02:00
Benjamin Otte 7cecc8e524 a11y: Remove AtkSelection implementation from combobox
AtkSelection requires that the immediate children of the object are the
selectable items. The combobox however is implemented with just 1 child:
The popup menu.

The popup menu is implementing the selectable interface.

Test are updated to reflect this change.
2013-05-02 15:31:26 +02:00
Matthias Clasen c6894cd606 Try this again
When the hostnamed call is cancelled, we get a G_IO_ERROR_CANCELLED
error back. Handle it properly.
2013-05-02 09:29:35 -04:00
Matthias Clasen f7f63ae3ee Revert "Remove a superfluous ref"
This reverts commit f326c0eac8.

Grr, turns out that cancelling is not that reliable :-(
2013-05-02 08:23:58 -04:00
Matthias Clasen 117c86d08a Clear list of attached windows when disposing a widget
We were silently relying on everybody to detach their windows,
and would leak memory otherwise.
2013-05-02 08:02:40 -04:00
Matthias Clasen fb08a26acd GtkWindow: use a weak ref to keep track of attach_widget
Taking a full reference of the attach widget creates a reference
cycle, and keeps the attach_widget alive longer than it should.
2013-05-02 08:01:14 -04:00
Matthias Clasen f326c0eac8 Remove a superfluous ref
If we cancel the call in dispose, no need to ref the object
we pass as userdata. Avoids the risk of leaking the ref if
the call is actually canceled.
2013-05-02 05:53:40 -04:00
Matthias Clasen 4dc01aca43 Fix build 2013-05-02 05:37:58 -04:00
Matthias Clasen 6c79fb72bd Revert "Temporarily remove window-border reftest"
This reverts commit cf6695088e.
2013-05-01 22:23:11 -04:00
Matthias Clasen e399798da8 Revert "Disable the filechooser template tests"
This reverts commit 17b9733372.
2013-05-01 22:22:22 -04:00
Matthias Clasen 8eeb379f7c Revert "Disable the object-finalize test for now"
This reverts commit a021dc793c.
2013-05-01 22:22:09 -04:00
Matthias Clasen 67595f3614 Reenable display manager tests
Still broken, but they test the right thing.
2013-05-01 22:20:58 -04:00
Matthias Clasen 43b42704c5 Bump version 2013-05-01 22:06:46 -04:00
Matthias Clasen 3c7fbe237d Remove window-border tests from makefile too 2013-05-01 21:43:19 -04:00
Matthias Clasen 0d49b97fce Silence a compiler warning 2013-05-01 21:35:39 -04:00
Matthias Clasen 286d3466a1 Revert "Temporarily remove button-wrapping reftest"
This reverts commit 851b631c4e.
2013-05-01 21:31:12 -04:00
Matthias Clasen 78189bf5e0 Fix up doc sections 2013-05-01 21:27:25 -04:00
Matthias Clasen 210451e86f Minor doc comment fix 2013-05-01 21:27:06 -04:00
Matthias Clasen 3f397d6b38 Make gtkplacessidebar.h look like a gtk header 2013-05-01 21:23:55 -04:00
Matthias Clasen 2f0a5dd541 GtkPlacesSidebar: Correct all since tags 2013-05-01 21:19:37 -04:00
Matthias Clasen e9e4c8b168 Disable broken picker a11y test
The GtkComboBox accessible implementation is pretty broken,
and it shows through in this a11y test. Disable it for now.
2013-05-01 21:03:55 -04:00
Matthias Clasen b84b933cac Update a few a11y test results 2013-05-01 19:07:10 -04:00
Matthias Clasen 51bbb76d35 Fix image-load-from-file reftest
Need to reset css here to avoid theme interference.
2013-05-01 19:07:10 -04:00
Matthias Clasen 3605e6c900 Temporarily remove grid-span reftest
This was testing grid size allocation changes that had to be
reverted because they broke gnumeric.
2013-05-01 19:07:10 -04:00
Matthias Clasen cf6695088e Temporarily remove window-border reftest
It is broken by unfinished csd changes.
2013-05-01 19:07:10 -04:00
Matthias Clasen 851b631c4e Temporarily remove button-wrapping reftest
Its broken by unsettled GtkBin size allocation changes.
2013-05-01 19:07:10 -04:00
Piotr Drąg 0f9c43b569 Updated POTFILES.skip 2013-05-01 23:48:33 +02:00
Benjamin Otte 327a164744 paned: Fixup recent commit
d90e3670ce had a bunch of embarrassing
bugs.

Fixes paned-undersized reftest.
2013-05-01 23:26:27 +02:00
Benjamin Otte a30b84f522 wayland: Don't add/remove displays manually
This code is handled by GdkDisplay itself these days.
2013-05-01 18:12:38 +02:00
Benjamin Otte 0122a9da8e x11: Move initialization code
Move it from GdkDisplayManagerX11.init to GdkDisplay.class_init.

This shouldn't cause any problems, but who knows, so keep this patch
small.

Reason for this is the unification of display managers.
2013-05-01 18:11:26 +02:00
Benjamin Otte 2d35f7a8e1 tests: make deprecated functions not warn
We still want to test them though.
2013-05-01 17:50:14 +02:00
Benjamin Otte 61f47829ba tests: Comment out unused functions 2013-05-01 17:46:50 +02:00
Benjamin Otte 2d29c4a43f window: last size is more important than default size
reorder size computation code to reflect that.

https://bugzilla.gnome.org/show_bug.cgi?id=696882
2013-05-01 16:41:12 +02:00
Benjamin Otte 01f7ed1d07 window: Deprecate gtk_window_reshow_with_initial_size() 2013-05-01 16:41:12 +02:00
Benjamin Otte d90e3670ce paned: Correctly compute child sizes in size requests 2013-05-01 16:41:12 +02:00
Benjamin Otte 6146bf7a32 gtkprivate: #define OPPOSITE_ORIENTATION
and use it
2013-05-01 16:41:11 +02:00
Benjamin Otte ea98c61f3c paned: Split size request code
The code is pretty different for both cases, so better split things
here.
2013-05-01 16:41:11 +02:00
Benjamin Otte 9c2eb4f233 paned: Split out a function 2013-05-01 16:41:11 +02:00
Benjamin Otte cb99cd2052 button: Rework size request/allocation code
- Split out a common function
- Implement hfw properly.
2013-05-01 16:41:11 +02:00
Benjamin Otte 41e8d3df6d widget: Improve debug output 2013-05-01 16:41:11 +02:00
Benjamin Otte 01fe4ce7f4 button: Use _gtk_widget_get_preferred_size_for_size()
This was accidently lost when merging baseline support.
2013-05-01 16:41:11 +02:00
Benjamin Otte 1349292e47 widget: Adapt _gtk_widget_get_preferred_size_for_size()
... for baseline support byu taking two extra (possible NULL) arguments.
2013-05-01 16:41:11 +02:00
Benjamin Otte 8f06590712 tests: Add reftest for broken button sizing
https://bugzilla.gnome.org/show_bug.cgi?id=698433
2013-05-01 16:41:11 +02:00
Matthias Clasen 17b9733372 Disable the filechooser template tests
The places sidebar breaks the finalization checks in these tests
https://bugzilla.gnome.org/show_bug.cgi?id=699393
2013-05-01 10:28:53 -04:00
Matthias Clasen a021dc793c Disable the object-finalize test for now
GtkPlacesSidebar breaks this:
https://bugzilla.gnome.org/show_bug.cgi?id=699393
2013-05-01 10:28:03 -04:00
Matthias Clasen 032636f3ea Add missing symbols 2013-05-01 10:27:48 -04:00
Matthias Clasen 4f9a71d286 Comment out broken tests
Tsk, tsk. These tests were broken in the recent display manager
changes.  Please run make check after major refactoring.
2013-05-01 09:41:11 -04:00
Matthias Clasen e30d5acc60 Avoid an accidental export 2013-05-01 08:46:50 -04:00
Matthias Clasen b01c69a018 Updates 2013-05-01 08:29:01 -04:00
Hib Eris 4dcd49352b Revert "Don't build gtk-launch when gio-unix is not available"
The gtk-launch tool can be build without gio-unix (although it
will not really do much without an alternative implementation for
g_desktop_app_info).

So there is no need to not build gtk-launch anymore.

This reverts commit 9a1235bf0d.

https://bugzilla.gnome.org/show_bug.cgi?id=682824
2013-05-01 07:39:36 +02:00
Milo Casagrande 11c9c70673 [l10n] Updated Italian translation. 2013-04-30 19:22:41 +02:00
Milo Casagrande c67eb10fcb [l10n] Updated Italian translation. 2013-04-29 23:01:03 +02:00
Matthias Clasen f47e578737 Fix a typo
Modifed should be Modified.
https://bugzilla.gnome.org/show_bug.cgi?id=699225
2013-04-29 13:08:18 -04:00
Alexander Larsson 8cb78d82d6 gtksizerequestcache: Fix typo that lead to crash/leak
We were checking for cache->requests_x but freeing cache->requests_y
which could cause a crash/leak.
2013-04-29 18:17:02 +02:00
David King b8d2806417 docs: Reorder compiler command line for new GCC
Newer versions of GCC/binutils must have the source file come before the
preprocessor and linker flags on the compiler command line, and this is
also compatible with previous versions.

https://bugzilla.gnome.org/show_bug.cgi?id=680241
2013-04-29 07:31:16 +01:00
David King 59c3e7bfe8 docs: Add GtkWidget::show,hide,map,unmap,realize,unrealize
Add gtk-doc comments for several signals on GtkWidget.

https://bugzilla.gnome.org/show_bug.cgi?id=688896
2013-04-29 07:23:46 +01:00
David King 402985077b docs: Add (inout) to requisition of gtk_menu_item_toggle_size_request()
https://bugzilla.gnome.org/show_bug.cgi?id=675571
2013-04-29 07:18:54 +01:00
Matthias Clasen e9f182e37a Fix a few memory leaks wrt to translations
Pointed out in https://bugzilla.gnome.org/show_bug.cgi?id=699016
The fix here is slightly different. We make
_gtk_builder_parser_translate return a const char * instead of
a dup'ed string, and fix up the callers.
2013-04-28 21:43:49 -04:00
Matthias Clasen 13858fde29 GtkGrid: Undo a size allocation tweak
Revert 5e1a06d1b1

This change caused empty rows to 'open up', which was not
intended and causes problems as seen in bug 698660.
2013-04-28 18:46:41 -04:00
Matthias Clasen ef759ef19d Add a testcase for empty grid rows
This adds a testcase described in bug 698660 to testgrid.
2013-04-28 18:46:11 -04:00
Žygimantas Beručka 51a31f9098 Updated Lithuanian translation 2013-04-28 13:24:47 +03:00
Mario Blättermann 0e4b460574 Updated German translation 2013-04-27 22:42:37 +02:00
Matthias Clasen 1f17efb81c Add some tests for GtkWindow
These tests may have some assumptions on reasonable window manager
behaviour.  For now, we just test that the default size of the
window ends up as the allocated size of the content. This test
currently fails with client-side decorations, because we are
not properly discriminating between overall window size and
content size.
2013-04-27 13:41:17 -04:00
Paolo Borelli d35596fe92 GtkImage: do not leak metrics in baseline align
https://bugzilla.gnome.org/show_bug.cgi?id=699020
2013-04-27 13:59:29 +02:00
Rico Tzschichholz b957e16695 gtk: Add COMPOSITE_TEMPLATES to EXTRA_DIST 2013-04-26 09:25:44 +02:00
Owen W. Taylor b72cf9129c wayland: when possible, fill in actual and predicted presentation times
There is currently no Wayland protocol for providing presentation
timestamps or hints about when drawing will be presented onscreen.
However, by assuming the straightforward algorithm used by the
DRM backend to Weston, we can reverse engineer the right values.

https://bugzilla.gnome.org/show_bug.cgi?id=698864
2013-04-25 13:55:03 -04:00
Owen W. Taylor 23031defde wayland: fill in refresh_interval in GdkFrameTimings
Track the outputs that a window is on, and use the refresh rate from
a random one of those outputs for the refresh_interval in
GdkFrameTimings.

https://bugzilla.gnome.org/show_bug.cgi?id=698864
2013-04-25 13:50:01 -04:00
Owen W. Taylor f1ce727b06 GdkWaylandWindow: Consolidate surface creation and destruction code
Combine duplicate code for creating and destroying surfaces.
To make the operation of the destroy() operation more obvious, the
destruction of the (fake) root window at display dispose time is
changed to not be a "foreign" destroy.

https://bugzilla.gnome.org/show_bug.cgi?id=698864
2013-04-25 13:49:47 -04:00
Owen W. Taylor ca120a98e5 GdkWaylandWindow: synchronize frame drawing
Use wl_surface_frame() to get notification when the compositor paints
a frame, and use this to throttle drawing to the compositor's refresh
cycle.

https://bugzilla.gnome.org/show_bug.cgi?id=698864
2013-04-25 13:45:21 -04:00
Owen W. Taylor c71fea568f GdkWindowWayland: make sure we attach the surface when repainting
Lazily creating the cairo surface that backs a window when we
first paint to it means that the call to
gdk_wayland_window_attach_image() in
gdk_wayland_window_process_updates_recurse() wasn't working the
first time a window was painted.

https://bugzilla.gnome.org/show_bug.cgi?id=698864
2013-04-25 13:45:12 -04:00
Owen W. Taylor d5310f9367 GdkWindowWayland: draw, then damage, then commit
When exposing an area, we were individually damaging and committing
each rectangle, *before* drawing. Surprisingly, this almost worked.
Order things right and only commit once.

https://bugzilla.gnome.org/show_bug.cgi?id=698864
2013-04-25 13:45:06 -04:00
Owen W. Taylor a082f4d804 animated-resizing, video-timer: Add missing return value from ::draw
When we connect to GtkWidget::draw, the signal handler should have
a return value. This fixes overdrawing client-side decorations.
2013-04-25 13:44:58 -04:00
Matthias Clasen 8dc090b9b1 GtkStack: improve docs 2013-04-24 22:07:09 -04:00
Matthias Clasen c69d2e4254 Generate new images 2013-04-24 21:56:08 -04:00
Matthias Clasen f3685c5e88 Docs: some widget gallery updates
Add images for Scrollbar, info bar, combo box text, etc.
2013-04-24 21:55:13 -04:00
Matthias Clasen a8a41b52ad GtkStackSwitcher: unset tooltip
It was pointed out to me that we leave the tooltip behind
when setting and unsetting an icon.
2013-04-24 20:10:05 -04:00
Matthias Clasen af49dd33cf GtkNotebook: Consistent boolean handling
Normalize boolean parameters in gtk_notebook_set_tab_reorderable and
gtk_notebook_set_tab_detachable before comparing them. Pointed out in
https://bugzilla.gnome.org/show_bug.cgi?id=697196
2013-04-24 19:58:22 -04:00
Cosimo Cecchi 06c8e8fa43 docs: fix some typos in newly introduced methods 2013-04-24 13:10:54 -04:00
Nik Kalach 95ce57443c [l10n] Update Interlingua translation 2013-04-24 16:03:15 +02:00
Yaron Shahrabani 9544ae08af Updated Hebrew translation. 2013-04-24 10:08:19 +03:00
Yaron Shahrabani 648ef7f7fa Updated Hebrew translation. 2013-04-24 09:45:26 +03:00
Matthias Clasen 661f24736b widget-factory: Add new widgets
Add GtkStack and GtkRevealer to the second page in
gtk3-widget-factory.
2013-04-23 17:39:46 -04:00
Benjamin Otte 174664b235 overlay: Silence gcc warnings 2013-04-23 14:13:51 -04:00
Owen W. Taylor 8c68050af8 tests/scrolling-performance: Add a new test for GtkViewport performance
Add a test that takes four copies of the widget-factory widgets and
scrolls them around to test how smoothly we can scroll and draw.
2013-04-23 14:04:40 -04:00
Owen W. Taylor b7063509f8 tests/animated-resizing: Split frame statistics out into a separate file
Split the code for computing frame rate and latency into a separate file
so we can use it from multiple tests.
2013-04-23 14:04:40 -04:00
Owen W. Taylor 0032b2dc5a GtkSpinButton: don't constantly recreate style contexts for buttons
Cache the style contexts for the up and down panels, instead of recreating
them each time they are drawn or size requested. GtkSpinButtons were
many times slower to draw than other widgets because of the constant
style matching.

https://bugzilla.gnome.org/show_bug.cgi?id=698682
2013-04-23 14:04:39 -04:00
Federico Mena Quintero d9b9ba5da0 Merge branch 'places-sidebar' 2013-04-23 13:58:09 -04:00
Rafael Ferreira 8ca13c4679 Updated Brazilian Portuguese translation 2013-04-23 05:11:52 -03:00
Alexander Larsson 316d450421 Handle non-baseline supporting subclasses overriding baseline supporting classes
If a subclass (say a child of GtkButton) overrides the non-baseline
size request methods we need to call these, rather than the new
get_height_and_baseline_for_width method.

In order to handle this we make the default for this method to be
NULL, and instead check at runtime which method to call. If any
non-baseline vfunc has changed in a class but the baseline one
hasn't, then we can't use the baseline one.
2013-04-23 05:58:48 +02:00
Alexander Larsson c7b4dd5f9d Add baseline functions to docs 2013-04-23 05:58:08 +02:00
Alexander Larsson e8d4bfd04b Add baseline alignment functions to gtk.symbols 2013-04-23 05:58:08 +02:00
Alexander Larsson e253a414b0 GtkLabel: Minor cleanup
Make sure we always compare for a set baseline in the same way.
I.e. baseline != -1, never baseline >= 0.
2013-04-23 05:58:08 +02:00
Alexander Larsson ac8817d34b GtkWidget: Add missing Since docs 2013-04-23 05:58:08 +02:00
Alexander Larsson c630804647 GtkImage: Reuse previously calculated baseline_align in draw()
No need to recalculate this every time we draw.
2013-04-23 05:58:08 +02:00
Alexander Larsson 43f1ac2b8f GtkBox: Add missing Since in docs 2013-04-23 05:58:08 +02:00
Alexander Larsson ebbc7791dd GtkGrid: Add missing Since docs 2013-04-23 05:58:07 +02:00
Alexander Larsson 2b4c9983da Add tests/testbaseline 2013-04-23 05:58:07 +02:00
Alexander Larsson f354cef61b GtkDialog: Baseline align buttons in action area 2013-04-23 05:58:07 +02:00
Alexander Larsson 8fbd6e2edc GtkEventBox: Support baseline alignment
This allows baselines to propagate from the child of the eventbox.
2013-04-23 05:58:07 +02:00
Alexander Larsson e64c1f8929 GtkButtonBox: Support baseline alignment 2013-04-23 05:58:07 +02:00
Alexander Larsson 1df8d18ad2 GtkCheckButton and GtkRadioButton: Implement baseline alignment 2013-04-23 05:58:07 +02:00
Alexander Larsson 433c0c2134 GtkSpinButton: Support baseline alignment 2013-04-23 05:58:07 +02:00
Alexander Larsson 627685e2a2 GtkGrid: Support baseline alignment in GtkGrid
We support a local baseline in each row, as well as selecting
a specific row for the global baseline of the entire GtkGrid.
2013-04-23 05:58:07 +02:00
Alexander Larsson 72cd8b4dab GtkEntry: Support baselines 2013-04-23 05:58:06 +02:00
Alexander Larsson d6684b5748 GtkButton: Add baseline align support 2013-04-23 05:58:06 +02:00
Alexander Larsson 7523b25942 GtkImage: Support baselines
This uses the current font metrics to guess the baseline of the image.
Without this any non-centered baseline in buttons with images look weird.
2013-04-23 05:50:38 +02:00
Alexander Larsson 6acc8c0817 GtkAlignment: Support baselines
We now report any baselines from the child, and allocate it.
Also, in the case of a baselign aligned child we ignore yscale/yalign
as that is not supportable.
2013-04-23 05:50:38 +02:00
Alexander Larsson 9a42942afb GtkBox: Add baseline alignment for horizontal boxes
Report a baseline based height and baseline whenever there
are children with ALIGN_BASELINE.

Assign baseline to childen in size_allocate. Either the one inherited
from the parent if set, or otherwise calculate one based on any
ALIGN_BASELINE children.
2013-04-23 05:50:38 +02:00
Alexander Larsson 1e1cf89e4f GtkLabel: Support baseline
Report the baseline in get_preferred_height_and_baseline_for_width().
2013-04-23 05:50:37 +02:00
Alexander Larsson 5ad618cb95 GtkSizeRequestCache: Don't store baselines in horizontal case
This saves memory for every widget (maximum 48 bytes per widget) at
a cost of a few duplicated codepaths in the size request cache.
2013-04-23 05:50:37 +02:00
Alexander Larsson 77e0f18eda Add GTK_DEBUG=baselines support
This draws red lines to show where the baselines are
2013-04-23 05:50:37 +02:00
Alexander Larsson 852cbb62b8 Initial support for baselines
This modifies the size machinery in order to allow baseline support.

We add a new widget vfunc get_preferred_height_and_baseline_for_width
which queries the normal height_for_width (or non-for-width if width
is -1) and additionally returns optional (-1 means "no baseline")
baselines for the minimal and natural heights.

We also add a new gtk_widget_size_allocate_with_baseline() which
baseline-aware containers can use to allocate children with a specific
baseline, either one inherited from the parent, or one introduced due
to requested baseline alignment in the container
itself. size_allocate_with_baseline() works just like a normal size
allocation, except the baseline gets recorded so that the child can
access it via gtk_widget_get_allocated_baseline() when it aligns
itself.

There are also adjust_baseline_request/allocation similar to the
allocation adjustment, and we extend the size request cache to also
store the baselines.
2013-04-23 05:50:37 +02:00
Alexander Larsson f15bc7818e Add GTK_ALIGN_BASELINE to GtkAlign
Setting this means baseline aware containers should align the widget
according to the baseline. For other containers this behaves like
FILL.

In order to not suprise old code with a new enum value we always
return _FILL for _BASELINE unless you specifically request it via
gtk_widget_get_valign_with_baseline().
2013-04-23 05:47:31 +02:00
John Ralls 655c781b6e Fix automake warning about CFLAGS etc. being user variables 2013-04-22 15:48:35 -07:00
John Ralls f0f07ad6d8 Remove get_atom_name and atom_intern
Completes aa9e974 for quartz
2013-04-22 15:48:35 -07:00
John Ralls 179004f0a7 Fix attempted inclusion of local headers with system brackets. 2013-04-22 15:48:34 -07:00
John Ralls e58b19db04 gdk: Temporarily add -xobjective-c to CFLAGS
To enable compiling the quartz backend after a6a4428
2013-04-22 15:48:34 -07:00
Benjamin Otte 315261260c button: Implement height-for-width
https://bugzilla.gnome.org/show_bug.cgi?id=698433
2013-04-22 18:29:21 -04:00
Benjamin Otte 3450388ff0 sizerequest: Split out a common function 2013-04-22 18:29:01 -04:00
Cosimo Cecchi 009aadf378 window: remove unused code
We don't need to add these style classes.
2013-04-22 18:10:22 -04:00
Cosimo Cecchi 7bbbb01ff5 window: rework the CSD theming layer
Instead of having three different boxes and style classes, we can just
get away with the regular background box, plus a window-frame, which
contains the external frame, together with the window drop shadows.

GtkWindow now has special code to ensure the backing actual window is
allocated big enough to accomodate the shadows (using the shadow size
calculations introduced in the previous commit). We also use the margin
value to determine the size of the invisible borders (which can then be
different than the shadow).
2013-04-22 18:10:22 -04:00
Cosimo Cecchi a44d6816d3 cssshadow: add a method to get the size of a shadows value
The method returns the size of each side of a GtkCssShadowsValue.
2013-04-22 18:10:21 -04:00
Cosimo Cecchi 7846bedebd window: factor out a gtk_window_get_maximized() function
Simplify code that does this same check over and over.
2013-04-22 18:10:21 -04:00
Cosimo Cecchi 87922575d3 window: remove title_border
We don't actually need this additional title border.
2013-04-22 18:10:21 -04:00
Federico Mena Quintero 0c1423d962 Remove GtkPlacesSidebar from our private Glade catalog
Now, Glade already knows about GtkPlacesSidebar AND MY MAD ICONS.
2013-04-22 17:00:08 -04:00
Ryan Lortie ca0a18918c GtkModelMenuItem: add support for 'icon' attribute
Add support for icons on a GMenuModel.

https://bugzilla.gnome.org/show_bug.cgi?id=688820
2013-04-22 15:55:08 -04:00
Federico Mena Quintero 5322420145 Use friendlier property names for Glade 2013-04-22 15:46:59 -04:00
Piotr Drąg 66007d0ab6 Updated POTFILES.in and POTFILES.skip 2013-04-22 20:51:32 +02:00
Matthias Clasen 15bba87e9a Add new symbols
Add the GtkRevealer functions to gtk.symbols
2013-04-22 12:42:39 -04:00
Matthias Clasen 8ff96b3bb2 Do rtl flipping for GtkRevealer transitions 2013-04-22 12:42:39 -04:00
Matthias Clasen 86688c6fde Add a revealer example to gtk-demo
I tried to make a 'revealer ballet'. Judge for yourself if
I succeeded.
2013-04-22 12:42:39 -04:00
Matthias Clasen aec62e1c10 Add docs for GtkRevealer 2013-04-22 12:42:38 -04:00
Matthias Clasen d7f43c30a3 GtkRevealer: Add a fading animation
Using a container for this is not necessarily the most
elegant solution, but it lets us reuse the animation
machinery in GtkRevealer.
2013-04-22 12:42:38 -04:00
Matthias Clasen 0bd173e3d8 Forgotten file 2013-04-22 12:42:37 -04:00
Matthias Clasen 443459b52e Add GtkRevealer
This is a widget that can hide or show (ie reveal) its child
in an animated fashion.

This widget was initially developed in libgd.
2013-04-22 12:42:37 -04:00
Cosimo Cecchi d82257e1c8 stack: fix a typo in docs 2013-04-22 11:20:06 -04:00
Matthias Clasen b88c0d7387 Typo fix in GtkStack docs 2013-04-22 10:25:30 -04:00
Matthias Clasen 6d77bf66ac Typo fix in GtkStackSwitcher docs 2013-04-22 10:25:30 -04:00
Benjamin Otte b8e4adfff9 Revert "Revert "gtkbin: Remove the silliest code on earth""
This reverts commit b164df7450.
2013-04-22 08:23:08 -04:00
Victor Ibragimov 361754b063 Tajik translation updated 2013-04-22 13:17:42 +05:00
Rafael Ferreira b5912e61fd Updated Brazilian translation for UI and PO-Prop. 2013-04-22 05:00:18 -03:00
Tristan Van Berkom e5b384f537 Updated private widget catalog to remove the reference to the shortcuts model
This model seems to be removed since Federico's places-sidebar work.
2013-04-22 15:55:20 +09:00
Tristan Van Berkom b164df7450 Revert "gtkbin: Remove the silliest code on earth"
This reverts commit f4438a1ffc.

The calculation of the delta between parent and child widget
is required in order to automate height-for-width and width-for-height
requests for various GtkBin widgets.

GtkButton, GtkCheckButton, GtkRadioButton, etc, all have different
requests for space around the content which can not be satisfied
with a simple calculation of GtkContainer border-width.
2013-04-22 15:20:51 +09:00
Matthias Clasen 6186429f5f GtkStack: shorten a few parameter names
Looks better in the docs.
2013-04-21 23:13:16 -04:00
Matthias Clasen a8123bf95e Forgot one place
Also change the property definition for transition-duration
to be uint instead of int.
2013-04-21 22:24:54 -04:00
Matthias Clasen af6f874060 Add new places sidebar symbols 2013-04-21 22:00:06 -04:00
Matthias Clasen b0cf4d057d Make transition-duration unsigned
The code doesn't deal with negative durations, so better
don't allow them.
2013-04-21 21:51:28 -04:00
Matthias Clasen 71f1f768cc Change transition-type property type
This is an enum, so declare the property as such.
2013-04-21 21:51:27 -04:00
Matthias Clasen 49511c7f42 Add a GtkStack example to gtk-demo 2013-04-21 21:51:27 -04:00
Matthias Clasen 85ccb93b9f GtkStack: warn if child names are not unique 2013-04-21 21:51:27 -04:00
Matthias Clasen 24bac24602 Add new symbols 2013-04-21 21:51:26 -04:00
Matthias Clasen f83ba08f7f Add new api to the docs 2013-04-21 21:51:26 -04:00
Matthias Clasen c37b30f317 GtkStack: add vertical slide transitions
We allow transitions that slide up or down.
2013-04-21 21:51:26 -04:00
Matthias Clasen 88cd26575d GtkStack: rtl flipping for animation
We switch slide-right and slight-left when in rtl.
2013-04-21 21:51:25 -04:00
Matthias Clasen e72a78c4e6 Add a way to specify transition types on the fly
Add a gtk_stack_set_visible_child_full that takes a
transition type.
2013-04-21 21:51:25 -04:00
Matthias Clasen 8ca73e3258 Add docs for GtkStackSwitcher 2013-04-21 21:51:25 -04:00
Matthias Clasen 06f5b1e572 Add docs for GtkStack 2013-04-21 21:51:24 -04:00
Matthias Clasen 2e39c4bab8 Add GtkStack
Add separate GtkStack and GtkStackSwitcher widgets that are an
alternative to GtkNotebook. Additionally, GtkStack supports
animated transitions when changing pages.
These widgets were initially developed in libgd.
2013-04-21 21:51:24 -04:00
Federico Mena Quintero 57c4bcb369 Merge branch 'master' into places-sidebar 2013-04-21 18:21:37 -04:00
Federico Mena Quintero 9b91e06513 Oops, only show 'Connect to server' if the caller enabled it 2013-04-21 18:20:46 -04:00
Cosimo Cecchi 44ba055d03 window: don't forget to fetch title border when not on CSD
We still need to respect this border value even when we're not running
under CSD, since we support setting a custom titlebar in all cases.

The border/style magic in gtk_window_draw() really needs to be separated
out into logical pieces soon, but for now let's keep a consistent
behavior with the previous code.
2013-04-21 16:59:14 -04:00
Federico Mena Quintero 32abb29b32 Merge branch 'places-sidebar' 2013-04-21 15:51:49 -04:00
Cosimo Cecchi a25e0a97d5 window: only account for decoration borders when we're client decorated 2013-04-21 14:44:24 -04:00
Federico Mena Quintero 9d8e3be6d7 Add a selected_volume argument to ::populate-popup
Nautilus needs this in order to implement a Format command for a volume's popup menu.

Signed-off-by: Federico Mena Quintero <federico@gnome.org>
2013-04-21 12:41:33 -04:00
Federico Mena Quintero 9ded1c0c99 Sync from nautilus commit 500770e8de18b07392ffa4435372525d5d03c688
Add a Connect to Server menu item, a show-connect-to-server property, and a show-connect-to-server signal.
2013-04-20 19:14:59 -04:00
156 changed files with 14106 additions and 9326 deletions
+198
View File
@@ -1,3 +1,201 @@
Overview of Changes in GTK+ 3.7 to 3.9
======================================
* GtkFileChooser:
- Always show fuse-mounted locations in shortcuts
- GtkFileChooserButton has received a lot of fixes and tests have
been added for many of them
* GtkWindow:
- Initial support for client-side decorations has been added. This
is going to be used by default under Wayland. To try it with other
backends, set the GTK_CSD=1 environment variable.
- gtk_window_set_titlebar: A new function that can set a custom,
client-side titlebar on toplevel windows.
* Wayland:
- Use client-side decorations
- Implement maximization
- Improve cursor handling
- Improve multi-monitor handling
- Support most GtkSettings (for now by reading GSettings directly)
- Complete the keymap implementation
- Add support for custom surfaces
- Implement animated cursors
- Support the WAYLAND_SOCKET environment variable
- Implement frame synchronizatio
- Document Wayland-specific APIs
* Broadway:
- Improve window size handling
- Implement frame synchronization
- Add support for password authentication
* New APIs, widgets, feature additions:
- GtkHeaderBar is a new widget similar to a GtkBox, with the extra
feature that it can center a child (typically a title), independent
of the other content.
- GtkPlacesSidebar is the sidebar widget in the file chooser, exported
as a public widget - it will be shared with nautilus.
- GtkStack is an alternative to GtkNotebook for showing one of several
child widgets at a time. It supports animated transitions. Tabs are
not built into this widgets, but instead provided by the separate
GtkStackSwitcher widget.
- GtkRevealer is a new new widget that can hide or show its child
in an animated fashion.
- GtkMenuTracker is a helper object that makes dealing with
GMenuModels easier and more efficient.
- gtk_grid_remove_row/column: New functions to remove whole rows
or columns from a GtkGrid
- Support for composite children has been added to GtkWidget. This
allows to create complex widgets from GtkBuilder ui files. All
complex GTK+ widgets have been converted to use this facility.
- Baseline support was added to the GTK+ size allocation machinery.
Widgets can now export the baseline of the text they contain,
and containers can align their children wrt to their baselines.
* Known problems, feature removals, compatibility caveats:
- Handling of window size is currently in flux, and there are
some known problems with sizes unintentionally changing
- Support for the Motif DND protocol has been dropped
- Client-side decorations still have some issues when drawing
directly on toplevel windows or setting their background
- Support for multiple screens per display has been removed. This
was only ever supported on X11, and is an exceedingly rare setup
nowadays. The display-screen relation is now 1:1, and we will do
some more simplification of displaymanager/display/screen/monitor
APIs.
- gdk_window_get_display has been deprecated
- gtk_widget_push_composite_child has been deprecated - this was
used for anything
- GtkSwitch has been changed to draw focus internally, instead of
reserving space outside the switch for it. This may require some
application adjustment where margins were tweaked to 'correct'
the alignment of switches manually
* Printing:
- Avoid blocking when looking for avahi printers
- Don't link against avahi-gobject, use D-Bus directly
* Bugs fixed:
504901 GtkCellRendererCombo requires click-and-hold
586367 In local_only mode, file chooser should return native pa...
671939 [regression] crash on exit
672018 Need API to set global application state (busy, counters...
674051 Scrolling zoom in view - incorrect image display
674759 GtkLabel: wrong value of "mnemonic-keyval" when "use-mar...
675571 (out) or (inout) annotation possibly missing for gtk_men...
675649 gtk-demo: Fix typo
680241 Instructions on how to build a GTK app won't work with r...
681446 gtkdnd memory leak
685419 gtkprintbackendfile: Infinite loop in _cairo_write()
685420 Critical warnings when GtkPrintJob is released too early
688820 GIcon is a bad interface
688896 Add documentation for GtkWidget::show,hide,map,unmap,rea...
690275 scrolling on other windows is applied when coming back (...
691040 selection is reported incorrectly in file chooser button
692871 Need to expose output information to make GdkScreen API ...
694339 Fix build of GTK+ on Windows
694465 Allow backends to fail during initialisation
695200 Switching apps while a combobox open makes the parent wi...
695228 GdkPixbuf:ERROR:gdk-pixbuf-animation.c:242:gdk_pixbuf_an...
695278 Avoid passing a NULL title to setTitle
695304 GtkTextView: don't popdown a bubble if we don't have one
695312 Initial 'text' set in the non-numeric-only GtkSpinButton...
695375 GtkEntryAccessible: also handle entry icon tooltip NULL ...
695380 gtk_binding_entry_skip broken
695391 wayland documentation section id is "gtk-osx"
695473 treeview: fix a critical warning
695476 Drop the Motif DND protocol
695482 Universal Access panel appears jumbled and horrible afte...
695493 testgtk: issues with the color selection example
695495 testgtk: cursor example segfaults
695497 testgtk: lack of key repeat
695506 gtk-demo: link hovering unreliable
695682 Cannot build docs for wayland-only build
695714 Getting of printer info can hang
695772 Different appearance of menus within Audacious
695783 GtkApplication: Allow passing windows on non-X11 targets
695861 Allow to use custom surfaces for GdkWindows in Wayland
695874 GtkFontChooser docs
695895 Fix the gtk3-demo demo program on Windows
695945 implement minimize / maximize functionality
695948 GtkFontButton sets wrong show-preview-entry
695998 csd: enable shadows in the outer border
696051 vertical grid lines in rtl mode
696138 GtkWidget: some deprecation marks are missing
696171 GtkAssistant highlighted font unreadable
696202 Add GtkSpinner animation back to Win32 theme
696232 win32: do not crash on invalid utf8 conversion
696340 wayland: device list is populated async
696370 GtkOverlay doesn't work on top of GtkClutterEmbed
696429 wayland: Implement animated cursors
696457 gnome-ostree build broken by 3a9de35a6cefddc09aaf000e523...
696468 improve GMenuModel -> GtkMenu conversion
696546 gtk_print_backend_cups_finalize() crashes if cups_get_pr...
696553 Crash in avahi_create_browsers
696561 GtkApplicationWindow rendering broken
696608 css_image_value_parse: returning FALSE in pointer function
696622 gtk option printer widget segfault in epiphany
696623 GtkOverlay with a revealer produces warnings setting a m...
696767 a pair of memory leaks
696882 [regression] GtkWindow changes size after hide/show cycle
697048 GtkTextView: small code improvements
697144 Popup menu mnemonics fixes
697196 gtk_notebook_set_tab_reorderable boolean handling
697200 GtkWindow: notify::attached-to not emitted
697263 Impossible to set window transparency on 3.8
697275 gtk_window_set_default_size() doesn't work anymore
697427 Unreferencing GtkStatusIcon object causes abort
697673 Apps should connect only once when using Wayland
697795 xi2: Improve pointer emulation debug reporting
697886 dnd icon drawing broken on master
697947 A lot of GTK+ apps fail to launch with error "desktop_she...
698181 Document icon-shadow CSS property
698433 Geometry management broken in GtkBin widgets
698682 GtkSpinButton: don't constantly recreate style contexts f...
698864 wayland: improve integration with GdkFrameClock
699020 GtkImage: do not leak metrics in baseline align
699225 typo: Modifed -> Modified
* Translation updates:
Arabic
Aragonese
Assamese
Belarusian
Brazilian Portuguese
British English
Catalan
Catalan (Valencian)
Czech
Danish
Finnish
French
Galician
German
Greek
Hindi
Hungarian
Indonesian
Italian
Kazakh
Korean
Latvian
Malayalam
Odia
Persian
Polish
Punjabi
Russian
Serbian
Simplified Chinese
Slovenian
Tajik
Tamil
Ukrainian
Overview of Changes in GTK+ 3.7.12
==================================
+1 -2
View File
@@ -10,7 +10,7 @@
m4_define([gtk_major_version], [3])
m4_define([gtk_minor_version], [9])
m4_define([gtk_micro_version], [0])
m4_define([gtk_micro_version], [1])
m4_define([gtk_interface_age], [0])
m4_define([gtk_binary_age],
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
@@ -1242,7 +1242,6 @@ if test "$have_gio_unix" = "yes"; then
else
GDK_GIO_PACKAGE=gio-2.0
fi
AM_CONDITIONAL(HAVE_GIO_UNIX, test "$have_gio_unix" = "yes")
# Check for Pango flags
+3 -1
View File
@@ -39,6 +39,7 @@ demos = \
pickers.c \
pixbufs.c \
printing.c \
revealer.c \
rotated_text.c \
search_entry.c \
sizegroup.c \
@@ -86,7 +87,7 @@ gsettings_SCHEMAS = \
@GSETTINGS_RULES@
demos.h: @REBUILD@ $(demos) geninclude.pl
$(AM_V_GEN) (here=`pwd` ; cd $(srcdir) && $(PERL) $$here/geninclude.pl $(demos)) > demos.h
$(AM_V_GEN) (here=`pwd` ; cd $(srcdir) && $(PERL) $$here/geninclude.pl $(demos)) > demos.h
gtk3_demo_SOURCES = \
$(demos) \
@@ -112,6 +113,7 @@ RESOURCES= $(demos) \
demo.ui \
menus.ui \
stack.ui \
revealer.ui \
theming.ui \
alphatest.png \
apple-red.png \
+4
View File
@@ -58,6 +58,9 @@
<gresource prefix="/stack">
<file>stack.ui</file>
</gresource>
<gresource prefix="/revealer">
<file>revealer.ui</file>
</gresource>
<gresource prefix="/images">
<file>alphatest.png</file>
<file>floppybuddy.gif</file>
@@ -110,6 +113,7 @@
<file>pickers.c</file>
<file>pixbufs.c</file>
<file>printing.c</file>
<file>revealer.c</file>
<file>rotated_text.c</file>
<file>search_entry.c</file>
<file>sizegroup.c</file>
+85
View File
@@ -0,0 +1,85 @@
/* Revealer
*
* GtkRevealer is a container that animates showing and hiding
* of its sole child with nice transitions.
*/
#include <gtk/gtk.h>
static GtkBuilder *builder;
static gint count = 0;
static void
change_direction (GtkRevealer *revealer)
{
gboolean revealed;
revealed = gtk_revealer_get_child_revealed (revealer);
gtk_revealer_set_reveal_child (revealer, !revealed);
}
static gboolean
reveal_one (gpointer data)
{
gchar *name;
GtkRevealer *revealer;
name = g_strdup_printf ("revealer%d", count);
revealer = (GtkRevealer *)gtk_builder_get_object (builder, name);
gtk_revealer_set_reveal_child (revealer, TRUE);
g_signal_connect (revealer, "notify::child-revealed",
G_CALLBACK (change_direction), NULL);
count++;
return count < 9;
}
static void
response_cb (GtkWidget *dialog,
gint response_id,
gpointer data)
{
gtk_widget_destroy (dialog);
}
GtkWidget *
do_revealer (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GError *err = NULL;
if (!window)
{
builder = gtk_builder_new ();
gtk_builder_add_from_resource (builder, "/revealer/revealer.ui", &err);
if (err)
{
g_error ("ERROR: %s\n", err->message);
return NULL;
}
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "dialog1"));
gtk_window_set_screen (GTK_WINDOW (window),
gtk_widget_get_screen (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
g_signal_connect (window, "response", G_CALLBACK (response_cb), NULL);
}
if (!gtk_widget_get_visible (window))
{
count = 0;
g_timeout_add (690, reveal_one, NULL);
gtk_widget_show_all (window);
}
else
{
gtk_widget_destroy (window);
window = NULL;
}
return window;
}
+223
View File
@@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.6 -->
<object class="GtkDialog" id="dialog1">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="type_hint">dialog</property>
<property name="default_width">300</property>
<property name="default_height">300</property>
<property name="title">Revealer</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkRevealer" id="revealer0">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkImage" id="image0">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="revealer1">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">slide-up</property>
<child>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="revealer2">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">slide-right</property>
<child>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">3</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="revealer3">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">slide-down</property>
<child>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="revealer4">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">slide-left</property>
<child>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="revealer5">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">slide-up</property>
<child>
<object class="GtkImage" id="image5">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="revealer6">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">slide-right</property>
<child>
<object class="GtkImage" id="image6">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">4</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="revealer7">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">slide-down</property>
<child>
<object class="GtkImage" id="image7">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">4</property>
</packing>
</child>
<child>
<object class="GtkRevealer" id="revealer8">
<property name="visible">True</property>
<property name="transition-duration">2000</property>
<property name="transition-type">slide-left</property>
<child>
<object class="GtkImage" id="image8">
<property name="visible">True</property>
<property name="icon-name">face-cool-symbolic</property>
<property name="icon-size">6</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">button1</action-widget>
</action-widgets>
</object>
</interface>
+38
View File
@@ -78,6 +78,35 @@ on_page_toggled (GtkToggleButton *button,
gtk_notebook_set_current_page (pages, page);
}
static void
spin_value_changed (GtkAdjustment *adjustment, GtkWidget *label)
{
GtkWidget *w;
gint v;
gchar *text;
v = (int)gtk_adjustment_get_value (adjustment);
if ((v % 3) == 0)
{
text = g_strdup_printf ("%d is a multiple of 3", v);
gtk_label_set_label (GTK_LABEL (label), text);
g_free (text);
}
w = gtk_widget_get_ancestor (label, GTK_TYPE_REVEALER);
gtk_revealer_set_reveal_child (GTK_REVEALER (w), (v % 3) == 0);
}
static void
dismiss (GtkWidget *button)
{
GtkWidget *w;
w = gtk_widget_get_ancestor (button, GTK_TYPE_REVEALER);
gtk_revealer_set_reveal_child (GTK_REVEALER (w), FALSE);
}
int
main (int argc, char *argv[])
{
@@ -86,6 +115,7 @@ main (int argc, char *argv[])
GtkWidget *widget;
GtkWidget *notebook;
gboolean dark = FALSE;
GtkAdjustment *adj;
gtk_init (&argc, &argv);
@@ -114,6 +144,14 @@ main (int argc, char *argv[])
widget = (GtkWidget*) gtk_builder_get_object (builder, "aboutmenuitem");
g_signal_connect (widget, "activate", G_CALLBACK (show_about), window);
widget = (GtkWidget*) gtk_builder_get_object (builder, "page2dismiss");
g_signal_connect (widget, "clicked", G_CALLBACK (dismiss), NULL);
widget = (GtkWidget*) gtk_builder_get_object (builder, "page2note");
adj = (GtkAdjustment *) gtk_builder_get_object (builder, "adjustment2");
g_signal_connect (adj, "value-changed",
G_CALLBACK (spin_value_changed), widget);
g_object_unref (G_OBJECT (builder));
gtk_widget_show (window);
+160 -15
View File
@@ -54,6 +54,23 @@ Vestibulum in tortor diam, quis aliquet quam. Praesent ut justo neque, tempus ru
Duis eu lectus quam. Vivamus eget metus a mauris molestie venenatis pulvinar eleifend nisi.
Nulla facilisi. Pellentesque at dolor sit amet purus dapibus pulvinar molestie quis neque.
Suspendisse feugiat quam quis dolor accumsan cursus. </property>
</object>
<object class="GtkTextBuffer" id="textbuffer2">
<property name="text">* Translation updates:
Aragonese
Assamese
Basque
Brazilian Portuguese
Dutch
German
Hebrew
Hungarian
Polish
Portuguese
Serbian
Slovenian
Spanish
Uyghur</property>
</object>
<object class="GtkAccelGroup" id="accelgroup1"/>
<object class="GtkWindow" id="window">
@@ -2146,30 +2163,158 @@ Suspendisse feugiat quam quis dolor accumsan cursus. </property>
</object>
</child>
<child>
<object class="GtkBox" id="page2">
<object class="GtkOverlay" id="page2">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<property name="border-width">6</property>
<child>
<object class="GtkBox" id="page2box1">
<child type="overlay">
<object class="GtkRevealer" id="page2revealer">
<property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">4</property>
<property name="halign">center</property>
<property name="valign">start</property>
<child>
<object class="GtkSpinButton" id="verticalspin1">
<object class="GtkFrame" id="page2frame">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="adjustment">adjustment2</property>
<property name="margin-top">2</property>
<child>
<object class="GtkBox" id="page2box">
<property name="visible">True</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-left">10</property>
<property name="margin-right">10</property>
<property name="spacing">20</property>
<child>
<object class="GtkLabel" id="page2note">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="halign">start</property>
<property name="label">NEWS!</property>
</object>
</child>
<child>
<object class="GtkButton" id="page2dismiss">
<property name="visible">True</property>
<child>
<object class="GtkImage" id="page2dismissi">
<property name="visible">True</property>
<property name="icon-name">window-close-symbolic</property>
<property name="icon-size">0</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkGrid" id="page2grid">
<property name="visible">True</property>
<property name="column-homogeneous">True</property>
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<property name="border-width">6</property>
<child>
<object class="GtkSpinButton" id="verticalspin2">
<object class="GtkBox" id="page2box1">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="orientation">vertical</property>
<property name="adjustment">adjustment1</property>
<property name="orientation">horizontal</property>
<property name="spacing">4</property>
<child>
<object class="GtkSpinButton" id="verticalspin1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="adjustment">adjustment2</property>
</object>
</child>
<child>
<object class="GtkSpinButton" id="verticalspin2">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="orientation">vertical</property>
<property name="adjustment">adjustment1</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="filler1">
<property name="visible">True</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="filler2">
<property name="visible">True</property>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkStackSwitcher" id="switcher">
<property name="visible">True</property>
<property name="stack">stack</property>
<property name="halign">center</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame">
<property name="visible">True</property>
<property name="hexpand">False</property>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="transition-type">crossfade</property>
<property name="transition-duration">1000</property>
<child>
<object class="GtkScrolledWindow" id="swo">
<property name="visible">True</property>
<property name="shadow-type">none</property>
<child>
<object class="GtkTextView" id="tvo">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="buffer">textbuffer2</property>
</object>
</child>
</object>
<packing>
<property name="name">page1</property>
<property name="icon-name">document-open-recent-symbolic</property>
<property name="title">News</property>
</packing>
</child>
<child>
<object class="GtkImage" id="imageo">
<property name="visible">True</property>
<property name="resource">/logos/gtk-logo-256.png</property>
</object>
<packing>
<property name="name">page2</property>
<property name="icon-name">system-shutdown-symbolic</property>
<property name="title">Logo</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
</object>
</child>
+5 -2
View File
@@ -301,7 +301,7 @@ HTML_IMAGES = \
$(srcdir)/images/appchooserdialog.png \
$(srcdir)/images/assistant.png \
$(srcdir)/images/box-packing.png \
$(srcdir)/images/box-expand.png \
$(srcdir)/images/box-expand.png \
$(srcdir)/images/button.png \
$(srcdir)/images/check-button.png \
$(srcdir)/images/color-button.png \
@@ -309,8 +309,8 @@ HTML_IMAGES = \
$(srcdir)/images/colorchooser.png \
$(srcdir)/images/combo-box.png \
$(srcdir)/images/combo-box-entry.png \
$(srcdir)/images/combo-box-text.png \
$(srcdir)/images/entry.png \
$(srcdir)/images/search-entry.png \
$(srcdir)/images/figure-hierarchical-drawing.png \
$(srcdir)/images/figure-windowed-label.png \
$(srcdir)/images/file-button.png \
@@ -321,6 +321,7 @@ HTML_IMAGES = \
$(srcdir)/images/frame.png \
$(srcdir)/images/icon-view.png \
$(srcdir)/images/image.png \
$(srcdir)/images/info-bar.png \
$(srcdir)/images/label.png \
$(srcdir)/images/levelbar.png \
$(srcdir)/images/link-button.png \
@@ -342,7 +343,9 @@ HTML_IMAGES = \
$(srcdir)/images/radio-group.png \
$(srcdir)/images/recentchooserdialog.png \
$(srcdir)/images/scales.png \
$(srcdir)/images/scrollbar.png \
$(srcdir)/images/scrolledwindow.png \
$(srcdir)/images/search-entry.png \
$(srcdir)/images/separator.png \
$(srcdir)/images/spinbutton.png \
$(srcdir)/images/spinner.png \
+3 -3
View File
@@ -42,7 +42,7 @@ feature of the shell. If you enclose a command in backticks
substituted into the command line before execution. So to compile
a GTK+ Hello, World, you would type the following:
<programlisting>
$ cc `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
$ cc `pkg-config --cflags gtk+-3.0` hello.c -o hello `pkg-config --libs gtk+-3.0`
</programlisting>
</para>
@@ -67,7 +67,7 @@ this range will trigger compiler warnings.
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_REQUIRED=GDK_VERSION_3_2 `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
$ cc `pkg-config --cflags gtk+-3.0` -DGDK_VERSION_MIN_REQIRED=GDK_VERSION_3_2 hello.c -o hello `pkg-config --libs gtk+-3.0`
</programlisting>
</para>
@@ -75,7 +75,7 @@ $ cc -DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_3_2 `pkg-config --cflags --libs gtk+
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
$ cc `pkg-config --cflags gtk+-3.0` -DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_3_4 hello.c -o hello `pkg-config --libs gtk+-3.0`
</programlisting>
</para>
+1
View File
@@ -237,6 +237,7 @@
<xi:include href="xml/gtkstack.xml" />
<xi:include href="xml/gtkstackswitcher.xml" />
<xi:include href="xml/gtkexpander.xml" />
<xi:include href="xml/gtkrevealer.xml" />
<xi:include href="xml/gtkoverlay.xml" />
<xi:include href="xml/gtkheaderbar.xml" />
<xi:include href="xml/gtkorientable.xml" />
+31 -2
View File
@@ -486,6 +486,8 @@ gtk_box_set_spacing
gtk_box_reorder_child
gtk_box_query_child_packing
gtk_box_set_child_packing
gtk_box_get_baseline_position
gtk_box_set_baseline_position
<SUBSECTION Standard>
GTK_BOX
GTK_IS_BOX
@@ -2485,7 +2487,7 @@ gtk_paned_get_type
<SECTION>
<FILE>gtkplacessidebar</FILE>
<TITLE>GtkPlacesSidebar</FILE>
<TITLE>GtkPlacesSidebar</TITLE>
GtkPlacesSidebar
GtkPlacesOpenFlags
gtk_places_sidebar_new
@@ -2493,11 +2495,14 @@ gtk_places_sidebar_set_open_flags
gtk_places_sidebar_set_location
gtk_places_sidebar_get_location
gtk_places_sidebar_set_show_desktop
gtk_places_sidebar_set_accept_uri_drops
gtk_places_sidebar_add_shortcut
gtk_places_sidebar_remove_shortcut
gtk_places_sidebar_list_shortcuts
gtk_places_sidebar_get_nth_bookmark
gtk_places_sidebar_get_open_flags
gtk_places_sidebar_get_show_connect_to_server
gtk_places_sidebar_get_show_desktop
gtk_places_sidebar_set_show_connect_to_server
<SUBSECTION Standard>
GTK_PLACES_SIDEBAR
GTK_IS_PLACES_SIDEBAR
@@ -5188,6 +5193,7 @@ gtk_widget_remove_tick_callback
gtk_widget_size_request
gtk_widget_get_child_requisition
gtk_widget_size_allocate
gtk_widget_size_allocate_with_baseline
gtk_widget_add_accelerator
gtk_widget_remove_accelerator
gtk_widget_set_accel_path
@@ -5320,6 +5326,7 @@ gtk_widget_get_allocated_width
gtk_widget_get_allocated_height
gtk_widget_get_allocation
gtk_widget_set_allocation
gtk_widget_get_allocated_baseline
gtk_widget_get_app_paintable
gtk_widget_get_can_default
gtk_widget_set_can_default
@@ -5380,8 +5387,10 @@ gtk_widget_get_preferred_height
gtk_widget_get_preferred_width
gtk_widget_get_preferred_height_for_width
gtk_widget_get_preferred_width_for_height
gtk_widget_get_preferred_height_and_baseline_for_width
gtk_widget_get_request_mode
gtk_widget_get_preferred_size
gtk_widget_get_preferred_size_and_baseline
gtk_distribute_natural_allocation
<SUBSECTION Alignment and Margins>
@@ -5389,6 +5398,7 @@ GtkAlign
gtk_widget_get_halign
gtk_widget_set_halign
gtk_widget_get_valign
gtk_widget_get_valign_with_baseline
gtk_widget_set_valign
gtk_widget_get_margin_left
gtk_widget_set_margin_left
@@ -7290,6 +7300,10 @@ gtk_grid_set_column_homogeneous
gtk_grid_get_column_homogeneous
gtk_grid_set_column_spacing
gtk_grid_get_column_spacing
gtk_grid_get_baseline_row
gtk_grid_set_baseline_row
gtk_grid_get_row_baseline_position
gtk_grid_set_row_baseline_position
<SUBSECTION Standard>
GtkGridClass
@@ -7594,3 +7608,18 @@ gtk_stack_switcher_new
gtk_stack_switcher_set_stack
gtk_stack_switcher_get_stack
</SECTION>
<SECTION>
<FILE>gtkrevealer</FILE>
<TITLE>GtkRevealer</TITLE>
GtkRevealer
gtk_revealer_new
gtk_revealer_get_reveal_child
gtk_revealer_set_reveal_child
gtk_revealer_get_child_revealed
gtk_revealer_get_transition_duration
gtk_revealer_set_transition_duration
GtkRevealerTransitionType
gtk_revealer_get_transition_type
gtk_revealer_set_transition_type
</SECTION>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

+12
View File
@@ -18,6 +18,9 @@
<link linkend="GtkComboBox">
<inlinegraphic fileref="combo-box.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkComboBoxText">
<inlinegraphic fileref="combo-box-text.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkEntry">
<inlinegraphic fileref="entry.png" format="PNG"></inlinegraphic>
</link>
@@ -147,4 +150,13 @@
<link linkend="GtkFontChooserDialog">
<inlinegraphic fileref="fontchooser.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkAboutDialog">
<inlinegraphic fileref="aboutdialog.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkInfoBar">
<inlinegraphic fileref="info-bar.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkScrollbar">
<inlinegraphic fileref="scrollbar.png" format="PNG"></inlinegraphic>
</link>
</para>
+76 -16
View File
@@ -400,11 +400,6 @@ create_combo_box_entry (void)
GtkWidget *align;
GtkWidget *child;
GtkTreeModel *model;
gtk_rc_parse_string ("style \"combo-box-entry-style\" {\n"
" GtkComboBox::appears-as-list = 1\n"
"}\n"
"widget_class \"GtkComboBoxEntry\" style \"combo-box-entry-style\"\n" );
model = (GtkTreeModel *)gtk_list_store_new (1, G_TYPE_STRING);
widget = g_object_new (GTK_TYPE_COMBO_BOX,
@@ -427,14 +422,22 @@ create_combo_box (void)
{
GtkWidget *widget;
GtkWidget *align;
gtk_rc_parse_string ("style \"combo-box-style\" {\n"
" GtkComboBox::appears-as-list = 0\n"
"}\n"
"widget_class \"GtkComboBox\" style \"combo-box-style\"\n" );
GtkCellRenderer *cell;
GtkListStore *store;
widget = gtk_combo_box_new ();
gtk_cell_layout_clear (GTK_CELL_LAYOUT (widget));
cell = gtk_cell_renderer_pixbuf_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell, "icon-name", 0, NULL);
cell = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell, "text", 1, NULL);
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
gtk_list_store_insert_with_values (store, NULL, -1, 0, "edit-delete", 1, "Combo Box", -1);
gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
widget = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Combo Box");
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_add (GTK_CONTAINER (align), widget);
@@ -442,6 +445,38 @@ create_combo_box (void)
return new_widget_info ("combo-box", align, SMALL);
}
static WidgetInfo *
create_combo_box_text (void)
{
GtkWidget *widget;
GtkWidget *align;
widget = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Combo Box Text");
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_add (GTK_CONTAINER (align), widget);
return new_widget_info ("combo-box-text", align, SMALL);
}
static WidgetInfo *
create_info_bar (void)
{
GtkWidget *widget;
GtkWidget *align;
widget = gtk_info_bar_new_with_buttons ("Close", 0, NULL);
gtk_info_bar_set_message_type (GTK_INFO_BAR (widget), GTK_MESSAGE_INFO);
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (widget))),
gtk_label_new ("Info Bar"));
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_add (GTK_CONTAINER (align), widget);
return new_widget_info ("info-bar", align, SMALL);
}
static WidgetInfo *
create_recent_chooser_dialog (void)
{
@@ -679,12 +714,12 @@ create_panes (void)
pane = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
gtk_paned_pack1 (GTK_PANED (pane),
g_object_new (GTK_TYPE_FRAME,
"shadow", GTK_SHADOW_IN,
"shadow-type", GTK_SHADOW_IN,
NULL),
FALSE, FALSE);
gtk_paned_pack2 (GTK_PANED (pane),
g_object_new (GTK_TYPE_FRAME,
"shadow", GTK_SHADOW_IN,
"shadow-type", GTK_SHADOW_IN,
NULL),
FALSE, FALSE);
gtk_box_pack_start (GTK_BOX (hbox),
@@ -693,12 +728,12 @@ create_panes (void)
pane = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
gtk_paned_pack1 (GTK_PANED (pane),
g_object_new (GTK_TYPE_FRAME,
"shadow", GTK_SHADOW_IN,
"shadow-type", GTK_SHADOW_IN,
NULL),
FALSE, FALSE);
gtk_paned_pack2 (GTK_PANED (pane),
g_object_new (GTK_TYPE_FRAME,
"shadow", GTK_SHADOW_IN,
"shadow-type", GTK_SHADOW_IN,
NULL),
FALSE, FALSE);
gtk_box_pack_start (GTK_BOX (hbox),
@@ -1022,6 +1057,8 @@ create_scrolledwindow (void)
GtkWidget *scrolledwin, *label;
scrolledwin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS);
label = gtk_label_new ("Scrolled Window");
gtk_container_add (GTK_CONTAINER (scrolledwin), label);
@@ -1029,6 +1066,26 @@ create_scrolledwindow (void)
return new_widget_info ("scrolledwindow", scrolledwin, MEDIUM);
}
static WidgetInfo *
create_scrollbar (void)
{
GtkWidget *widget;
GtkWidget *vbox, *align;
widget = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, NULL);
gtk_widget_set_size_request (widget, 100, -1);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_add (GTK_CONTAINER (align), widget);
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox),
gtk_label_new ("Scrollbar"),
FALSE, FALSE, 0);
return new_widget_info ("scrollbar", vbox, SMALL);
}
static WidgetInfo *
create_spinbutton (void)
{
@@ -1257,6 +1314,7 @@ get_all_widgets (void)
retval = g_list_prepend (retval, create_color_button ());
retval = g_list_prepend (retval, create_combo_box ());
retval = g_list_prepend (retval, create_combo_box_entry ());
retval = g_list_prepend (retval, create_combo_box_text ());
retval = g_list_prepend (retval, create_entry ());
retval = g_list_prepend (retval, create_file_button ());
retval = g_list_prepend (retval, create_font_button ());
@@ -1273,6 +1331,7 @@ get_all_widgets (void)
retval = g_list_prepend (retval, create_radio ());
retval = g_list_prepend (retval, create_scales ());
retval = g_list_prepend (retval, create_scrolledwindow ());
retval = g_list_prepend (retval, create_scrollbar ());
retval = g_list_prepend (retval, create_separator ());
retval = g_list_prepend (retval, create_spinbutton ());
retval = g_list_prepend (retval, create_statusbar ());
@@ -1298,6 +1357,7 @@ get_all_widgets (void)
retval = g_list_prepend (retval, create_menu_button ());
retval = g_list_prepend (retval, create_search_entry ());
retval = g_list_prepend (retval, create_level_bar ());
retval = g_list_prepend (retval, create_info_bar ());
return retval;
}
+2 -1
View File
@@ -174,6 +174,7 @@ libgdk_3_la_LIBADD += x11/libgdk-x11.la
endif # USE_X11
if USE_QUARTZ
libgdk_3_la_CFLAGS = -xobjective-c
libgdk_3_la_LIBADD += quartz/libgdk-quartz.la
endif # USE_QUARTZ
@@ -370,7 +371,7 @@ dist-hook: ../build/win32/vs9/gdk.vcproj ../build/win32/vs10/gdk.vcxproj ../buil
done >libgdk.sourcefiles
$(CPP) -P - <$(top_srcdir)/build/win32/vs9/gdk.vcprojin >$@
rm libgdk.sourcefiles
../build/win32/vs10/gdk.vcxproj: ../build/win32/vs10/gdk.vcxprojin
for F in $(libgdk_3_la_SOURCES); do \
case $$F in \
-51
View File
@@ -1470,56 +1470,6 @@ _gdk_broadway_window_queue_antiexpose (GdkWindow *window,
return TRUE;
}
static void
copy_region (cairo_surface_t *surface,
cairo_region_t *area,
gint dx,
gint dy)
{
cairo_t *cr;
cr = cairo_create (surface);
gdk_cairo_region (cr, area);
cairo_clip (cr);
/* NB: This is a self-copy and Cairo doesn't support that yet.
* So we do a litle trick.
*/
cairo_push_group (cr);
cairo_set_source_surface (cr, surface, dx, dy);
cairo_paint (cr);
cairo_pop_group_to_source (cr);
cairo_paint (cr);
cairo_destroy (cr);
}
void
_gdk_broadway_window_translate (GdkWindow *window,
cairo_region_t *area,
gint dx,
gint dy)
{
GdkWindowImplBroadway *impl;
GdkBroadwayDisplay *broadway_display;
impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
if (impl->surface)
{
copy_region (impl->surface, area, dx, dy);
broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
if (_gdk_broadway_server_window_translate (broadway_display->server,
impl->id,
area, dx, dy))
queue_flush (window);
}
}
guint32
gdk_broadway_get_last_seen_time (GdkWindow *window)
{
@@ -1558,7 +1508,6 @@ gdk_window_impl_broadway_class_init (GdkWindowImplBroadwayClass *klass)
impl_class->input_shape_combine_region = gdk_window_broadway_input_shape_combine_region;
impl_class->set_static_gravities = gdk_window_broadway_set_static_gravities;
impl_class->queue_antiexpose = _gdk_broadway_window_queue_antiexpose;
impl_class->translate = _gdk_broadway_window_translate;
impl_class->destroy = _gdk_broadway_window_destroy;
impl_class->destroy_foreign = gdk_broadway_window_destroy_foreign;
impl_class->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface;
+6 -5
View File
@@ -38,11 +38,12 @@
#endif
#ifdef GDK_WINDOWING_QUARTZ
/* We immediately include gdkquartzdisplaymanager.h here instead of
* gdkquartz.h so that we do not have to enable -xobjective-c for the
* "generic" GDK source code.
/* When the gdk_quartz_display_open function is removed We can
* immediately include gdkquartzdisplaymanager.h here instead of
* gdkprivate-quartz.h so that we won't have to enable -xobjective-c
* for the "generic" GDK source code.
* #include "quartz/gdkquartzdisplaymanager.h"
*/
#include "quartz/gdkquartzdisplaymanager.h"
#include "quartz/gdkprivate-quartz.h"
#endif
@@ -309,7 +310,7 @@ struct _GdkBackend {
GdkDisplay * (* open_display) (const char *name);
};
GdkBackend gdk_backends[] = {
static GdkBackend gdk_backends[] = {
#ifdef GDK_WINDOWING_QUARTZ
{ "quartz", gdk_quartz_display_manager_get_type, _gdk_quartz_display_open },
#endif
+11 -1
View File
@@ -384,6 +384,7 @@ gdk_frame_clock_paint_idle (void *data)
case GDK_FRAME_CLOCK_PHASE_LAYOUT:
if (priv->freeze_count == 0)
{
int iter;
#ifdef G_ENABLE_DEBUG
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
{
@@ -394,11 +395,20 @@ gdk_frame_clock_paint_idle (void *data)
#endif /* G_ENABLE_DEBUG */
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT)
/* We loop in the layout phase, because we don't want to progress
* into the paint phase with invalid size allocations. This may
* happen in some situation like races between user window
* resizes and natural size changes.
*/
iter = 0;
while ((priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT) &&
priv->freeze_count == 0 && iter++ < 4)
{
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
g_signal_emit_by_name (G_OBJECT (clock), "layout");
}
if (iter == 5)
g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
}
case GDK_FRAME_CLOCK_PHASE_PAINT:
if (priv->freeze_count == 0)
+4 -26
View File
@@ -224,6 +224,7 @@ struct _GdkWindow
guint native_visibility : 2; /* the native visibility of a impl windows */
guint viewable : 1; /* mapped and all parents mapped */
guint applied_shape : 1;
guint in_update : 1;
GdkFullscreenMode fullscreen_mode;
/* The GdkWindow that has the impl, ref:ed if another window.
@@ -250,10 +251,6 @@ struct _GdkWindow
GdkCursor *cursor;
GHashTable *device_cursor;
GSList *implicit_paint;
GList *outstanding_moves;
cairo_region_t *shape;
cairo_region_t *input_shape;
@@ -269,10 +266,11 @@ struct _GdkWindow
guint num_offscreen_children;
GdkFrameClock *frame_clock; /* NULL to use from parent or default */
GdkWindowInvalidateHandlerFunc invalidate_handler;
};
#define GDK_WINDOW_TYPE(d) (((GDK_WINDOW (d)))->window_type)
#define GDK_WINDOW_DESTROYED(d) (GDK_WINDOW (d)->destroyed)
#define GDK_WINDOW_TYPE(d) ((((GdkWindow *)(d)))->window_type)
#define GDK_WINDOW_DESTROYED(d) (((GdkWindow *)(d))->destroyed)
extern gchar *_gdk_display_name;
extern gint _gdk_screen_number;
@@ -354,26 +352,6 @@ void _gdk_windowing_got_event (GdkDisplay *display,
#define GDK_WINDOW_IS_MAPPED(window) (((window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0)
#define GDK_TYPE_PAINTABLE (_gdk_paintable_get_type ())
#define GDK_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_PAINTABLE, GdkPaintable))
#define GDK_IS_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_PAINTABLE))
#define GDK_PAINTABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GDK_TYPE_PAINTABLE, GdkPaintableIface))
typedef struct _GdkPaintable GdkPaintable;
typedef struct _GdkPaintableIface GdkPaintableIface;
struct _GdkPaintableIface
{
GTypeInterface g_iface;
void (* begin_paint_region) (GdkPaintable *paintable,
GdkWindow *window,
const cairo_region_t *region);
void (* end_paint) (GdkPaintable *paintable);
};
GType _gdk_paintable_get_type (void) G_GNUC_CONST;
void _gdk_window_invalidate_for_expose (GdkWindow *window,
cairo_region_t *region);
-37
View File
@@ -555,42 +555,6 @@ gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
return FALSE;
}
static void
gdk_offscreen_window_translate (GdkWindow *window,
cairo_region_t *area,
gint dx,
gint dy)
{
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
if (offscreen->surface)
{
cairo_t *cr;
cr = cairo_create (offscreen->surface);
area = cairo_region_copy (area);
gdk_cairo_region (cr, area);
cairo_clip (cr);
/* NB: This is a self-copy and Cairo doesn't support that yet.
* So we do a litle trick.
*/
cairo_push_group (cr);
cairo_set_source_surface (cr, offscreen->surface, dx, dy);
cairo_paint (cr);
cairo_pop_group_to_source (cr);
cairo_paint (cr);
cairo_destroy (cr);
}
_gdk_window_add_damage (window, area);
}
static cairo_surface_t *
gdk_offscreen_window_resize_cairo_surface (GdkWindow *window,
cairo_surface_t *surface,
@@ -752,7 +716,6 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
impl_class->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
impl_class->set_static_gravities = gdk_offscreen_window_set_static_gravities;
impl_class->queue_antiexpose = gdk_offscreen_window_queue_antiexpose;
impl_class->translate = gdk_offscreen_window_translate;
impl_class->destroy = gdk_offscreen_window_destroy;
impl_class->destroy_foreign = NULL;
impl_class->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface;
+344 -1502
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -634,6 +634,26 @@ gboolean gdk_window_set_static_gravities (GdkWindow *window,
/* GdkWindow */
/**
* GdkWindowInvalidateHandlerFunc:
* @window: a #GdkWindow
* @region: a #cairo_region_t
*
* Whenever some area of the window is invalidated (directly in the
* window or in a child window) this gets called with @region in
* the coordinate space of @window. You can use @region to just
* keep track of the dirty region, or you can actually change
* @region in case you are doing display tricks like showing
* a child in multiple places.
*
* Since: 3.10
*/
typedef void (*GdkWindowInvalidateHandlerFunc) (GdkWindow *window,
cairo_region_t *region);
GDK_AVAILABLE_IN_3_10
void gdk_window_set_invalidate_handler (GdkWindow *window,
GdkWindowInvalidateHandlerFunc handler);
gboolean gdk_window_has_native (GdkWindow *window);
void gdk_window_set_type_hint (GdkWindow *window,
GdkWindowTypeHint hint);
@@ -747,6 +767,9 @@ GdkWindow * gdk_window_get_effective_toplevel (GdkWindow *window);
GList * gdk_window_get_children (GdkWindow *window);
GList * gdk_window_peek_children (GdkWindow *window);
GList * gdk_window_get_children_with_user_data (GdkWindow *window,
gpointer user_data);
GdkEventMask gdk_window_get_events (GdkWindow *window);
void gdk_window_set_events (GdkWindow *window,
GdkEventMask event_mask);
+3 -10
View File
@@ -101,6 +101,9 @@ struct _GdkWindowImplClass
gint *x,
gint *y,
GdkModifierType *mask);
gboolean (* begin_paint_region) (GdkWindow *window,
const cairo_region_t *region);
void (* end_paint) (GdkWindow *window);
cairo_region_t * (* get_shape) (GdkWindow *window);
cairo_region_t * (* get_input_shape) (GdkWindow *window);
@@ -125,16 +128,6 @@ struct _GdkWindowImplClass
gboolean (* queue_antiexpose) (GdkWindow *window,
cairo_region_t *update_area);
/* Called to move @area inside @window by @dx x @dy pixels. @area is
* guaranteed to be inside @window. If part of @area is not invisible or
* invalid, it is this function's job to queue expose events in those
* areas.
*/
void (* translate) (GdkWindow *window,
cairo_region_t *area,
gint dx,
gint dy);
/* Called to do the windowing system specific part of gdk_window_destroy(),
*
* window: The window being destroyed
+1 -1
View File
@@ -21,7 +21,7 @@
#define __GDK_QUARTZ_DEVICE_MANAGER_CORE__
#include <gdkdevicemanagerprivate.h>
#include <gdkquartzdevicemanager-core.h>
#include "gdkquartzdevicemanager-core.h"
G_BEGIN_DECLS
-3
View File
@@ -71,7 +71,4 @@ gdk_quartz_display_manager_class_init (GdkQuartzDisplayManagerClass *class)
GdkDisplayManagerClass *manager_class = GDK_DISPLAY_MANAGER_CLASS (class);
object_class->finalize = gdk_quartz_display_manager_finalize;
manager_class->atom_intern = _gdk_quartz_display_manager_atom_intern;
manager_class->get_atom_name = _gdk_quartz_display_manager_get_atom_name;
}
+1 -1
View File
@@ -21,7 +21,7 @@
#define __GDK_QUARTZ_DND__
#include <gdkdndprivate.h>
#include <gdkquartzdnd.h>
#include "gdkquartzdnd.h"
#include <AppKit/AppKit.h>
-8
View File
@@ -154,14 +154,6 @@ gint _gdk_quartz_display_text_property_to_utf8_list (GdkDisplay *disp
gchar * _gdk_quartz_display_utf8_to_string_target (GdkDisplay *displayt,
const gchar *str);
/* Display manager methods - events */
GdkAtom _gdk_quartz_display_manager_atom_intern (GdkDisplayManager *manager,
const gchar *atom_name,
gboolean copy_name);
gchar * _gdk_quartz_display_manager_get_atom_name (GdkDisplayManager *manager,
GdkAtom atom);
/* Screen */
GdkScreen *_gdk_quartz_screen_new (void);
void _gdk_quartz_screen_update_window_sizes (GdkScreen *screen);
-20
View File
@@ -148,26 +148,6 @@ intern_atom_internal (const gchar *atom_name, gboolean allocate)
return result;
}
GdkAtom
_gdk_quartz_display_manager_atom_intern (GdkDisplayManager *manager,
const gchar *atom_name,
gboolean copy_name)
{
return intern_atom_internal (atom_name, copy_name);
}
gchar *
_gdk_quartz_display_manager_get_atom_name (GdkDisplayManager *manager,
GdkAtom atom)
{
ensure_atom_tables ();
if (GPOINTER_TO_INT (atom) >= atoms_to_names->len)
return NULL;
return g_strdup (g_ptr_array_index (atoms_to_names, GPOINTER_TO_INT (atom)));
}
void
_gdk_quartz_window_delete_property (GdkWindow *window,
GdkAtom property)
+10 -68
View File
@@ -364,19 +364,18 @@ gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
}
static void
gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
GdkWindow *window,
static gboolean
gdk_window_impl_quartz_begin_paint_region (GdkWindow *window,
const cairo_region_t *region)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->imp);
cairo_region_t *clipped_and_offset_region;
cairo_t *cr;
clipped_and_offset_region = cairo_region_copy (region);
cairo_region_intersect (clipped_and_offset_region,
window->clip_region_with_children);
window->clip_region);
cairo_region_translate (clipped_and_offset_region,
window->abs_x, window->abs_y);
@@ -415,12 +414,14 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
done:
cairo_region_destroy (clipped_and_offset_region);
return FALSE;
}
static void
gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
gdk_window_impl_quartz_end_paint (GdkWindow *window)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
impl->begin_paint_count--;
@@ -536,13 +537,6 @@ _gdk_quartz_display_after_process_all_updates (GdkDisplay *display)
NSEnableScreenUpdates ();
}
static void
gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
{
iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
iface->end_paint = gdk_window_impl_quartz_end_paint;
}
static const gchar *
get_default_title (void)
{
@@ -2237,49 +2231,6 @@ gdk_quartz_window_queue_antiexpose (GdkWindow *window,
return FALSE;
}
static void
gdk_quartz_window_translate (GdkWindow *window,
cairo_region_t *area,
gint dx,
gint dy)
{
cairo_region_t *invalidate, *scrolled;
GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *)window->impl;
GdkRectangle extents;
cairo_region_get_extents (area, &extents);
[impl->view scrollRect:NSMakeRect (extents.x - dx, extents.y - dy,
extents.width, extents.height)
by:NSMakeSize (dx, dy)];
if (impl->needs_display_region)
{
cairo_region_t *intersection;
/* Invalidate already invalidated area that was moved at new
* location.
*/
intersection = cairo_region_copy (impl->needs_display_region);
cairo_region_intersect (intersection, area);
cairo_region_translate (intersection, dx, dy);
gdk_quartz_window_set_needs_display_in_region (window, intersection);
cairo_region_destroy (intersection);
}
/* Calculate newly exposed area that needs invalidation */
scrolled = cairo_region_copy (area);
cairo_region_translate (scrolled, dx, dy);
invalidate = cairo_region_copy (area);
cairo_region_subtract (invalidate, scrolled);
cairo_region_destroy (scrolled);
gdk_quartz_window_set_needs_display_in_region (window, invalidate);
cairo_region_destroy (invalidate);
}
static void
gdk_quartz_window_set_focus_on_map (GdkWindow *window,
gboolean focus_on_map)
@@ -3078,12 +3029,13 @@ gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
impl_class->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
impl_class->set_static_gravities = gdk_window_quartz_set_static_gravities;
impl_class->queue_antiexpose = gdk_quartz_window_queue_antiexpose;
impl_class->translate = gdk_quartz_window_translate;
impl_class->destroy = gdk_quartz_window_destroy;
impl_class->destroy_foreign = gdk_quartz_window_destroy_foreign;
impl_class->resize_cairo_surface = gdk_window_quartz_resize_cairo_surface;
impl_class->get_shape = gdk_quartz_window_get_shape;
impl_class->get_input_shape = gdk_quartz_window_get_input_shape;
impl_class->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
impl_class->end_paint = gdk_window_impl_quartz_end_paint;
impl_class->focus = gdk_quartz_window_focus;
impl_class->set_type_hint = gdk_quartz_window_set_type_hint;
@@ -3159,19 +3111,9 @@ _gdk_window_impl_quartz_get_type (void)
(GInstanceInitFunc) gdk_window_impl_quartz_init,
};
const GInterfaceInfo paintable_info =
{
(GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
NULL,
NULL
};
object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL,
"GdkWindowImplQuartz",
&object_info, 0);
g_type_add_interface_static (object_type,
GDK_TYPE_PAINTABLE,
&paintable_info);
}
return object_type;
+1 -1
View File
@@ -5,7 +5,7 @@
static void
test_unset_display (void)
{
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
if (g_test_trap_fork (0, 0))//G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
{
GdkDisplayManager *manager;
-5
View File
@@ -260,8 +260,6 @@ gdk_wayland_display_dispose (GObject *object)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (object);
_gdk_wayland_display_manager_remove_display (gdk_display_manager_get (),
GDK_DISPLAY (display_wayland));
g_list_foreach (display_wayland->input_devices,
(GFunc) g_object_run_dispose, NULL);
@@ -613,9 +611,6 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass * class)
static void
gdk_wayland_display_init (GdkWaylandDisplay *display)
{
_gdk_wayland_display_manager_add_display (gdk_display_manager_get (),
GDK_DISPLAY (display));
display->xkb_context = xkb_context_new (0);
}
-28
View File
@@ -101,31 +101,3 @@ gdk_wayland_display_manager_init (GdkWaylandDisplayManager *manager)
{
}
void
_gdk_wayland_display_manager_add_display (GdkDisplayManager *manager,
GdkDisplay *display)
{
GdkWaylandDisplayManager *manager_wayland = GDK_WAYLAND_DISPLAY_MANAGER (manager);
if (manager_wayland->displays == NULL)
gdk_display_manager_set_default_display (manager, display);
manager_wayland->displays = g_slist_prepend (manager_wayland->displays, display);
}
void
_gdk_wayland_display_manager_remove_display (GdkDisplayManager *manager,
GdkDisplay *display)
{
GdkWaylandDisplayManager *manager_wayland = GDK_WAYLAND_DISPLAY_MANAGER (manager);
manager_wayland->displays = g_slist_remove (manager_wayland->displays, display);
if (gdk_display_manager_get_default_display (manager) == display)
{
if (manager_wayland->displays)
gdk_display_manager_set_default_display (manager, manager_wayland->displays->data);
else
gdk_display_manager_set_default_display (manager, NULL);
}
}
+2 -5
View File
@@ -164,11 +164,8 @@ void _gdk_wayland_screen_add_output (GdkScreen *screen,
struct wl_output *output);
void _gdk_wayland_screen_remove_output (GdkScreen *screen,
guint32 id);
void _gdk_wayland_display_manager_add_display (GdkDisplayManager *manager,
GdkDisplay *display);
void _gdk_wayland_display_manager_remove_display (GdkDisplayManager *manager,
GdkDisplay *display);
int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
struct wl_output *output);
void _gdk_wayland_window_set_device_grabbed (GdkWindow *window,
GdkDevice *device,
+21 -1
View File
@@ -87,6 +87,7 @@ struct _GdkWaylandMonitor
int height_mm;
char * output_name;
char * manufacturer;
int refresh_rate;
};
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
@@ -130,7 +131,7 @@ gdk_wayland_screen_dispose (GObject *object)
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
if (screen_wayland->root_window)
_gdk_window_destroy (screen_wayland->root_window, TRUE);
_gdk_window_destroy (screen_wayland->root_window, FALSE);
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->dispose (object);
}
@@ -917,6 +918,7 @@ output_handle_mode(void *data,
monitor->geometry.width = width;
monitor->geometry.height = height;
monitor->refresh_rate = refresh;
g_signal_emit_by_name (monitor->screen, "monitors-changed");
update_screen_size (monitor->screen);
@@ -965,3 +967,21 @@ _gdk_wayland_screen_remove_output (GdkScreen *screen,
}
}
}
int
_gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
struct wl_output *output)
{
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
int i;
for (i = 0; i < screen_wayland->monitors->len; i++)
{
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
if (monitor->output == output)
return monitor->refresh_rate;
}
return 0;
}
+288 -85
View File
@@ -26,6 +26,7 @@
#include "gdkwindow.h"
#include "gdkwindowimpl.h"
#include "gdkdisplay-wayland.h"
#include "gdkframeclockprivate.h"
#include "gdkprivate-wayland.h"
#include "gdkinternals.h"
#include "gdkdeviceprivate.h"
@@ -95,6 +96,9 @@ struct _GdkWindowImplWayland
GdkCursor *cursor;
/* The wl_outputs that this window currently touches */
GSList *outputs;
struct wl_surface *surface;
struct wl_shell_surface *shell_surface;
unsigned int mapped : 1;
@@ -140,6 +144,9 @@ struct _GdkWindowImplWayland
} saved_fullscreen, saved_maximized;
gboolean use_custom_surface;
gboolean pending_commit;
gint64 pending_frame_counter;
};
struct _GdkWindowImplWaylandClass
@@ -256,6 +263,162 @@ get_default_title (void)
return title;
}
static void
fill_presentation_time_from_frame_time (GdkFrameTimings *timings,
guint32 frame_time)
{
/* The timestamp in a wayland frame is a msec time value that in some
* way reflects the time at which the server started drawing the frame.
* This is not useful from our perspective.
*
* However, for the DRM backend of Weston, on reasonably recent
* Linux, we know that the time is the
* clock_gettime(CLOCK_MONOTONIC) value at the vblank, and that
* backend starts drawing immediately after receiving the vblank
* notification. If we detect this, and make the assumption that the
* compositor will finish drawing before the next vblank, we can
* then determine the presentation time as the frame time we
* recieved plus one refresh interval.
*
* If a backend is using clock_gettime(CLOCK_MONOTONIC), but not
* picking values right at the vblank, then the presentation times
* we compute won't be accurate, but not really worse than then
* the alternative of not providing presentation times at all.
*
* The complexity here is dealing with the fact that we receive
* only the low 32 bits of the CLOCK_MONOTONIC value in milliseconds.
*/
gint64 now_monotonic = g_get_monotonic_time ();
gint64 now_monotonic_msec = now_monotonic / 1000;
uint32_t now_monotonic_low = (uint32_t)now_monotonic_msec;
if (frame_time - now_monotonic_low < 1000 ||
frame_time - now_monotonic_low > (uint32_t)-1000)
{
/* Timestamp we received is within one second of the current time.
*/
gint64 last_frame_time = now_monotonic + (gint64)1000 * (gint32)(frame_time - now_monotonic_low);
if ((gint32)now_monotonic_low < 0 && (gint32)frame_time > 0)
last_frame_time += (gint64)1000 * G_GINT64_CONSTANT(0x100000000);
else if ((gint32)now_monotonic_low > 0 && (gint32)frame_time < 0)
last_frame_time -= (gint64)1000 * G_GINT64_CONSTANT(0x100000000);
timings->presentation_time = last_frame_time + timings->refresh_interval;
}
}
static void
frame_callback (void *data,
struct wl_callback *callback,
uint32_t time)
{
GdkWindow *window = data;
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
GdkFrameClock *clock = gdk_window_get_frame_clock (window);
GdkFrameTimings *timings;
wl_callback_destroy (callback);
_gdk_frame_clock_thaw (clock);
timings = gdk_frame_clock_get_timings (clock, impl->pending_frame_counter);
impl->pending_frame_counter = 0;
if (timings == NULL)
return;
timings->refresh_interval = 16667; /* default to 1/60th of a second */
if (impl->outputs)
{
/* We pick a random output out of the outputs that the window touches
* The rate here is in milli-hertz */
int refresh_rate = _gdk_wayland_screen_get_output_refresh_rate (wayland_display->screen,
impl->outputs->data);
if (refresh_rate != 0)
timings->refresh_interval = G_GINT64_CONSTANT(1000000000) / refresh_rate;
}
fill_presentation_time_from_frame_time (timings, time);
timings->complete = TRUE;
#ifdef G_ENABLE_DEBUG
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
_gdk_frame_clock_debug_print_timings (clock, timings);
#endif
}
static const struct wl_callback_listener listener = {
frame_callback
};
static void
on_frame_clock_before_paint (GdkFrameClock *clock,
GdkWindow *window)
{
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
gint64 presentation_time;
gint64 refresh_interval;
gdk_frame_clock_get_refresh_info (clock,
timings->frame_time,
&refresh_interval, &presentation_time);
if (presentation_time != 0)
{
/* Assume the algorithm used by the DRM backend of Weston - it
* starts drawing at the next vblank after receiving the commit
* for this frame, and presentation occurs at the vblank
* after that.
*/
timings->predicted_presentation_time = presentation_time + refresh_interval;
}
else
{
/* As above, but we don't actually know the phase of the vblank,
* so just assume that we're half way through a refresh cycle.
*/
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
}
}
static const cairo_user_data_key_t gdk_wayland_cairo_key;
typedef struct _GdkWaylandCairoSurfaceData {
gpointer buf;
size_t buf_length;
struct wl_shm_pool *pool;
struct wl_buffer *buffer;
GdkWaylandDisplay *display;
int32_t width, height;
gboolean busy;
} GdkWaylandCairoSurfaceData;
static void
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkWaylandCairoSurfaceData *data;
struct wl_callback *callback;
if (!impl->pending_commit)
return;
impl->pending_commit = FALSE;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
callback = wl_surface_frame (impl->surface);
wl_callback_add_listener (callback, &listener, window);
_gdk_frame_clock_freeze (clock);
wl_surface_commit (impl->surface);
data = cairo_surface_get_user_data (impl->cairo_surface,
&gdk_wayland_cairo_key);
data->busy = TRUE;
}
void
_gdk_wayland_display_create_window_impl (GdkDisplay *display,
GdkWindow *window,
@@ -266,6 +429,7 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
gint attributes_mask)
{
GdkWindowImplWayland *impl;
GdkFrameClock *frame_clock;
const char *title;
impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
@@ -306,19 +470,15 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
if (attributes_mask & GDK_WA_TYPE_HINT)
gdk_window_set_type_hint (window, attributes->type_hint);
frame_clock = gdk_window_get_frame_clock (window);
g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), window);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), window);
}
static const cairo_user_data_key_t gdk_wayland_cairo_key;
typedef struct _GdkWaylandCairoSurfaceData {
gpointer buf;
size_t buf_length;
struct wl_shm_pool *pool;
struct wl_buffer *buffer;
GdkWaylandDisplay *display;
int32_t width, height;
} GdkWaylandCairoSurfaceData;
static void
gdk_wayland_window_attach_image (GdkWindow *window)
{
@@ -368,6 +528,7 @@ gdk_wayland_window_attach_image (GdkWindow *window)
/* Attach this new buffer to the surface */
wl_surface_attach (impl->surface, data->buffer, dx, dy);
impl->pending_commit = TRUE;
}
static void
@@ -433,6 +594,19 @@ _create_shm_pool (struct wl_shm *shm,
return pool;
}
static void
buffer_release_callback (void *_data, struct wl_buffer *wl_buffer)
{
GdkWaylandCairoSurfaceData *data = _data;
data->busy = FALSE;
}
static const struct wl_buffer_listener buffer_listener = {
buffer_release_callback
};
static cairo_surface_t *
gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
int width, int height)
@@ -447,6 +621,7 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
data->buffer = NULL;
data->width = width;
data->height = height;
data->busy = FALSE;
stride = width * 4;
@@ -458,6 +633,7 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
width, height,
stride, WL_SHM_FORMAT_ARGB8888);
wl_buffer_add_listener (data->buffer, &buffer_listener, data);
surface = cairo_image_surface_create_for_data (data->buf,
CAIRO_FORMAT_ARGB32,
@@ -478,28 +654,34 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
return surface;
}
/* On this first call this creates a double reference - the first reference
* is held by the GdkWindowImplWayland struct - since unlike other backends
* the Cairo surface is not just a cheap wrapper around some other backing.
* It is the buffer itself.
*/
static cairo_surface_t *
gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
static void
gdk_wayland_window_ensure_cairo_surface (GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkWaylandDisplay *display_wayland =
GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper));
if (GDK_WINDOW_DESTROYED (impl->wrapper))
return NULL;
if (!impl->cairo_surface)
{
GdkWaylandDisplay *display_wayland =
GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper));
impl->cairo_surface =
gdk_wayland_create_cairo_surface (display_wayland,
impl->wrapper->width,
impl->wrapper->height);
}
}
/* Unlike other backends the Cairo surface is not just a cheap wrapper
* around some other backing. It is the buffer itself.
*/
static cairo_surface_t *
gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
if (GDK_WINDOW_DESTROYED (impl->wrapper))
return NULL;
gdk_wayland_window_ensure_cairo_surface (window);
cairo_surface_reference (impl->cairo_surface);
@@ -507,6 +689,20 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
}
static gboolean
gdk_window_impl_wayland_begin_paint_region (GdkWindow *window,
const cairo_region_t *region)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkWaylandCairoSurfaceData *data;
gdk_wayland_window_ensure_cairo_surface (window);
data = cairo_surface_get_user_data (impl->cairo_surface,
&gdk_wayland_cairo_key);
return data->busy;
}
static void
gdk_window_impl_wayland_finalize (GObject *object)
{
@@ -518,8 +714,6 @@ gdk_window_impl_wayland_finalize (GObject *object)
if (impl->cursor)
g_object_unref (impl->cursor);
if (impl->server_surface)
cairo_surface_destroy (impl->server_surface);
G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
}
@@ -638,6 +832,28 @@ gdk_wayland_window_map (GdkWindow *window)
}
}
static void
surface_enter (void *data,
struct wl_surface *wl_surface,
struct wl_output *output)
{
GdkWindow *window = GDK_WINDOW (data);
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
impl->outputs = g_slist_prepend (impl->outputs, output);
}
static void
surface_leave (void *data,
struct wl_surface *wl_surface,
struct wl_output *output)
{
GdkWindow *window = GDK_WINDOW (data);
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
impl->outputs = g_slist_remove (impl->outputs, output);
}
static void
shell_surface_handle_configure(void *data,
struct wl_shell_surface *shell_surface,
@@ -686,12 +902,30 @@ shell_surface_ping (void *data,
wl_shell_surface_pong(shell_surface, serial);
}
static const struct wl_surface_listener surface_listener = {
surface_enter,
surface_leave
};
static const struct wl_shell_surface_listener shell_surface_listener = {
shell_surface_ping,
shell_surface_handle_configure,
shell_surface_popup_done
};
static void
gdk_wayland_window_create_surface (GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
impl->surface = wl_compositor_create_surface (display_wayland->compositor);
wl_surface_set_user_data(impl->surface, window);
wl_surface_add_listener(impl->surface,
&surface_listener, window);
}
static void
gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
{
@@ -709,10 +943,7 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
gdk_wayland_window_set_user_time (window, impl->user_time);
if (!impl->surface)
{
impl->surface = wl_compositor_create_surface(display_wayland->compositor);
wl_surface_set_user_data(impl->surface, window);
}
gdk_wayland_window_create_surface (window);
if (!impl->shell_surface &&
!impl->use_custom_surface &&
@@ -738,7 +969,8 @@ gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
}
static void
gdk_wayland_window_hide (GdkWindow *window)
gdk_wayland_window_hide_surface (GdkWindow *window,
gboolean is_destroy)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
@@ -746,7 +978,7 @@ gdk_wayland_window_hide (GdkWindow *window)
{
if (impl->shell_surface)
wl_shell_surface_destroy(impl->shell_surface);
if (impl->use_custom_surface)
if (impl->use_custom_surface && !is_destroy)
{
wl_surface_attach (impl->surface, NULL, 0, 0);
wl_surface_commit (impl->surface);
@@ -755,21 +987,27 @@ gdk_wayland_window_hide (GdkWindow *window)
{
wl_surface_destroy(impl->surface);
impl->surface = NULL;
g_slist_free (impl->outputs);
impl->outputs = NULL;
}
impl->shell_surface = NULL;
cairo_surface_destroy(impl->server_surface);
impl->server_surface = NULL;
impl->mapped = FALSE;
}
}
static void
gdk_wayland_window_hide (GdkWindow *window)
{
gdk_wayland_window_hide_surface (window, FALSE);
_gdk_window_clear_update_area (window);
}
static void
gdk_window_wayland_withdraw (GdkWindow *window)
{
GdkWindowImplWayland *impl;
if (!window->destroyed)
{
if (GDK_WINDOW_IS_MAPPED (window))
@@ -777,26 +1015,7 @@ gdk_window_wayland_withdraw (GdkWindow *window)
g_assert (!GDK_WINDOW_IS_MAPPED (window));
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
if (impl->surface)
{
if (impl->shell_surface)
wl_shell_surface_destroy(impl->shell_surface);
if (impl->use_custom_surface)
{
wl_surface_attach (impl->surface, NULL, 0, 0);
wl_surface_commit (impl->surface);
}
else if (impl->surface)
{
wl_surface_destroy(impl->surface);
impl->surface = NULL;
}
impl->shell_surface = NULL;
cairo_surface_destroy(impl->server_surface);
impl->server_surface = NULL;
impl->mapped = FALSE;
}
gdk_wayland_window_hide_surface (window, FALSE);
}
}
@@ -1009,15 +1228,6 @@ gdk_wayland_window_queue_antiexpose (GdkWindow *window,
return FALSE;
}
static void
gdk_wayland_window_translate (GdkWindow *window,
cairo_region_t *area,
gint dx,
gint dy)
{
_gdk_window_invalidate_for_expose (window, area);
}
static void
gdk_wayland_window_destroy (GdkWindow *window,
gboolean recursing,
@@ -1027,22 +1237,20 @@ gdk_wayland_window_destroy (GdkWindow *window,
g_return_if_fail (GDK_IS_WINDOW (window));
/* We don't have nested windows */
g_return_if_fail (!recursing);
/* Wayland windows can't be externally destroyed; we may possibly
* eventually want to use this path at display close-down */
g_return_if_fail (!foreign_destroy);
gdk_wayland_window_hide_surface (window, TRUE);
if (impl->cairo_surface)
{
cairo_surface_finish (impl->cairo_surface);
cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key,
NULL, NULL);
}
if (!recursing && !foreign_destroy)
{
if (impl->shell_surface)
wl_shell_surface_destroy(impl->shell_surface);
if (impl->surface)
wl_surface_destroy(impl->surface);
impl->shell_surface = NULL;
impl->surface = NULL;
}
}
static void
@@ -1623,8 +1831,10 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window,
gdk_wayland_window_map (window);
if (impl->cairo_surface)
gdk_wayland_window_attach_image (window);
gdk_wayland_window_ensure_cairo_surface (window);
gdk_wayland_window_attach_image (window);
_gdk_window_process_updates_recurse (window, region);
n = cairo_region_num_rectangles(region);
for (i = 0; i < n; i++)
@@ -1632,10 +1842,8 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window,
cairo_region_get_rectangle (region, i, &rect);
wl_surface_damage (impl->surface,
rect.x, rect.y, rect.width, rect.height);
wl_surface_commit(impl->surface);
impl->pending_commit = TRUE;
}
_gdk_window_process_updates_recurse (window, region);
}
static void
@@ -1726,12 +1934,12 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region;
impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities;
impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose;
impl_class->translate = gdk_wayland_window_translate;
impl_class->destroy = gdk_wayland_window_destroy;
impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign;
impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface;
impl_class->get_shape = gdk_wayland_window_get_shape;
impl_class->get_input_shape = gdk_wayland_window_get_input_shape;
impl_class->begin_paint_region = gdk_window_impl_wayland_begin_paint_region;
/* impl_class->beep */
impl_class->focus = gdk_wayland_window_focus;
@@ -1897,18 +2105,13 @@ void
gdk_wayland_window_set_use_custom_surface (GdkWindow *window)
{
GdkWindowImplWayland *impl;
GdkWaylandDisplay *display;
g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
if (!impl->surface)
{
display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
impl->surface = wl_compositor_create_surface (display->compositor);
wl_surface_set_user_data (impl->surface, window);
}
gdk_wayland_window_create_surface (window);
impl->use_custom_surface = TRUE;
}
-72
View File
@@ -3319,77 +3319,6 @@ _gdk_win32_window_queue_antiexpose (GdkWindow *window,
return FALSE;
}
/* Gets called from gdwindow.c(do_move_region_bits_on_impl)
* and got tested with testgtk::big_window. Given the previous,
* untested implementation this one looks much too simple ;)
*/
static void
_gdk_win32_window_translate (GdkWindow *window,
cairo_region_t *area, /* In impl window coords */
gint dx,
gint dy)
{
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
HRGN hrgn, area_hrgn;
cairo_region_t *update_region;
HDC hdc;
int ret;
/* Note: This is the destination area, not the source, and
it has been moved by dx, dy from the source area */
area_hrgn = cairo_region_to_hrgn (area, 0, 0);
/* First we copy any outstanding invalid areas in the
source area to the new position in the destination area */
hrgn = CreateRectRgn (0, 0, 0, 0);
ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
if (ret == ERROR)
WIN32_API_FAILED ("GetUpdateRgn");
else if (ret != NULLREGION)
{
/* Convert the source invalid region as it would be copied */
OffsetRgn (hrgn, dx, dy);
/* Keep what intersects the copy destination area */
ret = CombineRgn (hrgn, hrgn, area_hrgn, RGN_AND);
/* And invalidate it */
if (ret == ERROR)
WIN32_API_FAILED ("CombineRgn");
else if (ret != NULLREGION)
API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), hrgn, TRUE));
}
/* Then we copy the bits, invalidating whatever is copied from
otherwise invisible areas */
hdc = _gdk_win32_impl_acquire_dc (impl);
/* Clip hdc to target region */
API_CALL (SelectClipRgn, (hdc, area_hrgn));
SetRectRgn (hrgn, 0, 0, 0, 0);
if (!ScrollDC (hdc, dx, dy, NULL, NULL, hrgn, NULL))
WIN32_GDI_FAILED ("ScrollDC");
else
{
update_region = _gdk_win32_hrgn_to_region (hrgn);
if (!cairo_region_is_empty (update_region))
_gdk_window_invalidate_for_expose (window, update_region);
cairo_region_destroy (update_region);
}
/* Unset hdc clip region */
API_CALL (SelectClipRgn, (hdc, NULL));
_gdk_win32_impl_release_dc (impl);
if (!DeleteObject (hrgn))
WIN32_GDI_FAILED ("DeleteObject");
if (!DeleteObject (area_hrgn))
WIN32_GDI_FAILED ("DeleteObject");
}
static void
gdk_win32_input_shape_combine_region (GdkWindow *window,
const cairo_region_t *shape_region,
@@ -3556,7 +3485,6 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
impl_class->input_shape_combine_region = gdk_win32_input_shape_combine_region;
impl_class->set_static_gravities = gdk_win32_window_set_static_gravities;
impl_class->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
impl_class->translate = _gdk_win32_window_translate;
impl_class->destroy = gdk_win32_window_destroy;
impl_class->destroy_foreign = gdk_win32_window_destroy_foreign;
impl_class->resize_cairo_surface = gdk_win32_window_resize_cairo_surface;
+2
View File
@@ -2824,4 +2824,6 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
display_class->convert_selection = _gdk_x11_display_convert_selection;
display_class->text_property_to_utf8_list = _gdk_x11_display_text_property_to_utf8_list;
display_class->utf8_to_string_target = _gdk_x11_display_utf8_to_string_target;
_gdk_x11_windowing_init ();
}
-1
View File
@@ -75,7 +75,6 @@ g_initable_iface_init (GInitableIface *iface)
static void
gdk_x11_display_manager_init (GdkX11DisplayManager *manager)
{
_gdk_x11_windowing_init ();
}
static void
+6 -126
View File
@@ -28,26 +28,11 @@
typedef struct _GdkWindowQueueItem GdkWindowQueueItem;
typedef struct _GdkWindowParentPos GdkWindowParentPos;
typedef enum {
GDK_WINDOW_QUEUE_TRANSLATE,
GDK_WINDOW_QUEUE_ANTIEXPOSE
} GdkWindowQueueType;
struct _GdkWindowQueueItem
{
GdkWindow *window;
gulong serial;
GdkWindowQueueType type;
union {
struct {
cairo_region_t *area;
gint dx;
gint dy;
} translate;
struct {
cairo_region_t *area;
} antiexpose;
} u;
cairo_region_t *antiexpose_area;
};
void
@@ -140,14 +125,7 @@ queue_item_free (GdkWindowQueueItem *item)
(gpointer *)&(item->window));
}
if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
cairo_region_destroy (item->u.antiexpose.area);
else
{
if (item->u.translate.area)
cairo_region_destroy (item->u.translate.area);
}
cairo_region_destroy (item->antiexpose_area);
g_free (item);
}
@@ -213,11 +191,8 @@ gdk_window_queue (GdkWindow *window,
GdkWindowQueueItem *item = tmp_list->data;
GList *next = tmp_list->next;
if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
{
queue_delete_link (display_x11->translate_queue, tmp_list);
queue_item_free (item);
}
queue_delete_link (display_x11->translate_queue, tmp_list);
queue_item_free (item);
tmp_list = next;
}
@@ -232,86 +207,12 @@ gdk_window_queue (GdkWindow *window,
g_queue_push_tail (display_x11->translate_queue, item);
}
static GC
_get_scratch_gc (GdkWindow *window, cairo_region_t *clip_region)
{
GdkX11Screen *screen;
XRectangle *rectangles;
gint n_rects;
gint depth;
screen = GDK_X11_SCREEN (gdk_window_get_screen (window));
depth = gdk_visual_get_depth (gdk_window_get_visual (window)) - 1;
if (!screen->subwindow_gcs[depth])
{
XGCValues values;
values.graphics_exposures = True;
values.subwindow_mode = IncludeInferiors;
screen->subwindow_gcs[depth] = XCreateGC (screen->xdisplay,
GDK_WINDOW_XID (window),
GCSubwindowMode | GCGraphicsExposures,
&values);
}
_gdk_x11_region_get_xrectangles (clip_region,
0, 0,
&rectangles,
&n_rects);
XSetClipRectangles (screen->xdisplay,
screen->subwindow_gcs[depth],
0, 0,
rectangles, n_rects,
YXBanded);
g_free (rectangles);
return screen->subwindow_gcs[depth];
}
void
_gdk_x11_window_translate (GdkWindow *window,
cairo_region_t *area,
gint dx,
gint dy)
{
GdkWindowQueueItem *item;
GC xgc;
GdkRectangle extents;
cairo_region_get_extents (area, &extents);
xgc = _get_scratch_gc (window, area);
cairo_region_translate (area, -dx, -dy); /* Move to source region */
item = g_new (GdkWindowQueueItem, 1);
item->type = GDK_WINDOW_QUEUE_TRANSLATE;
item->u.translate.area = cairo_region_copy (area);
item->u.translate.dx = dx;
item->u.translate.dy = dy;
gdk_window_queue (window, item);
XCopyArea (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
GDK_WINDOW_XID (window),
xgc,
extents.x - dx, extents.y - dy,
extents.width, extents.height,
extents.x, extents.y);
}
gboolean
_gdk_x11_window_queue_antiexpose (GdkWindow *window,
cairo_region_t *area)
{
GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1);
item->type = GDK_WINDOW_QUEUE_ANTIEXPOSE;
item->u.antiexpose.area = area;
item->antiexpose_area = area;
gdk_window_queue (window, item);
@@ -339,28 +240,7 @@ _gdk_x11_window_process_expose (GdkWindow *window,
if (serial - item->serial > (gulong) G_MAXLONG)
{
if (item->window == window)
{
if (item->type == GDK_WINDOW_QUEUE_TRANSLATE)
{
if (item->u.translate.area)
{
cairo_region_t *intersection;
intersection = cairo_region_copy (invalidate_region);
cairo_region_intersect (intersection, item->u.translate.area);
cairo_region_subtract (invalidate_region, intersection);
cairo_region_translate (intersection, item->u.translate.dx, item->u.translate.dy);
cairo_region_union (invalidate_region, intersection);
cairo_region_destroy (intersection);
}
else
cairo_region_translate (invalidate_region, item->u.translate.dx, item->u.translate.dy);
}
else /* anti-expose */
{
cairo_region_subtract (invalidate_region, item->u.antiexpose.area);
}
}
cairo_region_subtract (invalidate_region, item->antiexpose_area);
}
else
{
-1
View File
@@ -5334,7 +5334,6 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
impl_class->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
impl_class->set_static_gravities = gdk_window_x11_set_static_gravities;
impl_class->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
impl_class->translate = _gdk_x11_window_translate;
impl_class->destroy = gdk_x11_window_destroy;
impl_class->destroy_foreign = gdk_x11_window_destroy_foreign;
impl_class->resize_cairo_surface = gdk_window_x11_resize_cairo_surface;
+8 -4
View File
@@ -314,6 +314,7 @@ gtk_public_h_sources = \
gtkrecentchooserwidget.h \
gtkrecentfilter.h \
gtkrecentmanager.h \
gtkrevealer.h \
gtkscale.h \
gtkscalebutton.h \
gtkscrollable.h \
@@ -518,6 +519,7 @@ gtk_private_h_sources = \
gtkprintoperation-private.h \
gtkprintutils.h \
gtkprivate.h \
gtkpixelcacheprivate.h \
gtkquery.h \
gtkrbtree.h \
gtkrecentchooserdefault.h \
@@ -799,6 +801,7 @@ gtk_base_c_sources = \
gtkprivate.c \
gtkprivatetypebuiltins.c \
gtkprogressbar.c \
gtkpixelcache.c \
gtkradioaction.c \
gtkradiobutton.c \
gtkradiomenuitem.c \
@@ -815,6 +818,7 @@ gtk_base_c_sources = \
gtkrecentfilter.c \
gtkrecentmanager.c \
gtkresources.c \
gtkrevealer.c \
gtkroundedbox.c \
gtkscale.c \
gtkscalebutton.c \
@@ -1354,7 +1358,9 @@ endif
#
# Installed tools
#
bin_PROGRAMS = gtk-query-immodules-3.0
bin_PROGRAMS = \
gtk-query-immodules-3.0 \
gtk-launch
if BUILD_ICON_CACHE
bin_PROGRAMS += gtk-update-icon-cache
@@ -1401,11 +1407,8 @@ gtk_update_icon_cache_LDADD = $(GDK_PIXBUF_LIBS)
gtk_update_icon_cache_SOURCES = updateiconcache.c
endif
if HAVE_GIO_UNIX
bin_PROGRAMS += gtk-launch
gtk_launch_LDADD = $(LDADDS)
gtk_launch_SOURCES = gtk-launch.c
endif
noinst_PROGRAMS = extract-strings
@@ -1735,6 +1738,7 @@ endif
EXTRA_DIST += \
$(STOCK_ICONS) \
$(COMPOSITE_TEMPLATES) \
$(DND_CURSORS) \
$(GENERATED_ICONS) \
gtk.def \
+1 -107
View File
@@ -29,11 +29,9 @@ struct _GtkComboBoxAccessiblePrivate
};
static void atk_action_interface_init (AtkActionIface *iface);
static void atk_selection_interface_init (AtkSelectionIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkComboBoxAccessible, gtk_combo_box_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
static void
changed_cb (GtkWidget *widget)
@@ -52,7 +50,6 @@ changed_cb (GtkWidget *widget)
{
accessible->priv->old_selection = index;
g_object_notify (G_OBJECT (obj), "accessible-name");
g_signal_emit_by_name (obj, "selection-changed");
}
}
@@ -333,106 +330,3 @@ atk_action_interface_init (AtkActionIface *iface)
iface->get_localized_name = gtk_combo_box_accessible_action_get_localized_name;
iface->get_description = gtk_combo_box_accessible_action_get_description;
}
static gboolean
gtk_combo_box_accessible_add_selection (AtkSelection *selection,
gint i)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), i);
return TRUE;
}
static gboolean
gtk_combo_box_accessible_clear_selection (AtkSelection *selection)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), -1);
return TRUE;
}
static AtkObject *
gtk_combo_box_accessible_ref_selection (AtkSelection *selection,
gint i)
{
GtkComboBox *combo_box;
GtkWidget *widget;
AtkObject *obj;
gint index;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return NULL;
if (i != 0)
return NULL;
combo_box = GTK_COMBO_BOX (widget);
obj = gtk_combo_box_get_popup_accessible (combo_box);
index = gtk_combo_box_get_active (combo_box);
return atk_object_ref_accessible_child (obj, index);
}
static gint
gtk_combo_box_accessible_get_selection_count (AtkSelection *selection)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return 0;
return (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1) ? 0 : 1;
}
static gboolean
gtk_combo_box_accessible_is_child_selected (AtkSelection *selection,
gint i)
{
GtkWidget *widget;
gint j;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
j = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
return (j == i);
}
static gboolean
gtk_combo_box_accessible_remove_selection (AtkSelection *selection,
gint i)
{
if (atk_selection_is_child_selected (selection, i))
atk_selection_clear_selection (selection);
return TRUE;
}
static void
atk_selection_interface_init (AtkSelectionIface *iface)
{
iface->add_selection = gtk_combo_box_accessible_add_selection;
iface->clear_selection = gtk_combo_box_accessible_clear_selection;
iface->ref_selection = gtk_combo_box_accessible_ref_selection;
iface->get_selection_count = gtk_combo_box_accessible_get_selection_count;
iface->is_child_selected = gtk_combo_box_accessible_is_child_selected;
iface->remove_selection = gtk_combo_box_accessible_remove_selection;
}
-5
View File
@@ -11,8 +11,6 @@
<glade-widget-class name="GtkColorPlane" generic-name="colorplane" title="Color Plane" icon-name="widget-gtk-colorselection"/>
<glade-widget-class name="GtkColorScale" generic-name="colorscale" title="Color Scale" icon-name="widget-gtk-colorselection"/>
<glade-widget-class name="GtkScaleButtonScale" generic-name="scalebuttonscale" title="Scale Button Scale"/>
<glade-widget-class name="ShortcutsPaneModelFilter" generic-name="shortcutsfilter" title="Shortcuts Filter"
icon-name="widget-gtk-treemodelfilter"/>
<!-- gtkunixprint private widgets -->
<glade-widget-class name="GtkPrinterOptionWidget" generic-name="printeroptionwidget" title="Printer Option Widget"
@@ -22,7 +20,6 @@
<property id="size" disabled="True"/>
</properties>
</glade-widget-class>
<glade-widget-class name="GtkPlacesSidebar" generic-name="placessidebar" title="Places Sidebar"/>
</glade-widget-classes>
<glade-widget-group name="gtk-private" title="Private GTK+ Classes">
@@ -31,8 +28,6 @@
<glade-widget-class-ref name="GtkColorPlane"/>
<glade-widget-class-ref name="GtkColorScale"/>
<glade-widget-class-ref name="GtkScaleButtonScale"/>
<glade-widget-class-ref name="ShortcutsPaneModelFilter"/>
<glade-widget-class-ref name="GtkPrinterOptionWidget"/>
<glade-widget-class-ref name="GtkPlacesSidebar"/>
</glade-widget-group>
</glade-catalog>
+1
View File
@@ -163,6 +163,7 @@
#include <gtk/gtkrecentchooserwidget.h>
#include <gtk/gtkrecentfilter.h>
#include <gtk/gtkrecentmanager.h>
#include <gtk/gtkrevealer.h>
#include <gtk/gtkscale.h>
#include <gtk/gtkscalebutton.h>
#include <gtk/gtkscrollable.h>
+37
View File
@@ -288,6 +288,7 @@ gtk_assistant_set_page_title
gtk_assistant_set_page_type
gtk_assistant_update_buttons_state
gtk_attach_options_get_type
gtk_baseline_position_get_type
gtk_binding_entry_add_signal
gtk_binding_entry_add_signall
gtk_binding_entry_add_signal_from_string
@@ -308,6 +309,7 @@ gtk_border_free
gtk_border_get_type
gtk_border_new
gtk_border_style_get_type
gtk_box_get_baseline_position
gtk_box_get_homogeneous
gtk_box_get_spacing
gtk_box_get_type
@@ -316,6 +318,7 @@ gtk_box_pack_end
gtk_box_pack_start
gtk_box_query_child_packing
gtk_box_reorder_child
gtk_box_set_baseline_position
gtk_box_set_child_packing
gtk_box_set_homogeneous
gtk_box_set_spacing
@@ -1199,9 +1202,11 @@ gtk_grab_get_current
gtk_grab_remove
gtk_grid_attach
gtk_grid_attach_next_to
gtk_grid_get_baseline_row
gtk_grid_get_child_at
gtk_grid_get_column_homogeneous
gtk_grid_get_column_spacing
gtk_grid_get_row_baseline_position
gtk_grid_get_row_homogeneous
gtk_grid_get_row_spacing
gtk_grid_get_type
@@ -1211,8 +1216,10 @@ gtk_grid_insert_row
gtk_grid_new
gtk_grid_remove_column
gtk_grid_remove_row
gtk_grid_set_baseline_row
gtk_grid_set_column_homogeneous
gtk_grid_set_column_spacing
gtk_grid_set_row_baseline_position
gtk_grid_set_row_homogeneous
gtk_grid_set_row_spacing
gtk_handle_box_get_child_detached
@@ -1895,6 +1902,21 @@ gtk_parse_args
gtk_path_bar_get_type
gtk_path_priority_type_get_type
gtk_path_type_get_type
gtk_places_open_flags_get_type
gtk_places_sidebar_add_shortcut
gtk_places_sidebar_get_location
gtk_places_sidebar_get_nth_bookmark
gtk_places_sidebar_get_open_flags
gtk_places_sidebar_get_show_connect_to_server
gtk_places_sidebar_get_show_desktop
gtk_places_sidebar_get_type
gtk_places_sidebar_list_shortcuts
gtk_places_sidebar_new
gtk_places_sidebar_remove_shortcut
gtk_places_sidebar_set_location
gtk_places_sidebar_set_open_flags
gtk_places_sidebar_set_show_connect_to_server
gtk_places_sidebar_set_show_desktop
#ifdef G_OS_UNIX
gtk_plug_construct
gtk_plug_construct_for_display
@@ -2424,6 +2446,16 @@ gtk_requisition_get_type
gtk_requisition_new
gtk_resize_mode_get_type
gtk_response_type_get_type
gtk_revealer_new
gtk_revealer_get_type
gtk_revealer_get_reveal_child
gtk_revealer_set_reveal_child
gtk_revealer_get_child_revealed
gtk_revealer_get_transition_duration
gtk_revealer_set_transition_duration
gtk_revealer_get_transition_type
gtk_revealer_set_transition_type
gtk_revealer_transition_type_get_type
gtk_rgb_to_hsv
gtk_scale_accessible_get_type
gtk_scale_add_mark
@@ -3737,6 +3769,7 @@ gtk_widget_error_bell
gtk_widget_event
gtk_widget_freeze_child_notify
gtk_widget_get_accessible
gtk_widget_get_allocated_baseline
gtk_widget_get_allocated_height
gtk_widget_get_allocated_width
gtk_widget_get_allocation
@@ -3779,8 +3812,10 @@ gtk_widget_get_parent_window
gtk_widget_get_path
gtk_widget_get_pointer
gtk_widget_get_preferred_height
gtk_widget_get_preferred_height_and_baseline_for_width
gtk_widget_get_preferred_height_for_width
gtk_widget_get_preferred_size
gtk_widget_get_preferred_size_and_baseline
gtk_widget_get_preferred_width
gtk_widget_get_preferred_width_for_height
gtk_widget_get_realized
@@ -3803,6 +3838,7 @@ gtk_widget_get_tooltip_window
gtk_widget_get_toplevel
gtk_widget_get_type
gtk_widget_get_valign
gtk_widget_get_valign_with_baseline
gtk_widget_get_vexpand
gtk_widget_get_vexpand_set
gtk_widget_get_visible
@@ -3956,6 +3992,7 @@ gtk_widget_show
gtk_widget_show_all
gtk_widget_show_now
gtk_widget_size_allocate
gtk_widget_size_allocate_with_baseline
gtk_widget_size_request
gtk_widget_style_attach
gtk_widget_style_get
+70 -12
View File
@@ -108,6 +108,12 @@ static void gtk_alignment_get_preferred_height_for_width (GtkWidget *w
gint for_size,
gint *minimum_size,
gint *natural_size);
static void gtk_alignment_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline);
G_DEFINE_TYPE (GtkAlignment, gtk_alignment, GTK_TYPE_BIN)
@@ -128,6 +134,7 @@ gtk_alignment_class_init (GtkAlignmentClass *class)
widget_class->get_preferred_height = gtk_alignment_get_preferred_height;
widget_class->get_preferred_width_for_height = gtk_alignment_get_preferred_width_for_height;
widget_class->get_preferred_height_for_width = gtk_alignment_get_preferred_height_for_width;
widget_class->get_preferred_height_and_baseline_for_width = gtk_alignment_get_preferred_height_and_baseline_for_width;
g_object_class_install_property (gobject_class,
PROP_XALIGN,
@@ -507,6 +514,7 @@ gtk_alignment_size_allocate (GtkWidget *widget,
gint width, height;
guint border_width;
gint padding_horizontal, padding_vertical;
gint baseline;
padding_horizontal = 0;
padding_vertical = 0;
@@ -520,6 +528,7 @@ gtk_alignment_size_allocate (GtkWidget *widget,
gint child_nat_width;
gint child_nat_height;
gint child_width, child_height;
double yalign, yscale;
border_width = gtk_container_get_border_width (GTK_CONTAINER (alignment));
@@ -529,6 +538,25 @@ gtk_alignment_size_allocate (GtkWidget *widget,
width = MAX (1, allocation->width - padding_horizontal - 2 * border_width);
height = MAX (1, allocation->height - padding_vertical - 2 * border_width);
baseline = gtk_widget_get_allocated_baseline (widget);
if (baseline != -1)
baseline -= border_width + priv->padding_top;
/* If we get a baseline set that means we're baseline aligned, and the parent
honored that. In that case we have to ignore yalign/yscale as we need
yalign based on the baseline and always FILL mode to ensure we can place
the baseline anywhere */
if (baseline != -1)
{
yalign = 0;
yscale = 1.0;
}
else
{
yalign = priv->yalign;
yscale = priv->yscale;
}
if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
gtk_widget_get_preferred_width (child, NULL, &child_nat_width);
@@ -559,8 +587,8 @@ gtk_alignment_size_allocate (GtkWidget *widget,
if (height > child_height)
child_allocation.height = (child_height *
(1.0 - priv->yscale) +
height * priv->yscale);
(1.0 - yscale) +
height * yscale);
else
child_allocation.height = height;
@@ -569,9 +597,9 @@ gtk_alignment_size_allocate (GtkWidget *widget,
else
child_allocation.x = priv->xalign * (width - child_allocation.width) + allocation->x + border_width + priv->padding_left;
child_allocation.y = priv->yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding_top;
child_allocation.y = yalign * (height - child_allocation.height) + allocation->y + border_width + priv->padding_top;
gtk_widget_size_allocate (child, &child_allocation);
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
}
}
@@ -581,18 +609,30 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
GtkOrientation orientation,
gint for_size,
gint *minimum_size,
gint *natural_size)
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkAlignment *alignment = GTK_ALIGNMENT (widget);
GtkAlignmentPrivate *priv = alignment->priv;
GtkWidget *child;
guint minimum, natural;
guint top_offset;
guint border;
natural = minimum = gtk_container_get_border_width (GTK_CONTAINER (widget)) * 2;
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
border = gtk_container_get_border_width (GTK_CONTAINER (widget));
natural = minimum = border * 2;
top_offset = border;
if ((child = gtk_bin_get_child (GTK_BIN (widget))) && gtk_widget_get_visible (child))
{
gint child_min, child_nat;
gint child_min_baseline = -1, child_nat_baseline = -1;
/* Request extra space for the padding: */
if (orientation == GTK_ORIENTATION_HORIZONTAL)
@@ -619,9 +659,10 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
else
{
minimum += (priv->padding_top + priv->padding_bottom);
top_offset += priv->padding_top;
if (for_size < 0)
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
gtk_widget_get_preferred_height_and_baseline_for_width (child, -1, &child_min, &child_nat, &child_min_baseline, &child_nat_baseline);
else
{
gint min_width;
@@ -634,8 +675,13 @@ gtk_alignment_get_preferred_size (GtkWidget *widget,
for_size = (min_width * (1.0 - priv->xscale) +
for_size * priv->xscale);
gtk_widget_get_preferred_height_for_width (child, for_size, &child_min, &child_nat);
gtk_widget_get_preferred_height_and_baseline_for_width (child, for_size, &child_min, &child_nat, &child_min_baseline, &child_nat_baseline);
}
if (minimum_baseline && child_min_baseline >= 0)
*minimum_baseline = child_min_baseline + top_offset;
if (natural_baseline && child_nat_baseline >= 0)
*natural_baseline = child_nat_baseline + top_offset;
}
natural = minimum;
@@ -656,7 +702,7 @@ gtk_alignment_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size);
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -664,7 +710,7 @@ gtk_alignment_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size);
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size, NULL, NULL);
}
@@ -674,7 +720,7 @@ gtk_alignment_get_preferred_width_for_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size);
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -683,9 +729,21 @@ gtk_alignment_get_preferred_height_for_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size);
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, NULL, NULL);
}
static void
gtk_alignment_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
gtk_alignment_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, minimum_baseline, natural_baseline);
}
/**
* gtk_alignment_set_padding:
* @alignment: a #GtkAlignment
+161 -23
View File
@@ -101,6 +101,12 @@ static void gtk_button_box_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural);
static void gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline);
static void gtk_button_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
@@ -143,6 +149,7 @@ gtk_button_box_class_init (GtkButtonBoxClass *class)
widget_class->get_preferred_height = gtk_button_box_get_preferred_height;
widget_class->get_preferred_width_for_height = gtk_button_box_get_preferred_width_for_height;
widget_class->get_preferred_height_for_width = gtk_button_box_get_preferred_height_for_width;
widget_class->get_preferred_height_and_baseline_for_width = gtk_button_box_get_preferred_height_and_baseline_for_width;
widget_class->size_allocate = gtk_button_box_size_allocate;
container_class->remove = gtk_button_box_remove;
@@ -438,7 +445,10 @@ gtk_button_box_child_requisition (GtkWidget *widget,
gint *nvis_children,
gint *nvis_secondaries,
gint **widths,
gint **heights)
gint **heights,
gint **baselines,
gint *baseline,
gint *baseline_height)
{
GtkButtonBox *bbox;
GList *children, *list;
@@ -446,6 +456,7 @@ gtk_button_box_child_requisition (GtkWidget *widget,
gint nsecondaries;
gint needed_width;
gint needed_height;
gint needed_above, needed_below;
gint avg_w, avg_h;
GtkRequisition child_requisition;
gint ipad_w;
@@ -456,11 +467,15 @@ gtk_button_box_child_requisition (GtkWidget *widget,
gint ipad_y;
gboolean homogeneous;
gint i;
gint max_above, max_below, child_baseline;
GtkOrientation orientation;
gboolean have_baseline;
g_return_if_fail (GTK_IS_BUTTON_BOX (widget));
bbox = GTK_BUTTON_BOX (widget);
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget));
homogeneous = gtk_box_get_homogeneous (GTK_BOX (widget));
gtk_widget_style_get (widget,
@@ -475,22 +490,33 @@ gtk_button_box_child_requisition (GtkWidget *widget,
list = children = _gtk_box_get_children (GTK_BOX (bbox));
needed_width = child_min_width;
needed_height = child_min_height;
needed_above = 0;
needed_below = 0;
ipad_w = ipad_x * 2;
ipad_h = ipad_y * 2;
have_baseline = FALSE;
max_above = max_below = 0;
avg_w = avg_h = 0;
while (children)
for (children = list; children != NULL; children = children->next)
{
GtkWidget *child;
child = children->data;
children = children->next;
if (gtk_widget_get_visible (child))
{
nchildren += 1;
gtk_widget_get_preferred_size (child,
&child_requisition, NULL);
gtk_widget_get_preferred_size_and_baseline (child,
&child_requisition, NULL, &child_baseline, NULL);
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
child_baseline != -1)
{
have_baseline = TRUE;
max_above = MAX (max_above, child_baseline + ipad_y);
max_below = MAX (max_below , child_requisition.height + ipad_h - (child_baseline + ipad_y));
}
avg_w += child_requisition.width + ipad_w;
avg_h += child_requisition.height + ipad_h;
}
@@ -498,8 +524,14 @@ gtk_button_box_child_requisition (GtkWidget *widget,
avg_w /= MAX (nchildren, 1);
avg_h /= MAX (nchildren, 1);
if (baseline)
*baseline = have_baseline ? max_above : -1;
if (baseline_height)
*baseline_height = max_above + max_below;
*widths = g_new (gint, nchildren);
*heights = g_new (gint, nchildren);
*baselines = g_new (gint, nchildren);
i = 0;
children = list;
@@ -520,7 +552,8 @@ gtk_button_box_child_requisition (GtkWidget *widget,
if (is_secondary)
nsecondaries++;
gtk_widget_get_preferred_size (child, &child_requisition, NULL);
gtk_widget_get_preferred_size_and_baseline (child,
&child_requisition, NULL, &child_baseline, NULL);
if (homogeneous ||
(!non_homogeneous && (child_requisition.width + ipad_w < avg_w * 1.5)))
@@ -534,16 +567,38 @@ gtk_button_box_child_requisition (GtkWidget *widget,
(*widths)[i] = child_requisition.width + ipad_w;
}
(*baselines)[i] = -1;
if (homogeneous ||
(!non_homogeneous && (child_requisition.height + ipad_h < avg_h * 1.5)))
{
(*heights)[i] = -1;
if (child_requisition.height + ipad_h > needed_height)
needed_height = child_requisition.height + ipad_h;
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
child_baseline != -1)
{
(*baselines)[i] = child_baseline + ipad_y;
if (child_baseline + ipad_y > needed_above)
needed_above = child_baseline + ipad_y;
if (child_requisition.height - child_baseline + ipad_y > needed_below)
needed_below = child_requisition.height - child_baseline + ipad_y;
}
else
{
if (child_requisition.height + ipad_h > needed_height)
needed_height = child_requisition.height + ipad_h;
}
}
else
{
(*heights)[i] = child_requisition.height + ipad_h;
if (orientation == GTK_ORIENTATION_HORIZONTAL &&
gtk_widget_get_valign_with_baseline (child) == GTK_ALIGN_BASELINE &&
child_baseline != -1)
(*baselines)[i] = child_baseline + ipad_y;
}
i++;
@@ -552,12 +607,18 @@ gtk_button_box_child_requisition (GtkWidget *widget,
g_list_free (list);
needed_height = MAX (needed_height, needed_above + needed_below);
for (i = 0; i < nchildren; i++)
{
if ((*widths)[i] == -1)
(*widths)[i] = needed_width;
if ((*heights)[i] == -1)
(*heights)[i] = needed_height;
{
(*heights)[i] = needed_height;
if ((*baselines)[i] != -1)
(*baselines)[i] = needed_above;
}
}
if (nvis_children)
@@ -569,19 +630,24 @@ gtk_button_box_child_requisition (GtkWidget *widget,
static void
gtk_button_box_size_request (GtkWidget *widget,
GtkRequisition *requisition)
GtkRequisition *requisition,
gint *baseline)
{
GtkButtonBoxPrivate *priv;
GtkButtonBox *bbox;
gint nvis_children;
gint max_size;
gint max_size, max_above, max_below;
gint total_size;
gint spacing;
GtkOrientation orientation;
gint *widths;
gint *heights;
gint *baselines;
gint i;
if (baseline)
*baseline = -1;
bbox = GTK_BUTTON_BOX (widget);
priv = bbox->priv;
@@ -591,16 +657,22 @@ gtk_button_box_size_request (GtkWidget *widget,
gtk_button_box_child_requisition (widget,
&nvis_children,
NULL,
&widths, &heights);
&widths, &heights, &baselines, baseline, NULL);
max_size = 0;
max_size = max_above = max_below = 0;
total_size = 0;
for (i = 0; i < nvis_children; i++)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
total_size += widths[i];
max_size = MAX (max_size, heights[i]);
if (baselines[i] == -1)
max_size = MAX (max_size, heights[i]);
else
{
max_above = MAX (max_above, baselines[i]);
max_below = MAX (max_below, heights[i] - baselines[i]);
}
}
else
{
@@ -610,6 +682,23 @@ gtk_button_box_size_request (GtkWidget *widget,
}
g_free (widths);
g_free (heights);
g_free (baselines);
max_size = MAX (max_size, max_above + max_below);
switch (gtk_box_get_baseline_position (GTK_BOX (widget)))
{
case GTK_BASELINE_POSITION_TOP:
break;
case GTK_BASELINE_POSITION_CENTER:
if (baseline != NULL && *baseline != -1)
*baseline += (max_size - (max_above + max_below)) / 2;
break;
case GTK_BASELINE_POSITION_BOTTOM:
if (baseline != NULL && *baseline != -1)
*baseline += max_size - (max_above + max_below);
break;
}
if (nvis_children == 0)
{
@@ -656,7 +745,7 @@ gtk_button_box_get_preferred_width (GtkWidget *widget,
{
GtkRequisition requisition;
gtk_button_box_size_request (widget, &requisition);
gtk_button_box_size_request (widget, &requisition, NULL);
*minimum = *natural = requisition.width;
}
@@ -666,11 +755,9 @@ gtk_button_box_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
GtkRequisition requisition;
gtk_button_box_size_request (widget, &requisition);
*minimum = *natural = requisition.height;
gtk_button_box_get_preferred_height_and_baseline_for_width (widget, -1,
minimum, natural,
NULL, NULL);
}
static void
@@ -691,6 +778,26 @@ gtk_button_box_get_preferred_height_for_width (GtkWidget *widget,
gtk_button_box_get_preferred_height (widget, minimum, natural);
}
static void
gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkRequisition requisition;
gint baseline;
gtk_button_box_size_request (widget, &requisition, &baseline);
*minimum = *natural = requisition.height;
if (minimum_baseline)
*minimum_baseline = baseline;
if (natural_baseline)
*natural_baseline = baseline;
}
static void
gtk_button_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
@@ -714,10 +821,13 @@ gtk_button_box_size_allocate (GtkWidget *widget,
gint ipad_x, ipad_y;
gint *widths;
gint *heights;
gint *baselines;
gint *sizes;
gint primary_size;
gint secondary_size;
gint total_size;
gint baseline, baseline_height;
gint child_baseline, allocated_baseline;
gint i;
bbox = GTK_BUTTON_BOX (widget);
@@ -733,7 +843,27 @@ gtk_button_box_size_allocate (GtkWidget *widget,
gtk_button_box_child_requisition (widget,
&nvis_children,
&n_secondaries,
&widths, &heights);
&widths, &heights, &baselines, &baseline, &baseline_height);
allocated_baseline = gtk_widget_get_allocated_baseline (widget);
if (allocated_baseline != -1)
baseline = allocated_baseline;
else if (baseline != -1)
{
/* TODO: modify baseline based on baseline_pos && allocated_baseline*/
switch (gtk_box_get_baseline_position (GTK_BOX (widget)))
{
case GTK_BASELINE_POSITION_TOP:
baseline = baseline;
break;
case GTK_BASELINE_POSITION_CENTER:
baseline = baseline + (allocation->height - baseline_height) / 2;
break;
case GTK_BASELINE_POSITION_BOTTOM:
baseline = allocation->height - (baseline_height - baseline);
break;
}
}
n_primaries = nvis_children - n_secondaries;
primary_size = 0;
@@ -917,10 +1047,17 @@ gtk_button_box_size_allocate (GtkWidget *widget,
{
child_allocation.width = widths[i];
child_allocation.height = heights[i];
child_baseline = -1;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
if (baselines[i] != -1)
{
child_allocation.y = allocation->y + baseline - baselines[i];
child_baseline = baselines[i];
}
else
child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
if (gtk_button_box_get_child_secondary (bbox, child))
{
@@ -953,7 +1090,7 @@ gtk_button_box_size_allocate (GtkWidget *widget,
}
}
gtk_widget_size_allocate (child, &child_allocation);
gtk_widget_size_allocate_with_baseline (child, &child_allocation, child_baseline);
i++;
}
}
@@ -961,6 +1098,7 @@ gtk_button_box_size_allocate (GtkWidget *widget,
g_list_free (list);
g_free (widths);
g_free (heights);
g_free (baselines);
}
/**
+337 -54
View File
@@ -94,7 +94,8 @@ enum {
PROP_0,
PROP_ORIENTATION,
PROP_SPACING,
PROP_HOMOGENEOUS
PROP_HOMOGENEOUS,
PROP_BASELINE_POSITION
};
enum {
@@ -116,6 +117,7 @@ struct _GtkBoxPrivate
guint default_expand : 1;
guint homogeneous : 1;
guint spacing_set : 1;
guint baseline_pos : 2;
};
typedef struct _GtkBoxChild GtkBoxChild;
@@ -200,6 +202,12 @@ static void gtk_box_get_preferred_height_for_width (GtkWidget
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height,
gint *minimum_baseline,
gint *natural_baseline);
G_DEFINE_TYPE_WITH_CODE (GtkBox, gtk_box, GTK_TYPE_CONTAINER,
@@ -220,6 +228,7 @@ gtk_box_class_init (GtkBoxClass *class)
widget_class->get_preferred_width = gtk_box_get_preferred_width;
widget_class->get_preferred_height = gtk_box_get_preferred_height;
widget_class->get_preferred_height_for_width = gtk_box_get_preferred_height_for_width;
widget_class->get_preferred_height_and_baseline_for_width = gtk_box_get_preferred_height_and_baseline_for_width;
widget_class->get_preferred_width_for_height = gtk_box_get_preferred_width_for_height;
widget_class->compute_expand = gtk_box_compute_expand;
widget_class->direction_changed = gtk_box_direction_changed;
@@ -255,6 +264,15 @@ gtk_box_class_init (GtkBoxClass *class)
FALSE,
GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_BASELINE_POSITION,
g_param_spec_enum ("baseline-position",
P_("Baseline position"),
P_("The position of the baseline aligned widgets if extra space is availible"),
GTK_TYPE_BASELINE_POSITION,
GTK_BASELINE_POSITION_CENTER,
GTK_PARAM_READWRITE));
/**
* GtkBox:expand:
*
@@ -340,6 +358,7 @@ gtk_box_init (GtkBox *box)
private->homogeneous = FALSE;
private->spacing = 0;
private->spacing_set = FALSE;
private->baseline_pos = GTK_BASELINE_POSITION_CENTER;
}
static void
@@ -361,6 +380,9 @@ gtk_box_set_property (GObject *object,
case PROP_SPACING:
gtk_box_set_spacing (box, g_value_get_int (value));
break;
case PROP_BASELINE_POSITION:
gtk_box_set_baseline_position (box, g_value_get_enum (value));
break;
case PROP_HOMOGENEOUS:
gtk_box_set_homogeneous (box, g_value_get_boolean (value));
break;
@@ -387,6 +409,9 @@ gtk_box_get_property (GObject *object,
case PROP_SPACING:
g_value_set_int (value, private->spacing);
break;
case PROP_BASELINE_POSITION:
g_value_set_enum (value, private->baseline_pos);
break;
case PROP_HOMOGENEOUS:
g_value_set_boolean (value, private->homogeneous);
break;
@@ -435,6 +460,11 @@ gtk_box_size_allocate (GtkWidget *widget,
GtkTextDirection direction;
GtkAllocation child_allocation;
GtkRequestedSize *sizes;
gint child_minimum_baseline, child_natural_baseline;
gint minimum_above, natural_above;
gint minimum_below, natural_below;
gboolean have_baseline;
gint baseline;
GtkPackType packing;
@@ -461,6 +491,10 @@ gtk_box_size_allocate (GtkWidget *widget,
else
size = allocation->height - (nvis_children - 1) * private->spacing;
have_baseline = FALSE;
minimum_above = natural_above = 0;
minimum_below = natural_below = 0;
/* Retrieve desired size for visible children. */
for (i = 0, children = private->children; children; children = children->next)
{
@@ -475,11 +509,11 @@ gtk_box_size_allocate (GtkWidget *widget,
&sizes[i].minimum_size,
&sizes[i].natural_size);
else
gtk_widget_get_preferred_height_for_width (child->widget,
allocation->width,
&sizes[i].minimum_size,
&sizes[i].natural_size);
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget,
allocation->width,
&sizes[i].minimum_size,
&sizes[i].natural_size,
NULL, NULL);
/* Assert the api is working properly */
if (sizes[i].minimum_size < 0)
@@ -537,28 +571,9 @@ gtk_box_size_allocate (GtkWidget *widget,
extra = 0;
}
/* Allocate child positions. */
/* Allocate child sizes. */
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
{
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
{
child_allocation.y = allocation->y;
child_allocation.height = MAX (1, allocation->height);
if (packing == GTK_PACK_START)
x = allocation->x;
else
x = allocation->x + allocation->width;
}
else
{
child_allocation.x = allocation->x;
child_allocation.width = MAX (1, allocation->width);
if (packing == GTK_PACK_START)
y = allocation->y;
else
y = allocation->y + allocation->height;
}
for (i = 0, children = private->children;
children;
children = children->next)
@@ -605,6 +620,105 @@ gtk_box_size_allocate (GtkWidget *widget,
}
}
sizes[i].natural_size = child_size;
if (private->orientation == GTK_ORIENTATION_HORIZONTAL &&
gtk_widget_get_valign_with_baseline (child->widget) == GTK_ALIGN_BASELINE)
{
int child_allocation_width;
int child_minimum_height, child_natural_height;
if (child->fill)
child_allocation_width = MAX (1, child_size - child->padding * 2);
else
child_allocation_width = sizes[i].minimum_size;
child_minimum_baseline = -1;
child_natural_baseline = -1;
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget,
child_allocation_width,
&child_minimum_height, &child_natural_height,
&child_minimum_baseline, &child_natural_baseline);
if (child_minimum_baseline >= 0)
{
have_baseline = TRUE;
minimum_below = MAX (minimum_below, child_minimum_height - child_minimum_baseline);
natural_below = MAX (natural_below, child_natural_height - child_natural_baseline);
minimum_above = MAX (minimum_above, child_minimum_baseline);
natural_above = MAX (natural_above, child_natural_baseline);
}
}
i++;
}
}
baseline = gtk_widget_get_allocated_baseline (widget);
if (baseline == -1 && have_baseline)
{
gint height = MAX (1, allocation->height);
/* TODO: This is purely based on the minimum baseline, when things fit we should
use the natural one? */
switch (private->baseline_pos)
{
case GTK_BASELINE_POSITION_TOP:
baseline = minimum_above;
break;
case GTK_BASELINE_POSITION_CENTER:
baseline = minimum_above + (height - (minimum_above + minimum_below)) / 2;
break;
case GTK_BASELINE_POSITION_BOTTOM:
baseline = height - minimum_below;
break;
}
}
/* Allocate child positions. */
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
{
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
{
child_allocation.y = allocation->y;
child_allocation.height = MAX (1, allocation->height);
if (packing == GTK_PACK_START)
x = allocation->x;
else
x = allocation->x + allocation->width;
}
else
{
child_allocation.x = allocation->x;
child_allocation.width = MAX (1, allocation->width);
if (packing == GTK_PACK_START)
y = allocation->y;
else
y = allocation->y + allocation->height;
}
for (i = 0, children = private->children;
children;
children = children->next)
{
child = children->data;
/* If widget is not visible, skip it. */
if (!gtk_widget_get_visible (child->widget))
continue;
/* If widget is packed differently skip it, but still increment i,
* since widget is visible and will be handled in next loop iteration.
*/
if (child->pack != packing)
{
i++;
continue;
}
child_size = sizes[i].natural_size;
/* Assign the child's position. */
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
{
@@ -658,7 +772,7 @@ gtk_box_size_allocate (GtkWidget *widget,
child_allocation.y -= child_size;
}
}
gtk_widget_size_allocate (child->widget, &child_allocation);
gtk_widget_size_allocate_with_baseline (child->widget, &child_allocation, baseline);
i++;
}
@@ -677,10 +791,7 @@ gtk_box_compute_expand (GtkWidget *widget,
gboolean opposite_expand;
GtkOrientation opposite_orientation;
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
opposite_orientation = GTK_ORIENTATION_VERTICAL;
else
opposite_orientation = GTK_ORIENTATION_HORIZONTAL;
opposite_orientation = OPPOSITE_ORIENTATION (private->orientation);
our_expand = FALSE;
opposite_expand = FALSE;
@@ -1015,18 +1126,28 @@ static void
gtk_box_get_size (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBox *box;
GtkBoxPrivate *private;
GList *children;
gint nvis_children;
gint minimum, natural;
gint minimum_above, natural_above;
gint minimum_below, natural_below;
gboolean have_baseline;
gint min_baseline, nat_baseline;
box = GTK_BOX (widget);
private = box->priv;
have_baseline = FALSE;
minimum = natural = 0;
minimum_above = natural_above = 0;
minimum_below = natural_below = 0;
min_baseline = nat_baseline = -1;
nvis_children = 0;
@@ -1037,13 +1158,15 @@ gtk_box_get_size (GtkWidget *widget,
if (gtk_widget_get_visible (child->widget))
{
gint child_minimum, child_natural;
gint child_minimum_baseline = -1, child_natural_baseline = -1;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_widget_get_preferred_width (child->widget,
&child_minimum, &child_natural);
else
gtk_widget_get_preferred_height (child->widget,
&child_minimum, &child_natural);
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget, -1,
&child_minimum, &child_natural,
&child_minimum_baseline, &child_natural_baseline);
if (private->orientation == orientation)
{
@@ -1065,9 +1188,20 @@ gtk_box_get_size (GtkWidget *widget,
}
else
{
/* The biggest mins and naturals in the opposing orientation */
minimum = MAX (minimum, child_minimum);
natural = MAX (natural, child_natural);
if (child_minimum_baseline >= 0)
{
have_baseline = TRUE;
minimum_below = MAX (minimum_below, child_minimum - child_minimum_baseline);
natural_below = MAX (natural_below, child_natural - child_natural_baseline);
minimum_above = MAX (minimum_above, child_minimum_baseline);
natural_above = MAX (natural_above, child_natural_baseline);
}
else
{
/* The biggest mins and naturals in the opposing orientation */
minimum = MAX (minimum, child_minimum);
natural = MAX (natural, child_natural);
}
}
nvis_children += 1;
@@ -1085,11 +1219,39 @@ gtk_box_get_size (GtkWidget *widget,
natural += (nvis_children - 1) * private->spacing;
}
minimum = MAX (minimum, minimum_below + minimum_above);
natural = MAX (natural, natural_below + natural_above);
if (have_baseline)
{
switch (private->baseline_pos)
{
case GTK_BASELINE_POSITION_TOP:
min_baseline = minimum_above;
nat_baseline = natural_above;
break;
case GTK_BASELINE_POSITION_CENTER:
min_baseline = minimum_above + (minimum - (minimum_above + minimum_below)) / 2;
nat_baseline = natural_above + (natural - (natural_above + natural_below)) / 2;
break;
case GTK_BASELINE_POSITION_BOTTOM:
min_baseline = minimum - minimum_below;
nat_baseline = natural - natural_below;
break;
}
}
if (minimum_size)
*minimum_size = minimum;
if (natural_size)
*natural_size = natural;
if (minimum_baseline)
*minimum_baseline = min_baseline;
if (natural_baseline)
*natural_baseline = nat_baseline;
}
static void
@@ -1097,7 +1259,7 @@ gtk_box_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_box_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
gtk_box_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -1105,14 +1267,16 @@ gtk_box_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
}
static void
gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
gint avail_size,
gint *minimum_size,
gint *natural_size)
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBoxPrivate *private = box->priv;
GtkBoxChild *child;
@@ -1120,11 +1284,16 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
gint nvis_children;
gint nexpand_children;
gint computed_minimum = 0, computed_natural = 0;
gint computed_minimum_above = 0, computed_natural_above = 0;
gint computed_minimum_below = 0, computed_natural_below = 0;
gint computed_minimum_baseline = -1, computed_natural_baseline = -1;
GtkRequestedSize *sizes;
GtkPackType packing;
gint size, extra, i;
gint child_size, child_minimum, child_natural;
gint child_minimum_baseline, child_natural_baseline;
gint n_extra_widgets = 0;
gboolean have_baseline;
count_expand_children (box, &nvis_children, &nexpand_children);
@@ -1199,6 +1368,7 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
extra = 0;
}
have_baseline = FALSE;
/* Allocate child positions. */
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
{
@@ -1260,26 +1430,64 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
}
child_minimum_baseline = child_natural_baseline = -1;
/* Assign the child's position. */
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_widget_get_preferred_height_for_width (child->widget,
child_size, &child_minimum, &child_natural);
gtk_widget_get_preferred_height_and_baseline_for_width (child->widget, child_size,
&child_minimum, &child_natural,
&child_minimum_baseline, &child_natural_baseline);
else /* (private->orientation == GTK_ORIENTATION_VERTICAL) */
gtk_widget_get_preferred_width_for_height (child->widget,
child_size, &child_minimum, &child_natural);
computed_minimum = MAX (computed_minimum, child_minimum);
computed_natural = MAX (computed_natural, child_natural);
if (child_minimum_baseline >= 0)
{
have_baseline = TRUE;
computed_minimum_below = MAX (computed_minimum_below, child_minimum - child_minimum_baseline);
computed_natural_below = MAX (computed_natural_below, child_natural - child_natural_baseline);
computed_minimum_above = MAX (computed_minimum_above, child_minimum_baseline);
computed_natural_above = MAX (computed_natural_above, child_natural_baseline);
}
else
{
computed_minimum = MAX (computed_minimum, child_minimum);
computed_natural = MAX (computed_natural, child_natural);
}
}
i += 1;
}
}
if (have_baseline)
{
computed_minimum = MAX (computed_minimum, computed_minimum_below + computed_minimum_above);
computed_natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
switch (private->baseline_pos)
{
case GTK_BASELINE_POSITION_TOP:
computed_minimum_baseline = computed_minimum_above;
computed_natural_baseline = computed_natural_above;
break;
case GTK_BASELINE_POSITION_CENTER:
computed_minimum_baseline = computed_minimum_above + MAX((computed_minimum - (computed_minimum_above + computed_minimum_below)) / 2, 0);
computed_natural_baseline = computed_natural_above + MAX((computed_natural - (computed_natural_above + computed_natural_below)) / 2, 0);
break;
case GTK_BASELINE_POSITION_BOTTOM:
computed_minimum_baseline = computed_minimum - computed_minimum_below;
computed_natural_baseline = computed_natural - computed_natural_below;
break;
}
}
if (minimum_baseline)
*minimum_baseline = computed_minimum_baseline;
if (natural_baseline)
*natural_baseline = computed_natural_baseline;
if (minimum_size)
*minimum_size = computed_minimum;
if (natural_size)
*natural_size = computed_natural;
*natural_size = MAX (computed_natural, computed_natural_below + computed_natural_above);
}
static void
@@ -1355,24 +1563,46 @@ gtk_box_get_preferred_width_for_height (GtkWidget *widget,
GtkBoxPrivate *private = box->priv;
if (private->orientation == GTK_ORIENTATION_VERTICAL)
gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width);
gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width, NULL, NULL);
else
gtk_box_compute_size_for_orientation (box, height, minimum_width, natural_width);
}
static void
gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBox *box = GTK_BOX (widget);
GtkBoxPrivate *private = box->priv;
if (width < 0)
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_height, natural_height, minimum_baseline, natural_baseline);
else
{
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height, minimum_baseline, natural_baseline);
else
{
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
gtk_box_compute_size_for_orientation (box, width, minimum_height, natural_height);
}
}
}
static void
gtk_box_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height)
{
GtkBox *box = GTK_BOX (widget);
GtkBoxPrivate *private = box->priv;
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height);
else
gtk_box_compute_size_for_orientation (box, width, minimum_height, natural_height);
gtk_box_get_preferred_height_and_baseline_for_width (widget, width, minimum_height, natural_height, NULL, NULL);
}
/**
@@ -1550,6 +1780,59 @@ gtk_box_get_spacing (GtkBox *box)
return box->priv->spacing;
}
/**
* gtk_box_set_baseline_position:
* @box: a #GtkBox
* @position: a #GtkBaselinePosition
*
* Sets the baseline position of a box. This affects
* only horizontal boxes with at least one baseline aligned
* child. If there is more vertical space availible than requested,
* and the baseline is not allocated by the parent then
* @position is used to allocate the baseline wrt the
* extra space available.
*
* Since: 3.10
*/
void
gtk_box_set_baseline_position (GtkBox *box,
GtkBaselinePosition position)
{
GtkBoxPrivate *private;
g_return_if_fail (GTK_IS_BOX (box));
private = box->priv;
if (position != private->baseline_pos)
{
private->baseline_pos = position;
g_object_notify (G_OBJECT (box), "baseline-position");
gtk_widget_queue_resize (GTK_WIDGET (box));
}
}
/**
* gtk_box_get_baseline_position:
* @box: a #GtkBox
*
* Gets the value set by gtk_box_set_baseline_position().
*
* Return value: the baseline position
*
* Since: 3.10
**/
GtkBaselinePosition
gtk_box_get_baseline_position (GtkBox *box)
{
g_return_val_if_fail (GTK_IS_BOX (box), GTK_BASELINE_POSITION_CENTER);
return box->priv->baseline_pos;
}
void
_gtk_box_set_spacing_set (GtkBox *box,
gboolean spacing_set)
+5
View File
@@ -89,6 +89,11 @@ gboolean gtk_box_get_homogeneous (GtkBox *box);
void gtk_box_set_spacing (GtkBox *box,
gint spacing);
gint gtk_box_get_spacing (GtkBox *box);
GDK_AVAILABLE_IN_3_10
void gtk_box_set_baseline_position (GtkBox *box,
GtkBaselinePosition position);
GDK_AVAILABLE_IN_3_10
GtkBaselinePosition gtk_box_get_baseline_position (GtkBox *box);
void gtk_box_reorder_child (GtkBox *box,
GtkWidget *child,
+6 -7
View File
@@ -1015,19 +1015,19 @@ start_element (GMarkupParseContext *context,
element_name);
}
gchar *
const gchar *
_gtk_builder_parser_translate (const gchar *domain,
const gchar *context,
const gchar *text)
{
const char *s;
const gchar *s;
if (context)
s = g_dpgettext2 (domain, context, text);
else
s = g_dgettext (domain, text);
return g_strdup (s);
return s;
}
/* Called for close tags </foo> */
@@ -1128,15 +1128,14 @@ end_element (GMarkupParseContext *context,
if (prop_info->translatable && prop_info->text->len)
{
prop_info->data = _gtk_builder_parser_translate (data->domain,
prop_info->context,
prop_info->text->str);
prop_info->data = g_strdup (_gtk_builder_parser_translate (data->domain,
prop_info->context,
prop_info->text->str));
g_string_free (prop_info->text, TRUE);
}
else
{
prop_info->data = g_string_free (prop_info->text, FALSE);
}
object_info->properties =
+3 -3
View File
@@ -148,9 +148,9 @@ gboolean _gtk_builder_flags_from_string (GType type,
const char *string,
guint *value,
GError **error);
gchar * _gtk_builder_parser_translate (const gchar *domain,
const gchar *context,
const gchar *text);
const gchar * _gtk_builder_parser_translate (const gchar *domain,
const gchar *context,
const gchar *text);
gchar * _gtk_builder_get_resource_path (GtkBuilder *builder,
const gchar *string);
gchar * _gtk_builder_get_absolute_filename (GtkBuilder *builder,
+138 -80
View File
@@ -53,6 +53,7 @@
#include "gtkactivatable.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "a11y/gtkbuttonaccessible.h"
@@ -164,12 +165,26 @@ static void gtk_button_set_related_action (GtkButton *button,
static void gtk_button_set_use_action_appearance (GtkButton *button,
gboolean use_appearance);
static void gtk_button_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
static void gtk_button_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
static void gtk_button_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
static void gtk_button_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size);
static void gtk_button_get_preferred_width_for_height (GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size);
static void gtk_button_get_preferred_height_for_width (GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size);
static void gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum_size,
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline);
static guint button_signals[LAST_SIGNAL] = { 0 };
@@ -194,8 +209,11 @@ gtk_button_class_init (GtkButtonClass *klass)
gobject_class->set_property = gtk_button_set_property;
gobject_class->get_property = gtk_button_get_property;
widget_class->get_preferred_width = gtk_button_get_preferred_width;
widget_class->get_preferred_width = gtk_button_get_preferred_width;
widget_class->get_preferred_height = gtk_button_get_preferred_height;
widget_class->get_preferred_width_for_height = gtk_button_get_preferred_width_for_height;
widget_class->get_preferred_height_for_width = gtk_button_get_preferred_height_for_width;
widget_class->get_preferred_height_and_baseline_for_width = gtk_button_get_preferred_height_and_baseline_for_width;
widget_class->destroy = gtk_button_destroy;
widget_class->screen_changed = gtk_button_screen_changed;
widget_class->realize = gtk_button_realize;
@@ -1150,11 +1168,16 @@ gtk_button_construct_child (GtkButton *button)
else
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, image_spacing);
gtk_widget_set_valign (image, GTK_ALIGN_BASELINE);
gtk_widget_set_valign (box, GTK_ALIGN_BASELINE);
if (priv->align_set)
align = gtk_alignment_new (priv->xalign, priv->yalign, 0.0, 0.0);
else
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_widget_set_valign (align, GTK_ALIGN_BASELINE);
if (priv->image_position == GTK_POS_LEFT ||
priv->image_position == GTK_POS_TOP)
gtk_box_pack_start (GTK_BOX (box), priv->image, FALSE, FALSE, 0);
@@ -1172,6 +1195,8 @@ gtk_button_construct_child (GtkButton *button)
else
label = gtk_label_new (label_text);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
if (priv->image_position == GTK_POS_RIGHT ||
priv->image_position == GTK_POS_BOTTOM)
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
@@ -1196,6 +1221,8 @@ gtk_button_construct_child (GtkButton *button)
else
label = gtk_label_new (priv->label_text);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
if (priv->align_set)
gtk_misc_set_alignment (GTK_MISC (label), priv->xalign, priv->yalign);
@@ -1570,29 +1597,48 @@ gtk_button_get_props (GtkButton *button,
gtk_style_context_get_border (context, state, border);
}
/* Computes the size of the border around the button's child
* including all CSS and style properties so it can be used
* during size allocation and size request phases. */
static void
gtk_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
gtk_button_get_full_border (GtkButton *button,
GtkBorder *full_border)
{
GtkButton *button = GTK_BUTTON (widget);
GtkButtonPrivate *priv = button->priv;
GtkAllocation child_allocation;
GtkWidget *widget = GTK_WIDGET (button);
GtkStyleContext *context;
GtkWidget *child;
GtkBorder default_border;
GtkBorder padding;
GtkBorder border;
gint focus_width;
gint focus_pad;
GtkBorder default_border, padding, border;
int focus_width, focus_pad;
context = gtk_widget_get_style_context (widget);
gtk_button_get_props (button, &default_border, NULL,
&padding, &border, NULL);
gtk_style_context_get_style (context,
"focus-line-width", &focus_width,
"focus-padding", &focus_pad,
NULL);
"focus-line-width", &focus_width,
"focus-padding", &focus_pad,
NULL);
full_border->left = padding.left + border.left + focus_width + focus_pad;
full_border->right = padding.right + border.right + focus_width + focus_pad;
full_border->top = padding.top + border.top + focus_width + focus_pad;
full_border->bottom = padding.bottom + border.bottom + focus_width + focus_pad;
if (gtk_widget_get_can_default (GTK_WIDGET (button)))
{
full_border->left += default_border.left;
full_border->right += default_border.right;
full_border->top += default_border.top;
full_border->bottom += default_border.bottom;
}
}
static void
gtk_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkButton *button = GTK_BUTTON (widget);
GtkButtonPrivate *priv = button->priv;
GtkWidget *child;
gtk_widget_set_allocation (widget, allocation);
@@ -1606,52 +1652,40 @@ gtk_button_size_allocate (GtkWidget *widget,
child = gtk_bin_get_child (GTK_BIN (button));
if (child && gtk_widget_get_visible (child))
{
child_allocation.x = allocation->x + padding.left + border.left;
child_allocation.y = allocation->y + padding.top + border.top;
GtkAllocation child_allocation;
GtkBorder border;
gint baseline;
child_allocation.width =
allocation->width -
(padding.left + padding.right) -
(border.left + border.right);
gtk_button_get_full_border (button, &border);
child_allocation.height =
allocation->height -
(padding.top + padding.bottom) -
(border.top + border.bottom);
child_allocation.x = allocation->x + border.left;
child_allocation.y = allocation->y + border.top;
child_allocation.width = allocation->width - border.left - border.right;
child_allocation.height = allocation->height - border.top - border.bottom;
if (gtk_widget_get_can_default (GTK_WIDGET (button)))
{
child_allocation.x += default_border.left;
child_allocation.y += default_border.top;
child_allocation.width = child_allocation.width - default_border.left - default_border.right;
child_allocation.height = child_allocation.height - default_border.top - default_border.bottom;
}
if (gtk_widget_get_can_focus (GTK_WIDGET (button)))
{
child_allocation.x += focus_width + focus_pad;
child_allocation.y += focus_width + focus_pad;
child_allocation.width = child_allocation.width - (focus_width + focus_pad) * 2;
child_allocation.height = child_allocation.height - (focus_width + focus_pad) * 2;
}
baseline = gtk_widget_get_allocated_baseline (widget);
if (baseline != -1)
baseline -= border.top;
if (priv->depressed)
{
gint child_displacement_x;
gint child_displacement_y;
gtk_style_context_get_style (context,
gtk_style_context_get_style (gtk_widget_get_style_context (GTK_WIDGET (button)),
"child-displacement-x", &child_displacement_x,
"child-displacement-y", &child_displacement_y,
NULL);
child_allocation.x += child_displacement_x;
child_allocation.y += child_displacement_y;
if (baseline != -1)
baseline -= child_displacement_y;
}
child_allocation.width = MAX (1, child_allocation.width);
child_allocation.height = MAX (1, child_allocation.height);
gtk_widget_size_allocate (child, &child_allocation);
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
}
}
@@ -2062,57 +2096,52 @@ gtk_button_finish_activate (GtkButton *button,
static void
gtk_button_get_size (GtkWidget *widget,
GtkOrientation orientation,
gint for_size,
gint *minimum_size,
gint *natural_size)
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkButton *button = GTK_BUTTON (widget);
GtkStyleContext *context;
GtkWidget *child;
GtkBorder default_border;
GtkBorder padding;
GtkBorder border;
gint focus_width;
gint focus_pad;
gint minimum, natural;
context = gtk_widget_get_style_context (widget);
gtk_button_get_props (button, &default_border, NULL,
&padding, &border, NULL);
gtk_style_context_get_style (context,
"focus-line-width", &focus_width,
"focus-padding", &focus_pad,
NULL);
gtk_button_get_full_border (button, &border);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
minimum = padding.left + padding.right +
border.left + border.right;
minimum = border.left + border.right;
natural = minimum;
if (gtk_widget_get_can_default (GTK_WIDGET (widget)))
minimum += default_border.left + default_border.right;
if (for_size >= 0)
for_size -= border.top + border.bottom;
}
else
{
minimum = padding.top + padding.bottom +
border.top + border.bottom;
minimum = border.top + border.bottom;
natural = minimum;
if (gtk_widget_get_can_default (GTK_WIDGET (widget)))
minimum += default_border.top + default_border.bottom;
}
minimum += 2 * (focus_width + focus_pad);
natural = minimum;
if (for_size >= 0)
for_size -= border.left + border.right;
}
if ((child = gtk_bin_get_child (GTK_BIN (button))) &&
gtk_widget_get_visible (child))
{
gint child_min, child_nat;
gint child_min_baseline = -1, child_nat_baseline = -1;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_widget_get_preferred_width (child, &child_min, &child_nat);
else
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
_gtk_widget_get_preferred_size_for_size (child,
orientation,
for_size,
&child_min, &child_nat,
&child_min_baseline, &child_nat_baseline);
if (minimum_baseline && child_min_baseline >= 0)
*minimum_baseline = child_min_baseline + border.top;
if (natural_baseline && child_nat_baseline >= 0)
*natural_baseline = child_nat_baseline + border.top;
minimum += child_min;
natural += child_nat;
@@ -2130,7 +2159,7 @@ gtk_button_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -2138,7 +2167,36 @@ gtk_button_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size, NULL, NULL);
}
static void
gtk_button_get_preferred_width_for_height (GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size, NULL, NULL);
}
static void
gtk_button_get_preferred_height_for_width (GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, NULL, NULL);
}
static void
gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum_size,
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, width, minimum_size, natural_size, minimum_baseline, natural_baseline);
}
/**
+3
View File
@@ -39,6 +39,9 @@ struct _GtkButtonPrivate
gfloat xalign;
gfloat yalign;
/* This is only used by checkbox and subclasses */
gfloat baseline_align;
guint activate_timeout;
guint32 grab_time;
-4
View File
@@ -239,10 +239,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkCellAreaBox, gtk_cell_area_box, GTK_TYPE_CELL_AREA,
gtk_cell_area_box_cell_layout_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL));
#define OPPOSITE_ORIENTATION(orientation) \
((orientation) == GTK_ORIENTATION_HORIZONTAL ? \
GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL)
static void
gtk_cell_area_box_init (GtkCellAreaBox *box)
{
+1 -1
View File
@@ -812,7 +812,7 @@ cell_packing_end_element (GMarkupParseContext *context,
/* translate the string */
if (parser_data->string->len && parser_data->translatable)
{
gchar *translated;
const gchar *translated;
const gchar* domain;
domain = gtk_builder_get_translation_domain (parser_data->builder);
+69 -7
View File
@@ -58,6 +58,12 @@ static void gtk_check_button_get_preferred_width (GtkWidget *widget,
static void gtk_check_button_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural);
static void gtk_check_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline);
static void gtk_check_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean gtk_check_button_draw (GtkWidget *widget,
@@ -80,6 +86,7 @@ gtk_check_button_class_init (GtkCheckButtonClass *class)
widget_class->get_preferred_width = gtk_check_button_get_preferred_width;
widget_class->get_preferred_height = gtk_check_button_get_preferred_height;
widget_class->get_preferred_height_and_baseline_for_width = gtk_check_button_get_preferred_height_and_baseline_for_width;
widget_class->size_allocate = gtk_check_button_size_allocate;
widget_class->draw = gtk_check_button_draw;
@@ -287,9 +294,12 @@ gtk_check_button_get_preferred_width (GtkWidget *widget,
}
static void
gtk_check_button_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
gtk_check_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (widget);
@@ -301,6 +311,7 @@ gtk_check_button_get_preferred_height (GtkWidget *widget,
gint indicator_spacing;
gint focus_width;
gint focus_pad;
gint old_minimum, old_natural;
guint border_width;
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
@@ -320,29 +331,61 @@ gtk_check_button_get_preferred_height (GtkWidget *widget,
if (child && gtk_widget_get_visible (child))
{
gint child_min, child_nat;
gint child_min_baseline = -1, child_nat_baseline = -1;
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
gtk_widget_get_preferred_height_and_baseline_for_width (child, -1,
&child_min, &child_nat,
&child_min_baseline, &child_nat_baseline);
if (minimum_baseline && child_min_baseline >= 0)
*minimum_baseline = child_min_baseline + border_width;
if (natural_baseline && child_nat_baseline >= 0)
*natural_baseline = child_nat_baseline + border_width;
*minimum += child_min;
*natural += child_nat;
}
old_minimum = *minimum;
old_natural = *natural;
temp = indicator_size + indicator_spacing * 2;
*minimum = MAX (*minimum, temp) + 2 * (focus_width + focus_pad);
*natural = MAX (*natural, temp) + 2 * (focus_width + focus_pad);
if (minimum_baseline && *minimum_baseline != -1)
minimum_baseline += (*minimum - old_minimum) / 2;
if (natural_baseline && *natural_baseline != -1)
natural_baseline += (*natural - old_natural) / 2;
}
else
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->get_preferred_height (widget, minimum, natural);
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->get_preferred_height_and_baseline_for_width (widget, width,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_check_button_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
gtk_check_button_get_preferred_height_and_baseline_for_width (widget, -1,
minimum, natural,
NULL, NULL);
}
static void
gtk_check_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
PangoContext *pango_context;
PangoFontMetrics *metrics;
GtkCheckButton *check_button;
GtkToggleButton *toggle_button;
GtkButton *button;
GtkAllocation child_allocation;
gint baseline;
button = GTK_BUTTON (widget);
check_button = GTK_CHECK_BUTTON (widget);
@@ -389,8 +432,21 @@ gtk_check_button_size_allocate (GtkWidget *widget,
child_allocation.x = allocation->x + allocation->width
- (child_allocation.x - allocation->x + child_allocation.width);
gtk_widget_size_allocate (child, &child_allocation);
baseline = gtk_widget_get_allocated_baseline (widget);
if (baseline != -1)
baseline -= child_allocation.y - allocation->y;
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
}
pango_context = gtk_widget_get_pango_context (widget);
metrics = pango_context_get_metrics (pango_context,
pango_context_get_font_description (pango_context),
pango_context_get_language (pango_context));
button->priv->baseline_align =
(double)pango_font_metrics_get_ascent (metrics) /
(pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics));
pango_font_metrics_unref (metrics);
}
else
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->size_allocate (widget, allocation);
@@ -448,6 +504,7 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
gint indicator_spacing;
gint focus_width;
gint focus_pad;
gint baseline;
guint border_width;
gboolean interior_focus;
GtkAllocation allocation;
@@ -458,6 +515,7 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
toggle_button = GTK_TOGGLE_BUTTON (check_button);
gtk_widget_get_allocation (widget, &allocation);
baseline = gtk_widget_get_allocated_baseline (widget);
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
@@ -472,7 +530,11 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
x = indicator_spacing + border_width;
y = (allocation.height - indicator_size) / 2;
if (baseline == -1)
y = (allocation.height - indicator_size) / 2;
else
y = CLAMP (baseline - indicator_size * button->priv->baseline_align,
0, allocation.height - indicator_size);
child = gtk_bin_get_child (GTK_BIN (check_button));
if (!interior_focus || !(child && gtk_widget_get_visible (child)))
+1 -1
View File
@@ -234,7 +234,7 @@ item_end_element (GMarkupParseContext *context,
{
if (data->translatable)
{
gchar *translated;
const gchar *translated;
/* FIXME: This will not use the domain set in the .ui file,
* since the parser is not telling the builder about the domain.
+73 -10
View File
@@ -309,12 +309,17 @@ static void gtk_container_adjust_size_request (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size);
static void gtk_container_adjust_baseline_request (GtkWidget *widget,
gint *minimum_baseline,
gint *natural_baseline);
static void gtk_container_adjust_size_allocation (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size,
gint *allocated_pos,
gint *allocated_size);
static void gtk_container_adjust_baseline_allocation (GtkWidget *widget,
gint *baseline);
static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget);
static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
@@ -444,7 +449,9 @@ gtk_container_class_init (GtkContainerClass *class)
widget_class->focus = gtk_container_focus;
widget_class->adjust_size_request = gtk_container_adjust_size_request;
widget_class->adjust_baseline_request = gtk_container_adjust_baseline_request;
widget_class->adjust_size_allocation = gtk_container_adjust_size_allocation;
widget_class->adjust_baseline_allocation = gtk_container_adjust_baseline_allocation;
widget_class->get_request_mode = gtk_container_get_request_mode;
class->add = gtk_container_add_unimplemented;
@@ -657,8 +664,8 @@ attributes_end_element (GMarkupParseContext *context,
/* translate the string */
if (parser_data->string->len && parser_data->translatable)
{
gchar *translated;
const gchar* domain;
const gchar *translated;
const gchar *domain;
domain = gtk_builder_get_translation_domain (parser_data->builder);
@@ -1917,6 +1924,28 @@ gtk_container_adjust_size_request (GtkWidget *widget,
minimum_size, natural_size);
}
static void
gtk_container_adjust_baseline_request (GtkWidget *widget,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkContainer *container;
container = GTK_CONTAINER (widget);
if (GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width)
{
int border_width;
border_width = container->priv->border_width;
*minimum_baseline += border_width;
*natural_baseline += border_width;
}
parent_class->adjust_baseline_request (widget, minimum_baseline, natural_baseline);
}
static void
gtk_container_adjust_size_allocation (GtkWidget *widget,
GtkOrientation orientation,
@@ -1952,6 +1981,27 @@ gtk_container_adjust_size_allocation (GtkWidget *widget,
allocated_size);
}
static void
gtk_container_adjust_baseline_allocation (GtkWidget *widget,
gint *baseline)
{
GtkContainer *container;
int border_width;
container = GTK_CONTAINER (widget);
if (GTK_CONTAINER_GET_CLASS (widget)->_handle_border_width)
{
border_width = container->priv->border_width;
if (*baseline >= 0)
*baseline -= border_width;
}
parent_class->adjust_baseline_allocation (widget, baseline);
}
typedef struct {
gint hfw;
gint wfh;
@@ -3315,7 +3365,7 @@ gtk_container_propagate_draw (GtkContainer *container,
{
GdkEventExpose *event;
GtkAllocation allocation;
GdkWindow *window, *w;
GdkWindow *window, *w, *event_window, *child_in_window;
int x, y;
g_return_if_fail (GTK_IS_CONTAINER (container));
@@ -3324,13 +3374,26 @@ gtk_container_propagate_draw (GtkContainer *container,
g_assert (gtk_widget_get_parent (child) == GTK_WIDGET (container));
if (!gtk_widget_is_drawable (child))
return;
/* Only propagate to native child window if we're not handling
an expose (i.e. in a pure gtk_widget_draw() call */
event = _gtk_cairo_get_event (cr);
if (event)
{
if (gtk_widget_get_has_window (child) ||
gtk_widget_get_window (child) != event->window)
return;
}
if (event &&
(gtk_widget_get_has_window (child) &&
gdk_window_has_native (gtk_widget_get_window (child))))
return;
/* Never propagate to a child window when exposing a window
that is not the one the child widget is in. */
event_window = _gtk_cairo_get_event_window (cr);
if (gtk_widget_get_has_window (child))
child_in_window = gdk_window_get_parent (gtk_widget_get_window (child));
else
child_in_window = gtk_widget_get_window (child);
if (event_window != NULL && child_in_window != event_window)
return;
cairo_save (cr);
@@ -3372,7 +3435,7 @@ gtk_container_propagate_draw (GtkContainer *container,
cairo_translate (cr, x, y);
_gtk_widget_draw_internal (child, cr, TRUE);
_gtk_widget_draw (child, cr);
cairo_restore (cr);
}
+34
View File
@@ -300,3 +300,37 @@ _gtk_css_shadows_value_paint_box (const GtkCssValue *shadows,
_gtk_css_shadow_value_paint_box (shadows->values[i], cr, padding_box);
}
}
void
_gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
GtkBorder *border)
{
guint i;
GtkBorder b = { 0 };
const GtkCssValue *shadow;
gdouble hoffset, voffset, spread, radius;
g_return_if_fail (shadows->class == &GTK_CSS_VALUE_SHADOWS);
for (i = 0; i < shadows->len; i++)
{
shadow = shadows->values[i];
if (_gtk_css_shadow_value_get_inset (shadow))
continue;
_gtk_css_shadow_value_get_geometry (shadow,
&hoffset, &voffset,
&radius, &spread);
b.top = MAX (0, radius + spread - voffset);
b.right = MAX (0, radius + spread + hoffset);
b.bottom = MAX (0, radius + spread + voffset);
b.left = MAX (0, radius + spread - hoffset);
border->top = MAX (border->top, b.top);
border->right = MAX (border->right, b.right);
border->bottom = MAX (border->bottom, b.bottom);
border->left = MAX (border->left, b.left);
}
}
+3
View File
@@ -49,6 +49,9 @@ void _gtk_css_shadows_value_paint_box (const GtkCssValue
const GtkRoundedBox *padding_box,
gboolean inset);
void _gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
GtkBorder *border);
G_END_DECLS
#endif /* __GTK_CSS_SHADOWS_VALUE_H__ */
+20
View File
@@ -453,6 +453,26 @@ _gtk_css_shadow_value_get_inset (const GtkCssValue *shadow)
return shadow->inset;
}
void
_gtk_css_shadow_value_get_geometry (const GtkCssValue *shadow,
gdouble *hoffset,
gdouble *voffset,
gdouble *radius,
gdouble *spread)
{
g_return_if_fail (shadow->class == &GTK_CSS_VALUE_SHADOW);
if (hoffset != NULL)
*hoffset = _gtk_css_number_value_get (shadow->hoffset, 0);
if (voffset != NULL)
*voffset = _gtk_css_number_value_get (shadow->voffset, 0);
if (radius != NULL)
*radius = _gtk_css_number_value_get (shadow->radius, 0);
if (spread != NULL)
*spread = _gtk_css_number_value_get (shadow->spread, 0);
}
void
_gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
cairo_t *cr,
+6
View File
@@ -36,6 +36,12 @@ GtkCssValue * _gtk_css_shadow_value_parse (GtkCssParser
gboolean _gtk_css_shadow_value_get_inset (const GtkCssValue *shadow);
void _gtk_css_shadow_value_get_geometry (const GtkCssValue *shadow,
gdouble *hoffset,
gdouble *voffset,
gdouble *radius,
gdouble *spread);
void _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
cairo_t *cr,
PangoLayout *layout);
+3 -1
View File
@@ -47,7 +47,9 @@ typedef enum {
GTK_DEBUG_PRINTING = 1 << 10,
GTK_DEBUG_BUILDER = 1 << 11,
GTK_DEBUG_SIZE_REQUEST = 1 << 12,
GTK_DEBUG_NO_CSS_CACHE = 1 << 13
GTK_DEBUG_NO_CSS_CACHE = 1 << 13,
GTK_DEBUG_BASELINES = 1 << 14,
GTK_DEBUG_PIXEL_CACHE = 1 << 15
} GtkDebugFlag;
#ifdef G_ENABLE_DEBUG
+1
View File
@@ -744,6 +744,7 @@ gtk_dialog_add_button (GtkDialog *dialog,
button = gtk_button_new_from_stock (button_text);
gtk_widget_set_can_default (button, TRUE);
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
gtk_widget_show (button);
+48 -5
View File
@@ -367,6 +367,12 @@ static void gtk_entry_get_preferred_width (GtkWidget *widget,
static void gtk_entry_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural);
static void gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height,
gint *minimum_baseline,
gint *natural_baseline);
static void gtk_entry_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_entry_draw_frame (GtkWidget *widget,
@@ -682,6 +688,7 @@ gtk_entry_class_init (GtkEntryClass *class)
widget_class->unrealize = gtk_entry_unrealize;
widget_class->get_preferred_width = gtk_entry_get_preferred_width;
widget_class->get_preferred_height = gtk_entry_get_preferred_height;
widget_class->get_preferred_height_and_baseline_for_width = gtk_entry_get_preferred_height_and_baseline_for_width;
widget_class->size_allocate = gtk_entry_size_allocate;
widget_class->draw = gtk_entry_draw;
widget_class->enter_notify_event = gtk_entry_enter_notify;
@@ -3305,16 +3312,19 @@ gtk_entry_get_preferred_width (GtkWidget *widget,
}
static void
gtk_entry_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = entry->priv;
PangoFontMetrics *metrics;
GtkBorder borders;
PangoContext *context;
gint height;
gint height, baseline;
PangoLayout *layout;
layout = gtk_entry_ensure_layout (entry, TRUE);
@@ -3333,8 +3343,27 @@ gtk_entry_get_preferred_height (GtkWidget *widget,
height += borders.top + borders.bottom;
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
baseline += borders.top;
*minimum = height;
*natural = height;
if (minimum_baseline)
*minimum_baseline = baseline;
if (natural_baseline)
*natural_baseline = baseline;
}
static void
gtk_entry_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
gtk_entry_get_preferred_height_and_baseline_for_width (widget,
-1,
minimum,
natural,
NULL, NULL);
}
static void
@@ -3452,13 +3481,17 @@ gtk_entry_get_frame_size (GtkEntry *entry,
GtkAllocation allocation;
GtkRequisition requisition;
GtkWidget *widget = GTK_WIDGET (entry);
gint area_height, y_pos;
gint baseline;
gint req_height;
GtkBorder borders;
gtk_widget_get_preferred_size (widget, &requisition, NULL);
req_height = requisition.height - gtk_widget_get_margin_top (widget) - gtk_widget_get_margin_bottom (widget);
gtk_widget_get_allocation (widget, &allocation);
baseline = gtk_widget_get_allocated_baseline (widget);
if (x)
*x = allocation.x;
@@ -3468,7 +3501,17 @@ gtk_entry_get_frame_size (GtkEntry *entry,
if (priv->is_cell_renderer)
*y = 0;
else
*y = (allocation.height - req_height) / 2;
{
if (baseline == -1)
*y = (allocation.height - req_height) / 2;
else
{
_gtk_entry_get_borders (entry, &borders);
area_height = req_height - borders.top - borders.bottom;
y_pos = ((area_height * PANGO_SCALE - priv->ascent - priv->descent) / 2 + priv->ascent) / PANGO_SCALE;
*y = baseline - y_pos - borders.top;
}
}
*y += allocation.y;
}
+29 -1
View File
@@ -51,6 +51,7 @@ G_BEGIN_DECLS
* or top
* @GTK_ALIGN_CENTER: center natural width of widget inside the
* allocation
* @GTK_ALIGN_BASELINE: align the widget according to the baseline. Since 3.10.
*
* Controls how a widget deals with extra space in a single (x or y)
* dimension.
@@ -64,13 +65,18 @@ G_BEGIN_DECLS
*
* Note that in horizontal context @GTK_ALIGN_START and @GTK_ALIGN_END
* are interpreted relative to text direction.
*
* GTK_ALIGN_BASELINE support for it is optional for containers and widgets, and
* it is only supported for vertical alignment. When its not supported by
* a child or a container it is treated as @GTK_ALIGN_FILL.
*/
typedef enum
{
GTK_ALIGN_FILL,
GTK_ALIGN_START,
GTK_ALIGN_END,
GTK_ALIGN_CENTER
GTK_ALIGN_CENTER,
GTK_ALIGN_BASELINE
} GtkAlign;
@@ -125,6 +131,28 @@ typedef enum
GTK_FILL = 1 << 2
} GtkAttachOptions;
/**
* GtkBaselinePosition:
* @GTK_BASELINE_POSITION_TOP: Align the baseline at the top
* @GTK_BASELINE_POSITION_CENTER: Center the baseline
* @GTK_BASELINE_POSITION_BOTTOM: Align the baseline at the bottom
*
* Whenever a container has some form of natural row it may align
* children in that row along a common typographical baseline. If
* the amount of verical space in the row is taller than the total
* requested height of the baseline-aligned children then it can use a
* #GtkBaselinePosition to select where to put the baseline inside the
* extra availible space.
*
* Since: 3.10
*/
typedef enum
{
GTK_BASELINE_POSITION_TOP,
GTK_BASELINE_POSITION_CENTER,
GTK_BASELINE_POSITION_BOTTOM
} GtkBaselinePosition;
/**
* GtkButtonBoxStyle:
* @GTK_BUTTONBOX_DEFAULT_STYLE: Default packing.
+38 -5
View File
@@ -65,6 +65,12 @@ static void gtk_event_box_get_preferred_width (GtkWidget *widget,
static void gtk_event_box_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural);
static void gtk_event_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline);
static void gtk_event_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean gtk_event_box_draw (GtkWidget *widget,
@@ -96,6 +102,7 @@ gtk_event_box_class_init (GtkEventBoxClass *class)
widget_class->unmap = gtk_event_box_unmap;
widget_class->get_preferred_width = gtk_event_box_get_preferred_width;
widget_class->get_preferred_height = gtk_event_box_get_preferred_height;
widget_class->get_preferred_height_and_baseline_for_width = gtk_event_box_get_preferred_height_and_baseline_for_width;
widget_class->size_allocate = gtk_event_box_size_allocate;
widget_class->draw = gtk_event_box_draw;
@@ -515,9 +522,12 @@ gtk_event_box_get_preferred_width (GtkWidget *widget,
}
static void
gtk_event_box_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
gtk_event_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBin *bin = GTK_BIN (widget);
GtkWidget *child;
@@ -528,9 +538,30 @@ gtk_event_box_get_preferred_height (GtkWidget *widget,
if (natural)
*natural = 0;
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
child = gtk_bin_get_child (bin);
if (child && gtk_widget_get_visible (child))
gtk_widget_get_preferred_height (child, minimum, natural);
gtk_widget_get_preferred_height_and_baseline_for_width (child,
-1,
minimum,
natural,
minimum_baseline,
natural_baseline);
}
static void
gtk_event_box_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
gtk_event_box_get_preferred_height_and_baseline_for_width (widget, -1,
minimum, natural,
NULL, NULL);
}
static void
@@ -539,6 +570,7 @@ gtk_event_box_size_allocate (GtkWidget *widget,
{
GtkBin *bin;
GtkAllocation child_allocation;
gint baseline;
GtkEventBoxPrivate *priv;
GtkWidget *child;
@@ -578,9 +610,10 @@ gtk_event_box_size_allocate (GtkWidget *widget,
child_allocation.height);
}
baseline = gtk_widget_get_allocated_baseline (widget);
child = gtk_bin_get_child (bin);
if (child)
gtk_widget_size_allocate (child, &child_allocation);
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
}
static gboolean
+1 -1
View File
@@ -290,7 +290,7 @@
<child>
<object class="GtkTreeViewColumn" id="list_mtime_column">
<property name="resizable">True</property>
<property name="title" translatable="yes">Modifed</property>
<property name="title" translatable="yes">Modified</property>
<child>
<object class="GtkCellRendererText" id="list_mtime_renderer"/>
</child>
+611 -119
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -109,6 +109,18 @@ gboolean gtk_grid_get_column_homogeneous (GtkGrid *grid);
void gtk_grid_set_column_spacing (GtkGrid *grid,
guint spacing);
guint gtk_grid_get_column_spacing (GtkGrid *grid);
GDK_AVAILABLE_IN_3_10
void gtk_grid_set_row_baseline_position (GtkGrid *grid,
gint row,
GtkBaselinePosition pos);
GDK_AVAILABLE_IN_3_10
GtkBaselinePosition gtk_grid_get_row_baseline_position (GtkGrid *grid,
gint row);
GDK_AVAILABLE_IN_3_10
void gtk_grid_set_baseline_row (GtkGrid *grid,
gint row);
GDK_AVAILABLE_IN_3_10
gint gtk_grid_get_baseline_row (GtkGrid *grid);
G_END_DECLS
+70 -7
View File
@@ -140,6 +140,8 @@ struct _GtkImagePrivate
gchar *filename; /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
gchar *resource_path; /* Only used with GTK_IMAGE_PIXBUF */
float baseline_align;
};
@@ -154,6 +156,12 @@ static void gtk_image_get_preferred_width (GtkWidget *widget,
static void gtk_image_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural);
static void gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline);
static void gtk_image_style_updated (GtkWidget *widget);
static void gtk_image_screen_changed (GtkWidget *widget,
@@ -207,6 +215,7 @@ gtk_image_class_init (GtkImageClass *class)
widget_class->draw = gtk_image_draw;
widget_class->get_preferred_width = gtk_image_get_preferred_width;
widget_class->get_preferred_height = gtk_image_get_preferred_height;
widget_class->get_preferred_height_and_baseline_for_width = gtk_image_get_preferred_height_and_baseline_for_width;
widget_class->unmap = gtk_image_unmap;
widget_class->unrealize = gtk_image_unrealize;
widget_class->style_updated = gtk_image_style_updated;
@@ -1393,6 +1402,28 @@ gtk_image_get_preferred_size (GtkImage *image,
*height_out = height;
}
static float
gtk_image_get_baseline_align (GtkImage *image)
{
PangoContext *pango_context;
PangoFontMetrics *metrics;
if (image->priv->baseline_align == 0.0)
{
pango_context = gtk_widget_get_pango_context (GTK_WIDGET (image));
metrics = pango_context_get_metrics (pango_context,
pango_context_get_font_description (pango_context),
pango_context_get_language (pango_context));
image->priv->baseline_align =
(float)pango_font_metrics_get_ascent (metrics) /
(pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics));
pango_font_metrics_unref (metrics);
}
return image->priv->baseline_align;
}
static gint
gtk_image_draw (GtkWidget *widget,
cairo_t *cr)
@@ -1401,7 +1432,7 @@ gtk_image_draw (GtkWidget *widget,
GtkImagePrivate *priv;
GtkMisc *misc;
GtkStyleContext *context;
gint x, y, width, height;
gint x, y, width, height, baseline;
gfloat xalign, yalign;
GtkBorder border;
@@ -1427,8 +1458,14 @@ gtk_image_draw (GtkWidget *widget,
if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
xalign = 1.0 - xalign;
baseline = gtk_widget_get_allocated_baseline (widget);
x = floor ((gtk_widget_get_allocated_width (widget) - width) * xalign) + border.left;
y = floor ((gtk_widget_get_allocated_height (widget) - height) * yalign) + border.top;
if (baseline == -1)
y = floor ((gtk_widget_get_allocated_height (widget) - height) * yalign) + border.top;
else
y = CLAMP (baseline - height * gtk_image_get_baseline_align (image),
border.top, gtk_widget_get_allocated_height (widget) - height);
if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
{
@@ -1535,15 +1572,37 @@ gtk_image_get_preferred_width (GtkWidget *widget,
*minimum = *natural = width;
}
static void
gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
gint height;
float baseline_align;
gtk_image_get_preferred_size (GTK_IMAGE (widget), NULL, &height);
*minimum = *natural = height;
if (minimum_baseline || natural_baseline)
{
baseline_align = gtk_image_get_baseline_align (GTK_IMAGE (widget));
if (minimum_baseline)
*minimum_baseline = height * baseline_align;
if (natural_baseline)
*natural_baseline = height * baseline_align;
}
}
static void
gtk_image_get_preferred_height (GtkWidget *widget,
gint *minimum,
gint *natural)
{
gint height;
gtk_image_get_preferred_size (GTK_IMAGE (widget), NULL, &height);
*minimum = *natural = height;
gtk_image_get_preferred_height_and_baseline_for_width (widget, -1, minimum, natural,
NULL, NULL);
}
static void
@@ -1558,9 +1617,13 @@ icon_theme_changed (GtkImage *image)
static void
gtk_image_style_updated (GtkWidget *widget)
{
GtkImage *image = GTK_IMAGE (widget);
GtkImagePrivate *priv = image->priv;
GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget);
icon_theme_changed (GTK_IMAGE (widget));
icon_theme_changed (image);
priv->baseline_align = 0.0;
}
static void
+91 -17
View File
@@ -519,6 +519,12 @@ static void gtk_label_get_preferred_height_for_width (GtkWidget
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height,
gint *minimum_baseline,
gint *natural_baseline);
static GtkBuildableIface *buildable_parent_iface = NULL;
@@ -585,6 +591,7 @@ gtk_label_class_init (GtkLabelClass *class)
widget_class->get_preferred_height = gtk_label_get_preferred_height;
widget_class->get_preferred_width_for_height = gtk_label_get_preferred_width_for_height;
widget_class->get_preferred_height_for_width = gtk_label_get_preferred_height_for_width;
widget_class->get_preferred_height_and_baseline_for_width = gtk_label_get_preferred_height_and_baseline_for_width;
class->move_cursor = gtk_label_move_cursor;
class->copy_clipboard = gtk_label_copy_clipboard;
@@ -3462,15 +3469,18 @@ gtk_label_get_request_mode (GtkWidget *widget)
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
}
static void
get_size_for_allocation (GtkLabel *label,
GtkOrientation orientation,
gint allocation,
gint *minimum_size,
gint *natural_size)
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
PangoLayout *layout;
gint text_height;
gint text_height, baseline;
layout = gtk_label_get_measuring_layout (label, NULL, allocation * PANGO_SCALE);
@@ -3482,6 +3492,16 @@ get_size_for_allocation (GtkLabel *label,
if (natural_size)
*natural_size = text_height;
if (minimum_baseline || natural_baseline)
{
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
if (minimum_baseline)
*minimum_baseline = baseline;
if (natural_baseline)
*natural_baseline = baseline;
}
g_object_unref (layout);
}
@@ -3578,7 +3598,9 @@ static void
gtk_label_get_preferred_size (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkLabel *label = GTK_LABEL (widget);
GtkLabelPrivate *priv = label->priv;
@@ -3586,6 +3608,12 @@ gtk_label_get_preferred_size (GtkWidget *widget,
PangoRectangle smallest_rect;
GtkBorder border;
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
gtk_label_get_preferred_layout_size (label, &smallest_rect, &widest_rect);
/* Now that we have minimum and natural sizes in pango extents, apply a possible transform */
@@ -3640,7 +3668,8 @@ gtk_label_get_preferred_size (GtkWidget *widget,
get_size_for_allocation (label,
GTK_ORIENTATION_VERTICAL,
smallest_rect.height,
minimum_size, natural_size);
minimum_size, natural_size,
NULL, NULL);
}
else
@@ -3667,7 +3696,16 @@ gtk_label_get_preferred_size (GtkWidget *widget,
get_size_for_allocation (label,
GTK_ORIENTATION_HORIZONTAL,
widest_rect.width,
minimum_size, natural_size);
minimum_size, natural_size,
minimum_baseline, natural_baseline);
if (priv->angle == 180)
{
if (minimum_baseline)
*minimum_baseline = *minimum_size - *minimum_baseline;
if (natural_baseline)
*natural_baseline = *natural_size - *natural_baseline;
}
}
else
{
@@ -3680,6 +3718,12 @@ gtk_label_get_preferred_size (GtkWidget *widget,
*minimum_size += border.top + border.bottom;
*natural_size += border.top + border.bottom;
if (minimum_baseline && *minimum_baseline != -1)
*minimum_baseline += border.top;
if (natural_baseline && *natural_baseline != -1)
*natural_baseline += border.top;
}
}
@@ -3688,7 +3732,7 @@ gtk_label_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -3696,7 +3740,7 @@ gtk_label_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -3719,7 +3763,8 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL,
MAX (1, height - border.top - border.bottom),
minimum_width, natural_width);
minimum_width, natural_width,
NULL, NULL);
if (minimum_width)
*minimum_width += border.right + border.left;
@@ -3732,15 +3777,17 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
}
static void
gtk_label_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height)
gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkLabel *label = GTK_LABEL (widget);
GtkLabelPrivate *priv = label->priv;
if (priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
if (width != -1 && priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
{
GtkBorder border;
@@ -3751,7 +3798,13 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL,
MAX (1, width - border.left - border.right),
minimum_height, natural_height);
minimum_height, natural_height,
minimum_baseline, natural_baseline);
if (minimum_baseline && *minimum_baseline != -1)
*minimum_baseline += border.top;
if (natural_baseline && *natural_baseline != -1)
*natural_baseline += border.top;
if (minimum_height)
*minimum_height += border.top + border.bottom;
@@ -3760,7 +3813,18 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
*natural_height += border.top + border.bottom;
}
else
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_height, natural_height, minimum_baseline, natural_baseline);
}
static void
gtk_label_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height)
{
return gtk_label_get_preferred_height_and_baseline_for_width (widget, width,
minimum_height, natural_height,
NULL, NULL);
}
static void
@@ -3855,6 +3919,7 @@ get_layout_location (GtkLabel *label,
gint req_height;
gfloat xalign, yalign;
PangoRectangle logical;
gint baseline, layout_baseline, baseline_offset;
misc = GTK_MISC (label);
widget = GTK_WIDGET (label);
@@ -3887,6 +3952,15 @@ get_layout_location (GtkLabel *label,
x = floor (allocation.x + border.left + xalign * (allocation.width - req_width) - logical.x);
baseline_offset = 0;
baseline = gtk_widget_get_allocated_baseline (widget);
if (baseline != -1 && !priv->have_transform)
{
layout_baseline = pango_layout_get_baseline (priv->layout) / PANGO_SCALE;
baseline_offset = baseline - layout_baseline;
yalign = 0.0; /* Can't support yalign while baseline aligning */
}
/* bgo#315462 - For single-line labels, *do* align the requisition with
* respect to the allocation, even if we are under-allocated. For multi-line
* labels, always show the top of the text when they are under-allocated. The
@@ -3901,9 +3975,9 @@ get_layout_location (GtkLabel *label,
* middle". You want to read the first line, at least, to get some context.
*/
if (pango_layout_get_line_count (priv->layout) == 1)
y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y;
y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y + baseline_offset;
else
y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y;
y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y + baseline_offset;
if (xp)
*xp = x;
+3 -3
View File
@@ -2555,9 +2555,9 @@ list_store_text (GMarkupParseContext *context,
* since the parser is not telling the builder about the domain.
* However, it will work for gtk_builder_set_translation_domain() calls.
*/
translated = _gtk_builder_parser_translate (data->domain,
info->context,
string);
translated = g_strdup (_gtk_builder_parser_translate (data->domain,
info->context,
string));
g_free (string);
string = translated;
}
+14 -4
View File
@@ -171,7 +171,9 @@ static const GDebugKey gtk_debug_keys[] = {
{"printing", GTK_DEBUG_PRINTING},
{"builder", GTK_DEBUG_BUILDER},
{"size-request", GTK_DEBUG_SIZE_REQUEST},
{"no-css-cache", GTK_DEBUG_NO_CSS_CACHE}
{"no-css-cache", GTK_DEBUG_NO_CSS_CACHE},
{"baselines", GTK_DEBUG_BASELINES},
{"pixel-cache", GTK_DEBUG_PIXEL_CACHE}
};
#endif /* G_ENABLE_DEBUG */
@@ -1614,9 +1616,17 @@ gtk_main_do_event (GdkEvent *event)
case GDK_EXPOSE:
if (event->any.window && gtk_widget_get_double_buffered (event_widget))
{
gdk_window_begin_paint_region (event->any.window, event->expose.region);
gtk_widget_send_expose (event_widget, event);
gdk_window_end_paint (event->any.window);
/* We handle exposes only on native windows, relying on the
* draw() handler to propagate down to non-native windows.
* This is ok now that we child windows always are considered
* (semi)transparent.
*/
if (gdk_window_has_native (event->expose.window))
{
gdk_window_begin_paint_region (event->any.window, event->expose.region);
gtk_widget_send_expose (event_widget, event);
gdk_window_end_paint (event->any.window);
}
}
else
{
+2 -20
View File
@@ -50,6 +50,7 @@
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
/* Properties */
enum {
@@ -308,25 +309,6 @@ gtk_menu_bar_get_property (GObject *object,
}
}
static void
get_preferred_size_for_size (GtkWidget *widget,
GtkOrientation orientation,
gint size,
gint *minimum,
gint *natural)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
if (size < 0)
gtk_widget_get_preferred_width (widget, minimum, natural);
else
gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
else
if (size < 0)
gtk_widget_get_preferred_height (widget, minimum, natural);
else
gtk_widget_get_preferred_height_for_width (widget, size, minimum, natural);
}
static void
gtk_menu_bar_size_request (GtkWidget *widget,
GtkOrientation orientation,
@@ -374,7 +356,7 @@ gtk_menu_bar_size_request (GtkWidget *widget,
if (gtk_widget_get_visible (child))
{
get_preferred_size_for_size (child, orientation, size, &child_minimum, &child_natural);
_gtk_widget_get_preferred_size_for_size (child, orientation, size, &child_minimum, &child_natural, NULL, NULL);
if (use_toggle_size)
{
+1 -1
View File
@@ -1378,7 +1378,7 @@ gtk_menu_item_activate (GtkMenuItem *menu_item)
/**
* gtk_menu_item_toggle_size_request:
* @menu_item: the menu item
* @requisition: the requisition to use as signal data.
* @requisition: (inout): the requisition to use as signal data.
*
* Emits the #GtkMenuItem::toggle-size-request signal on the given item.
*/
+49 -11
View File
@@ -25,6 +25,8 @@
#include "gtkactionhelper.h"
#include "gtkwidgetprivate.h"
#include "gtkaccellabel.h"
#include "gtkimage.h"
#include "gtkbox.h"
struct _GtkModelMenuItem
{
@@ -113,6 +115,51 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
GMenuModel *submenu;
const gchar *key;
GVariant *value;
GtkWidget *label;
label = NULL;
/* In the case that we have an icon, make an HBox and put it beside
* the label. Otherwise, we just have a label directly.
*/
if ((value = g_menu_model_get_item_attribute_value (model, item_index, "icon", NULL)))
{
GIcon *icon;
icon = g_icon_deserialize (value);
if (icon != NULL)
{
GtkWidget *image;
GtkWidget *box;
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
g_object_unref (icon);
label = gtk_accel_label_new ("");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), GTK_WIDGET (item));
gtk_box_pack_end (GTK_BOX (box), label, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (item), box);
gtk_widget_show_all (box);
}
g_variant_unref (value);
}
if (label == NULL)
{
/* Ensure that the GtkAccelLabel has been created... */
(void) gtk_menu_item_get_label (GTK_MENU_ITEM (item));
label = gtk_bin_get_child (GTK_BIN (item));
}
g_assert (label != NULL);
if ((submenu = g_menu_model_get_item_link (model, item_index, "submenu")))
{
@@ -141,7 +188,7 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
while (g_menu_attribute_iter_get_next (iter, &key, &value))
{
if (g_str_equal (key, "label") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
gtk_menu_item_set_label (GTK_MENU_ITEM (item), g_variant_get_string (value, NULL));
gtk_label_set_text_with_mnemonic (GTK_LABEL (label), g_variant_get_string (value, NULL));
else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
{
@@ -151,16 +198,7 @@ gtk_model_menu_item_setup (GtkModelMenuItem *item,
gtk_accelerator_parse (g_variant_get_string (value, NULL), &key, &modifiers);
if (key)
{
GtkAccelLabel *accel_label;
/* Ensure that the GtkAccelLabel has been created... */
(void) gtk_menu_item_get_label (GTK_MENU_ITEM (item));
accel_label = GTK_ACCEL_LABEL (gtk_bin_get_child (GTK_BIN (item)));
g_assert (accel_label);
gtk_accel_label_set_accel (accel_label, key, modifiers);
}
gtk_accel_label_set_accel (GTK_ACCEL_LABEL (label), key, modifiers);
}
else if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+13 -26
View File
@@ -2214,25 +2214,6 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook *notebook,
}
}
static void
get_preferred_size_for_size (GtkWidget *widget,
GtkOrientation orientation,
gint size,
gint *minimum,
gint *natural)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
if (size < 0)
gtk_widget_get_preferred_width (widget, minimum, natural);
else
gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
else
if (size < 0)
gtk_widget_get_preferred_height (widget, minimum, natural);
else
gtk_widget_get_preferred_height_for_width (widget, size, minimum, natural);
}
static void
get_padding_and_border (GtkNotebook *notebook,
GtkBorder *border)
@@ -2282,11 +2263,13 @@ gtk_notebook_size_request (GtkWidget *widget,
if (gtk_widget_get_visible (page->child))
{
vis_pages++;
get_preferred_size_for_size (page->child,
orientation,
size,
&child_minimum,
&child_natural);
_gtk_widget_get_preferred_size_for_size (page->child,
orientation,
size,
&child_minimum,
&child_natural,
NULL,
NULL);
*minimum = MAX (*minimum, child_minimum);
*natural = MAX (*natural, child_natural);
@@ -8195,9 +8178,11 @@ gtk_notebook_set_tab_reorderable (GtkNotebook *notebook,
if (!list)
return;
reorderable = reorderable != FALSE;
if (GTK_NOTEBOOK_PAGE (list)->reorderable != reorderable)
{
GTK_NOTEBOOK_PAGE (list)->reorderable = (reorderable == TRUE);
GTK_NOTEBOOK_PAGE (list)->reorderable = reorderable;
gtk_widget_child_notify (child, "reorderable");
}
}
@@ -8288,9 +8273,11 @@ gtk_notebook_set_tab_detachable (GtkNotebook *notebook,
if (!list)
return;
detachable = detachable != FALSE;
if (GTK_NOTEBOOK_PAGE (list)->detachable != detachable)
{
GTK_NOTEBOOK_PAGE (list)->detachable = (detachable == TRUE);
GTK_NOTEBOOK_PAGE (list)->detachable = detachable;
gtk_widget_child_notify (child, "detachable");
}
}
+8
View File
@@ -399,6 +399,10 @@ gtk_overlay_get_child_position (GtkOverlay *overlay,
case GTK_ALIGN_END:
alloc->x += main_alloc.width - req.width;
break;
case GTK_ALIGN_BASELINE:
default:
g_assert_not_reached ();
break;
}
alloc->y = main_alloc.y;
@@ -418,6 +422,10 @@ gtk_overlay_get_child_position (GtkOverlay *overlay,
case GTK_ALIGN_END:
alloc->y += main_alloc.height - req.height;
break;
case GTK_ALIGN_BASELINE:
default:
g_assert_not_reached ();
break;
}
return TRUE;
+167 -92
View File
@@ -35,6 +35,7 @@
#include "gtkorientableprivate.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "gtkwidgetprivate.h"
#include "a11y/gtkpanedaccessible.h"
/**
@@ -870,22 +871,166 @@ gtk_paned_finalize (GObject *object)
}
static void
get_preferred_size_for_size (GtkWidget *widget,
GtkOrientation orientation,
gint size,
gint *minimum,
gint *natural)
gtk_paned_compute_position (GtkPaned *paned,
gint allocation,
gint child1_req,
gint child2_req,
gint *min_pos,
gint *max_pos,
gint *out_pos)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
if (size < 0)
gtk_widget_get_preferred_width (widget, minimum, natural);
else
gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
GtkPanedPrivate *priv = paned->priv;
gint min, max, pos;
min = priv->child1_shrink ? 0 : child1_req;
max = allocation;
if (!priv->child2_shrink)
max = MAX (1, max - child2_req);
max = MAX (min, max);
if (!priv->position_set)
{
if (priv->child1_resize && !priv->child2_resize)
pos = MAX (0, allocation - child2_req);
else if (!priv->child1_resize && priv->child2_resize)
pos = child1_req;
else if (child1_req + child2_req != 0)
pos = allocation * ((gdouble)child1_req / (child1_req + child2_req)) + 0.5;
else
pos = allocation * 0.5 + 0.5;
}
else
if (size < 0)
gtk_widget_get_preferred_height (widget, minimum, natural);
else
gtk_widget_get_preferred_height_for_width (widget, size, minimum, natural);
{
/* If the position was set before the initial allocation.
* (priv->last_allocation <= 0) just clamp it and leave it.
*/
if (priv->last_allocation > 0)
{
if (priv->child1_resize && !priv->child2_resize)
pos = priv->child1_size + allocation - priv->last_allocation;
else if (!(!priv->child1_resize && priv->child2_resize))
pos = allocation * ((gdouble) priv->child1_size / (priv->last_allocation)) + 0.5;
else
pos = priv->child1_size;
}
else
pos = priv->child1_size;
}
pos = CLAMP (pos, min, max);
if (min_pos)
*min_pos = min;
if (max_pos)
*max_pos = max;
if (out_pos)
*out_pos = pos;
}
static void
gtk_paned_get_preferred_size_for_orientation (GtkWidget *widget,
gint size,
gint *minimum,
gint *natural)
{
GtkPaned *paned = GTK_PANED (widget);
GtkPanedPrivate *priv = paned->priv;
gint child_min, child_nat;
*minimum = *natural = 0;
if (priv->child1 && gtk_widget_get_visible (priv->child1))
{
_gtk_widget_get_preferred_size_for_size (priv->child1, priv->orientation, size, &child_min, &child_nat, NULL, NULL);
if (priv->child1_shrink)
*minimum = 0;
else
*minimum = child_min;
*natural = child_nat;
}
if (priv->child2 && gtk_widget_get_visible (priv->child2))
{
_gtk_widget_get_preferred_size_for_size (priv->child2, priv->orientation, size, &child_min, &child_nat, NULL, NULL);
if (!priv->child2_shrink)
*minimum += child_min;
*natural += child_nat;
}
if (priv->child1 && gtk_widget_get_visible (priv->child1) &&
priv->child2 && gtk_widget_get_visible (priv->child2))
{
gint handle_size;
gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
*minimum += handle_size;
*natural += handle_size;
}
}
static void
gtk_paned_get_preferred_size_for_opposite_orientation (GtkWidget *widget,
gint size,
gint *minimum,
gint *natural)
{
GtkPaned *paned = GTK_PANED (widget);
GtkPanedPrivate *priv = paned->priv;
gint for_child1, for_child2;
gint child_min, child_nat;
if (size > -1 &&
priv->child1 && gtk_widget_get_visible (priv->child1) &&
priv->child2 && gtk_widget_get_visible (priv->child2))
{
gint child1_req, child2_req;
gint handle_size;
gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
_gtk_widget_get_preferred_size_for_size (priv->child1, priv->orientation, -1, &child1_req, NULL, NULL, NULL);
_gtk_widget_get_preferred_size_for_size (priv->child2, priv->orientation, -1, &child2_req, NULL, NULL, NULL);
gtk_paned_compute_position (paned,
size, child1_req, child2_req,
NULL, NULL, &for_child1);
for_child2 = size - for_child1 - handle_size;
}
else
{
for_child1 = size;
for_child2 = size;
}
*minimum = *natural = 0;
if (priv->child1 && gtk_widget_get_visible (priv->child1))
{
_gtk_widget_get_preferred_size_for_size (priv->child1,
OPPOSITE_ORIENTATION (priv->orientation),
for_child1,
&child_min, &child_nat,
NULL, NULL);
*minimum = child_min;
*natural = child_nat;
}
if (priv->child2 && gtk_widget_get_visible (priv->child2))
{
_gtk_widget_get_preferred_size_for_size (priv->child2,
OPPOSITE_ORIENTATION (priv->orientation),
for_child2,
&child_min, &child_nat,
NULL, NULL);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
}
}
static void
@@ -897,50 +1042,11 @@ gtk_paned_get_preferred_size (GtkWidget *widget,
{
GtkPaned *paned = GTK_PANED (widget);
GtkPanedPrivate *priv = paned->priv;
gint child_min, child_nat;
*minimum = *natural = 0;
if (priv->child1 && gtk_widget_get_visible (priv->child1))
{
get_preferred_size_for_size (priv->child1, orientation, size, &child_min, &child_nat);
if (priv->child1_shrink && priv->orientation == orientation)
*minimum = 0;
else
*minimum = child_min;
*natural = child_nat;
}
if (priv->child2 && gtk_widget_get_visible (priv->child2))
{
get_preferred_size_for_size (priv->child2, orientation, size, &child_min, &child_nat);
if (priv->orientation == orientation)
{
if (!priv->child2_shrink)
*minimum += child_min;
*natural += child_nat;
}
else
{
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
}
}
if (priv->child1 && gtk_widget_get_visible (priv->child1) &&
priv->child2 && gtk_widget_get_visible (priv->child2))
{
gint handle_size;
gtk_widget_style_get (widget, "handle-size", &handle_size, NULL);
if (priv->orientation == orientation)
{
*minimum += handle_size;
*natural += handle_size;
}
}
if (orientation == priv->orientation)
return gtk_paned_get_preferred_size_for_orientation (widget, size, minimum, natural);
else
return gtk_paned_get_preferred_size_for_opposite_orientation (widget, size, minimum, natural);
}
static void
@@ -2082,41 +2188,10 @@ gtk_paned_calc_position (GtkPaned *paned,
old_min_position = priv->min_position;
old_max_position = priv->max_position;
priv->min_position = priv->child1_shrink ? 0 : child1_req;
priv->max_position = allocation;
if (!priv->child2_shrink)
priv->max_position = MAX (1, priv->max_position - child2_req);
priv->max_position = MAX (priv->min_position, priv->max_position);
if (!priv->position_set)
{
if (priv->child1_resize && !priv->child2_resize)
priv->child1_size = MAX (0, allocation - child2_req);
else if (!priv->child1_resize && priv->child2_resize)
priv->child1_size = child1_req;
else if (child1_req + child2_req != 0)
priv->child1_size = allocation * ((gdouble)child1_req / (child1_req + child2_req)) + 0.5;
else
priv->child1_size = allocation * 0.5 + 0.5;
}
else
{
/* If the position was set before the initial allocation.
* (priv->last_allocation <= 0) just clamp it and leave it.
*/
if (priv->last_allocation > 0)
{
if (priv->child1_resize && !priv->child2_resize)
priv->child1_size += allocation - priv->last_allocation;
else if (!(!priv->child1_resize && priv->child2_resize))
priv->child1_size = allocation * ((gdouble) priv->child1_size / (priv->last_allocation)) + 0.5;
}
}
priv->child1_size = CLAMP (priv->child1_size,
priv->min_position,
priv->max_position);
gtk_paned_compute_position (paned,
allocation, child1_req, child2_req,
&priv->min_position, &priv->max_position,
&priv->child1_size);
if (priv->child1)
gtk_paned_set_child_visible (paned, 0, priv->child1_size != 0);
+395
View File
@@ -0,0 +1,395 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkdebug.h"
#include "gtkpixelcacheprivate.h"
#define BLOW_CACHE_TIMEOUT_SEC 20
/* The extra size of the offscreen surface we allocate
to make scrolling more efficient */
#define EXTRA_SIZE 64
/* When resizing viewport to smaller we allow this extra
size to avoid constantly reallocating when resizing */
#define ALLOW_LARGER_SIZE 32
struct _GtkPixelCache {
cairo_surface_t *surface;
/* Valid if surface != NULL */
int surface_x;
int surface_y;
int surface_w;
int surface_h;
/* may be null if not dirty */
cairo_region_t *surface_dirty;
guint timeout_tag;
};
GtkPixelCache *
_gtk_pixel_cache_new ()
{
GtkPixelCache *cache;
cache = g_new0 (GtkPixelCache, 1);
return cache;
}
void
_gtk_pixel_cache_free (GtkPixelCache *cache)
{
if (cache == NULL)
return;
if (cache->timeout_tag)
g_source_remove (cache->timeout_tag);
if (cache->surface != NULL)
cairo_surface_destroy (cache->surface);
if (cache->surface_dirty != NULL)
cairo_region_destroy (cache->surface_dirty);
g_free (cache);
}
/* Region is in canvas coordinates */
void
_gtk_pixel_cache_invalidate (GtkPixelCache *cache,
cairo_region_t *region)
{
cairo_rectangle_int_t r;
cairo_region_t *free_region = NULL;
if (cache->surface == NULL ||
(region != NULL && cairo_region_is_empty (region)))
return;
if (region == NULL)
{
r.x = cache->surface_x;
r.y = cache->surface_y;
r.width = cache->surface_w;
r.height = cache->surface_h;
free_region = region =
cairo_region_create_rectangle (&r);
}
if (cache->surface_dirty == NULL)
{
cache->surface_dirty = cairo_region_copy (region);
cairo_region_translate (cache->surface_dirty,
-cache->surface_x,
-cache->surface_y);
}
else
{
cairo_region_translate (region,
-cache->surface_x,
-cache->surface_y);
cairo_region_union (cache->surface_dirty, region);
cairo_region_translate (region,
cache->surface_x,
cache->surface_y);
}
if (free_region)
cairo_region_destroy (free_region);
r.x = 0;
r.y = 0;
r.width = cache->surface_w;
r.height = cache->surface_h;
cairo_region_intersect_rectangle (cache->surface_dirty, &r);
}
static void
_gtk_pixel_cache_create_surface_if_needed (GtkPixelCache *cache,
GdkWindow *window,
cairo_rectangle_int_t *view_rect,
cairo_rectangle_int_t *canvas_rect)
{
cairo_rectangle_int_t rect;
int surface_w, surface_h;
cairo_content_t content;
cairo_pattern_t *bg;
double red, green, blue, alpha;
content = CAIRO_CONTENT_COLOR_ALPHA;
bg = gdk_window_get_background_pattern (window);
if (bg != NULL &&
cairo_pattern_get_type (bg) == CAIRO_PATTERN_TYPE_SOLID &&
cairo_pattern_get_rgba (bg, &red, &green, &blue, &alpha) == CAIRO_STATUS_SUCCESS &&
alpha == 1.0)
content = CAIRO_CONTENT_COLOR;
surface_w = view_rect->width;
if (canvas_rect->width > surface_w)
surface_w = MIN (surface_w + EXTRA_SIZE, canvas_rect->width);
surface_h = view_rect->height;
if (canvas_rect->height > surface_h)
surface_h = MIN (surface_h + EXTRA_SIZE, canvas_rect->height);
/* If current surface can't fit view_rect or is too large, kill it */
if (cache->surface != NULL &&
(cairo_surface_get_content (cache->surface) != content ||
cache->surface_w < view_rect->width ||
cache->surface_w > surface_w + ALLOW_LARGER_SIZE ||
cache->surface_h < view_rect->height ||
cache->surface_h > surface_h + ALLOW_LARGER_SIZE))
{
cairo_surface_destroy (cache->surface);
cache->surface = NULL;
if (cache->surface_dirty)
cairo_region_destroy (cache->surface_dirty);
cache->surface_dirty = NULL;
}
/* Don't allocate a surface if view >= canvas, as we won't
be scrolling then anyway */
if (cache->surface == NULL &&
(view_rect->width < canvas_rect->width ||
view_rect->height < canvas_rect->height))
{
cache->surface_x = -canvas_rect->x;
cache->surface_y = -canvas_rect->y;
cache->surface_w = surface_w;
cache->surface_h = surface_h;
cache->surface =
gdk_window_create_similar_surface (window, content,
surface_w, surface_h);
rect.x = 0;
rect.y = 0;
rect.width = surface_w;
rect.height = surface_h;
cache->surface_dirty =
cairo_region_create_rectangle (&rect);
}
}
void
_gtk_pixel_cache_set_position (GtkPixelCache *cache,
cairo_rectangle_int_t *view_rect,
cairo_rectangle_int_t *canvas_rect)
{
cairo_rectangle_int_t r, view_pos;
cairo_region_t *copy_region;
int new_surf_x, new_surf_y;
cairo_t *backing_cr;
if (cache->surface == NULL)
return;
/* Position of view inside canvas */
view_pos.x = -canvas_rect->x;
view_pos.y = -canvas_rect->y;
view_pos.width = view_rect->width;
view_pos.height = view_rect->height;
/* Reposition so all is visible */
if (view_pos.x < cache->surface_x ||
view_pos.x + view_pos.width >
cache->surface_x + cache->surface_w ||
view_pos.y < cache->surface_y ||
view_pos.y + view_pos.height >
cache->surface_y + cache->surface_h)
{
new_surf_x = cache->surface_x;
if (view_pos.x < cache->surface_x)
new_surf_x = MAX (view_pos.x + view_pos.width - cache->surface_w, 0);
else if (view_pos.x + view_pos.width >
cache->surface_x + cache->surface_w)
new_surf_x = MIN (view_pos.x, canvas_rect->width - cache->surface_w);
new_surf_y = cache->surface_y;
if (view_pos.y < cache->surface_y)
new_surf_y = MAX (view_pos.y + view_pos.height - cache->surface_h, 0);
else if (view_pos.y + view_pos.height >
cache->surface_y + cache->surface_h)
new_surf_y = MIN (view_pos.y, canvas_rect->height - cache->surface_h);
r.x = 0;
r.y = 0;
r.width = cache->surface_w;
r.height = cache->surface_h;
copy_region = cairo_region_create_rectangle (&r);
if (cache->surface_dirty)
{
cairo_region_subtract (copy_region, cache->surface_dirty);
cairo_region_destroy (cache->surface_dirty);
cache->surface_dirty = NULL;
}
cairo_region_translate (copy_region,
cache->surface_x - new_surf_x,
cache->surface_y - new_surf_y);
cairo_region_intersect_rectangle (copy_region, &r);
backing_cr = cairo_create (cache->surface);
gdk_cairo_region (backing_cr, copy_region);
cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE);
cairo_clip (backing_cr);
cairo_push_group (backing_cr);
cairo_set_source_surface (backing_cr, cache->surface,
cache->surface_x - new_surf_x,
cache->surface_y - new_surf_y);
cairo_paint (backing_cr);
cairo_pop_group_to_source (backing_cr);
cairo_paint (backing_cr);
cairo_destroy (backing_cr);
cache->surface_x = new_surf_x;
cache->surface_y = new_surf_y;
cairo_region_xor_rectangle (copy_region, &r);
cache->surface_dirty = copy_region;
}
}
void
_gtk_pixel_cache_repaint (GtkPixelCache *cache,
GtkPixelCacheDrawFunc draw,
cairo_rectangle_int_t *view_rect,
cairo_rectangle_int_t *canvas_rect,
gpointer user_data)
{
cairo_t *backing_cr;
if (cache->surface &&
cache->surface_dirty &&
!cairo_region_is_empty (cache->surface_dirty))
{
backing_cr = cairo_create (cache->surface);
gdk_cairo_region (backing_cr, cache->surface_dirty);
cairo_clip (backing_cr);
cairo_translate (backing_cr,
-cache->surface_x - canvas_rect->x - view_rect->x,
-cache->surface_y - canvas_rect->y - view_rect->y);
cairo_set_source_rgba (backing_cr,
0.0, 0, 0, 0.0);
cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (backing_cr);
cairo_set_operator (backing_cr, CAIRO_OPERATOR_OVER);
cairo_save (backing_cr);
draw (backing_cr, user_data);
cairo_restore (backing_cr);
#ifdef G_ENABLE_DEBUG
if (gtk_get_debug_flags () & GTK_DEBUG_PIXEL_CACHE)
{
GdkRGBA colors[] = {
{ 1, 0, 0, 0.08},
{ 0, 1, 0, 0.08},
{ 0, 0, 1, 0.08},
{ 1, 0, 1, 0.08},
{ 1, 1, 0, 0.08},
{ 0, 1, 1, 0.08},
};
static int current_color = 0;
gdk_cairo_set_source_rgba (backing_cr, &colors[(current_color++) % G_N_ELEMENTS (colors)]);
cairo_paint (backing_cr);
}
#endif
cairo_destroy (backing_cr);
}
if (cache->surface_dirty)
{
cairo_region_destroy (cache->surface_dirty);
cache->surface_dirty = NULL;
}
}
static gboolean
blow_cache_cb (gpointer user_data)
{
GtkPixelCache *cache = user_data;
cache->timeout_tag = 0;
if (cache->surface)
{
cairo_surface_destroy (cache->surface);
cache->surface = NULL;
if (cache->surface_dirty)
cairo_region_destroy (cache->surface_dirty);
cache->surface_dirty = NULL;
}
return G_SOURCE_REMOVE;
}
void
_gtk_pixel_cache_draw (GtkPixelCache *cache,
cairo_t *cr,
GdkWindow *window,
/* View position in widget coords */
cairo_rectangle_int_t *view_rect,
/* Size and position of canvas in view coords */
cairo_rectangle_int_t *canvas_rect,
GtkPixelCacheDrawFunc draw,
gpointer user_data)
{
if (cache->timeout_tag)
g_source_remove (cache->timeout_tag);
cache->timeout_tag = g_timeout_add_seconds (BLOW_CACHE_TIMEOUT_SEC,
blow_cache_cb, cache);
_gtk_pixel_cache_create_surface_if_needed (cache, window,
view_rect, canvas_rect);
_gtk_pixel_cache_set_position (cache, view_rect, canvas_rect);
_gtk_pixel_cache_repaint (cache, draw, view_rect, canvas_rect, user_data);
if (cache->surface &&
/* Don't use backing surface if rendering elsewhere */
cairo_surface_get_type (cache->surface) == cairo_surface_get_type (cairo_get_target (cr)))
{
cairo_save (cr);
cairo_set_source_surface (cr, cache->surface,
cache->surface_x + view_rect->x + canvas_rect->x,
cache->surface_y + view_rect->y + canvas_rect->y);
cairo_rectangle (cr, view_rect->x, view_rect->y,
view_rect->width, view_rect->height);
cairo_fill (cr);
cairo_restore (cr);
}
else
{
cairo_rectangle (cr,
view_rect->x, view_rect->y,
view_rect->width, view_rect->height);
cairo_clip (cr);
draw (cr, user_data);
}
}
+48
View File
@@ -0,0 +1,48 @@
/*
* Copyright © 2013 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Alexander Larsson <alexl@gnome.org>
*/
#ifndef __GTK_PIXEL_CACHE_PRIVATE_H__
#define __GTK_PIXEL_CACHE_PRIVATE_H__
#include <glib-object.h>
#include <gtkwidget.h>
G_BEGIN_DECLS
typedef struct _GtkPixelCache GtkPixelCache;
typedef void (*GtkPixelCacheDrawFunc) (cairo_t *cr,
gpointer user_data);
GtkPixelCache *_gtk_pixel_cache_new (void);
void _gtk_pixel_cache_free (GtkPixelCache *cache);
void _gtk_pixel_cache_invalidate (GtkPixelCache *cache,
cairo_region_t *region);
void _gtk_pixel_cache_draw (GtkPixelCache *cache,
cairo_t *cr,
GdkWindow *window,
cairo_rectangle_int_t *view_rect,
cairo_rectangle_int_t *canvas_rect,
GtkPixelCacheDrawFunc draw,
gpointer user_data);
G_END_DECLS
#endif /* __GTK_PIXEL_CACHE_PRIVATE_H__ */
+208 -71
View File
@@ -170,6 +170,7 @@ struct _GtkPlacesSidebar {
char *drop_target_uri;
guint show_desktop : 1;
guint show_connect_to_server : 1;
};
struct _GtkPlacesSidebarClass {
@@ -180,10 +181,12 @@ struct _GtkPlacesSidebarClass {
GtkPlacesOpenFlags open_flags);
void (* populate_popup) (GtkPlacesSidebar *sidebar,
GtkMenu *menu,
GFile *selected_item);
GFile *selected_item,
GVolume *selected_volume);
void (* show_error_message) (GtkPlacesSidebar *sidebar,
const char *primary,
const char *secondary);
void (* show_connect_to_server) (GtkPlacesSidebar *sidebar);
GdkDragAction (* drag_action_requested) (GtkPlacesSidebar *sidebar,
GdkDragContext *context,
GFile *dest_file,
@@ -221,6 +224,7 @@ typedef enum {
PLACES_MOUNTED_VOLUME,
PLACES_BOOKMARK,
PLACES_HEADING,
PLACES_CONNECT_TO_SERVER,
PLACES_DROP_FEEDBACK
} PlaceType;
@@ -235,6 +239,7 @@ enum {
OPEN_LOCATION,
POPULATE_POPUP,
SHOW_ERROR_MESSAGE,
SHOW_CONNECT_TO_SERVER,
DRAG_ACTION_REQUESTED,
DRAG_ACTION_ASK,
DRAG_PERFORM_DROP,
@@ -245,15 +250,17 @@ enum {
PROP_LOCATION = 1,
PROP_OPEN_FLAGS,
PROP_SHOW_DESKTOP,
PROP_SHOW_CONNECT_TO_SERVER,
NUM_PROPERTIES,
};
/* Names for themed icons */
#define ICON_NAME_HOME "user-home-symbolic"
#define ICON_NAME_DESKTOP "user-desktop"
#define ICON_NAME_FILESYSTEM "drive-harddisk-symbolic"
#define ICON_NAME_EJECT "media-eject-symbolic"
#define ICON_NAME_NETWORK "network-workgroup-symbolic"
#define ICON_NAME_HOME "user-home-symbolic"
#define ICON_NAME_DESKTOP "user-desktop"
#define ICON_NAME_FILESYSTEM "drive-harddisk-symbolic"
#define ICON_NAME_EJECT "media-eject-symbolic"
#define ICON_NAME_NETWORK "network-workgroup-symbolic"
#define ICON_NAME_NETWORK_SERVER "network-server-symbolic"
#define ICON_NAME_FOLDER_DESKTOP "user-desktop"
#define ICON_NAME_FOLDER_DOCUMENTS "folder-documents-symbolic"
@@ -336,10 +343,10 @@ emit_open_location (GtkPlacesSidebar *sidebar, GFile *location, GtkPlacesOpenFla
}
static void
emit_populate_popup (GtkPlacesSidebar *sidebar, GtkMenu *menu, GFile *selected_item)
emit_populate_popup (GtkPlacesSidebar *sidebar, GtkMenu *menu, GFile *selected_item, GVolume *selected_volume)
{
g_signal_emit (sidebar, places_sidebar_signals[POPULATE_POPUP], 0,
menu, selected_item);
menu, selected_item, selected_volume);
}
static void
@@ -349,6 +356,12 @@ emit_show_error_message (GtkPlacesSidebar *sidebar, const char *primary, const c
primary, secondary);
}
static void
emit_show_connect_to_server (GtkPlacesSidebar *sidebar)
{
g_signal_emit (sidebar, places_sidebar_signals[SHOW_CONNECT_TO_SERVER], 0);
}
static GdkDragAction
emit_drag_action_requested (GtkPlacesSidebar *sidebar,
GdkDragContext *context,
@@ -1062,6 +1075,16 @@ update_places (GtkPlacesSidebar *sidebar)
_("Browse the contents of the network"));
g_object_unref (icon);
if (sidebar->show_connect_to_server) {
icon = g_themed_icon_new (ICON_NAME_NETWORK_SERVER);
add_place (sidebar, PLACES_CONNECT_TO_SERVER,
SECTION_NETWORK,
_("Connect to Server"), icon, NULL,
NULL, NULL, NULL, 0,
_("Connect to a network server address"));
g_object_unref (icon);
}
network_volumes = g_list_reverse (network_volumes);
for (l = network_volumes; l != NULL; l = l->next) {
volume = l->data;
@@ -2186,54 +2209,79 @@ mount_volume (GtkPlacesSidebar *sidebar, GVolume *volume)
g_volume_mount (volume, 0, mount_op, NULL, volume_mount_cb, sidebar);
}
static void
open_selected_volume (GtkPlacesSidebar *sidebar,
GtkTreeModel *model,
GtkTreeIter *iter,
GtkPlacesOpenFlags open_flags)
{
GDrive *drive;
GVolume *volume;
gtk_tree_model_get (model, iter,
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
-1);
if (volume != NULL && !sidebar->mounting) {
sidebar->mounting = TRUE;
sidebar->go_to_after_mount_open_flags = open_flags;
mount_volume (sidebar, volume);
} else if (volume == NULL && drive != NULL &&
(g_drive_can_start (drive) || g_drive_can_start_degraded (drive))) {
GMountOperation *mount_op;
mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_from_bookmark_cb, NULL);
g_object_unref (mount_op);
}
if (drive != NULL)
g_object_unref (drive);
if (volume != NULL)
g_object_unref (volume);
}
static void
open_selected_uri (GtkPlacesSidebar *sidebar,
const gchar *uri,
GtkPlacesOpenFlags open_flags)
{
GFile *location;
location = g_file_new_for_uri (uri);
emit_open_location (sidebar, location, open_flags);
g_object_unref (location);
}
static void
open_selected_bookmark (GtkPlacesSidebar *sidebar,
GtkTreeModel *model,
GtkTreeIter *iter,
GtkPlacesOpenFlags open_flags)
{
GFile *location;
char *uri;
PlaceType place_type;
if (!iter) {
return;
}
gtk_tree_model_get (model, iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1);
gtk_tree_model_get (model, iter,
PLACES_SIDEBAR_COLUMN_URI, &uri,
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &place_type,
-1);
if (uri != NULL) {
location = g_file_new_for_uri (uri);
emit_open_location (sidebar, location, open_flags);
g_object_unref (location);
open_selected_uri (sidebar, uri, open_flags);
g_free (uri);
} else if (place_type == PLACES_CONNECT_TO_SERVER) {
emit_show_connect_to_server (sidebar);
} else {
GDrive *drive;
GVolume *volume;
gtk_tree_model_get (model, iter,
PLACES_SIDEBAR_COLUMN_DRIVE, &drive,
PLACES_SIDEBAR_COLUMN_VOLUME, &volume,
-1);
if (volume != NULL && !sidebar->mounting) {
sidebar->mounting = TRUE;
sidebar->go_to_after_mount_open_flags = open_flags;
mount_volume (sidebar, volume);
} else if (volume == NULL && drive != NULL &&
(g_drive_can_start (drive) || g_drive_can_start_degraded (drive))) {
GMountOperation *mount_op;
mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
g_drive_start (drive, G_DRIVE_START_NONE, mount_op, NULL, drive_start_from_bookmark_cb, sidebar);
g_object_unref (mount_op);
}
g_clear_object (&drive);
g_clear_object (&volume);
open_selected_volume (sidebar, model, iter, open_flags);
}
}
@@ -3161,9 +3209,10 @@ bookmarks_build_popup_menu (GtkPlacesSidebar *sidebar)
else
file = NULL;
emit_populate_popup (sidebar, GTK_MENU (sidebar->popup_menu), file);
emit_populate_popup (sidebar, GTK_MENU (sidebar->popup_menu), file, sel_info.volume);
g_object_unref (file);
if (file)
g_object_unref (file);
free_selection_info (&sel_info);
}
@@ -3292,7 +3341,8 @@ bookmarks_button_release_event_cb (GtkWidget *widget,
PLACES_SIDEBAR_COLUMN_ROW_TYPE, &row_type,
-1);
if (row_type != PLACES_HEADING) {
if (row_type != PLACES_HEADING
&& row_type != PLACES_CONNECT_TO_SERVER) {
bookmarks_popup_menu (sidebar, event);
}
}
@@ -3477,7 +3527,9 @@ places_sidebar_sort_func (GtkTreeModel *model,
g_free (name_a);
g_free (name_b);
}
} else if (place_type_a == PLACES_CONNECT_TO_SERVER) {
retval = 1;
}
return retval;
}
@@ -3516,12 +3568,15 @@ hostname_proxy_new_cb (GObject *source_object,
{
GtkPlacesSidebar *sidebar = user_data;
GError *error = NULL;
GDBusProxy *proxy;
sidebar->hostnamed_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
sidebar->hostnamed_proxy = proxy;
g_clear_object (&sidebar->hostnamed_cancellable);
g_object_unref (sidebar);
if (error != NULL) {
g_debug ("Failed to create D-Bus proxy: %s", error->message);
g_error_free (error);
@@ -3781,7 +3836,7 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
"org.freedesktop.hostname1",
sidebar->hostnamed_cancellable,
hostname_proxy_new_cb,
g_object_ref (sidebar));
sidebar);
sidebar->drop_state = DROP_STATE_NORMAL;
sidebar->new_bookmark_index = -1;
@@ -3805,6 +3860,9 @@ gtk_places_sidebar_set_property (GObject *obj,
case PROP_SHOW_DESKTOP:
gtk_places_sidebar_set_show_desktop (sidebar, g_value_get_boolean (value));
break;
case PROP_SHOW_CONNECT_TO_SERVER:
gtk_places_sidebar_set_show_connect_to_server (sidebar, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
break;
@@ -3829,6 +3887,9 @@ gtk_places_sidebar_get_property (GObject *obj,
case PROP_SHOW_DESKTOP:
g_value_set_boolean (value, gtk_places_sidebar_get_show_desktop (sidebar));
break;
case PROP_SHOW_CONNECT_TO_SERVER:
g_value_set_boolean (value, gtk_places_sidebar_get_show_connect_to_server (sidebar));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
break;
@@ -3931,7 +3992,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
* location; for example, a file manager should show a list of files in
* the specified location.
*
* Since: 3.8
* Since: 3.10
*/
places_sidebar_signals [OPEN_LOCATION] =
g_signal_new (I_("open-location"),
@@ -3948,7 +4009,8 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
* GtkPlacesSidebar::populate-popup:
* @sidebar: the object which received the signal.
* @menu: a #GtkMenu.
* @selected_item: #GFile with the item to which the menu should refer.
* @selected_item: #GFile with the item to which the menu should refer, or #NULL in the case of a @selected_volume.
* @selected_volume: #GVolume if the selected item is a volume, or #NULL if it is a file.
*
* The places sidebar emits this signal when the user invokes a contextual
* menu on one of its items. In the signal handler, the application may
@@ -3960,11 +4022,16 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
* gtk_places_sidebar_get_location() to get the file to which the item
* refers.
*
* The @selected_item argument may be #NULL in case the selection refers to
* a volume. In this case, @selected_volume will be non-NULL. In this case,
* the calling application will have to g_object_ref() the @selected_volume and
* keep it around for the purposes of its menu item's "activate" callback.
*
* The @menu and all its menu items are destroyed after the user
* dismisses the menu. The menu is re-created (and thus, this signal is
* emitted) every time the user activates the contextual menu.
*
* Since: 3.8
* Since: 3.10
*/
places_sidebar_signals [POPULATE_POPUP] =
g_signal_new (I_("populate-popup"),
@@ -3972,8 +4039,9 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkPlacesSidebarClass, populate_popup),
NULL, NULL,
_gtk_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE, 2,
_gtk_marshal_VOID__OBJECT_OBJECT_OBJECT,
G_TYPE_NONE, 3,
G_TYPE_OBJECT,
G_TYPE_OBJECT,
G_TYPE_OBJECT);
@@ -3988,7 +4056,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
* refer to mounting or unmounting media, for example, when a drive
* cannot be started for some reason.
*
* Since: 3.8
* Since: 3.10
*/
places_sidebar_signals [SHOW_ERROR_MESSAGE] =
g_signal_new (I_("show-error-message"),
@@ -4001,6 +4069,27 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
G_TYPE_STRING,
G_TYPE_STRING);
/**
* GtkPlacesSidebar::show-connect-to-server:
* @sidebar: the object which received the signal.
*
* The places sidebar emits this signal when it needs the calling
* application to present an way to connect directly to a network server.
* For example, the application may bring up a dialog box asking for
* a URL like "sftp://ftp.example.com". It is up to the application to create
* the corresponding mount by using, for example, g_file_mount_enclosing_volume().
*
* Since: 3.10
*/
places_sidebar_signals [SHOW_CONNECT_TO_SERVER] =
g_signal_new (I_("show-connect-to-server"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkPlacesSidebarClass, show_connect_to_server),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkPlacesSidebar::drag-action-requested:
* @sidebar: the object which received the signal.
@@ -4022,7 +4111,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
* or #GDK_ACTION_MOVE, or 0 if no action is allowed here (i.e. drops
* are not allowed in the specified @dest_file).
*
* Since: 3.8
* Since: 3.10
*/
places_sidebar_signals [DRAG_ACTION_REQUESTED] =
g_signal_new (I_("drag-action-requested"),
@@ -4047,7 +4136,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
* Return value: the final drag action that the sidebar should pass to the drag side
* of the drag-and-drop operation.
*
* Since: 3.8
* Since: 3.10
*/
places_sidebar_signals [DRAG_ACTION_ASK] =
g_signal_new (I_("drag-action-ask"),
@@ -4072,7 +4161,7 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
* @source_file_list has the list of files that are dropped into it and
* which should be copied/moved/etc. based on the specified @action.
*
* Since: 3.8
* Since: 3.10
*/
places_sidebar_signals [DRAG_PERFORM_DROP] =
g_signal_new (I_("drag-perform-drop"),
@@ -4088,21 +4177,27 @@ gtk_places_sidebar_class_init (GtkPlacesSidebarClass *class)
properties[PROP_LOCATION] =
g_param_spec_object ("location",
P_("Location to select"),
P_("Location to Select"),
P_("The location to highlight in the sidebar"),
G_TYPE_FILE,
G_PARAM_READWRITE);
properties[PROP_OPEN_FLAGS] =
g_param_spec_flags ("open-flags",
P_("The open modes supported for this widget"),
P_("The set of open modes supported for this widget"),
P_("Open Flags"),
P_("Modes in which the calling application can open locations selected in the sidebar"),
GTK_TYPE_PLACES_OPEN_FLAGS,
GTK_PLACES_OPEN_NORMAL,
G_PARAM_READWRITE);
properties[PROP_SHOW_DESKTOP] =
g_param_spec_boolean ("show-desktop",
P_("Whether to show desktop"),
P_("Whether the sidebar includes a builtin shortcut to the desktop folder"),
P_("Show 'Desktop'"),
P_("Whether the sidebar includes a builtin shortcut to the Desktop folder"),
FALSE,
G_PARAM_READWRITE);
properties[PROP_SHOW_CONNECT_TO_SERVER] =
g_param_spec_boolean ("show-connect-to-server",
P_("Show 'Connect to Server'"),
P_("Whether the sidebar includes a builtin shortcut to a 'Connect to server' dialog"),
FALSE,
G_PARAM_READWRITE);
@@ -4224,7 +4319,7 @@ shortcuts_model_new (GtkPlacesSidebar *sidebar)
* Passing 0 for @flags will cause #GTK_PLACES_OPEN_NORMAL to always be sent
* to callbacks for the "open-location" signal.
*
* Since: 3.8
* Since: 3.10
*/
void
gtk_places_sidebar_set_open_flags (GtkPlacesSidebar *sidebar, GtkPlacesOpenFlags flags)
@@ -4256,7 +4351,7 @@ gtk_places_sidebar_get_open_flags (GtkPlacesSidebar *sidebar)
* places, or it will unhighlight everything if the @location is not among the
* places in the list.
*
* Since: 3.8
* Since: 3.10
*/
void
gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar, GFile *location)
@@ -4316,7 +4411,7 @@ gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar, GFile *location)
* Returns: (transfer full): a GFile with the selected location, or #NULL if nothing is visually
* selected.
*
* Since: 3.8
* Since: 3.10
*/
GFile *
gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar)
@@ -4351,7 +4446,7 @@ gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar)
* An application may want to turn this on if the desktop environment actually supports the
* notion of a desktop.
*
* Since: 3.8
* Since: 3.10
*/
void
gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar, gboolean show_desktop)
@@ -4374,7 +4469,7 @@ gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar, gboolean show_de
*
* Return value: %TRUE if the sidebar will display a builtin shortcut to the desktop folder.
*
* Since: 3.8
* Since: 3.10
*/
gboolean
gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar)
@@ -4384,6 +4479,48 @@ gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar)
return sidebar->show_desktop;
}
/**
* gtk_places_sidebar_set_show_connect_to_server:
* @sidebar: a places sidebar
* @show_connect_to_server: whether to show an item for the Connect to Server command
*
* Sets whether the @sidebar should show an item for connecting to a network server; this is off by default.
* An application may want to turn this on if it implements a way for the user to connect
* to network servers directly.
*
* Since: 3.10
*/
void
gtk_places_sidebar_set_show_connect_to_server (GtkPlacesSidebar *sidebar, gboolean show_connect_to_server)
{
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
show_connect_to_server = !!show_connect_to_server;
if (sidebar->show_connect_to_server != show_connect_to_server) {
sidebar->show_connect_to_server = show_connect_to_server;
update_places (sidebar);
g_object_notify_by_pspec (G_OBJECT (sidebar), properties[PROP_SHOW_CONNECT_TO_SERVER]);
}
}
/**
* gtk_places_sidebar_get_show_connect_to_server:
* @sidebar: a places sidebar
*
* Returns the value previously set with gtk_places_sidebar_set_show_connect_to_server()
*
* Return value: %TRUE if the sidebar will display a "Connect to Server" item.
*
* Since: 3.10
*/
gboolean
gtk_places_sidebar_get_show_connect_to_server (GtkPlacesSidebar *sidebar)
{
g_return_val_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar), FALSE);
return sidebar->show_connect_to_server;
}
static GSList *
find_shortcut_link (GtkPlacesSidebar *sidebar, GFile *location)
{
@@ -4416,7 +4553,7 @@ find_shortcut_link (GtkPlacesSidebar *sidebar, GFile *location)
* is called multiple times with different locations, then they are added
* to the sidebar's list in the same order as the function is called.
*
* Since: 3.8
* Since: 3.10
*/
void
gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar, GFile *location)
@@ -4439,7 +4576,7 @@ gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar, GFile *location)
* inserted with gtk_places_sidebar_add_shortcut(). If the @location is not a
* shortcut in the sidebar, then nothing is done.
*
* Since: 3.8
* Since: 3.10
*/
void
gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar, GFile *location)
@@ -4472,7 +4609,7 @@ gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar, GFile *location)
* g_slist_free_full (list, (GDestroyNotify) g_object_unref);
* ]|
*
* Since: 3.8
* Since: 3.10
*/
GSList *
gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar)
@@ -4495,7 +4632,7 @@ gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar)
* #NULL if no such index exist. Note that the indices start at 0, even though
* the file chooser starts them with the keyboard shortcut "Alt-1".
*
* Since: 3.8
* Since: 3.10
*/
GFile *
gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar, int n)
+22 -12
View File
@@ -77,23 +77,33 @@ typedef enum {
GTK_PLACES_OPEN_NEW_WINDOW = 1 << 2
} GtkPlacesOpenFlags;
GType gtk_places_sidebar_get_type (void);
GtkWidget *gtk_places_sidebar_new (void);
GType gtk_places_sidebar_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_places_sidebar_new (void);
GtkPlacesOpenFlags gtk_places_sidebar_get_open_flags (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_open_flags (GtkPlacesSidebar *sidebar, GtkPlacesOpenFlags flags);
GtkPlacesOpenFlags gtk_places_sidebar_get_open_flags (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_open_flags (GtkPlacesSidebar *sidebar,
GtkPlacesOpenFlags flags);
GFile *gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar, GFile *location);
GFile * gtk_places_sidebar_get_location (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_location (GtkPlacesSidebar *sidebar,
GFile *location);
gboolean gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar, gboolean show_desktop);
gboolean gtk_places_sidebar_get_show_desktop (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_show_desktop (GtkPlacesSidebar *sidebar,
gboolean show_desktop);
void gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar, GFile *location);
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar, GFile *location);
GSList *gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar);
gboolean gtk_places_sidebar_get_show_connect_to_server (GtkPlacesSidebar *sidebar);
void gtk_places_sidebar_set_show_connect_to_server (GtkPlacesSidebar *sidebar,
gboolean show_connect_to_server);
GFile *gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar, int n);
void gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar,
GFile *location);
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
GFile *location);
GSList * gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar);
GFile * gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar,
gint n);
G_END_DECLS
+2
View File
@@ -37,6 +37,8 @@ G_BEGIN_DECLS
#define GTK_PARAM_WRITABLE G_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB
#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB
#define OPPOSITE_ORIENTATION(_orientation) (1 - (_orientation))
#ifdef G_DISABLE_CAST_CHECKS
/* This is true for debug no and minimum */
#define gtk_internal_return_if_fail(__expr) G_STMT_START{ (void)0; }G_STMT_END
+7 -1
View File
@@ -903,6 +903,7 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
gint indicator_size, indicator_spacing;
gint focus_width;
gint focus_pad;
gint baseline;
guint border_width;
gboolean interior_focus;
@@ -923,9 +924,14 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
_gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
gtk_widget_get_allocation (widget, &allocation);
baseline = gtk_widget_get_allocated_baseline (widget);
x = indicator_spacing + border_width;
y = (allocation.height - indicator_size) / 2;
if (baseline == -1)
y = (allocation.height - indicator_size) / 2;
else
y = CLAMP (baseline - indicator_size * button->priv->baseline_align,
0, allocation.height - indicator_size);
child = gtk_bin_get_child (GTK_BIN (check_button));
if (!interior_focus || !(child && gtk_widget_get_visible (child)))
+896
View File
@@ -0,0 +1,896 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Copyright (c) 2013 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author: Alexander Larsson <alexl@redhat.com>
*
*/
#include "config.h"
#include "gtkrevealer.h"
#include <gdk/gdk.h>
#include "gtktypebuiltins.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include <math.h>
/**
* SECTION:gtkrevealer
* @Short_description: Hide and show with animation
* @Title: GtkRevealer
* @See_also: #GtkExpander
*
* The GtkRevealer widget is a container which animates
* the transition of its child from invisible to visible.
*
* The style of transition can be controlled with
* gtk_revealer_set_transition_type().
*
* The GtkRevealer widget was added in GTK+ 3.10.
*/
/**
* GtkRevealerTransitionType:
* @GTK_REVEALER_TRANSITION_TYPE_NONE: No transition
* @GTK_REVEALER_TRANSITION_TYPE_CROSSFADE: Fade in
* @GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT: Slide in from the left
* @GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT: Slide in from the right
* @GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP: Slide in from the bottom
* @GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN: Slide in from the top
*
* These enumeration values describe the possible transitions
* when the child of a #GtkRevealer widget is shown or hidden.
*/
enum {
PROP_0,
PROP_TRANSITION_TYPE,
PROP_TRANSITION_DURATION,
PROP_REVEAL_CHILD,
PROP_CHILD_REVEALED
};
struct _GtkRevealerPrivate {
GtkRevealerTransitionType transition_type;
guint transition_duration;
GdkWindow* bin_window;
GdkWindow* view_window;
gdouble current_pos;
gdouble source_pos;
gdouble target_pos;
guint tick_id;
gint64 start_time;
gint64 end_time;
};
static void gtk_revealer_real_realize (GtkWidget *widget);
static void gtk_revealer_real_unrealize (GtkWidget *widget);
static void gtk_revealer_real_add (GtkContainer *widget,
GtkWidget *child);
static void gtk_revealer_real_style_updated (GtkWidget *widget);
static void gtk_revealer_real_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_revealer_real_map (GtkWidget *widget);
static void gtk_revealer_real_unmap (GtkWidget *widget);
static gboolean gtk_revealer_real_draw (GtkWidget *widget,
cairo_t *cr);
static void gtk_revealer_real_get_preferred_height (GtkWidget *widget,
gint *minimum_height,
gint *natural_height);
static void gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height);
static void gtk_revealer_real_get_preferred_width (GtkWidget *widget,
gint *minimum_width,
gint *natural_width);
static void gtk_revealer_real_get_preferred_width_for_height (GtkWidget *widget,
gint height,
gint *minimum_width,
gint *natural_width);
G_DEFINE_TYPE (GtkRevealer, gtk_revealer, GTK_TYPE_BIN);
static void
gtk_revealer_init (GtkRevealer *revealer)
{
GtkRevealerPrivate *priv;
priv = G_TYPE_INSTANCE_GET_PRIVATE (revealer, GTK_TYPE_REVEALER, GtkRevealerPrivate);
revealer->priv = priv;
priv->transition_type = GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN;
priv->transition_duration = 250;
priv->current_pos = 0.0;
priv->target_pos = 0.0;
gtk_widget_set_has_window ((GtkWidget*) revealer, TRUE);
gtk_widget_set_redraw_on_allocate ((GtkWidget*) revealer, FALSE);
}
static void
gtk_revealer_finalize (GObject *obj)
{
GtkRevealer *revealer = GTK_REVEALER (obj);
GtkRevealerPrivate *priv = revealer->priv;
if (priv->tick_id != 0)
gtk_widget_remove_tick_callback (GTK_WIDGET (revealer), priv->tick_id);
priv->tick_id = 0;
G_OBJECT_CLASS (gtk_revealer_parent_class)->finalize (obj);
}
static void
gtk_revealer_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkRevealer *revealer = GTK_REVEALER (object);
switch (property_id)
{
case PROP_TRANSITION_TYPE:
g_value_set_enum (value, gtk_revealer_get_transition_type (revealer));
break;
case PROP_TRANSITION_DURATION:
g_value_set_uint (value, gtk_revealer_get_transition_duration (revealer));
break;
case PROP_REVEAL_CHILD:
g_value_set_boolean (value, gtk_revealer_get_reveal_child (revealer));
break;
case PROP_CHILD_REVEALED:
g_value_set_boolean (value, gtk_revealer_get_child_revealed (revealer));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_revealer_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkRevealer *revealer = GTK_REVEALER (object);
switch (property_id)
{
case PROP_TRANSITION_TYPE:
gtk_revealer_set_transition_type (revealer, g_value_get_enum (value));
break;
case PROP_TRANSITION_DURATION:
gtk_revealer_set_transition_duration (revealer, g_value_get_uint (value));
break;
case PROP_REVEAL_CHILD:
gtk_revealer_set_reveal_child (revealer, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_revealer_class_init (GtkRevealerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
object_class->get_property = gtk_revealer_get_property;
object_class->set_property = gtk_revealer_set_property;
object_class->finalize = gtk_revealer_finalize;
widget_class->realize = gtk_revealer_real_realize;
widget_class->unrealize = gtk_revealer_real_unrealize;
widget_class->style_updated = gtk_revealer_real_style_updated;
widget_class->size_allocate = gtk_revealer_real_size_allocate;
widget_class->map = gtk_revealer_real_map;
widget_class->unmap = gtk_revealer_real_unmap;
widget_class->draw = gtk_revealer_real_draw;
widget_class->get_preferred_height = gtk_revealer_real_get_preferred_height;
widget_class->get_preferred_height_for_width = gtk_revealer_real_get_preferred_height_for_width;
widget_class->get_preferred_width = gtk_revealer_real_get_preferred_width;
widget_class->get_preferred_width_for_height = gtk_revealer_real_get_preferred_width_for_height;
container_class->add = gtk_revealer_real_add;
g_object_class_install_property (object_class,
PROP_TRANSITION_TYPE,
g_param_spec_enum ("transition-type",
P_("Transition type"),
P_("The type of animation used to transition"),
GTK_TYPE_REVEALER_TRANSITION_TYPE,
GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_TRANSITION_DURATION,
g_param_spec_uint ("transition-duration",
P_("Transition duration"),
P_("The animation duration, in milliseconds"),
0, G_MAXUINT,
250,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_REVEAL_CHILD,
g_param_spec_boolean ("reveal-child",
P_("Reveal Child"),
P_("Whether the container should reveal the child"),
FALSE,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_CHILD_REVEALED,
g_param_spec_boolean ("child-revealed",
P_("Child Revealed"),
P_("Whether the child is revealed and the animation target reached"),
FALSE,
G_PARAM_READABLE));
g_type_class_add_private (klass, sizeof (GtkRevealerPrivate));
}
GtkWidget *
gtk_revealer_new (void)
{
return g_object_new (GTK_TYPE_REVEALER, NULL);
}
static GtkRevealerTransitionType
effective_transition (GtkRevealer *revealer)
{
GtkRevealerPrivate *priv = revealer->priv;
if (gtk_widget_get_direction (GTK_WIDGET (revealer)) == GTK_TEXT_DIR_RTL)
{
if (priv->transition_type == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT)
return GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT;
else if (priv->transition_type == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
return GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT;
}
return priv->transition_type;
}
static void
gtk_revealer_get_child_allocation (GtkRevealer *revealer,
GtkAllocation *allocation,
GtkAllocation *child_allocation)
{
GtkWidget *child;
GtkRevealerTransitionType transition;
g_return_if_fail (revealer != NULL);
g_return_if_fail (allocation != NULL);
child_allocation->x = 0;
child_allocation->y = 0;
child_allocation->width = allocation->width;
child_allocation->height = allocation->height;
child = gtk_bin_get_child (GTK_BIN (revealer));
if (child != NULL && gtk_widget_get_visible (child))
{
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
gtk_widget_get_preferred_width_for_height (child, child_allocation->height, NULL,
&child_allocation->width);
else
gtk_widget_get_preferred_height_for_width (child, child_allocation->width, NULL,
&child_allocation->height);
}
}
static void
gtk_revealer_real_realize (GtkWidget *widget)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
GtkAllocation allocation;
GdkWindowAttr attributes = { 0 };
GdkWindowAttributesType attributes_mask;
GtkAllocation child_allocation;
GtkWidget *child;
GtkStyleContext *context;
GtkRevealerTransitionType transition;
gtk_widget_set_realized (widget, TRUE);
gtk_widget_get_allocation (widget, &allocation);
attributes.x = allocation.x;
attributes.y = allocation.y;
attributes.width = allocation.width;
attributes.height = allocation.height;
attributes.window_type = GDK_WINDOW_CHILD;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (widget);
attributes.event_mask =
gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
attributes_mask = (GDK_WA_X | GDK_WA_Y) | GDK_WA_VISUAL;
priv->view_window =
gdk_window_new (gtk_widget_get_parent_window ((GtkWidget*) revealer),
&attributes, attributes_mask);
gtk_widget_set_window (widget, priv->view_window);
gtk_widget_register_window (widget, priv->view_window);
gtk_revealer_get_child_allocation (revealer, &allocation, &child_allocation);
attributes.x = 0;
attributes.y = 0;
attributes.width = child_allocation.width;
attributes.height = child_allocation.height;
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
attributes.y = allocation.height - child_allocation.height;
else if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
attributes.x = allocation.width - child_allocation.width;
priv->bin_window =
gdk_window_new (priv->view_window, &attributes, attributes_mask);
gtk_widget_register_window (widget, priv->bin_window);
child = gtk_bin_get_child (GTK_BIN (revealer));
if (child != NULL)
gtk_widget_set_parent_window (child, priv->bin_window);
context = gtk_widget_get_style_context (widget);
gtk_style_context_set_background (context, priv->view_window);
gtk_style_context_set_background (context, priv->bin_window);
gdk_window_show (priv->bin_window);
}
static void
gtk_revealer_real_unrealize (GtkWidget *widget)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
gtk_widget_unregister_window (widget, priv->bin_window);
gdk_window_destroy (priv->bin_window);
priv->view_window = NULL;
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->unrealize (widget);
}
static void
gtk_revealer_real_add (GtkContainer *container,
GtkWidget *child)
{
GtkRevealer *revealer = GTK_REVEALER (container);
GtkRevealerPrivate *priv = revealer->priv;
g_return_if_fail (child != NULL);
gtk_widget_set_parent_window (child, priv->bin_window);
gtk_widget_set_child_visible (child, priv->current_pos != 0.0);
GTK_CONTAINER_CLASS (gtk_revealer_parent_class)->add (container, child);
}
static void
gtk_revealer_real_style_updated (GtkWidget *widget)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
GtkStyleContext* context;
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->style_updated (widget);
if (gtk_widget_get_realized (widget))
{
context = gtk_widget_get_style_context (widget);
gtk_style_context_set_background (context, priv->bin_window);
gtk_style_context_set_background (context, priv->view_window);
}
}
static void
gtk_revealer_real_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
GtkAllocation child_allocation;
GtkWidget *child;
gboolean window_visible;
int bin_x, bin_y;
GtkRevealerTransitionType transition;
g_return_if_fail (allocation != NULL);
gtk_widget_set_allocation (widget, allocation);
gtk_revealer_get_child_allocation (revealer, allocation, &child_allocation);
child = gtk_bin_get_child (GTK_BIN (revealer));
if (child != NULL && gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation);
if (gtk_widget_get_realized (widget))
{
if (gtk_widget_get_mapped (widget))
{
window_visible = allocation->width > 0 && allocation->height > 0;
if (!window_visible && gdk_window_is_visible (priv->view_window))
gdk_window_hide (priv->view_window);
if (window_visible && !gdk_window_is_visible (priv->view_window))
gdk_window_show (priv->view_window);
}
gdk_window_move_resize (priv->view_window,
allocation->x, allocation->y,
allocation->width, allocation->height);
bin_x = 0;
bin_y = 0;
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
bin_y = allocation->height - child_allocation.height;
else if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
bin_x = allocation->width - child_allocation.width;
gdk_window_move_resize (priv->bin_window,
bin_x, bin_y,
child_allocation.width, child_allocation.height);
}
}
static void
gtk_revealer_set_position (GtkRevealer *revealer,
gdouble pos)
{
GtkRevealerPrivate *priv = revealer->priv;
gboolean new_visible;
GtkWidget *child;
GtkRevealerTransitionType transition;
priv->current_pos = pos;
/* We check target_pos here too, because we want to ensure we set
* child_visible immediately when starting a reveal operation
* otherwise the child widgets will not be properly realized
* after the reveal returns.
*/
new_visible = priv->current_pos != 0.0 || priv->target_pos != 0.0;
child = gtk_bin_get_child (GTK_BIN (revealer));
if (child != NULL &&
new_visible != gtk_widget_get_child_visible (child))
gtk_widget_set_child_visible (child, new_visible);
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_CROSSFADE)
{
gtk_widget_set_opacity (GTK_WIDGET (revealer), priv->current_pos);
gtk_widget_queue_draw (GTK_WIDGET (revealer));
}
else
{
gtk_widget_queue_resize (GTK_WIDGET (revealer));
}
if (priv->current_pos == priv->target_pos)
g_object_notify (G_OBJECT (revealer), "child-revealed");
}
static gdouble
ease_out_quad (gdouble t, gdouble d)
{
gdouble p = t / d;
return ((-1.0) * p) * (p - 2);
}
static void
gtk_revealer_animate_step (GtkRevealer *revealer,
gint64 now)
{
GtkRevealerPrivate *priv = revealer->priv;
gdouble t;
t = 1.0;
if (now < priv->end_time)
t = (now - priv->start_time) / (gdouble) (priv->end_time - priv->start_time);
t = ease_out_quad (t, 1.0);
gtk_revealer_set_position (revealer,
priv->source_pos + (t * (priv->target_pos - priv->source_pos)));
}
static gboolean
gtk_revealer_animate_cb (GtkRevealer *revealer,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GtkRevealerPrivate *priv = revealer->priv;
gint64 now;
now = gdk_frame_clock_get_frame_time (frame_clock);
gtk_revealer_animate_step (revealer, now);
if (priv->current_pos == priv->target_pos)
{
priv->tick_id = 0;
return FALSE;
}
return TRUE;
}
static void
gtk_revealer_start_animation (GtkRevealer *revealer,
gdouble target)
{
GtkRevealerPrivate *priv = revealer->priv;
GtkWidget *widget = GTK_WIDGET (revealer);
GtkRevealerTransitionType transition;
if (priv->target_pos == target)
return;
priv->target_pos = target;
g_object_notify (G_OBJECT (revealer), "reveal-child");
transition = effective_transition (revealer);
if (gtk_widget_get_mapped (widget) &&
priv->transition_duration != 0 &&
transition != GTK_REVEALER_TRANSITION_TYPE_NONE)
{
priv->source_pos = priv->current_pos;
priv->start_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
priv->end_time = priv->start_time + (priv->transition_duration * 1000);
if (priv->tick_id == 0)
priv->tick_id =
gtk_widget_add_tick_callback (widget, (GtkTickCallback)gtk_revealer_animate_cb, revealer, NULL);
gtk_revealer_animate_step (revealer, priv->start_time);
}
else
{
gtk_revealer_set_position (revealer, target);
}
}
static void
gtk_revealer_stop_animation (GtkRevealer *revealer)
{
GtkRevealerPrivate *priv = revealer->priv;
priv->current_pos = priv->target_pos;
if (priv->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (revealer), priv->tick_id);
priv->tick_id = 0;
}
}
static void
gtk_revealer_real_map (GtkWidget *widget)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
GtkAllocation allocation;
if (!gtk_widget_get_mapped (widget))
{
gtk_widget_get_allocation (widget, &allocation);
if (allocation.width > 0 && allocation.height > 0)
gdk_window_show (priv->view_window);
gtk_revealer_start_animation (revealer, priv->target_pos);
}
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->map (widget);
}
static void
gtk_revealer_real_unmap (GtkWidget *widget)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->unmap (widget);
gtk_revealer_stop_animation (revealer);
}
static gboolean
gtk_revealer_real_draw (GtkWidget *widget,
cairo_t *cr)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
if (gtk_cairo_should_draw_window (cr, priv->bin_window))
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->draw (widget, cr);
return TRUE;
}
/**
* gtk_revealer_set_reveal_child:
* @revealer: a #GtkRevealer
* @reveal_child: %TRUE to reveal the child
*
* Tells the #GtkRevealer to reveal or conceal its child.
*
* The transition will be animated with the current
* transition type of @revealer.
*
* Since: 3.10
*/
void
gtk_revealer_set_reveal_child (GtkRevealer *revealer,
gboolean reveal_child)
{
g_return_if_fail (GTK_IS_REVEALER (revealer));
if (reveal_child)
gtk_revealer_start_animation (revealer, 1.0);
else
gtk_revealer_start_animation (revealer, 0.0);
}
/**
* gtk_revealer_get_reveal_child:
* @revealer: a #GtkRevealer
*
* Returns whether the child is currently
* revealed. See gtk_revealer_set_reveal_child().
*
* This function returns %TRUE as soon as the transition
* is to the revealed state is started. To learn whether
* the child is fully revealed (ie the transition is completed),
* use gtk_revealer_get_child_revealed().
*
* Return value: %TRUE if the child is revealed.
*
* Since: 3.10
*/
gboolean
gtk_revealer_get_reveal_child (GtkRevealer *revealer)
{
g_return_val_if_fail (GTK_IS_REVEALER (revealer), FALSE);
return revealer->priv->target_pos != 0.0;
}
/**
* gtk_revealer_get_child_revealed:
* @revealer: a #GtkRevealer
*
* Returns whether the child is fully revealed, ie wether
* the transition to the revealed state is completed.
*
* Return value: %TRUE if the child is fully revealed
*
* Since: 3.10
*/
gboolean
gtk_revealer_get_child_revealed (GtkRevealer *revealer)
{
gboolean animation_finished = (revealer->priv->target_pos == revealer->priv->current_pos);
gboolean reveal_child = gtk_revealer_get_reveal_child (revealer);
if (animation_finished)
return reveal_child;
else
return !reveal_child;
}
/* These all report only the natural size, ignoring the minimal size,
* because its not really possible to allocate the right size during
* animation if the child size can change (without the child
* re-arranging itself during the animation).
*/
static void
gtk_revealer_real_get_preferred_height (GtkWidget *widget,
gint *minimum_height_out,
gint *natural_height_out)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
gint minimum_height;
gint natural_height;
GtkRevealerTransitionType transition;
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height (widget, &minimum_height, &natural_height);
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
natural_height = round (natural_height * priv->current_pos);
minimum_height = natural_height;
if (minimum_height_out)
*minimum_height_out = minimum_height;
if (natural_height_out)
*natural_height_out = natural_height;
}
static void
gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum_height_out,
gint *natural_height_out)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
gint minimum_height;
gint natural_height;
GtkRevealerTransitionType transition;
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height_for_width (widget, width, &minimum_height, &natural_height);
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN)
natural_height = round (natural_height * priv->current_pos);
minimum_height = natural_height;
if (minimum_height_out)
*minimum_height_out = minimum_height;
if (natural_height_out)
*natural_height_out = natural_height;
}
static void
gtk_revealer_real_get_preferred_width (GtkWidget *widget,
gint *minimum_width_out,
gint *natural_width_out)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
gint minimum_width;
gint natural_width;
GtkRevealerTransitionType transition;
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width (widget, &minimum_width, &natural_width);
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
natural_width = round (natural_width * priv->current_pos);
minimum_width = natural_width;
if (minimum_width_out)
*minimum_width_out = minimum_width;
if (natural_width_out)
*natural_width_out = natural_width;
}
static void
gtk_revealer_real_get_preferred_width_for_height (GtkWidget *widget,
gint height,
gint *minimum_width_out,
gint *natural_width_out)
{
GtkRevealer *revealer = GTK_REVEALER (widget);
GtkRevealerPrivate *priv = revealer->priv;
gint minimum_width;
gint natural_width;
GtkRevealerTransitionType transition;
GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width_for_height (widget, height, &minimum_width, &natural_width);
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
natural_width = round (natural_width * priv->current_pos);
minimum_width = natural_width;
if (minimum_width_out)
*minimum_width_out = minimum_width;
if (natural_width_out)
*natural_width_out = natural_width;
}
/**
* gtk_revealer_get_transition_duration:
* @revealer: a #GtkRevealer
*
* Returns the amount of time (in milliseconds) that
* transitions will take.
*
* Returns: the transition duration
*
* Since: 3.10
*/
guint
gtk_revealer_get_transition_duration (GtkRevealer *revealer)
{
g_return_val_if_fail (GTK_IS_REVEALER (revealer), 0);
return revealer->priv->transition_duration;
}
/**
* gtk_revealer_set_transition_duration:
* @revealer: a #GtkRevealer
* @duration: the new duration, in milliseconds
*
* Sets the duration that transitions will take.
*
* Since: 3.10
*/
void
gtk_revealer_set_transition_duration (GtkRevealer *revealer,
guint value)
{
g_return_if_fail (GTK_IS_REVEALER (revealer));
revealer->priv->transition_duration = value;
g_object_notify (G_OBJECT (revealer), "transition-duration");
}
/**
* gtk_revealer_get_transition_type:
* @revealer: a #GtkRevealer
*
* Gets the type of animation that will be used
* for transitions in @revealer.
*
* Return value: the current transition type of @revealer
*
* Since: 3.10
*/
GtkRevealerTransitionType
gtk_revealer_get_transition_type (GtkRevealer *revealer)
{
g_return_val_if_fail (GTK_IS_REVEALER (revealer), GTK_REVEALER_TRANSITION_TYPE_NONE);
return revealer->priv->transition_type;
}
/**
* gtk_revealer_set_transition_type:
* @revealer: a #GtkRevealer
* @transition: the new transition type
*
* Sets the type of animation that will be used for
* transitions in @revealer. Available types include
* various kinds of fades and slides.
*
* Since: 3.10
*/
void
gtk_revealer_set_transition_type (GtkRevealer *revealer,
GtkRevealerTransitionType transition)
{
g_return_if_fail (GTK_IS_REVEALER (revealer));
revealer->priv->transition_type = transition;
gtk_widget_queue_resize (GTK_WIDGET (revealer));
g_object_notify (G_OBJECT (revealer), "transition-type");
}
+75
View File
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2013 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Author: Alexander Larsson <alexl@redhat.com>
*
*/
#ifndef __GTK_REVEALER_H__
#define __GTK_REVEALER_H__
#include <gtk/gtkbin.h>
G_BEGIN_DECLS
#define GTK_TYPE_REVEALER (gtk_revealer_get_type ())
#define GTK_REVEALER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_REVEALER, GtkRevealer))
#define GTK_REVEALER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_REVEALER, GtkRevealerClass))
#define GTK_IS_REVEALER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_REVEALER))
#define GTK_IS_REVEALER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_REVEALER))
#define GTK_REVEALER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_REVEALER, GtkRevealerClass))
typedef struct _GtkRevealer GtkRevealer;
typedef struct _GtkRevealerClass GtkRevealerClass;
typedef struct _GtkRevealerPrivate GtkRevealerPrivate;
typedef enum {
GTK_REVEALER_TRANSITION_TYPE_NONE,
GTK_REVEALER_TRANSITION_TYPE_CROSSFADE,
GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT,
GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT,
GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP,
GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN
} GtkRevealerTransitionType;
struct _GtkRevealer {
GtkBin parent_instance;
GtkRevealerPrivate * priv;
};
struct _GtkRevealerClass {
GtkBinClass parent_class;
};
GType gtk_revealer_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_revealer_new (void);
gboolean gtk_revealer_get_reveal_child (GtkRevealer *revealer);
void gtk_revealer_set_reveal_child (GtkRevealer *revealer,
gboolean reveal_child);
gboolean gtk_revealer_get_child_revealed (GtkRevealer *revealer);
guint gtk_revealer_get_transition_duration (GtkRevealer *revealer);
void gtk_revealer_set_transition_duration (GtkRevealer *revealer,
guint duration);
void gtk_revealer_set_transition_type (GtkRevealer *revealer,
GtkRevealerTransitionType transition);
GtkRevealerTransitionType gtk_revealer_get_transition_type (GtkRevealer *revealer);
G_END_DECLS
#endif
+1 -1
View File
@@ -1880,7 +1880,7 @@ gtk_scale_buildable_custom_finished (GtkBuildable *buildable,
if (strcmp (tagname, "marks") == 0)
{
GSList *m;
gchar *markup;
const gchar *markup;
marks_data = (MarksSubparserData *)user_data;
+310 -79
View File
@@ -93,16 +93,61 @@ get_vfunc_name (GtkOrientation orientation,
return for_size < 0 ? "get_preferred_height" : "get_preferred_height_for_width";
}
static gboolean
widget_class_has_baseline_support (GtkWidgetClass *widget_class)
{
GtkWidgetClass *parent_class;
if (widget_class->get_preferred_height_and_baseline_for_width == NULL)
return FALSE;
/* This is kinda hacky, but for backwards compatibility reasons we have to handle the case
where a class previously did not support get_preferred_height_and_baseline_for_width,
but then gained support for it, and a subclass of it overrides the previous non-baseline
methods. If this happens we need to call the overridden (non-baseline supporting) versions
on the subclass, rather than the inherited but not overriddent new get_preferred_height_and_baseline_for_width.
*/
/* Loop over all parent classes that inherit the same get_preferred_height_and_baseline_for_width */
parent_class = g_type_class_peek_parent (widget_class);
while (parent_class != NULL &&
parent_class->get_preferred_height_and_baseline_for_width == widget_class->get_preferred_height_and_baseline_for_width)
{
if (parent_class->get_preferred_height != widget_class->get_preferred_height ||
parent_class->get_preferred_height_for_width != widget_class->get_preferred_height_for_width)
return FALSE;
parent_class = g_type_class_peek_parent (parent_class);
}
return TRUE;
}
gboolean
_gtk_widget_has_baseline_support (GtkWidget *widget)
{
GtkWidgetClass *widget_class;
widget_class = GTK_WIDGET_GET_CLASS (widget);
return widget_class_has_baseline_support (widget_class);
}
static void
gtk_widget_query_size_for_orientation (GtkWidget *widget,
GtkOrientation orientation,
gint for_size,
gint *minimum_size,
gint *natural_size)
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
SizeRequestCache *cache;
GtkWidgetClass *widget_class;
gint min_size = 0;
gint nat_size = 0;
gint min_baseline = -1;
gint nat_baseline = -1;
gboolean found_in_cache;
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
@@ -113,7 +158,11 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
orientation,
for_size,
&min_size,
&nat_size);
&nat_size,
&min_baseline,
&nat_baseline);
widget_class = GTK_WIDGET_GET_CLASS (widget);
if (!found_in_cache)
{
@@ -128,7 +177,7 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
if (for_size < 0)
{
push_recursion_check (widget, orientation, for_size);
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_size, &nat_size);
widget_class->get_preferred_width (widget, &min_size, &nat_size);
pop_recursion_check (widget, orientation);
}
else
@@ -142,17 +191,17 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
gtk_widget_get_preferred_height (widget, &minimum_height, &natural_height);
/* convert for_size to unadjusted height (for_size is a proposed allocation) */
GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
GTK_ORIENTATION_VERTICAL,
&minimum_height,
&natural_height,
&ignored_position,
&adjusted_for_size);
widget_class->adjust_size_allocation (widget,
GTK_ORIENTATION_VERTICAL,
&minimum_height,
&natural_height,
&ignored_position,
&adjusted_for_size);
push_recursion_check (widget, orientation, for_size);
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width_for_height (widget,
MAX (adjusted_for_size, minimum_height),
&min_size, &nat_size);
widget_class->get_preferred_width_for_height (widget,
MAX (adjusted_for_size, minimum_height),
&min_size, &nat_size);
pop_recursion_check (widget, orientation);
}
}
@@ -161,7 +210,12 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
if (for_size < 0)
{
push_recursion_check (widget, orientation, for_size);
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, &min_size, &nat_size);
if (widget_class_has_baseline_support (widget_class))
widget_class->get_preferred_height_and_baseline_for_width (widget, -1,
&min_size, &nat_size,
&min_baseline, &nat_baseline);
else
widget_class->get_preferred_height (widget, &min_size, &nat_size);
pop_recursion_check (widget, orientation);
}
else
@@ -175,17 +229,21 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
gtk_widget_get_preferred_width (widget, &minimum_width, &natural_width);
/* convert for_size to unadjusted width (for_size is a proposed allocation) */
GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
GTK_ORIENTATION_HORIZONTAL,
&minimum_width,
&natural_width,
&ignored_position,
&adjusted_for_size);
widget_class->adjust_size_allocation (widget,
GTK_ORIENTATION_HORIZONTAL,
&minimum_width,
&natural_width,
&ignored_position,
&adjusted_for_size);
push_recursion_check (widget, orientation, for_size);
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget,
MAX (adjusted_for_size, minimum_width),
&min_size, &nat_size);
if (widget_class_has_baseline_support (widget_class))
widget_class->get_preferred_height_and_baseline_for_width (widget, MAX (adjusted_for_size, minimum_width),
&min_size, &nat_size,
&min_baseline, &nat_baseline);
else
widget_class->get_preferred_height_for_width (widget, MAX (adjusted_for_size, minimum_width),
&min_size, &nat_size);
pop_recursion_check (widget, orientation);
}
}
@@ -198,10 +256,10 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
adjusted_min = min_size;
adjusted_natural = nat_size;
GTK_WIDGET_GET_CLASS (widget)->adjust_size_request (widget,
orientation,
&adjusted_min,
&adjusted_natural);
widget_class->adjust_size_request (widget,
orientation,
&adjusted_min,
&adjusted_natural);
if (adjusted_min < min_size ||
adjusted_natural < nat_size)
@@ -229,11 +287,42 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
nat_size = adjusted_natural;
}
if (min_baseline != -1 || nat_baseline != -1)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
g_warning ("%s %p reported a horizontal baseline",
G_OBJECT_TYPE_NAME (widget), widget);
min_baseline = -1;
nat_baseline = -1;
}
else if (min_baseline == -1 || nat_baseline == -1)
{
g_warning ("%s %p reported baseline for only one of min/natural (min: %d, natural: %d)",
G_OBJECT_TYPE_NAME (widget), widget,
min_baseline, nat_baseline);
min_baseline = -1;
nat_baseline = -1;
}
else if (gtk_widget_get_valign_with_baseline (widget) != GTK_ALIGN_BASELINE)
{
/* Ignore requested baseline for non-aligned widgets */
min_baseline = -1;
nat_baseline = -1;
}
else
widget_class->adjust_baseline_request (widget,
&min_baseline,
&nat_baseline);
}
_gtk_size_request_cache_commit (cache,
orientation,
for_size,
min_size,
nat_size);
nat_size,
min_baseline,
nat_baseline);
}
if (minimum_size)
@@ -242,15 +331,26 @@ gtk_widget_query_size_for_orientation (GtkWidget *widget,
if (natural_size)
*natural_size = nat_size;
if (minimum_baseline)
*minimum_baseline = min_baseline;
if (natural_baseline)
*natural_baseline = nat_baseline;
g_assert (min_size <= nat_size);
GTK_NOTE (SIZE_REQUEST,
g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d (hit cache: %s)\n",
g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d",
widget, G_OBJECT_TYPE_NAME (widget),
orientation == GTK_ORIENTATION_HORIZONTAL ?
"width for height" : "height for width" ,
for_size, min_size, nat_size,
found_in_cache ? "yes" : "no"));
for_size, min_size, nat_size);
if (min_baseline != -1 || nat_baseline != -1)
g_print (", baseline %d/%d",
min_baseline, nat_baseline);
g_print (" (hit cache: %s)\n",
found_in_cache ? "yes" : "no")
);
}
/* This is the main function that checks for a cached size and
@@ -263,7 +363,9 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural)
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GHashTable *widgets;
GHashTableIter iter;
@@ -276,12 +378,17 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
*minimum = 0;
if (natural)
*natural = 0;
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
return;
}
if (G_LIKELY (!_gtk_widget_get_sizegroups (widget)))
{
gtk_widget_query_size_for_orientation (widget, orientation, for_size, minimum, natural);
gtk_widget_query_size_for_orientation (widget, orientation, for_size, minimum, natural,
minimum_baseline, natural_baseline);
return;
}
@@ -295,7 +402,7 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
GtkWidget *tmp_widget = key;
gint min_dimension, nat_dimension;
gtk_widget_query_size_for_orientation (tmp_widget, orientation, for_size, &min_dimension, &nat_dimension);
gtk_widget_query_size_for_orientation (tmp_widget, orientation, for_size, &min_dimension, &nat_dimension, NULL, NULL);
min_result = MAX (min_result, min_dimension);
nat_result = MAX (nat_result, nat_dimension);
@@ -305,6 +412,13 @@ _gtk_widget_compute_size_for_orientation (GtkWidget *widget,
g_hash_table_destroy (widgets);
/* Baselines make no sense with sizegroups really */
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
if (minimum)
*minimum = min_result;
@@ -377,7 +491,8 @@ gtk_widget_get_preferred_width (GtkWidget *widget,
GTK_ORIENTATION_HORIZONTAL,
-1,
minimum_width,
natural_width);
natural_width,
NULL, NULL);
}
@@ -411,7 +526,8 @@ gtk_widget_get_preferred_height (GtkWidget *widget,
GTK_ORIENTATION_VERTICAL,
-1,
minimum_height,
natural_height);
natural_height,
NULL, NULL);
}
@@ -448,7 +564,8 @@ gtk_widget_get_preferred_width_for_height (GtkWidget *widget,
GTK_ORIENTATION_HORIZONTAL,
height,
minimum_width,
natural_width);
natural_width,
NULL, NULL);
}
/**
@@ -483,7 +600,122 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
GTK_ORIENTATION_VERTICAL,
width,
minimum_height,
natural_height);
natural_height,
NULL, NULL);
}
/**
* gtk_widget_get_preferred_height_and_baseline_for_width:
* @widget: a #GtkWidget instance
* @width: the width which is available for allocation, or -1 if none
* @minimum_height: (out) (allow-none): location for storing the minimum height, or %NULL
* @natural_height: (out) (allow-none): location for storing the natural height, or %NULL
* @minimum_baseline: (out) (allow-none): location for storing the baseline for the minimum height, or %NULL
* @natural_baseline: (out) (allow-none): location for storing the baseline for the natural height, or %NULL
*
* Retrieves a widget's minimum and natural height and the corresponding baselines if it would be given
* the specified @width, or the default height if @width is -1. The baselines may be -1 which means
* that no baseline is requested for this widget.
*
* The returned request will be modified by the
* GtkWidgetClass::adjust_size_request and GtkWidgetClass::adjust_baseline_request virtual methods
* and by any #GtkSizeGroup<!-- -->s that have been applied. That is, the returned request
* is the one that should be used for layout, not necessarily the one
* returned by the widget itself.
*
* Since: 3.10
*/
void
gtk_widget_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint *minimum_height,
gint *natural_height,
gint *minimum_baseline,
gint *natural_baseline)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (minimum_height != NULL || natural_height != NULL);
g_return_if_fail (width >= -1);
_gtk_widget_compute_size_for_orientation (widget,
GTK_ORIENTATION_VERTICAL,
width,
minimum_height,
natural_height,
minimum_baseline,
natural_baseline);
}
/**
* gtk_widget_get_preferred_size_and_baseline:
* @widget: a #GtkWidget instance
* @minimum_size: (out) (allow-none): location for storing the minimum size, or %NULL
* @natural_size: (out) (allow-none): location for storing the natural size, or %NULL
*
* Retrieves the minimum and natural size and the corresponding baselines of a widget, taking
* into account the widget's preference for height-for-width management. The baselines may
* be -1 which means that no baseline is requested for this widget.
*
* This is used to retrieve a suitable size by container widgets which do
* not impose any restrictions on the child placement. It can be used
* to deduce toplevel window and menu sizes as well as child widgets in
* free-form containers such as GtkLayout.
*
* <note><para>Handle with care. Note that the natural height of a height-for-width
* widget will generally be a smaller size than the minimum height, since the required
* height for the natural width is generally smaller than the required height for
* the minimum width.</para></note>
*
* Since: 3.10
*/
void
gtk_widget_get_preferred_size_and_baseline (GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
gint min_width, nat_width;
gint min_height, nat_height;
g_return_if_fail (GTK_IS_WIDGET (widget));
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
gtk_widget_get_preferred_width (widget, &min_width, &nat_width);
if (minimum_size)
{
minimum_size->width = min_width;
gtk_widget_get_preferred_height_and_baseline_for_width (widget, min_width,
&minimum_size->height, NULL, minimum_baseline, NULL);
}
if (natural_size)
{
natural_size->width = nat_width;
gtk_widget_get_preferred_height_and_baseline_for_width (widget, nat_width,
NULL, &natural_size->height, NULL, natural_baseline);
}
}
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT or CONSTANT_SIZE */
{
gtk_widget_get_preferred_height_and_baseline_for_width (widget, -1, &min_height, &nat_height, minimum_baseline, natural_baseline);
if (minimum_size)
{
minimum_size->height = min_height;
gtk_widget_get_preferred_width_for_height (widget, min_height,
&minimum_size->width, NULL);
}
if (natural_size)
{
natural_size->height = nat_height;
gtk_widget_get_preferred_width_for_height (widget, nat_height,
NULL, &natural_size->width);
}
}
}
/**
@@ -505,6 +737,9 @@ gtk_widget_get_preferred_height_for_width (GtkWidget *widget,
* height for the natural width is generally smaller than the required height for
* the minimum width.</para></note>
*
* Use gtk_widget_get_preferred_size_and_baseline() if you want to support
* baseline alignment.
*
* Since: 3.0
*/
void
@@ -512,50 +747,10 @@ gtk_widget_get_preferred_size (GtkWidget *widget,
GtkRequisition *minimum_size,
GtkRequisition *natural_size)
{
gint min_width, nat_width;
gint min_height, nat_height;
g_return_if_fail (GTK_IS_WIDGET (widget));
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
gtk_widget_get_preferred_width (widget, &min_width, &nat_width);
if (minimum_size)
{
minimum_size->width = min_width;
gtk_widget_get_preferred_height_for_width (widget, min_width,
&minimum_size->height, NULL);
}
if (natural_size)
{
natural_size->width = nat_width;
gtk_widget_get_preferred_height_for_width (widget, nat_width,
NULL, &natural_size->height);
}
}
else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT or CONSTANT_SIZE */
{
gtk_widget_get_preferred_height (widget, &min_height, &nat_height);
if (minimum_size)
{
minimum_size->height = min_height;
gtk_widget_get_preferred_width_for_height (widget, min_height,
&minimum_size->width, NULL);
}
if (natural_size)
{
natural_size->height = nat_height;
gtk_widget_get_preferred_width_for_height (widget, nat_height,
NULL, &natural_size->width);
}
}
gtk_widget_get_preferred_size_and_baseline (widget, minimum_size, natural_size,
NULL, NULL);
}
static gint
compare_gap (gconstpointer p1,
gconstpointer p2,
@@ -657,3 +852,39 @@ gtk_distribute_natural_allocation (gint extra_space,
return extra_space;
}
void
_gtk_widget_get_preferred_size_for_size (GtkWidget *widget,
GtkOrientation orientation,
gint size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (size >= -1);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (size < 0)
gtk_widget_get_preferred_width (widget, minimum, natural);
else
gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
}
else
{
gtk_widget_get_preferred_height_and_baseline_for_width (widget,
size,
minimum,
natural,
minimum_baseline,
natural_baseline);
}
}

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