Compare commits

..

129 Commits

Author SHA1 Message Date
Emmanuele Bassi bb37613711 WIP: Create an animation manager for GtkWindow 2019-07-30 17:11:59 +01:00
Emmanuele Bassi 908ebf2b23 WIP: Add GtkAnimationManager
A private class that keeps track of all in flight animations for a top
level.
2019-07-30 17:11:59 +01:00
Emmanuele Bassi 715dd26260 WIP: Add GtkPropertyAnimation
A GtkAnimation subclass that interpolates a GObject property.
2019-07-30 17:11:59 +01:00
Emmanuele Bassi 83d41b32e9 WIP: Add GtkAnimation base class
A base class for describing an animation.
2019-07-30 17:11:59 +01:00
Emmanuele Bassi 9bf52a274c Port easing GtkCssValue to GtkTimingFunction
We can share the logic, parsing, and serialization code.
2019-07-30 17:11:59 +01:00
Emmanuele Bassi 4aae883fe8 Add GtkTimingFunction
A timing function converts and input value into an output value
according to a known easing curve.

See also: https://drafts.csswg.org/css-easing/
2019-07-30 17:11:59 +01:00
Daniel Mustieles 2691e4e949 Updated Spanish translation 2019-07-30 09:39:55 +02:00
Timm Bäder 20d7b7f59b widget factory: add a tooltip to a button in a popover 2019-07-30 07:05:45 +02:00
Matthias Clasen 1fcd08d76a Merge branch 'issue2057' into 'master'
Bump wayland-protocols requirements

See merge request GNOME/gtk!1030
2019-07-29 12:17:52 +00:00
Olivier Fourdan 060a9f072c Bump wayland-protocols requirements
The `name` and `description` events were added to `xdg-output` protocol
in version 2 which is part of wayland-protocols 1.14.

In xdg-output-v1 version 3, the `xdg-output.done` event was deprecated
and the `xdg-output.description` event was made mutable, but that
doesn't change the actual events so we do not actually need to require
that version of xdg-output from wayland-protocols 1.18.

Update the wayland-protocols requirement to the bare minimum version,
which is 1.14.

https://gitlab.gnome.org/GNOME/gtk/issues/2057
2019-07-29 12:03:07 +02:00
Matthias Clasen 4a631787bd Merge branch 'subpixel-positioning' into 'master'
Subpixel positioning

See merge request GNOME/gtk!1024
2019-07-28 21:02:31 +00:00
Matthias Clasen 032473fef8 reftest: Exclude flaky tests
These depend on details of text rendering,
and started failing with newer pango.
2019-07-28 16:42:52 -04:00
Matthias Clasen 5dd8801ee5 gl: implement subpixel positioning
Pass the glyph position into the glyph caching functions,
not just the glyph index. This allows us to cache different
images for different subpixel positions.
2019-07-28 16:42:52 -04:00
Matthias Clasen 5c9643b6eb vulkan: implement subpixel positioning
Pass the glyph position into the glyph caching functions,
not just the glyph index. This allows us to cache different
images for different subpixel positions.
2019-07-28 16:42:52 -04:00
Matthias Clasen 4de670b0b4 Turn off metrics hinting
This will be necessary to see the effects of subpixel positioning.
2019-07-28 16:42:52 -04:00
Matthias Clasen ade40a7a0c Merge branch 'wip/chergert/textview-caching' into 'master'
textlayout: introduce caching for GtkTextLineDisplay

See merge request GNOME/gtk!1025
2019-07-28 20:32:56 +00:00
Christian Hergert 9926e6ebde textlayout: introduce caching for GtkTextLineDisplay
This adds a GtkTextLineDisplayCache which can be used to cache a number
of GtkTextLineDisplay (and thus, PangoLayout) while displaying a view.

It uses a GSequence to track the position of the GtkTextLineDisplay
relative to each other, a MRU to cull the least recently used display,
and and a direct hashtable to lookup display by GtkTextLine.

We only cache lines that are to be displayed (!size_only). We may want to
either create a second collection of "size_only" lines to speed that up,
or determine that it is unnecessary (which is likely the case).
2019-07-28 10:34:15 -07:00
Christian Hergert b930c5a8a2 textiter: add _gtk_text_iter_same_line()
This is a faster form to compare two text iter to see if they are on the
same line.
2019-07-28 10:34:15 -07:00
Matthias Clasen 7eb5dfd294 inspector: Show the pango backend 2019-07-28 11:39:16 -04:00
Matthias Clasen 8752564fea Remove new attributes from tests
Until we can depend on pango 1.44, these will
fail in ci. Partially reverts f1c7803f80
2019-07-28 11:00:29 -04:00
Matthias Clasen 988fac404a Add pango version checks
Seems the ci does not have pango 1.44 yet.
2019-07-28 10:50:14 -04:00
Matthias Clasen 7a3eaad193 gl: Simplify glyph cache rendering
We are currently using a weird mix of pango and cairo,
but there is no need for us to go through a pango
renderer here; we can just use cairo directly.
2019-07-28 09:54:17 -04:00
Matthias Clasen 3fccb16ca6 gsk: Move text-related test out of ci
These are too sensitive to rendering differences
between renderers to run reliably in ci, but we
still want to keep them around. In particular,
the big glyph tests are useful to exercise the
GL glyph cache.
2019-07-28 09:35:37 -04:00
Timm Bäder 2c38b71ca5 glyph cache: Upload large glyphs in lookup () directly
Instead of relying on a texture id of 0, which can happen for other
reasons, e.g. when the glyph is being scaled too small.

Fixes part of #2046
2019-07-28 12:00:15 +02:00
Timm Bäder 1c93bef0d5 glyph cache: check glyphs for scaled size
We can't rely on just the ink_rect, since that might be without the
scaled applied, which is what ends up on the texture.

Fixes #2046
2019-07-28 10:58:10 +02:00
Timm Bäder eea76e8cce textview: Remove some unnecessary gtk_widget_show() calls
Widgets are visible by default.
2019-07-28 08:44:45 +02:00
Jordi Mas 3b604331ec Update Catalan translation 2019-07-28 01:05:25 +02:00
Matthias Clasen 92546cf9f7 Merge branch 'overview-recursive-dependancy' into 'master'
overview.xml: The GTK library does not depend on the GTK library

See merge request GNOME/gtk!1026
2019-07-27 21:46:52 +00:00
Piotr Drąg 3c9f9d598b Update Polish translation 2019-07-27 15:20:40 +02:00
Piotr Drąg ed46053dc9 Update POTFILES.skip 2019-07-27 15:03:47 +02:00
Дилян Палаузов a3db7437b3 overview.xml: The GTK library does not depend on the GTK library
The documentation stated:

GTK is a library.…  GTK depends on the following libraries:

GTK       The GTK library itself contains widgets, that is, GUI
          components such as GtkButton or GtkTextView.

There is no point in stating, that the GTK library
depends on the GTK library.
2019-07-27 11:59:45 +00:00
Timm Bäder b2d639b6d9 window: Unroot with old display
Things might rely on the old display being set while unrooting.

Fixes #2052
2019-07-27 07:57:06 +02:00
Matthias Clasen f1c7803f80 label: Parse new pango attributes
Support allow-breaks and show attributes.
These will be in pango 1.44
2019-07-27 00:02:08 -04:00
Matthias Clasen c179fce6c7 Merge branch 'xdg-output-v3-gtk4' into 'master'
wayland: Add xdg-output v3 support

See merge request GNOME/gtk!1022
2019-07-26 17:13:39 +00:00
Olivier Fourdan 795899f9d5 wayland: Add xdg-output v3 support
xdg-output v3 marks xdg-output.done as deprecated and compositors are
not required to send that event anymore.

So if the xdg-output version is 3 or higher, simply set the initial
value `xdg_output_done` to TRUE so we don't wait/expect that event
from the compositor.

https://gitlab.gnome.org/GNOME/gtk/issues/2053
2019-07-26 17:32:17 +02:00
Matthias Clasen 88ab3a6942 Merge branch 'wip/no-move-surface' into 'master'
Remove surface moving APIs

See merge request GNOME/gtk!1016
2019-07-26 14:31:49 +00:00
Timm Bäder 58e8dd1c0d gl renderer: Fix dx/dy handling on hidpi
Fixes misplaced error squiggles in the node editor.
2019-07-26 16:27:39 +02:00
Timm Bäder b8bbf7b63b gl renderer: Rework transform handling
Fix all the ref counting mishaps. Makes hidpi work again and without
memory leaks.
2019-07-26 15:35:06 +02:00
Kukuh Syafaat 05e28fb498 Update Indonesian translation 2019-07-26 11:31:46 +00:00
Kjartan Maraas c6d9963d1a Update Norwegian Bokmål translation 2019-07-26 09:01:15 +00:00
Daniel Mustieles 2d3a902beb Updated Spanish translation 2019-07-26 09:18:25 +02:00
Matthias Clasen 8b1f3936b6 font rendering demo: Make boxes optional 2019-07-26 00:31:07 -04:00
Matthias Clasen 108ea50179 font rendering demo: Show unrounded extents
This makes more sense.
2019-07-25 23:35:09 -04:00
Matthias Clasen df1892c052 font rendering: Show ink rect too 2019-07-25 22:06:34 -04:00
Matthias Clasen 0820a79bf5 Improve the font rendering demo
Show the pixel grid, extents, and baseline.
2019-07-25 19:07:12 -04:00
Matthias Clasen 4427bde8a7 Merge branch 'fontrendering-demo' into 'master'
Add a font rendering demo

See merge request GNOME/gtk!1019
2019-07-25 21:06:54 +00:00
Matthias Clasen dec4db5943 Add a font rendering demo
This renders a magnified version of the text,
to make the effect of various font rendering options
more visible.

It also shows the phases of subpixel rendering,
if you have a recent pango and cairo.
2019-07-25 16:43:22 -04:00
Matthias Clasen fd7f6ca7ad tests: improve error handling 2019-07-25 13:51:34 -04:00
Matthias Clasen dea309144b gtk-demo: Fix a crash 2019-07-25 13:51:34 -04:00
Emmanuele Bassi f1e4efebb7 Merge branch 'gtk-4-add-TCRYPT-options-to-ask-password-dialog' into 'master'
gtkmountoperation: Add TCRYPT options to the ask-password dialog

See merge request GNOME/gtk!263
2019-07-25 10:16:11 +00:00
Jonas Ådahl 0885eb0a7b gdk: Remove gdk_surface_move_resize() API
Windows/surface's aren't supposed to be explicitly moved by any external
part, so don't provide API for doing so. Usage throughout Gdk is
replaced by the corresponding backend variants.
2019-07-25 10:35:43 +02:00
Jonas Ådahl fc68d1b1e6 gdk: Make backends implement move_to_rect()
The generic layer still does the heavy lifting, leaving the backends
more or less just act as thin wrappers, dealing a bit with global
coordinate transformations. The end goal is to remove explicit surface
moving from the generic gdk layer.
2019-07-25 10:24:50 +02:00
Jonas Ådahl b329090e69 gdk: Remove gdk_surface_move()
Generic gdk code now uses the internal helper; backends use their own
private implementations when necessary.
2019-07-25 10:24:50 +02:00
Jonas Ådahl 6314ebd435 gdk/surface: Add toplevel_resize vfunc
To separate how toplevels and popups are configured, a first step is to
introduce a resize-only vfunc for backends to implement. It's meant to
only configure toplevel windows, i.e. popups. Currently it's used for
both types, but introducing the resize-only API is a first step.
2019-07-25 10:24:50 +02:00
Matthias Clasen e89e182565 Merge branch 'avoid-redundant-attributes' into 'master'
text layout: Avoid redundant text attributes

See merge request GNOME/gtk!1015
2019-07-24 23:47:41 +00:00
Matthias Clasen 552fe0406c text layout: Avoid redundant text attributes
Don't insert text attributes if the font, or scale
or fallback did not actually change. This helps
Pango avoid excessive item breaks, which in turn
helps shaping to work across things like color
changes.

Related: https://gitlab.gnome.org/GNOME/pango/issues/28
2019-07-24 19:05:32 -04:00
Jonas Ådahl b062dea1aa wayland: Cleanup surface configuration
Configuration should happen in response to the xdg_surface.configure
event, not in the events that preceeds it. Do this by making all
configured state pending until the committing "configure" event. Also
split up toplevel vs popup configuration in a more clear way.
2019-07-24 22:42:37 +02:00
Jonas Ådahl 9b561581d5 wayland: Rename gdk_wayland_surface_configure to *_resize
It only issues a resize; configuring should imply more state is
configured, e.g. maximized, etc.
2019-07-24 22:42:37 +02:00
Jonas Ådahl 7f6c31c041 tests: Remove obsolete props from popover2.ui 2019-07-24 22:42:37 +02:00
Matthias Clasen 717c55c9aa Merge branch 'gtkapp-opening-str' into 'master'
Use commas to differentiate between text and filename

See merge request GNOME/gtk!1013
2019-07-24 13:51:22 +00:00
Jordi Mas 7d1c6272be Use commas to differentiate between text and filename 2019-07-24 13:51:22 +00:00
Matthias Clasen 2f387c2a23 Merge branch 'missing-gobject-annotation' into 'master'
Add nullable annotation to combo_box_text_get_active_text

See merge request GNOME/gtk!1012
2019-07-24 13:50:04 +00:00
Timm Bäder 0d95c5dfe2 passwordentry: Normalize boolean value 2019-07-24 08:10:37 +02:00
Timm Bäder f2a2908c59 passwordentry: Remove empty vfunc implementation 2019-07-24 08:10:26 +02:00
Timm Bäder f4cb60dcca textlayout: Avoid querying CSS state if we don't have to
This is actually pretty slow, and we almost never render a selection.
2019-07-24 07:54:30 +02:00
Timm Bäder b3d0629709 popover: Remove some unnecessary checks
gtk_popover_move_resize() already checks whether the popover has a
surface.
2019-07-24 07:54:30 +02:00
Matthias Clasen 30f55c4d07 Remove a redundant vfunc
PangoRenderer has a perfectly adequate default
implementation of draw_glyphs, no need to duplicate that.
2019-07-23 23:28:24 -04:00
Ryan Westlund f00d964f4f Add nullable annotation to combo_box_text_get_active_text 2019-07-23 22:59:35 -04:00
Matthias Clasen d2920c501d Merge branch 'blink-later' into 'master'
Blink later

See merge request GNOME/gtk!1011
2019-07-24 02:05:32 +00:00
Matthias Clasen af528b08dc Merge branch 'error-nodes' into 'master'
Render error underlines as render nodes

See merge request GNOME/gtk!1009
2019-07-24 01:39:37 +00:00
Matthias Clasen a628907891 textview: Defer cursor blinking on input
We were not calling the right cursor functions
in the commit handler.
2019-07-23 21:18:03 -04:00
Matthias Clasen 19ad4d67ef textview: Delay initial cursor blinking
These changes follow the same changes for
gtktext.c in the previous commit.
2019-07-23 21:17:05 -04:00
Matthias Clasen a4e427b44a text: Delay initial cursor blinking
We used to have a solid cursor for 2/3 of the cycle,
now we start fading after 1/4th. To make up for it,
add half a cycle of delay.
2019-07-23 21:08:47 -04:00
Matthias Clasen 5b94e3c2f2 Merge branch 'wip/chergert/refcount-line-display' into 'master'
make GtkTextLineDisplay ref counted

See merge request GNOME/gtk!1010
2019-07-23 22:44:59 +00:00
Matthias Clasen 3278e9ab6c Render error underlines as render nodes
Use a sequence of transformed squares,
instead of a cairo node. The drawing is not
identical to the previous code, but reasonably
close.
2019-07-23 18:31:39 -04:00
Christian Hergert 02d8e95b73 textlayout: remove use of gtk_text_layout_free_line_display
Now that these are reference counted, we no longer need to use
the variant requiring access to the GtkTextLayout.
2019-07-23 14:59:40 -07:00
Christian Hergert e0b9b51e9f textlayout: make GtkTextLineDisplay reference counted
This makes GtkTextLineDisplay use GRcBox instead of g_slice_*
directly. By using reference counting for this structure, we
can ensure that we hold an extra ref for one_display_cache as
well as caching additional GtkTextLineDisplay for the visible
range in the future.
2019-07-23 14:52:14 -07:00
Matthias Clasen fb06b7fa94 text: Remove an outdated comment 2019-07-23 15:14:38 -04:00
Matthias Clasen 7b451678f5 fix the build 2019-07-23 14:26:32 -04:00
Piotr Drąg 3be9e819d6 Update POTFILES.in 2019-07-23 19:47:43 +02:00
Matthias Clasen 758c54eab8 text: Fix incomplete invalidation
When a style change affects the text, we need to
clear the cached content, in order to pick up the
new text style.
2019-07-23 10:41:52 -04:00
Matthias Clasen c39cc15573 text view: Fix incomplete invalidation
Update the cached text style when a css change affects
content or background. This fixes text views drawing
black-on-dark when switching to the dark theme.
2019-07-23 10:41:43 -04:00
Jordi Mas 8999bb0b78 Update Catalan translation 2019-07-22 11:06:27 +02:00
Matthias Clasen 7a81b7c7be Merge branch 'wip/chergert/fix-textlayout-bounds' into 'master'
textlayout: fix bounds for clipping

See merge request GNOME/gtk!1006
2019-07-22 01:53:17 +00:00
Christian Hergert e475d4bdc5 textlayout: fix bounds for clipping
This should match gtk_snapshot_append_layout(), which means that we expect the
bounds to be rooted at 0, 0.
2019-07-21 18:21:04 -07:00
Matthias Clasen 980a6a20b1 Merge branch 'wip/textview' into 'master'
textview: port GtkTextView to GskPangoRenderer

See merge request GNOME/gtk!1005
2019-07-21 23:10:41 +00:00
Matthias Clasen 064ad42432 text view: Smooth cursor blinking
Fade the text cursor in and out, instead
of abruptly turning it on and off.
2019-07-21 16:03:49 -07:00
Christian Hergert 4ff9163c47 textview: port GtkTextView to GskPangoRenderer
This removes the use of GtkTextDisplay (a PangoRenderer) to use
the GskPangoRender which generates render nodes. Part of this means
improving the GskPangoRenderer to support the necessary features for
displaying a GtkTextView.

Primarily, this is a merging of GtkTextDisplay features into
GskPangoRender. Additionally, GtkTextDisplay was removed to allow for
gtk_text_layout_snapshot() to be implemented elsewhere.
2019-07-21 16:03:45 -07:00
Matthias Clasen 45ebe47d94 textview: Stop exporting private apis
These headers are no longer 'semi-public, but private
and uninstalled, so exporting these functions does
not do any good.
2019-07-21 13:26:40 -07:00
Matthias Clasen 2803bd93ce gsk: Fix a crash in gsk_render_node_diff
The only thing worse than freeing the same
cairo region twice is freeing it three times.
2019-07-21 13:18:58 -07:00
Matthias Clasen 51161fb0d6 text: Smooth cursor blinking
Fade the text cursor in and out, instead
of abruptly turning it on and off.
2019-07-21 11:35:13 -07:00
Matthias Clasen 63fd97749c Adwaita: Fix entry block cursors 2019-07-21 11:35:04 -07:00
Asier Sarasua Garmendia f2d736d2cc Update Basque translation 2019-07-21 18:02:07 +00:00
Serdar Sağlam 9b9a656e54 Update Turkish translation 2019-07-21 14:15:15 +00:00
Timm Bäder 8f734b01b2 window: Plug a GList leak
We need to free the GList manually when using g_list_remove_link().
2019-07-21 12:45:10 +02:00
Timm Bäder 69250371b0 gtk.supp: Add glXQueryServerString exceptions 2019-07-21 12:45:10 +02:00
Timm Bäder 731613d70b gl renderer: Remove leftover modelview matrix
We use a GskTransform there nowadays.
2019-07-21 12:45:10 +02:00
Timm Bäder 5f21c45f75 Revert "gl renderer: ops_set_modelview is (transfer full)"
This reverts commit e904c49e8a.

This breaks HiDPI setups, i.e. setups where the call to
ops_set_modelview does not end up with a NULL transform.
2019-07-21 12:45:10 +02:00
Timm Bäder 8beea4d958 window: Merge some functions into their only callers
So it's clear we only add or remove the pointerfocus-es in
_update_pointer_focus.
2019-07-21 11:06:24 +02:00
Timm Bäder 1583200e24 cellrenderertext: Remove some unnecessary NULL checks 2019-07-21 10:26:00 +02:00
Timm Bäder 03fa8ed259 cellrenderertext: Don't unnecessarily ref a layout
We never pass a NULL layout to get_size().
2019-07-21 10:22:05 +02:00
Timm Bäder 0bd939624e textlayout: Remove some outdated comments
These two members have been commented out for 19 years.
2019-07-21 10:02:54 +02:00
Timm Bäder b658a1a8e3 entry: Measure icons again
This was previously removed because it changes the minimum and natural
size of the entry when the icons are shown/hidden at runtime. Just not
measuring them does not work however, so reintroduce this.
2019-07-21 09:58:08 +02:00
Timm Bäder 7eae9d115c placesview: Make "Other Locations" search case-insensitive
It's just weird to search for "c" and not find the list item labelled
"Computer".
2019-07-21 09:51:54 +02:00
Timm Bäder 2ca56d4c4c linedisplay: Save paragraph bg color inline
No need to allocate this separately.
2019-07-21 09:47:09 +02:00
Timm Bäder f6d7967e96 gtk.supp: Add a pixman_image_composite32 exception 2019-07-21 09:13:24 +02:00
Timm Bäder 9bddc0ff85 gtk.supp: add a FcDefaultSubstitute exception 2019-07-21 09:07:27 +02:00
Timm Bäder 6e47ebe030 rendernodeparser: Fix a memory leak when parsing glyphs 2019-07-21 09:06:50 +02:00
Timm Bäder 9728dabf12 rendernodeparser: Fix a memory leak when parsing textures 2019-07-21 09:06:29 +02:00
Timm Bäder e904c49e8a gl renderer: ops_set_modelview is (transfer full)
regarding the passed modelview matrix
2019-07-21 09:06:10 +02:00
Timm Bäder 27ddd39d69 gl renderer: Pull out code from a loop
Does not not actually depend on anything done inside the loop.
2019-07-21 08:39:25 +02:00
Goran Vidović 86e907b088 Update Croatian translation 2019-07-19 21:29:56 +00:00
Goran Vidović 8b46538af9 Update Croatian translation 2019-07-19 21:20:13 +00:00
Timm Bäder 5910a28aa5 gl renderer: Replace a redundant function call
We're already getting the radius from the node above.
2019-07-19 18:14:50 +02:00
Timm Bäder 3935027880 filechooserwidget: Fold function into only caller 2019-07-19 18:14:50 +02:00
Timm Bäder 8665828d7f filechooserwidget: Don't emit default-size-changed() in unroot()
It doesn't make much sense to assume the default size has changed just
because the widget has been unrooted.
2019-07-19 18:14:50 +02:00
Timm Bäder a8b559e99f filechooser: Remove SETTINGS_KEY_WINDOW_POSITION
Now unused.
2019-07-19 18:14:50 +02:00
Timm Bäder 5674a3db46 filechooserwidget: Don't look at saved window position
We don't save it anymore so no need to look at it here.
2019-07-19 18:14:49 +02:00
Timm Bäder dd3acc9014 filechooserdialog: Stop using gtk_window_get_position() 2019-07-19 18:14:49 +02:00
Timm Bäder a9364bc053 Revert "file chooser: Stop using gtk_window_get_position"
This reverts commit 2ed533c3e1.

This also made the filechooser dialog not save the window size anymore,
which does not depend on the gtk_window_get_position() removal.
2019-07-19 18:14:49 +02:00
Timm Bäder 59313e1459 gtkfilechooserwidget: Temporarily disable revealer transitions...
... when going between recent and browse. It just looks weird to have
this transition while the treeview model is just cleared/repopulated
without any transition.
2019-07-19 18:14:49 +02:00
Timm Bäder 3e54d374de placessidebar: Remove sidebar border again 2019-07-19 18:14:49 +02:00
Christoph Reiter 9856218073 Merge branch 'tests-no-box-packing' into 'master'
testsuite: Remove dangling references to box-packing tests

See merge request GNOME/gtk!997
2019-07-18 19:32:19 +00:00
segfault 97cdf87350 gtkmountoperation: Add TCRYPT options to the ask-password dialog 2019-07-18 20:06:20 +02:00
Emmanuele Bassi d8f91e7df9 Merge branch 'pc-libs-private' into 'master'
gtk4.pc: Move third-party libraries from Libs to Libs.private

See merge request GNOME/gtk!998
2019-07-18 10:31:19 +00:00
Emmanuele Bassi 91d4e2b3e3 Merge branch 'gtk-4-support-tcrypt-with-proxy-handler' into 'master'
gtkmountoperation: Support TCRYPT options when using proxy handler

See merge request GNOME/gtk!245
2019-07-18 10:11:12 +00:00
segfault e5cccbf5a0 gtkmountoperation: Support TCRYPT options when using proxy handler
GMountOperation now supports options to unlock TCRYPT volumes. This
patch sets these options if they are returned by AskPassword() of a
GtkMountOperationHandlerProxy.
2019-07-18 11:41:45 +02:00
Simon McVittie 5cfe9ab603 testsuite: Remove dangling references to box-packing tests
These were removed in commit c47abb5f, before 3.96.0.

Signed-off-by: Simon McVittie <smcv@debian.org>
2019-07-18 09:26:07 +01:00
Simon McVittie 01a6bbdc73 gtk4.pc: Move third-party libraries from Libs to Libs.private
This avoids "overlinking". These libraries are an implementation detail
of particular backends, so they only need to appear on library consumers'
linker command-lines if the dependency cannot be picked up from the
shared library automatically (when linking statically, or when building
on a deficient OS that doesn't support transitive dependencies between
shared libraries, in which case pkg-config should be built with
--enable-indirect-deps).

Signed-off-by: Simon McVittie <smcv@debian.org>
2019-07-18 09:24:41 +01:00
112 changed files with 11600 additions and 6587 deletions
+4
View File
@@ -174,6 +174,7 @@
<file>foreigndrawing.c</file>
<file>font_features.c</file>
<file>fontplane.c</file>
<file>fontrendering.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>headerbar.c</file>
@@ -281,6 +282,9 @@
<gresource prefix="/fixed">
<file>fixed.css</file>
</gresource>
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>
+288
View File
@@ -0,0 +1,288 @@
/* Pango/Font rendering
*
* Demonstrates various aspects of font rendering.
*/
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
static GtkWidget *font_button = NULL;
static GtkWidget *entry = NULL;
static GtkWidget *image = NULL;
static GtkWidget *hinting = NULL;
static GtkWidget *hint_metrics = NULL;
static GtkWidget *up_button = NULL;
static GtkWidget *down_button = NULL;
static GtkWidget *text_radio = NULL;
static GtkWidget *show_grid = NULL;
static GtkWidget *show_extents = NULL;
static PangoContext *context;
static int scale = 10;
static void
on_destroy (gpointer data)
{
window = NULL;
}
static void
update_image (void)
{
const char *text;
PangoFontDescription *desc;
PangoLayout *layout;
PangoRectangle ink, pink, logical;
int baseline;
cairo_surface_t *surface;
cairo_t *cr;
GdkPixbuf *pixbuf;
GdkPixbuf *pixbuf2;
const char *hint;
cairo_font_options_t *fopt;
cairo_hint_style_t hintstyle;
cairo_hint_metrics_t hintmetrics;
int i;
if (!context)
context = gtk_widget_create_pango_context (image);
text = gtk_editable_get_text (GTK_EDITABLE (entry));
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
if (strcmp (hint, "none") == 0)
hintstyle = CAIRO_HINT_STYLE_NONE;
else if (strcmp (hint, "slight") == 0)
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
else if (strcmp (hint, "medium") == 0)
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
else if (strcmp (hint, "full") == 0)
hintstyle = CAIRO_HINT_STYLE_FULL;
else
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
cairo_font_options_set_hint_style (fopt, hintstyle);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (hint_metrics)))
hintmetrics = CAIRO_HINT_METRICS_ON;
else
hintmetrics = CAIRO_HINT_METRICS_OFF;
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
pango_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango_context_changed (context);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
{
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, text, -1);
pango_layout_get_extents (layout, &ink, &logical);
pink = ink;
baseline = pango_layout_get_baseline (layout);
pango_extents_to_pixels (&ink, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_move_to (cr, 10, 10);
pango_cairo_show_layout (cr, layout);
cairo_destroy (cr);
g_object_unref (layout);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
cairo_surface_destroy (surface);
surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (pixbuf2),
CAIRO_FORMAT_ARGB32,
gdk_pixbuf_get_width (pixbuf2),
gdk_pixbuf_get_height (pixbuf2),
gdk_pixbuf_get_rowstride (pixbuf2));
cr = cairo_create (surface);
cairo_set_line_width (cr, 1);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_grid)))
{
cairo_set_source_rgba (cr, 0.2, 0, 0, 0.2);
for (i = 1; i < ink.height + 20; i++)
{
cairo_move_to (cr, 0, scale * i - 0.5);
cairo_line_to (cr, scale * (ink.width + 20), scale * i - 0.5);
cairo_stroke (cr);
}
for (i = 1; i < ink.width + 20; i++)
{
cairo_move_to (cr, scale * i - 0.5, 0);
cairo_line_to (cr, scale * i - 0.5, scale * (ink.height + 20));
cairo_stroke (cr);
}
}
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_extents)))
{
cairo_set_source_rgba (cr, 0, 0, 1, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
scale * pango_units_to_double (logical.width) + 1,
scale * pango_units_to_double (logical.height) + 1);
cairo_stroke (cr);
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_stroke (cr);
cairo_set_source_rgba (cr, 1, 0, 0, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (pink.x)) + 0.5,
scale * (10 + pango_units_to_double (pink.y)) + 0.5,
scale * pango_units_to_double (pink.width) - 1,
scale * pango_units_to_double (pink.height) - 1);
cairo_stroke (cr);
}
cairo_surface_destroy (surface);
cairo_destroy (cr);
}
else
{
PangoLayoutIter *iter;
PangoLayoutRun *run;
PangoGlyphInfo *g;
int i, j;
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, "aaaa", -1);
pango_layout_get_extents (layout, &ink, &logical);
pango_extents_to_pixels (&logical, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
iter = pango_layout_get_iter (layout);
run = pango_layout_iter_get_run (iter);
cairo_set_source_rgb (cr, 0, 0, 0);
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[i]);
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
}
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[i]);
g->geometry.x_offset = i * (PANGO_SCALE / 4);
g->geometry.y_offset = j * (PANGO_SCALE / 4);
}
cairo_move_to (cr, 0, j * logical.height);
pango_cairo_show_layout (cr, layout);
}
cairo_destroy (cr);
pango_layout_iter_free (iter);
g_object_unref (layout);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
cairo_surface_destroy (surface);
}
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
g_object_unref (pixbuf2);
pango_font_description_free (desc);
}
static void
update_buttons (void)
{
gtk_widget_set_sensitive (up_button, scale < 32);
gtk_widget_set_sensitive (down_button, scale > 1);
}
static void
scale_up (void)
{
scale += 1;
update_buttons ();
update_image ();
}
static void
scale_down (void)
{
scale -= 1;
update_buttons ();
update_image ();
}
GtkWidget *
do_fontrendering (GtkWidget *do_widget)
{
if (!window)
{
GtkBuilder *builder;
builder = gtk_builder_new_from_resource ("/fontrendering/fontrendering.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (on_destroy), NULL);
g_object_set_data_full (G_OBJECT (window), "builder", builder, g_object_unref);
font_button = GTK_WIDGET (gtk_builder_get_object (builder, "font_button"));
up_button = GTK_WIDGET (gtk_builder_get_object (builder, "up_button"));
down_button = GTK_WIDGET (gtk_builder_get_object (builder, "down_button"));
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
show_extents = GTK_WIDGET (gtk_builder_get_object (builder, "show_extents"));
g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL);
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_extents, "notify::active", G_CALLBACK (update_image), NULL);
update_image ();
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}
+215
View File
@@ -0,0 +1,215 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="scale_adj">
<property name="upper">24</property>
<property name="step-increment">1</property>
<property name="page-increment">4</property>
</object>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">300</property>
<property name="title">Font rendering</property>
<child>
<object class="GtkGrid">
<property name="margin-top">10</property>
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="margin-start">10</property>
<property name="label">Text</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkEntry" id="entry">
<property name="text">Fonts render</property>
<layout>
<property name="left-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="margin-start">10</property>
<property name="label">Font</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkFontButton" id="font_button">
<layout>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Hinting</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="left-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="hinting">
<property name="active">0</property>
<property name="valign">center</property>
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="slight">Slight</item>
<item translatable="yes" id="medium">Medium</item>
<item translatable="yes" id="full">Full</item>
</items>
<layout>
<property name="left-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="hint_metrics">
<child>
<object class="GtkLabel">
<property name="label">Hint Metrics</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">3</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_extents">
<property name="active">1</property>
<child>
<object class="GtkLabel">
<property name="label">Show Extents</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">4</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_grid">
<property name="active">1</property>
<child>
<object class="GtkLabel">
<property name="label">Show Grid</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<layout>
<property name="left-attach">4</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="up_button">
<property name="icon-name">list-add-symbolic</property>
<style>
<class name="circular"/>
</style>
<layout>
<property name="left-attach">5</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="down_button">
<property name="icon-name">list-remove-symbolic</property>
<style>
<class name="circular"/>
</style>
<layout>
<property name="left-attach">5</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="hexpand">1</property>
<layout>
<property name="left-attach">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style><class name="linked"/></style>
<child>
<object class="GtkRadioButton" id="text_radio">
<property name="draw-indicator">0</property>
<property name="label">Text</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="grid_radio">
<property name="draw-indicator">0</property>
<property name="label">Grid</property>
<property name="group">text_radio</property>
</object>
</child>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="column-span">7</property>
</layout>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="propagate-natural-height">1</property>
<property name="shadow-type">in</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkPicture" id="image">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="can-shrink">0</property>
</object>
</child>
<layout>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
<property name="column-span">7</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</interface>
+1 -1
View File
@@ -202,7 +202,7 @@ languages_variant_init (const char *variant)
else
g_warning ("Failed to load '%s': %s\n", filename, error->message);
g_free (error);
g_clear_error (&error);
g_free (filename);
g_free (buf);
}
+1
View File
@@ -28,6 +28,7 @@ demos = files([
'filtermodel.c',
'fishbowl.c',
'fixed.c',
'fontrendering.c',
'foreigndrawing.c',
'gestures.c',
'glarea.c',
+1
View File
@@ -3435,6 +3435,7 @@ bad things might happen.</property>
<property name="halign">end</property>
<property name="icon-name">emblem-system-symbolic</property>
<property name="menu-model">gear_menu</property>
<property name="tooltip-text">This is a menu button</property>
<layout>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
+4 -9
View File
@@ -11,7 +11,10 @@ GTK is released under the GNU Library General Public License
applications. GTK has a C-based object-oriented architecture that
allows for maximum flexibility. Bindings for many other languages have
been written, including C++, Objective-C, Guile/Scheme, Perl, Python,
TOM, Ada95, Free Pascal, and Eiffel.
TOM, Ada95, Free Pascal, and Eiffel. The GTK library itself contains
<firstterm>widgets</firstterm>, that is, GUI components such as GtkButton
or GtkTextView.
</para>
<para>
GTK depends on the following libraries:
@@ -105,14 +108,6 @@ and rendering it using different rendering APIs. GSK provides renderers
for OpenGL, Vulkan and cairo.
</para></listitem>
</varlistentry>
<varlistentry>
<term>GTK</term>
<listitem><para>
The GTK library itself contains <firstterm>widgets</firstterm>,
that is, GUI components such as GtkButton or GtkTextView.
</para></listitem>
</varlistentry>
</variablelist>
</para>
</partintro>
+3 -1
View File
@@ -98,7 +98,9 @@ _gdk_broadway_display_size_changed (GdkDisplay *display,
GdkBroadwaySurface *toplevel = l->data;
if (toplevel->maximized)
gdk_surface_move_resize (GDK_SURFACE (toplevel), 0, 0, msg->width, msg->height);
gdk_broadway_surface_move_resize (GDK_SURFACE (toplevel),
0, 0,
msg->width, msg->height);
}
}
+6
View File
@@ -70,6 +70,12 @@ void _gdk_broadway_surface_grab_check_unmap (GdkSurface *surface,
gulong serial);
void gdk_broadway_surface_update_popups (GdkSurface *surface);
void gdk_broadway_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height);
void _gdk_keymap_keys_changed (GdkDisplay *display);
gint _gdk_broadway_get_group_for_state (GdkDisplay *display,
GdkModifierType state);
+100 -18
View File
@@ -368,12 +368,12 @@ gdk_broadway_surface_withdraw (GdkSurface *surface)
}
static void
gdk_broadway_surface_move_resize (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
gdk_broadway_surface_move_resize_internal (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
@@ -424,6 +424,84 @@ gdk_broadway_surface_move_resize (GdkSurface *surface,
}
}
void
gdk_broadway_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height)
{
gdk_broadway_surface_move_resize_internal (surface, TRUE,
x, y,
width, height);
}
static void
gdk_broadway_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
gdk_broadway_surface_move_resize_internal (surface, FALSE,
0, 0,
width, height);
}
static void
gdk_broadway_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_broadway_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
}
static void
gdk_broadway_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
gdk_broadway_surface_move_resize (surface,
x, y,
final_rect.width, final_rect.height);
}
else
{
gdk_broadway_surface_move (surface, x, y);
}
}
static void
gdk_broadway_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_broadway_surface_moved_to_rect);
}
static void
gdk_broadway_surface_raise (GdkSurface *surface)
{
@@ -695,9 +773,9 @@ gdk_broadway_surface_maximize (GdkSurface *surface)
monitor = gdk_display_get_primary_monitor (display);
gdk_monitor_get_geometry (monitor, &geom);
gdk_surface_move_resize (surface,
geom.x, geom.y,
geom.width, geom.height);
gdk_broadway_surface_move_resize (surface,
geom.x, geom.y,
geom.width, geom.height);
}
static void
@@ -718,11 +796,11 @@ gdk_broadway_surface_unmaximize (GdkSurface *surface)
gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_MAXIMIZED, 0);
gdk_surface_move_resize (surface,
impl->pre_maximize_x,
impl->pre_maximize_y,
impl->pre_maximize_width,
impl->pre_maximize_height);
gdk_broadway_surface_move_resize (surface,
impl->pre_maximize_x,
impl->pre_maximize_y,
impl->pre_maximize_width,
impl->pre_maximize_height);
}
static void
@@ -813,7 +891,9 @@ gdk_broadway_surface_update_popups (GdkSurface *parent)
int new_y = parent->y + popup_impl->offset_y;
if (new_x != popup->x || new_y != popup->y)
gdk_broadway_surface_move_resize (popup, TRUE, new_x, new_y, popup->width, popup->height);
gdk_broadway_surface_move_resize (popup,
new_x, new_y,
popup->width, popup->height);
gdk_broadway_surface_restack_toplevel (popup, parent, TRUE);
}
}
@@ -935,7 +1015,8 @@ update_pos (MoveResizeData *mv_resize,
w, h, &w, &h);
}
gdk_surface_move_resize (mv_resize->moveresize_surface, x, y, w, h);
gdk_broadway_surface_move_resize (mv_resize->moveresize_surface,
x, y, w, h);
}
else
{
@@ -944,7 +1025,7 @@ update_pos (MoveResizeData *mv_resize,
x = mv_resize->moveresize_orig_x + dx;
y = mv_resize->moveresize_orig_y + dy;
gdk_surface_move (mv_resize->moveresize_surface, x, y);
gdk_broadway_surface_move (mv_resize->moveresize_surface, x, y);
}
}
@@ -1311,7 +1392,8 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
impl_class->raise = gdk_broadway_surface_raise;
impl_class->lower = gdk_broadway_surface_lower;
impl_class->restack_toplevel = gdk_broadway_surface_restack_toplevel;
impl_class->move_resize = gdk_broadway_surface_move_resize;
impl_class->toplevel_resize = gdk_broadway_surface_toplevel_resize;
impl_class->move_to_rect = gdk_broadway_surface_move_to_rect;
impl_class->get_geometry = gdk_broadway_surface_get_geometry;
impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
impl_class->get_device_state = gdk_broadway_surface_get_device_state;
-10
View File
@@ -264,16 +264,6 @@ void gdk_surface_get_geometry (GdkSurface *surface,
gint *width,
gint *height);
void gdk_surface_move (GdkSurface *surface,
gint x,
gint y);
void gdk_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height);
GdkGLContext *gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
G_END_DECLS
+13 -94
View File
@@ -246,14 +246,15 @@ maybe_flip_position (gint bounds_pos,
return primary;
}
static void
gdk_surface_real_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
void
gdk_surface_move_to_rect_helper (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy,
GdkSurfaceMovedToRect moved_to_rect)
{
GdkSurface *toplevel;
GdkDisplay *display;
@@ -362,17 +363,14 @@ gdk_surface_real_move_to_rect (GdkSurface *surface,
final_rect.width += surface->shadow_left + surface->shadow_right;
final_rect.height += surface->shadow_top + surface->shadow_bottom;
if (final_rect.width != surface->width || final_rect.height != surface->height)
gdk_surface_move_resize (surface, final_rect.x, final_rect.y, final_rect.width, final_rect.height);
else
gdk_surface_move (surface, final_rect.x, final_rect.y);
gdk_surface_get_origin (toplevel, &x, &y);
final_rect.x -= x;
final_rect.y -= y;
flipped_rect.x -= x;
flipped_rect.y -= y;
moved_to_rect (surface, final_rect);
g_signal_emit_by_name (surface,
"moved-to-rect",
&flipped_rect,
@@ -411,7 +409,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
object_class->get_property = gdk_surface_get_property;
klass->beep = gdk_surface_real_beep;
klass->move_to_rect = gdk_surface_real_move_to_rect;
/**
* GdkSurface:cursor:
@@ -2072,59 +2069,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
GDK_SURFACE_GET_CLASS (surface)->hide (surface);
}
static void
gdk_surface_move_resize_toplevel (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
GDK_SURFACE_GET_CLASS (surface)->move_resize (surface, with_move, x, y, width, height);
}
static void
gdk_surface_move_resize_internal (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
g_return_if_fail (GDK_IS_SURFACE (surface));
if (surface->destroyed)
return;
gdk_surface_move_resize_toplevel (surface, with_move, x, y, width, height);
}
/*
* gdk_surface_move:
* @surface: a #GdkSurface
* @x: X coordinate relative to surfaces parent
* @y: Y coordinate relative to surfaces parent
*
* Repositions a surface relative to its parent surface.
* For toplevel surfaces, window managers may ignore or modify the move;
* you should probably use gtk_window_move() on a #GtkWindow widget
* anyway, instead of using GDK functions. For child surfaces,
* the move will reliably succeed.
*
* If youre also planning to resize the surface, use gdk_surface_move_resize()
* to both move and resize simultaneously, for a nicer visual effect.
**/
void
gdk_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
}
/**
* gdk_surface_resize:
* @surface: a #GdkSurface
@@ -2142,31 +2086,7 @@ gdk_surface_resize (GdkSurface *surface,
gint width,
gint height)
{
gdk_surface_move_resize_internal (surface, FALSE, 0, 0, width, height);
}
/*
* gdk_surface_move_resize:
* @surface: a #GdkSurface
* @x: new X position relative to surfaces parent
* @y: new Y position relative to surfaces parent
* @width: new width
* @height: new height
*
* Equivalent to calling gdk_surface_move() and gdk_surface_resize(),
* except that both operations are performed at once, avoiding strange
* visual effects. (i.e. the user may be able to see the surface first
* move, then resize, if you dont use gdk_surface_move_resize().)
**/
void
gdk_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height)
{
gdk_surface_move_resize_internal (surface, TRUE, x, y, width, height);
GDK_SURFACE_GET_CLASS (surface)->toplevel_resize (surface, width, height);
}
/**
@@ -2963,8 +2883,7 @@ gdk_surface_set_modal_hint (GdkSurface *surface,
* this is to constrain user resizing, but the windowing system
* will typically (but is not required to) also constrain the
* current size of the surface to the provided values and
* constrain programatic resizing via gdk_surface_resize() or
* gdk_surface_move_resize().
* constrain programatic resizing via gdk_surface_resize().
*
* Note that on X11, this effect has no effect on surfaces
* of type %GDK_SURFACE_TEMP since these surfaces are not resizable
+14 -4
View File
@@ -113,10 +113,7 @@ struct _GdkSurfaceClass
GdkSurface *sibling,
gboolean above);
void (* move_resize) (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
void (* toplevel_resize) (GdkSurface *surface,
gint width,
gint height);
void (* move_to_rect) (GdkSurface *surface,
@@ -258,6 +255,19 @@ struct _GdkSurfaceClass
void gdk_surface_set_state (GdkSurface *surface,
GdkSurfaceState new_state);
typedef void (* GdkSurfaceMovedToRect) (GdkSurface *surface,
GdkRectangle final_rect);
void
gdk_surface_move_to_rect_helper (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy,
GdkSurfaceMovedToRect moved_to_rect);
G_END_DECLS
#endif /* __GDK_SURFACE_PRIVATE_H__ */
+51 -13
View File
@@ -1237,24 +1237,61 @@ window_quartz_move_resize (GdkSurface *window,
}
static void
gdk_surface_quartz_move_resize (GdkSurface *window,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
gdk_surface_quartz_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
if (with_move && (width < 0 && height < 0))
window_quartz_move (window, x, y);
window_quartz_resize (window, width, height);
}
static void
gdk_quartz_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
window_quartz_move_resize (surface,
x, y,
final_rect.width, final_rect.height);
}
else
{
if (with_move)
window_quartz_move_resize (window, x, y, width, height);
else
window_quartz_resize (window, width, height);
window_quartz_resize (surface, final_rect.width, final_rect.height);
}
}
static void
gdk_quartz_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_quartz_surface_moved_to_rect);
}
/* Get the toplevel ordering from NSApp and update our own list. We do
* this on demand since the NSApps list is not up to date directly
* after we get windowDidBecomeMain.
@@ -2641,7 +2678,8 @@ gdk_surface_impl_quartz_class_init (GdkSurfaceImplQuartzClass *klass)
impl_class->raise = gdk_surface_quartz_raise;
impl_class->lower = gdk_surface_quartz_lower;
impl_class->restack_toplevel = gdk_surface_quartz_restack_toplevel;
impl_class->move_resize = gdk_surface_quartz_move_resize;
impl_class->toplevel_resize = gdk_surface_quartz_toplevel_resize;
impl_class->move_to_rect = gdk_surface_quartz_move_to_rect;
impl_class->get_geometry = gdk_surface_quartz_get_geometry;
impl_class->get_root_coords = gdk_surface_quartz_get_root_coords;
impl_class->get_device_state = gdk_surface_quartz_get_device_state;
+10 -2
View File
@@ -93,6 +93,7 @@
#define GTK_SHELL1_VERSION 2
#define OUTPUT_VERSION_WITH_DONE 2
#define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3
static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland);
@@ -531,7 +532,7 @@ gdk_registry_handle_global (void *data,
}
else if (strcmp(interface, "zxdg_output_manager_v1") == 0)
{
display_wayland->xdg_output_manager_version = MIN (version, 2);
display_wayland->xdg_output_manager_version = MIN (version, 3);
display_wayland->xdg_output_manager =
wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_output_manager_v1_interface,
@@ -2217,6 +2218,9 @@ should_update_monitor (GdkWaylandMonitor *monitor)
static void
apply_monitor_change (GdkWaylandMonitor *monitor)
{
GdkDisplay *display = GDK_MONITOR (monitor)->display;
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GDK_NOTE (MISC,
g_message ("monitor %d changed position %d %d, size %d %d",
monitor->id,
@@ -2227,7 +2231,11 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
gdk_monitor_set_size (GDK_MONITOR (monitor), monitor->width, monitor->height);
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
monitor->wl_output_done = FALSE;
monitor->xdg_output_done = FALSE;
/* xdg_output v3 marks xdg_output.done as deprecated, so if using
* that version, no need to wait for xdg-output.done event.
*/
monitor->xdg_output_done =
(display_wayland->xdg_output_manager_version >= NO_XDG_OUTPUT_DONE_SINCE_VERSION);
update_scale (GDK_MONITOR (monitor)->display);
}
+160 -93
View File
@@ -150,9 +150,20 @@ struct _GdkWaylandSurface
} pending_move_to_rect;
struct {
int width;
int height;
GdkSurfaceState state;
struct {
int width;
int height;
GdkSurfaceState state;
} toplevel;
struct {
int x;
int y;
int width;
int height;
} popup;
uint32_t serial;
} pending;
struct {
@@ -170,10 +181,12 @@ struct _GdkWaylandSurfaceClass
GdkSurfaceClass parent_class;
};
static void gdk_wayland_surface_maybe_configure (GdkSurface *surface,
int width,
int height,
int scale);
static void gdk_wayland_surface_maybe_resize (GdkSurface *surface,
int width,
int height,
int scale);
static void gdk_wayland_surface_configure (GdkSurface *surface);
static void maybe_set_gtk_surface_dbus_properties (GdkSurface *surface);
static void maybe_set_gtk_surface_modal (GdkSurface *surface);
@@ -184,6 +197,12 @@ static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface);
static void unset_transient_for_exported (GdkSurface *surface);
static void gdk_wayland_surface_move_resize (GdkSurface *surface,
gint x,
gint y,
gint width,
gint height);
static void calculate_moved_to_rect_result (GdkSurface *surface,
int x,
int y,
@@ -492,7 +511,9 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
}
/* Notify app that scale changed */
gdk_wayland_surface_maybe_configure (surface, surface->width, surface->height, scale);
gdk_wayland_surface_maybe_resize (surface,
surface->width, surface->height,
scale);
}
static void gdk_wayland_surface_create_surface (GdkSurface *surface);
@@ -649,10 +670,10 @@ gdk_wayland_surface_finalize (GObject *object)
}
static void
gdk_wayland_surface_configure (GdkSurface *surface,
int width,
int height,
int scale)
gdk_wayland_surface_resize (GdkSurface *surface,
int width,
int height,
int scale)
{
GdkDisplay *display;
GdkEvent *event;
@@ -702,10 +723,10 @@ static void gdk_wayland_surface_show (GdkSurface *surface,
static void gdk_wayland_surface_hide (GdkSurface *surface);
static void
gdk_wayland_surface_maybe_configure (GdkSurface *surface,
int width,
int height,
int scale)
gdk_wayland_surface_maybe_resize (GdkSurface *surface,
int width,
int height,
int scale)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gboolean is_xdg_popup;
@@ -728,7 +749,7 @@ gdk_wayland_surface_maybe_configure (GdkSurface *surface,
if (is_xdg_popup && is_visible && !impl->initial_configure_received)
gdk_wayland_surface_hide (surface);
gdk_wayland_surface_configure (surface, width, height, scale);
gdk_wayland_surface_resize (surface, width, height, scale);
if (is_xdg_popup && is_visible && !impl->initial_configure_received)
gdk_wayland_surface_show (surface, FALSE);
@@ -1039,44 +1060,27 @@ gdk_wayland_surface_create_surface (GdkSurface *surface)
}
static void
gdk_wayland_surface_handle_configure (GdkSurface *surface,
uint32_t serial)
gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland =
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkSurfaceState new_state;
int width = impl->pending.width;
int height = impl->pending.height;
int width, height;
gboolean fixed_size;
gboolean saved_size;
if (!impl->initial_configure_received)
{
gdk_surface_thaw_updates (surface);
impl->initial_configure_received = TRUE;
}
if (impl->display_server.xdg_popup)
{
xdg_surface_ack_configure (impl->display_server.xdg_surface, serial);
return;
}
else if (impl->display_server.zxdg_popup_v6)
{
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
serial);
return;
}
new_state = impl->pending.state;
impl->pending.state = 0;
new_state = impl->pending.toplevel.state;
impl->pending.toplevel.state = 0;
fixed_size =
new_state & (GDK_SURFACE_STATE_MAXIMIZED |
GDK_SURFACE_STATE_FULLSCREEN |
GDK_SURFACE_STATE_TILED);
width = impl->pending.toplevel.width;
height = impl->pending.toplevel.height;
saved_size = (width == 0 && height == 0);
/* According to xdg_shell, an xdg_surface.configure with size 0x0
* should be interpreted as that it is up to the client to set a
@@ -1113,7 +1117,7 @@ gdk_wayland_surface_handle_configure (GdkSurface *surface,
_gdk_wayland_surface_save_size (surface);
}
gdk_wayland_surface_configure (surface, width, height, impl->scale);
gdk_wayland_surface_resize (surface, width, height, impl->scale);
}
GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS,
@@ -1129,11 +1133,12 @@ gdk_wayland_surface_handle_configure (GdkSurface *surface,
switch (display_wayland->shell_variant)
{
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
xdg_surface_ack_configure (impl->display_server.xdg_surface, serial);
xdg_surface_ack_configure (impl->display_server.xdg_surface,
impl->pending.serial);
break;
case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
serial);
impl->pending.serial);
break;
default:
g_assert_not_reached ();
@@ -1144,6 +1149,87 @@ gdk_wayland_surface_handle_configure (GdkSurface *surface,
gdk_wayland_surface_update_dialogs (surface);
}
static void
gdk_wayland_surface_configure_popup (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
int x, y, width, height;
GdkRectangle flipped_rect;
GdkRectangle final_rect;
gboolean flipped_x;
gboolean flipped_y;
g_return_if_fail (impl->transient_for);
if (impl->display_server.xdg_popup)
{
xdg_surface_ack_configure (impl->display_server.xdg_surface,
impl->pending.serial);
}
else if (impl->display_server.zxdg_popup_v6)
{
zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6,
impl->pending.serial);
}
if (impl->position_method != POSITION_METHOD_MOVE_TO_RECT)
return;
x = impl->pending.popup.x;
y = impl->pending.popup.y;
width = impl->pending.popup.width;
height = impl->pending.popup.height;
gdk_wayland_surface_resize (surface, width, height, impl->scale);
calculate_moved_to_rect_result (surface,
x, y,
width, height,
&flipped_rect,
&final_rect,
&flipped_x,
&flipped_y);
impl->position_method = POSITION_METHOD_MOVE_TO_RECT;
g_signal_emit_by_name (surface,
"moved-to-rect",
&flipped_rect,
&final_rect,
flipped_x,
flipped_y);
}
static void
gdk_wayland_surface_configure (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!impl->initial_configure_received)
{
gdk_surface_thaw_updates (surface);
impl->initial_configure_received = TRUE;
}
if (is_realized_popup (surface))
gdk_wayland_surface_configure_popup (surface);
else if (is_realized_toplevel (surface))
gdk_wayland_surface_configure_toplevel (surface);
else
g_warn_if_reached ();
}
static void
gdk_wayland_surface_handle_configure (GdkSurface *surface,
uint32_t serial)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
impl->pending.serial = serial;
gdk_wayland_surface_configure (surface);
}
static void
gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface,
int32_t width,
@@ -1152,9 +1238,9 @@ gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface,
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
impl->pending.state |= state;
impl->pending.width = width;
impl->pending.height = height;
impl->pending.toplevel.state |= state;
impl->pending.toplevel.width = width;
impl->pending.toplevel.height = height;
}
static void
@@ -1433,30 +1519,11 @@ gdk_wayland_surface_handle_configure_popup (GdkSurface *surface,
int32_t height)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkRectangle flipped_rect;
GdkRectangle final_rect;
gboolean flipped_x;
gboolean flipped_y;
g_return_if_fail (impl->transient_for);
if (impl->position_method != POSITION_METHOD_MOVE_TO_RECT)
return;
calculate_moved_to_rect_result (surface, x, y, width, height,
&flipped_rect,
&final_rect,
&flipped_x,
&flipped_y);
impl->position_method = POSITION_METHOD_MOVE_TO_RECT;
g_signal_emit_by_name (surface,
"moved-to-rect",
&flipped_rect,
&final_rect,
flipped_x,
flipped_y);
impl->pending.popup.x = x;
impl->pending.popup.y = y;
impl->pending.popup.width = width;
impl->pending.popup.height = height;
}
static void
@@ -1902,9 +1969,9 @@ calculate_moved_to_rect_result (GdkSurface *surface,
surface_width = width + surface->shadow_left + surface->shadow_right;
surface_height = height + surface->shadow_top + surface->shadow_bottom;
gdk_surface_move_resize (surface,
surface_x, surface_y,
surface_width, surface_height);
gdk_wayland_surface_move_resize (surface,
surface_x, surface_y,
surface_width, surface_height);
calculate_popup_rect (surface,
impl->pending_move_to_rect.rect_anchor,
@@ -2647,7 +2714,6 @@ gdk_wayland_surface_restack_toplevel (GdkSurface *surface,
static void
gdk_wayland_surface_move_resize (GdkSurface *surface,
gboolean with_move,
gint x,
gint y,
gint width,
@@ -2655,22 +2721,21 @@ gdk_wayland_surface_move_resize (GdkSurface *surface,
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (with_move)
{
/* Each toplevel has in its own "root" coordinate system */
if (GDK_SURFACE_TYPE (surface) != GDK_SURFACE_TOPLEVEL)
{
surface->x = x;
surface->y = y;
impl->position_method = POSITION_METHOD_MOVE_RESIZE;
}
}
surface->x = x;
surface->y = y;
gdk_wayland_surface_maybe_resize (surface, width, height, impl->scale);
}
/* If this function is called with width and height = -1 then that means
* just move the surface - don't update its size
*/
if (width > 0 && height > 0)
gdk_wayland_surface_maybe_configure (surface, width, height, impl->scale);
static void
gdk_wayland_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gdk_wayland_surface_maybe_resize (surface,
width, height,
impl->scale);
}
/* Avoid zero width/height as this is a protocol error */
@@ -2924,7 +2989,7 @@ gtk_surface_configure (void *data,
}
}
impl->pending.state |= new_state;
impl->pending.toplevel.state |= new_state;
}
static void
@@ -2961,7 +3026,7 @@ gtk_surface_configure_edges (void *data,
}
}
impl->pending.state |= new_state;
impl->pending.toplevel.state |= new_state;
}
static const struct gtk_surface1_listener gtk_surface_listener = {
@@ -3663,7 +3728,9 @@ gdk_wayland_surface_set_shadow_width (GdkSurface *surface,
(impl->margin_left + impl->margin_right) + (left + right);
new_height = surface->height -
(impl->margin_top + impl->margin_bottom) + (top + bottom);
gdk_wayland_surface_maybe_configure (surface, new_width, new_height, impl->scale);
gdk_wayland_surface_maybe_resize (surface,
new_width, new_height,
impl->scale);
impl->margin_left = left;
impl->margin_right = right;
@@ -3746,7 +3813,7 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
impl_class->raise = gdk_wayland_surface_raise;
impl_class->lower = gdk_wayland_surface_lower;
impl_class->restack_toplevel = gdk_wayland_surface_restack_toplevel;
impl_class->move_resize = gdk_wayland_surface_move_resize;
impl_class->toplevel_resize = gdk_wayland_surface_toplevel_resize;
impl_class->move_to_rect = gdk_wayland_surface_move_to_rect;
impl_class->get_geometry = gdk_wayland_surface_get_geometry;
impl_class->get_root_coords = gdk_wayland_surface_get_root_coords;
+11 -6
View File
@@ -736,9 +736,9 @@ move_drag_surface (GdkDrag *drag,
g_assert (_win32_main_thread == NULL ||
_win32_main_thread == g_thread_self ());
gdk_surface_move (drag_win32->drag_surface,
x_root - drag_win32->hot_x,
y_root - drag_win32->hot_y);
gdk_win32_surface_move (drag_win32->drag_surface,
x_root - drag_win32->hot_x,
y_root - drag_win32->hot_y);
gdk_surface_raise (drag_win32->drag_surface);
}
@@ -2090,6 +2090,7 @@ gdk_drag_anim_timeout (gpointer data)
gint64 current_time;
double f;
double t;
gint x, y;
if (!frame_clock)
return G_SOURCE_REMOVE;
@@ -2104,9 +2105,13 @@ gdk_drag_anim_timeout (gpointer data)
t = ease_out_cubic (f);
gdk_surface_show (drag->drag_surface);
gdk_surface_move (drag->drag_surface,
drag->util_data.last_x + (drag->start_x - drag->util_data.last_x) * t - drag->hot_x,
drag->util_data.last_y + (drag->start_y - drag->util_data.last_y) * t - drag->hot_y);
x = (drag->util_data.last_x +
(drag->start_x - drag->util_data.last_x) * t -
drag->hot_x);
y = (drag->util_data.last_y +
(drag->start_y - drag->util_data.last_y) * t -
drag->hot_y);
gdk_win32_surface_move (drag->drag_surface, x, y);
gdk_surface_set_opacity (drag->drag_surface, 1.0 - f);
return G_SOURCE_CONTINUE;
+3 -1
View File
@@ -1588,7 +1588,9 @@ handle_dpi_changed (GdkSurface *window,
_gdk_win32_adjust_client_rect (window, rect);
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
gdk_surface_move_resize (window, window->x, window->y, window->width, window->height);
gdk_win32_surface_move_resize (window,
window->x, window->y,
window->width, window->height);
else
gdk_surface_resize (window, window->width, window->height);
}
+102 -23
View File
@@ -1098,8 +1098,8 @@ gdk_win32_surface_withdraw (GdkSurface *window)
}
static void
gdk_win32_surface_move (GdkSurface *window,
gint x, gint y)
gdk_win32_surface_do_move (GdkSurface *window,
gint x, gint y)
{
RECT outer_rect;
GdkWin32Surface *impl;
@@ -1174,11 +1174,11 @@ gdk_win32_surface_resize (GdkSurface *window,
}
static void
gdk_win32_surface_move_resize_internal (GdkSurface *window,
gint x,
gint y,
gint width,
gint height)
gdk_win32_surface_do_move_resize (GdkSurface *window,
gint x,
gint y,
gint width,
gint height)
{
RECT outer_rect;
GdkWin32Surface *impl;
@@ -1224,12 +1224,12 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
}
static void
gdk_win32_surface_move_resize (GdkSurface *window,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
gdk_win32_surface_move_resize_internal (GdkSurface *window,
gboolean with_move,
gint x,
gint y,
gint width,
gint height)
{
GdkWin32Surface *surface = GDK_WIN32_SURFACE (window);
@@ -1242,13 +1242,13 @@ gdk_win32_surface_move_resize (GdkSurface *window,
if (with_move && (width < 0 && height < 0))
{
gdk_win32_surface_move (window, x, y);
gdk_win32_surface_do_move (window, x, y);
}
else
{
if (with_move)
{
gdk_win32_surface_move_resize_internal (window, x, y, width, height);
gdk_win32_surface_do_move_resize (window, x, y, width, height);
}
else
{
@@ -1262,6 +1262,80 @@ gdk_win32_surface_move_resize (GdkSurface *window,
_gdk_win32_emit_configure_event (window);
}
void
gdk_win32_surface_move_resize (GdkSurface *window,
gint x,
gint y,
gint width,
gint height)
{
gdk_win32_surface_move_resize_internal (window, TRUE, x, y, width, height);
}
static void
gdk_win32_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
gdk_win32_surface_move_resize_internal (surface, FALSE, 0, 0, width, height);
}
void
gdk_win32_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_win32_surface_move_resize_internal (surface, TRUE, x, y, -1, -1);
}
static void
gdk_win32_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
gdk_win32_surface_move_resize (surface,
x, y,
final_rect.width, final_rect.height);
}
else
{
gdk_win32_surface_move (surface, x, y);
}
}
static void
gdk_win32_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_win32_surface_moved_to_rect);
}
static void
gdk_win32_surface_raise (GdkSurface *window)
{
@@ -2518,8 +2592,8 @@ unsnap (GdkSurface *window,
GDK_NOTE (MISC, g_print ("Unsnapped window size %d x %d @ %d : %d\n", rect.width, rect.height, rect.x, rect.y));
gdk_surface_move_resize (window, rect.x, rect.y,
rect.width, rect.height);
gdk_win32_surface_move_resize (window, rect.x, rect.y,
rect.width, rect.height);
g_clear_pointer (&impl->snap_stash, g_free);
g_clear_pointer (&impl->snap_stash_int, g_free);
@@ -2624,7 +2698,7 @@ snap_up (GdkSurface *window)
width += impl->margins_x;
height += impl->margins_y;
gdk_surface_move_resize (window, x, y, width, height);
gdk_win32_surface_move_resize (window, x, y, width, height);
}
static void
@@ -2650,7 +2724,9 @@ snap_left (GdkSurface *window,
rect.width = rect.width + impl->margins_x;
rect.height = rect.height + impl->margins_y;
gdk_surface_move_resize (window, rect.x, rect.y, rect.width, rect.height);
gdk_win32_surface_move_resize (window,
rect.x, rect.y,
rect.width, rect.height);
}
static void
@@ -2677,7 +2753,9 @@ snap_right (GdkSurface *window,
rect.width = rect.width + impl->margins_x;
rect.height = rect.height + impl->margins_y;
gdk_surface_move_resize (window, rect.x, rect.y, rect.width, rect.height);
gdk_win32_surface_move_resize (window,
rect.x, rect.y,
rect.width, rect.height);
}
void
@@ -3928,8 +4006,8 @@ setup_drag_move_resize_context (GdkSurface *window,
GDK_NOTE (MISC, g_print ("Unsnapped window to %d : %d\n",
new_pos.x, new_pos.y));
discard_snapinfo (window);
gdk_surface_move_resize (window, new_pos.x, new_pos.y,
new_pos.width, new_pos.height);
gdk_win32_surface_move_resize (window, new_pos.x, new_pos.y,
new_pos.width, new_pos.height);
}
@@ -5082,7 +5160,8 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
impl_class->raise = gdk_win32_surface_raise;
impl_class->lower = gdk_win32_surface_lower;
impl_class->restack_toplevel = gdk_win32_surface_restack_toplevel;
impl_class->move_resize = gdk_win32_surface_move_resize;
impl_class->toplevel_resize = gdk_win32_surface_toplevel_resize;
impl_class->move_to_rect = gdk_win32_surface_move_to_rect;
impl_class->get_geometry = gdk_win32_surface_get_geometry;
impl_class->get_device_state = gdk_surface_win32_get_device_state;
impl_class->get_root_coords = gdk_win32_surface_get_root_coords;
+9
View File
@@ -361,6 +361,15 @@ void _gdk_win32_update_layered_window_from_cache (GdkSurface *window,
gboolean do_resize,
gboolean do_paint);
void gdk_win32_surface_move (GdkSurface *surface,
gint x,
gint y);
void gdk_win32_surface_move_resize (GdkSurface *window,
gint x,
gint y,
gint width,
gint height);
void
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
+2 -2
View File
@@ -289,7 +289,7 @@ gdk_x11_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
files_count = g_list_length (files);
if (files_count == 0)
{
description = g_strdup_printf (_("Starting %s"), g_app_info_get_name (info));
description = g_strdup_printf (_("Starting %s"), g_app_info_get_name (info));
}
else if (files_count == 1)
{
@@ -302,7 +302,7 @@ gdk_x11_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
0, NULL, NULL);
display_name = get_display_name (files->data, fileinfo);
description = g_strdup_printf (_("Opening %s"), display_name);
description = g_strdup_printf (_("Opening %s"), display_name);
g_free (display_name);
}
else
+6 -6
View File
@@ -1459,9 +1459,9 @@ move_drag_surface (GdkDrag *drag,
{
GdkX11Drag *drag_x11 = GDK_X11_DRAG (drag);
gdk_surface_move (drag_x11->drag_surface,
x_root - drag_x11->hot_x,
y_root - drag_x11->hot_y);
gdk_x11_surface_move (drag_x11->drag_surface,
x_root - drag_x11->hot_x,
y_root - drag_x11->hot_y);
gdk_surface_raise (drag_x11->drag_surface);
}
@@ -1841,9 +1841,9 @@ gdk_drag_anim_timeout (gpointer data)
t = ease_out_cubic (f);
gdk_surface_show (drag->drag_surface);
gdk_surface_move (drag->drag_surface,
drag->last_x + (drag->start_x - drag->last_x) * t,
drag->last_y + (drag->start_y - drag->last_y) * t);
gdk_x11_surface_move (drag->drag_surface,
drag->last_x + (drag->start_x - drag->last_x) * t,
drag->last_y + (drag->start_y - drag->last_y) * t);
gdk_surface_set_opacity (drag->drag_surface, 1.0 - f);
return G_SOURCE_CONTINUE;
+71 -4
View File
@@ -1392,6 +1392,71 @@ gdk_x11_surface_move_resize (GdkSurface *surface,
}
}
static void
gdk_x11_surface_toplevel_resize (GdkSurface *surface,
gint width,
gint height)
{
x11_surface_resize (surface, width, height);
}
void
gdk_x11_surface_move (GdkSurface *surface,
gint x,
gint y)
{
gdk_x11_surface_move_resize (surface, TRUE, x, y, -1, -1);
}
static void
gdk_x11_surface_moved_to_rect (GdkSurface *surface,
GdkRectangle final_rect)
{
GdkSurface *toplevel;
int x, y;
if (surface->surface_type == GDK_SURFACE_POPUP)
toplevel = surface->parent;
else
toplevel = surface->transient_for;
gdk_surface_get_origin (toplevel, &x, &y);
x += final_rect.x;
y += final_rect.y;
if (final_rect.width != surface->width ||
final_rect.height != surface->height)
{
gdk_x11_surface_move_resize (surface,
TRUE,
x, y,
final_rect.width, final_rect.height);
}
else
{
gdk_x11_surface_move (surface, x, y);
}
}
static void
gdk_x11_surface_move_to_rect (GdkSurface *surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity surface_anchor,
GdkAnchorHints anchor_hints,
gint rect_anchor_dx,
gint rect_anchor_dy)
{
gdk_surface_move_to_rect_helper (surface,
rect,
rect_anchor,
surface_anchor,
anchor_hints,
rect_anchor_dx,
rect_anchor_dy,
gdk_x11_surface_moved_to_rect);
}
static void gdk_x11_surface_restack_toplevel (GdkSurface *surface,
GdkSurface *sibling,
gboolean above);
@@ -3245,7 +3310,7 @@ gdk_x11_surface_fullscreen_on_monitor (GdkSurface *surface,
return;
gdk_monitor_get_geometry (monitor, &geom);
gdk_surface_move (surface, geom.x, geom.y);
gdk_x11_surface_move (surface, geom.x, geom.y);
gdk_surface_set_fullscreen_mode (surface, GDK_FULLSCREEN_ON_CURRENT_MONITOR);
gdk_x11_surface_fullscreen (surface);
@@ -3887,7 +3952,8 @@ update_pos (MoveResizeData *mv_resize,
w, h, &w, &h);
}
gdk_surface_move_resize (mv_resize->moveresize_surface, x, y, w, h);
gdk_x11_surface_move_resize (mv_resize->moveresize_surface, TRUE,
x, y, w, h);
}
else
{
@@ -3896,7 +3962,7 @@ update_pos (MoveResizeData *mv_resize,
x = mv_resize->moveresize_orig_x + dx;
y = mv_resize->moveresize_orig_y + dy;
gdk_surface_move (mv_resize->moveresize_surface, x, y);
gdk_x11_surface_move (mv_resize->moveresize_surface, x, y);
}
}
@@ -4589,7 +4655,8 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
impl_class->raise = gdk_x11_surface_raise;
impl_class->lower = gdk_x11_surface_lower;
impl_class->restack_toplevel = gdk_x11_surface_restack_toplevel;
impl_class->move_resize = gdk_x11_surface_move_resize;
impl_class->toplevel_resize = gdk_x11_surface_toplevel_resize;
impl_class->move_to_rect = gdk_x11_surface_move_to_rect;
impl_class->get_geometry = gdk_x11_surface_get_geometry;
impl_class->get_root_coords = gdk_x11_surface_get_root_coords;
impl_class->get_device_state = gdk_x11_surface_get_device_state;
+4
View File
@@ -183,6 +183,10 @@ void _gdk_x11_surface_set_surface_scale (GdkSurface *window,
void gdk_x11_surface_pre_damage (GdkSurface *surface);
void gdk_x11_surface_move (GdkSurface *surface,
gint x,
gint y);
G_END_DECLS
#endif /* __GDK_X11_SURFACE__ */
+70 -84
View File
@@ -24,6 +24,7 @@
*/
#define MAX_FRAME_AGE (5 * 60)
#define MAX_GLYPH_SIZE 128 /* Will get its own texture if bigger */
static guint glyph_cache_hash (gconstpointer v);
static gboolean glyph_cache_equal (gconstpointer v1,
@@ -82,6 +83,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
return key1->font == key2->font &&
key1->glyph == key2->glyph &&
key1->xshift == key2->xshift &&
key1->yshift == key2->yshift &&
key1->scale == key2->scale;
}
@@ -90,7 +93,11 @@ glyph_cache_hash (gconstpointer v)
{
const GlyphCacheKey *key = v;
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
return GPOINTER_TO_UINT (key->font) ^
key->glyph ^
(key->xshift << 24) ^
(key->yshift << 26) ^
key->scale;
}
static void
@@ -116,8 +123,7 @@ render_glyph (GlyphCacheKey *key,
cairo_surface_t *surface;
cairo_t *cr;
cairo_scaled_font_t *scaled_font;
PangoGlyphString glyph_string;
PangoGlyphInfo glyph_info;
cairo_glyph_t cairo_glyph;
int surface_width, surface_height;
int stride;
unsigned char *data;
@@ -144,18 +150,14 @@ render_glyph (GlyphCacheKey *key,
cairo_set_scaled_font (cr, scaled_font);
cairo_set_source_rgba (cr, 1, 1, 1, 1);
glyph_info.glyph = key->glyph;
glyph_info.geometry.width = value->draw_width * 1024;
cairo_glyph.index = key->glyph;
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
glyph_info.geometry.x_offset = 0;
cairo_glyph.x = 0.25 * key->xshift;
else
glyph_info.geometry.x_offset = - value->draw_x * 1024;
glyph_info.geometry.y_offset = - value->draw_y * 1024;
cairo_glyph.x = 0.25 * key->xshift - value->draw_x;
cairo_glyph.y = 0.25 * key->yshift - value->draw_y;
glyph_string.num_glyphs = 1;
glyph_string.glyphs = &glyph_info;
pango_cairo_show_glyph_string (cr, key->font, &glyph_string);
cairo_show_glyphs (cr, &cairo_glyph, 1);
cairo_destroy (cr);
cairo_surface_flush (surface);
@@ -206,85 +208,69 @@ upload_glyph (GlyphCacheKey *key,
static void
add_to_cache (GskGLGlyphCache *self,
GlyphCacheKey *key,
GskGLDriver *driver,
GskGLCachedGlyph *value)
{
const int width = value->draw_width * key->scale / 1024;
const int height = value->draw_height * key->scale / 1024;
GskGLTextureAtlas *atlas = NULL;
int packed_x = 0;
int packed_y = 0;
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
if (width < MAX_GLYPH_SIZE && height < MAX_GLYPH_SIZE)
{
GskGLTextureAtlas *atlas = NULL;
int packed_x = 0;
int packed_y = 0;
value->tx = (float)(packed_x + 1) / atlas->width;
value->ty = (float)(packed_y + 1) / atlas->height;
value->tw = (float)width / atlas->width;
value->th = (float)height / atlas->height;
value->used = TRUE;
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
value->tx = (float)(packed_x + 1) / atlas->width;
value->ty = (float)(packed_y + 1) / atlas->height;
value->tw = (float)width / atlas->width;
value->th = (float)height / atlas->height;
value->used = TRUE;
value->atlas = atlas;
value->texture_id = atlas->texture_id;
}
else
{
value->atlas = NULL;
value->texture_id = gsk_gl_driver_create_texture (driver, width, height);
gsk_gl_driver_bind_source_texture (driver, value->texture_id);
gsk_gl_driver_init_texture_empty (driver, value->texture_id, GL_NEAREST, GL_NEAREST);
value->tx = 0.0f;
value->ty = 0.0f;
value->tw = 1.0f;
value->th = 1.0f;
}
value->atlas = atlas;
value->texture_id = atlas->texture_id;
upload_glyph (key, value);
}
void
gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
PangoFont *font,
PangoGlyph glyph,
float scale,
GskGLCachedGlyph *value)
{
PangoRectangle ink_rect;
GlyphCacheKey key;
int width, height;
guint texture_id;
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
key.font = font;
key.glyph = glyph;
key.scale = (guint)(scale * 1024);
value->atlas = NULL;
value->timestamp = 0;
value->draw_x = ink_rect.x;
value->draw_y = ink_rect.y;
value->draw_width = ink_rect.width;
value->draw_height = ink_rect.height;
value->tx = 0.0f;
value->ty = 0.0f;
value->tw = 1.0f;
value->th = 1.0f;
width = value->draw_width * key.scale / 1024;
height = value->draw_height * key.scale / 1024;
texture_id = gsk_gl_driver_create_texture (driver, width, height);
gsk_gl_driver_bind_source_texture (driver, texture_id);
gsk_gl_driver_init_texture_empty (driver, texture_id, GL_NEAREST, GL_NEAREST);
value->texture_id = texture_id;
upload_glyph (&key, value);
}
#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
gboolean
gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale,
GskGLDriver *driver,
GskGLCachedGlyph *cached_glyph_out)
{
GskGLCachedGlyph *value;
guint xshift = PHASE (x);
guint yshift = PHASE (y);
value = g_hash_table_lookup (cache->hash_table,
&(GlyphCacheKey) {
.font = font,
.glyph = glyph,
.xshift = xshift,
.yshift = yshift,
.scale = (guint)(scale * 1024)
});
@@ -310,10 +296,16 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
if (value == NULL)
{
GlyphCacheKey *key;
PangoRectangle ink_rect;
const guint key_scale = (guint)(scale * 1024);
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
if (xshift != 0)
ink_rect.width += 1;
if (yshift != 0)
ink_rect.height += 1;
value = g_new0 (GskGLCachedGlyph, 1);
@@ -324,27 +316,21 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
value->timestamp = cache->timestamp;
value->atlas = NULL; /* For now */
if (ink_rect.width < 128 && ink_rect.height < 128)
{
GlyphCacheKey *key;
key = g_new0 (GlyphCacheKey, 1);
key = g_new0 (GlyphCacheKey, 1);
key->font = g_object_ref (font);
key->glyph = glyph;
key->xshift = xshift;
key->yshift = yshift;
key->scale = key_scale;
key->font = g_object_ref (font);
key->glyph = glyph;
key->scale = (guint)(scale * 1024);
if (key->scale > 0 &&
ink_rect.width * key->scale > 0 &&
ink_rect.height * key->scale > 0)
add_to_cache (cache, key, driver, value);
if (ink_rect.width > 0 && ink_rect.height > 0 && key->scale > 0)
add_to_cache (cache, key, value);
*cached_glyph_out = *value;
g_hash_table_insert (cache->hash_table, key, value);
}
else
{
*cached_glyph_out = *value;
glyph_cache_value_free (value);
}
*cached_glyph_out = *value;
g_hash_table_insert (cache->hash_table, key, value);
}
else
{
+6 -6
View File
@@ -22,6 +22,8 @@ typedef struct
{
PangoFont *font;
PangoGlyph glyph;
guint xshift;
guint yshift;
guint scale; /* times 1024 */
} GlyphCacheKey;
@@ -55,12 +57,10 @@ void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale,
GskGLCachedGlyph *cached_glyph_out);
void gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
PangoFont *font,
PangoGlyph glyph,
float scale,
GskGLCachedGlyph *glyph_out);
GskGLDriver *driver,
GskGLCachedGlyph *cached_glyph_out);
#endif
+19 -25
View File
@@ -595,26 +595,21 @@ render_text_node (GskGLRenderer *self,
gsk_gl_glyph_cache_lookup (self->glyph_cache,
(PangoFont *)font,
gi->glyph,
x * PANGO_SCALE + x_position + gi->geometry.x_offset,
+ y * PANGO_SCALE + gi->geometry.y_offset,
text_scale,
self->gl_driver,
&glyph);
/* e.g. whitespace */
if (glyph.draw_width <= 0 || glyph.draw_height <= 0)
goto next;
/* big glyphs are not cached */
if (!glyph.texture_id)
{
gsk_gl_glyph_cache_get_texture (self->gl_driver,
(PangoFont *)font,
gi->glyph,
text_scale,
&glyph);
g_assert (glyph.texture_id != 0);
}
if (glyph.texture_id == 0)
goto next;
cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
cy = gi->geometry.y_offset / PANGO_SCALE;
ops_set_texture (builder, glyph.texture_id);
@@ -1428,7 +1423,7 @@ render_blur_node (GskGLRenderer *self,
ops_set_program (builder, &self->blur_program);
op.op = OP_CHANGE_BLUR;
graphene_size_init_from_size (&op.blur.size, &node->bounds.size);
op.blur.radius = gsk_blur_node_get_radius (node);
op.blur.radius = blur_radius;
ops_add (builder, &op);
ops_set_texture (builder, region.texture_id);
@@ -1439,7 +1434,7 @@ render_blur_node (GskGLRenderer *self,
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
{ { max_x, max_y }, { 1, 0 }, },
{ { min_x, max_y }, { 0, 0 }, },
{ { max_x, min_y }, { 1, 1 }, },
@@ -1890,10 +1885,10 @@ render_shadow_node (GskGLRenderer *self,
RenderOpBuilder *builder,
const GskQuadVertex *vertex_data)
{
float min_x = node->bounds.origin.x;
float min_y = node->bounds.origin.y;
float max_x = min_x + node->bounds.size.width;
float max_y = min_y + node->bounds.size.height;
float min_x;
float min_y;
float max_x;
float max_y;
GskRenderNode *original_child = gsk_shadow_node_get_child (node);
GskRenderNode *shadow_child = original_child;
gsize n_shadows = gsk_shadow_node_get_n_shadows (node);
@@ -1919,6 +1914,11 @@ render_shadow_node (GskGLRenderer *self,
shadow_child = gsk_color_matrix_node_get_child (shadow_child);
}
min_x = builder->dx + shadow_child->bounds.origin.x;
min_y = builder->dy + shadow_child->bounds.origin.y;
max_x = min_x + shadow_child->bounds.size.width;
max_y = min_y + shadow_child->bounds.size.height;
for (i = 0; i < n_shadows; i ++)
{
const GskShadow *shadow = gsk_shadow_node_peek_shadow (node, i);
@@ -1940,11 +1940,6 @@ render_shadow_node (GskGLRenderer *self,
if (gdk_rgba_is_clear (&shadow->color))
continue;
min_x = builder->dx + shadow_child->bounds.origin.x;
min_y = builder->dy + shadow_child->bounds.origin.y;
max_x = min_x + shadow_child->bounds.size.width;
max_y = min_y + shadow_child->bounds.size.height;
/* Draw the child offscreen, without the offset. */
add_offscreen_ops (self, builder,
&shadow_child->bounds,
@@ -3196,7 +3191,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
int scale_factor)
{
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
graphene_matrix_t modelview, projection;
graphene_matrix_t projection;
gsize buffer_size;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
@@ -3216,7 +3211,6 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
g_assert (gsk_gl_driver_in_frame (self->gl_driver));
/* Set up the modelview and projection matrices to fit our viewport */
graphene_matrix_init_scale (&modelview, scale_factor, scale_factor, 1.0);
graphene_matrix_init_ortho (&projection,
viewport->origin.x,
viewport->origin.x + viewport->size.width,
+53 -32
View File
@@ -8,6 +8,15 @@ rect_equal (const graphene_rect_t *a,
return memcmp (a, b, sizeof (graphene_rect_t)) == 0;
}
static inline ProgramState *
get_current_program_state (RenderOpBuilder *builder)
{
if (!builder->current_program)
return NULL;
return &builder->program_state[builder->current_program->index];
}
void
ops_finish (RenderOpBuilder *builder)
{
@@ -27,7 +36,6 @@ ops_finish (RenderOpBuilder *builder)
builder->current_render_target = 0;
builder->current_texture = 0;
builder->current_program = NULL;
builder->current_program_state = NULL;
graphene_matrix_init_identity (&builder->current_projection);
builder->current_viewport = GRAPHENE_RECT_INIT (0, 0, 0, 0);
}
@@ -265,8 +273,6 @@ ops_set_program (RenderOpBuilder *builder,
g_array_append_val (builder->render_ops, op);
program_state->opacity = builder->current_opacity;
}
builder->current_program_state = &builder->program_state[program->index];
}
static void
@@ -274,9 +280,10 @@ ops_set_clip (RenderOpBuilder *builder,
const GskRoundedRect *clip)
{
RenderOp *last_op;
ProgramState *current_program_state = get_current_program_state (builder);
if (builder->current_program_state &&
memcmp (&builder->current_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
if (current_program_state &&
memcmp (&current_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
return;
if (builder->render_ops->len > 0)
@@ -298,7 +305,7 @@ ops_set_clip (RenderOpBuilder *builder,
}
if (builder->current_program != NULL)
builder->current_program_state->clip = *clip;
current_program_state->clip = *clip;
}
void
@@ -348,6 +355,7 @@ static void
ops_set_modelview_internal (RenderOpBuilder *builder,
GskTransform *transform)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
graphene_matrix_t matrix;
@@ -382,10 +390,18 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
}
if (builder->current_program != NULL)
builder->current_program_state->modelview = transform;
{
gsk_transform_unref (current_program_state->modelview);
current_program_state->modelview = gsk_transform_ref (transform);
}
}
/* This sets the modelview to the given one without looking at the
/**
* ops_set_modelview:
* @builder
* @transform: (transfer full): The new modelview transform
*
* This sets the modelview to the given one without looking at the
* one that's currently set */
void
ops_set_modelview (RenderOpBuilder *builder,
@@ -401,11 +417,11 @@ ops_set_modelview (RenderOpBuilder *builder,
g_array_set_size (builder->mv_stack, builder->mv_stack->len + 1);
entry = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
entry->transform = gsk_transform_ref (transform);
entry->transform = transform;
entry->metadata.dx_before = builder->dx;
entry->metadata.dy_before = builder->dy;
extract_matrix_metadata (transform, &entry->metadata);
extract_matrix_metadata (entry->transform, &entry->metadata);
builder->dx = 0;
builder->dy = 0;
@@ -419,7 +435,6 @@ void
ops_push_modelview (RenderOpBuilder *builder,
GskTransform *transform)
{
float scale = ops_get_scale (builder);
MatrixStackEntry *entry;
if (G_UNLIKELY (builder->mv_stack == NULL))
@@ -439,10 +454,9 @@ ops_push_modelview (RenderOpBuilder *builder,
/* Multiply given matrix with current modelview */
t = gsk_transform_translate (gsk_transform_ref (cur->transform),
&(graphene_point_t) { builder->dx * scale, builder->dy * scale});
&(graphene_point_t) { builder->dx, builder->dy});
t = gsk_transform_transform (t, transform);
entry->transform = t;
}
else
{
@@ -451,7 +465,6 @@ ops_push_modelview (RenderOpBuilder *builder,
entry->metadata.dx_before = builder->dx;
entry->metadata.dy_before = builder->dy;
extract_matrix_metadata (entry->transform, &entry->metadata);
builder->dx = 0;
@@ -491,6 +504,7 @@ graphene_matrix_t
ops_set_projection (RenderOpBuilder *builder,
const graphene_matrix_t *projection)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
graphene_matrix_t prev_mv;
@@ -516,7 +530,7 @@ ops_set_projection (RenderOpBuilder *builder,
}
if (builder->current_program != NULL)
builder->current_program_state->projection = *projection;
current_program_state->projection = *projection;
prev_mv = builder->current_projection;
builder->current_projection = *projection;
@@ -528,19 +542,20 @@ graphene_rect_t
ops_set_viewport (RenderOpBuilder *builder,
const graphene_rect_t *viewport)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
graphene_rect_t prev_viewport;
if (builder->current_program_state != NULL &&
rect_equal (&builder->current_program_state->viewport, viewport))
return builder->current_program_state->viewport;
if (current_program_state != NULL &&
rect_equal (&current_program_state->viewport, viewport))
return current_program_state->viewport;
op.op = OP_CHANGE_VIEWPORT;
op.viewport = *viewport;
g_array_append_val (builder->render_ops, op);
if (builder->current_program != NULL)
builder->current_program_state->viewport = *viewport;
current_program_state->viewport = *viewport;
prev_viewport = builder->current_viewport;
builder->current_viewport = *viewport;
@@ -605,6 +620,7 @@ float
ops_set_opacity (RenderOpBuilder *builder,
float opacity)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
float prev_opacity;
RenderOp *last_op;
@@ -638,7 +654,7 @@ ops_set_opacity (RenderOpBuilder *builder,
builder->current_opacity = opacity;
if (builder->current_program != NULL)
builder->current_program_state->opacity = opacity;
current_program_state->opacity = opacity;
return prev_opacity;
}
@@ -647,12 +663,13 @@ void
ops_set_color (RenderOpBuilder *builder,
const GdkRGBA *color)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
if (gdk_rgba_equal (color, &builder->current_program_state->color))
if (gdk_rgba_equal (color, &current_program_state->color))
return;
builder->current_program_state->color = *color;
current_program_state->color = *color;
op.op = OP_CHANGE_COLOR;
op.color = *color;
@@ -664,18 +681,19 @@ ops_set_color_matrix (RenderOpBuilder *builder,
const graphene_matrix_t *matrix,
const graphene_vec4_t *offset)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
if (memcmp (matrix,
&builder->current_program_state->color_matrix.matrix,
&current_program_state->color_matrix.matrix,
sizeof (graphene_matrix_t)) == 0 &&
memcmp (offset,
&builder->current_program_state->color_matrix.offset,
&current_program_state->color_matrix.offset,
sizeof (graphene_vec4_t)) == 0)
return;
builder->current_program_state->color_matrix.matrix = *matrix;
builder->current_program_state->color_matrix.offset = *offset;
current_program_state->color_matrix.matrix = *matrix;
current_program_state->color_matrix.offset = *offset;
op.op = OP_CHANGE_COLOR_MATRIX;
op.color_matrix.matrix = *matrix;
@@ -687,13 +705,14 @@ void
ops_set_border (RenderOpBuilder *builder,
const GskRoundedRect *outline)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
if (memcmp (&builder->current_program_state->border.outline,
if (memcmp (&current_program_state->border.outline,
outline, sizeof (GskRoundedRect)) == 0)
return;
builder->current_program_state->border.outline = *outline;
current_program_state->border.outline = *outline;
op.op = OP_CHANGE_BORDER;
op.border.outline = *outline;
@@ -704,13 +723,14 @@ void
ops_set_border_width (RenderOpBuilder *builder,
const float *widths)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
if (memcmp (builder->current_program_state->border.widths,
if (memcmp (current_program_state->border.widths,
widths, sizeof (float) * 4) == 0)
return;
memcpy (&builder->current_program_state->border.widths,
memcpy (&current_program_state->border.widths,
widths, sizeof (float) * 4);
op.op = OP_CHANGE_BORDER_WIDTH;
@@ -726,15 +746,16 @@ void
ops_set_border_color (RenderOpBuilder *builder,
const GdkRGBA *color)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
op.op = OP_CHANGE_BORDER_COLOR;
rgba_to_float (color, op.border.color);
if (memcmp (&op.border.color, &builder->current_program_state->border.color,
if (memcmp (&op.border.color, &current_program_state->border.color,
sizeof (float) * 4) == 0)
return;
rgba_to_float (color, builder->current_program_state->border.color);
rgba_to_float (color, current_program_state->border.color);
g_array_append_val (builder->render_ops, op);
}
-2
View File
@@ -258,8 +258,6 @@ typedef struct
typedef struct
{
ProgramState program_state[GL_N_PROGRAMS];
/* Current global state */
ProgramState *current_program_state;
const Program *current_program;
int current_render_target;
int current_texture;
+2 -2
View File
@@ -1966,14 +1966,14 @@ gsk_transform_node_diff (GskRenderNode *node1,
cairo_region_t *tmp = cairo_region_copy (sub);
cairo_region_translate (tmp, 1, 0);
cairo_region_union (sub, tmp);
cairo_region_destroy (sub);
cairo_region_destroy (tmp);
}
if (floor (dy) != dy)
{
cairo_region_t *tmp = cairo_region_copy (sub);
cairo_region_translate (tmp, 0, 1);
cairo_region_union (sub, tmp);
cairo_region_destroy (sub);
cairo_region_destroy (tmp);
}
cairo_region_union (region, sub);
cairo_region_destroy (sub);
+3
View File
@@ -94,6 +94,7 @@ parse_texture (GtkCssParser *parser,
if (bytes)
{
stream = g_memory_input_stream_new_from_bytes (bytes);
g_bytes_unref (bytes);
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
g_object_unref (stream);
if (pixbuf != NULL)
@@ -748,6 +749,8 @@ parse_glyphs (GtkCssParser *parser,
pango_glyph_string_set_size (glyph_string, glyph_string->num_glyphs + 1);
glyph_string->glyphs[glyph_string->num_glyphs - 1] = gi;
}
g_free (s);
}
else
{
+8 -3
View File
@@ -119,12 +119,17 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
if (gi->glyph != PANGO_GLYPH_EMPTY)
{
double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
GskVulkanColorTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
font,
gi->glyph,
x_position + gi->geometry.x_offset,
gi->geometry.y_offset,
scale);
instance->tex_rect[0] = glyph->tx;
instance->tex_rect[1] = glyph->ty;
+21 -4
View File
@@ -115,6 +115,8 @@ gsk_vulkan_glyph_cache_class_init (GskVulkanGlyphCacheClass *klass)
typedef struct {
PangoFont *font;
PangoGlyph glyph;
guint xshift;
guint yshift;
guint scale; /* times 1024 */
} GlyphCacheKey;
@@ -126,6 +128,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
return key1->font == key2->font &&
key1->glyph == key2->glyph &&
key1->xshift == key2->xshift &&
key1->yshift == key2->yshift &&
key1->scale == key2->scale;
}
@@ -134,7 +138,7 @@ glyph_cache_hash (gconstpointer v)
{
const GlyphCacheKey *key = v;
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ (key->xshift << 24) ^ (key->yshift << 26) ^ key->scale;
}
static void
@@ -267,10 +271,10 @@ render_glyph (Atlas *atlas,
gi.glyph = key->glyph;
gi.geometry.width = value->draw_width * 1024;
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
gi.geometry.x_offset = 0;
gi.geometry.x_offset = key->xshift * 256;
else
gi.geometry.x_offset = - value->draw_x * 1024;
gi.geometry.y_offset = - value->draw_y * 1024;
gi.geometry.x_offset = key->xshift * 256 - value->draw_x * 1024;
gi.geometry.y_offset = key->yshift * 256 - value->draw_y * 1024;
glyphs.num_glyphs = 1;
glyphs.glyphs = &gi;
@@ -328,18 +332,29 @@ gsk_vulkan_glyph_cache_new (GskRenderer *renderer,
return cache;
}
#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
GskVulkanCachedGlyph *
gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
gboolean create,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale)
{
GlyphCacheKey lookup_key;
GskVulkanCachedGlyph *value;
guint xshift;
guint yshift;
xshift = PHASE (x);
yshift = PHASE (y);
lookup_key.font = font;
lookup_key.glyph = glyph;
lookup_key.xshift = xshift;
lookup_key.yshift = yshift;
lookup_key.scale = (guint)(scale * 1024);
value = g_hash_table_lookup (cache->hash_table, &lookup_key);
@@ -374,6 +389,8 @@ gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
key->font = g_object_ref (font);
key->glyph = glyph;
key->xshift = xshift;
key->yshift = yshift;
key->scale = (guint)(scale * 1024);
if (ink_rect.width > 0 && ink_rect.height > 0)
+3
View File
@@ -22,6 +22,9 @@ GskVulkanCachedGlyph *gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache
gboolean create,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale);
void gsk_vulkan_glyph_cache_begin_frame (GskVulkanGlyphCache *cache);
+14 -10
View File
@@ -362,15 +362,6 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
return image;
}
guint
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
float scale)
{
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, scale)->texture_index;
}
GskVulkanImage *
gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
GskVulkanUploader *uploader,
@@ -379,13 +370,26 @@ gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
return g_object_ref (gsk_vulkan_glyph_cache_get_glyph_image (self->glyph_cache, uploader, index));
}
guint
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale)
{
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, x, y, scale)->texture_index;
}
GskVulkanCachedGlyph *
gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale)
{
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, scale);
return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, x, y, scale);
}
/**
+4
View File
@@ -30,6 +30,8 @@ typedef struct
guint gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *renderer,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale);
GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
@@ -39,6 +41,8 @@ GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *
GskVulkanCachedGlyph * gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
int x,
int y,
float scale);
+10 -1
View File
@@ -370,6 +370,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
int i;
guint count;
guint texture_index;
gint x_position;
GskVulkanRenderer *renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
if (font_has_color_glyphs (font))
@@ -402,11 +403,17 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
op.text.texture_index = G_MAXUINT;
op.text.scale = self->scale_factor;
x_position = 0;
for (i = 0, count = 0; i < num_glyphs; i++)
{
const PangoGlyphInfo *gi = &glyphs[i];
texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph, op.text.scale);
texture_index = gsk_vulkan_renderer_cache_glyph (renderer,
(PangoFont *)font,
gi->glyph,
x_position + gi->geometry.x_offset,
gi->geometry.y_offset,
op.text.scale);
if (op.text.texture_index == G_MAXUINT)
op.text.texture_index = texture_index;
if (texture_index != op.text.texture_index)
@@ -421,6 +428,8 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
}
else
count++;
x_position += gi->geometry.width;
}
if (op.text.texture_index != G_MAXUINT && count != 0)
+8 -3
View File
@@ -127,12 +127,17 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
if (gi->glyph != PANGO_GLYPH_EMPTY)
{
double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
GskVulkanTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
font,
gi->glyph,
x_position + gi->geometry.x_offset,
gi->geometry.y_offset,
scale);
instance->tex_rect[0] = glyph->tx;
instance->tex_rect[1] = glyph->ty;
+50
View File
@@ -128,6 +128,37 @@
fun:epoxy_glReadPixels_global_rewrite_ptr
}
{
epoxy glxQueryServerString 1
Memcheck:Leak
fun:malloc
fun:XextAddDisplay
obj:*
obj:*
obj:*
obj:*
obj:*
fun:epoxy_glXQueryServerString_global_rewrite_ptr
}
{
epoxy glxQueryServerString 2
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:realpath*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
fun:epoxy_glXQueryServerString_global_rewrite_ptr
}
# Fontconfig
{
FcFontSetList
@@ -149,6 +180,25 @@
fun:FcFontRenderPrepare
}
{
FcDefaultSubstitute
Memcheck:Leak
match-leak-kinds: definite
fun:realloc
obj:/usr/lib/libfontconfig.so*
obj:/usr/lib/libfontconfig.so*
fun:FcDefaultSubstitute
}
# Pixman
{
pixman_image_composite32
Memcheck:Cond
obj:/usr/lib/libpixman-1.so*
obj:/usr/lib/libpixman-1.so*
fun:pixman_image_composite32
}
# Pango
{
pango 1
+206 -157
View File
@@ -23,41 +23,26 @@
#include "gsk/gskrendernodeprivate.h"
#include "gskpango.h"
#include "gtksnapshotprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtktextlayoutprivate.h"
#include "gtktextviewprivate.h"
#include <math.h>
#include <pango/pango.h>
#include <cairo.h>
#define GSK_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_PANGO_RENDERER, GskPangoRendererClass))
#define GSK_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_PANGO_RENDERER))
#define GSK_PANGO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_PANGO_RENDERER, GskPangoRendererClass))
/*
* This is a PangoRenderer implementation that translates all the draw calls to
* gsk render nodes, using the GtkSnapshot helper class. Glyphs are translated
* to text nodes, all other draw calls fall back to cairo nodes.
*/
struct _GskPangoRenderer
{
PangoRenderer parent_instance;
GtkSnapshot *snapshot;
GdkRGBA fg_color;
graphene_rect_t bounds;
/* house-keeping options */
gboolean is_cached_renderer;
};
struct _GskPangoRendererClass
{
PangoRendererClass parent_class;
};
G_DEFINE_TYPE (GskPangoRenderer, gsk_pango_renderer, PANGO_TYPE_RENDERER)
void
gsk_pango_renderer_set_state (GskPangoRenderer *crenderer,
GskPangoRendererState state)
{
g_return_if_fail (GSK_IS_PANGO_RENDERER (crenderer));
crenderer->state = state;
}
static void
get_color (GskPangoRenderer *crenderer,
PangoRenderPart part,
@@ -101,16 +86,11 @@ set_color (GskPangoRenderer *crenderer,
}
static void
gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
const char *text,
int text_len,
PangoGlyphString *glyphs,
cairo_text_cluster_t *clusters,
int num_clusters,
gboolean backward,
PangoFont *font,
int x,
int y)
gsk_pango_renderer_draw_glyph_item (PangoRenderer *renderer,
const char *text,
PangoGlyphItem *glyph_item,
int x,
int y)
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
GdkRGBA color;
@@ -118,36 +98,13 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
get_color (crenderer, PANGO_RENDER_PART_FOREGROUND, &color);
gtk_snapshot_append_text (crenderer->snapshot,
font,
glyphs,
glyph_item->item->analysis.font,
glyph_item->glyphs,
&color,
(float) x / PANGO_SCALE,
(float) y / PANGO_SCALE);
}
static void
gsk_pango_renderer_draw_glyphs (PangoRenderer *renderer,
PangoFont *font,
PangoGlyphString *glyphs,
int x,
int y)
{
gsk_pango_renderer_show_text_glyphs (renderer, NULL, 0, glyphs, NULL, 0, FALSE, font, x, y);
}
static void
gsk_pango_renderer_draw_glyph_item (PangoRenderer *renderer,
const char *text,
PangoGlyphItem *glyph_item,
int x,
int y)
{
PangoFont *font = glyph_item->item->analysis.font;
PangoGlyphString *glyphs = glyph_item->glyphs;
gsk_pango_renderer_show_text_glyphs (renderer, NULL, 0, glyphs, NULL, 0, FALSE, font, x, y);
}
static void
gsk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
PangoRenderPart part,
@@ -158,15 +115,14 @@ gsk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
GdkRGBA rgba;
graphene_rect_t bounds;
get_color (crenderer, part, &rgba);
graphene_rect_init (&bounds,
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
gtk_snapshot_append_color (crenderer->snapshot, &rgba, &bounds);
gtk_snapshot_append_color (crenderer->snapshot,
&rgba,
&GRAPHENE_RECT_INIT ((double)x / PANGO_SCALE,
(double)y / PANGO_SCALE,
(double)width / PANGO_SCALE,
(double)height / PANGO_SCALE));
}
static void
@@ -203,78 +159,7 @@ gsk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
cairo_destroy (cr);
}
/* Draws an error underline that looks like one of:
* H E H
* /\ /\ /\ /\ /\ -
* A/ \ / \ / \ A/ \ / \ |
* \ \ / \ / /D \ \ / \ |
* \ \/ C \/ / \ \/ C \ | height = HEIGHT_SQUARES * square
* \ /\ F / \ F /\ \ |
* \ / \ / \ / \ \G |
* \ / \ / \ / \ / |
* \/ \/ \/ \/ -
* B B
* |---|
* unit_width = (HEIGHT_SQUARES - 1) * square
*
* The x, y, width, height passed in give the desired bounding box;
* x/width are adjusted to make the underline a integer number of units
* wide.
*/
#define HEIGHT_SQUARES 2.5
static void
draw_error_underline (cairo_t *cr,
double x,
double y,
double width,
double height)
{
double square = height / HEIGHT_SQUARES;
double unit_width = (HEIGHT_SQUARES - 1) * square;
double double_width = 2 * unit_width;
int width_units = (width + unit_width / 2) / unit_width;
double y_top, y_bottom;
double x_left, x_middle, x_right;
int i;
x += (width - width_units * unit_width) / 2;
y_top = y;
y_bottom = y + height;
/* Bottom of squiggle */
x_middle = x + unit_width;
x_right = x + double_width;
cairo_move_to (cr, x - square / 2, y_top + square / 2); /* A */
for (i = 0; i < width_units-2; i += 2)
{
cairo_line_to (cr, x_middle, y_bottom); /* B */
cairo_line_to (cr, x_right, y_top + square); /* C */
x_middle += double_width;
x_right += double_width;
}
cairo_line_to (cr, x_middle, y_bottom); /* B */
if (i + 1 == width_units)
cairo_line_to (cr, x_middle + square / 2, y_bottom - square / 2); /* G */
else if (i + 2 == width_units) {
cairo_line_to (cr, x_right + square / 2, y_top + square / 2); /* D */
cairo_line_to (cr, x_right, y_top); /* E */
}
/* Top of squiggle */
x_left = x_middle - unit_width;
for (; i >= 0; i -= 2)
{
cairo_line_to (cr, x_middle, y_bottom - square); /* F */
cairo_line_to (cr, x_left, y_top); /* H */
x_left -= double_width;
x_middle -= double_width;
}
}
#define HEIGHT_RATIO (M_SQRT2/5.0)
static void
gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
@@ -283,22 +168,61 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
int width,
int height)
{
GdkRGBA rgba;
double xx, yy, ww, hh;
double hs;
double e, o;
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
cairo_t *cr;
cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds);
xx = (double)x / PANGO_SCALE;
yy = (double)y / PANGO_SCALE;
ww = (double)width / PANGO_SCALE;
hh = (double)height / PANGO_SCALE;
hs = hh / M_SQRT2;
set_color (crenderer, PANGO_RENDER_PART_UNDERLINE, cr);
e = fmod (ww - 2 * hs * HEIGHT_RATIO, hs * (1 - HEIGHT_RATIO));
cairo_new_path (cr);
#if 0
gdk_rgba_parse (&rgba, "yellow");
gtk_snapshot_append_color (crenderer->snapshot, &rgba,
&GRAPHENE_RECT_INIT (xx, yy, ww, hh));
#endif
draw_error_underline (cr,
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
cairo_fill (cr);
get_color (crenderer, PANGO_RENDER_PART_UNDERLINE, &rgba);
gtk_snapshot_save (crenderer->snapshot);
gtk_snapshot_translate (crenderer->snapshot,
&GRAPHENE_POINT_INIT (xx, yy));
cairo_destroy (cr);
gtk_snapshot_rotate (crenderer->snapshot, 45);
gtk_snapshot_translate (crenderer->snapshot,
&GRAPHENE_POINT_INIT (e / 2 + hs * HEIGHT_RATIO,
- hs * HEIGHT_RATIO));
xx = yy = o = 0;
while (1)
{
if (o + hs * (1 + HEIGHT_RATIO) >= ww)
break;
gtk_snapshot_append_color (crenderer->snapshot, &rgba,
&GRAPHENE_RECT_INIT (xx, yy, hh, hh * HEIGHT_RATIO));
xx += hh * (1 - HEIGHT_RATIO);
yy -= hh * (1 - HEIGHT_RATIO);
o += hs * (1 - HEIGHT_RATIO);
if (o + hs * (1 + HEIGHT_RATIO) >= ww)
break;
gtk_snapshot_append_color (crenderer->snapshot, &rgba,
&GRAPHENE_RECT_INIT (xx, yy, hh * HEIGHT_RATIO, hh));
o += hs * (1 - HEIGHT_RATIO);
}
gtk_snapshot_restore (crenderer->snapshot);
}
static void
@@ -336,6 +260,124 @@ gsk_pango_renderer_draw_shape (PangoRenderer *renderer,
cairo_destroy (cr);
}
static void
text_renderer_set_rgba (GskPangoRenderer *crenderer,
PangoRenderPart part,
const GdkRGBA *rgba)
{
PangoRenderer *renderer = PANGO_RENDERER (crenderer);
PangoColor color = { 0, };
guint16 alpha;
if (rgba)
{
color.red = (guint16)(rgba->red * 65535);
color.green = (guint16)(rgba->green * 65535);
color.blue = (guint16)(rgba->blue * 65535);
alpha = (guint16)(rgba->alpha * 65535);
pango_renderer_set_color (renderer, part, &color);
pango_renderer_set_alpha (renderer, part, alpha);
}
else
{
pango_renderer_set_color (renderer, part, NULL);
pango_renderer_set_alpha (renderer, part, 0);
}
}
static GtkTextAppearance *
get_item_appearance (PangoItem *item)
{
GSList *tmp_list = item->analysis.extra_attrs;
while (tmp_list)
{
PangoAttribute *attr = tmp_list->data;
if (attr->klass->type == gtk_text_attr_appearance_type)
return &((GtkTextAttrAppearance *)attr)->appearance;
tmp_list = tmp_list->next;
}
return NULL;
}
static void
gsk_pango_renderer_prepare_run (PangoRenderer *renderer,
PangoLayoutRun *run)
{
GtkStyleContext *context;
GskPangoRenderer *crenderer = GSK_PANGO_RENDERER (renderer);
GdkRGBA *bg_rgba = NULL;
GdkRGBA *fg_rgba = NULL;
GtkTextAppearance *appearance;
PANGO_RENDERER_CLASS (gsk_pango_renderer_parent_class)->prepare_run (renderer, run);
appearance = get_item_appearance (run->item);
if (appearance == NULL)
return;
context = gtk_widget_get_style_context (crenderer->widget);
if (appearance->draw_bg && crenderer->state == GSK_PANGO_RENDERER_NORMAL)
bg_rgba = appearance->bg_rgba;
else
bg_rgba = NULL;
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_BACKGROUND, bg_rgba);
if (crenderer->state == GSK_PANGO_RENDERER_SELECTED &&
GTK_IS_TEXT_VIEW (crenderer->widget))
{
GtkCssNode *selection_node;
selection_node = gtk_text_view_get_selection_node ((GtkTextView *)crenderer->widget);
gtk_style_context_save_to_node (context, selection_node);
gtk_style_context_get (context,
"color", &fg_rgba,
NULL);
gtk_style_context_restore (context);
}
else if (crenderer->state == GSK_PANGO_RENDERER_CURSOR && gtk_widget_has_focus (crenderer->widget))
{
gtk_style_context_get (context,
"background-color", &fg_rgba,
NULL);
}
else
fg_rgba = appearance->fg_rgba;
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_FOREGROUND, fg_rgba);
if (appearance->strikethrough_rgba)
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_STRIKETHROUGH, appearance->strikethrough_rgba);
else
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_STRIKETHROUGH, fg_rgba);
if (appearance->underline_rgba)
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_UNDERLINE, appearance->underline_rgba);
else if (appearance->underline == PANGO_UNDERLINE_ERROR)
{
if (!crenderer->error_color)
{
static const GdkRGBA red = { 1, 0, 0, 1 };
crenderer->error_color = gdk_rgba_copy (&red);
}
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_UNDERLINE, crenderer->error_color);
}
else
text_renderer_set_rgba (crenderer, PANGO_RENDER_PART_UNDERLINE, fg_rgba);
if (fg_rgba != appearance->fg_rgba)
gdk_rgba_free (fg_rgba);
}
static void
gsk_pango_renderer_init (GskPangoRenderer *renderer G_GNUC_UNUSED)
{
@@ -346,19 +388,19 @@ gsk_pango_renderer_class_init (GskPangoRendererClass *klass)
{
PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
renderer_class->draw_glyphs = gsk_pango_renderer_draw_glyphs;
renderer_class->draw_glyph_item = gsk_pango_renderer_draw_glyph_item;
renderer_class->draw_rectangle = gsk_pango_renderer_draw_rectangle;
renderer_class->draw_trapezoid = gsk_pango_renderer_draw_trapezoid;
renderer_class->draw_error_underline = gsk_pango_renderer_draw_error_underline;
renderer_class->draw_shape = gsk_pango_renderer_draw_shape;
renderer_class->prepare_run = gsk_pango_renderer_prepare_run;
}
static GskPangoRenderer *cached_renderer = NULL; /* MT-safe */
G_LOCK_DEFINE_STATIC (cached_renderer);
static GskPangoRenderer *
acquire_renderer (void)
GskPangoRenderer *
gsk_pango_renderer_acquire (void)
{
GskPangoRenderer *renderer;
@@ -380,13 +422,20 @@ acquire_renderer (void)
return renderer;
}
static void
release_renderer (GskPangoRenderer *renderer)
void
gsk_pango_renderer_release (GskPangoRenderer *renderer)
{
if (G_LIKELY (renderer->is_cached_renderer))
{
renderer->widget = NULL;
renderer->snapshot = NULL;
if (renderer->error_color)
{
gdk_rgba_free (renderer->error_color);
renderer->error_color = NULL;
}
G_UNLOCK (cached_renderer);
}
else
@@ -414,7 +463,7 @@ gtk_snapshot_append_layout (GtkSnapshot *snapshot,
g_return_if_fail (snapshot != NULL);
g_return_if_fail (PANGO_IS_LAYOUT (layout));
crenderer = acquire_renderer ();
crenderer = gsk_pango_renderer_acquire ();
crenderer->snapshot = snapshot;
crenderer->fg_color = *color;
@@ -424,5 +473,5 @@ gtk_snapshot_append_layout (GtkSnapshot *snapshot,
pango_renderer_draw_layout (PANGO_RENDERER (crenderer), layout, 0, 0);
release_renderer (crenderer);
gsk_pango_renderer_release (crenderer);
}
+48 -6
View File
@@ -24,15 +24,57 @@
G_BEGIN_DECLS
#define GSK_TYPE_PANGO_RENDERER (gsk_pango_renderer_get_type ())
#define GSK_TYPE_PANGO_RENDERER (gsk_pango_renderer_get_type ())
#define GSK_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_PANGO_RENDERER, GskPangoRenderer))
#define GSK_IS_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_PANGO_RENDERER))
#define GSK_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_PANGO_RENDERER, GskPangoRendererClass))
#define GSK_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_PANGO_RENDERER))
#define GSK_PANGO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_PANGO_RENDERER, GskPangoRendererClass))
#define GSK_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_PANGO_RENDERER, GskPangoRenderer))
#define GSK_IS_PANGO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_PANGO_RENDERER))
typedef struct _GskPangoRenderer GskPangoRenderer;
typedef struct _GskPangoRendererClass GskPangoRendererClass;
typedef struct _GskPangoRenderer GskPangoRenderer;
typedef struct _GskPangoRendererClass GskPangoRendererClass;
typedef enum
{
GSK_PANGO_RENDERER_NORMAL,
GSK_PANGO_RENDERER_SELECTED,
GSK_PANGO_RENDERER_CURSOR
} GskPangoRendererState;
GType gsk_pango_renderer_get_type (void) G_GNUC_CONST;
/*
* This is a PangoRenderer implementation that translates all the draw calls to
* gsk render nodes, using the GtkSnapshot helper class. Glyphs are translated
* to text nodes, all other draw calls fall back to cairo nodes.
*/
struct _GskPangoRenderer
{
PangoRenderer parent_instance;
GtkWidget *widget;
GtkSnapshot *snapshot;
GdkRGBA fg_color;
graphene_rect_t bounds;
/* Error underline color for this widget */
GdkRGBA *error_color;
GskPangoRendererState state;
/* house-keeping options */
guint is_cached_renderer : 1;
};
struct _GskPangoRendererClass
{
PangoRendererClass parent_class;
};
GType gsk_pango_renderer_get_type (void) G_GNUC_CONST;
void gsk_pango_renderer_set_state (GskPangoRenderer *crenderer,
GskPangoRendererState state);
GskPangoRenderer *gsk_pango_renderer_acquire (void);
void gsk_pango_renderer_release (GskPangoRenderer *crenderer);
G_END_DECLS
+1
View File
@@ -232,6 +232,7 @@
#include <gtk/gtktexttag.h>
#include <gtk/gtktexttagtable.h>
#include <gtk/gtktextview.h>
#include <gtk/gtktimingfunction.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtktoggletoolbutton.h>
#include <gtk/gtktoolbar.h>
+279
View File
@@ -0,0 +1,279 @@
/* gtkanimation.c: An animation
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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/>.
*/
/**
* SECTION:gtkanimation
* @Title: GtkAnimation
* @Short_description: The base class for animations
*
* ...
*/
#include "config.h"
#include "gtkanimationprivate.h"
#include "gtkintl.h"
#include "gtktypebuiltins.h"
typedef struct {
double duration;
double delay;
GtkAnimationDirection direction;
int repeat_count;
gboolean auto_reverse;
GtkTimingFunction *timing;
} GtkAnimationPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkAnimation, gtk_animation, G_TYPE_OBJECT)
enum {
PROP_DURATION = 1,
PROP_DELAY,
PROP_DIRECTION,
PROP_REPEAT_COUNT,
PROP_AUTO_REVERSE,
PROP_TIMING_FUNCTION,
N_PROPS
};
static GParamSpec *animation_props[N_PROPS];
static void
gtk_animation_finalize (GObject *gobject)
{
G_OBJECT_CLASS (gtk_animation_parent_class)->finalize (gobject);
}
static void
gtk_animation_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkAnimation *self = GTK_ANIMATION (gobject);
switch (prop_id)
{
case PROP_DURATION:
gtk_animation_set_duration (self, g_value_get_double (value));
break;
case PROP_DELAY:
gtk_animation_set_delay (self, g_value_get_double (value));
break;
case PROP_DIRECTION:
gtk_animation_set_direction (self, g_value_get_enum (value));
break;
case PROP_REPEAT_COUNT:
break;
case PROP_AUTO_REVERSE:
break;
case PROP_TIMING_FUNCTION:
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
gtk_animation_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkAnimation *self = GTK_ANIMATION (gobject);
GtkAnimationPrivate *priv = gtk_animation_get_instance_private (self);
switch (prop_id)
{
case PROP_DURATION:
break;
case PROP_DELAY:
break;
case PROP_DIRECTION:
break;
case PROP_REPEAT_COUNT:
break;
case PROP_AUTO_REVERSE:
break;
case PROP_TIMING_FUNCTION:
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
gtk_animation_class_init (GtkAnimationClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = gtk_animation_set_property:
gobject_class->get_property = gtk_animation_get_property;
gobject_class->finalize = gtk_animation_finalize;
animation_props[PROP_DURATION] =
g_param_spec_uint64 ("duration",
P_("Duration"),
P_("The duration of the animation, in milliseconds"),
0, G_MAXUINT64, 0,
G_PARAM_READ_WRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
animation_props[PROP_DELAY] =
g_param_spec_uint64 ("delay",
P_("Delay"),
P_("The delay before the animation starts, in milliseconds"),
0, G_MAXUINT64, 0,
G_PARAM_READ_WRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
animation_props[PROP_DIRECTION] =
g_param_spec_enum ("direction",
P_("Direction"),
P_("The direction of the animation's progress"),
GTK_TYPE_ANIMATION_DIRECTION,
GTK_ANIMATION_DIRECTION_FORWARD,
G_PARAM_READ_WRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (gobject_class, N_PROPS, animation_props);
}
static void
gtk_animation_init (GtkAnimation *self)
{
}
/*< private >
* gtk_animation_advance:
* @animation: a #GtkAnimation
* @frame_time: the frame time, coming from the frame clock
*
* Advances the given @animation by @frame_time milliseconds.
*/
void
gtk_animation_advance (GtkAnimation *animation,
gint64 frame_time)
{
}
void
gtk_animation_set_duration (GtkAnimation *animation,
guint64 milliseconds)
{
}
guint64
gtk_animation_get_duration (GtkAnimation *animation)
{
}
void
gtk_animation_set_delay (GtkAnimation *animation,
double seconds)
{
}
double
gtk_animation_get_delay (GtkAnimation *animation)
{
}
void
gtk_animation_set_direction (GtkAnimation *animation,
GtkAnimationDirection direction)
{
}
GtkAnimationDirection
gtk_animation_get_direction (GtkAnimation *animation)
{
}
void
gtk_animation_set_repeat_count (GtkAnimation *animation,
int repeats)
{
}
int
gtk_animation_get_repeat_count (GtkAnimation *animation)
{
}
void
gtk_animation_set_auto_reverse (GtkAnimation *animation,
gboolean auto_reverse)
{
}
gboolean
gtk_animation_get_auto_reverse (GtkAnimation *animation)
{
}
void
gtk_animation_set_timing_function (GtkAnimation *animation,
GtkTimingFunction *function)
{
}
GtkTimingFunction *
gtk_animation_get_timing_function (GtkAnimation *animation)
{
}
double
gtk_animation_get_elapsed_time (GtkAnimation *animation)
{
}
double
gtk_animation_get_progress (GtkAnimation *animation)
{
}
double
gtk_animation_get_total_duration (GtkAnimation *animation)
{
}
int
gtk_animation_get_current_repeat (GtkAnimation *animation)
{
}
+87
View File
@@ -0,0 +1,87 @@
/* gtkanimation.h: A class representing an animation
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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/>.
*/
#pragma once
#include <gtk/gtktypes.h>
#include <gtk/gtkenums.h>
#include <gtk/gtktimingfunction.h>
G_BEGIN_DECLS
#define GTK_TYPE_ANIMATION (gtk_animation_get_type())
/**
* GtkAnimation:
*
* A base type for representing an animation.
*/
GDK_AVAILABLE_IN_ALL
G_DECLARE_DERIVABLE_TYPE (GtkAnimation, gtk_animation, GTK, ANIMATION, GObject)
/**
* double:
*
* A type used to represent elapsed time in seconds.
*/
typedef double double;
/* Properties */
GDK_AVAILABLE_IN_ALL
void gtk_animation_set_duration (GtkAnimation *animation,
double duration);
GDK_AVAILABLE_IN_ALL
double gtk_animation_get_duration (GtkAnimation *animation);
GDK_AVAILABLE_IN_ALL
void gtk_animation_set_delay (GtkAnimation *animation,
double delay);
GDK_AVAILABLE_IN_ALL
double gtk_animation_get_delay (GtkAnimation *animation);
GDK_AVAILABLE_IN_ALL
void gtk_animation_set_direction (GtkAnimation *animation,
GtkAnimationDirection direction);
GDK_AVAILABLE_IN_ALL
GtkAnimationDirection gtk_animation_get_direction (GtkAnimation *animation);
GDK_AVAILABLE_IN_ALL
void gtk_animation_set_repeat_count (GtkAnimation *animation,
int repeats);
GDK_AVAILABLE_IN_ALL
int gtk_animation_get_repeat_count (GtkAnimation *animation);
GDK_AVAILABLE_IN_ALL
void gtk_animation_set_auto_reverse (GtkAnimation *animation,
gboolean auto_reverse);
GDK_AVAILABLE_IN_ALL
gboolean gtk_animation_get_auto_reverse (GtkAnimation *animation);
GDK_AVAILABLE_IN_ALL
void gtk_animation_set_timing_function (GtkAnimation *animation,
GtkTimingFunction *function);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_animation_get_timing_function (GtkAnimation *animation);
/* State query */
GDK_AVAILABLE_IN_ALL
double gtk_animation_get_elapsed_time (GtkAnimation *animation);
GDK_AVAILABLE_IN_ALL
double gtk_animation_get_progress (GtkAnimation *animation);
GDK_AVAILABLE_IN_ALL
double gtk_animation_get_total_duration (GtkAnimation *animation);
GDK_AVAILABLE_IN_ALL
int gtk_animation_get_current_repeat (GtkAnimation *animation);
G_END_DECLS
+37
View File
@@ -0,0 +1,37 @@
#include "config.h"
#include "gtkanimationmanagerprivate.h"
struct _GtkAnimationManager
{
GObject parent_instance;
GdkFrameClock *frame_clock;
gint64 last_frame_time;
};
G_DEFINE_TYPE (GtkAnimationManager, gtk_animation_manager, G_TYPE_OBJECT)
static void
gtk_animation_manager_class_init (GtkAnimationManagerClass *klass)
{
}
static void
gtk_animation_manager_init (GtkAnimationManager *self)
{
}
GtkAnimationManager *
gtk_animation_manager_new (void)
{
return g_object_new (GTK_TYPE_ANIMATION_MANAGER, NULL);
}
void
gtk_animation_manager_set_frame_clock (GtkAnimationManager *self,
GdkFrameClock *frame_clock)
{
}
+38
View File
@@ -0,0 +1,38 @@
/* gtkanimationmanagerprivate.h: Animation manager
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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/>.
*/
#pragma once
#include <gtk/gtktypes.h>
G_BEGIN_DECLS
#define GTK_TYPE_ANIMATION_MANAGER (gtk_animation_manager_get_type())
G_DECLARE_FINAL_TYPE (GtkAnimationManager, gtk_animation_manager, GTK, ANIMATION_MANAGER, GObject)
GtkAnimationManager *
gtk_animation_manager_new (void);
void
gtk_animation_manager_set_frame_clock (GtkAnimationManager *self,
GdkFrameClock *frame_clock);
G_END_DECLS
+41
View File
@@ -0,0 +1,41 @@
/* gtkanimationprivate.h: Animation type
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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/>.
*/
#pragma once
#include "gtkanimation.h"
G_BEGIN_DECLS
struct _GtkAnimationClass
{
GObjectClass parent_class;
void (* start) (GtkAnimation *animation);
void (* advance) (GtkAnimation *animation,
gint64 frame_time);
void (* stop) (GtkAnimation *animation,
gboolean is_finished);
void (* iteration) (GtkAnimation *animation);
};
void gtk_animation_advance (GtkAnimation *animation,
gint64 frame_time);
G_END_DECLS
+15 -36
View File
@@ -1604,8 +1604,9 @@ get_size (GtkCellRenderer *cell,
GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
GtkCellRendererTextPrivate *priv = gtk_cell_renderer_text_get_instance_private (celltext);
PangoRectangle rect;
gint xpad, ypad;
gint cell_width, cell_height;
int xpad, ypad;
int cell_width, cell_height;
float xalign, yalign;
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
@@ -1652,52 +1653,30 @@ get_size (GtkCellRenderer *cell,
if (width == NULL)
return;
}
if (layout)
g_object_ref (layout);
else
layout = get_layout (celltext, widget, NULL, 0);
pango_layout_get_pixel_extents (layout, NULL, &rect);
if (cell_area)
{
gfloat xalign, yalign;
gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
rect.height = MIN (rect.height, cell_area->height - 2 * ypad);
rect.width = MIN (rect.width, cell_area->width - 2 * xpad);
rect.height = MIN (rect.height, cell_area->height - 2 * ypad);
rect.width = MIN (rect.width, cell_area->width - 2 * xpad);
if (x_offset)
{
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
*x_offset = (1.0 - xalign) * (cell_area->width - (rect.width + (2 * xpad)));
else
*x_offset = xalign * (cell_area->width - (rect.width + (2 * xpad)));
if ((priv->ellipsize_set && priv->ellipsize != PANGO_ELLIPSIZE_NONE) || priv->wrap_width != -1)
*x_offset = MAX(*x_offset, 0);
}
if (y_offset)
{
*y_offset = yalign * (cell_area->height - (rect.height + (2 * ypad)));
*y_offset = MAX (*y_offset, 0);
}
}
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
*x_offset = (1.0 - xalign) * (cell_area->width - (rect.width + (2 * xpad)));
else
{
if (x_offset) *x_offset = 0;
if (y_offset) *y_offset = 0;
}
*x_offset = xalign * (cell_area->width - (rect.width + (2 * xpad)));
if ((priv->ellipsize_set && priv->ellipsize != PANGO_ELLIPSIZE_NONE) || priv->wrap_width != -1)
*x_offset = MAX(*x_offset, 0);
*y_offset = yalign * (cell_area->height - (rect.height + (2 * ypad)));
*y_offset = MAX (*y_offset, 0);
if (height)
*height = ypad * 2 + rect.height;
if (width)
*width = xpad * 2 + rect.width;
g_object_unref (layout);
}
static void
+1 -1
View File
@@ -580,7 +580,7 @@ gtk_combo_box_text_remove_all (GtkComboBoxText *combo_box)
* function will return its contents (which will not necessarily
* be an item from the list).
*
* Returns: (transfer full): a newly allocated string containing the
* Returns: (nullable) (transfer full): a newly allocated string containing the
* currently active text. Must be freed with g_free().
*/
gchar *
+15 -264
View File
@@ -18,34 +18,19 @@
#include "config.h"
#include "gtkcsseasevalueprivate.h"
#include "gtktimingfunctionprivate.h"
#include <math.h>
typedef enum {
GTK_CSS_EASE_CUBIC_BEZIER,
GTK_CSS_EASE_STEPS
} GtkCssEaseType;
struct _GtkCssValue {
GTK_CSS_VALUE_BASE
GtkCssEaseType type;
union {
struct {
double x1;
double y1;
double x2;
double y2;
} cubic;
struct {
guint steps;
gboolean start;
} steps;
} u;
GtkTimingFunction *tm;
};
static void
gtk_css_value_ease_free (GtkCssValue *value)
{
gtk_timing_function_unref (value->tm);
g_slice_free (GtkCssValue, value);
}
@@ -63,23 +48,7 @@ static gboolean
gtk_css_value_ease_equal (const GtkCssValue *ease1,
const GtkCssValue *ease2)
{
if (ease1->type != ease2->type)
return FALSE;
switch (ease1->type)
{
case GTK_CSS_EASE_CUBIC_BEZIER:
return ease1->u.cubic.x1 == ease2->u.cubic.x1 &&
ease1->u.cubic.y1 == ease2->u.cubic.y1 &&
ease1->u.cubic.x2 == ease2->u.cubic.x2 &&
ease1->u.cubic.y2 == ease2->u.cubic.y2;
case GTK_CSS_EASE_STEPS:
return ease1->u.steps.steps == ease2->u.steps.steps &&
ease1->u.steps.start == ease2->u.steps.start;
default:
g_assert_not_reached ();
return FALSE;
}
return gtk_timing_function_equal (ease1->tm, ease2->tm);
}
static GtkCssValue *
@@ -95,43 +64,7 @@ static void
gtk_css_value_ease_print (const GtkCssValue *ease,
GString *string)
{
switch (ease->type)
{
case GTK_CSS_EASE_CUBIC_BEZIER:
if (ease->u.cubic.x1 == 0.25 && ease->u.cubic.y1 == 0.1 &&
ease->u.cubic.x2 == 0.25 && ease->u.cubic.y2 == 1.0)
g_string_append (string, "ease");
else if (ease->u.cubic.x1 == 0.0 && ease->u.cubic.y1 == 0.0 &&
ease->u.cubic.x2 == 1.0 && ease->u.cubic.y2 == 1.0)
g_string_append (string, "linear");
else if (ease->u.cubic.x1 == 0.42 && ease->u.cubic.y1 == 0.0 &&
ease->u.cubic.x2 == 1.0 && ease->u.cubic.y2 == 1.0)
g_string_append (string, "ease-in");
else if (ease->u.cubic.x1 == 0.0 && ease->u.cubic.y1 == 0.0 &&
ease->u.cubic.x2 == 0.58 && ease->u.cubic.y2 == 1.0)
g_string_append (string, "ease-out");
else if (ease->u.cubic.x1 == 0.42 && ease->u.cubic.y1 == 0.0 &&
ease->u.cubic.x2 == 0.58 && ease->u.cubic.y2 == 1.0)
g_string_append (string, "ease-in-out");
else
g_string_append_printf (string, "cubic-bezier(%g,%g,%g,%g)",
ease->u.cubic.x1, ease->u.cubic.y1,
ease->u.cubic.x2, ease->u.cubic.y2);
break;
case GTK_CSS_EASE_STEPS:
if (ease->u.steps.steps == 1)
{
g_string_append (string, ease->u.steps.start ? "step-start" : "step-end");
}
else
{
g_string_append_printf (string, "steps(%u%s)", ease->u.steps.steps, ease->u.steps.start ? ",start" : "");
}
break;
default:
g_assert_not_reached ();
break;
}
gtk_timing_function_print (ease->tm, string);
}
static const GtkCssValueClass GTK_CSS_VALUE_EASE = {
@@ -145,42 +78,12 @@ static const GtkCssValueClass GTK_CSS_VALUE_EASE = {
};
GtkCssValue *
_gtk_css_ease_value_new_cubic_bezier (double x1,
double y1,
double x2,
double y2)
_gtk_css_ease_value_new_ease (void)
{
GtkCssValue *value;
g_return_val_if_fail (x1 >= 0.0, NULL);
g_return_val_if_fail (x1 <= 1.0, NULL);
g_return_val_if_fail (x2 >= 0.0, NULL);
g_return_val_if_fail (x2 <= 1.0, NULL);
value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_EASE);
value->type = GTK_CSS_EASE_CUBIC_BEZIER;
value->u.cubic.x1 = x1;
value->u.cubic.y1 = y1;
value->u.cubic.x2 = x2;
value->u.cubic.y2 = y2;
return value;
}
static GtkCssValue *
_gtk_css_ease_value_new_steps (guint n_steps,
gboolean start)
{
GtkCssValue *value;
g_return_val_if_fail (n_steps > 0, NULL);
value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_EASE);
value->type = GTK_CSS_EASE_STEPS;
value->u.steps.steps = n_steps;
value->u.steps.start = start;
value->tm = gtk_ease ();
return value;
}
@@ -224,131 +127,19 @@ _gtk_css_ease_value_can_parse (GtkCssParser *parser)
return FALSE;
}
static guint
gtk_css_ease_value_parse_cubic_bezier_arg (GtkCssParser *parser,
guint arg,
gpointer data)
{
double *values = data;
if (!gtk_css_parser_consume_number (parser, &values[arg]))
return 0;
if (arg % 2 == 0)
{
if (values[arg] < 0 || values[arg] > 1.0)
{
gtk_css_parser_error_value (parser, "value %g out of range. Must be from 0.0 to 1.0", values[arg]);
return 0;
}
}
return 1;
}
static GtkCssValue *
gtk_css_ease_value_parse_cubic_bezier (GtkCssParser *parser)
{
double values[4];
if (!gtk_css_parser_consume_function (parser, 4, 4, gtk_css_ease_value_parse_cubic_bezier_arg, values))
return NULL;
return _gtk_css_ease_value_new_cubic_bezier (values[0], values[1], values[2], values[3]);
}
typedef struct
{
int n_steps;
gboolean start;
} ParseStepsData;
static guint
gtk_css_ease_value_parse_steps_arg (GtkCssParser *parser,
guint arg,
gpointer data_)
{
ParseStepsData *data = data_;
switch (arg)
{
case 0:
if (!gtk_css_parser_consume_integer (parser, &data->n_steps))
{
return 0;
}
else if (data->n_steps < 1)
{
gtk_css_parser_error_value (parser, "Number of steps must be > 0");
return 0;
}
return 1;
case 1:
if (gtk_css_parser_try_ident (parser, "start"))
data->start = TRUE;
else if (gtk_css_parser_try_ident (parser, "end"))
data->start = FALSE;
else
{
gtk_css_parser_error_syntax (parser, "Only allowed values are 'start' and 'end'");
return 0;
}
return 1;
default:
g_return_val_if_reached (0);
}
}
static GtkCssValue *
gtk_css_ease_value_parse_steps (GtkCssParser *parser)
{
ParseStepsData data = { 0, FALSE };
if (!gtk_css_parser_consume_function (parser, 1, 2, gtk_css_ease_value_parse_steps_arg, &data))
return NULL;
return _gtk_css_ease_value_new_steps (data.n_steps, data.start);
}
GtkCssValue *
_gtk_css_ease_value_parse (GtkCssParser *parser)
{
guint i;
GtkCssValue *value;
GtkTimingFunction *tm;
g_return_val_if_fail (parser != NULL, NULL);
if (!gtk_timing_function_parser_parse (parser, &tm))
return NULL;
for (i = 0; i < G_N_ELEMENTS (parser_values); i++)
{
if (parser_values[i].is_function)
{
if (gtk_css_parser_has_function (parser, parser_values[i].name))
{
if (parser_values[i].is_bezier)
return gtk_css_ease_value_parse_cubic_bezier (parser);
else
return gtk_css_ease_value_parse_steps (parser);
}
}
else
{
if (gtk_css_parser_try_ident (parser, parser_values[i].name))
{
if (parser_values[i].is_bezier)
return _gtk_css_ease_value_new_cubic_bezier (parser_values[i].values[0],
parser_values[i].values[1],
parser_values[i].values[2],
parser_values[i].values[3]);
else
return _gtk_css_ease_value_new_steps (parser_values[i].values[0],
parser_values[i].values[1] != 0.0);
}
}
}
value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_EASE);
value->tm = tm;
gtk_css_parser_error_syntax (parser, "Expected a valid ease value");
return NULL;
return value;
}
double
@@ -362,45 +153,5 @@ _gtk_css_ease_value_transform (const GtkCssValue *ease,
if (progress >= 1)
return 1;
switch (ease->type)
{
case GTK_CSS_EASE_CUBIC_BEZIER:
{
static const double epsilon = 0.00001;
double tmin, t, tmax;
tmin = 0.0;
tmax = 1.0;
t = progress;
while (tmin < tmax)
{
double sample;
sample = (((1.0 + 3 * ease->u.cubic.x1 - 3 * ease->u.cubic.x2) * t
+ -6 * ease->u.cubic.x1 + 3 * ease->u.cubic.x2) * t
+ 3 * ease->u.cubic.x1 ) * t;
if (fabs(sample - progress) < epsilon)
break;
if (progress > sample)
tmin = t;
else
tmax = t;
t = (tmax + tmin) * .5;
}
return (((1.0 + 3 * ease->u.cubic.y1 - 3 * ease->u.cubic.y2) * t
+ -6 * ease->u.cubic.y1 + 3 * ease->u.cubic.y2) * t
+ 3 * ease->u.cubic.y1 ) * t;
}
case GTK_CSS_EASE_STEPS:
progress *= ease->u.steps.steps;
progress = floor (progress) + (ease->u.steps.start ? 0 : 1);
return progress / ease->u.steps.steps;
default:
g_assert_not_reached ();
return 1.0;
}
return gtk_timing_function_transform_time (ease->tm, progress, 1.0);
}
+1 -4
View File
@@ -25,10 +25,7 @@
G_BEGIN_DECLS
GtkCssValue * _gtk_css_ease_value_new_cubic_bezier (double x1,
double y1,
double x2,
double y2);
GtkCssValue * _gtk_css_ease_value_new_ease (void);
gboolean _gtk_css_ease_value_can_parse (GtkCssParser *parser);
GtkCssValue * _gtk_css_ease_value_parse (GtkCssParser *parser);
+2 -4
View File
@@ -1613,8 +1613,7 @@ _gtk_css_style_property_init_properties (void)
0,
transition_timing_function_parse,
NULL,
_gtk_css_array_value_new (
_gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0)));
_gtk_css_array_value_new (_gtk_css_ease_value_new_ease ()));
gtk_css_style_property_register ("transition-delay",
GTK_CSS_PROPERTY_TRANSITION_DELAY,
G_TYPE_NONE,
@@ -1647,8 +1646,7 @@ _gtk_css_style_property_init_properties (void)
0,
transition_timing_function_parse,
NULL,
_gtk_css_array_value_new (
_gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0)));
_gtk_css_array_value_new (_gtk_css_ease_value_new_ease ()));
gtk_css_style_property_register ("animation-iteration-count",
GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT,
G_TYPE_NONE,
+25
View File
@@ -1529,6 +1529,7 @@ gtk_entry_measure (GtkWidget *widget,
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
int i;
gtk_widget_measure (priv->text,
orientation,
@@ -1536,6 +1537,30 @@ gtk_entry_measure (GtkWidget *widget,
minimum, natural,
minimum_baseline, natural_baseline);
for (i = 0; i < MAX_ICONS; i++)
{
EntryIconInfo *icon_info = priv->icons[i];
int icon_min, icon_nat;
if (!icon_info)
continue;
gtk_widget_measure (icon_info->widget,
GTK_ORIENTATION_HORIZONTAL,
-1, &icon_min, &icon_nat, NULL, NULL);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
*minimum += icon_min;
*natural += icon_nat;
}
else
{
*minimum = MAX (*minimum, icon_min);
*natural = MAX (*natural, icon_nat);
}
}
if (priv->progress_widget && gtk_widget_get_visible (priv->progress_widget))
{
int prog_min, prog_nat;
+22
View File
@@ -1147,4 +1147,26 @@ typedef enum {
GTK_CONSTRAINT_VFL_PARSER_ERROR_INVALID_RELATION
} GtkConstraintVflParserError;
/**
* GtkAnimationDirection:
* @GTK_ANIMATION_DIRECTION_FORWARD:
* @GTK_ANIMATION_DIRECTION_BACKWARD:
*
* The direction of the animation.
*/
typedef enum {
GTK_ANIMATION_DIRECTION_FORWARD,
GTK_ANIMATION_DIRECTION_BACKWARD
} GtkAnimationDirection;
typedef enum {
GTK_STEP_POSITION_JUMP_START,
GTK_STEP_POSITION_JUMP_END,
GTK_STEP_POSITION_JUMP_NONE,
GTK_STEP_POSITION_JUMP_BOTH,
GTK_STEP_POSITION_START = GTK_STEP_POSITION_JUMP_START,
GTK_STEP_POSITION_END = GTK_STEP_POSITION_JUMP_END
} GtkStepPosition;
#endif /* __GTK_ENUMS_H__ */
+27
View File
@@ -577,9 +577,34 @@ gtk_file_chooser_dialog_map (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->map (widget);
}
static void
save_dialog_geometry (GtkFileChooserDialog *dialog)
{
GtkWindow *window;
GSettings *settings;
int old_width, old_height;
int width, height;
settings = _gtk_file_chooser_get_settings_for_widget (GTK_WIDGET (dialog));
window = GTK_WINDOW (dialog);
gtk_window_get_size (window, &width, &height);
g_settings_get (settings, SETTINGS_KEY_WINDOW_SIZE, "(ii)", &old_width, &old_height);
if (old_width != width || old_height != height)
g_settings_set (settings, SETTINGS_KEY_WINDOW_SIZE, "(ii)", width, height);
g_settings_apply (settings);
}
static void
gtk_file_chooser_dialog_unmap (GtkWidget *widget)
{
GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
save_dialog_geometry (dialog);
GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->unmap (widget);
}
@@ -593,6 +618,8 @@ gtk_file_chooser_dialog_size_allocate (GtkWidget *widget,
width,
height,
baseline);
if (gtk_widget_is_drawable (widget))
save_dialog_geometry (GTK_FILE_CHOOSER_DIALOG (widget));
}
/* We do a signal connection here rather than overriding the method in
+27 -15
View File
@@ -2460,19 +2460,6 @@ location_changed_timeout_cb (gpointer user_data)
return G_SOURCE_REMOVE;
}
static void
reset_location_timeout (GtkFileChooserWidget *impl)
{
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
if (priv->location_changed_id > 0)
g_source_remove (priv->location_changed_id);
priv->location_changed_id = g_timeout_add (LOCATION_CHANGED_TIMEOUT,
location_changed_timeout_cb,
impl);
g_source_set_name_by_id (priv->location_changed_id, "[gtk] location_changed_timeout_cb");
}
static void
location_entry_changed_cb (GtkEditable *editable,
GtkFileChooserWidget *impl)
@@ -2489,7 +2476,16 @@ location_entry_changed_cb (GtkEditable *editable,
}
if (priv->action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
reset_location_timeout (impl);
{
/* Reset location timeout */
if (priv->location_changed_id > 0)
g_source_remove (priv->location_changed_id);
priv->location_changed_id = g_timeout_add (LOCATION_CHANGED_TIMEOUT,
location_changed_timeout_cb,
impl);
g_source_set_name_by_id (priv->location_changed_id, "[gtk] location_changed_timeout_cb");
}
}
static void
@@ -3051,12 +3047,20 @@ static void
operation_mode_set_browse (GtkFileChooserWidget *impl)
{
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
GtkRevealerTransitionType old_revealer_transition_type;
gtk_places_sidebar_set_location (GTK_PLACES_SIDEBAR (priv->places_sidebar), priv->current_folder);
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_files_stack), "list");
location_mode_set (impl, LOCATION_MODE_PATH_BAR);
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_header_stack), "pathbar");
old_revealer_transition_type = gtk_revealer_get_transition_type (GTK_REVEALER (priv->browse_header_revealer));
gtk_revealer_set_transition_type (GTK_REVEALER (priv->browse_header_revealer),
GTK_REVEALER_TRANSITION_TYPE_NONE);
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->browse_header_revealer), TRUE);
gtk_revealer_set_transition_type (GTK_REVEALER (priv->browse_header_revealer),
old_revealer_transition_type);
gtk_widget_set_sensitive (priv->filter_combo, TRUE);
g_object_notify (G_OBJECT (impl), "subtitle");
}
@@ -3090,10 +3094,19 @@ operation_mode_set_recent (GtkFileChooserWidget *impl)
{
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
GFile *file;
GtkRevealerTransitionType old_revealer_transition_type;
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_files_stack), "list");
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_header_stack), "pathbar");
/* Hide browse_header without a transition */
old_revealer_transition_type = gtk_revealer_get_transition_type (GTK_REVEALER (priv->browse_header_revealer));
gtk_revealer_set_transition_type (GTK_REVEALER (priv->browse_header_revealer),
GTK_REVEALER_TRANSITION_TYPE_NONE);
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->browse_header_revealer), FALSE);
gtk_revealer_set_transition_type (GTK_REVEALER (priv->browse_header_revealer),
old_revealer_transition_type);
location_bar_update (impl);
recent_start_loading (impl);
file = g_file_new_for_uri ("recent:///");
@@ -3584,7 +3597,6 @@ gtk_file_chooser_widget_unroot (GtkWidget *widget)
remove_settings_signal (impl, gtk_widget_get_display (widget));
check_icon_theme (impl);
emit_default_size_changed (impl);
GTK_WIDGET_CLASS (gtk_file_chooser_widget_parent_class)->unroot (widget);
}
+10
View File
@@ -1543,6 +1543,16 @@ attribute_from_text (GtkBuilder *builder,
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
attribute = pango_attr_background_alpha_new ((guint16)g_value_get_int (&val));
break;
#if PANGO_VERSION_CHECK(1,44,0)
case PANGO_ATTR_ALLOW_BREAKS:
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
attribute = pango_attr_allow_breaks_new (g_value_get_boolean (&val));
break;
case PANGO_ATTR_SHOW:
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_SHOW_FLAGS, value, &val, error))
attribute = pango_attr_show_new (g_value_get_flags (&val));
break;
#endif
case PANGO_ATTR_INVALID:
default:
break;
+81 -1
View File
@@ -25,6 +25,7 @@
#include "config.h"
#include <errno.h>
#include <string.h>
#include "gtkmountoperationprivate.h"
@@ -122,7 +123,10 @@ struct _GtkMountOperationPrivate {
GtkWidget *username_entry;
GtkWidget *domain_entry;
GtkWidget *password_entry;
GtkWidget *pim_entry;
GtkWidget *anonymous_toggle;
GtkWidget *tcrypt_hidden_toggle;
GtkWidget *tcrypt_system_toggle;
GList *user_widgets;
GAskPasswordFlags ask_flags;
@@ -349,6 +353,27 @@ pw_dialog_got_response (GtkDialog *dialog,
g_mount_operation_set_password (op, text);
}
if (priv->pim_entry)
{
text = gtk_editable_get_text (GTK_EDITABLE (priv->pim_entry));
if (text && strlen (text) > 0)
{
guint64 pim;
gchar *end = NULL;
errno = 0;
pim = g_ascii_strtoull (text, &end, 10);
if (errno == 0 && pim <= G_MAXUINT && end != text)
g_mount_operation_set_pim (op, (guint) pim);
}
}
if (priv->tcrypt_hidden_toggle && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->tcrypt_hidden_toggle)))
g_mount_operation_set_is_tcrypt_hidden_volume (op, TRUE);
if (priv->tcrypt_system_toggle && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->tcrypt_system_toggle)))
g_mount_operation_set_is_tcrypt_system_volume (op, TRUE);
if (priv->ask_flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
g_mount_operation_set_password_save (op, priv->password_save);
@@ -376,6 +401,29 @@ entry_has_input (GtkWidget *entry_widget)
return text != NULL && text[0] != '\0';
}
static gboolean
pim_entry_is_valid (GtkWidget *entry_widget)
{
const char *text;
gchar *end = NULL;
guint64 pim;
if (entry_widget == NULL)
return TRUE;
text = gtk_editable_get_text (GTK_EDITABLE (entry_widget));
/* An empty PIM entry is OK */
if (text == NULL || text[0] == '\0')
return TRUE;
errno = 0;
pim = g_ascii_strtoull (text, &end, 10);
if (errno || pim > G_MAXUINT || end == text)
return FALSE;
else
return TRUE;
}
static gboolean
pw_dialog_input_is_valid (GtkMountOperation *operation)
{
@@ -389,7 +437,8 @@ pw_dialog_input_is_valid (GtkMountOperation *operation)
* definitively needs a password.
*/
is_valid = entry_has_input (priv->username_entry) &&
entry_has_input (priv->domain_entry);
entry_has_input (priv->domain_entry) &&
pim_entry_is_valid (priv->pim_entry);
return is_valid;
}
@@ -643,6 +692,31 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
priv->domain_entry = table_add_entry (operation, rows++, _("_Domain"),
default_domain, operation);
priv->pim_entry = NULL;
if (priv->ask_flags & G_ASK_PASSWORD_TCRYPT)
{
GtkWidget *volume_type_label;
GtkWidget *volume_type_box;
volume_type_label = gtk_label_new (_("Volume type"));
gtk_widget_set_halign (volume_type_label, GTK_ALIGN_END);
gtk_widget_set_hexpand (volume_type_label, FALSE);
gtk_grid_attach (GTK_GRID (grid), volume_type_label, 0, rows, 1, 1);
priv->user_widgets = g_list_prepend (priv->user_widgets, volume_type_label);
volume_type_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
gtk_grid_attach (GTK_GRID (grid), volume_type_box, 1, rows++, 1, 1);
priv->user_widgets = g_list_prepend (priv->user_widgets, volume_type_box);
priv->tcrypt_hidden_toggle = gtk_check_button_new_with_mnemonic (_("_Hidden"));
gtk_container_add (GTK_CONTAINER (volume_type_box), priv->tcrypt_hidden_toggle);
priv->tcrypt_system_toggle = gtk_check_button_new_with_mnemonic (_("_Windows system"));
gtk_container_add (GTK_CONTAINER (volume_type_box), priv->tcrypt_system_toggle);
priv->pim_entry = table_add_entry (operation, rows++, _("_PIM"), NULL, operation);
}
priv->password_entry = NULL;
if (priv->ask_flags & G_ASK_PASSWORD_NEED_PASSWORD)
{
@@ -759,6 +833,12 @@ call_password_proxy_cb (GObject *source,
g_mount_operation_set_password (op, g_variant_get_string (value, NULL));
else if (strcmp (key, "password_save") == 0)
g_mount_operation_set_password_save (op, g_variant_get_uint32 (value));
else if (strcmp (key, "hidden_volume") == 0)
g_mount_operation_set_is_tcrypt_hidden_volume (op, g_variant_get_boolean (value));
else if (strcmp (key, "system_volume") == 0)
g_mount_operation_set_is_tcrypt_system_volume (op, g_variant_get_boolean (value));
else if (strcmp (key, "pim") == 0)
g_mount_operation_set_pim (op, g_variant_get_uint32 (value));
}
out:
+2 -7
View File
@@ -192,12 +192,6 @@ gtk_password_entry_dispose (GObject *object)
G_OBJECT_CLASS (gtk_password_entry_parent_class)->dispose (object);
}
static void
gtk_password_entry_finalize (GObject *object)
{
G_OBJECT_CLASS (gtk_password_entry_parent_class)->finalize (object);
}
static void
gtk_password_entry_set_property (GObject *object,
guint prop_id,
@@ -380,7 +374,6 @@ gtk_password_entry_class_init (GtkPasswordEntryClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = gtk_password_entry_dispose;
object_class->finalize = gtk_password_entry_finalize;
object_class->get_property = gtk_password_entry_get_property;
object_class->set_property = gtk_password_entry_set_property;
@@ -477,6 +470,8 @@ gtk_password_entry_set_show_peek_icon (GtkPasswordEntry *entry,
g_return_if_fail (GTK_IS_PASSWORD_ENTRY (entry));
show_peek_icon = !!show_peek_icon;
if (show_peek_icon == (priv->peek_icon != NULL))
return;
+15 -3
View File
@@ -1999,10 +1999,22 @@ listbox_filter_func (GtkListBoxRow *row,
NULL);
if (name)
retval |= strstr (name, priv->search_query) != NULL;
{
char *lowercase_name = g_utf8_strdown (name, -1);
retval |= strstr (lowercase_name, priv->search_query) != NULL;
g_free (lowercase_name);
}
if (path)
retval |= strstr (path, priv->search_query) != NULL;
{
char *lowercase_path = g_utf8_strdown (path, -1);
retval |= strstr (lowercase_path, priv->search_query) != NULL;
g_free (lowercase_path);
}
g_free (name);
g_free (path);
@@ -2459,7 +2471,7 @@ gtk_places_view_set_search_query (GtkPlacesView *view,
if (g_strcmp0 (priv->search_query, query_text) != 0)
{
g_clear_pointer (&priv->search_query, g_free);
priv->search_query = g_strdup (query_text);
priv->search_query = g_utf8_strdown (query_text, -1);
gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->listbox));
gtk_list_box_invalidate_headers (GTK_LIST_BOX (priv->listbox));
+2 -6
View File
@@ -1091,8 +1091,7 @@ gtk_popover_size_allocate (GtkWidget *widget,
GtkAllocation child_alloc;
int tail_height = priv->has_arrow ? TAIL_HEIGHT : 0;
if (priv->surface)
gtk_popover_move_resize (popover);
gtk_popover_move_resize (popover);
switch (priv->final_position)
{
@@ -1414,10 +1413,7 @@ size_changed (GtkWidget *widget,
int baseline,
GtkPopover *popover)
{
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
if (priv->surface)
gtk_popover_move_resize (popover);
gtk_popover_move_resize (popover);
}
void
+49
View File
@@ -0,0 +1,49 @@
/* gtkpropertyanimation.c: An animation controlling a single property
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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/>.
*/
#include "gtkpropertyanimation.h"
#include "gtktransitionprivate.h"
enum
{
INITIAL,
FINAL,
N_STATES
};
struct _GtkPropertyAnimation
{
GtkTransition parent_instance;
GValue interval[N_STATES];
};
G_DEFINE_TYPE (GtkPropertyAnimation, gtk_property_animation, GTK_TYPE_ANIMATION)
static void
gtk_property_animation_class_init (GtkPropertyAnimationClass *klass)
{
}
static void
gtk_property_animation_init (GtkPropertyAnimation *self)
{
}
+52
View File
@@ -0,0 +1,52 @@
/* gtkpropertyanimation.h: An animation controlling a single object property
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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/>.
*/
#pragma once
#include <gtk/gtkanimation.h>
G_BEGIN_DECLS
/**
* GtkPropertyAnimation:
*
* A animation that operates on a single property of a #GObject.
*/
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkPropertyAnimation, gtk_property_animation, GTK, PROPERTY_ANIMATION, GtkAnimation)
GDK_AVAILABLE_IN_ALL
GtkAnimation * gtk_property_animation_new (const char *property_name);
/* Interval */
GDK_AVAILABLE_IN_ALL
void gtk_property_animation_set_from (GtkPropertyAnimation *animation,
...);
GDK_AVAILABLE_IN_ALL
void gtk_property_animation_set_from_value (GtkPropertyAnimation *animation,
const GValue *value);
GDK_AVAILABLE_IN_ALL
void gtk_property_animation_set_to (GtkPropertyAnimation *animation,
...);
GDK_AVAILABLE_IN_ALL
void gtk_property_animation_set_to_value (GtkPropertyAnimation *animation,
const GValue *value);
G_END_DECLS
+18 -1
View File
@@ -50,18 +50,24 @@ gtk_root_default_get_display (GtkRoot *self)
return gdk_display_get_default ();
}
static GtkConstraintSolver *
gtk_root_default_get_constraint_solver (GtkRoot *self)
{
return NULL;
}
static GtkAnimationManager *
gtk_root_default_get_animation_manager (GtkRoot *self)
{
return NULL;
}
static void
gtk_root_default_init (GtkRootInterface *iface)
{
iface->get_display = gtk_root_default_get_display;
iface->get_constraint_solver = gtk_root_default_get_constraint_solver;
iface->get_animation_manager = gtk_root_default_get_animation_manager;
g_object_interface_install_property (iface,
g_param_spec_object ("focus-widget",
@@ -101,6 +107,17 @@ gtk_root_get_constraint_solver (GtkRoot *self)
return iface->get_constraint_solver (self);
}
GtkAnimationManager *
gtk_root_get_animation_manager (GtkRoot *self)
{
GtkRootInterface *iface;
g_return_val_if_fail (GTK_IS_ROOT (self), NULL);
iface = GTK_ROOT_GET_IFACE (self);
return iface->get_animation_manager (self);
}
/**
* gtk_root_set_focus:
* @self: a #GtkRoot
+4 -1
View File
@@ -3,11 +3,12 @@
#include "gtkroot.h"
#include "gtkanimationmanagerprivate.h"
#include "gtkconstraintsolverprivate.h"
G_BEGIN_DECLS
/**
/*< private >
* GtkRootIface:
*
* The list of functions that must be implemented for the #GtkRoot interface.
@@ -21,9 +22,11 @@ struct _GtkRootInterface
GdkDisplay * (* get_display) (GtkRoot *self);
GtkConstraintSolver * (* get_constraint_solver) (GtkRoot *self);
GtkAnimationManager * (* get_animation_manager) (GtkRoot *self);
};
GtkConstraintSolver * gtk_root_get_constraint_solver (GtkRoot *self);
GtkAnimationManager * gtk_root_get_animation_manager (GtkRoot *self);
enum {
GTK_ROOT_PROP_FOCUS_WIDGET,
+1 -1
View File
@@ -2062,7 +2062,7 @@ settings_update_font_options (GtkSettings *settings)
priv->font_options = cairo_font_options_create ();
cairo_font_options_set_hint_metrics (priv->font_options, CAIRO_HINT_METRICS_ON);
cairo_font_options_set_hint_metrics (priv->font_options, CAIRO_HINT_METRICS_OFF);
hint_style = CAIRO_HINT_STYLE_DEFAULT;
if (hinting == 0)
+119 -87
View File
@@ -195,8 +195,9 @@ struct _GtkTextPrivate
gunichar invisible_char;
guint blink_time; /* time in msec the cursor has blinked since last user event */
guint blink_timeout;
guint64 blink_start_time;
guint blink_tick;
float cursor_alpha;
guint16 preedit_length; /* length of preedit string, in bytes */
guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */
@@ -212,7 +213,6 @@ struct _GtkTextPrivate
guint activates_default : 1;
guint cache_includes_preedit : 1;
guint change_count : 8;
guint cursor_visible : 1;
guint editing_canceled : 1; /* Only used by GtkCellRendererText */
guint in_click : 1; /* Flag so we don't select all when clicking in entry to focus in */
guint invisible_char_set : 1;
@@ -1765,10 +1765,10 @@ gtk_text_destroy (GtkWidget *widget)
gtk_text_reset_im_context (self);
gtk_text_reset_layout (self);
if (priv->blink_timeout)
if (priv->blink_tick)
{
g_source_remove (priv->blink_timeout);
priv->blink_timeout = 0;
gtk_widget_remove_tick_callback (widget, priv->blink_tick);
priv->blink_tick = 0;
}
if (priv->magnifier)
@@ -1825,9 +1825,6 @@ gtk_text_finalize (GObject *object)
g_clear_pointer (&priv->placeholder, gtk_widget_unparent);
if (priv->blink_timeout)
g_source_remove (priv->blink_timeout);
if (priv->tabs)
pango_tab_array_free (priv->tabs);
@@ -2193,9 +2190,6 @@ gtk_text_size_allocate (GtkWidget *widget,
-1);
}
/* Do this here instead of gtk_text_size_allocate() so it works
* inside spinbuttons, which don't chain up.
*/
if (gtk_widget_get_realized (widget))
gtk_text_recompute (self);
@@ -2267,8 +2261,12 @@ gtk_text_snapshot (GtkWidget *widget,
/* When no text is being displayed at all, don't show the cursor */
if (gtk_text_get_display_mode (self) != DISPLAY_BLANK &&
gtk_widget_has_focus (widget) &&
priv->selection_bound == priv->current_pos && priv->cursor_visible)
gtk_text_draw_cursor (self, snapshot, CURSOR_STANDARD);
priv->selection_bound == priv->current_pos)
{
gtk_snapshot_push_opacity (snapshot, priv->cursor_alpha);
gtk_text_draw_cursor (self, snapshot, CURSOR_STANDARD);
gtk_snapshot_pop (snapshot);
}
gtk_text_draw_undershoot (self, snapshot);
}
@@ -3261,10 +3259,21 @@ static void
gtk_text_style_updated (GtkWidget *widget)
{
GtkText *self = GTK_TEXT (widget);
GtkStyleContext *context;
GtkCssStyleChange *change = NULL;
context = gtk_widget_get_style_context (widget);
change = gtk_style_context_get_change (context);
GTK_WIDGET_CLASS (gtk_text_parent_class)->style_updated (widget);
gtk_text_update_cached_style_values (self);
if (change == NULL ||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT |
GTK_CSS_AFFECTS_BACKGROUND |
GTK_CSS_AFFECTS_CONTENT))
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
@@ -6293,47 +6302,85 @@ get_cursor_blink_timeout (GtkText *self)
return timeout;
}
typedef struct {
guint64 start;
guint64 end;
} BlinkData;
static gboolean blink_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer user_data);
static void
show_cursor (GtkText *self)
add_blink_timeout (GtkText *self,
gboolean delay)
{
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
GtkWidget *widget;
BlinkData *data;
int blink_time;
if (!priv->cursor_visible)
{
priv->cursor_visible = TRUE;
priv->blink_start_time = g_get_monotonic_time ();
priv->cursor_alpha = 1.0;
widget = GTK_WIDGET (self);
if (gtk_widget_has_focus (widget) && priv->selection_bound == priv->current_pos)
gtk_widget_queue_draw (widget);
}
blink_time = get_cursor_time (self);
data = g_new (BlinkData, 1);
data->start = priv->blink_start_time;
if (delay)
data->start += blink_time * 1000 / 2;
data->end = data->start + blink_time * 1000;
priv->blink_tick = gtk_widget_add_tick_callback (GTK_WIDGET (self),
blink_cb,
data,
g_free);
}
static void
hide_cursor (GtkText *self)
remove_blink_timeout (GtkText *self)
{
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
GtkWidget *widget;
if (priv->cursor_visible)
if (priv->blink_tick)
{
priv->cursor_visible = FALSE;
widget = GTK_WIDGET (self);
if (gtk_widget_has_focus (widget) && priv->selection_bound == priv->current_pos)
gtk_widget_queue_draw (widget);
gtk_widget_remove_tick_callback (GTK_WIDGET (self), priv->blink_tick);
priv->blink_tick = 0;
}
}
/*
* Blink!
*/
static int
blink_cb (gpointer data)
static float
blink_alpha (float phase)
{
GtkText *self = data;
/* keep it simple, and split the blink cycle evenly
* into visible, fading out, invisible, fading in
*/
if (phase < 0.25)
return 1;
else if (phase < 0.5)
return 1 - 4 * (phase - 0.25);
else if (phase < 0.75)
return 0;
else
return 4 * (phase - 0.75);
}
static gboolean
blink_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer user_data)
{
GtkText *self = GTK_TEXT (widget);
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
BlinkData *data = user_data;
int blink_timeout;
int blink_time;
guint64 now;
float phase;
float alpha;
if (!gtk_widget_has_focus (GTK_WIDGET (self)))
{
@@ -6342,39 +6389,43 @@ blink_cb (gpointer data)
"GDK_EVENT_PROPAGATE so the self gets the event as well");
gtk_text_check_cursor_blink (self);
return G_SOURCE_REMOVE;
}
g_assert (priv->selection_bound == priv->current_pos);
blink_timeout = get_cursor_blink_timeout (self);
blink_time = get_cursor_time (self);
now = g_get_monotonic_time ();
if (now > priv->blink_start_time + blink_timeout * 1000000)
{
/* we've blinked enough without the user doing anything, stop blinking */
priv->cursor_alpha = 1.0;
remove_blink_timeout (self);
gtk_widget_queue_draw (widget);
return G_SOURCE_REMOVE;
}
g_assert (priv->selection_bound == priv->current_pos);
blink_timeout = get_cursor_blink_timeout (self);
if (priv->blink_time > 1000 * blink_timeout &&
blink_timeout < G_MAXINT/1000)
phase = (now - data->start) / (float) (data->end - data->start);
if (now >= data->end)
{
/* we've blinked enough without the user doing anything, stop blinking */
show_cursor (self);
priv->blink_timeout = 0;
}
else if (priv->cursor_visible)
{
hide_cursor (self);
priv->blink_timeout = g_timeout_add (get_cursor_time (self) * CURSOR_OFF_MULTIPLIER / CURSOR_DIVIDER,
blink_cb,
self);
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
}
else
{
show_cursor (self);
priv->blink_time += get_cursor_time (self);
priv->blink_timeout = g_timeout_add (get_cursor_time (self) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER,
blink_cb,
self);
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
data->start = data->end;
data->end = data->start + blink_time * 1000;
}
return G_SOURCE_REMOVE;
alpha = blink_alpha (phase);
if (priv->cursor_alpha != alpha)
{
priv->cursor_alpha = alpha;
gtk_widget_queue_draw (widget);
}
return G_SOURCE_CONTINUE;
}
static void
@@ -6384,42 +6435,23 @@ gtk_text_check_cursor_blink (GtkText *self)
if (cursor_blinks (self))
{
if (!priv->blink_timeout)
{
show_cursor (self);
priv->blink_timeout = g_timeout_add (get_cursor_time (self) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER,
blink_cb,
self);
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
}
if (!priv->blink_tick)
add_blink_timeout (self, FALSE);
}
else
{
if (priv->blink_timeout)
{
g_source_remove (priv->blink_timeout);
priv->blink_timeout = 0;
}
priv->cursor_visible = TRUE;
if (priv->blink_tick)
remove_blink_timeout (self);
}
}
static void
gtk_text_pend_cursor_blink (GtkText *self)
{
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
if (cursor_blinks (self))
{
if (priv->blink_timeout != 0)
g_source_remove (priv->blink_timeout);
priv->blink_timeout = g_timeout_add (get_cursor_time (self) * CURSOR_PEND_MULTIPLIER / CURSOR_DIVIDER,
blink_cb,
self);
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
show_cursor (self);
remove_blink_timeout (self);
add_blink_timeout (self, TRUE);
}
}
@@ -6428,7 +6460,7 @@ gtk_text_reset_blink_time (GtkText *self)
{
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
priv->blink_time = 0;
priv->blink_start_time = g_get_monotonic_time ();
}
/**
-932
View File
@@ -1,932 +0,0 @@
/* gtktextdisplay.c - display layed-out text
*
* Copyright (c) 1992-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 2000 Red Hat, Inc.
* Tk->Gtk port by Havoc Pennington
*
* This file can be used under your choice of two licenses, the LGPL
* and the original Tk license.
*
* LGPL:
*
* 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/>.Free
*
* Original Tk license:
*
* This software is copyrighted by the Regents of the University of
* California, Sun Microsystems, Inc., and other parties. The
* following terms apply to all files associated with the software
* unless explicitly disclaimed in individual files.
*
* The authors hereby grant permission to use, copy, modify,
* distribute, and license this software and its documentation for any
* purpose, provided that existing copyright notices are retained in
* all copies and that this notice is included verbatim in any
* distributions. No written agreement, license, or royalty fee is
* required for any of the authorized uses. Modifications to this
* software may be copyrighted by their authors and need not follow
* the licensing terms described here, provided that the new terms are
* clearly indicated on the first page of each file where they apply.
*
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
* DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
* OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
* NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
* AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* GOVERNMENT USE: If you are acquiring this software on behalf of the
* U.S. government, the Government shall have only "Restricted Rights"
* in the software and related documentation as defined in the Federal
* Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
* are acquiring the software on behalf of the Department of Defense,
* the software shall be classified as "Commercial Computer Software"
* and the Government shall have only "Restricted Rights" as defined
* in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
* foregoing, the authors grant the U.S. Government and others acting
* in its behalf permission to use and distribute the software in
* accordance with the terms specified in this license.
*
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gtktextdisplayprivate.h"
#include "gtktextviewprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtkintl.h"
#include <gdk/gdktextureprivate.h>
#define GTK_TYPE_TEXT_RENDERER (_gtk_text_renderer_get_type())
#define GTK_TEXT_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_TEXT_RENDERER, GtkTextRenderer))
#define GTK_IS_TEXT_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_TEXT_RENDERER))
#define GTK_TEXT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_RENDERER, GtkTextRendererClass))
#define GTK_IS_TEXT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT_RENDERER))
#define GTK_TEXT_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TEXT_RENDERER, GtkTextRendererClass))
typedef struct _GtkTextRenderer GtkTextRenderer;
typedef struct _GtkTextRendererClass GtkTextRendererClass;
enum {
NORMAL,
SELECTED,
CURSOR
};
struct _GtkTextRenderer
{
PangoRenderer parent_instance;
GtkWidget *widget;
cairo_t *cr;
GdkRGBA *error_color; /* Error underline color for this widget */
GList *widgets; /* widgets encountered when drawing */
guint state : 2;
};
struct _GtkTextRendererClass
{
PangoRendererClass parent_class;
};
GType _gtk_text_renderer_get_type (void);
G_DEFINE_TYPE (GtkTextRenderer, _gtk_text_renderer, PANGO_TYPE_RENDERER)
static void
text_renderer_set_rgba (GtkTextRenderer *text_renderer,
PangoRenderPart part,
const GdkRGBA *rgba)
{
PangoRenderer *renderer = PANGO_RENDERER (text_renderer);
PangoColor color = { 0, };
guint16 alpha;
if (rgba)
{
color.red = (guint16)(rgba->red * 65535);
color.green = (guint16)(rgba->green * 65535);
color.blue = (guint16)(rgba->blue * 65535);
alpha = (guint16)(rgba->alpha * 65535);
pango_renderer_set_color (renderer, part, &color);
pango_renderer_set_alpha (renderer, part, alpha);
}
else
{
pango_renderer_set_color (renderer, part, NULL);
pango_renderer_set_alpha (renderer, part, 0);
}
}
static GtkTextAppearance *
get_item_appearance (PangoItem *item)
{
GSList *tmp_list = item->analysis.extra_attrs;
while (tmp_list)
{
PangoAttribute *attr = tmp_list->data;
if (attr->klass->type == gtk_text_attr_appearance_type)
return &((GtkTextAttrAppearance *)attr)->appearance;
tmp_list = tmp_list->next;
}
return NULL;
}
static void
gtk_text_renderer_prepare_run (PangoRenderer *renderer,
PangoLayoutRun *run)
{
GtkStyleContext *context;
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
GdkRGBA *bg_rgba = NULL;
GdkRGBA *fg_rgba = NULL;
GtkTextAppearance *appearance;
PANGO_RENDERER_CLASS (_gtk_text_renderer_parent_class)->prepare_run (renderer, run);
appearance = get_item_appearance (run->item);
g_assert (appearance != NULL);
context = gtk_widget_get_style_context (text_renderer->widget);
if (appearance->draw_bg && text_renderer->state == NORMAL)
bg_rgba = appearance->bg_rgba;
else
bg_rgba = NULL;
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_BACKGROUND, bg_rgba);
if (text_renderer->state == SELECTED)
{
GtkCssNode *selection_node;
selection_node = gtk_text_view_get_selection_node ((GtkTextView *)text_renderer->widget);
gtk_style_context_save_to_node (context, selection_node);
gtk_style_context_get (context,
"color", &fg_rgba,
NULL);
gtk_style_context_restore (context);
}
else if (text_renderer->state == CURSOR && gtk_widget_has_focus (text_renderer->widget))
{
gtk_style_context_get (context,
"background-color", &fg_rgba,
NULL);
}
else
fg_rgba = appearance->fg_rgba;
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_FOREGROUND, fg_rgba);
if (appearance->strikethrough_rgba)
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH, appearance->strikethrough_rgba);
else
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH, fg_rgba);
if (appearance->underline_rgba)
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, appearance->underline_rgba);
else if (appearance->underline == PANGO_UNDERLINE_ERROR)
{
if (!text_renderer->error_color)
{
static const GdkRGBA red = { 1, 0, 0, 1 };
text_renderer->error_color = gdk_rgba_copy (&red);
}
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, text_renderer->error_color);
}
else
text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, fg_rgba);
if (fg_rgba != appearance->fg_rgba)
gdk_rgba_free (fg_rgba);
}
static void
set_color (GtkTextRenderer *text_renderer,
PangoRenderPart part)
{
PangoColor *color;
GdkRGBA rgba;
guint16 alpha;
cairo_save (text_renderer->cr);
color = pango_renderer_get_color (PANGO_RENDERER (text_renderer), part);
alpha = pango_renderer_get_alpha (PANGO_RENDERER (text_renderer), part);
if (color)
{
rgba.red = color->red / 65535.;
rgba.green = color->green / 65535.;
rgba.blue = color->blue / 65535.;
rgba.alpha = alpha / 65535.;
gdk_cairo_set_source_rgba (text_renderer->cr, &rgba);
}
}
static void
unset_color (GtkTextRenderer *text_renderer)
{
cairo_restore (text_renderer->cr);
}
static void
gtk_text_renderer_draw_glyphs (PangoRenderer *renderer,
PangoFont *font,
PangoGlyphString *glyphs,
int x,
int y)
{
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
set_color (text_renderer, PANGO_RENDER_PART_FOREGROUND);
cairo_move_to (text_renderer->cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
pango_cairo_show_glyph_string (text_renderer->cr, font, glyphs);
unset_color (text_renderer);
}
static void
gtk_text_renderer_draw_glyph_item (PangoRenderer *renderer,
const char *text,
PangoGlyphItem *glyph_item,
int x,
int y)
{
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
set_color (text_renderer, PANGO_RENDER_PART_FOREGROUND);
cairo_move_to (text_renderer->cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
pango_cairo_show_glyph_item (text_renderer->cr, text, glyph_item);
unset_color (text_renderer);
}
static void
gtk_text_renderer_draw_rectangle (PangoRenderer *renderer,
PangoRenderPart part,
int x,
int y,
int width,
int height)
{
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
set_color (text_renderer, part);
cairo_rectangle (text_renderer->cr,
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
cairo_fill (text_renderer->cr);
unset_color (text_renderer);
}
static void
gtk_text_renderer_draw_trapezoid (PangoRenderer *renderer,
PangoRenderPart part,
double y1_,
double x11,
double x21,
double y2,
double x12,
double x22)
{
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
cairo_t *cr;
cairo_matrix_t matrix;
set_color (text_renderer, part);
cr = text_renderer->cr;
cairo_get_matrix (cr, &matrix);
matrix.xx = matrix.yy = 1.0;
matrix.xy = matrix.yx = 0.0;
cairo_set_matrix (cr, &matrix);
cairo_move_to (cr, x11, y1_);
cairo_line_to (cr, x21, y1_);
cairo_line_to (cr, x22, y2);
cairo_line_to (cr, x12, y2);
cairo_close_path (cr);
cairo_fill (cr);
unset_color (text_renderer);
}
static void
gtk_text_renderer_draw_error_underline (PangoRenderer *renderer,
int x,
int y,
int width,
int height)
{
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
set_color (text_renderer, PANGO_RENDER_PART_UNDERLINE);
pango_cairo_show_error_underline (text_renderer->cr,
(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
unset_color (text_renderer);
}
static void
gtk_text_renderer_draw_shape (PangoRenderer *renderer,
PangoAttrShape *attr,
int x,
int y)
{
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
if (attr->data == NULL)
{
/* This happens if we have an empty widget anchor. Draw
* something empty-looking.
*/
GdkRectangle shape_rect;
cairo_t *cr;
shape_rect.x = PANGO_PIXELS (x);
shape_rect.y = PANGO_PIXELS (y + attr->logical_rect.y);
shape_rect.width = PANGO_PIXELS (x + attr->logical_rect.width) - shape_rect.x;
shape_rect.height = PANGO_PIXELS (y + attr->logical_rect.y + attr->logical_rect.height) - shape_rect.y;
set_color (text_renderer, PANGO_RENDER_PART_FOREGROUND);
cr = text_renderer->cr;
cairo_set_line_width (cr, 1.0);
cairo_rectangle (cr,
shape_rect.x + 0.5, shape_rect.y + 0.5,
shape_rect.width - 1, shape_rect.height - 1);
cairo_move_to (cr, shape_rect.x + 0.5, shape_rect.y + 0.5);
cairo_line_to (cr,
shape_rect.x + shape_rect.width - 0.5,
shape_rect.y + shape_rect.height - 0.5);
cairo_move_to (cr, shape_rect.x + 0.5,
shape_rect.y + shape_rect.height - 0.5);
cairo_line_to (cr, shape_rect.x + shape_rect.width - 0.5,
shape_rect.y + 0.5);
cairo_stroke (cr);
unset_color (text_renderer);
}
else if (GDK_IS_TEXTURE (attr->data))
{
cairo_t *cr = text_renderer->cr;
GdkTexture *texture = GDK_TEXTURE (attr->data);
cairo_surface_t *surface;
surface = gdk_texture_download_surface (texture);
cairo_save (cr);
cairo_set_source_surface (cr, surface,
PANGO_PIXELS (x),
PANGO_PIXELS (y) - gdk_texture_get_height (texture));
cairo_paint (cr);
cairo_restore (cr);
cairo_surface_destroy (surface);
}
else if (GTK_IS_WIDGET (attr->data))
{
GtkWidget *widget;
widget = GTK_WIDGET (attr->data);
text_renderer->widgets = g_list_prepend (text_renderer->widgets,
g_object_ref (widget));
}
else
g_assert_not_reached (); /* not a texture or widget */
}
static void
gtk_text_renderer_finalize (GObject *object)
{
G_OBJECT_CLASS (_gtk_text_renderer_parent_class)->finalize (object);
}
static void
_gtk_text_renderer_init (GtkTextRenderer *renderer)
{
}
static void
_gtk_text_renderer_class_init (GtkTextRendererClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
renderer_class->prepare_run = gtk_text_renderer_prepare_run;
renderer_class->draw_glyphs = gtk_text_renderer_draw_glyphs;
renderer_class->draw_glyph_item = gtk_text_renderer_draw_glyph_item;
renderer_class->draw_rectangle = gtk_text_renderer_draw_rectangle;
renderer_class->draw_trapezoid = gtk_text_renderer_draw_trapezoid;
renderer_class->draw_error_underline = gtk_text_renderer_draw_error_underline;
renderer_class->draw_shape = gtk_text_renderer_draw_shape;
object_class->finalize = gtk_text_renderer_finalize;
}
static void
text_renderer_set_state (GtkTextRenderer *text_renderer,
int state)
{
text_renderer->state = state;
}
static void
text_renderer_begin (GtkTextRenderer *text_renderer,
GtkWidget *widget,
cairo_t *cr)
{
GtkStyleContext *context;
GdkRGBA color;
GtkCssNode *text_node;
text_renderer->widget = widget;
text_renderer->cr = cr;
context = gtk_widget_get_style_context (widget);
text_node = gtk_text_view_get_text_node ((GtkTextView *)widget);
gtk_style_context_save_to_node (context, text_node);
gtk_style_context_get_color (context, &color);
cairo_save (cr);
gdk_cairo_set_source_rgba (cr, &color);
}
/* Returns a GSList of (referenced) widgets encountered while drawing.
*/
static void
text_renderer_end (GtkTextRenderer *text_renderer)
{
GtkStyleContext *context;
cairo_restore (text_renderer->cr);
context = gtk_widget_get_style_context (text_renderer->widget);
gtk_style_context_restore (context);
text_renderer->widget = NULL;
text_renderer->cr = NULL;
if (text_renderer->error_color)
{
gdk_rgba_free (text_renderer->error_color);
text_renderer->error_color = NULL;
}
}
static cairo_region_t *
get_selected_clip (GtkTextRenderer *text_renderer,
PangoLayout *layout,
PangoLayoutLine *line,
int x,
int y,
int height,
int start_index,
int end_index)
{
gint *ranges;
gint n_ranges, i;
cairo_region_t *clip_region = cairo_region_create ();
pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
for (i=0; i < n_ranges; i++)
{
GdkRectangle rect;
rect.x = x + PANGO_PIXELS (ranges[2*i]);
rect.y = y;
rect.width = PANGO_PIXELS (ranges[2*i + 1]) - PANGO_PIXELS (ranges[2*i]);
rect.height = height;
cairo_region_union_rectangle (clip_region, &rect);
}
g_free (ranges);
return clip_region;
}
static void
render_para (GtkTextRenderer *text_renderer,
GtkTextLineDisplay *line_display,
int selection_start_index,
int selection_end_index)
{
GtkStyleContext *context;
PangoLayout *layout = line_display->layout;
int byte_offset = 0;
PangoLayoutIter *iter;
int screen_width;
GdkRGBA *selection;
gboolean first = TRUE;
GtkCssNode *selection_node;
iter = pango_layout_get_iter (layout);
screen_width = line_display->total_width;
context = gtk_widget_get_style_context (text_renderer->widget);
selection_node = gtk_text_view_get_selection_node ((GtkTextView*)text_renderer->widget);
gtk_style_context_save_to_node (context, selection_node);
gtk_style_context_get (context, "background-color", &selection, NULL);
gtk_style_context_restore (context);
do
{
PangoLayoutLine *line = pango_layout_iter_get_line_readonly (iter);
int selection_y, selection_height;
int first_y, last_y;
PangoRectangle line_rect;
int baseline;
gboolean at_last_line;
pango_layout_iter_get_line_extents (iter, NULL, &line_rect);
baseline = pango_layout_iter_get_baseline (iter);
pango_layout_iter_get_line_yrange (iter, &first_y, &last_y);
/* Adjust for margins */
line_rect.x += line_display->x_offset * PANGO_SCALE;
line_rect.y += line_display->top_margin * PANGO_SCALE;
baseline += line_display->top_margin * PANGO_SCALE;
/* Selection is the height of the line, plus top/bottom
* margin if we're the first/last line
*/
selection_y = PANGO_PIXELS (first_y) + line_display->top_margin;
selection_height = PANGO_PIXELS (last_y) - PANGO_PIXELS (first_y);
if (first)
{
selection_y -= line_display->top_margin;
selection_height += line_display->top_margin;
}
at_last_line = pango_layout_iter_at_last_line (iter);
if (at_last_line)
selection_height += line_display->bottom_margin;
first = FALSE;
if (selection_start_index < byte_offset &&
selection_end_index > line->length + byte_offset) /* All selected */
{
cairo_t *cr = text_renderer->cr;
cairo_save (cr);
gdk_cairo_set_source_rgba (cr, selection);
cairo_rectangle (cr,
line_display->left_margin, selection_y,
screen_width, selection_height);
cairo_fill (cr);
cairo_restore(cr);
text_renderer_set_state (text_renderer, SELECTED);
pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer),
line,
line_rect.x,
baseline);
}
else
{
if (line_display->pg_bg_rgba)
{
cairo_t *cr = text_renderer->cr;
cairo_save (cr);
gdk_cairo_set_source_rgba (text_renderer->cr, line_display->pg_bg_rgba);
cairo_rectangle (cr,
line_display->left_margin, selection_y,
screen_width, selection_height);
cairo_fill (cr);
cairo_restore (cr);
}
text_renderer_set_state (text_renderer, NORMAL);
pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer),
line,
line_rect.x,
baseline);
/* Check if some part of the line is selected; the newline
* that is after line->length for the last line of the
* paragraph counts as part of the line for this
*/
if ((selection_start_index < byte_offset + line->length ||
(selection_start_index == byte_offset + line->length && pango_layout_iter_at_last_line (iter))) &&
selection_end_index > byte_offset)
{
cairo_t *cr = text_renderer->cr;
cairo_region_t *clip_region = get_selected_clip (text_renderer, layout, line,
line_display->x_offset,
selection_y,
selection_height,
selection_start_index, selection_end_index);
cairo_save (cr);
gdk_cairo_region (cr, clip_region);
cairo_clip (cr);
cairo_region_destroy (clip_region);
gdk_cairo_set_source_rgba (cr, selection);
cairo_rectangle (cr,
PANGO_PIXELS (line_rect.x),
selection_y,
PANGO_PIXELS (line_rect.width),
selection_height);
cairo_fill (cr);
text_renderer_set_state (text_renderer, SELECTED);
pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer),
line,
line_rect.x,
baseline);
cairo_restore (cr);
/* Paint in the ends of the line */
if (line_rect.x > line_display->left_margin * PANGO_SCALE &&
((line_display->direction == GTK_TEXT_DIR_LTR && selection_start_index < byte_offset) ||
(line_display->direction == GTK_TEXT_DIR_RTL && selection_end_index > byte_offset + line->length)))
{
cairo_save (cr);
gdk_cairo_set_source_rgba (cr, selection);
cairo_rectangle (cr,
line_display->left_margin,
selection_y,
PANGO_PIXELS (line_rect.x) - line_display->left_margin,
selection_height);
cairo_fill (cr);
cairo_restore (cr);
}
if (line_rect.x + line_rect.width <
(screen_width + line_display->left_margin) * PANGO_SCALE &&
((line_display->direction == GTK_TEXT_DIR_LTR && selection_end_index > byte_offset + line->length) ||
(line_display->direction == GTK_TEXT_DIR_RTL && selection_start_index < byte_offset)))
{
int nonlayout_width;
nonlayout_width =
line_display->left_margin + screen_width -
PANGO_PIXELS (line_rect.x) - PANGO_PIXELS (line_rect.width);
cairo_save (cr);
gdk_cairo_set_source_rgba (cr, selection);
cairo_rectangle (cr,
PANGO_PIXELS (line_rect.x) + PANGO_PIXELS (line_rect.width),
selection_y,
nonlayout_width,
selection_height);
cairo_fill (cr);
cairo_restore (cr);
}
}
else if (line_display->has_block_cursor &&
gtk_widget_has_focus (text_renderer->widget) &&
byte_offset <= line_display->insert_index &&
(line_display->insert_index < byte_offset + line->length ||
(at_last_line && line_display->insert_index == byte_offset + line->length)))
{
GdkRectangle cursor_rect;
GdkRGBA cursor_color;
cairo_t *cr = text_renderer->cr;
/* we draw text using base color on filled cursor rectangle of cursor color
* (normally white on black) */
_gtk_style_context_get_cursor_color (context, &cursor_color, NULL);
cursor_rect.x = line_display->x_offset + line_display->block_cursor.x;
cursor_rect.y = line_display->block_cursor.y + line_display->top_margin;
cursor_rect.width = line_display->block_cursor.width;
cursor_rect.height = line_display->block_cursor.height;
cairo_save (cr);
gdk_cairo_rectangle (cr, &cursor_rect);
cairo_clip (cr);
gdk_cairo_set_source_rgba (cr, &cursor_color);
cairo_paint (cr);
/* draw text under the cursor if any */
if (!line_display->cursor_at_line_end)
{
GdkRGBA *color;
gtk_style_context_get (context, "background-color", &color, NULL);
gdk_cairo_set_source_rgba (cr, color);
text_renderer_set_state (text_renderer, CURSOR);
pango_renderer_draw_layout_line (PANGO_RENDERER (text_renderer),
line,
line_rect.x,
baseline);
gdk_rgba_free (color);
}
cairo_restore (cr);
}
}
byte_offset += line->length;
}
while (pango_layout_iter_next_line (iter));
gdk_rgba_free (selection);
pango_layout_iter_free (iter);
}
static GtkTextRenderer *
get_text_renderer (void)
{
static GtkTextRenderer *text_renderer = NULL;
if (!text_renderer)
text_renderer = g_object_new (GTK_TYPE_TEXT_RENDERER, NULL);
return text_renderer;
}
void
gtk_text_layout_snapshot (GtkTextLayout *layout,
GtkWidget *widget,
GtkSnapshot *snapshot,
const GdkRectangle *clip)
{
GtkStyleContext *context;
gint offset_y;
GtkTextRenderer *text_renderer;
GtkTextIter selection_start, selection_end;
gboolean have_selection;
GSList *line_list;
GSList *tmp_list;
cairo_t *cr;
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
g_return_if_fail (layout->default_style != NULL);
g_return_if_fail (layout->buffer != NULL);
g_return_if_fail (snapshot != NULL);
context = gtk_widget_get_style_context (widget);
line_list = gtk_text_layout_get_lines (layout, clip->y, clip->y + clip->height, &offset_y);
if (line_list == NULL)
return; /* nothing on the screen */
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT(clip->x, clip->y, clip->width, clip->height));
text_renderer = get_text_renderer ();
text_renderer_begin (text_renderer, widget, cr);
/* text_renderer_begin/end does cairo_save/restore */
cairo_translate (cr, 0, offset_y);
gtk_text_layout_wrap_loop_start (layout);
have_selection = gtk_text_buffer_get_selection_bounds (layout->buffer,
&selection_start,
&selection_end);
tmp_list = line_list;
while (tmp_list != NULL)
{
GtkTextLineDisplay *line_display;
gint selection_start_index = -1;
gint selection_end_index = -1;
GtkTextLine *line = tmp_list->data;
line_display = gtk_text_layout_get_line_display (layout, line, FALSE);
if (line_display->height > 0)
{
g_assert (line_display->layout != NULL);
if (have_selection)
{
GtkTextIter line_start, line_end;
gint byte_count;
gtk_text_layout_get_iter_at_line (layout,
&line_start,
line, 0);
line_end = line_start;
if (!gtk_text_iter_ends_line (&line_end))
gtk_text_iter_forward_to_line_end (&line_end);
byte_count = gtk_text_iter_get_visible_line_index (&line_end);
if (gtk_text_iter_compare (&selection_start, &line_end) <= 0 &&
gtk_text_iter_compare (&selection_end, &line_start) >= 0)
{
if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
selection_start_index = gtk_text_iter_get_visible_line_index (&selection_start);
else
selection_start_index = -1;
if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
selection_end_index = gtk_text_iter_get_visible_line_index (&selection_end);
else
selection_end_index = byte_count + 1; /* + 1 to flag past-the-end */
}
}
render_para (text_renderer, line_display,
selection_start_index, selection_end_index);
/* We paint the cursors last, because they overlap another chunk
* and need to appear on top.
*/
if (line_display->cursors != NULL)
{
int i;
for (i = 0; i < line_display->cursors->len; i++)
{
int index;
PangoDirection dir;
index = g_array_index(line_display->cursors, int, i);
dir = (line_display->direction == GTK_TEXT_DIR_RTL) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
gtk_render_insertion_cursor (context, cr,
line_display->x_offset, line_display->top_margin,
line_display->layout, index, dir);
}
}
} /* line_display->height > 0 */
cairo_translate (cr, 0, line_display->height);
gtk_text_layout_free_line_display (layout, line_display);
tmp_list = tmp_list->next;
}
gtk_text_layout_wrap_loop_end (layout);
text_renderer_end (text_renderer);
g_slist_free (line_list);
cairo_destroy (cr);
}
-101
View File
@@ -1,101 +0,0 @@
/* gtktextdisplay.c - display layed-out text
*
* Copyright (c) 1992-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 2000 Red Hat, Inc.
* Tk->Gtk port by Havoc Pennington
*
* This file can be used under your choice of two licenses, the LGPL
* and the original Tk license.
*
* LGPL:
*
* 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/>.
*
* Original Tk license:
*
* This software is copyrighted by the Regents of the University of
* California, Sun Microsystems, Inc., and other parties. The
* following terms apply to all files associated with the software
* unless explicitly disclaimed in individual files.
*
* The authors hereby grant permission to use, copy, modify,
* distribute, and license this software and its documentation for any
* purpose, provided that existing copyright notices are retained in
* all copies and that this notice is included verbatim in any
* distributions. No written agreement, license, or royalty fee is
* required for any of the authorized uses. Modifications to this
* software may be copyrighted by their authors and need not follow
* the licensing terms described here, provided that the new terms are
* clearly indicated on the first page of each file where they apply.
*
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
* DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
* OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
* NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
* AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* GOVERNMENT USE: If you are acquiring this software on behalf of the
* U.S. government, the Government shall have only "Restricted Rights"
* in the software and related documentation as defined in the Federal
* Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
* are acquiring the software on behalf of the Department of Defense,
* the software shall be classified as "Commercial Computer Software"
* and the Government shall have only "Restricted Rights" as defined
* in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
* foregoing, the authors grant the U.S. Government and others acting
* in its behalf permission to use and distribute the software in
* accordance with the terms specified in this license.
*
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_TEXT_DISPLAY_PRIVATE_H__
#define __GTK_TEXT_DISPLAY_PRIVATE_H__
#include "gtktextlayoutprivate.h"
G_BEGIN_DECLS
/* A semi-public header intended for use by code that also
* uses GtkTextLayout
*/
/* The drawable should be pre-initialized to your preferred background.
* widget - Widget to grab some style info from
* snapshot - Snapshot to render to, matrix set so that (0, 0)
* is the top left of the layout
* clip - visible area
*/
void gtk_text_layout_snapshot (GtkTextLayout *layout,
GtkWidget *widget,
GtkSnapshot *snapshot,
const GdkRectangle *clip);
G_END_DECLS
#endif /* __GTK_TEXT_DISPLAY_PRIVATE_H__ */
+19
View File
@@ -5358,6 +5358,25 @@ gtk_text_iter_equal (const GtkTextIter *lhs,
}
}
gboolean
_gtk_text_iter_same_line (const GtkTextIter *lhs,
const GtkTextIter *rhs)
{
GtkTextRealIter *real_lhs;
GtkTextRealIter *real_rhs;
real_lhs = gtk_text_iter_make_surreal (lhs);
real_rhs = gtk_text_iter_make_surreal (rhs);
if (real_lhs == NULL || real_rhs == NULL)
return FALSE;
check_invariants (lhs);
check_invariants (rhs);
return real_lhs->line == real_rhs->line;
}
/**
* gtk_text_iter_compare:
* @lhs: a #GtkTextIter
+2
View File
@@ -41,6 +41,8 @@ gboolean _gtk_text_iter_forward_indexable_segment (GtkTextIter
gboolean _gtk_text_iter_backward_indexable_segment (GtkTextIter *iter);
gint _gtk_text_iter_get_segment_byte (const GtkTextIter *iter);
gint _gtk_text_iter_get_segment_char (const GtkTextIter *iter);
gboolean _gtk_text_iter_same_line (const GtkTextIter *lhs,
const GtkTextIter *rhs);
gboolean gtk_text_iter_get_attributes (const GtkTextIter *iter,
GtkTextAttributes *values);
+686 -264
View File
File diff suppressed because it is too large Load Diff
+27 -77
View File
@@ -138,11 +138,6 @@ struct _GtkTextLayout
* over long runs with the same style. */
GtkTextAttributes *one_style_cache;
/* A cache of one line display. Getting the same line
* many times in a row is the most common case.
*/
GtkTextLineDisplay *one_display_cache;
/* Whether we are allowed to wrap right now */
gint wrap_loop_count;
@@ -223,6 +218,12 @@ struct _GtkTextLineDisplay
PangoLayout *layout;
GArray *cursors; /* indexes of cursors in the PangoLayout */
/* GSequenceIter backpointer for use within cache */
GSequenceIter *cache_iter;
/* GQueue link for use in MRU to help cull cache */
GList mru_link;
GtkTextDirection direction;
gint width; /* Width of layout */
@@ -246,224 +247,173 @@ struct _GtkTextLineDisplay
guint cursor_at_line_end : 1;
guint size_only : 1;
GdkRGBA *pg_bg_rgba;
GdkRGBA pg_bg_rgba;
guint pg_bg_rgba_set : 1;
};
#ifdef GTK_COMPILATION
extern G_GNUC_INTERNAL PangoAttrType gtk_text_attr_appearance_type;
#endif
GDK_AVAILABLE_IN_ALL
GType gtk_text_layout_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkTextLayout* gtk_text_layout_new (void);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_buffer (GtkTextLayout *layout,
GtkTextBuffer *buffer);
GDK_AVAILABLE_IN_ALL
GtkTextBuffer *gtk_text_layout_get_buffer (GtkTextLayout *layout);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_default_style (GtkTextLayout *layout,
GtkTextAttributes *values);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_contexts (GtkTextLayout *layout,
PangoContext *ltr_context,
PangoContext *rtl_context);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_cursor_direction (GtkTextLayout *layout,
GtkTextDirection direction);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_overwrite_mode (GtkTextLayout *layout,
gboolean overwrite);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_keyboard_direction (GtkTextLayout *layout,
GtkTextDirection keyboard_dir);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_default_style_changed (GtkTextLayout *layout);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_screen_width (GtkTextLayout *layout,
gint width);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_preedit_string (GtkTextLayout *layout,
const gchar *preedit_string,
PangoAttrList *preedit_attrs,
gint cursor_pos);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
gboolean cursor_visible);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_get_cursor_visible (GtkTextLayout *layout);
/* Getting the size or the lines potentially results in a call to
* recompute, which is pretty massively expensive. Thus it should
* basically only be done in an idle handler.
*
* Long-term, we would really like to be able to do these without
* a full recompute so they may get cheaper over time.
*/
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_get_size (GtkTextLayout *layout,
gint *width,
gint *height);
GDK_AVAILABLE_IN_ALL
GSList* gtk_text_layout_get_lines (GtkTextLayout *layout,
/* [top_y, bottom_y) */
gint top_y,
gint bottom_y,
gint *first_line_y);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_wrap_loop_start (GtkTextLayout *layout);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_wrap_loop_end (GtkTextLayout *layout);
GDK_AVAILABLE_IN_ALL
GtkTextLineDisplay* gtk_text_layout_get_line_display (GtkTextLayout *layout,
GtkTextLine *line,
gboolean size_only);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_free_line_display (GtkTextLayout *layout,
GtkTextLineDisplay *display);
GDK_AVAILABLE_IN_ALL
GtkTextLineDisplay *gtk_text_line_display_ref (GtkTextLineDisplay *display);
void gtk_text_line_display_unref (GtkTextLineDisplay *display);
gint gtk_text_line_display_compare (const GtkTextLineDisplay *display1,
const GtkTextLineDisplay *display2,
GtkTextLayout *layout);
void gtk_text_layout_get_line_at_y (GtkTextLayout *layout,
GtkTextIter *target_iter,
gint y,
gint *line_top);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_get_iter_at_pixel (GtkTextLayout *layout,
GtkTextIter *iter,
gint x,
gint y);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_get_iter_at_position (GtkTextLayout *layout,
GtkTextIter *iter,
gint *trailing,
gint x,
gint y);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_invalidate (GtkTextLayout *layout,
const GtkTextIter *start,
const GtkTextIter *end);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_invalidate_cursors(GtkTextLayout *layout,
const GtkTextIter *start,
const GtkTextIter *end);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_free_line_data (GtkTextLayout *layout,
GtkTextLine *line,
GtkTextLineData *line_data);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_is_valid (GtkTextLayout *layout);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_validate_yrange (GtkTextLayout *layout,
GtkTextIter *anchor_line,
gint y0_,
gint y1_);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_validate (GtkTextLayout *layout,
gint max_pixels);
/* This function should return the passed-in line data,
* OR remove the existing line data from the line, and
* return a NEW line data after adding it to the line.
* That is, invariant after calling the callback is that
* there should be exactly one line data for this view
* stored on the btree line.
*/
GDK_AVAILABLE_IN_ALL
GtkTextLineData* gtk_text_layout_wrap (GtkTextLayout *layout,
GtkTextLine *line,
GtkTextLineData *line_data); /* may be NULL */
GDK_AVAILABLE_IN_ALL
GtkTextLineData *line_data);
void gtk_text_layout_changed (GtkTextLayout *layout,
gint y,
gint old_height,
gint new_height);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_cursors_changed (GtkTextLayout *layout,
gint y,
gint old_height,
gint new_height);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_get_iter_location (GtkTextLayout *layout,
const GtkTextIter *iter,
GdkRectangle *rect);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_get_line_yrange (GtkTextLayout *layout,
const GtkTextIter *iter,
gint *y,
gint *height);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_get_cursor_locations (GtkTextLayout *layout,
GtkTextIter *iter,
GdkRectangle *strong_pos,
GdkRectangle *weak_pos);
GtkTextLineDisplay *gtk_text_layout_create_display (GtkTextLayout *layout,
GtkTextLine *line,
gboolean size_only);
void gtk_text_layout_update_display_cursors (GtkTextLayout *layout,
GtkTextLine *line,
GtkTextLineDisplay *display);
gboolean _gtk_text_layout_get_block_cursor (GtkTextLayout *layout,
GdkRectangle *pos);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_clamp_iter_to_vrange (GtkTextLayout *layout,
GtkTextIter *iter,
gint top,
gint bottom);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
GtkTextIter *iter,
gint direction);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
GtkTextIter *iter);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
GtkTextIter *iter);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
GtkTextIter *iter,
gint x);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
GtkTextIter *iter,
gint count);
GDK_AVAILABLE_IN_ALL
gboolean gtk_text_layout_iter_starts_line (GtkTextLayout *layout,
const GtkTextIter *iter);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_get_iter_at_line (GtkTextLayout *layout,
GtkTextIter *iter,
GtkTextLine *line,
gint byte_offset);
/* Don't use these. Use gtk_text_view_add_child_at_anchor().
* These functions are defined in gtktextchild.c, but here
* since they are semi-public and require GtkTextLayout to
* be declared.
*/
GDK_AVAILABLE_IN_ALL
void gtk_text_child_anchor_register_child (GtkTextChildAnchor *anchor,
GtkWidget *child,
GtkTextLayout *layout);
GDK_AVAILABLE_IN_ALL
void gtk_text_child_anchor_unregister_child (GtkTextChildAnchor *anchor,
GtkWidget *child);
GDK_AVAILABLE_IN_ALL
void gtk_text_child_anchor_queue_resize (GtkTextChildAnchor *anchor,
GtkTextLayout *layout);
GDK_AVAILABLE_IN_ALL
void gtk_text_anchored_child_set_layout (GtkWidget *child,
GtkTextLayout *layout);
GDK_AVAILABLE_IN_ALL
void gtk_text_layout_spew (GtkTextLayout *layout);
void gtk_text_layout_snapshot (GtkTextLayout *layout,
GtkWidget *widget,
GtkSnapshot *snapshot,
const GdkRectangle *clip,
float cursor_alpha);
G_END_DECLS
#endif /* __GTK_TEXT_LAYOUT_PRIVATE_H__ */
+716
View File
@@ -0,0 +1,716 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* Copyright (C) 2019 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 "gtktextbtree.h"
#include "gtktextbufferprivate.h"
#include "gtktextiterprivate.h"
#include "gtktextlinedisplaycacheprivate.h"
#define MRU_MAX_SIZE 250
#define BLOW_CACHE_TIMEOUT_SEC 20
#define DEBUG_LINE_DISPLAY_CACHE 0
struct _GtkTextLineDisplayCache
{
GSequence *sorted_by_line;
GHashTable *line_to_display;
GtkTextLine *cursor_line;
GQueue mru;
GSource *evict_source;
#if DEBUG_LINE_DISPLAY_CACHE
guint log_source;
gint hits;
gint misses;
gint inval;
gint inval_cursors;
gint inval_by_line;
gint inval_by_range;
gint inval_by_y_range;
#endif
};
#if DEBUG_LINE_DISPLAY_CACHE
# define STAT_ADD(val,n) ((val) += n)
# define STAT_INC(val) STAT_ADD(val,1)
static gboolean
dump_stats (gpointer data)
{
GtkTextLineDisplayCache *cache = data;
g_printerr ("%p: size=%u hits=%d misses=%d inval_total=%d "
"inval_cursors=%d inval_by_line=%d "
"inval_by_range=%d inval_by_y_range=%d\n",
cache, g_hash_table_size (cache->line_to_display),
cache->hits, cache->misses,
cache->inval, cache->inval_cursors,
cache->inval_by_line, cache->inval_by_range,
cache->inval_by_y_range);
return G_SOURCE_CONTINUE;
}
#else
# define STAT_ADD(val,n)
# define STAT_INC(val)
#endif
GtkTextLineDisplayCache *
gtk_text_line_display_cache_new (void)
{
GtkTextLineDisplayCache *ret;
ret = g_slice_new0 (GtkTextLineDisplayCache);
ret->sorted_by_line = g_sequence_new ((GDestroyNotify)gtk_text_line_display_unref);
ret->line_to_display = g_hash_table_new (NULL, NULL);
#if DEBUG_LINE_DISPLAY_CACHE
ret->log_source = g_timeout_add_seconds (1, dump_stats, ret);
#endif
return g_steal_pointer (&ret);
}
void
gtk_text_line_display_cache_free (GtkTextLineDisplayCache *cache)
{
#if DEBUG_LINE_DISPLAY_CACHE
g_clear_handle_id (&cache->log_source, g_source_remove);
#endif
g_clear_pointer (&cache->evict_source, g_source_destroy);
g_clear_pointer (&cache->sorted_by_line, g_sequence_free);
g_clear_pointer (&cache->line_to_display, g_hash_table_unref);
g_slice_free (GtkTextLineDisplayCache, cache);
}
static gboolean
gtk_text_line_display_cache_blow_cb (gpointer data)
{
GtkTextLineDisplayCache *cache = data;
g_assert (cache != NULL);
#if DEBUG_LINE_DISPLAY_CACHE
g_printerr ("Evicting GtkTextLineDisplayCache\n");
#endif
cache->evict_source = NULL;
gtk_text_line_display_cache_invalidate (cache);
return G_SOURCE_REMOVE;
}
void
gtk_text_line_display_cache_delay_eviction (GtkTextLineDisplayCache *cache)
{
g_assert (cache != NULL);
if (cache->evict_source != NULL)
{
gint64 deadline;
deadline = g_get_monotonic_time () + (BLOW_CACHE_TIMEOUT_SEC * G_USEC_PER_SEC);
g_source_set_ready_time (cache->evict_source, deadline);
}
else
{
guint tag;
tag = g_timeout_add_seconds (BLOW_CACHE_TIMEOUT_SEC,
gtk_text_line_display_cache_blow_cb,
cache);
cache->evict_source = g_main_context_find_source_by_id (NULL, tag);
g_source_set_name (cache->evict_source, "[gtk+] gtk_text_line_display_cache_blow_cb");
}
}
#if DEBUG_LINE_DISPLAY_CACHE
static void
check_disposition (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout)
{
GSequenceIter *iter;
gint last = G_MAXUINT;
g_assert (cache != NULL);
g_assert (cache->sorted_by_line != NULL);
g_assert (cache->line_to_display != NULL);
for (iter = g_sequence_get_begin_iter (cache->sorted_by_line);
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
GtkTextLineDisplay *display = g_sequence_get (iter);
GtkTextIter text_iter;
guint line;
gtk_text_layout_get_iter_at_line (layout, &text_iter, display->line, 0);
line = gtk_text_iter_get_line (&text_iter);
g_assert_cmpint (line, >, last);
last = line;
}
}
#endif
static void
gtk_text_line_display_cache_take_display (GtkTextLineDisplayCache *cache,
GtkTextLineDisplay *display,
GtkTextLayout *layout)
{
g_assert (cache != NULL);
g_assert (display != NULL);
g_assert (display->line != NULL);
g_assert (display->cache_iter == NULL);
g_assert (display->mru_link.data == display);
g_assert (display->mru_link.prev == NULL);
g_assert (display->mru_link.next == NULL);
g_assert (g_hash_table_lookup (cache->line_to_display, display->line) == NULL);
#if DEBUG_LINE_DISPLAY_CACHE
check_disposition (cache, layout);
#endif
display->cache_iter =
g_sequence_insert_sorted (cache->sorted_by_line,
display,
(GCompareDataFunc) gtk_text_line_display_compare,
layout);
g_hash_table_insert (cache->line_to_display, display->line, display);
g_queue_push_head_link (&cache->mru, &display->mru_link);
/* Cull the cache if we're at capacity */
while (cache->mru.length > MRU_MAX_SIZE)
{
display = g_queue_peek_tail (&cache->mru);
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
}
}
/*
* gtk_text_line_display_cache_invalidate_display:
* @cache: a GtkTextLineDisplayCache
* @display: a GtkTextLineDisplay
* @cursors_only: if only the cursor positions should be invalidated
*
* If @cursors_only is TRUE, then only the cursors are invalidated. Otherwise,
* @display is removed from the cache.
*
* Use this function when you already have access to a display as it reduces
* some overhead.
*/
void
gtk_text_line_display_cache_invalidate_display (GtkTextLineDisplayCache *cache,
GtkTextLineDisplay *display,
gboolean cursors_only)
{
g_assert (cache != NULL);
g_assert (display != NULL);
g_assert (display->line != NULL);
if (cursors_only)
{
g_clear_pointer (&display->cursors, g_array_unref);
display->cursors_invalid = TRUE;
display->has_block_cursor = FALSE;
}
else
{
GSequenceIter *iter = g_steal_pointer (&display->cache_iter);
if (cache->cursor_line == display->line)
cache->cursor_line = NULL;
g_hash_table_remove (cache->line_to_display, display->line);
g_queue_unlink (&cache->mru, &display->mru_link);
if (iter != NULL)
g_sequence_remove (iter);
}
STAT_INC (cache->inval);
}
/*
* gtk_text_line_display_cache_get:
* @cache: a #GtkTextLineDisplayCache
* @layout: a GtkTextLayout
* @line: a GtkTextLine
* @size_only: if only line sizing is needed
*
* Gets a GtkTextLineDisplay for @line.
*
* If no cached display exists, a new display will be created.
*
* It's possible that calling this function will cause some existing
* cached displays to be released and destroyed.
*
* Returns: (transfer full) (not nullable): a #GtkTextLineDisplay
*/
GtkTextLineDisplay *
gtk_text_line_display_cache_get (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout,
GtkTextLine *line,
gboolean size_only)
{
GtkTextLineDisplay *display;
g_assert (cache != NULL);
g_assert (layout != NULL);
g_assert (line != NULL);
display = g_hash_table_lookup (cache->line_to_display, line);
if (display != NULL)
{
if (size_only || !display->size_only)
{
STAT_INC (cache->hits);
if (!size_only && display->line == cache->cursor_line)
gtk_text_layout_update_display_cursors (layout, display->line, display);
/* Move to front of MRU */
g_queue_unlink (&cache->mru, &display->mru_link);
g_queue_push_head_link (&cache->mru, &display->mru_link);
return gtk_text_line_display_ref (display);
}
/* We need an updated display that includes more than just
* sizing, so we need to drop this entry and force the layout
* to create a new one.
*/
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
}
STAT_INC (cache->misses);
g_assert (!g_hash_table_lookup (cache->line_to_display, line));
display = gtk_text_layout_create_display (layout, line, size_only);
g_assert (display != NULL);
g_assert (display->line == line);
if (!size_only)
{
if (line == cache->cursor_line)
gtk_text_layout_update_display_cursors (layout, line, display);
gtk_text_line_display_cache_take_display (cache,
gtk_text_line_display_ref (display),
layout);
}
return g_steal_pointer (&display);
}
void
gtk_text_line_display_cache_invalidate (GtkTextLineDisplayCache *cache)
{
g_assert (cache != NULL);
g_assert (cache->sorted_by_line != NULL);
g_assert (cache->line_to_display != NULL);
STAT_ADD (cache->inval, g_hash_table_size (cache->line_to_display));
cache->cursor_line = NULL;
while (cache->mru.head != NULL)
{
GtkTextLineDisplay *display = g_queue_peek_head (&cache->mru);
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
}
g_assert (g_hash_table_size (cache->line_to_display) == 0);
g_assert (g_sequence_get_length (cache->sorted_by_line) == 0);
g_assert (cache->mru.length == 0);
}
void
gtk_text_line_display_cache_invalidate_cursors (GtkTextLineDisplayCache *cache,
GtkTextLine *line)
{
GtkTextLineDisplay *display;
g_assert (cache != NULL);
g_assert (line != NULL);
STAT_INC (cache->inval_cursors);
display = g_hash_table_lookup (cache->line_to_display, line);
if (display != NULL)
gtk_text_line_display_cache_invalidate_display (cache, display, TRUE);
}
/*
* gtk_text_line_display_cache_invalidate_line:
* @self: a GtkTextLineDisplayCache
* @line: a GtkTextLine
*
* Removes a cached display for @line.
*
* Compare to gtk_text_line_display_cache_invalidate_cursors() which
* only invalidates the cursors for this row.
*/
void
gtk_text_line_display_cache_invalidate_line (GtkTextLineDisplayCache *cache,
GtkTextLine *line)
{
GtkTextLineDisplay *display;
g_assert (cache != NULL);
g_assert (line != NULL);
display = g_hash_table_lookup (cache->line_to_display, line);
if (display != NULL)
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
STAT_INC (cache->inval_by_line);
}
static GSequenceIter *
find_iter_at_text_iter (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout,
const GtkTextIter *iter)
{
GSequenceIter *left;
GSequenceIter *right;
GSequenceIter *mid;
GSequenceIter *end;
GtkTextLine *target;
guint target_lineno;
g_assert (cache != NULL);
g_assert (iter != NULL);
if (g_sequence_is_empty (cache->sorted_by_line))
return NULL;
/* gtk_text_iter_get_line() will have cached value */
target_lineno = gtk_text_iter_get_line (iter);
target = _gtk_text_iter_get_text_line (iter);
/* Get some iters so we can work with pointer compare */
end = g_sequence_get_end_iter (cache->sorted_by_line);
left = g_sequence_get_begin_iter (cache->sorted_by_line);
right = g_sequence_iter_prev (end);
/* We already checked for empty above */
g_assert (!g_sequence_iter_is_end (left));
g_assert (!g_sequence_iter_is_end (right));
for (;;)
{
GtkTextLineDisplay *display;
guint lineno;
if (left == right)
mid = left;
else
mid = g_sequence_range_get_midpoint (left, right);
g_assert (mid != NULL);
g_assert (!g_sequence_iter_is_end (mid));
if (mid == end)
break;
display = g_sequence_get (mid);
g_assert (display != NULL);
g_assert (display->line != NULL);
g_assert (display->cache_iter != NULL);
if (target == display->line)
return mid;
if (right == left)
break;
lineno = _gtk_text_line_get_number (display->line);
if (target_lineno < lineno)
right = mid;
else if (target_lineno > lineno)
left = g_sequence_iter_next (mid);
else
g_assert_not_reached ();
}
return NULL;
}
/*
* gtk_text_line_display_cache_invalidate_range:
* @cache: a GtkTextLineDisplayCache
* @begin: the starting text iter
* @end: the ending text iter
*
* Removes all GtkTextLineDisplay that fall between or including
* @begin and @end.
*/
void
gtk_text_line_display_cache_invalidate_range (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout,
const GtkTextIter *begin,
const GtkTextIter *end,
gboolean cursors_only)
{
GSequenceIter *begin_iter;
GSequenceIter *end_iter;
GSequenceIter *iter;
g_assert (cache != NULL);
g_assert (layout != NULL);
g_assert (begin != NULL);
g_assert (end != NULL);
STAT_INC (cache->inval_by_range);
/* Short-circuit, is_empty() is O(1) */
if (g_sequence_is_empty (cache->sorted_by_line))
return;
/* gtk_text_iter_order() preserving const */
if (gtk_text_iter_compare (begin, end) > 0)
{
const GtkTextIter *tmp = begin;
end = begin;
begin = tmp;
}
/* Common case, begin/end on same line. Just try to find the line by
* line number and invalidate it alone.
*/
if G_LIKELY (_gtk_text_iter_same_line (begin, end))
{
begin_iter = find_iter_at_text_iter (cache, layout, begin);
if (begin_iter != NULL)
{
GtkTextLineDisplay *display = g_sequence_get (begin_iter);
g_assert (display != NULL);
g_assert (display->line != NULL);
gtk_text_line_display_cache_invalidate_display (cache, display, cursors_only);
}
return;
}
/* Find GSequenceIter containing GtkTextLineDisplay that correspond
* to each of the text positions.
*/
begin_iter = find_iter_at_text_iter (cache, layout, begin);
end_iter = find_iter_at_text_iter (cache, layout, end);
/* Short-circuit if we found nothing */
if (begin_iter == NULL && end_iter == NULL)
return;
/* If nothing matches the end, we need to walk to the end of our
* cached displays. We know there is a non-zero number of items
* in the sequence at this point, so we can iter_prev() safely.
*/
if (end_iter == NULL)
end_iter = g_sequence_iter_prev (g_sequence_get_end_iter (cache->sorted_by_line));
/* If nothing matched the begin, we need to walk starting from
* the first display we have cached.
*/
if (begin_iter == NULL)
begin_iter = g_sequence_get_begin_iter (cache->sorted_by_line);
iter = begin_iter;
for (;;)
{
GtkTextLineDisplay *display = g_sequence_get (iter);
GSequenceIter *next = g_sequence_iter_next (iter);
gtk_text_line_display_cache_invalidate_display (cache, display, cursors_only);
if (iter == end_iter)
break;
iter = next;
}
}
static GSequenceIter *
find_iter_at_at_y (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout,
gint y)
{
GtkTextBTree *btree;
GSequenceIter *left;
GSequenceIter *right;
GSequenceIter *mid;
GSequenceIter *end;
g_assert (cache != NULL);
g_assert (layout != NULL);
if (g_sequence_is_empty (cache->sorted_by_line))
return NULL;
btree = _gtk_text_buffer_get_btree (layout->buffer);
/* Get some iters so we can work with pointer compare */
end = g_sequence_get_end_iter (cache->sorted_by_line);
left = g_sequence_get_begin_iter (cache->sorted_by_line);
right = g_sequence_iter_prev (end);
/* We already checked for empty above */
g_assert (!g_sequence_iter_is_end (left));
g_assert (!g_sequence_iter_is_end (right));
for (;;)
{
GtkTextLineDisplay *display;
gint cache_y;
gint cache_height;
if (left == right)
mid = left;
else
mid = g_sequence_range_get_midpoint (left, right);
g_assert (mid != NULL);
g_assert (!g_sequence_iter_is_end (mid));
if (mid == end)
break;
display = g_sequence_get (mid);
g_assert (display != NULL);
g_assert (display->line != NULL);
cache_y = _gtk_text_btree_find_line_top (btree, display->line, layout);
cache_height = display->height;
if (y >= cache_y && y <= (cache_y + cache_height))
return mid;
if (left == right)
break;
if (y < cache_y)
right = mid;
else if (y > (cache_y + cache_height))
left = g_sequence_iter_next (mid);
else
g_assert_not_reached ();
}
return NULL;
}
/*
* gtk_text_line_display_cache_invalidate_y_range:
* @cache: a GtkTextLineDisplayCache
* @y: the starting Y position
* @old_height: the height to invalidate
* @cursors_only: if only cursors should be invalidated
*
* Remove all GtkTextLineDisplay that fall into the range starting
* from the Y position to Y+Height.
*/
void
gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout,
gint y,
gint old_height,
gboolean cursors_only)
{
GSequenceIter *iter;
GtkTextBTree *btree;
g_assert (cache != NULL);
g_assert (layout != NULL);
STAT_INC (cache->inval_by_y_range);
btree = _gtk_text_buffer_get_btree (layout->buffer);
iter = find_iter_at_at_y (cache, layout, y);
if (iter == NULL)
return;
while (!g_sequence_iter_is_end (iter))
{
GtkTextLineDisplay *display;
gint cache_y;
gint cache_height;
display = g_sequence_get (iter);
iter = g_sequence_iter_next (iter);
cache_y = _gtk_text_btree_find_line_top (btree, display->line, layout);
cache_height = display->height;
if (cache_y + cache_height > y && cache_y < y + old_height)
{
gtk_text_line_display_cache_invalidate_display (cache, display, cursors_only);
y += cache_height;
old_height -= cache_height;
if (old_height > 0)
continue;
}
break;
}
}
void
gtk_text_line_display_cache_set_cursor_line (GtkTextLineDisplayCache *cache,
GtkTextLine *cursor_line)
{
GtkTextLineDisplay *display;
g_assert (cache != NULL);
if (cursor_line == cache->cursor_line)
return;
display = g_hash_table_lookup (cache->line_to_display, cache->cursor_line);
if (display != NULL)
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
cache->cursor_line = cursor_line;
display = g_hash_table_lookup (cache->line_to_display, cache->cursor_line);
if (display != NULL)
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
}
+59
View File
@@ -0,0 +1,59 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* Copyright (C) 2019 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/>.
*/
#ifndef __GTK_TEXT_LINE_DISPLAY_CACHE_PRIVATE_H__
#define __GTK_TEXT_LINE_DISPLAY_CACHE_PRIVATE_H__
#include "gtktextlayoutprivate.h"
G_BEGIN_DECLS
typedef struct _GtkTextLineDisplayCache GtkTextLineDisplayCache;
GtkTextLineDisplayCache *gtk_text_line_display_cache_new (void);
void gtk_text_line_display_cache_free (GtkTextLineDisplayCache *cache);
GtkTextLineDisplay *gtk_text_line_display_cache_get (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout,
GtkTextLine *line,
gboolean size_only);
void gtk_text_line_display_cache_delay_eviction (GtkTextLineDisplayCache *cache);
void gtk_text_line_display_cache_set_cursor_line (GtkTextLineDisplayCache *cache,
GtkTextLine *line);
void gtk_text_line_display_cache_invalidate (GtkTextLineDisplayCache *cache);
void gtk_text_line_display_cache_invalidate_cursors (GtkTextLineDisplayCache *cache,
GtkTextLine *line);
void gtk_text_line_display_cache_invalidate_display (GtkTextLineDisplayCache *cache,
GtkTextLineDisplay *display,
gboolean cursors_only);
void gtk_text_line_display_cache_invalidate_line (GtkTextLineDisplayCache *cache,
GtkTextLine *line);
void gtk_text_line_display_cache_invalidate_range (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout,
const GtkTextIter *begin,
const GtkTextIter *end,
gboolean cursors_only);
void gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache,
GtkTextLayout *layout,
gint y,
gint height,
gboolean cursors_only);
G_END_DECLS
#endif /* __GTK_TEXT_LINE_DISPLAY_CACHE_PRIVATE_H__ */
-1
View File
@@ -150,7 +150,6 @@ struct _GtkTextLineSegment {
};
GDK_AVAILABLE_IN_ALL
GtkTextLineSegment *gtk_text_line_segment_split (const GtkTextIter *iter);
GtkTextLineSegment *_gtk_char_segment_new (const gchar *text,
+2 -2
View File
@@ -27,8 +27,8 @@
#include "gtktextview.h"
#include "gtktextutil.h"
#include "gtktextdisplayprivate.h"
#include "gtktextbuffer.h"
#include "gtktextlayoutprivate.h"
#include "gtkmenuitem.h"
#include "gtkintl.h"
@@ -335,7 +335,7 @@ gtk_text_util_create_rich_drag_icon (GtkWidget *widget,
snapshot = gtk_snapshot_new ();
gtk_text_layout_snapshot (layout, widget, snapshot, &(GdkRectangle) { 0, 0, layout_width, layout_height });
gtk_text_layout_snapshot (layout, widget, snapshot, &(GdkRectangle) { 0, 0, layout_width, layout_height }, 1.0);
g_object_unref (layout);
g_object_unref (new_buffer);
+124 -88
View File
@@ -41,7 +41,6 @@
#include "gtkrenderbackgroundprivate.h"
#include "gtkseparatormenuitem.h"
#include "gtksettings.h"
#include "gtktextdisplayprivate.h"
#include "gtktextiterprivate.h"
#include "gtkimmulticontext.h"
#include "gtkprivate.h"
@@ -210,7 +209,10 @@ struct _GtkTextViewPrivate
GtkTextMark *first_para_mark; /* Mark at the beginning of the first onscreen paragraph */
gint first_para_pixels; /* Offset of top of screen in the first onscreen paragraph */
guint blink_timeout;
guint64 blink_start_time;
guint blink_tick;
float cursor_alpha;
guint scroll_timeout;
guint first_validate_idle; /* Idle to revalidate onscreen portion, runs before resize */
@@ -4571,11 +4573,15 @@ gtk_text_view_style_updated (GtkWidget *widget)
style_context = gtk_widget_get_style_context (widget);
change = gtk_style_context_get_change (style_context);
if ((change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT)) &&
if ((change == NULL ||
gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT |
GTK_CSS_AFFECTS_BACKGROUND |
GTK_CSS_AFFECTS_CONTENT)) &&
priv->layout && priv->layout->default_style)
{
gtk_text_view_set_attributes_from_style (text_view,
priv->layout->default_style);
gtk_text_layout_default_style_changed (priv->layout);
ltr_context = gtk_widget_create_pango_context (widget);
pango_context_set_base_dir (ltr_context, PANGO_DIRECTION_LTR);
@@ -5347,12 +5353,6 @@ gtk_text_view_paint (GtkWidget *widget,
g_warning (G_STRLOC ": somehow some text lines were modified or scrolling occurred since the last validation of lines on the screen - may be a text widget bug.");
g_assert_not_reached ();
}
#if 0
printf ("painting %d,%d %d x %d\n",
area->x, area->y,
area->width, area->height);
#endif
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (-priv->xoffset, -priv->yoffset));
@@ -5365,7 +5365,8 @@ gtk_text_view_paint (GtkWidget *widget,
priv->yoffset,
gtk_widget_get_width (widget),
gtk_widget_get_height (widget)
});
},
priv->cursor_alpha);
gtk_snapshot_restore (snapshot);
}
@@ -5662,23 +5663,88 @@ get_cursor_blink_timeout (GtkTextView *text_view)
* Blink!
*/
static gint
blink_cb (gpointer data)
{
GtkTextView *text_view;
GtkTextViewPrivate *priv;
gboolean visible;
gint blink_timeout;
typedef struct {
guint64 start;
guint64 end;
} BlinkData;
text_view = GTK_TEXT_VIEW (data);
priv = text_view->priv;
static gboolean blink_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer user_data);
static void
add_blink_timeout (GtkTextView *self,
gboolean delay)
{
GtkTextViewPrivate *priv = self->priv;
BlinkData *data;
int blink_time;
priv->blink_start_time = g_get_monotonic_time ();
priv->cursor_alpha = 1.0;
blink_time = get_cursor_time (self);
data = g_new (BlinkData, 1);
data->start = priv->blink_start_time;
if (delay)
data->start += blink_time * 1000 / 2;
data->end = data->start + blink_time * 1000;
priv->blink_tick = gtk_widget_add_tick_callback (GTK_WIDGET (self),
blink_cb,
data,
g_free);
}
static void
remove_blink_timeout (GtkTextView *self)
{
GtkTextViewPrivate *priv = self->priv;
if (priv->blink_tick)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), priv->blink_tick);
priv->blink_tick = 0;
}
}
static float
blink_alpha (float phase)
{
/* keep it simple, and split the blink cycle evenly
* into visible, fading out, invisible, fading in
*/
if (phase < 0.25)
return 1;
else if (phase < 0.5)
return 1 - 4 * (phase - 0.25);
else if (phase < 0.75)
return 0;
else
return 4 * (phase - 0.75);
}
static gboolean
blink_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer user_data)
{
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
GtkTextViewPrivate *priv = text_view->priv;
BlinkData *data = user_data;
gint blink_timeout;
gint blink_time;
guint64 now;
float phase;
float alpha;
if (!gtk_widget_has_focus (GTK_WIDGET (text_view)))
{
g_warning ("GtkTextView - did not receive a focus-out.\n"
"If you handle this event, you must return\n"
"GDK_EVENT_PROPAGATE so the text view gets the event as well");
gtk_text_view_check_cursor_blink (text_view);
return FALSE;
@@ -5687,47 +5753,45 @@ blink_cb (gpointer data)
g_assert (priv->layout);
g_assert (cursor_visible (text_view));
visible = gtk_text_layout_get_cursor_visible (priv->layout);
blink_timeout = get_cursor_blink_timeout (text_view);
if (priv->blink_time > 1000 * blink_timeout &&
blink_timeout < G_MAXINT/1000)
blink_time = get_cursor_time (text_view);
now = g_get_monotonic_time ();
if (now > priv->blink_start_time + blink_timeout * 1000000)
{
/* we've blinked enough without the user doing anything, stop blinking */
visible = 0;
priv->blink_timeout = 0;
}
else if (visible)
{
priv->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_OFF_MULTIPLIER / CURSOR_DIVIDER,
blink_cb,
text_view);
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
}
else
{
priv->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_ON_MULTIPLIER / CURSOR_DIVIDER,
blink_cb,
text_view);
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
priv->blink_time += get_cursor_time (text_view);
priv->cursor_alpha = 1.0;
remove_blink_timeout (text_view);
gtk_widget_queue_draw (widget);
return G_SOURCE_REMOVE;
}
gtk_text_layout_set_cursor_visible (priv->layout, !visible);
phase = (now - data->start) / (float) (data->end - data->start);
/* Remove ourselves */
return FALSE;
if (now >= data->end)
{
data->start = data->end;
data->end = data->start + blink_time * 1000;
}
alpha = blink_alpha (phase);
if (priv->cursor_alpha != alpha)
{
priv->cursor_alpha = alpha;
gtk_widget_queue_draw (widget);
}
return G_SOURCE_CONTINUE;
}
static void
gtk_text_view_stop_cursor_blink (GtkTextView *text_view)
{
if (text_view->priv->blink_timeout)
{
g_source_remove (text_view->priv->blink_timeout);
text_view->priv->blink_timeout = 0;
}
remove_blink_timeout (text_view);
}
static void
@@ -5735,52 +5799,25 @@ gtk_text_view_check_cursor_blink (GtkTextView *text_view)
{
GtkTextViewPrivate *priv = text_view->priv;
if (priv->layout != NULL &&
cursor_visible (text_view) &&
gtk_widget_has_focus (GTK_WIDGET (text_view)))
if (cursor_blinks (text_view))
{
if (cursor_blinks (text_view))
{
if (priv->blink_timeout == 0)
{
gtk_text_layout_set_cursor_visible (priv->layout, TRUE);
priv->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_OFF_MULTIPLIER / CURSOR_DIVIDER,
blink_cb,
text_view);
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
}
}
else
{
gtk_text_view_stop_cursor_blink (text_view);
gtk_text_layout_set_cursor_visible (priv->layout, TRUE);
}
if (!priv->blink_tick)
add_blink_timeout (text_view, FALSE);
}
else
{
gtk_text_view_stop_cursor_blink (text_view);
gtk_text_layout_set_cursor_visible (priv->layout, FALSE);
if (priv->blink_tick)
remove_blink_timeout (text_view);
}
}
static void
gtk_text_view_pend_cursor_blink (GtkTextView *text_view)
{
GtkTextViewPrivate *priv = text_view->priv;
if (priv->layout != NULL &&
cursor_visible (text_view) &&
gtk_widget_has_focus (GTK_WIDGET (text_view)) &&
cursor_blinks (text_view))
if (cursor_blinks (text_view))
{
gtk_text_view_stop_cursor_blink (text_view);
gtk_text_layout_set_cursor_visible (priv->layout, TRUE);
priv->blink_timeout = g_timeout_add (get_cursor_time (text_view) * CURSOR_PEND_MULTIPLIER / CURSOR_DIVIDER,
blink_cb,
text_view);
g_source_set_name_by_id (priv->blink_timeout, "[gtk] blink_cb");
remove_blink_timeout (text_view);
add_blink_timeout (text_view, TRUE);
}
}
@@ -5789,7 +5826,7 @@ gtk_text_view_reset_blink_time (GtkTextView *text_view)
{
GtkTextViewPrivate *priv = text_view->priv;
priv->blink_time = 0;
priv->blink_start_time = g_get_monotonic_time ();
}
@@ -8218,6 +8255,8 @@ gtk_text_view_commit_handler (GtkIMContext *context,
GtkTextView *text_view)
{
gtk_text_view_commit_text (text_view, str);
gtk_text_view_reset_blink_time (text_view);
gtk_text_view_pend_cursor_blink (text_view);
}
static void
@@ -8864,12 +8903,10 @@ append_bubble_item (GtkTextView *text_view,
item = gtk_button_new ();
gtk_widget_set_focus_on_click (item, FALSE);
image = gtk_image_new_from_icon_name (icon_name);
gtk_widget_show (image);
gtk_container_add (GTK_CONTAINER (item), image);
gtk_style_context_add_class (gtk_widget_get_style_context (item), "image-button");
gtk_actionable_set_action_name (GTK_ACTIONABLE (item), action_name);
gtk_widget_show (GTK_WIDGET (item));
gtk_container_add (GTK_CONTAINER (toolbar), item);
}
@@ -8900,7 +8937,6 @@ gtk_text_view_selection_bubble_popup_show (gpointer user_data)
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
g_object_set (box, "margin", 10, NULL);
gtk_widget_show (box);
toolbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_style_context_add_class (gtk_widget_get_style_context (toolbar), "linked");
gtk_container_add (GTK_CONTAINER (priv->selection_bubble), box);
File diff suppressed because it is too large Load Diff
+94
View File
@@ -0,0 +1,94 @@
/* gtktimingfunction.h: Timing functions for animations
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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/>.
*/
#pragma once
#include <gtk/gtktypes.h>
#include <gtk/gtkenums.h>
G_BEGIN_DECLS
#define GTK_TYPE_TIMING_FUNCTION (gtk_timing_function_get_type())
/**
* GtkTimingFunction:
*
* An opaque type representing a timing, or "easing" function.
*/
typedef struct _GtkTimingFunction GtkTimingFunction;
GDK_AVAILABLE_IN_ALL
GType gtk_timing_function_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
gboolean gtk_timing_function_equal (GtkTimingFunction *a,
GtkTimingFunction *b);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_timing_function_ref (GtkTimingFunction *self);
GDK_AVAILABLE_IN_ALL
void gtk_timing_function_unref (GtkTimingFunction *self);
GDK_AVAILABLE_IN_ALL
char * gtk_timing_function_to_string (GtkTimingFunction *self);
GDK_AVAILABLE_IN_ALL
void gtk_timing_function_print (GtkTimingFunction *self,
GString *buf);
GDK_AVAILABLE_IN_ALL
gboolean gtk_timing_function_parse (const char *string,
GtkTimingFunction **out_func);
GDK_AVAILABLE_IN_ALL
double gtk_timing_function_transform_time (GtkTimingFunction *self,
double elapsed,
double duration);
GDK_AVAILABLE_IN_ALL
gboolean gtk_timing_function_get_control_points (GtkTimingFunction *self,
double *x_1,
double *y_1,
double *x_2,
double *y_2);
GDK_AVAILABLE_IN_ALL
gboolean gtk_timing_function_get_steps (GtkTimingFunction *self,
int *n_steps,
GtkStepPosition *position);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_linear (void);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_cubic_bezier (double x_1,
double y_1,
double x_2,
double y_2);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_ease (void);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_ease_in (void);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_ease_out (void);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_ease_in_out (void);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_steps (int n_steps,
GtkStepPosition position);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_step_start (void);
GDK_AVAILABLE_IN_ALL
GtkTimingFunction * gtk_step_end (void);
G_END_DECLS
+29
View File
@@ -0,0 +1,29 @@
/* gtktimingfunctionprivate.h: Private declarations for GtkTimingFunction
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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/>.
*/
#include "gtktimingfunction.h"
#include "gtkcssparserprivate.h"
G_BEGIN_DECLS
gboolean gtk_timing_function_parser_parse (GtkCssParser *parser,
GtkTimingFunction **out_function);
G_END_DECLS
-1
View File
@@ -10107,7 +10107,6 @@ gtk_widget_buildable_finish_layout_properties (GtkWidget *widget,
}
g_slist_free_full (layout_properties, layout_property_info_free);
g_slice_free (LayoutParserData, layout_data);
}
static void
+33 -28
View File
@@ -283,6 +283,7 @@ typedef struct
GList *foci;
GtkConstraintSolver *constraint_solver;
GtkAnimationManager *animation_manager;
} GtkWindowPrivate;
#ifdef GDK_WINDOWING_X11
@@ -2367,6 +2368,23 @@ gtk_window_root_get_constraint_solver (GtkRoot *root)
return priv->constraint_solver;
}
static GtkAnimationManager *
gtk_window_root_get_animation_manager (GtkRoot *root)
{
GtkWindow *self = GTK_WINDOW (root);
GtkWindowPrivate *priv = gtk_window_get_instance_private (self);
GdkFrameClock *frame_clock;
if (priv->animation_manager == NULL)
priv->animation_manager = gtk_animation_manager_new ();
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
if (frame_clock != NULL)
gtk_animation_manager_set_frame_clock (priv->animation_manager, frame_clock);
return priv->animation_manager;
}
static void
gtk_window_native_get_surface_transform (GtkNative *native,
int *x,
@@ -2396,6 +2414,7 @@ gtk_window_root_interface_init (GtkRootInterface *iface)
{
iface->get_display = gtk_window_root_get_display;
iface->get_constraint_solver = gtk_window_root_get_constraint_solver;
iface->get_animation_manager = gtk_window_root_get_animation_manager;
}
static void
@@ -4738,6 +4757,7 @@ gtk_window_finalize (GObject *object)
priv->mnemonics_display_timeout_id = 0;
}
g_clear_object (&priv->animation_manager);
g_clear_object (&priv->constraint_solver);
g_clear_object (&priv->renderer);
@@ -8087,9 +8107,10 @@ gtk_window_set_display (GtkWindow *window,
"notify::gtk-application-prefer-dark-theme",
G_CALLBACK (gtk_window_on_theme_variant_changed), window);
#endif
priv->display = display;
gtk_widget_unroot (widget);
priv->display = display;
gtk_widget_root (widget);
g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_DISPLAY]);
@@ -9233,30 +9254,6 @@ gtk_window_unexport_handle (GtkWindow *window)
G_OBJECT_TYPE_NAME (priv->surface));
}
static void
gtk_window_add_pointer_focus (GtkWindow *window,
GtkPointerFocus *focus)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
priv->foci = g_list_prepend (priv->foci, gtk_pointer_focus_ref (focus));
}
static void
gtk_window_remove_pointer_focus (GtkWindow *window,
GtkPointerFocus *focus)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GList *pos;
pos = g_list_find (priv->foci, focus);
if (!pos)
return;
priv->foci = g_list_remove (priv->foci, focus);
gtk_pointer_focus_unref (focus);
}
static GtkPointerFocus *
gtk_window_lookup_pointer_focus (GtkWindow *window,
GdkDevice *device,
@@ -9317,6 +9314,7 @@ gtk_window_update_pointer_focus (GtkWindow *window,
gdouble x,
gdouble y)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkPointerFocus *focus;
focus = gtk_window_lookup_pointer_focus (window, device, sequence);
@@ -9331,7 +9329,14 @@ gtk_window_update_pointer_focus (GtkWindow *window,
}
else
{
gtk_window_remove_pointer_focus (window, focus);
GList *pos;
pos = g_list_find (priv->foci, focus);
if (pos)
{
priv->foci = g_list_remove (priv->foci, focus);
gtk_pointer_focus_unref (focus);
}
}
gtk_pointer_focus_unref (focus);
@@ -9339,8 +9344,7 @@ gtk_window_update_pointer_focus (GtkWindow *window,
else if (target)
{
focus = gtk_pointer_focus_new (window, target, device, sequence, x, y);
gtk_window_add_pointer_focus (window, focus);
gtk_pointer_focus_unref (focus);
priv->foci = g_list_prepend (priv->foci, focus);
}
}
@@ -9371,6 +9375,7 @@ gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
/* Unmapping the toplevel, remove pointer focus */
priv->foci = g_list_remove_link (priv->foci, cur);
gtk_pointer_focus_unref (focus);
g_list_free (cur);
}
else if (focus->target == widget ||
gtk_widget_is_ancestor (focus->target, widget))
+24
View File
@@ -71,6 +71,7 @@ struct _GtkInspectorGeneralPrivate
GtkWidget *gtk_version;
GtkWidget *gdk_backend;
GtkWidget *gsk_renderer;
GtkWidget *pango_fontmap;
GtkWidget *gl_version;
GtkWidget *gl_vendor;
GtkWidget *vk_device;
@@ -625,6 +626,27 @@ init_display (GtkInspectorGeneral *gen)
populate_display (display, gen);
}
static void
init_pango (GtkInspectorGeneral *gen)
{
PangoFontMap *fontmap;
const char *type;
const char *name;
fontmap = pango_cairo_font_map_get_default ();
type = G_OBJECT_TYPE_NAME (fontmap);
if (strcmp (type, "PangoCairoFcFontMap") == 0)
name = "fontconfig";
else if (strcmp (type, "PangoCairoCoreTextFontMap") == 0)
name = "coretext";
else if (strcmp (type, "PangoCairoWin32FontMap") == 0)
name = "win32";
else
name = type;
gtk_label_set_label (GTK_LABEL (gen->priv->pango_fontmap), name);
}
static void populate_seats (GtkInspectorGeneral *gen);
static void
@@ -793,6 +815,7 @@ gtk_inspector_general_init (GtkInspectorGeneral *gen)
init_version (gen);
init_env (gen);
init_display (gen);
init_pango (gen);
init_gl (gen);
init_vulkan (gen);
init_device (gen);
@@ -924,6 +947,7 @@ gtk_inspector_general_class_init (GtkInspectorGeneralClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gtk_version);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gdk_backend);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gsk_renderer);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, pango_fontmap);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gl_version);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, gl_vendor);
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorGeneral, vk_device);
+28
View File
@@ -96,6 +96,33 @@
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<property name="margin">10</property>
<property name="spacing">40</property>
<child>
<object class="GtkLabel" id="pango_fontmap_label">
<property name="label" translatable="yes">Pango Fontmap</property>
<property name="halign">start</property>
<property name="valign">baseline</property>
<property name="xalign">0.0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="pango_fontmap">
<property name="selectable">1</property>
<property name="halign">end</property>
<property name="valign">baseline</property>
<property name="hexpand">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
@@ -578,6 +605,7 @@
<widget name="gtk_version_label"/>
<widget name="gdk_backend_label"/>
<widget name="gsk_renderer_label"/>
<widget name="pango_fontmap_label"/>
<widget name="gl_version_label"/>
<widget name="gl_vendor_label"/>
<widget name="vk_device_label"/>
+5 -2
View File
@@ -23,6 +23,7 @@ gtk_private_sources = files([
'gtkactionobservable.c',
'gtkactionobserver.c',
'gtkallocatedbitmask.c',
'gtkanimationmanager.c',
'gtkapplicationaccels.c',
'gtkapplicationimpl.c',
'gtkbookmarksmanager.c',
@@ -315,7 +316,6 @@ gtk_public_sources = files([
'gtkradiomenuitem.c',
'gtkradiotoolbutton.c',
'gtkrange.c',
'gtktreerbtree.c',
'gtkrecentmanager.c',
'gtkrender.c',
'gtkrenderbackground.c',
@@ -366,10 +366,10 @@ gtk_public_sources = files([
'gtktextattributes.c',
'gtktextbuffer.c',
'gtktextchild.c',
'gtktextdisplay.c',
'gtktexthandle.c',
'gtktextiter.c',
'gtktextlayout.c',
'gtktextlinedisplaycache.c',
'gtktextmark.c',
'gtktextsegment.c',
'gtktexttag.c',
@@ -377,6 +377,7 @@ gtk_public_sources = files([
'gtktexttypes.c',
'gtktextutil.c',
'gtktextview.c',
'gtktimingfunction.c',
'gtktogglebutton.c',
'gtktoggletoolbutton.c',
'gtktoolbar.c',
@@ -391,6 +392,7 @@ gtk_public_sources = files([
'gtktreemodel.c',
'gtktreemodelfilter.c',
'gtktreemodelsort.c',
'gtktreerbtree.c',
'gtktreeselection.c',
'gtktreesortable.c',
'gtktreestore.c',
@@ -618,6 +620,7 @@ gtk_public_headers = files([
'gtktexttag.h',
'gtktexttagtable.h',
'gtktextview.h',
'gtktimingfunction.h',
'gtktogglebutton.h',
'gtktoggletoolbutton.h',
'gtktoolbar.h',
+5 -1
View File
@@ -315,6 +315,10 @@ entry {
@extend .dim-label;
}
block-cursor {
@include entry(block_cursor);
}
&.flat {
&:focus, &:backdrop, &:disabled, &:backdrop:disabled, & {
min-height: 0;
@@ -3986,7 +3990,7 @@ row image.sidebar-icon { opacity: $_placesidebar_icons_opacity; } // dim the sid
// on this oddity
placessidebar {
> viewport.frame { border-style: none; }
> scrolledwindow.frame { border-style: none; }
row {
// Needs overriding of the GtkListBoxRow padding
+5 -1
View File
@@ -39,7 +39,7 @@
// use the default one
//
// possible $t values:
// normal, focus, insensitive, backdrop, backdrop-insensitive, osd, osd-focus, osd-backdrop;
// normal, focus, insensitive, backdrop, backdrop-insensitive, osd, osd-focus, osd-backdrop, block_cursor;
//
$_blank_edge: if($edge == none, none, 0 1px transparentize($edge, 1));
@@ -111,6 +111,10 @@
text-shadow: none;
-gtk-icon-shadow: none;
}
@if $t==block_cursor {
color: $base_color;
background-color: $text_color;
}
}
// buttons
+2 -1
View File
@@ -12,5 +12,6 @@ Description: GTK Graphical UI Library
Version: @VERSION@
Requires: @GDK_PACKAGES@ @GSK_PACKAGES@ @GTK_PACKAGES@
Requires.private: @GDK_PRIVATE_PACKAGES@ @GSK_PRIVATE_PACKAGES@ @GTK_PRIVATE_PACKAGES@
Libs: -L${libdir} -lgtk-4 @GDK_EXTRA_LIBS@ @GSK_EXTRA_LIBS@ @GTK_EXTRA_LIBS@
Libs: -L${libdir} -lgtk-4
Libs.private: @GDK_EXTRA_LIBS@ @GSK_EXTRA_LIBS@ @GTK_EXTRA_LIBS@
Cflags: -I${includedir}/gtk-@GTK_API_VERSION@ @GDK_EXTRA_CFLAGS@ @GSK_EXTRA_CFLAGS@ @GTK_EXTRA_CFLAGS@
+1 -1
View File
@@ -33,7 +33,7 @@ atk_req = '>= 2.15.1'
cairo_req = '>= 1.14.0'
gdk_pixbuf_req = '>= 2.30.0'
introspection_req = '>= 1.39.0'
wayland_proto_req = '>= 1.12'
wayland_proto_req = '>= 1.14'
wayland_req = '>= 1.14.91'
graphene_req = '>= 1.9.1'
epoxy_req = '>= 1.4'
-1
View File
@@ -284,7 +284,6 @@ gtk/gtkswitch.c
gtk/gtktextbuffer.c
gtk/gtktext.c
gtk/gtktextchild.c
gtk/gtktextdisplay.c
gtk/gtktexthandle.c
gtk/gtktextiter.c
gtk/gtktextlayout.c
+1
View File
@@ -19,6 +19,7 @@ demos/gtk-demo/filtermodel.ui
demos/gtk-demo/fishbowl.ui
demos/gtk-demo/font_features.c
demos/gtk-demo/font-features.ui
demos/gtk-demo/fontrendering.ui
demos/gtk-demo/iconview.c
demos/gtk-demo/infobar.c
demos/gtk-demo/listbox.ui
+3 -3
View File
@@ -370,15 +370,15 @@ msgstr "L'etiqueta de l'enllaç al lloc web del programa"
#: gtk/gtkaboutdialog.c:501
msgid "Authors"
msgstr "Autors"
msgstr "Autoria"
#: gtk/gtkaboutdialog.c:502
msgid "List of authors of the program"
msgstr "Llista d'autors del programa"
msgstr "Autoria del programa"
#: gtk/gtkaboutdialog.c:515
msgid "Documenters"
msgstr "Documentadors"
msgstr "Equip de documentació"
#: gtk/gtkaboutdialog.c:516
msgid "List of people documenting the program"
+97 -97
View File
@@ -8,8 +8,8 @@
msgid ""
msgstr "Project-Id-Version: gtk+_properties master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-08 07:11+0000\n"
"PO-Revision-Date: 2019-04-26 19:00+0100\n"
"POT-Creation-Date: 2019-07-18 19:33+0000\n"
"PO-Revision-Date: 2019-07-21 10:00+0100\n"
"Last-Translator: Asier Sarasua Garmendia <asier.sarasua@gmail.com>\n"
"Language-Team: Basque <librezale@librezale.eus>\n"
"Language: eu\n"
@@ -193,7 +193,7 @@ msgid "The GL context this context shares data with"
msgstr "GL-ren testuingurua (testuinguruko datuak partekatu dituenak)"
#
#: gdk/gdksurface.c:424 gdk/gdksurface.c:425 gtk/gtkwidget.c:1067
#: gdk/gdksurface.c:424 gdk/gdksurface.c:425 gtk/gtkwidget.c:1069
msgid "Cursor"
msgstr "Kurtsorea"
@@ -224,7 +224,7 @@ msgstr "Automatikoki ezkutatu"
#: gdk/gdksurface.c:473
msgid "Whether to dismiss the surface on outside clicks"
msgstr ""
msgstr "Gainazala baztertuko den ala ez kanpoko kliketan"
#
#: gdk/gdksurface.c:479 gdk/gdksurface.c:480
@@ -686,7 +686,7 @@ msgstr "Erakutsi menu-barra"
msgid "TRUE if the window should show a menubar at the top of the window"
msgstr "TRUE (egia) leihoak goian menu-barra erakutsi behar badu"
#: gtk/gtkaspectframe.c:120 gtk/gtkwidget.c:1138
#: gtk/gtkaspectframe.c:120 gtk/gtkwidget.c:1140
msgid "Horizontal Alignment"
msgstr "Lerrokadura horizontala"
@@ -694,7 +694,7 @@ msgstr "Lerrokadura horizontala"
msgid "X alignment of the child"
msgstr "Umearen X lerrokatzea"
#: gtk/gtkaspectframe.c:127 gtk/gtkwidget.c:1151
#: gtk/gtkaspectframe.c:127 gtk/gtkwidget.c:1153
msgid "Vertical Alignment"
msgstr "Lerrokatze bertikala"
@@ -1066,7 +1066,7 @@ msgstr "ikusgai"
msgid "Display the cell"
msgstr "Bistaratu gelaxka"
#: gtk/gtkcellrenderer.c:308 gtk/gtkwidget.c:996
#: gtk/gtkcellrenderer.c:308 gtk/gtkwidget.c:998
msgid "Sensitive"
msgstr "Sentikorra"
@@ -1258,7 +1258,7 @@ msgstr "Progresio-barraren balioa"
#: gtk/gtkcellrendererprogress.c:166 gtk/gtkcellrenderertext.c:253
#: gtk/gtkeditable.c:369 gtk/gtkentrybuffer.c:351 gtk/gtkmessagedialog.c:200
#: gtk/gtkmodelbutton.c:1048 gtk/gtkprogressbar.c:227 gtk/gtktextbuffer.c:425
#: gtk/gtkmodelbutton.c:1048 gtk/gtkprogressbar.c:213 gtk/gtktextbuffer.c:425
msgid "Text"
msgstr "Testua"
@@ -1295,16 +1295,16 @@ msgid "The vertical text alignment, from 0 (top) to 1 (bottom)."
msgstr "Lerrokatze bertikala, 0tik (goian) 1era (behean)."
#: gtk/gtkcellrendererprogress.c:230 gtk/gtklevelbar.c:1060
#: gtk/gtkprogressbar.c:204 gtk/gtkrange.c:380
#: gtk/gtkprogressbar.c:190 gtk/gtkrange.c:380
msgid "Inverted"
msgstr "Alderantzikatuta"
#: gtk/gtkcellrendererprogress.c:231 gtk/gtkprogressbar.c:205
#: gtk/gtkcellrendererprogress.c:231 gtk/gtkprogressbar.c:191
msgid "Invert the direction in which the progress bar grows"
msgstr "Alderantzikatu aurrerapen-barraren hazte-norabidea"
#: gtk/gtkcellrendererspin.c:131 gtk/gtkrange.c:373 gtk/gtkscalebutton.c:213
#: gtk/gtkscrollbar.c:235 gtk/gtkspinbutton.c:379
#: gtk/gtkscrollbar.c:198 gtk/gtkspinbutton.c:379
msgid "Adjustment"
msgstr "Egokitzea"
@@ -1528,7 +1528,7 @@ msgid ""
"probably dont need it"
msgstr "Testu honetako hizkuntza ISOren kode gisa dago. Pango-k laguntza gisa erabil dezake testua bihurtzean. Parametro hori ulertzen ez baduzu, beharbada ez duzu beharko"
#: gtk/gtkcellrenderertext.c:444 gtk/gtklabel.c:935 gtk/gtkprogressbar.c:266
#: gtk/gtkcellrenderertext.c:444 gtk/gtklabel.c:935 gtk/gtkprogressbar.c:252
msgid "Ellipsize"
msgstr "Elipsi gisa"
@@ -1880,7 +1880,7 @@ msgstr "Uneko kolorea, GdkRGBA gisa"
msgid "Whether alpha should be shown"
msgstr "Alfa erakutsi behar den ala ez adierazten du"
#: gtk/gtkcolorchooserdialog.c:217 gtk/gtkcolorchooserwidget.c:711
#: gtk/gtkcolorchooserdialog.c:217 gtk/gtkcolorchooserwidget.c:709
msgid "Show editor"
msgstr "Erakutsi editorea"
@@ -2034,7 +2034,7 @@ msgstr "Iturburuko atributua"
#: gtk/gtkconstraint.c:249
msgid "The attribute of the source widget set by the constraint"
msgstr ""
msgstr "Iturburuko trepetaren atributua, murriztapenak ezarritakoa"
#
#: gtk/gtkconstraint.c:263
@@ -2083,7 +2083,7 @@ msgstr "Egoeraren banderak"
#
#: gtk/gtkcssnode.c:649 gtk/gtknativedialog.c:236 gtk/gtkstack.c:415
#: gtk/gtktreeviewcolumn.c:272 gtk/gtkwidget.c:989
#: gtk/gtktreeviewcolumn.c:272 gtk/gtkwidget.c:991
msgid "Visible"
msgstr "Ikusgai"
@@ -4562,7 +4562,7 @@ msgstr "Burbuila-leihoa kokatzeko posizioa"
#: gtk/gtkpopover.c:1359
msgid "Whether to dismiss the popver on outside clicks"
msgstr ""
msgstr "Bunbuiloa baztertuko den ala ez kanpoko kliketan"
#: gtk/gtkpopover.c:1365 gtk/gtkwindow.c:1069
msgid "Default widget"
@@ -4583,7 +4583,7 @@ msgstr "Gezia marraztuko den ala ez"
#: gtk/gtkpopovermenubar.c:509
msgid "The model from which the bar is made."
msgstr ""
msgstr "Barra egiteko erabili den eredua."
#: gtk/gtkpopovermenu.c:391
msgid "Visible submenu"
@@ -4896,35 +4896,35 @@ msgid "Whether the application has a selection"
msgstr "Aplikazioak hautapen bat duen edo ez"
#
#: gtk/gtkprogressbar.c:211
#: gtk/gtkprogressbar.c:197
msgid "Fraction"
msgstr "Frakzioa"
#: gtk/gtkprogressbar.c:212
#: gtk/gtkprogressbar.c:198
msgid "The fraction of total work that has been completed"
msgstr "Amaitu den lan guztiaren frakzioa"
#: gtk/gtkprogressbar.c:219
#: gtk/gtkprogressbar.c:205
msgid "Pulse Step"
msgstr "Pultsuaren urratsa"
#: gtk/gtkprogressbar.c:220
#: gtk/gtkprogressbar.c:206
msgid "The fraction of total progress to move the bouncing block when pulsed"
msgstr "Sakatutakoan errebote-blokeak egin beharreko progresio osoaren frakzioa"
#: gtk/gtkprogressbar.c:228
#: gtk/gtkprogressbar.c:214
msgid "Text to be displayed in the progress bar"
msgstr "Progresio-barran bistaratu beharreko testua"
#: gtk/gtkprogressbar.c:247
#: gtk/gtkprogressbar.c:233
msgid "Show text"
msgstr "Erakutsi testua"
#: gtk/gtkprogressbar.c:248
#: gtk/gtkprogressbar.c:234
msgid "Whether the progress is shown as text."
msgstr "Progresioa testu gisa erakutsiko den ala ez adierazten du"
#: gtk/gtkprogressbar.c:267
#: gtk/gtkprogressbar.c:253
msgid ""
"The preferred place to ellipsize the string, if the progress bar does not "
"have enough room to display the entire string, if at all."
@@ -5132,7 +5132,7 @@ msgstr "Edukiaren tamaina nola zehaztu behar den"
msgid "Vertical Scrollable Policy"
msgstr "Korritze-barra bertikalaren politika"
#: gtk/gtkscrollbar.c:236
#: gtk/gtkscrollbar.c:199
msgid "The GtkAdjustment that contains the current value of this scrollbar"
msgstr "Korritze-barra honen uneko balioa duen GtkAdjustment"
@@ -5804,7 +5804,7 @@ msgstr "Norabide hauetan, taldearen tamainak osagai-trepetentzat eskatutako tama
#: gtk/gtkslicelistmodel.c:288
msgid "Child model to take slice from"
msgstr ""
msgstr "Zatia hartzeko erabili den eredu haurra"
#: gtk/gtkslicelistmodel.c:299
msgid "Offset"
@@ -5973,7 +5973,7 @@ msgstr "Tamaina leunki aldatuko den ala ez (tamaina desberdineko umeen artean al
#: gtk/gtkstack.c:795
msgid "A selection model with the stacks pages"
msgstr ""
msgstr "Pilen orriak dituen hautapen-eredu bat"
#: gtk/gtkstacksidebar.c:408 gtk/gtkstackswitcher.c:573
#: gtk/gtkstackswitcher.c:574
@@ -6102,7 +6102,7 @@ msgid "Whether the entry should grow and shrink with the content"
msgstr "Sarrera handituko eta txikituko den edukiarekin batera"
#
#: gtk/gtktexthandle.c:634 gtk/gtktexthandle.c:635 gtk/gtkwidget.c:953
#: gtk/gtktexthandle.c:634 gtk/gtktexthandle.c:635 gtk/gtkwidget.c:955
msgid "Parent widget"
msgstr "Trepeta gurasoa"
@@ -6637,11 +6637,11 @@ msgstr "Bistaratutako erro-eredua"
#: gtk/gtktreelistmodel.c:730
msgid "passthrough"
msgstr ""
msgstr "pasabidea"
#: gtk/gtktreelistmodel.c:731
msgid "If child model values are passed through"
msgstr ""
msgstr "Eredu-balio haurrak pasatuko diren ala ez"
#: gtk/gtktreelistmodel.c:1047
msgid "Children"
@@ -6985,261 +6985,261 @@ msgid "Whether to use symbolic icons"
msgstr "Ikono sinbolikoak erabiliko diren edo ez adierazten du"
#
#: gtk/gtkwidget.c:946
#: gtk/gtkwidget.c:948
msgid "Widget name"
msgstr "Trepeta-izena"
#: gtk/gtkwidget.c:947
#: gtk/gtkwidget.c:949
msgid "The name of the widget"
msgstr "Trepetaren izena"
#: gtk/gtkwidget.c:954
#: gtk/gtkwidget.c:956
msgid "The parent widget of this widget."
msgstr "Trepeta honen trepeta gurasoa."
#
#: gtk/gtkwidget.c:966
#: gtk/gtkwidget.c:968
msgid "Root widget"
msgstr "Erro-trepeta"
#: gtk/gtkwidget.c:967
#: gtk/gtkwidget.c:969
msgid "The root widget in the widget tree."
msgstr "Trepeta-zuhaitzeko erro-trepeta."
#: gtk/gtkwidget.c:973
#: gtk/gtkwidget.c:975
msgid "Width request"
msgstr "Zabalera-eskaera"
#: gtk/gtkwidget.c:974
#: gtk/gtkwidget.c:976
msgid ""
"Override for width request of the widget, or -1 if natural request should be "
"used"
msgstr "Gainidatzi trepetaren zabalera-eskaera, edo -1 eskaera naturala erabili behar bada"
#: gtk/gtkwidget.c:981
#: gtk/gtkwidget.c:983
msgid "Height request"
msgstr "Altuera-eskaera"
#: gtk/gtkwidget.c:982
#: gtk/gtkwidget.c:984
msgid ""
"Override for height request of the widget, or -1 if natural request should "
"be used"
msgstr "Gainidatzi trepetaren altuera-eskaera, edo -1 eskaera naturala erabili behar bada"
#: gtk/gtkwidget.c:990
#: gtk/gtkwidget.c:992
msgid "Whether the widget is visible"
msgstr "Trepeta ikusgai dagoen ala ez adierazten du"
#: gtk/gtkwidget.c:997
#: gtk/gtkwidget.c:999
msgid "Whether the widget responds to input"
msgstr "Trepetak sarrerari erantzuten dion ala ez adierazten du"
#: gtk/gtkwidget.c:1003
#: gtk/gtkwidget.c:1005
msgid "Can focus"
msgstr "Enfoka dezake"
#: gtk/gtkwidget.c:1004
#: gtk/gtkwidget.c:1006
msgid "Whether the widget can accept the input focus"
msgstr "Trepetak sarrera-fokua onar dezakeen ala ez adierazten du"
#: gtk/gtkwidget.c:1010
#: gtk/gtkwidget.c:1012
msgid "Has focus"
msgstr "Fokua du"
#: gtk/gtkwidget.c:1011
#: gtk/gtkwidget.c:1013
msgid "Whether the widget has the input focus"
msgstr "Trepetak sarrera-fokua duen ala ez adierazten du"
#: gtk/gtkwidget.c:1017
#: gtk/gtkwidget.c:1019
msgid "Is focus"
msgstr "Fokua da"
#: gtk/gtkwidget.c:1018
#: gtk/gtkwidget.c:1020
msgid "Whether the widget is the focus widget within the toplevel"
msgstr "Trepeta goi-mailakoaren barruan foku-trepeta den ala ez adierazten du"
#: gtk/gtkwidget.c:1024
#: gtk/gtkwidget.c:1026
msgid "Can target"
msgstr ""
msgstr "Helburua izan daiteke"
#: gtk/gtkwidget.c:1025
#: gtk/gtkwidget.c:1027
msgid "Whether the widget can receive pointer events"
msgstr ""
msgstr "Trepetak erakuslearen gertaerak jaso ditzakeen ala ez"
#: gtk/gtkwidget.c:1041
#: gtk/gtkwidget.c:1043
msgid "Focus on click"
msgstr "Fokua klik egindakoan"
#: gtk/gtkwidget.c:1042
#: gtk/gtkwidget.c:1044
msgid "Whether the widget should grab focus when it is clicked with the mouse"
msgstr "Trepetak saguaren klik jasotakoan fokua hartzen duen ala ez adierazten du"
#
#: gtk/gtkwidget.c:1048
#: gtk/gtkwidget.c:1050
msgid "Has default"
msgstr "Lehenetsia dauka"
#: gtk/gtkwidget.c:1049
#: gtk/gtkwidget.c:1051
msgid "Whether the widget is the default widget"
msgstr "Trepeta trepeta lehenetsia den ala ez adierazten du"
#: gtk/gtkwidget.c:1055
#: gtk/gtkwidget.c:1057
msgid "Receives default"
msgstr "Lehenetsia jasotzen du"
#: gtk/gtkwidget.c:1056
#: gtk/gtkwidget.c:1058
msgid "If TRUE, the widget will receive the default action when it is focused"
msgstr "TRUE (egia) bada, trepetak ekintza lehenetsia jasoko du enfokatutakoan"
#: gtk/gtkwidget.c:1068
#: gtk/gtkwidget.c:1070
msgid "The cursor to show when hoving above widget"
msgstr ""
msgstr "Trepetaren gainetik igarotzean erakutsiko den kurtsorea"
#: gtk/gtkwidget.c:1082
#: gtk/gtkwidget.c:1084
msgid "Has tooltip"
msgstr "Argibidea du"
#: gtk/gtkwidget.c:1083
#: gtk/gtkwidget.c:1085
msgid "Whether this widget has a tooltip"
msgstr "Trepetak argibidea duen edo ez"
#: gtk/gtkwidget.c:1104
#: gtk/gtkwidget.c:1106
msgid "Tooltip Text"
msgstr "Argibidearen testua"
#: gtk/gtkwidget.c:1105 gtk/gtkwidget.c:1127
#: gtk/gtkwidget.c:1107 gtk/gtkwidget.c:1129
msgid "The contents of the tooltip for this widget"
msgstr "Trepetaren argibidearen edukia"
#: gtk/gtkwidget.c:1126
#: gtk/gtkwidget.c:1128
msgid "Tooltip markup"
msgstr "Markaren argibidea"
#: gtk/gtkwidget.c:1139
#: gtk/gtkwidget.c:1141
msgid "How to position in extra horizontal space"
msgstr "Nola kokatu leku horizontal gehigarrian"
#: gtk/gtkwidget.c:1152
#: gtk/gtkwidget.c:1154
msgid "How to position in extra vertical space"
msgstr "Nola kokatu leku bertikal gehigarrian"
#: gtk/gtkwidget.c:1169
#: gtk/gtkwidget.c:1171
msgid "Margin on Start"
msgstr "Hasierako marjina"
#: gtk/gtkwidget.c:1170
#: gtk/gtkwidget.c:1172
msgid "Pixels of extra space on the start"
msgstr "Hasierako tarte gehigarriaren pixelak"
#: gtk/gtkwidget.c:1187
#: gtk/gtkwidget.c:1189
msgid "Margin on End"
msgstr "Amaierako marjina"
#: gtk/gtkwidget.c:1188
#: gtk/gtkwidget.c:1190
msgid "Pixels of extra space on the end"
msgstr "Amaierako tarte gehigarriaren pixelak"
#: gtk/gtkwidget.c:1204
#: gtk/gtkwidget.c:1206
msgid "Margin on Top"
msgstr "Marjina goian"
#: gtk/gtkwidget.c:1205
#: gtk/gtkwidget.c:1207
msgid "Pixels of extra space on the top side"
msgstr "Goi aldeko tarte gehigarriaren pixelak"
#: gtk/gtkwidget.c:1221
#: gtk/gtkwidget.c:1223
msgid "Margin on Bottom"
msgstr "Marjina behean"
#: gtk/gtkwidget.c:1222
#: gtk/gtkwidget.c:1224
msgid "Pixels of extra space on the bottom side"
msgstr "Leku gehigarriaren pixelak beheko alboan"
#: gtk/gtkwidget.c:1235
#: gtk/gtkwidget.c:1237
msgid "All Margins"
msgstr "Marjina guztiak"
#: gtk/gtkwidget.c:1236
#: gtk/gtkwidget.c:1238
msgid "Pixels of extra space on all four sides"
msgstr "Leku gehigarriaren pixelak lau alboetan"
#: gtk/gtkwidget.c:1248
#: gtk/gtkwidget.c:1250
msgid "Horizontal Expand"
msgstr "Betegarri horizontala"
#: gtk/gtkwidget.c:1249
#: gtk/gtkwidget.c:1251
msgid "Whether widget wants more horizontal space"
msgstr "Trepetak tarte horizontal gehiago nahi duen edo ez"
#: gtk/gtkwidget.c:1260
#: gtk/gtkwidget.c:1262
msgid "Horizontal Expand Set"
msgstr "Betegarri horizontala ezarrita"
#: gtk/gtkwidget.c:1261
#: gtk/gtkwidget.c:1263
msgid "Whether to use the hexpand property"
msgstr "'hexpand' (betegarri horizontala) propietatea erabiliko den edo ez"
#: gtk/gtkwidget.c:1272
#: gtk/gtkwidget.c:1274
msgid "Vertical Expand"
msgstr "Betegarri bertikala"
#: gtk/gtkwidget.c:1273
#: gtk/gtkwidget.c:1275
msgid "Whether widget wants more vertical space"
msgstr "Trepetak tarte bertikal gehiago nahi duen edo ez"
#: gtk/gtkwidget.c:1284
#: gtk/gtkwidget.c:1286
msgid "Vertical Expand Set"
msgstr "Betegarri bertikala ezarrita"
#: gtk/gtkwidget.c:1285
#: gtk/gtkwidget.c:1287
msgid "Whether to use the vexpand property"
msgstr "'vexpand' (betegarri bertikala) propietatea erabiliko den edo ez"
#: gtk/gtkwidget.c:1296
#: gtk/gtkwidget.c:1298
msgid "Expand Both"
msgstr "Zabaldu biak"
#: gtk/gtkwidget.c:1297
#: gtk/gtkwidget.c:1299
msgid "Whether widget wants to expand in both directions"
msgstr "Trepetak bi norabideetan zabaltzea nahi duen edo ez"
#: gtk/gtkwidget.c:1311
#: gtk/gtkwidget.c:1313
msgid "Opacity for Widget"
msgstr "Trepetaren opakutasuna"
#: gtk/gtkwidget.c:1312
#: gtk/gtkwidget.c:1314
msgid "The opacity of the widget, from 0 to 1"
msgstr "Trepetaren opakutasuna, 0 eta 1 artekoa"
#: gtk/gtkwidget.c:1324
#: gtk/gtkwidget.c:1326
msgid "Overflow"
msgstr "Gainezkatzea"
#: gtk/gtkwidget.c:1325
#: gtk/gtkwidget.c:1327
msgid "How content outside the widgets content area is treated"
msgstr "Trepetaren eduki-areatik kanpoko edukia nola tratatuko den"
#: gtk/gtkwidget.c:1338
#: gtk/gtkwidget.c:1340
msgid "Scale factor"
msgstr "Eskalatzeko faktorea"
#: gtk/gtkwidget.c:1339
#: gtk/gtkwidget.c:1341
msgid "The scaling factor of the window"
msgstr "Leihoaren eskalatzeko faktorea"
#: gtk/gtkwidget.c:1351
#: gtk/gtkwidget.c:1353
msgid "CSS Name"
msgstr "CSS izena"
#: gtk/gtkwidget.c:1352
#: gtk/gtkwidget.c:1354
msgid "The name of this widget in the CSS tree"
msgstr "Trepetaren honen izena CSS zuhaitzean"
#: gtk/gtkwidget.c:1364
#: gtk/gtkwidget.c:1366
msgid "Layout Manager"
msgstr "Diseinu-kudeatzailea"
#: gtk/gtkwidget.c:1365
#: gtk/gtkwidget.c:1367
msgid "The layout manager used to layout children of the widget"
msgstr "Trepetaren haurrak diseinatzeko erabilitako diseinu-kudeatzailea"
+322 -267
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -287,7 +287,6 @@ gtk/gtkswitch.c
gtk/gtktextbuffer.c
gtk/gtktext.c
gtk/gtktextchild.c
gtk/gtktextdisplay.c
gtk/gtktexthandle.c
gtk/gtktextiter.c
gtk/gtktextlayout.c
+1
View File
@@ -19,6 +19,7 @@ demos/gtk-demo/filtermodel.ui
demos/gtk-demo/fishbowl.ui
demos/gtk-demo/font_features.c
demos/gtk-demo/font-features.ui
demos/gtk-demo/fontrendering.ui
demos/gtk-demo/iconview.c
demos/gtk-demo/infobar.c
demos/gtk-demo/listbox.ui
+1 -1
View File
@@ -3380,7 +3380,7 @@ msgstr "Dreceres de cerca"
#: gtk/gtkshortcutswindow.c:1039 gtk/ui/gtkemojichooser.ui:320
#: gtk/ui/gtkfilechooserwidget.ui:293
msgid "No Results Found"
msgstr "No s'ha trobat cap tipus de lletra"
msgstr "No s'ha trobat cap resultat"
#: gtk/gtkshortcutswindow.c:1045 gtk/ui/gtkemojichooser.ui:333
#: gtk/ui/gtkfilechooserwidget.ui:306 gtk/ui/gtkplacesview.ui:247
+132 -121
View File
@@ -16,15 +16,15 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk+.master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-06-23 07:58+0000\n"
"PO-Revision-Date: 2019-06-24 09:57+0200\n"
"POT-Creation-Date: 2019-07-30 05:07+0000\n"
"PO-Revision-Date: 2019-07-30 09:27+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: es <gnome-es-list@gnome.org>\n"
"Language: es\n"
"Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Gtranslator 3.32.0\n"
"X-Generator: Gtranslator 3.32.1\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: gdk/broadway/gdkbroadway-server.c:133
@@ -64,15 +64,15 @@ msgstr "No se soporta arrastrar y soltar desde otras aplicaciones."
msgid "No compatible formats to transfer contents."
msgstr "No hay formatos compatibles para transferir el contenido."
#: gdk/gdksurface.c:1160
#: gdk/gdksurface.c:1157
msgid "GL support disabled via GDK_DEBUG"
msgstr "Soporte de GL desactivado mediante GDK_DEBUG"
#: gdk/gdksurface.c:1171
#: gdk/gdksurface.c:1168
msgid "The current backend does not support OpenGL"
msgstr "El «backend» actual no soporta OpenGL"
#: gdk/gdksurface.c:1279
#: gdk/gdksurface.c:1276
msgid "Vulkan support disabled via GDK_DEBUG"
msgstr "Soporte de Vulkan desactivado mediante GDK_DEBUG"
@@ -701,13 +701,13 @@ msgstr "COLORES"
#: gdk/x11/gdkapplaunchcontext-x11.c:292
#, c-format
msgid "Starting %s"
msgstr "Iniciando %s"
msgid "Starting %s"
msgstr "Iniciando «%s»"
#: gdk/x11/gdkapplaunchcontext-x11.c:305
#, c-format
msgid "Opening %s"
msgstr "Abriendo %s"
msgid "Opening %s"
msgstr "Abriendo «%s»"
#: gdk/x11/gdkapplaunchcontext-x11.c:310
#, c-format
@@ -887,15 +887,15 @@ msgctxt "Stock label"
msgid "_Close"
msgstr "_Cerrar"
#: gtk/a11y/gtkimageaccessible.c:60 gtk/gtkheaderbar.c:421 gtk/gtkwindow.c:6721
#: gtk/a11y/gtkimageaccessible.c:60 gtk/gtkheaderbar.c:421 gtk/gtkwindow.c:6737
msgid "Minimize"
msgstr "Minimizar"
#: gtk/a11y/gtkimageaccessible.c:61 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6730
#: gtk/a11y/gtkimageaccessible.c:61 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6746
msgid "Maximize"
msgstr "Maximizar"
#: gtk/a11y/gtkimageaccessible.c:62 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6687
#: gtk/a11y/gtkimageaccessible.c:62 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6703
msgid "Restore"
msgstr "Restaurar"
@@ -1883,20 +1883,20 @@ msgid "White"
msgstr "Blanco"
#. translators: label for the custom section in the color chooser
#: gtk/gtkcolorchooserwidget.c:551
#: gtk/gtkcolorchooserwidget.c:549
msgid "Custom"
msgstr "Personalizada"
#: gtk/gtkcolorchooserwidget.c:562
#: gtk/gtkcolorchooserwidget.c:560
msgid "Custom color"
msgstr "Color personalizado"
# C en conflicto con Cancelar
#: gtk/gtkcolorchooserwidget.c:563
#: gtk/gtkcolorchooserwidget.c:561
msgid "Create a custom color"
msgstr "Crear un color personalizado"
#: gtk/gtkcolorchooserwidget.c:582
#: gtk/gtkcolorchooserwidget.c:580
#, c-format
msgid "Custom color %d: %s"
msgstr "Color personalizado %d: %s"
@@ -1915,7 +1915,7 @@ msgctxt "Color channel"
msgid "Alpha"
msgstr "Alfa"
#: gtk/gtkcolorswatch.c:289
#: gtk/gtkcolorswatch.c:287
msgid "Customize"
msgstr "Personalizar"
@@ -1983,7 +1983,7 @@ msgstr "_Derecho:"
msgid "Paper Margins"
msgstr "Márgenes del papel"
#: gtk/gtkentry.c:3502
#: gtk/gtkentry.c:3527
msgid "Insert Emoji"
msgstr "Insertar emoticono"
@@ -2065,12 +2065,12 @@ msgid "A file with that name already exists"
msgstr "Ya existe un archivo con ese nombre"
#: gtk/gtkfilechoosernative.c:525 gtk/gtkfilechoosernative.c:603
#: gtk/gtkfilechooserwidget.c:1464 gtk/gtkfilechooserwidget.c:6322
#: gtk/gtkfilechooserwidget.c:1464 gtk/gtkfilechooserwidget.c:6334
#: gtk/gtkmessagedialog.c:791 gtk/gtkmessagedialog.c:800
#: gtk/gtkmountoperation.c:543 gtk/gtkpagesetupunixdialog.c:210
#: gtk/gtkmountoperation.c:592 gtk/gtkpagesetupunixdialog.c:210
#: gtk/gtkprintbackend.c:657 gtk/gtkprinteroptionwidget.c:545
#: gtk/gtkprintunixdialog.c:680 gtk/gtkprintunixdialog.c:746
#: gtk/gtkwindow.c:9009 gtk/inspector/css-editor.c:237
#: gtk/gtkwindow.c:9026 gtk/inspector/css-editor.c:237
#: gtk/inspector/recorder.c:1026 gtk/ui/gtkappchooserdialog.ui:46
#: gtk/ui/gtkassistant.ui:50 gtk/ui/gtkcolorchooserdialog.ui:28
#: gtk/ui/gtkfontchooserdialog.ui:22
@@ -2172,7 +2172,7 @@ msgid "If you delete an item, it will be permanently lost."
msgstr "Si elimina un elemento, se perderña definitivamente."
#: gtk/gtkfilechooserwidget.c:1465 gtk/gtkfilechooserwidget.c:2199
#: gtk/gtklabel.c:6096 gtk/gtktext.c:5768 gtk/gtktextview.c:8628
#: gtk/gtklabel.c:6106 gtk/gtktext.c:5781 gtk/gtktextview.c:8667
msgid "_Delete"
msgstr "_Eliminar"
@@ -2218,7 +2218,6 @@ msgid "Show _Size Column"
msgstr "Mostrar columna de _tamaño"
#: gtk/gtkfilechooserwidget.c:2206
#| msgid "Show _Size Column"
msgid "Show T_ype Column"
msgstr "Mostrar columna de t_ipo"
@@ -2231,169 +2230,162 @@ msgid "Sort _Folders before Files"
msgstr "Ordenar _carpetas antes que archivos"
#. this is the header for the location column in the print dialog
#: gtk/gtkfilechooserwidget.c:2509 gtk/inspector/css-node-tree.ui:133
#: gtk/gtkfilechooserwidget.c:2505 gtk/inspector/css-node-tree.ui:133
#: gtk/ui/gtkfilechooserwidget.ui:194 gtk/ui/gtkprintunixdialog.ui:108
msgid "Location"
msgstr "Lugar"
#. Label
#: gtk/gtkfilechooserwidget.c:2602
#: gtk/gtkfilechooserwidget.c:2598
msgid "_Name:"
msgstr "_Nombre:"
#: gtk/gtkfilechooserwidget.c:3226 gtk/gtkfilechooserwidget.c:3240
#: gtk/gtkfilechooserwidget.c:3239 gtk/gtkfilechooserwidget.c:3253
#, c-format
msgid "Searching in %s"
msgstr "Buscando en %s"
#: gtk/gtkfilechooserwidget.c:3246
#: gtk/gtkfilechooserwidget.c:3259
msgid "Searching"
msgstr "Buscando"
#: gtk/gtkfilechooserwidget.c:3253
#: gtk/gtkfilechooserwidget.c:3266
msgid "Enter location"
msgstr "Introducir ubicación"
#: gtk/gtkfilechooserwidget.c:3255
#: gtk/gtkfilechooserwidget.c:3268
msgid "Enter location or URL"
msgstr "Introducir ubicación o URL"
#: gtk/gtkfilechooserwidget.c:4263 gtk/gtkfilechooserwidget.c:7232
#: gtk/gtkfilechooserwidget.c:4275 gtk/gtkfilechooserwidget.c:7244
#: gtk/ui/gtkfilechooserwidget.ui:234
msgid "Modified"
msgstr "Modificado"
#: gtk/gtkfilechooserwidget.c:4541
#: gtk/gtkfilechooserwidget.c:4553
#, c-format
msgid "Could not read the contents of %s"
msgstr "No se pudo leer el contenido de %s"
#: gtk/gtkfilechooserwidget.c:4545
#: gtk/gtkfilechooserwidget.c:4557
msgid "Could not read the contents of the folder"
msgstr "No se pudo leer el contenido del la carpeta"
#. Translators: see g_date_time_format() for details on the format
#: gtk/gtkfilechooserwidget.c:4670 gtk/gtkfilechooserwidget.c:4714
#: gtk/gtkfilechooserwidget.c:4682 gtk/gtkfilechooserwidget.c:4726
msgid "%H:%M"
msgstr "%H:%M"
#: gtk/gtkfilechooserwidget.c:4672 gtk/gtkfilechooserwidget.c:4716
#: gtk/gtkfilechooserwidget.c:4684 gtk/gtkfilechooserwidget.c:4728
msgid "%l:%M %p"
msgstr "%l:%M %p"
#: gtk/gtkfilechooserwidget.c:4676
#: gtk/gtkfilechooserwidget.c:4688
msgid "Yesterday"
msgstr "Ayer"
#: gtk/gtkfilechooserwidget.c:4684
#: gtk/gtkfilechooserwidget.c:4696
msgid "%-e %b"
msgstr "%-e %b"
#: gtk/gtkfilechooserwidget.c:4688
#: gtk/gtkfilechooserwidget.c:4700
msgid "%-e %b %Y"
msgstr "%-e %b %Y"
#: gtk/gtkfilechooserwidget.c:4778 gtk/gtkfilechooserwidget.c:4786
#: gtk/gtkfilechooserwidget.c:4790 gtk/gtkfilechooserwidget.c:4798
msgid "Program"
msgstr "Programa"
#: gtk/gtkfilechooserwidget.c:4779
#| msgctxt "keyboard label"
#| msgid "AudioMute"
#: gtk/gtkfilechooserwidget.c:4791
msgid "Audio"
msgstr "Sonido"
#: gtk/gtkfilechooserwidget.c:4780 gtk/gtkfontbutton.c:611
#: gtk/gtkfilechooserwidget.c:4792 gtk/gtkfontbutton.c:611
#: gtk/inspector/visual.ui:187
msgid "Font"
msgstr "Tipografía"
#: gtk/gtkfilechooserwidget.c:4781
#: gtk/gtkfilechooserwidget.c:4793
msgid "Image"
msgstr "Imagen"
#: gtk/gtkfilechooserwidget.c:4782
#| msgctxt "paper size"
#| msgid "Arch A"
#: gtk/gtkfilechooserwidget.c:4794
msgid "Archive"
msgstr "Archivador"
#: gtk/gtkfilechooserwidget.c:4783
#: gtk/gtkfilechooserwidget.c:4795
msgid "Markup"
msgstr "Marcado"
#: gtk/gtkfilechooserwidget.c:4784 gtk/gtkfilechooserwidget.c:4785
#: gtk/gtkfilechooserwidget.c:4796 gtk/gtkfilechooserwidget.c:4797
msgid "Text"
msgstr "Texto"
#: gtk/gtkfilechooserwidget.c:4787
#: gtk/gtkfilechooserwidget.c:4799
msgid "Video"
msgstr "Vídeo"
#: gtk/gtkfilechooserwidget.c:4788
#: gtk/gtkfilechooserwidget.c:4800
msgid "Contacts"
msgstr "Contactos"
#: gtk/gtkfilechooserwidget.c:4789
#| msgid "calendar:MY"
#: gtk/gtkfilechooserwidget.c:4801
msgid "Calendar"
msgstr "Calendario"
#: gtk/gtkfilechooserwidget.c:4790
#| msgid "Documented by"
#: gtk/gtkfilechooserwidget.c:4802
msgid "Document"
msgstr "Documento"
#: gtk/gtkfilechooserwidget.c:4791
#| msgid "_Orientation:"
#: gtk/gtkfilechooserwidget.c:4803
msgid "Presentation"
msgstr "Presentación"
#: gtk/gtkfilechooserwidget.c:4792
#: gtk/gtkfilechooserwidget.c:4804
msgid "Spreadsheet"
msgstr "Hoja de cálculo"
#. Translators: We don't know whether this printer is
#. * available to print to.
#: gtk/gtkfilechooserwidget.c:4823 gtk/gtkfilechooserwidget.c:5007
#: gtk/gtkfilechooserwidget.c:4835 gtk/gtkfilechooserwidget.c:5019
#: gtk/inspector/prop-editor.c:1506
#: modules/printbackends/gtkprintbackendcloudprint.c:731
msgid "Unknown"
msgstr "Desconocido"
#: gtk/gtkfilechooserwidget.c:5046 gtk/gtkplacessidebar.c:1087
#: gtk/gtkfilechooserwidget.c:5058 gtk/gtkplacessidebar.c:1087
msgid "Home"
msgstr "Carpeta personal"
#: gtk/gtkfilechooserwidget.c:5540
#: gtk/gtkfilechooserwidget.c:5552
msgid "Cannot change to folder because it is not local"
msgstr "No se pudo cambiar a la carpeta porque no es local"
#: gtk/gtkfilechooserwidget.c:6315 gtk/gtkprintunixdialog.c:671
#: gtk/gtkfilechooserwidget.c:6327 gtk/gtkprintunixdialog.c:671
#, c-format
msgid "A file named “%s” already exists. Do you want to replace it?"
msgstr "Ya existe un archivo llamado «%s». ¿Quiere reemplazarlo?"
#: gtk/gtkfilechooserwidget.c:6318 gtk/gtkprintunixdialog.c:675
#: gtk/gtkfilechooserwidget.c:6330 gtk/gtkprintunixdialog.c:675
#, c-format
msgid ""
"The file already exists in “%s”. Replacing it will overwrite its contents."
msgstr ""
"El archivo ya existe en «%s». Si lo reemplaza sobrescribirá su contenido."
#: gtk/gtkfilechooserwidget.c:6323 gtk/gtkprintunixdialog.c:683
#: gtk/gtkfilechooserwidget.c:6335 gtk/gtkprintunixdialog.c:683
msgid "_Replace"
msgstr "_Reemplazar"
#: gtk/gtkfilechooserwidget.c:6531
#: gtk/gtkfilechooserwidget.c:6543
msgid "You do not have access to the specified folder."
msgstr "No tiene acceso a la carpeta especificada."
#: gtk/gtkfilechooserwidget.c:7155
#: gtk/gtkfilechooserwidget.c:7167
msgid "Could not send the search request"
msgstr "No se ha podido enviar la petición de búsqueda"
#: gtk/gtkfilechooserwidget.c:7450
#: gtk/gtkfilechooserwidget.c:7462
msgid "Accessed"
msgstr "Accedido"
@@ -2476,7 +2468,7 @@ msgstr "Falló al crear el contexto de OpenGL"
msgid "Application menu"
msgstr "Menú de la aplicación"
#: gtk/gtkheaderbar.c:462 gtk/gtkwindow.c:6757
#: gtk/gtkheaderbar.c:462 gtk/gtkwindow.c:6773
msgid "Close"
msgstr "Cerrar"
@@ -2505,27 +2497,27 @@ msgstr "Advertencia"
msgid "Error"
msgstr "Error"
#: gtk/gtklabel.c:6093 gtk/gtktext.c:5756 gtk/gtktextview.c:8616
#: gtk/gtklabel.c:6103 gtk/gtktext.c:5769 gtk/gtktextview.c:8655
msgid "Cu_t"
msgstr "Cor_tar"
#: gtk/gtklabel.c:6094 gtk/gtktext.c:5760 gtk/gtktextview.c:8620
#: gtk/gtklabel.c:6104 gtk/gtktext.c:5773 gtk/gtktextview.c:8659
msgid "_Copy"
msgstr "_Copiar"
#: gtk/gtklabel.c:6095 gtk/gtktext.c:5764 gtk/gtktextview.c:8624
#: gtk/gtklabel.c:6105 gtk/gtktext.c:5777 gtk/gtktextview.c:8663
msgid "_Paste"
msgstr "_Pegar"
#: gtk/gtklabel.c:6101 gtk/gtktext.c:5777 gtk/gtktextview.c:8637
#: gtk/gtklabel.c:6111 gtk/gtktext.c:5790 gtk/gtktextview.c:8676
msgid "Select _All"
msgstr "Seleccionar _todo"
#: gtk/gtklabel.c:6106
#: gtk/gtklabel.c:6116
msgid "_Open Link"
msgstr "_Abrir enlace"
#: gtk/gtklabel.c:6110
#: gtk/gtklabel.c:6120
msgid "Copy _Link Address"
msgstr "Copiar la dirección del _enlace"
@@ -2574,7 +2566,7 @@ msgstr ""
#. * Do *not* translate it to "predefinito:LTR", if it
#. * it isn't default:LTR or default:RTL it will not work
#.
#: gtk/gtkmain.c:976
#: gtk/gtkmain.c:977
msgid "default:LTR"
msgstr "default:LTR"
@@ -2627,7 +2619,7 @@ msgid "%d:%02d"
msgstr "%d:%02d"
#: gtk/gtkmessagedialog.c:783 gtk/gtkmessagedialog.c:801
#: gtk/gtkprintbackend.c:658 gtk/gtkwindow.c:9010
#: gtk/gtkprintbackend.c:658 gtk/gtkwindow.c:9027
msgid "_OK"
msgstr "_Aceptar"
@@ -2639,57 +2631,73 @@ msgstr "_No"
msgid "_Yes"
msgstr "_Sí"
#: gtk/gtkmountoperation.c:544
#: gtk/gtkmountoperation.c:593
msgid "Co_nnect"
msgstr "Co_nectar"
#: gtk/gtkmountoperation.c:611
#: gtk/gtkmountoperation.c:660
msgid "Connect As"
msgstr "Conectar como"
#: gtk/gtkmountoperation.c:620
#: gtk/gtkmountoperation.c:669
msgid "_Anonymous"
msgstr "_Anónimo"
#: gtk/gtkmountoperation.c:628
#: gtk/gtkmountoperation.c:677
msgid "Registered U_ser"
msgstr "U_suario registrado"
#: gtk/gtkmountoperation.c:638
#: gtk/gtkmountoperation.c:687
msgid "_Username"
msgstr "Nombre de _usuario"
#: gtk/gtkmountoperation.c:643
#: gtk/gtkmountoperation.c:692
msgid "_Domain"
msgstr "_Dominio"
#: gtk/gtkmountoperation.c:649
#: gtk/gtkmountoperation.c:701
msgid "Volume type"
msgstr "Tipo de volumen"
#: gtk/gtkmountoperation.c:711
msgid "_Hidden"
msgstr "_Oculto"
#: gtk/gtkmountoperation.c:714
msgid "_Windows system"
msgstr "Sistema _Windows"
#: gtk/gtkmountoperation.c:717
msgid "_PIM"
msgstr "_PIM"
#: gtk/gtkmountoperation.c:723
msgid "_Password"
msgstr "_Contraseña"
#: gtk/gtkmountoperation.c:671
#: gtk/gtkmountoperation.c:745
msgid "Forget password _immediately"
msgstr "Olvidar contraseña _inmediatamente"
#: gtk/gtkmountoperation.c:681
#: gtk/gtkmountoperation.c:755
msgid "Remember password until you _logout"
msgstr "Recordar la contraseña hasta _salir de la sesión"
#: gtk/gtkmountoperation.c:691
#: gtk/gtkmountoperation.c:765
msgid "Remember _forever"
msgstr "_Recordar para siempre"
#: gtk/gtkmountoperation.c:1080
#: gtk/gtkmountoperation.c:1160
#, c-format
msgid "Unknown Application (PID %d)"
msgstr "Aplicación desconocida (PID %d)"
#: gtk/gtkmountoperation.c:1265
#: gtk/gtkmountoperation.c:1345
#, c-format
msgid "Unable to end process"
msgstr "No se pudo finalizar el proceso"
#: gtk/gtkmountoperation.c:1300
#: gtk/gtkmountoperation.c:1380
msgid "_End Process"
msgstr "_Finalizar proceso"
@@ -2778,7 +2786,7 @@ msgstr "Configuración de página"
msgid "Hide text"
msgstr "Ocultar texto"
#: gtk/gtkpasswordentry.c:136 gtk/gtkpasswordentry.c:488
#: gtk/gtkpasswordentry.c:136 gtk/gtkpasswordentry.c:483
msgid "Show text"
msgstr "Mostrar texto"
@@ -2786,11 +2794,11 @@ msgstr "Mostrar texto"
msgid "Caps Lock is on"
msgstr "Bloq Mayús está activado"
#: gtk/gtkpasswordentry.c:350
#: gtk/gtkpasswordentry.c:344
msgid "Password"
msgstr "Contraseña"
#: gtk/gtkpasswordentry.c:562
#: gtk/gtkpasswordentry.c:557
msgid "_Show Text"
msgstr "_Mostrar texto"
@@ -3087,11 +3095,11 @@ msgstr "_Conectar"
msgid "Unable to get remote server location"
msgstr "No se pudo obtener la ubicación del servidor remoto"
#: gtk/gtkplacesview.c:2026 gtk/gtkplacesview.c:2035
#: gtk/gtkplacesview.c:2038 gtk/gtkplacesview.c:2047
msgid "Networks"
msgstr "Redes"
#: gtk/gtkplacesview.c:2026 gtk/gtkplacesview.c:2035
#: gtk/gtkplacesview.c:2038 gtk/gtkplacesview.c:2047
msgid "On This Computer"
msgstr "En este equipo"
@@ -3358,7 +3366,7 @@ msgstr "De arriba a abajo"
msgid "Bottom to top"
msgstr "De abajo a arriba"
#: gtk/gtkprogressbar.c:626
#: gtk/gtkprogressbar.c:613
#, c-format
msgctxt "progress bar label"
msgid "%.0f%%"
@@ -3472,7 +3480,7 @@ msgstr "No se han encontrado resultados"
msgid "Try a different search"
msgstr "Pruebe una búsqueda diferente"
#: gtk/gtktext.c:5782 gtk/gtktextview.c:8642
#: gtk/gtktext.c:5795 gtk/gtktextview.c:8681
msgid "Insert _Emoji"
msgstr "Insertar _emoticono"
@@ -3539,24 +3547,24 @@ msgctxt "volume percentage"
msgid "%d%%"
msgstr "%d%%"
#: gtk/gtkwindow.c:6705
#: gtk/gtkwindow.c:6721
msgid "Move"
msgstr "Mover"
#: gtk/gtkwindow.c:6713
#: gtk/gtkwindow.c:6729
msgid "Resize"
msgstr "Redimensionar"
#: gtk/gtkwindow.c:6744
#: gtk/gtkwindow.c:6760
msgid "Always on Top"
msgstr "Siempre encima"
#: gtk/gtkwindow.c:8997
#: gtk/gtkwindow.c:9014
#, c-format
msgid "Do you want to use GTK Inspector?"
msgstr "¿Quiere usar el inspector de GTK?"
#: gtk/gtkwindow.c:8999
#: gtk/gtkwindow.c:9016
#, c-format
msgid ""
"GTK Inspector is an interactive debugger that lets you explore and modify "
@@ -3567,7 +3575,7 @@ msgstr ""
"modificar los aspectos internos de cualquier aplicación de GTK. Al usarlo "
"puede hacer que la aplicación falle o se cierre."
#: gtk/gtkwindow.c:9004
#: gtk/gtkwindow.c:9021
msgid "Dont show this message again"
msgstr "No mostrar este mensaje de nuevo"
@@ -3665,25 +3673,25 @@ msgid "Show data"
msgstr "Mostrar los datos"
# src/file-manager/fm-icon-text-window.c:85
#: gtk/inspector/general.c:342
#: gtk/inspector/general.c:343
msgctxt "GL version"
msgid "None"
msgstr "Ninguna"
# src/file-manager/fm-icon-text-window.c:85
#: gtk/inspector/general.c:343
#: gtk/inspector/general.c:344
msgctxt "GL vendor"
msgid "None"
msgstr "Ninguno"
# src/file-manager/fm-icon-text-window.c:85
#: gtk/inspector/general.c:445
#: gtk/inspector/general.c:446
msgctxt "Vulkan device"
msgid "None"
msgstr "Ninguno"
# src/file-manager/fm-icon-text-window.c:85
#: gtk/inspector/general.c:446 gtk/inspector/general.c:447
#: gtk/inspector/general.c:447 gtk/inspector/general.c:448
msgctxt "Vulkan version"
msgid "None"
msgstr "Ninguna"
@@ -3700,39 +3708,43 @@ msgstr "«Backend» de GDK"
msgid "GSK Renderer"
msgstr "Renderizador GSK"
#: gtk/inspector/general.ui:118 gtk/ui/gtkplacesview.ui:77
#: gtk/inspector/general.ui:108
msgid "Pango Fontmap"
msgstr "Mapa de tipografías de Pango"
#: gtk/inspector/general.ui:145 gtk/ui/gtkplacesview.ui:77
msgid "Prefix"
msgstr "Prefijo"
#: gtk/inspector/general.ui:324
#: gtk/inspector/general.ui:351
msgid "Display"
msgstr "Pantalla"
#: gtk/inspector/general.ui:352
#: gtk/inspector/general.ui:379
msgid "RGBA Visual"
msgstr "RGBA visual"
#: gtk/inspector/general.ui:379
#: gtk/inspector/general.ui:406
msgid "Composited"
msgstr "Compuesta"
#: gtk/inspector/general.ui:416
#: gtk/inspector/general.ui:443
msgid "GL Version"
msgstr "Versión de GL"
#: gtk/inspector/general.ui:444
#: gtk/inspector/general.ui:471
msgid "GL Vendor"
msgstr "Fabricante GL"
#: gtk/inspector/general.ui:482
#: gtk/inspector/general.ui:509
msgid "Vulkan Device"
msgstr "Dispositivo vulkan"
#: gtk/inspector/general.ui:510
#: gtk/inspector/general.ui:537
msgid "Vulkan API version"
msgstr "Versión de la API Vulkan"
#: gtk/inspector/general.ui:538
#: gtk/inspector/general.ui:565
msgid "Vulkan driver version"
msgstr "Versión del driver Vulkan"
@@ -7897,6 +7909,9 @@ msgstr "No hay un perfil disponible"
msgid "Unspecified profile"
msgstr "Perfil no especificado"
#~ msgid "Opening %s"
#~ msgstr "Abriendo %s"
#~ msgid "C_ustomize"
#~ msgstr "_Personalizar"
@@ -8195,10 +8210,6 @@ msgstr "Perfil no especificado"
#~ msgid "Cyrillic (Transliterated)"
#~ msgstr "Cirílico (Transliterado)"
#~ msgctxt "input method menu"
#~ msgid "Windows IME"
#~ msgstr "Windows IME"
#~ msgctxt "input method menu"
#~ msgid "Inuktitut (Transliterated)"
#~ msgstr "Inuktitut (Transliterado)"
+151 -99
View File
@@ -5,9 +5,9 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk+ 0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-06-21 22:07+0000\n"
"PO-Revision-Date: 2019-06-22 00:39+0200\n"
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"POT-Creation-Date: 2019-07-18 19:32+0000\n"
"PO-Revision-Date: 2019-07-19 23:19+0200\n"
"Last-Translator: gogo <linux.hr@protonmail.com>\n"
"Language-Team: Croatian <lokalizacija@linux.hr>\n"
"Language: hr\n"
"MIME-Version: 1.0\n"
@@ -876,15 +876,15 @@ msgctxt "Stock label"
msgid "_Close"
msgstr "_Zatvori"
#: gtk/a11y/gtkimageaccessible.c:60 gtk/gtkheaderbar.c:421 gtk/gtkwindow.c:6721
#: gtk/a11y/gtkimageaccessible.c:60 gtk/gtkheaderbar.c:421 gtk/gtkwindow.c:6737
msgid "Minimize"
msgstr "Smanji"
#: gtk/a11y/gtkimageaccessible.c:61 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6730
#: gtk/a11y/gtkimageaccessible.c:61 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6746
msgid "Maximize"
msgstr "Uvećaj"
#: gtk/a11y/gtkimageaccessible.c:62 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6687
#: gtk/a11y/gtkimageaccessible.c:62 gtk/gtkheaderbar.c:444 gtk/gtkwindow.c:6703
msgid "Restore"
msgstr "Vrati"
@@ -1870,19 +1870,19 @@ msgid "White"
msgstr "Bijela"
#. translators: label for the custom section in the color chooser
#: gtk/gtkcolorchooserwidget.c:551
#: gtk/gtkcolorchooserwidget.c:549
msgid "Custom"
msgstr "Prilagođena"
#: gtk/gtkcolorchooserwidget.c:562
#: gtk/gtkcolorchooserwidget.c:560
msgid "Custom color"
msgstr "Prilagođena boja"
#: gtk/gtkcolorchooserwidget.c:563
#: gtk/gtkcolorchooserwidget.c:561
msgid "Create a custom color"
msgstr "Stvori prilagođenu boju"
#: gtk/gtkcolorchooserwidget.c:582
#: gtk/gtkcolorchooserwidget.c:580
#, c-format
msgid "Custom color %d: %s"
msgstr "Prilagođena boja %d: %s"
@@ -1901,7 +1901,7 @@ msgctxt "Color channel"
msgid "Alpha"
msgstr "Alfa"
#: gtk/gtkcolorswatch.c:289
#: gtk/gtkcolorswatch.c:287
msgid "Customize"
msgstr "Prilagodi"
@@ -2050,12 +2050,12 @@ msgid "A file with that name already exists"
msgstr "Datoteka s tim nazivom već postoji"
#: gtk/gtkfilechoosernative.c:525 gtk/gtkfilechoosernative.c:603
#: gtk/gtkfilechooserwidget.c:1450 gtk/gtkfilechooserwidget.c:6150
#: gtk/gtkfilechooserwidget.c:1464 gtk/gtkfilechooserwidget.c:6322
#: gtk/gtkmessagedialog.c:791 gtk/gtkmessagedialog.c:800
#: gtk/gtkmountoperation.c:543 gtk/gtkpagesetupunixdialog.c:210
#: gtk/gtkprintbackend.c:657 gtk/gtkprinteroptionwidget.c:545
#: gtk/gtkprintunixdialog.c:680 gtk/gtkprintunixdialog.c:746
#: gtk/gtkwindow.c:9009 gtk/inspector/css-editor.c:237
#: gtk/gtkwindow.c:9025 gtk/inspector/css-editor.c:237
#: gtk/inspector/recorder.c:1026 gtk/ui/gtkappchooserdialog.ui:46
#: gtk/ui/gtkassistant.ui:50 gtk/ui/gtkcolorchooserdialog.ui:28
#: gtk/ui/gtkfontchooserdialog.ui:22
@@ -2074,7 +2074,7 @@ msgstr "_Otvori"
msgid "_Save"
msgstr "_Spremi"
#: gtk/gtkfilechoosernativequartz.c:331 gtk/ui/gtkfilechooserwidget.ui:350
#: gtk/gtkfilechoosernativequartz.c:331 gtk/ui/gtkfilechooserwidget.ui:362
msgid "Select which types of files are shown"
msgstr "Odaberi koje vrste datoteka se prikazuju"
@@ -2087,15 +2087,15 @@ msgstr "Odaberi koje vrste datoteka se prikazuju"
msgid "%1$s on %2$s"
msgstr "%1$s na %2$s"
#: gtk/gtkfilechooserwidget.c:381
#: gtk/gtkfilechooserwidget.c:393
msgid "Type name of new folder"
msgstr "Upišite naziv nove mape"
#: gtk/gtkfilechooserwidget.c:773
#: gtk/gtkfilechooserwidget.c:787
msgid "The folder could not be created"
msgstr "Mapa nije mogla biti stvorena"
#: gtk/gtkfilechooserwidget.c:786
#: gtk/gtkfilechooserwidget.c:800
msgid ""
"The folder could not be created, as a file with the same name already "
"exists. Try using a different name for the folder, or rename the file first."
@@ -2103,213 +2103,271 @@ msgstr ""
"Mapa nije mogla biti stvorena, jer već postoji datoteka s istim nazivom. "
"Pokušajte koristiti drugi naziv za mapu, ili prvo preimenujte datoteku."
#: gtk/gtkfilechooserwidget.c:801
#: gtk/gtkfilechooserwidget.c:815
msgid "You need to choose a valid filename."
msgstr "Morate odabrati valjani naziv datoteke."
#: gtk/gtkfilechooserwidget.c:804
#: gtk/gtkfilechooserwidget.c:818
#, c-format
msgid "Cannot create a file under %s as it is not a folder"
msgstr "Nemoguće stvaranje datoteke unutar %s pošto nije mapa"
#: gtk/gtkfilechooserwidget.c:814
#: gtk/gtkfilechooserwidget.c:828
msgid "Cannot create file as the filename is too long"
msgstr "Nemoguće stvaranje datoteke je je naziv predugačak"
#: gtk/gtkfilechooserwidget.c:815
#: gtk/gtkfilechooserwidget.c:829
msgid "Try using a shorter name."
msgstr "Pokušajte koristiti kraći naziv."
#: gtk/gtkfilechooserwidget.c:825
#: gtk/gtkfilechooserwidget.c:839
msgid "You may only select folders"
msgstr "Možete odabrati samo mape"
#: gtk/gtkfilechooserwidget.c:826
#: gtk/gtkfilechooserwidget.c:840
msgid "The item that you selected is not a folder try using a different item."
msgstr "Stavka koju ste odabrali nije mapa, pokušajte odabrati drugu stavku."
#: gtk/gtkfilechooserwidget.c:834
#: gtk/gtkfilechooserwidget.c:848
msgid "Invalid file name"
msgstr "Neispravni naziv datoteke"
#: gtk/gtkfilechooserwidget.c:843
#: gtk/gtkfilechooserwidget.c:857
msgid "The folder contents could not be displayed"
msgstr "Sadržaj mape nije mogao biti prikazan"
#: gtk/gtkfilechooserwidget.c:851
#: gtk/gtkfilechooserwidget.c:865
msgid "The file could not be deleted"
msgstr "Datoteku je nemoguće obrisati"
#: gtk/gtkfilechooserwidget.c:859
#: gtk/gtkfilechooserwidget.c:873
msgid "The file could not be moved to the Trash"
msgstr "Datoteka se ne može premjestiti u smeće"
#: gtk/gtkfilechooserwidget.c:1446
#: gtk/gtkfilechooserwidget.c:1460
#, c-format
msgid "Are you sure you want to permanently delete “%s”?"
msgstr "Sigurno želite trajno obrisati “%s”?"
#: gtk/gtkfilechooserwidget.c:1449
#: gtk/gtkfilechooserwidget.c:1463
#, c-format
msgid "If you delete an item, it will be permanently lost."
msgstr "Ako obrišete stavku, biti će trajno izgubljena."
#: gtk/gtkfilechooserwidget.c:1451 gtk/gtkfilechooserwidget.c:2168
#: gtk/gtklabel.c:6096 gtk/gtktext.c:5810 gtk/gtktextview.c:8629
#: gtk/gtkfilechooserwidget.c:1465 gtk/gtkfilechooserwidget.c:2199
#: gtk/gtklabel.c:6096 gtk/gtktext.c:5772 gtk/gtktextview.c:8628
msgid "_Delete"
msgstr "_Obriši"
#: gtk/gtkfilechooserwidget.c:1578
#: gtk/gtkfilechooserwidget.c:1592
msgid "The file could not be renamed"
msgstr "Datoteka ne može biti preimenovana"
#: gtk/gtkfilechooserwidget.c:1820
#: gtk/gtkfilechooserwidget.c:1850
msgid "Could not select file"
msgstr "Nemoguć odabir datoteke"
#: gtk/gtkfilechooserwidget.c:2163
#: gtk/gtkfilechooserwidget.c:2194
msgid "_Visit File"
msgstr "_Posjeti datoteku"
#: gtk/gtkfilechooserwidget.c:2164
#: gtk/gtkfilechooserwidget.c:2195
msgid "_Open With File Manager"
msgstr "_Otvori s preglednikom datoteka"
#: gtk/gtkfilechooserwidget.c:2165
#: gtk/gtkfilechooserwidget.c:2196
msgid "_Copy Location"
msgstr "_Kopiraj lokaciju"
#: gtk/gtkfilechooserwidget.c:2166
#: gtk/gtkfilechooserwidget.c:2197
msgid "_Add to Bookmarks"
msgstr "_Dodaj u zabilješke"
#: gtk/gtkfilechooserwidget.c:2167 gtk/gtkplacessidebar.c:2690
#: gtk/ui/gtkfilechooserwidget.ui:470
#: gtk/gtkfilechooserwidget.c:2198 gtk/gtkplacessidebar.c:2690
#: gtk/ui/gtkfilechooserwidget.ui:482
msgid "_Rename"
msgstr "_Preimenuj"
#: gtk/gtkfilechooserwidget.c:2169
#: gtk/gtkfilechooserwidget.c:2200
msgid "_Move to Trash"
msgstr "_Premjesti u smeće"
#: gtk/gtkfilechooserwidget.c:2173
#: gtk/gtkfilechooserwidget.c:2204
msgid "Show _Hidden Files"
msgstr "Prikaži _skrivene datoteke"
#: gtk/gtkfilechooserwidget.c:2174
#: gtk/gtkfilechooserwidget.c:2205
msgid "Show _Size Column"
msgstr "Prikaži _stupac veličine"
#: gtk/gtkfilechooserwidget.c:2175
#: gtk/gtkfilechooserwidget.c:2206
msgid "Show T_ype Column"
msgstr "Prikaži s_tupac vrste"
#: gtk/gtkfilechooserwidget.c:2207
msgid "Show _Time"
msgstr "Prikaži _vrijeme"
#: gtk/gtkfilechooserwidget.c:2176
#: gtk/gtkfilechooserwidget.c:2208
msgid "Sort _Folders before Files"
msgstr "Poredaj _mape prije datoteka"
#. this is the header for the location column in the print dialog
#: gtk/gtkfilechooserwidget.c:2473 gtk/inspector/css-node-tree.ui:133
#: gtk/gtkfilechooserwidget.c:2509 gtk/inspector/css-node-tree.ui:133
#: gtk/ui/gtkfilechooserwidget.ui:194 gtk/ui/gtkprintunixdialog.ui:108
msgid "Location"
msgstr "Lokacija"
#. Label
#: gtk/gtkfilechooserwidget.c:2566
#: gtk/gtkfilechooserwidget.c:2602
msgid "_Name:"
msgstr "_Naziv:"
#: gtk/gtkfilechooserwidget.c:3190 gtk/gtkfilechooserwidget.c:3204
#: gtk/gtkfilechooserwidget.c:3226 gtk/gtkfilechooserwidget.c:3240
#, c-format
msgid "Searching in %s"
msgstr "Pretražujem u %s"
#: gtk/gtkfilechooserwidget.c:3210
#: gtk/gtkfilechooserwidget.c:3246
msgid "Searching"
msgstr "Pretraživanje"
#: gtk/gtkfilechooserwidget.c:3217
#: gtk/gtkfilechooserwidget.c:3253
msgid "Enter location"
msgstr "Upiši lokaciju"
#: gtk/gtkfilechooserwidget.c:3219
#: gtk/gtkfilechooserwidget.c:3255
msgid "Enter location or URL"
msgstr "Upiši URL lokacije"
#: gtk/gtkfilechooserwidget.c:4185 gtk/gtkfilechooserwidget.c:7059
#: gtk/ui/gtkfilechooserwidget.ui:222
#: gtk/gtkfilechooserwidget.c:4263 gtk/gtkfilechooserwidget.c:7232
#: gtk/ui/gtkfilechooserwidget.ui:234
msgid "Modified"
msgstr "Mijenjano"
#: gtk/gtkfilechooserwidget.c:4463
#: gtk/gtkfilechooserwidget.c:4541
#, c-format
msgid "Could not read the contents of %s"
msgstr "Nemoguće pročitati sadržaj %s"
#: gtk/gtkfilechooserwidget.c:4467
#: gtk/gtkfilechooserwidget.c:4545
msgid "Could not read the contents of the folder"
msgstr "Nemoguće čitanje sadržaja mape"
#. Translators: see g_date_time_format() for details on the format
#: gtk/gtkfilechooserwidget.c:4592 gtk/gtkfilechooserwidget.c:4636
#: gtk/gtkfilechooserwidget.c:4670 gtk/gtkfilechooserwidget.c:4714
msgid "%H:%M"
msgstr "%H:%M"
#: gtk/gtkfilechooserwidget.c:4594 gtk/gtkfilechooserwidget.c:4638
#: gtk/gtkfilechooserwidget.c:4672 gtk/gtkfilechooserwidget.c:4716
msgid "%l:%M %p"
msgstr "%l:%M %p"
#: gtk/gtkfilechooserwidget.c:4598
#: gtk/gtkfilechooserwidget.c:4676
msgid "Yesterday"
msgstr "Jučer"
#: gtk/gtkfilechooserwidget.c:4606
#: gtk/gtkfilechooserwidget.c:4684
msgid "%-e %b"
msgstr "%-e %b"
#: gtk/gtkfilechooserwidget.c:4610
#: gtk/gtkfilechooserwidget.c:4688
msgid "%-e %b %Y"
msgstr "%-e %b %Y"
#: gtk/gtkfilechooserwidget.c:4778 gtk/gtkfilechooserwidget.c:4786
msgid "Program"
msgstr "Program"
#: gtk/gtkfilechooserwidget.c:4779
msgid "Audio"
msgstr "Zvuk"
#: gtk/gtkfilechooserwidget.c:4780 gtk/gtkfontbutton.c:611
#: gtk/inspector/visual.ui:187
msgid "Font"
msgstr "Slova"
#: gtk/gtkfilechooserwidget.c:4781
msgid "Image"
msgstr "Slika"
#: gtk/gtkfilechooserwidget.c:4782
msgid "Archive"
msgstr "Arhiva"
#: gtk/gtkfilechooserwidget.c:4783
msgid "Markup"
msgstr "Oznaka"
#: gtk/gtkfilechooserwidget.c:4784 gtk/gtkfilechooserwidget.c:4785
msgid "Text"
msgstr "Tekst"
#: gtk/gtkfilechooserwidget.c:4787
msgid "Video"
msgstr "Video snimka"
#: gtk/gtkfilechooserwidget.c:4788
msgid "Contacts"
msgstr "Kontakti"
#: gtk/gtkfilechooserwidget.c:4789
msgid "Calendar"
msgstr "Kalendar"
#: gtk/gtkfilechooserwidget.c:4790
msgid "Document"
msgstr "Dokument"
#: gtk/gtkfilechooserwidget.c:4791
msgid "Presentation"
msgstr "Prezentacija"
#: gtk/gtkfilechooserwidget.c:4792
msgid "Spreadsheet"
msgstr "Proračunska tablica"
#. Translators: We don't know whether this printer is
#. * available to print to.
#: gtk/gtkfilechooserwidget.c:4836 gtk/inspector/prop-editor.c:1506
#: gtk/gtkfilechooserwidget.c:4823 gtk/gtkfilechooserwidget.c:5007
#: gtk/inspector/prop-editor.c:1506
#: modules/printbackends/gtkprintbackendcloudprint.c:731
msgid "Unknown"
msgstr "Nepoznato"
#: gtk/gtkfilechooserwidget.c:4875 gtk/gtkplacessidebar.c:1087
#: gtk/gtkfilechooserwidget.c:5046 gtk/gtkplacessidebar.c:1087
msgid "Home"
msgstr "Osobna mapa"
#: gtk/gtkfilechooserwidget.c:5368
#: gtk/gtkfilechooserwidget.c:5540
msgid "Cannot change to folder because it is not local"
msgstr "Nemoguća promjena u mapu jer nije na lokalnom računalu"
#: gtk/gtkfilechooserwidget.c:6143 gtk/gtkprintunixdialog.c:671
#: gtk/gtkfilechooserwidget.c:6315 gtk/gtkprintunixdialog.c:671
#, c-format
msgid "A file named “%s” already exists. Do you want to replace it?"
msgstr "Datoteka naziva “%s” već postoji. Želite li ju zamijeniti?"
#: gtk/gtkfilechooserwidget.c:6146 gtk/gtkprintunixdialog.c:675
#: gtk/gtkfilechooserwidget.c:6318 gtk/gtkprintunixdialog.c:675
#, c-format
msgid ""
"The file already exists in “%s”. Replacing it will overwrite its contents."
msgstr "Datoteka već postoji u “%s”. Zamjena će prebrisati sav njen sadržaj."
#: gtk/gtkfilechooserwidget.c:6151 gtk/gtkprintunixdialog.c:683
#: gtk/gtkfilechooserwidget.c:6323 gtk/gtkprintunixdialog.c:683
msgid "_Replace"
msgstr "_Zamijeni"
#: gtk/gtkfilechooserwidget.c:6359
#: gtk/gtkfilechooserwidget.c:6531
msgid "You do not have access to the specified folder."
msgstr "Ne možete pristupiti određenoj mapi."
#: gtk/gtkfilechooserwidget.c:6983
#: gtk/gtkfilechooserwidget.c:7155
msgid "Could not send the search request"
msgstr "Nemoguće slanje zahtjeva pretrage"
#: gtk/gtkfilechooserwidget.c:7276
#: gtk/gtkfilechooserwidget.c:7450
msgid "Accessed"
msgstr "Pristupljeno"
@@ -2330,10 +2388,6 @@ msgstr "Sans 12"
msgid "Pick a Font"
msgstr "Odaberi slova"
#: gtk/gtkfontbutton.c:611 gtk/inspector/visual.ui:187
msgid "Font"
msgstr "Slova"
#: gtk/gtkfontbutton.c:1329
msgctxt "font"
msgid "None"
@@ -2395,7 +2449,7 @@ msgstr "Neuspjelo stvaranje OpenGL sadržaja"
msgid "Application menu"
msgstr "Izbornik aplikacije"
#: gtk/gtkheaderbar.c:462 gtk/gtkwindow.c:6757
#: gtk/gtkheaderbar.c:462 gtk/gtkwindow.c:6773
msgid "Close"
msgstr "Zatvori"
@@ -2424,19 +2478,19 @@ msgstr "Upozorenje"
msgid "Error"
msgstr "Greška"
#: gtk/gtklabel.c:6093 gtk/gtktext.c:5798 gtk/gtktextview.c:8617
#: gtk/gtklabel.c:6093 gtk/gtktext.c:5760 gtk/gtktextview.c:8616
msgid "Cu_t"
msgstr "Iz_reži"
#: gtk/gtklabel.c:6094 gtk/gtktext.c:5802 gtk/gtktextview.c:8621
#: gtk/gtklabel.c:6094 gtk/gtktext.c:5764 gtk/gtktextview.c:8620
msgid "_Copy"
msgstr "_Kopiraj"
#: gtk/gtklabel.c:6095 gtk/gtktext.c:5806 gtk/gtktextview.c:8625
#: gtk/gtklabel.c:6095 gtk/gtktext.c:5768 gtk/gtktextview.c:8624
msgid "_Paste"
msgstr "_Zalijepi"
#: gtk/gtklabel.c:6101 gtk/gtktext.c:5819 gtk/gtktextview.c:8638
#: gtk/gtklabel.c:6101 gtk/gtktext.c:5781 gtk/gtktextview.c:8637
msgid "Select _All"
msgstr "Odaberi _sve"
@@ -2493,7 +2547,7 @@ msgstr ""
#. * Do *not* translate it to "predefinito:LTR", if it
#. * it isn't default:LTR or default:RTL it will not work
#.
#: gtk/gtkmain.c:976
#: gtk/gtkmain.c:977
msgid "default:LTR"
msgstr "default:LTR"
@@ -2546,7 +2600,7 @@ msgid "%d:%02d"
msgstr "%d:%02d"
#: gtk/gtkmessagedialog.c:783 gtk/gtkmessagedialog.c:801
#: gtk/gtkprintbackend.c:658 gtk/gtkwindow.c:9010
#: gtk/gtkprintbackend.c:658 gtk/gtkwindow.c:9026
msgid "_OK"
msgstr "_U redu"
@@ -2598,17 +2652,17 @@ msgstr "Zapamti lozinku do _odjave"
msgid "Remember _forever"
msgstr "Zapamti _zauvijek"
#: gtk/gtkmountoperation.c:1080
#: gtk/gtkmountoperation.c:1086
#, c-format
msgid "Unknown Application (PID %d)"
msgstr "Nepoznata aplikacija (PID %d)"
#: gtk/gtkmountoperation.c:1265
#: gtk/gtkmountoperation.c:1271
#, c-format
msgid "Unable to end process"
msgstr "Nemoguće zaustavljanje procesa"
#: gtk/gtkmountoperation.c:1300
#: gtk/gtkmountoperation.c:1306
msgid "_End Process"
msgstr "_Zaustavi proces"
@@ -2855,7 +2909,7 @@ msgstr "Ovaj naziv se već koristi"
#: gtk/gtkplacessidebar.c:2684 gtk/inspector/actions.ui:25
#: gtk/inspector/css-node-tree.ui:34 gtk/ui/gtkfilechooserwidget.ui:176
#: gtk/ui/gtkfilechooserwidget.ui:445
#: gtk/ui/gtkfilechooserwidget.ui:457
msgid "Name"
msgstr "Naziv"
@@ -3279,7 +3333,7 @@ msgstr "S vrha nadno"
msgid "Bottom to top"
msgstr "S dna na vrh"
#: gtk/gtkprogressbar.c:626
#: gtk/gtkprogressbar.c:613
#, c-format
msgctxt "progress bar label"
msgid "%.0f%%"
@@ -3384,16 +3438,16 @@ msgid "Search Shortcuts"
msgstr "Prečaci pretrage"
#: gtk/gtkshortcutswindow.c:1011 gtk/ui/gtkemojichooser.ui:322
#: gtk/ui/gtkfilechooserwidget.ui:294
#: gtk/ui/gtkfilechooserwidget.ui:306
msgid "No Results Found"
msgstr "Nema pronađenih rezultata"
#: gtk/gtkshortcutswindow.c:1017 gtk/ui/gtkemojichooser.ui:335
#: gtk/ui/gtkfilechooserwidget.ui:307 gtk/ui/gtkplacesview.ui:235
#: gtk/ui/gtkfilechooserwidget.ui:319 gtk/ui/gtkplacesview.ui:235
msgid "Try a different search"
msgstr "Pokušaj drugačiju pretragu"
#: gtk/gtktext.c:5824 gtk/gtktextview.c:8643
#: gtk/gtktext.c:5786 gtk/gtktextview.c:8642
msgid "Insert _Emoji"
msgstr "Umetni _smajli"
@@ -3460,24 +3514,24 @@ msgctxt "volume percentage"
msgid "%d%%"
msgstr "%d%%"
#: gtk/gtkwindow.c:6705
#: gtk/gtkwindow.c:6721
msgid "Move"
msgstr "Pomakni"
#: gtk/gtkwindow.c:6713
#: gtk/gtkwindow.c:6729
msgid "Resize"
msgstr "Promijeni veličinu"
#: gtk/gtkwindow.c:6744
#: gtk/gtkwindow.c:6760
msgid "Always on Top"
msgstr "Uvijek na vrhu"
#: gtk/gtkwindow.c:8997
#: gtk/gtkwindow.c:9013
#, c-format
msgid "Do you want to use GTK Inspector?"
msgstr "Želite li koristiti GTK Inspektora?"
#: gtk/gtkwindow.c:8999
#: gtk/gtkwindow.c:9015
#, c-format
msgid ""
"GTK Inspector is an interactive debugger that lets you explore and modify "
@@ -3488,7 +3542,7 @@ msgstr ""
"otkrivanje i promjenu unutrašnjosti bilo koje GTK aplikacije. Njegovo "
"korištenje može uzrokovati rušenje ili prekid u radu aplikacije."
#: gtk/gtkwindow.c:9004
#: gtk/gtkwindow.c:9020
msgid "Dont show this message again"
msgstr "Ne prikazuj više ovu poruku"
@@ -3676,6 +3730,7 @@ msgid "Address"
msgstr "Adresa"
#: gtk/inspector/misc-info.ui:56 gtk/inspector/statistics.ui:45
#: gtk/ui/gtkfilechooserwidget.ui:222
msgid "Type"
msgstr "Vrsta"
@@ -6861,15 +6916,15 @@ msgstr "Stvori mapu"
msgid "Files"
msgstr "Datoteke"
#: gtk/ui/gtkfilechooserwidget.ui:245
#: gtk/ui/gtkfilechooserwidget.ui:257
msgid "Remote location — only searching the current folder"
msgstr "Udaljena lokacija — samo pretraži trenutnu mapu"
#: gtk/ui/gtkfilechooserwidget.ui:385
#: gtk/ui/gtkfilechooserwidget.ui:397
msgid "Folder Name"
msgstr "Naziv mape"
#: gtk/ui/gtkfilechooserwidget.ui:411
#: gtk/ui/gtkfilechooserwidget.ui:423
msgid "_Create"
msgstr "_Stvori"
@@ -7901,9 +7956,6 @@ msgstr "Neodređeni profil"
#~ msgid "Similar"
#~ msgstr "Slično"
#~ msgid "Image"
#~ msgstr "Slika"
#~ msgid "GL Rendering"
#~ msgstr "GL prikazivanje"

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