Compare commits

..

206 Commits

Author SHA1 Message Date
Matthias Clasen 47ffaefa25 testrevealer: Cover the new transitions
Add tests for all the swing transitions.
2019-03-29 10:51:00 -04:00
Benjamin Otte 9d0a42dc14 stack: Add a cube spin transition
Add a transition to GtkStack that pretends pages
are the sides or a cube, and switch them by
rotating the cube.

Use this transition in widget-factory.
2019-03-29 10:03:18 -04:00
Anders Jonsson ec9be21771 Update Swedish translation
(cherry picked from commit 2b768edd43)
2019-03-29 10:51:19 +00:00
Benjamin Otte 1944ffe351 Revert "Bump meson req to 0.50"
This reverts commit f0845d98a2.

The commit breaks CI. CI has more power than meson telling things.
2019-03-29 10:19:41 +01:00
Benjamin Otte a8dccef507 build: The private reftest library needs to be shared
Otherwise the module and gtk-reftest will each have their own copy and
that'll mean all symbols - and inhibiting the shutdown - will exist
twice. Not good.
2019-03-29 09:56:52 +01:00
Benjamin Otte 90f460c236 reftests: Remove notebook-childproperties test
Notebooks have no child properties anymore.
2019-03-29 09:56:52 +01:00
Benjamin Otte e5e516468a reftests: Fix textview-tags test
The test was timeouting on X11.

I'm still not sure it does what it should do, but at least that
problem's gone.
2019-03-29 09:56:52 +01:00
Benjamin Otte b88c9439aa reftests: Fix label-sizing test
Set border, padding and margin to 0, not just padding.
2019-03-29 09:56:52 +01:00
Benjamin Otte 95f9c8a5eb reftests: Remove box-packing test
Boxes have no packing flags anymore.
2019-03-29 09:56:52 +01:00
Benjamin Otte fbc8bb979d reftests: Fix grid-empty-with-spacing test
Widgets are visible by default now, so make sure the ones that should be
invisible are marked as such.
2019-03-29 09:56:52 +01:00
Benjamin Otte e861b0d6c1 reftests: Fix grid-spacing2 test
The expand flag needs to be set on widgets when previously it was a
packing property.
2019-03-29 09:56:52 +01:00
Benjamin Otte 7918eaf677 picture: Don't cause warnings on load failures
When a file set via gtk_picture_set_file() can't be loaded, just
silently don't load it.

Reftest picture-load-invalid-file added for that case.
2019-03-29 09:56:52 +01:00
Benjamin Otte bf2a93ca0e reftests: Fix image-load-from-file test
- Images are always correctly sized
- Use a GtkPicture for the large file
2019-03-29 09:56:52 +01:00
Benjamin Otte 606aea2302 reftests: Fix iconview-empty test
Images have a static size now, use a GtkPicture instead.
2019-03-29 09:56:52 +01:00
Benjamin Otte b21882bcea cssimagelinear: Make gradient offsets stay in [0, 1]
Fixes linear-gradient reftest
2019-03-29 09:56:52 +01:00
Benjamin Otte fee8f6b9be reftests: Fix shorthand-entry-border test
We weren't setting CSS back to defaults, so the border highlight
transition would be at different stages when the 2 snapshots happened.
2019-03-29 09:56:52 +01:00
Benjamin Otte 3a8a9fc2bd reftests: Remove style-properties-nth-child test
Style properties don't exist anymore.
2019-03-29 09:56:52 +01:00
Benjamin Otte 866bc13557 reftests: Fix statusbar-remove-all test 2019-03-29 09:56:52 +01:00
Benjamin Otte d10a73f509 textview: Paint border windows in the right spot
Fixes textview-border-windows reftest
2019-03-29 09:56:52 +01:00
Benjamin Otte 3c44f83909 Fix textview-margins reftest
Draw something, otherwise the test will timeout
2019-03-29 09:56:52 +01:00
Benjamin Otte 38fbb6856c headerbar: Duct-tape over the measure mess
Fixes various reftests.

The headerbar needs soeone to redo sizing.
2019-03-29 09:56:52 +01:00
Benjamin Otte 9ca5495380 reftests: Fix inherit-and-initial test
Run gtk-builder-tool --3to4 over it. As the test cares about the
"initial" and "inherit" CSS keywords, the actual widgets aren't that
important. It's just important to have many of them.
2019-03-29 09:56:52 +01:00
Benjamin Otte 4b07d28153 textlayout: Allow querying empty areas
This only happens when the textview has no content, but it does happen
now that such a textview gets allocated 0x0 and not 1x1.
2019-03-29 09:56:52 +01:00
Benjamin Otte c04190e761 rendernode: Round pixel colors in color matrix drawing
Fixes symbolic-icon-translucent-color.ui reftest
2019-03-29 09:56:52 +01:00
Benjamin Otte 822791d8a9 reftests: Remove info-bar-message-types test
- The test doesn't properly test infobars. An infobar is not a box.

- Infobar message types aren't styled anymore.
2019-03-29 09:56:52 +01:00
Benjamin Otte f070872b36 reftests: Fix notebook-tab-position test
The tab-fill child property is gone, don't use it.
2019-03-29 09:56:52 +01:00
Benjamin Otte f3e47ee92e reftests: Fix icon-style-basics test
Add a type-func to the GThemedIcon and GEmeblemedIcon usages so
GtkBuilder finds them.
2019-03-29 09:56:52 +01:00
Benjamin Otte e612b55bd4 reftests: Fix css-match-name test
- Replace GtkImage::pixbuf with GtkImage::paintable
- Use a GtkPicture so the sizing is correct
2019-03-29 09:56:52 +01:00
Benjamin Otte 6d38f1dcb5 reftests: Fix css-match-type test
- Replace GtkImage::pixbuf with GtkImage::paintable
- Use a GtkPicture so the sizing is correct
2019-03-29 09:56:52 +01:00
Benjamin Otte d4df5211f3 reftests: Fix border-image-excess-size.ui test
The old reftests drew an opaque image, the new image is transparent.

This test drew the reference image as black and the test as transparent
black, and those are now different.
2019-03-29 09:56:52 +01:00
Benjamin Otte 2e67c2eb8f reftests: Delete removed tests from testdata 2019-03-29 09:56:52 +01:00
Benjamin Otte 47d4b06eca reftests: Fix css-currentcolor-alpha.ui test
The test did not draw anything, which fails now.
2019-03-29 09:56:52 +01:00
Benjamin Otte 5ddce32e1a reftests: Fix css-match-class test
- Replace GtkImage::pixbuf with GtkImage::paintable
- Use a GtkPicture so the sizing is correct
2019-03-29 09:56:52 +01:00
Benjamin Otte 8846f28369 reftests: Fix background-size-zero test
We were drawing nothing, causing a timeout.
2019-03-29 09:56:52 +01:00
Benjamin Otte 62d0bd7153 reftests: Fix nth-child test
Box children no longer have a "position" child property.
2019-03-29 09:56:52 +01:00
Benjamin Otte d5175526f9 reftests: Fix treeview-fixed-height test
Convert -gtk-gradient() to linear-gradient in the CSS.
2019-03-29 09:56:52 +01:00
Benjamin Otte 7935f9d3b8 reftests: Actually build a module
Reftests are expecting a module called libreftest.so, so don't build a
static libgtkreftest.a but what they expect.
2019-03-29 09:56:52 +01:00
Benjamin Otte 7cc5e51a92 reftests: Fix actionbar test
Boxes have no pack-type anymore.
2019-03-29 09:56:52 +01:00
Benjamin Otte 8542ac2c42 reftests: Fix window-height-for-width test
The dialog's vbox internal child is now called content_area
2019-03-29 09:56:52 +01:00
Benjamin Otte b3eddbb45d reftests: Fix grid-spacing1 test 2019-03-29 09:56:52 +01:00
Benjamin Otte e3dbf8d524 reftests: Fix unresolvable.ui test
- Make sure we draw something
- Don't use -gtk-gradient() but linear-gradient instead
2019-03-29 09:56:52 +01:00
Benjamin Otte 5dd5ff5236 widgetpaintable: Don't emit signals on dispose 2019-03-29 09:56:52 +01:00
Benjamin Otte d3be32f8ea reftest: Be more careful about snapshotting
Instead of waiting for the first invalidate-contents signal, wait until
we get a render node. This will break spectacularly for reftests not
drawing anything at all, but we just hope that won't happen.
2019-03-29 09:56:52 +01:00
Benjamin Otte 0c81ea2f28 reftests: Make meson run every test separately
This way, we don't get an abort once the first test gets a warning.

We also can use meson test to run individual tests.

Unfortunately, only ~60% of tests pass.
2019-03-29 09:56:52 +01:00
Benjamin Otte c564a349e5 testsuite: Make reftests work again
Well, the testrunner works again, the tests don't all succeed.

So exclude them from CI.
2019-03-29 09:56:52 +01:00
Benjamin Otte 42d580dc07 reftests: Remove image-recording-surface test
It's no longer possible to set surfaces on a GtkImage, so we don't need
to test that setting a recording surface works.
2019-03-29 09:56:52 +01:00
Chun-wei Fan 4784c5a980 gdk/win32/gdkdrag-win32.c: Include math.h
We need that for round().
2019-03-29 16:50:53 +08:00
Chun-wei Fan 6b08227110 meson.build: Pull in fallback for PangoFT2 only when needed
On some systems PangoFT2 is optional, so we only use the fallback when
it is being required.
2019-03-29 16:50:35 +08:00
Matthias Clasen 6f470affef Merge branch 'adwaita-radii-fixes-master' into 'master'
Adwaita radii fixes master

See merge request GNOME/gtk!628
2019-03-29 00:51:23 +00:00
Matthias Clasen c30fc92b3e builder-tool: Don't strip the xml declaration
This is useful for interoperability with other tools.
2019-03-28 19:28:05 -04:00
Matthias Clasen 7222bda146 file chooser entry: Fix a crash
The ::focus-out signal signature has changed. Adapt.
2019-03-28 18:55:36 -04:00
Matthias Clasen eaae9650d9 popover menu: Fix a parameter name mismatch 2019-03-28 18:36:15 -04:00
Matthias Clasen f20f02c416 overlay: Remove no-longer-existing api from header 2019-03-28 18:36:15 -04:00
Matthias Clasen 94533495aa gtk: Some documentation cleanups 2019-03-28 18:36:15 -04:00
Matthias Clasen c9e08efcbf gsk: Fix up docs a bit
Some apis that were either removed or have never
existed were listed for the docs.
2019-03-28 18:36:15 -04:00
Matthias Clasen e0f9c98e44 gsk: Add GskRoundedRect to the docs 2019-03-28 18:36:15 -04:00
Christoph Reiter 80c26ab904 CI: install meson 0.50 2019-03-28 22:47:18 +01:00
Matthias Clasen f0845d98a2 Bump meson req to 0.50
meson told me to.
2019-03-28 17:35:50 -04:00
Matthias Clasen 121bbcec4b Merge branch 'overlay-layout' into 'master'
overlay: Use a layout manager

See merge request GNOME/gtk!677
2019-03-28 21:07:38 +00:00
Matthias Clasen 700183e5b6 Convert ui files
Run gtk4-builder-tool simplify --3to4 over all ui files.
2019-03-28 16:37:21 -04:00
Matthias Clasen 8d993160c2 builder-tool: Small refactoring
Introduce a PropKind enum, since the collection of
booleans is getting out of hands.
2019-03-28 16:36:59 -04:00
Matthias Clasen fc3cae34ec builder-tool: Convert overlay child properties 2019-03-28 16:36:59 -04:00
Matthias Clasen 866640c0c2 overlay: Use a layout manager
This lets us get rid of the child properties,
by converting them to layout properties.
2019-03-28 16:36:59 -04:00
Piotr Drąg 0f7ca7e550 Update POTFILES.in 2019-03-28 18:58:56 +01:00
Matthias Clasen 18d1ea19e0 Merge branch 'layout-child-type' into 'master'
Connect LayoutManager to LayoutChild

See merge request GNOME/gtk!678
2019-03-28 17:41:33 +00:00
Emmanuele Bassi 208cae2f05 Do not leak unapplied layout properties
If the layout manager does not have a GtkLayoutChild, or if we cannot
apply layout properties, we should free them instead of leaking them.
2019-03-28 17:22:02 +00:00
Emmanuele Bassi ecba428d52 Add missing handler for <layout> elements in UI files
The layout properties sub-parser needs to handle the parent tag.
2019-03-28 17:21:56 +00:00
Emmanuele Bassi 3f0f7c73e0 Connect LayoutManager to LayoutChild
If we want to inspect the type of layout properties exposed by a
GtkLayoutManager, we need a way to connect the layout manager type to
the GtkLayoutChild type it creates. In order to do so, we can set the
GtkLayoutChild type on a field of the GtkLayoutManagerClass structure.

Storing the GtkLayoutChild type on the class structure of the layout
manager also allows us to implement a default create_layout_child()
virtual function.
2019-03-28 16:58:00 +00:00
Emmanuele Bassi 3d6a456c85 Add release info to our demo apps
The appstream-util check performed by Flatpak on recent GNOME SDKs has
become more stringent, and now it requires a <release> tag in the
AppData XML file. If we don't have it, the Flatpak bundles of gtk-demo
and gtk-widget-factory will fail on our CI infrastructure.
2019-03-28 12:16:53 +00:00
Emmanuele Bassi 65c394dbaa Document how to define layout manager properties 2019-03-28 11:47:46 +00:00
Matthias Clasen 4d9f4ed14b Merge branch 'gbsneto/install-header' into 'master'
build: Install gtkboxlayout.h

See merge request GNOME/gtk!676
2019-03-28 02:48:03 +00:00
Georges Basile Stavracas Neto 56d420c06e boxlayout: Notify orientation changes
This was missing from the initial implementation, and
breaks the tests.
2019-03-27 23:34:03 -03:00
Matthias Clasen dec2cf49dd Merge branch 'child-properties' into 'master'
Remove some more child properties

See merge request GNOME/gtk!675
2019-03-28 02:04:42 +00:00
Georges Basile Stavracas Neto 3d524cc67d build: Install gtkboxlayout.h
This is included by gtk.h, and thus required to build.
2019-03-27 22:55:07 -03:00
Matthias Clasen 396deb44fa Convert ui files
Run gtk4-builder-tool simplify --3to4 over all ui files.
2019-03-27 21:48:12 -04:00
Matthias Clasen 3631878cee builder-tool: Rewrite paned child properties 2019-03-27 21:48:12 -04:00
Matthias Clasen 26de69eaae paned: Replace the child properties
Replace the resize and shrink child properties
by resize-child1/2 and shrink-child1/2 properties.
2019-03-27 21:48:12 -04:00
Matthias Clasen f89c93ea8e Merge branch 'window-api-cleanup' into 'master'
GtkWindow api cleanup

See merge request GNOME/gtk!674
2019-03-28 00:14:51 +00:00
Matthias Clasen 6b050a277e Convert ui files
Run gtk4-builder-tool simplify --3to4 over all ui files.
2019-03-27 20:03:59 -04:00
Matthias Clasen 7e88fcf24e builder-tool: Rewrite toolbar child properties 2019-03-27 20:03:34 -04:00
Matthias Clasen a443145a4d toolbar: Remove the homogeneous and expand child properties
Replace these with GtkToolItem properties homogeneous
and expand-item.
2019-03-27 20:02:48 -04:00
Matthias Clasen bbb6772934 win32: Drop set_role
One overlooked (non-)implementation of set_role.
2019-03-27 18:48:59 -04:00
Matthias Clasen 3600d129bf win32: Add a missing include
We are using round() now, so include math.h.
2019-03-27 18:47:56 -04:00
Matthias Clasen 14ad26a599 Convert ui files
Run gtk4-builder-tool simplify --3to4 over all ui files.
2019-03-27 18:40:40 -04:00
Matthias Clasen 8c807303da builder-tool: Rewrite GtkPopoverMenu::submenu 2019-03-27 18:38:29 -04:00
Matthias Clasen 5c2697633c popover menu: Drop the submenu child property
We are using the GtkWidget::name property instead.
2019-03-27 18:37:57 -04:00
Matthias Clasen 4a1019bed0 popover menu: Add an api for adding submenus
This is a step towards removing the submenu
child property.
2019-03-27 17:53:48 -04:00
Matthias Clasen 0d43d11387 gdk: Drop gdk_surface_set_role
This is a very old X session management thing, and you
will be hard-pressed to find a session manager that can
make use of it, and even harder-pressed to find apps
using it to their advantage.
2019-03-27 17:29:17 -04:00
Matthias Clasen 8ef4e231ec gdk: Stop implementing set_role
All but the X implementation of these were
empty anyway. And the X one is just setting
a property.
2019-03-27 17:29:17 -04:00
Matthias Clasen 2f358469af Remove GtkWindow::role
...and the setter/getter for it.

This is a very old X session management thing, and you
will be hard-pressed to find a session manager that can
make use of it, and even harder-pressed to find apps
using it to their advantage.
2019-03-27 17:29:17 -04:00
Matthias Clasen be944e0a31 file chooser: Stop setting a role
It does nothing.
2019-03-27 17:29:17 -04:00
Matthias Clasen e5722367b3 Merge branch 'fixed-layout' into 'master'
Add GtkFixedLayout

See merge request GNOME/gtk!668
2019-03-27 18:51:04 +00:00
Alexander Larsson 2440e89a72 Merge branch 'wip/alexl/broadway6' into 'master'
broadway: Use css transforms

See merge request GNOME/gtk!673
2019-03-27 18:45:17 +00:00
Alexander Larsson 9212727f53 broadway: Use css transforms
This allows generic transforms nodes to work.
2019-03-27 19:27:16 +01:00
Matthias Clasen 733271e09a migration guide: Improve warp-pointer entry
Mention platform APIs.
2019-03-27 14:21:26 -04:00
Matthias Clasen 868d3cd609 Merge branch 'pack-type' into 'master'
Drop some more child properties

See merge request GNOME/gtk!672
2019-03-27 18:12:01 +00:00
Matthias Clasen 4a15b16198 Mention pack-type in the migration guide 2019-03-27 13:52:47 -04:00
Matthias Clasen 7ac250dea7 Convert all ui files
Run gtk4-builder-tool simplify --3to4 over all ui files.
2019-03-27 13:36:24 -04:00
Matthias Clasen c507160bf2 builder-tool: Rewrite pack-type
Replace GtkActionBar::pack-type and GtHeaderBar::pack-type
with child types when going from 3 to 4.
2019-03-27 13:36:24 -04:00
Matthias Clasen 84480b3da8 action bar: Drop pack-type
Drop the pack-type child property. Allow ui
files to direct children by adding a child
type for it.
2019-03-27 13:36:24 -04:00
Matthias Clasen 6c30b474f5 header bar: Drop pack-type
Drop the pack-type child property. Allow ui files
to direct children by adding a child type.
2019-03-27 13:36:24 -04:00
Matthias Clasen 2fd2c61d37 dialog: Stop using GtkHeaderBar::pack-type
We want to get rid of child properties.
2019-03-27 13:36:24 -04:00
Alexander Larsson 411dc7e138 broadway: Fix leftover dom modification not using display_commands 2019-03-27 14:21:28 +01:00
Matthias Clasen 141f758c5c Migration guide: Updates 2019-03-27 02:18:36 -04:00
Matthias Clasen 5fb96392e3 Merge branch 'entry-sizing' into 'master'
Entry sizing

Closes #1721

See merge request GNOME/gtk!670
2019-03-27 05:55:06 +00:00
Matthias Clasen 7843382784 text: Allow growing entries
Add a propagate-text-width property, which, when set,
makes the entry request a natural width that is just
enough to fit the content, within the limits given
by width-chars and max-width-chars.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1721
2019-03-27 01:42:00 -04:00
Matthias Clasen 544fe83864 search entry: Fix sizing
Use the same sizing approach we use for GtkEntry:
ignore icons when measuring. This ensures that
search entries don't change size as icons come
and go.
2019-03-27 01:42:00 -04:00
Matthias Clasen 8a9290d0ba password entry: Fix sizing
Use the same sizing approach we use for GtkEntry:
ignore icons when measuring. This ensures that
password entries don't change size as icons come
and go.
2019-03-27 01:42:00 -04:00
Matthias Clasen 8d4343a550 Merge branch 'get_caret_offset_negative_one' into 'master'
Return -1 for AtkText::get_caret_offset on failure

See merge request GNOME/gtk!666
2019-03-26 23:14:48 +00:00
Matthias Clasen 8984320964 Merge branch 'gdk-api-cleanups' into 'master'
Gdk api cleanups

See merge request GNOME/gtk!669
2019-03-26 22:37:27 +00:00
Matthias Clasen c0aaa43122 Rename gdk_device_get_surface_at_position_double
We can drop the double suffix now.
2019-03-26 18:12:55 -04:00
Matthias Clasen 5935f26a1d Drop gdk_device_get_surface_at_position
It is no longer used.
2019-03-26 18:12:55 -04:00
Matthias Clasen 562cc8b9ab gtk: Stop using gtk_device_get_surface_at_position
We should always use the double variant of the api.
2019-03-26 18:12:55 -04:00
Matthias Clasen 9021e7d3cd gdk: Stop using gdk_device_get_surface_at_position
We should always use the double variant.
2019-03-26 18:12:55 -04:00
Matthias Clasen 03eb455c93 Rename gdk_device_get_position_double
We can drop the double suffix now.
2019-03-26 18:12:55 -04:00
Matthias Clasen 6288043ec2 Drop gdk_device_get_position
It is no longer used.
2019-03-26 18:12:55 -04:00
Matthias Clasen 7e4707642a gtk: Stop using gdk_device_get_position
We should always use the double variant of this api.
2019-03-26 18:12:55 -04:00
Matthias Clasen 8dece0e940 gdk: Stop using gdk_device_get_position
We should always use the double variant of this api.
2019-03-26 18:12:55 -04:00
Matthias Clasen 21580309d3 Rename gdk_surface_get_device_position_double
Drop the _double suffix, now that the int version is gone.
2019-03-26 18:12:54 -04:00
Matthias Clasen f1d61d5515 Drop gdk_surface_get_device_position
Not used anymore.
2019-03-26 18:08:39 -04:00
Matthias Clasen 2d10a7b9c4 gtk: Stop using gdk_surface_get_device_position
Use the double version directly.
2019-03-26 18:08:32 -04:00
Matthias Clasen 54a969e0ad gdk: Stop using gdk_surface_get_device_position
Use the double variant instead.
2019-03-26 17:55:29 -04:00
Matthias Clasen eb4e7b9172 Remove GtkWindow::gravity
This was used to interpret the position passed
to gtk_window_move. Since that is gone, gravity
is no longer useful.
2019-03-26 17:55:29 -04:00
Matthias Clasen de741e57f3 tests: Stop using gtk_window_set_gravity
This api is going away.
2019-03-26 17:55:29 -04:00
Matthias Clasen 0481f123ea Drop gtk_window_move and gtk_window_get_position
These functions operate with global coordinates,
which are not available on Wayland.
2019-03-26 17:55:29 -04:00
Matthias Clasen 6f072c80db treeview: Stop using gtk_window_move
It is going away. The search popup needs to be
redone using popovers.
2019-03-26 17:55:29 -04:00
Matthias Clasen 2ed533c3e1 file chooser: Stop using gtk_window_get_position
It is going away.
2019-03-26 17:55:29 -04:00
Matthias Clasen 27c286773c tests: Stop using gtk_window_move
It is going away.
2019-03-26 17:55:29 -04:00
Matthias Clasen f7d3815fa8 a11y: Don't support changing widget size and position
This does not make sense.
2019-03-26 17:55:29 -04:00
Matthias Clasen d45996c728 Avoid root coordinates in begin_drag/move apis
Change the all the begin_drag and begin_move apis in
GdkSurface and GtkWindow to expect surface coordinates.

Update the x11 implementation to translate to root
coordinates where it matters. Wayland is ignoring the
coordinates anyway.
2019-03-26 15:57:11 -04:00
Matthias Clasen 6b6f26ed45 Add a window move/resize test 2019-03-26 15:57:04 -04:00
Emmanuele Bassi 060e30de3f Turn GtkFixedLayoutChild:position into a transformation
This way we can transform children instead of just allocating them at an
offset.
2019-03-26 19:17:26 +00:00
Emmanuele Bassi fc33bf2d1f Skip all LayoutChild when testing
GtkLayoutChild instances are created on demand once we have a widget, a
GtkLayoutManager, and a child widget. This makes testing their creation
fairly tricky.

Let's skip them, for the time being.
2019-03-26 18:46:55 +00:00
Emmanuele Bassi dd5c981b63 Use GtkFixedLayout in GtkFixed
Drop the child properties and the sizing code.
2019-03-26 18:15:13 +00:00
Emmanuele Bassi 9a4c19349e Add GtkFixedLayout
A layout manager for fixed positioning.
2019-03-26 17:43:53 +00:00
Emmanuele Bassi 3389ddf6fc Do not connect to a non-existing signal
The GtkWidget::parent-set signal was removed in ff6cd8f7.

Instead of removing GtkLayoutChild instances associated to a widget
using notifications when the widget's parent changes, we can have
gtk_widget_unparent() call a method on GtkLayoutManager to remove any
eventual GtkLayoutChild instances associated to the widget.
2019-03-26 17:37:49 +00:00
Emmanuele Bassi 341660e056 Drop warning from GtkLayoutManager::get_request_mode()
We can return a sensible default value, so we don't really need to warn
about a missing implementation.
2019-03-26 17:37:49 +00:00
Piotr Drąg b42bf99b13 Update POTFILES.in 2019-03-26 18:36:51 +01:00
Alexander Larsson 18d814d2ce Merge branch 'wip/alexl/broadway5' into 'master'
Update broadway for gtk4

See merge request GNOME/gtk!667
2019-03-26 16:25:10 +00:00
Alexander Larsson 6fce18e1a1 broadway: Remove some spew 2019-03-26 17:09:41 +01:00
Alexander Larsson cf4226586a broadway: Load all textures before applying display ops, fixing flickers 2019-03-26 17:07:47 +01:00
Alexander Larsson 0481aa10e7 broadway: Use const use for constants in the js code 2019-03-26 17:07:47 +01:00
Alexander Larsson edbaa0964f broadway: Clean up stuff using const defines 2019-03-26 17:07:47 +01:00
Alexander Larsson fbefec52a5 Broadway: Add id for nodes and reuse old ones
When sending render nodes from the client to the daemon we add an id,
and whenever we're about to re-send the entire tree node we instead
send the old id. We track all the nodes for the previous frame
of the surface this way.

Having the id on the daemon side will allow us do to much better deltas.
2019-03-26 17:07:47 +01:00
Alexander Larsson d59d8b5dd4 Disable accidental debug spew 2019-03-26 17:07:47 +01:00
Alexander Larsson 87a13fe3d2 broadway: Prepare for splitting display ops out of command handling 2019-03-26 17:07:47 +01:00
Alexander Larsson 2f85443e37 broadway: Refcount textures
We want to delay some rendering, and to make that safe we need to correctly
refcount the use of blob uris for the textures so that we don't unref
it while something is scheduled to use it.
2019-03-26 17:07:47 +01:00
Alexander Larsson 311aa01e01 broadway: Simplify fallback node cache
Since nodes are now cached we just store the fallback as a
texture in a hashtable indexed by the node. If its unused for
5 frames we drop it.
2019-03-26 17:07:47 +01:00
Alexander Larsson 3bbbe9f71b broadway: Don't crash of drag-resizing when already active
This is what the X11 code does.
2019-03-26 17:07:47 +01:00
Alexander Larsson 890b759091 broadway: Send actual float32, not some hack 2019-03-26 17:07:47 +01:00
Alexander Larsson d997903d29 broadway: Use DataView instead of hand-rolled int parsers
This is nicer in general, but also will let us do floats more sanely.
2019-03-26 17:07:47 +01:00
Alexander Larsson b097f0a7d8 Broadway: Add node for debug nodes
This can be helpful when debugging broadway.
2019-03-26 17:07:47 +01:00
Alexander Larsson 1b5b1bfd0e broadway: Don't fall back for translation transform nodes
These are trivial anyway
2019-03-26 17:07:47 +01:00
Christoph Reiter c94867f8a1 CI: set a timeout multiplier for the tests
CI can be slower than your normal dev machine so give it a bit more time
2019-03-26 16:37:22 +01:00
Martin Robinson c8d250deb1 Return -1 for AtkText::get_caret_offset on failure
ATK now expects this virtual method to return -1 on failure. This allows
ATs to distinguish between a caret at position 0 and a failure.
2019-03-26 15:38:20 +01:00
Matthias Clasen dbac377ad2 Merge branch 'wip/layout-manager' into 'master'
Add Layout Managers

See merge request GNOME/gtk!534
2019-03-26 12:38:18 +00:00
Christoph Reiter 0638dca29a win32: remove another call to gdk_device_warp()
Inline the implementation (untested). To fix the build.
2019-03-26 08:20:07 +01:00
Christoph Reiter ae68dc7a7d win32: remove unused gdk_display_warp_device
to fix the build
2019-03-26 07:59:01 +01:00
Matthias Clasen 20b4a8b38c Yet another win32 build fix
So much empty warping.
2019-03-25 23:29:34 -04:00
Emmanuele Bassi 65965bed16 Changes after review
- Rename GtkLegacyLayout to GtkCustomLayout
 - Use for() to iterate over children in GtkBinLayout
 - Whitespace fixes for code imported from GtkBox
 - Store the GtkLayoutChild instances inside LayoutManager
 - Simplify the GtkLayoutManager API by dropping unnecessary arguments
 - Fix the ownership model of GtkLayoutManager
2019-03-26 00:11:27 +00:00
Emmanuele Bassi 630442f31c Parse layout properties
If a widget has a LayoutManager instance, then we want to parse layout
properties in UI description files; the grammar is similar to packing
properties in GtkContainer:

    <child>
      <object ...>
        <property name="...">...</property>
        <layout>
          <property name="pname">value</property>
        </layout>
      </object>
    </child>

The properties are applied after a child has been added to its parent,
to the parent's layout manager property should be set.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi d6dfa41f10 Add GtkBinLayout
Like GtkBin, but lets you lay out multiple children instead of just one.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi 8cf06befc0 Port GtkSwitch to GtkLegacyLayout 2019-03-26 00:11:27 +00:00
Emmanuele Bassi 128a34fe37 Add GtkLegacyLayout
GtkLegacyLayout is a layout manager for the transitional period between
the introduction of layout managers and the removal of GtkWidget virtual
functions for the size negotiation.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi 0285919f4a docs: Add chapter on layout managers 2019-03-26 00:11:27 +00:00
Emmanuele Bassi 1fed357752 Port GtkBox to GtkBoxLayout
We can delegate all the layout management to a GtkBoxLayout, now that we
have one.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi ef9863ab63 Add GtkBoxLayout
The same layout policy of GtkBox, without all the GtkContainer calories.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi 5cbf6f5fbd Add GtkLayoutChild
Layout managers needs a way to store properties that control the layout
policy of a widget; typically, we used to store these in GtkContainer's
child properties, but since GtkLayoutManager is decoupled from the
actual container widget, we need a separate storage. Additionally, child
properties have their own downsides, like requiring a separate, global
GParamSpecPool storage, and additional lookup API.

GtkLayoutChild is a simple GObject class, which means you can introspect
and document it as you would any other type.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi 15fda18791 Rename the internal GtkLayoutChild type
The type is completely private to GtkLayout, so there's really no need
to namespace it.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi f7856e887e Add GtkWidget:layout-manager
We can use a constructor property for existing container widgets with
a layout policy, and move the layout policy implementation out of the
widget itself and into a LayoutManager subclass.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi 1b8595b5f2 Hook GtkLayoutManager into GtkWidget
We delegate the size request mode, the measuring, and the allocation of
a widget through a GtkLayoutManager instance, if one has been attached
to the widget; otherwise, we fall back to the widget's own implementation.
2019-03-26 00:11:27 +00:00
Emmanuele Bassi 24754c3259 Add GtkLayoutManager
A base abstract class for layout manager delegate objects.

Layout managers are associated to a single widget, like event
controllers, and are responsible for measuring and allocating the
children of the widget they are bound to.
2019-03-26 00:11:27 +00:00
Matthias Clasen 4dfe2a8aa8 Fix the windows build
There was another warp implementation that needed to be removed.
This commit also addresses a number of compiler warnings
in passing.
2019-03-25 20:06:08 -04:00
Timm Bäder ab7507150b Doc comment fixup 2019-03-25 15:57:31 +01:00
Timm Bäder e657d9d553 popover: Always measure contents gizmo
Otherwise we're getting warnings about allocating a widget we haven't
measured first, which is fair. The contents gizmo itself will later take
care about whether or not the real popover child is NULL.
2019-03-25 15:57:31 +01:00
Timm Bäder 36e00ae95e popover: Don't try to compute_bounds of a NULL child 2019-03-25 15:57:30 +01:00
Matthias Clasen f2dff5115f win32: Drop the warp implementation
We no longer support pointer warping.
2019-03-25 10:16:14 -04:00
Piotr Drąg a246f8c22a Update Polish translation 2019-03-25 14:37:44 +01:00
Piotr Drąg 6efa1fc006 Update POTFILES.in 2019-03-25 14:19:54 +01:00
Matthias Clasen 3d37f08f38 Remove gdk_device_warp
This was only ever implemented on X11, and is
not something we want to encourage apps to do, ever.
2019-03-24 20:49:08 -04:00
Matthias Clasen 160f1e581a Remove a dead file
We are not using this anymore.
2019-03-24 20:48:35 -04:00
Matthias Clasen 661e195ffc color editor: Don't warn if editing is cancelled
Thats a valid way to end color picking.
2019-03-24 20:47:26 -04:00
Benjamin Otte 551ced9ae4 Fix compile warning 2019-03-23 03:08:20 +01:00
Benjamin Otte 799cb39e08 Remove win32 themeing support
It was unused through all of GTK 3, so it is not worth supporting.

The best Windows themes do not make use of it at all.
2019-03-22 22:30:01 +01:00
LRN 0615668dd9 Merge branch 'ime-load-fix' into 'master'
Ime load fix (GTK4)

See merge request GNOME/gtk!662
2019-03-22 21:10:35 +00:00
Matthias Clasen 1ada7bbc02 Fix hover state handling
We were not paying enough attention to detail when updating
hover and focus state while generating crossing events. The
invariant that we need to preserve here is that when a widget
has focus or hover, its parent does too.
2019-03-22 16:35:20 -04:00
Matthias Clasen 81658105f7 Stop walking parent surfaces for crossing event generation
We basically don't have child surfaces anymore (the last
use in popovers is on the way out). This really needs
to be done in terms of widgets, not surfaces. For now,
just stop walking parent surfaces.
2019-03-22 16:35:20 -04:00
Benjamin Otte d9ef734458 cssparser: Simplify
Remove the uint parser (and use the int parser in the one user of it).

And avoid unnecessarily going through a macro.
2019-03-22 19:55:34 +01:00
Benjamin Otte 73760e5835 cssparser: Remove unused functions 2019-03-22 19:55:34 +01:00
Matthias Clasen 5638882dca Remove debug spew 2019-03-22 14:44:51 -04:00
Руслан Ижбулатов 8da56cef79 GDK W32: Fix property setting to correctly use static strings
The strings that are set are static, so g_value_set_static_string() should
be used to set them instead of g_value_set_string().
2019-03-22 16:59:03 +00:00
Руслан Ижбулатов 64ab82c403 GDK W32: Test for IME correctly
ImmIsIME() doesn't work (always returns TRUE) since Vista.
Use ITfActiveLanguageProfileNotifySink to detect TSF changes,
which are equal to IME changes for us.

Also make sure that IMMultiContext re-loads the IM when keyboard layout
changes, otherwise there's a subtle bug that could happen:
* Run GTK application with non-IME layout (US, for example)
* Focus on an editable widget (GtkEntry, for example)
* IM Context is initialized to use the simple IM
* Switch to an IME layout (such as Korean)
* Start typing
* Since IME module is not loaded yet, keypresses are handled
  by a default MS IME handler
* Once IME commits a character, GDK will get a WM_KEYDOWN,
  which will trigger a GdkKeyEvent, which will be handled by
  an event filter in IM Context, which will finally re-evaluate
  its status and load IME, and only after that GTK will get
  to handle IME by itself - but by that point input would
  already be broken.
To avoid this we can emit a dummy event (with Void keyval),
which will cause IM Context to load the appropriate module
immediately.
2019-03-22 16:58:59 +00:00
Matthias Clasen 56df49971a entry: Disconnect text signals in dispose
This was showing up as crashes when closing
the file chooser.
2019-03-21 19:15:55 -04:00
Matthias Clasen 0bf136a902 Merge branch 'adwaita-remove-selectionmode-assets-master' into 'master'
Adwaita: Drop checkbox-selectionmode assets

See merge request GNOME/gtk!634
2019-03-20 14:10:18 +00:00
Matthias Clasen 2479d60012 Merge branch 'adwaita-selectionmode-checkboxes-master' into 'master'
Adwaita: Fix selection-mode checkboxes

Closes #28

See merge request GNOME/gtk!629
2019-03-20 14:10:05 +00:00
Matthias Clasen 6990f73940 Merge branch 'adwaita-headerbar-switch-margins-master' into 'master'
Adwaita: Adjust switch margins on headerbars

Closes #1759

See merge request GNOME/gtk!651
2019-03-20 14:06:19 +00:00
Matthias Clasen 254c27acbe Merge branch 'wip/jimmac/focus-ring-radii' into 'master'
Adwaita: draw bigger radius for focus rings

Closes #1756

See merge request GNOME/gtk!649
2019-03-20 12:32:15 +00:00
Matthias Clasen 558405e1bc window: Update state flags
When the window gets active / inactive, we
don't propagate events, but just send focus-in / -out
to the current focus_widget. Improve this by updating
its state flags as well.
2019-03-19 21:33:38 -04:00
Matthias Clasen f47c376fb1 main: Fix crossing event generation for parented roots
We were walking the parent chain here, which now
always needs to consider whether it should stop
at roots. Like this one should.

The symptom was that a label with a popup attached to
it would end up with an unintentional focus ring that
would not go away.
2019-03-19 21:33:38 -04:00
Alex Monday 5679b9a687 Adwaita: Adjust switch margins on headerbars
Closes https://gitlab.gnome.org/GNOME/gtk/issues/1759
2019-03-19 19:59:05 +05:00
Jakub Steiner 24235f61ab Adwaita: draw bigger radius for focus rings
Fixes https://gitlab.gnome.org/GNOME/gtk/issues/1756
2019-03-19 14:07:10 +01:00
Alex Monday d07cd892e7 Adwaita: Drop checkbox-selectionmode assets 2019-03-13 14:12:45 +05:00
Alex Monday 4bba279085 Adwaita: Fix selection-mode checkboxes
Use object-select-symbolic as a check icon, adjust styles.

Closes https://gitlab.gnome.org/GNOME/gtk/issues/28
2019-03-12 22:05:08 +05:00
Alex Monday 36539a22d7 Adwaita: Adjust entry border-radius
Replace entry border-radius value with $button_radius variable.
2019-03-12 20:42:48 +05:00
Alex Monday ad96220448 Adwaita: Replace spinbutton border-radii with variables
Replace hardcoded border-radius values with $button_radius
variable on spinbuttons.
2019-03-12 20:34:38 +05:00
Alex Monday 73139d524b Adwaita: Replace all %linked radii with variables
Some of hardcoded border-radius values on linked elements were left
unchanged during Adwaita refresh.
2019-03-12 20:32:14 +05:00
367 changed files with 13475 additions and 31103 deletions
+2 -2
View File
@@ -13,7 +13,7 @@ stages:
- subprojects/pango/
fedora-x86_64:
image: registry.gitlab.gnome.org/gnome/gtk/master:v2
image: registry.gitlab.gnome.org/gnome/gtk/master:v3
stage: build
script:
- bash -x ./.gitlab-ci/test-docker.sh
@@ -64,7 +64,7 @@ flatpak:widget-factory:
<<: *flatpak-defaults
pages:
image: registry.gitlab.gnome.org/gnome/gtk/master:v2
image: registry.gitlab.gnome.org/gnome/gtk/master:v3
stage: deploy
script:
- meson -Ddocumentation=true _build .
+1 -1
View File
@@ -70,7 +70,7 @@ RUN dnf -y install \
xorg-x11-server-Xvfb \
&& dnf clean all
RUN pip3 install meson==0.49.0
RUN pip3 install meson==0.50.0
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
+1 -1
View File
@@ -2,7 +2,7 @@
set -e
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v2"
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v3"
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
--file "Dockerfile" .
+2
View File
@@ -26,7 +26,9 @@ ccache --show-stats
xvfb-run -a -s "-screen 0 1024x768x24" \
meson test \
--timeout-multiplier 2 \
--print-errorlogs \
--suite=gtk \
--no-suite=gtk:gsk \
--no-suite=gtk:reftest \
--no-suite=gtk:a11y
+2 -2
View File
@@ -196,7 +196,7 @@ edit_label_done (GtkWidget *entry, gpointer data)
GtkWidget *label;
int x, y;
gtk_container_child_get (GTK_CONTAINER (fixed), entry, "x", &x, "y", &y, NULL);
gtk_fixed_get_child_position (GTK_FIXED (fixed), entry, &x, &y);
label = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "label"));
gtk_label_set_text (GTK_LABEL (label), gtk_editable_get_text (GTK_EDITABLE (entry)));
@@ -210,7 +210,7 @@ edit_cb (GtkWidget *child)
GtkWidget *fixed = gtk_widget_get_parent (child);
int x, y;
gtk_container_child_get (GTK_CONTAINER (fixed), child, "x", &x, "y", &y, NULL);
gtk_fixed_get_child_position (GTK_FIXED (fixed), child, &x, &y);
if (GTK_IS_LABEL (child))
{
+15 -27
View File
@@ -23,58 +23,46 @@
</child>
</object>
</child>
<child>
<child type="end">
<object class="GtkLabel">
<property name="label">fps</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
<child>
<child type="end">
<object class="GtkLabel">
<property name="label" bind-source="bowl" bind-property="framerate"/>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
<child>
<child type="end">
<object class="GtkLabel">
<property name="label">Icons, </property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
<child>
<child type="end">
<object class="GtkLabel">
<property name="label" bind-source="bowl" bind-property="count"/>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
<child>
<child type="end">
<object class="GtkToggleButton" id="changes_allow">
<property name="visible" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean"/>
<property name="icon-name">changes-allow</property>
<property name="relief">none</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
<child>
<child type="end">
<object class="GtkToggleButton" id="changes_prevent">
<property name="active" bind-source="changes_allow" bind-property="active" bind-flags="bidirectional|invert-boolean">1</property>
<property name="visible" bind-source="changes_prevent" bind-property="active" bind-flags="invert-boolean">0</property>
<property name="active" bind-source="changes_allow" bind-property="active" bind-flags="bidirectional|invert-boolean"/>
<property name="visible" bind-source="changes_prevent" bind-property="active" bind-flags="invert-boolean"/>
<property name="icon-name">changes-prevent</property>
<property name="relief">none</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
</object>
</child>
@@ -82,7 +70,7 @@
<object class="GtkFishbowl" id="bowl">
<property name="visible">True</property>
<property name="animating">True</property>
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean">1</property>
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean"/>
</object>
</child>
</object>
+7
View File
@@ -30,4 +30,11 @@
<translation type="gettext">gtk-4.0</translation>
<update_contact>matthias.clasen_at_gmail.com</update_contact>
<developer_name>Matthias Clasen and others</developer_name>
<releases>
<release version="3.94.0" date="2018-06-25">
<description>
<p>A new developers snapshot towards GTK 4.0.</p>
</description>
</release>
</releases>
</component>
+12 -36
View File
@@ -11,41 +11,36 @@
</style>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
<property name="active">1</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
<property name="icon-name">edit-find</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Raised</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
@@ -54,12 +49,10 @@
<class name="raised"/>
</style>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Raised Active</property>
<property name="use-underline">1</property>
<property name="is-important">1</property>
@@ -69,12 +62,10 @@
<class name="raised"/>
</style>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive Active</property>
<property name="use-underline">1</property>
@@ -82,9 +73,6 @@
<property name="is-important">1</property>
<property name="active">1</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToolItem">
@@ -149,68 +137,56 @@
</style>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="icon-name">list-add-symbolic</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Normal</property>
<property name="use-underline">1</property>
<property name="icon-name">list-add-symbolic</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="icon-name">list-remove-symbolic</property>
<property name="active">1</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="label" translatable="yes">Active</property>
<property name="use-underline">1</property>
<property name="icon-name">list-remove-symbolic</property>
<property name="active">1</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive</property>
<property name="use-underline">1</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton">
<property name="homogeneous">1</property>
<property name="sensitive">0</property>
<property name="label" translatable="yes">Insensitive Active</property>
<property name="use-underline">1</property>
<property name="icon-name">go-up-symbolic</property>
<property name="active">1</property>
</object>
<packing>
<property name="homogeneous">1</property>
</packing>
</child>
</object>
</child>
+2 -4
View File
@@ -35,7 +35,7 @@
</child>
</object>
</child>
<child>
<child type="end">
<object class="GtkToggleButton" id="search">
<style>
<class name="image-button"/>
@@ -46,9 +46,7 @@
</object>
</child>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
</object>
</child>
-1
View File
@@ -1,4 +1,3 @@
subdir('gtk-demo')
subdir('icon-browser')
subdir('node-editor')
subdir('widget-factory')
-17
View File
@@ -1,17 +0,0 @@
node_editor_sources = [
'main.c',
'node-editor-application.c',
'node-editor-window.c',
]
node_editor_resources = gnome.compile_resources('node_editor_resources',
'node-editor.gresource.xml',
source_dir: '.')
executable('gtk4-node-editor',
node_editor_sources, node_editor_resources,
dependencies: libgtk_dep,
include_directories: confinc,
gui_app: true,
link_args: extra_demo_ldflags,
install: false)
-114
View File
@@ -1,114 +0,0 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "node-editor-application.h"
#include "node-editor-window.h"
struct _NodeEditorApplication
{
GtkApplication parent;
};
struct _NodeEditorApplicationClass
{
GtkApplicationClass parent_class;
};
G_DEFINE_TYPE(NodeEditorApplication, node_editor_application, GTK_TYPE_APPLICATION);
static void
node_editor_application_init (NodeEditorApplication *app)
{
}
static void
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer data)
{
g_application_quit (G_APPLICATION (data));
}
static GActionEntry app_entries[] =
{
{ "quit", quit_activated, NULL, NULL, NULL }
};
static void
node_editor_application_startup (GApplication *app)
{
const gchar *quit_accels[2] = { "<Ctrl>Q", NULL };
G_APPLICATION_CLASS (node_editor_application_parent_class)->startup (app);
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
}
static void
node_editor_application_activate (GApplication *app)
{
NodeEditorWindow *win;
win = node_editor_window_new (NODE_EDITOR_APPLICATION (app));
gtk_window_present (GTK_WINDOW (win));
}
static void
node_editor_application_open (GApplication *app,
GFile **files,
gint n_files,
const gchar *hint)
{
NodeEditorWindow *win;
gint i;
for (i = 0; i < n_files; i++)
{
win = node_editor_window_new (NODE_EDITOR_APPLICATION (app));
node_editor_window_load (win, files[i]);
gtk_window_present (GTK_WINDOW (win));
}
}
static void
node_editor_application_class_init (NodeEditorApplicationClass *class)
{
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
application_class->startup = node_editor_application_startup;
application_class->activate = node_editor_application_activate;
application_class->open = node_editor_application_open;
}
NodeEditorApplication *
node_editor_application_new (void)
{
return g_object_new (NODE_EDITOR_APPLICATION_TYPE,
"application-id", "org.gtk.gtk4.NodeEditor",
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
}
@@ -1,38 +0,0 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __NODE_EDITOR_APPLICATION_H__
#define __NODE_EDITOR_APPLICATION_H__
#include <gtk/gtk.h>
#define NODE_EDITOR_APPLICATION_TYPE (node_editor_application_get_type ())
#define NODE_EDITOR_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NODE_EDITOR_APPLICATION_TYPE, NodeEditorApplication))
typedef struct _NodeEditorApplication NodeEditorApplication;
typedef struct _NodeEditorApplicationClass NodeEditorApplicationClass;
GType node_editor_application_get_type (void);
NodeEditorApplication *node_editor_application_new (void);
#endif /* __NODE_EDITOR_APPLICATION_H__ */
-408
View File
@@ -1,408 +0,0 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "node-editor-window.h"
#include "gsk/gskrendernodeparserprivate.h"
struct _NodeEditorWindow
{
GtkApplicationWindow parent;
guint text_timeout;
GtkWidget *picture;
GtkWidget *text_view;
GtkTextBuffer *text_buffer;
};
struct _NodeEditorWindowClass
{
GtkApplicationWindowClass parent_class;
};
G_DEFINE_TYPE(NodeEditorWindow, node_editor_window, GTK_TYPE_APPLICATION_WINDOW);
static gchar *
get_current_text (GtkTextBuffer *buffer)
{
GtkTextIter start, end;
gtk_text_buffer_get_start_iter (buffer, &start);
gtk_text_buffer_get_end_iter (buffer, &end);
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
}
static void
update_node (NodeEditorWindow *self)
{
GskRenderNode *node;
GError *error = NULL;
char *text;
GBytes *bytes;
text = get_current_text (self->text_buffer);
bytes = g_bytes_new_take (text, strlen (text));
node = gsk_render_node_deserialize (bytes, &error);
g_bytes_unref (bytes);
if (node)
{
/* XXX: Is this code necessary or can we have API to turn nodes into paintables? */
GtkSnapshot *snapshot;
GdkPaintable *paintable;
graphene_rect_t bounds;
snapshot = gtk_snapshot_new ();
gsk_render_node_get_bounds (node, &bounds);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- bounds.origin.x, - bounds.origin.y));
gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
paintable = gtk_snapshot_free_to_paintable (snapshot, &bounds.size);
gtk_picture_set_paintable (GTK_PICTURE (self->picture), paintable);
g_clear_object (&paintable);
}
else
{
gtk_picture_set_paintable (GTK_PICTURE (self->picture), NULL);
g_clear_error (&error);
}
}
static gboolean
update_timeout (gpointer data)
{
NodeEditorWindow *self = data;
self->text_timeout = 0;
update_node (self);
return G_SOURCE_REMOVE;
}
static void
text_changed (GtkTextBuffer *buffer,
NodeEditorWindow *self)
{
if (self->text_timeout != 0)
g_source_remove (self->text_timeout);
self->text_timeout = g_timeout_add (100, update_timeout, self);
}
static gboolean
query_tooltip_cb (GtkWidget *widget,
gint x,
gint y,
gboolean keyboard_tip,
GtkTooltip *tooltip,
NodeEditorWindow *self)
{
GtkTextIter iter;
//GList *l;
if (keyboard_tip)
{
gint offset;
g_object_get (self->text_buffer, "cursor-position", &offset, NULL);
gtk_text_buffer_get_iter_at_offset (self->text_buffer, &iter, offset);
}
else
{
gint bx, by, trailing;
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (self->text_view), GTK_TEXT_WINDOW_TEXT,
x, y, &bx, &by);
gtk_text_view_get_iter_at_position (GTK_TEXT_VIEW (self->text_view), &iter, &trailing, bx, by);
}
#if 0
for (l = ce->priv->errors; l; l = l->next)
{
CssError *css_error = l->data;
if (gtk_text_iter_in_range (&iter, &css_error->start, &css_error->end))
{
gtk_tooltip_set_text (tooltip, css_error->error->message);
return TRUE;
}
}
#endif
return FALSE;
}
gboolean
node_editor_window_load (NodeEditorWindow *self,
GFile *file)
{
GtkTextIter start, end;
GBytes *bytes;
bytes = g_file_load_bytes (file, NULL, NULL, NULL);
if (bytes == NULL)
return FALSE;
if (!g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
{
g_bytes_unref (bytes);
return FALSE;
}
gtk_text_buffer_get_start_iter (self->text_buffer, &start);
gtk_text_buffer_get_end_iter (self->text_buffer, &end);
gtk_text_buffer_insert (self->text_buffer,
&end,
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes));
return TRUE;
}
static void
open_response_cb (GtkWidget *dialog,
gint response,
NodeEditorWindow *self)
{
gtk_widget_hide (dialog);
if (response == GTK_RESPONSE_ACCEPT)
{
GFile *file;
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
node_editor_window_load (self, file);
g_object_unref (file);
}
gtk_widget_destroy (dialog);
}
static void
open_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("",
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Load", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
gtk_widget_show (dialog);
}
static void
save_response_cb (GtkWidget *dialog,
gint response,
NodeEditorWindow *self)
{
gtk_widget_hide (dialog);
if (response == GTK_RESPONSE_ACCEPT)
{
char *text, *filename;
GError *error = NULL;
text = get_current_text (self->text_buffer);
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
if (!g_file_set_contents (filename, text, -1, &error))
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
"Saving failed");
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", error->message);
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (dialog);
g_error_free (error);
}
g_free (filename);
}
gtk_widget_destroy (dialog);
}
static void
save_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("",
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
GTK_FILE_CHOOSER_ACTION_SAVE,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Save", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
g_signal_connect (dialog, "response", G_CALLBACK (save_response_cb), self);
gtk_widget_show (dialog);
}
static GdkTexture *
create_texture (NodeEditorWindow *self)
{
GdkPaintable *paintable;
GtkSnapshot *snapshot;
GskRenderer *renderer;
GskRenderNode *node;
GdkTexture *texture;
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
if (paintable == NULL ||
gdk_paintable_get_intrinsic_width (paintable) <= 0 ||
gdk_paintable_get_intrinsic_height (paintable) <= 0)
return NULL;
snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable));
node = gtk_snapshot_free_to_node (snapshot);
if (node == NULL)
return NULL;
/* ahem */
renderer = GTK_ROOT_GET_IFACE (gtk_widget_get_root (GTK_WIDGET (self)))->get_renderer (gtk_widget_get_root (GTK_WIDGET (self)));
texture = gsk_renderer_render_texture (renderer, node, NULL);
gsk_render_node_unref (node);
return texture;
}
static void
export_image_response_cb (GtkWidget *dialog,
gint response,
GdkTexture *texture)
{
gtk_widget_hide (dialog);
if (response == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
if (!gdk_texture_save_to_png (texture, filename))
{
GtkWidget *message_dialog;
message_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))),
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
"Exporting to image failed");
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (message_dialog);
}
g_free (filename);
}
gtk_widget_destroy (dialog);
g_object_unref (texture);
}
static void
export_image_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GdkTexture *texture;
GtkWidget *dialog;
texture = create_texture (self);
if (texture == NULL)
return;
dialog = gtk_file_chooser_dialog_new ("",
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
GTK_FILE_CHOOSER_ACTION_SAVE,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Save", GTK_RESPONSE_ACCEPT,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
g_signal_connect (dialog, "response", G_CALLBACK (export_image_response_cb), texture);
gtk_widget_show (dialog);
}
static void
node_editor_window_finalize (GObject *object)
{
NodeEditorWindow *self = NODE_EDITOR_WINDOW (object);
if (self->text_timeout != 0)
g_source_remove (self->text_timeout);
G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object);
}
static void
node_editor_window_class_init (NodeEditorWindowClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->finalize = node_editor_window_finalize;
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/gtk4/node-editor/node-editor-window.ui");
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, text_buffer);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, text_view);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, picture);
gtk_widget_class_bind_template_callback (widget_class, text_changed);
gtk_widget_class_bind_template_callback (widget_class, query_tooltip_cb);
gtk_widget_class_bind_template_callback (widget_class, open_cb);
gtk_widget_class_bind_template_callback (widget_class, save_cb);
gtk_widget_class_bind_template_callback (widget_class, export_image_cb);
}
static void
node_editor_window_init (NodeEditorWindow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
NodeEditorWindow *
node_editor_window_new (NodeEditorApplication *application)
{
return g_object_new (NODE_EDITOR_WINDOW_TYPE,
"application", application,
NULL);
}
-42
View File
@@ -1,42 +0,0 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __NODE_EDITOR_WINDOW_H__
#define __NODE_EDITOR_WINDOW_H__
#include <gtk/gtk.h>
#include "node-editor-application.h"
#define NODE_EDITOR_WINDOW_TYPE (node_editor_window_get_type ())
#define NODE_EDITOR_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NODE_EDITOR_WINDOW_TYPE, NodeEditorWindow))
typedef struct _NodeEditorWindow NodeEditorWindow;
typedef struct _NodeEditorWindowClass NodeEditorWindowClass;
GType node_editor_window_get_type (void);
NodeEditorWindow * node_editor_window_new (NodeEditorApplication *application);
gboolean node_editor_window_load (NodeEditorWindow *self,
GFile *file);
#endif /* __NODE_EDITOR_WINDOW_H__ */
-118
View File
@@ -1,118 +0,0 @@
<interface>
<object class="GtkTextTagTable" id="tags">
<child type="tag">
<object class="GtkTextTag">
<property name="name">warning</property>
<property name="underline">single</property>
<property name="underline-rgba">darkorange</property>
</object>
</child>
<child type="tag">
<object class="GtkTextTag">
<property name="name">error</property>
<property name="underline">error</property>
</object>
</child>
</object>
<object class="GtkTextBuffer" id="text_buffer">
<property name="tag-table">tags</property>
<signal name="changed" handler="text_changed"/>
</object>
<template class="NodeEditorWindow" parent="GtkApplicationWindow">
<style>
<class name="devel"/>
</style>
<property name="title" translatable="yes">GTK Node Editor</property>
<property name="default-width">1024</property>
<property name="default-height">768</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="title" translatable="yes">GTK Node Editor</property>
<property name="show-title-buttons">1</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkButton">
<property name="icon-name">document-open-symbolic</property>
<signal name="clicked" handler="open_cb"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">document-save-symbolic</property>
<signal name="clicked" handler="save_cb"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">insert-image-symbolic</property>
<signal name="clicked" handler="export_image_cb"/>
</object>
</child>
</object>
<packing>
<property name="pack-type">start</property>
</packing>
</child>
<child type="title">
<object class="GtkLabel">
<property name="label" translatable="yes">GTK Node Editor</property>
</object>
</child>
<child>
<object class="GtkToggleButton">
<property name="icon-name">view-more-symbolic</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkPaned">
<property name="position">99999</property>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="expand">1</property>
<child>
<object class="GtkTextView" id="text_view">
<property name="buffer">text_buffer</property>
<property name="wrap-mode">word</property>
<property name="monospace">1</property>
<property name="has-focus">1</property>
<property name="left-margin">6</property>
<property name="right-margin">6</property>
<property name="has-tooltip">1</property>
<signal name="query-tooltip" handler="query_tooltip_cb"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="expand">1</property>
<property name="min-content-height">100</property>
<property name="min-content-width">100</property>
<child>
<object class="GtkViewport">
<child>
<object class="GtkPicture" id="picture">
<property name="can-shrink">false</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="shrink">false</property>
</packing>
</child>
</object>
</child>
</template>
</interface>
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gtk/gtk4/node-editor">
<file preprocess="xml-stripblanks">node-editor-window.ui</file>
</gresource>
</gresources>
@@ -31,4 +31,11 @@
<translation type="gettext">gtk-4.0</translation>
<update_contact>matthias.clasen_at_gmail.com</update_contact>
<developer_name>Matthias Clasen and others</developer_name>
<releases>
<release version="3.94.0" date="2018-06-25">
<description>
<p>A new developers snapshot towards GTK 4.0.</p>
</description>
</release>
</releases>
</component>
+1 -1
View File
@@ -48,7 +48,7 @@ change_transition_state (GSimpleAction *action,
GtkStackTransitionType transition;
if (g_variant_get_boolean (state))
transition = GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT;
transition = GTK_STACK_TRANSITION_TYPE_ROTATE_LEFT_RIGHT;
else
transition = GTK_STACK_TRANSITION_TYPE_NONE;
+4 -12
View File
@@ -411,15 +411,12 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="stack">toplevel_stack</property>
</object>
</child>
<child>
<child type="end">
<object class="GtkMenuButton" id="gear_menu_button">
<property name="valign">center</property>
<property name="menu-model">gear_menu</property>
<property name="icon-name">open-menu-symbolic</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
</object>
</child>
@@ -429,7 +426,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="margin">10</property>
<child>
<object class="GtkStack" id="toplevel_stack">
<property name="transition-duration">30000</property>
<property name="transition-duration">1000</property>
<child>
<object class="GtkStackPage">
<property name="name">page1</property>
@@ -1588,16 +1585,13 @@ microphone-sensitivity-medium-symbolic</property>
<property name="halign">center</property>
</object>
</child>
<child>
<child type="end">
<object class="GtkMenuButton">
<property name="menu-model">dinner_menu</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="icon-name">emblem-system-symbolic</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
</object>
</child>
@@ -2848,6 +2842,7 @@ microphone-sensitivity-medium-symbolic</property>
</child>
<child>
<object class="GtkToolItem">
<property name="expand-item">1</property>
<child>
<object class="GtkScale">
<property name="draw-value">0</property>
@@ -2855,9 +2850,6 @@ microphone-sensitivity-medium-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">1</property>
</packing>
</child>
<child>
<object class="GtkToolItem">
-5
View File
@@ -271,7 +271,6 @@ gdk_surface_get_frame_extents
gdk_surface_get_origin
gdk_surface_get_root_coords
gdk_surface_get_device_position
gdk_surface_get_device_position_double
GdkModifierType
GdkModifierIntent
gdk_surface_get_parent
@@ -280,7 +279,6 @@ gdk_surface_get_children
gdk_surface_peek_children
gdk_surface_set_icon_name
gdk_surface_set_transient_for
gdk_surface_set_role
gdk_surface_set_startup_id
gdk_surface_set_group
gdk_surface_get_group
@@ -502,7 +500,6 @@ gdk_device_get_has_cursor
gdk_device_get_n_axes
gdk_device_get_n_keys
gdk_device_get_axes
gdk_device_warp
gdk_device_get_seat
<SUBSECTION>
@@ -512,9 +509,7 @@ gdk_device_ungrab
<SUBSECTION>
gdk_device_get_state
gdk_device_get_position
gdk_device_get_position_double
gdk_device_get_surface_at_position
gdk_device_get_surface_at_position_double
gdk_device_get_history
gdk_device_free_history
GdkTimeCoord
+1
View File
@@ -18,6 +18,7 @@
<title>API Reference</title>
<xi:include href="xml/GskRenderer.xml" />
<xi:include href="xml/GskRenderNode.xml" />
<xi:include href="xml/GskRoundedRect.xml" />
<xi:include href="xml/GskTransform.xml" />
</reference>
+1 -8
View File
@@ -67,11 +67,7 @@ gsk_container_node_get_n_children
gsk_container_node_get_child
gsk_transform_node_new
gsk_transform_node_get_child
gsk_transform_node_peek_transform
gsk_offset_node_new
gsk_offset_node_get_child
gsk_offset_node_get_x_offset
gsk_offset_node_get_y_offset
gsk_transform_node_get_transform
gsk_opacity_node_new
gsk_opacity_node_get_child
gsk_opacity_node_get_opacity
@@ -147,7 +143,6 @@ gsk_rounded_rect_intersects_rect
<SECTION>
<FILE>GskTransform</FILE>
<TITLE>3D transformations</TITLE>
GskTransform
gsk_transform_ref
gsk_transform_unref
@@ -157,8 +152,6 @@ gsk_transform_get_category
<SUBSECTION>
gsk_transform_print
gsk_transform_to_string
gsk_transform_from_string
<SUBSECTION>
gsk_transform_to_matrix
gsk_transform_to_2d
gsk_transform_to_affine
+2 -16
View File
@@ -546,7 +546,7 @@ checkbutton:indeterminate {
GTK adds several additional ways to specify colors.
</para>
<literallayout><code>〈gtk color〉 = 〈symbolic color〉 | 〈color expression〉 | 〈win32 color〉</code>
<literallayout><code>〈gtk color〉 = 〈symbolic color〉 | 〈color expression〉</code>
</literallayout>
<para>
@@ -592,13 +592,6 @@ checkbutton:indeterminate {
<literallayout><code>〈color expression〉 = lighter( 〈color〉 ) | darker( 〈color〉 ) | shade( 〈color〉, 〈number〉 ) |</code>
<code> alpha( 〈color〉, 〈number〉 ) | mix( 〈color〉, 〈color〉, 〈number〉 )</code>
</literallayout>
<para>
On Windows, GTK allows to refer to system colors, as follows:
</para>
<literallayout><code>〈win32 color〉 = -gtk-win32-color( 〈name〉, 〈integer〉 )</code>
</literallayout>
</refsect2>
@@ -737,7 +730,7 @@ label {
GTK extends the CSS syntax for images and also uses it for specifying icons.
</para>
<literallayout><code>〈gtk image〉 = 〈themed icon〉 | 〈scaled image〉 | 〈recolored image〉 | 〈win32 theme part〉</code>
<literallayout><code>〈gtk image〉 = 〈themed icon〉 | 〈scaled image〉 | 〈recolored image〉</code>
</literallayout>
<para>
@@ -815,13 +808,6 @@ arrow {
}
]]></programlisting>
</example>
<para>
On Windows, GTK allows to refer to system theme parts as images, as follows:
</para>
<literallayout><code>〈win32 theme part〉 = -gtk-win32-theme-part( 〈name〉, 〈integer〉 〈integer〉</code>
<code> [ , [ over( 〈integer〉 〈integer〉 [ , 〈alpha value〉 ]? ) | margins( 〈integer〉{1,4} ) ] ]* )</code>
</literallayout>
</refsect2>
-14
View File
@@ -65,20 +65,6 @@ We use <literallayout> for syntax productions, and each line is put in a <code>
not quite the same as the CSS definition of rem.
</para>
<para>
Whereever a number is allowed, GTK also accepts a Windows-specific
theme size:
</para>
<literallayout>
<code>〈win32 theme size〉 = 〈win32 size〉 | 〈win32 part size〉</code>
<code>〈win32 size〉 = -gtk-win32-size ( 〈theme name〉, 〈metric id〉 )</code>
<code>〈win32 part size〉 = [ -gtk-win32-part-width | -gtk-win32-part-height |</code>
<code> -gtk-win32-part-border-top | -gtk-win32-part-border-right |</code>
<code> -gtk-win32-part-border-bottom | -gtk-win32-part-border-left ]</code>
<code> ( 〈theme name〉 , 〈integer〉 , 〈integer〉 )</code>
</literallayout>
<literallayout><code>〈calc expression〉 = calc( 〈calc sum〉 )</code>
<code>〈calc sum〉 = 〈calc product〉 [ [ + | - ] 〈calc product〉 ]*</code>
<code>〈calc product〉 = 〈calc value〉 [ * 〈calc value〉 | / 〈number〉 ]*</code>
+7
View File
@@ -100,6 +100,13 @@
<xi:include href="xml/gtkfixed.xml" />
</chapter>
<chapter id="LayoutManagers">
<title>Layout Managers</title>
<xi:include href="xml/gtklayoutmanager.xml" />
<xi:include href="xml/gtklayoutchild.xml" />
<xi:include href="xml/gtkboxlayout.xml" />
</chapter>
<chapter id="DisplayWidgets">
<title>Display Widgets</title>
<xi:include href="xml/gtklabel.xml" />
+70 -7
View File
@@ -424,6 +424,7 @@ gtk_selection_model_select_range
gtk_selection_model_unselect_range
gtk_selection_model_select_all
gtk_selection_model_unselect_all
gtk_selection_model_query_range
<SUBSECTION>
gtk_selection_model_selection_changed
<SUBSECTION Standard>
@@ -1297,6 +1298,8 @@ gtk_file_filter_get_type
<TITLE>GtkFilterListModel</TITLE>
GtkFilterListModel
gtk_filter_list_model_new
gtk_filter_list_model_new_for_type
gtk_filter_list_model_set_model
gtk_filter_list_model_get_model
gtk_filter_list_model_set_filter_func
gtk_filter_list_model_has_filter
@@ -1386,6 +1389,7 @@ gtk_font_chooser_set_font
gtk_font_chooser_get_font_desc
gtk_font_chooser_set_font_desc
gtk_font_chooser_get_font_features
gtk_font_chooser_get_language
gtk_font_chooser_set_language
gtk_font_chooser_get_preview_text
gtk_font_chooser_set_preview_text
@@ -4378,6 +4382,8 @@ gtk_snapshot_push_clip
gtk_snapshot_push_rounded_clip
gtk_snapshot_push_cross_fade
gtk_snapshot_push_blend
gtk_snapshot_push_blur
gtk_snapshot_push_shadow
gtk_snapshot_push_debug
gtk_snapshot_pop
gtk_snapshot_save
@@ -4406,6 +4412,8 @@ gtk_snapshot_render_frame
gtk_snapshot_render_focus
gtk_snapshot_render_layout
gtk_snapshot_render_insertion_cursor
<SUBSECTION Private>
gtk_snapshot_get_type
</SECTION>
<SECTION>
@@ -4496,7 +4504,6 @@ gtk_widget_get_cursor
gtk_widget_set_cursor
gtk_widget_set_cursor_from_name
gtk_widget_mnemonic_activate
gtk_widget_send_focus_change
gtk_widget_class_set_accessible_type
gtk_widget_class_set_accessible_role
gtk_widget_get_accessible
@@ -4590,6 +4597,8 @@ gtk_widget_get_first_child
gtk_widget_get_last_child
gtk_widget_insert_before
gtk_widget_insert_after
gtk_widget_set_layout_manager
gtk_widget_get_layout_manager
<SUBSECTION>
gtk_widget_get_path
@@ -4686,8 +4695,6 @@ gtk_window_activate_focus
gtk_window_activate_default
gtk_window_set_modal
gtk_window_set_default_size
gtk_window_set_gravity
gtk_window_get_gravity
gtk_window_set_hide_on_close
gtk_window_get_hide_on_close
GtkWindowPosition
@@ -4735,7 +4742,6 @@ gtk_window_set_urgency_hint
gtk_window_set_accept_focus
gtk_window_set_focus_on_map
gtk_window_set_startup_id
gtk_window_set_role
gtk_window_get_decorated
gtk_window_get_deletable
gtk_window_get_default_icon_name
@@ -4744,8 +4750,6 @@ gtk_window_get_destroy_with_parent
gtk_window_get_icon_name
gtk_window_get_mnemonic_modifier
gtk_window_get_modal
gtk_window_get_position
gtk_window_get_role
gtk_window_get_size
gtk_window_get_title
gtk_window_get_transient_for
@@ -4759,7 +4763,6 @@ gtk_window_get_focus_on_map
gtk_window_get_group
gtk_window_has_group
gtk_window_get_window_type
gtk_window_move
gtk_window_resize
gtk_window_set_default_icon_name
gtk_window_set_icon_name
@@ -6216,6 +6219,10 @@ gtk_color_chooser_get_use_alpha
gtk_color_chooser_set_use_alpha
gtk_color_chooser_add_palette
<SUBSECTION>
gtk_hsv_to_rgb
gtk_rgb_to_hsv
<SUBSECTION Standard>
GTK_TYPE_COLOR_CHOOSER
GTK_COLOR_CHOOSER
@@ -6333,6 +6340,7 @@ gtk_stack_add_named
gtk_stack_add_titled
gtk_stack_get_child_by_name
gtk_stack_get_page
gtk_stack_get_pages
gtk_stack_page_get_child
gtk_stack_set_visible_child
gtk_stack_get_visible_child
@@ -6363,6 +6371,7 @@ GTK_STACK_GET_CLASS
<SUBSECTION Private>
gtk_stack_get_type
gtk_stack_page_get_type
</SECTION>
<SECTION>
@@ -6524,6 +6533,7 @@ gtk_popover_get_type
<TITLE>GtkPopoverMenu</TITLE>
GtkPopoverMenu
gtk_popover_menu_new
gtk_popover_menu_add_submenu
gtk_popover_menu_open_submenu
<SUBSECTION Standard>
@@ -7149,6 +7159,59 @@ gtk_media_stream_get_type
<TITLE>GtkRoot</TITLE>
GtkRoot
gtk_root_get_for_surface
gtk_root_get_focus
gtk_root_set_focus
<SUBSECTION>
gtk_root_install_properties
<SUBSECTION Private>
gtk_root_get_type
</SECTION>
<SECTION>
<FILE>gtklayoutmanager</FILE>
GtkLayoutManager
GtkLayoutManagerClass
gtk_layout_manager_measure
gtk_layout_manager_allocate
gtk_layout_manager_get_request_mode
gtk_layout_manager_get_widget
gtk_layout_manager_get_layout_child
gtk_layout_manager_layout_changed
<SUBSECTION Standard>
GTK_TYPE_LAYOUT_MANAGER
gtk_layout_manager_get_type
</SECTION>
<SECTION>
<FILE>gtklayoutchild</FILE>
GtkLayoutChild
GtkLayoutChildClass
gtk_layout_child_get_layout_manager
gtk_layout_child_get_child_widget
<SUBSECTION Standard>
GTK_TYPE_LAYOUT_CHILD
gtk_layout_child_get_type
</SECTION>
<SECTION>
<FILE>gtkboxlayout</FILE>
GtkBoxLayout
gtk_box_layout_new
gtk_box_layout_set_homogeneous
gtk_box_layout_get_homogeneous
gtk_box_layout_set_spacing
gtk_box_layout_get_spacing
gtk_box_layout_set_baseline_position
gtk_box_layout_get_baseline_position
<SUBSECTION Standard>
GTK_TYPE_BOX_LAYOUT
gtk_box_layout_get_type
</SECTION>
+33 -1
View File
@@ -289,6 +289,28 @@
</para>
</section>
<section>
<title>Stop using gdk_pointer_warp()</title>
<para>
Warping the pointer is disorienting and unfriendly to users.
GTK 4 does not support it. In special circumstances (such as when
implementing remote connection UIs) it can be necessary to
warp the pointer; in this case, use platform APIs such as XWarpPointer
directly.
</para>
</section>
<section>
<title>Adapt to coordinate api changes</title>
<para>
A number of coordinate apis in GTK 3 had _double variants:
gdk_device_get_position(), gdk_device_get_surface_at_position(),
gdk_surface_get_device_position(). These have been changed to use
doubles, and the _double variants have been removed. Update your
code accordingly.
</para>
</section>
<section>
<title>Adapt to GdkKeymap API changes</title>
<para>
@@ -321,12 +343,22 @@
</section>
<section>
<title>Adapt to GtkHeaderBar API changes</title>
<title>Adapt to GtkHeaderBar and GtkActionBar API changes</title>
<para>
The gtk_header_bar_set_show_close_button() function has been renamed to
the more accurate name gtk_header_bar_set_show_title_buttons(). The corresponding
getter and the property itself have also been renamed.
</para>
<para>
The ::pack-type child properties of GtkHeaderBar and GtkActionBar have
been removed. If you need to programmatically place children, use the
pack_start() and pack_end() APIs. In ui files, use the type attribute
on the child element.
</para>
<para>
gtk4-builder-tool can help with this conversion, with the --3to4 option
of the simplify command.
</para>
</section>
<section>
+2 -5
View File
@@ -150,11 +150,8 @@ see for example <link
linkend="gtk-window-iconify">gtk_window_iconify()</link> or <link
linkend="gtk-window-maximize">gtk_window_maximize()</link> or <link
linkend="gtk-window-set-decorated">gtk_window_set_decorated()</link>.
Keep in mind that <link
linkend="gtk-window-move">gtk_window_move()</link> and window sizing
are ultimately controlled by the window manager as well and most
window managers <emphasis>will</emphasis> ignore certain requests from
time to time, in the interests of good user interface.
Keep in mind that most window managers <emphasis>will</emphasis> ignore
certain requests from time to time, in the interests of good user interface.
</para>
<!--
+4 -8
View File
@@ -22,25 +22,21 @@
<property name="stack">stack</property>
</object>
</child>
<child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
<child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
<style>
<class name="image-button"/>
</style>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
</object>
</child>
+2 -4
View File
@@ -13,14 +13,12 @@
<property name="stack">stack</property>
</object>
</child>
<child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
</object>
</child>
+4 -8
View File
@@ -13,25 +13,21 @@
<property name="stack">stack</property>
</object>
</child>
<child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
<child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
<style>
<class name="image-button"/>
</style>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
</object>
</child>
+4 -8
View File
@@ -24,25 +24,21 @@
<property name="stack">stack</property>
</object>
</child>
<child>
<child type="end">
<object class="GtkToggleButton" id="search">
<property name="sensitive">0</property>
<property name="icon-name">edit-find-symbolic</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
<child>
<child type="end">
<object class="GtkMenuButton" id="gears">
<property name="direction">none</property>
<style>
<class name="image-button"/>
</style>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
<packing/>
</child>
</object>
</child>
+5
View File
@@ -22,6 +22,9 @@ typedef enum { /* Sync changes with broadway.js */
BROADWAY_NODE_CLIP = 10,
BROADWAY_NODE_KEEP_ALL = 11,
BROADWAY_NODE_KEEP_THIS = 12,
BROADWAY_NODE_TRANSFORM = 13,
BROADWAY_NODE_DEBUG = 14,
BROADWAY_NODE_REUSE = 15,
} BroadwayNodeType;
static const char *broadway_node_type_names[] G_GNUC_UNUSED = {
@@ -38,6 +41,8 @@ static const char *broadway_node_type_names[] G_GNUC_UNUSED = {
"CLIP",
"KEEP_ALL",
"KEEP_THIS",
"TRANSLATE",
"DEBUG",
};
typedef enum {
+253 -26
View File
@@ -35,7 +35,6 @@
#include <string.h>
#endif
typedef struct {
int id;
guint32 tag;
@@ -126,23 +125,56 @@ struct BroadwaySurface {
gint32 transient_for;
guint32 texture;
BroadwayNode *nodes;
GHashTable *node_lookup;
};
struct _BroadwayTexture {
grefcount refcount;
guint32 id;
GBytes *bytes;
};
static void broadway_server_resync_surfaces (BroadwayServer *server);
static void send_outstanding_roundtrips (BroadwayServer *server);
static void broadway_server_ref_texture (BroadwayServer *server,
guint32 id);
static GType broadway_server_get_type (void);
G_DEFINE_TYPE (BroadwayServer, broadway_server, G_TYPE_OBJECT)
static void
broadway_node_free (BroadwayNode *node)
broadway_texture_free (BroadwayTexture *texture)
{
g_bytes_unref (texture->bytes);
g_free (texture);
}
static void
broadway_node_unref (BroadwayServer *server,
BroadwayNode *node)
{
int i;
for (i = 0; i < node->n_children; i++)
broadway_node_free (node->children[i]);
g_free (node);
if (g_ref_count_dec (&node->refcount))
{
for (i = 0; i < node->n_children; i++)
broadway_node_unref (server, node->children[i]);
if (node->texture_id)
broadway_server_release_texture (server, node->texture_id);
g_free (node);
}
}
static BroadwayNode *
broadway_node_ref (BroadwayNode *node)
{
g_ref_count_inc (&node->refcount);
return node;
}
gboolean
@@ -204,7 +236,7 @@ broadway_server_init (BroadwayServer *server)
server->surface_id_hash = g_hash_table_new (NULL, NULL);
server->id_counter = 0;
server->textures = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
(GDestroyNotify)g_bytes_unref);
(GDestroyNotify)broadway_texture_free);
root = g_new0 (BroadwaySurface, 1);
root->id = server->id_counter++;
@@ -241,10 +273,12 @@ broadway_server_class_init (BroadwayServerClass * class)
}
static void
broadway_surface_free (BroadwaySurface *surface)
broadway_surface_free (BroadwayServer *server,
BroadwaySurface *surface)
{
if (surface->nodes)
broadway_node_free (surface->nodes);
broadway_node_unref (server, surface->nodes);
g_hash_table_unref (surface->node_lookup);
g_free (surface);
}
@@ -1477,7 +1511,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
server->surfaces = g_list_remove (server->surfaces, surface);
g_hash_table_remove (server->surface_id_hash,
GINT_TO_POINTER (id));
broadway_surface_free (surface);
broadway_surface_free (server, surface);
}
}
@@ -1605,53 +1639,242 @@ broadway_server_has_client (BroadwayServer *server)
return server->output != NULL;
}
#define NODE_SIZE_COLOR 1
#define NODE_SIZE_FLOAT 1
#define NODE_SIZE_POINT 2
#define NODE_SIZE_MATRIX 16
#define NODE_SIZE_SIZE 2
#define NODE_SIZE_RECT (NODE_SIZE_POINT + NODE_SIZE_SIZE)
#define NODE_SIZE_RRECT (NODE_SIZE_RECT + 4 * NODE_SIZE_SIZE)
#define NODE_SIZE_COLOR_STOP (NODE_SIZE_FLOAT + NODE_SIZE_COLOR)
#define NODE_SIZE_SHADOW (NODE_SIZE_COLOR + 3 * NODE_SIZE_FLOAT)
static guint32
rotl (guint32 value, int shift)
{
if ((shift &= 32 - 1) == 0)
return value;
return (value << shift) | (value >> (32 - shift));
}
static BroadwayNode *
decode_nodes (BroadwayServer *server,
BroadwaySurface *surface,
int len,
guint32 data[],
GHashTable *client_texture_map,
int *pos)
{
BroadwayNode *node;
guint32 type, id;
guint32 i, n_stops, n_shadows, n_chars;
guint32 size, n_children;
gint32 texture_offset;
guint32 hash;
guint32 transform_type;
g_assert (*pos < len);
size = 0;
n_children = 0;
texture_offset = -1;
type = data[(*pos)++];
id = data[(*pos)++];
switch (type) {
case BROADWAY_NODE_REUSE:
node = g_hash_table_lookup (surface->node_lookup, GINT_TO_POINTER(id));
g_assert (node != NULL);
return broadway_node_ref (node);
break;
case BROADWAY_NODE_COLOR:
size = NODE_SIZE_RECT + NODE_SIZE_COLOR;
break;
case BROADWAY_NODE_BORDER:
size = NODE_SIZE_RRECT + 4 * NODE_SIZE_FLOAT + 4 * NODE_SIZE_COLOR;
break;
case BROADWAY_NODE_INSET_SHADOW:
case BROADWAY_NODE_OUTSET_SHADOW:
size = NODE_SIZE_RRECT + NODE_SIZE_COLOR + 4 * NODE_SIZE_FLOAT;
break;
case BROADWAY_NODE_TEXTURE:
texture_offset = 4;
size = 5;
break;
case BROADWAY_NODE_CONTAINER:
size = 1;
n_children = data[*pos];
break;
case BROADWAY_NODE_ROUNDED_CLIP:
size = NODE_SIZE_RRECT;
n_children = 1;
break;
case BROADWAY_NODE_CLIP:
size = NODE_SIZE_RECT;
n_children = 1;
break;
case BROADWAY_NODE_TRANSFORM:
transform_type = data[(*pos)];
size = 1;
if (transform_type == 0) {
size += NODE_SIZE_POINT;
} else if (transform_type == 1) {
size += NODE_SIZE_MATRIX;
} else {
g_assert_not_reached();
}
n_children = 1;
break;
case BROADWAY_NODE_LINEAR_GRADIENT:
size = NODE_SIZE_RECT + 2 * NODE_SIZE_POINT;
n_stops = data[*pos + size++];
size += n_stops * NODE_SIZE_COLOR_STOP;
break;
case BROADWAY_NODE_SHADOW:
size = 1;
n_shadows = data[*pos];
size += n_shadows * NODE_SIZE_SHADOW;
n_children = 1;
break;
case BROADWAY_NODE_OPACITY:
size = NODE_SIZE_FLOAT;
n_children = 1;
break;
case BROADWAY_NODE_DEBUG:
n_chars = data[*pos];
size = 1 + (n_chars + 3) / 4;
n_children = 1;
break;
default:
g_assert_not_reached ();
}
node = g_malloc (sizeof(BroadwayNode) + (size - 1) * sizeof(guint32) + n_children * sizeof (BroadwayNode *));
g_ref_count_init (&node->refcount);
node->type = type;
node->id = id;
node->texture_id = 0;
node->n_children = n_children;
node->children = (BroadwayNode **)((char *)node + sizeof(BroadwayNode) + (size - 1) * sizeof(guint32));
node->n_data = size;
for (i = 0; i < size; i++)
{
node->data[i] = data[(*pos)++];
if (i == texture_offset)
{
node->texture_id = GPOINTER_TO_INT (g_hash_table_lookup (client_texture_map, GINT_TO_POINTER (node->data[i])));
broadway_server_ref_texture (server, node->texture_id);
node->data[i] = node->texture_id;
}
}
for (i = 0; i < n_children; i++)
node->children[i] = decode_nodes (server, surface, len, data, client_texture_map, pos);
hash = node->type << 16;
for (i = 0; i < size; i++)
hash ^= rotl (node->data[i], i);
for (i = 0; i < n_children; i++)
hash ^= rotl (node->children[i]->hash, i);
node->hash = hash;
return node;
}
static void
init_node_lookup (BroadwaySurface *surface,
BroadwayNode *node)
{
int i;
g_hash_table_insert (surface->node_lookup, GINT_TO_POINTER(node->id), node);
for (i = 0; i < node->n_children; i++)
init_node_lookup (surface, node->children[i]);
}
/* passes ownership of nodes */
void
broadway_server_surface_set_nodes (BroadwayServer *server,
gint id,
BroadwayNode *root)
broadway_server_surface_update_nodes (BroadwayServer *server,
gint id,
guint32 data[],
int len,
GHashTable *client_texture_map)
{
BroadwaySurface *surface;
int pos = 0;
BroadwayNode *root;
surface = broadway_server_lookup_surface (server, id);
if (surface == NULL)
return;
root = decode_nodes (server, surface, len, data, client_texture_map, &pos);
if (server->output != NULL)
broadway_output_surface_set_nodes (server->output, surface->id,
root,
surface->nodes);
if (surface->nodes)
broadway_node_free (surface->nodes);
broadway_node_unref (server, surface->nodes);
surface->nodes = root;
g_hash_table_remove_all (surface->node_lookup);
init_node_lookup (surface, surface->nodes);
}
guint32
broadway_server_upload_texture (BroadwayServer *server,
GBytes *texture)
GBytes *bytes)
{
guint32 id;
BroadwayTexture *texture;
texture = g_new0 (BroadwayTexture, 1);
g_ref_count_init (&texture->refcount);
texture->id = ++server->next_texture_id;
texture->bytes = g_bytes_ref (bytes);
id = ++server->next_texture_id;
g_hash_table_replace (server->textures,
GINT_TO_POINTER (id),
g_bytes_ref (texture));
GINT_TO_POINTER (texture->id),
texture);
if (server->output)
broadway_output_upload_texture (server->output, id, texture);
broadway_output_upload_texture (server->output, texture->id, texture->bytes);
return id;
return texture->id;
}
static void
broadway_server_ref_texture (BroadwayServer *server,
guint32 id)
{
BroadwayTexture *texture;
texture = g_hash_table_lookup (server->textures, GINT_TO_POINTER (id));
if (texture)
g_ref_count_inc (&texture->refcount);
}
void
broadway_server_release_texture (BroadwayServer *server,
guint32 id)
{
g_hash_table_remove (server->textures, GINT_TO_POINTER (id));
BroadwayTexture *texture;
if (server->output)
broadway_output_release_texture (server->output, id);
texture = g_hash_table_lookup (server->textures, GINT_TO_POINTER (id));
if (texture && g_ref_count_dec (&texture->refcount))
{
g_hash_table_remove (server->textures, GINT_TO_POINTER (id));
if (server->output)
broadway_output_release_texture (server->output, id);
}
}
gboolean
@@ -1801,6 +2024,7 @@ broadway_server_new_surface (BroadwayServer *server,
surface->width = width;
surface->height = height;
surface->is_temp = is_temp;
surface->node_lookup = g_hash_table_new (g_direct_hash, g_direct_equal);
g_hash_table_insert (server->surface_id_hash,
GINT_TO_POINTER (surface->id),
@@ -1835,9 +2059,12 @@ broadway_server_resync_surfaces (BroadwayServer *server)
/* First upload all textures */
g_hash_table_iter_init (&iter, server->textures);
while (g_hash_table_iter_next (&iter, &key, &value))
broadway_output_upload_texture (server->output,
GPOINTER_TO_INT (key),
(GBytes *)value);
{
BroadwayTexture *texture = value;
broadway_output_upload_texture (server->output,
GPOINTER_TO_INT (key),
texture->bytes);
}
/* Then create all surfaces */
for (l = server->surfaces; l != NULL; l = l->next)
+8 -2
View File
@@ -19,12 +19,16 @@ typedef struct _BroadwayServerClass BroadwayServerClass;
#define BROADWAY_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BROADWAY_TYPE_SERVER, BroadwayServerClass))
typedef struct _BroadwayNode BroadwayNode;
typedef struct _BroadwayTexture BroadwayTexture;
struct _BroadwayNode {
grefcount refcount;
guint32 type;
guint32 id;
guint32 hash; /* deep hash */
guint32 n_children;
BroadwayNode **children;
guint32 texture_id;
guint32 n_data;
guint32 data[1];
};
@@ -99,9 +103,11 @@ void broadway_server_release_texture (BroadwayServer *
guint32 id);
cairo_surface_t * broadway_server_create_surface (int width,
int height);
void broadway_server_surface_set_nodes (BroadwayServer *server,
void broadway_server_surface_update_nodes (BroadwayServer *server,
gint id,
BroadwayNode *root);
guint32 data[],
int len,
GHashTable *client_texture_map);
gboolean broadway_server_surface_move_resize (BroadwayServer *server,
gint id,
gboolean with_move,
+521 -277
View File
File diff suppressed because it is too large Load Diff
+3 -116
View File
@@ -215,116 +215,6 @@ get_client_serial (BroadwayClient *client, guint32 daemon_serial)
return client_serial;
}
#define NODE_SIZE_COLOR 1
#define NODE_SIZE_FLOAT 1
#define NODE_SIZE_POINT 2
#define NODE_SIZE_SIZE 2
#define NODE_SIZE_RECT (NODE_SIZE_POINT + NODE_SIZE_SIZE)
#define NODE_SIZE_RRECT (NODE_SIZE_RECT + 4 * NODE_SIZE_SIZE)
#define NODE_SIZE_COLOR_STOP (NODE_SIZE_FLOAT + NODE_SIZE_COLOR)
#define NODE_SIZE_SHADOW (NODE_SIZE_COLOR + 3 * NODE_SIZE_FLOAT)
static guint32
rotl (guint32 value, int shift)
{
if ((shift &= 32 - 1) == 0)
return value;
return (value << shift) | (value >> (32 - shift));
}
static BroadwayNode *
decode_nodes (BroadwayClient *client,
int len, guint32 data[], int *pos)
{
BroadwayNode *node;
guint32 type;
guint32 i, n_stops, n_shadows;
guint32 size, n_children;
gint32 texture_offset;
guint32 hash;
g_assert (*pos < len);
size = 0;
n_children = 0;
texture_offset = -1;
type = data[(*pos)++];
switch (type) {
case BROADWAY_NODE_COLOR:
size = NODE_SIZE_RECT + NODE_SIZE_COLOR;
break;
case BROADWAY_NODE_BORDER:
size = NODE_SIZE_RRECT + 4 * NODE_SIZE_FLOAT + 4 * NODE_SIZE_COLOR;
break;
case BROADWAY_NODE_INSET_SHADOW:
case BROADWAY_NODE_OUTSET_SHADOW:
size = NODE_SIZE_RRECT + NODE_SIZE_COLOR + 4 * NODE_SIZE_FLOAT;
break;
case BROADWAY_NODE_TEXTURE:
texture_offset = 4;
size = 5;
break;
case BROADWAY_NODE_CONTAINER:
size = 1;
n_children = data[*pos];
break;
case BROADWAY_NODE_ROUNDED_CLIP:
size = NODE_SIZE_RRECT;
n_children = 1;
break;
case BROADWAY_NODE_CLIP:
size = NODE_SIZE_RECT;
n_children = 1;
break;
case BROADWAY_NODE_LINEAR_GRADIENT:
size = NODE_SIZE_RECT + 2 * NODE_SIZE_POINT;
n_stops = data[*pos + size++];
size += n_stops * NODE_SIZE_COLOR_STOP;
break;
case BROADWAY_NODE_SHADOW:
size = 1;
n_shadows = data[*pos];
size += n_shadows * NODE_SIZE_SHADOW;
n_children = 1;
break;
case BROADWAY_NODE_OPACITY:
size = NODE_SIZE_FLOAT;
n_children = 1;
break;
default:
g_assert_not_reached ();
}
node = g_malloc (sizeof(BroadwayNode) + (size - 1) * sizeof(guint32) + n_children * sizeof (BroadwayNode *));
node->type = type;
node->n_children = n_children;
node->children = (BroadwayNode **)((char *)node + sizeof(BroadwayNode) + (size - 1) * sizeof(guint32));
node->n_data = size;
for (i = 0; i < size; i++)
{
node->data[i] = data[(*pos)++];
if (i == texture_offset)
node->data[i] = GPOINTER_TO_INT (g_hash_table_lookup (client->textures,
GINT_TO_POINTER (node->data[i])));
}
for (i = 0; i < n_children; i++)
node->children[i] = decode_nodes (client, len, data, pos);
hash = node->type << 16;
for (i = 0; i < size; i++)
hash ^= rotl (node->data[i], i);
for (i = 0; i < n_children; i++)
hash ^= rotl (node->children[i]->hash, i);
node->hash = hash;
return node;
}
static void
client_handle_request (BroadwayClient *client,
BroadwayRequest *request)
@@ -400,13 +290,10 @@ client_handle_request (BroadwayClient *client,
{
gsize array_size = request->base.size - sizeof (BroadwayRequestSetNodes) + sizeof(guint32);
int n_data = array_size / sizeof(guint32);
int pos = 0;
BroadwayNode *node;
node = decode_nodes (client, n_data, request->set_nodes.data, &pos);
broadway_server_surface_set_nodes (server, request->set_nodes.id,
node);
broadway_server_surface_update_nodes (server, request->set_nodes.id,
request->set_nodes.data, n_data,
client->textures);
}
break;
case BROADWAY_REQUEST_UPLOAD_TEXTURE:
+1 -12
View File
@@ -36,9 +36,6 @@ static void gdk_broadway_device_get_state (GdkDevice *device,
static void gdk_broadway_device_set_surface_cursor (GdkDevice *device,
GdkSurface *surface,
GdkCursor *cursor);
static void gdk_broadway_device_warp (GdkDevice *device,
gdouble x,
gdouble y);
static void gdk_broadway_device_query_state (GdkDevice *device,
GdkSurface *surface,
GdkSurface **child_surface,
@@ -73,7 +70,6 @@ gdk_broadway_device_class_init (GdkBroadwayDeviceClass *klass)
device_class->get_history = gdk_broadway_device_get_history;
device_class->get_state = gdk_broadway_device_get_state;
device_class->set_surface_cursor = gdk_broadway_device_set_surface_cursor;
device_class->warp = gdk_broadway_device_warp;
device_class->query_state = gdk_broadway_device_query_state;
device_class->grab = gdk_broadway_device_grab;
device_class->ungrab = gdk_broadway_device_ungrab;
@@ -110,7 +106,7 @@ gdk_broadway_device_get_state (GdkDevice *device,
{
gdouble x, y;
gdk_surface_get_device_position_double (surface, device, &x, &y, mask);
gdk_surface_get_device_position (surface, device, &x, &y, mask);
if (axes)
{
@@ -126,13 +122,6 @@ gdk_broadway_device_set_surface_cursor (GdkDevice *device,
{
}
static void
gdk_broadway_device_warp (GdkDevice *device,
gdouble x,
gdouble y)
{
}
static void
gdk_broadway_device_query_state (GdkDevice *device,
GdkSurface *surface,
+1 -1
View File
@@ -380,7 +380,7 @@ gdk_broadway_display_ensure_texture (GdkDisplay *display,
data = g_new0 (BroadwayTextureData, 1);
data->id = id;
data->display = g_object_ref (display);
g_object_set_data_full (G_OBJECT (texture), "broadway-data", data, (GDestroyNotify)broadway_texture_data_free);
g_object_set_data_full (G_OBJECT (texture), "broadway-data", data, (GDestroyNotify)broadway_texture_data_free);
}
return data->id;
+2
View File
@@ -64,6 +64,8 @@ gdk_broadway_draw_context_end_frame (GdkDrawContext *draw_context,
g_array_unref (self->nodes);
self->nodes = NULL;
/* We now sent all new texture refs to the daemon via the nodes, so we can drop them here */
g_ptr_array_unref (self->node_textures);
self->node_textures = NULL;
}
+6 -7
View File
@@ -501,12 +501,6 @@ gdk_broadway_surface_set_title (GdkSurface *surface,
{
}
static void
gdk_broadway_surface_set_role (GdkSurface *surface,
const gchar *role)
{
}
static void
gdk_broadway_surface_set_startup_id (GdkSurface *surface,
const gchar *startup_id)
@@ -1232,6 +1226,9 @@ gdk_broadway_surface_begin_resize_drag (GdkSurface *surface,
mv_resize = get_move_resize_data (gdk_surface_get_display (surface), TRUE);
if (mv_resize->moveresize_surface != NULL)
return; /* already a drag operation in progress */
mv_resize->is_resize = TRUE;
mv_resize->moveresize_button = button;
mv_resize->resize_edge = edge;
@@ -1272,6 +1269,9 @@ gdk_broadway_surface_begin_move_drag (GdkSurface *surface,
mv_resize = get_move_resize_data (gdk_surface_get_display (surface), TRUE);
if (mv_resize->moveresize_surface != NULL)
return; /* already a drag operation in progress */
mv_resize->is_resize = FALSE;
mv_resize->moveresize_button = button;
mv_resize->moveresize_x = root_x;
@@ -1352,7 +1352,6 @@ gdk_surface_impl_broadway_class_init (GdkSurfaceImplBroadwayClass *klass)
impl_class->set_urgency_hint = gdk_broadway_surface_set_urgency_hint;
impl_class->set_geometry_hints = gdk_broadway_surface_set_geometry_hints;
impl_class->set_title = gdk_broadway_surface_set_title;
impl_class->set_role = gdk_broadway_surface_set_role;
impl_class->set_startup_id = gdk_broadway_surface_set_startup_id;
impl_class->set_transient_for = gdk_broadway_surface_set_transient_for;
impl_class->get_frame_extents = gdk_broadway_surface_get_frame_extents;
+8 -99
View File
@@ -529,7 +529,7 @@ gdk_device_get_state (GdkDevice *device,
}
/**
* gdk_device_get_position_double:
* gdk_device_get_position:
* @device: pointer device to query status about.
* @x: (out) (allow-none): location to store root window X coordinate of @device, or %NULL.
* @y: (out) (allow-none): location to store root window Y coordinate of @device, or %NULL.
@@ -540,9 +540,9 @@ gdk_device_get_state (GdkDevice *device,
* unless there is an ongoing grab on them. See gdk_device_grab().
**/
void
gdk_device_get_position_double (GdkDevice *device,
gdouble *x,
gdouble *y)
gdk_device_get_position (GdkDevice *device,
double *x,
double *y)
{
GdkDisplay *display;
gdouble tmp_x, tmp_y;
@@ -568,33 +568,7 @@ gdk_device_get_position_double (GdkDevice *device,
}
/**
* gdk_device_get_position:
* @device: pointer device to query status about.
* @x: (out) (allow-none): location to store root window X coordinate of @device, or %NULL.
* @y: (out) (allow-none): location to store root window Y coordinate of @device, or %NULL.
*
* Gets the current location of @device. As a slave device
* coordinates are those of its master pointer, This function
* may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
* unless there is an ongoing grab on them, see gdk_device_grab().
**/
void
gdk_device_get_position (GdkDevice *device,
gint *x,
gint *y)
{
gdouble tmp_x, tmp_y;
gdk_device_get_position_double (device, &tmp_x, &tmp_y);
if (x)
*x = round (tmp_x);
if (y)
*y = round (tmp_y);
}
/**
* gdk_device_get_surface_at_position_double:
* gdk_device_get_surface_at_position:
* @device: pointer #GdkDevice to query info to.
* @win_x: (out) (allow-none): return location for the X coordinate of the device location,
* relative to the surface origin, or %NULL.
@@ -613,9 +587,9 @@ gdk_device_get_position (GdkDevice *device,
* device position, or %NULL.
**/
GdkSurface *
gdk_device_get_surface_at_position_double (GdkDevice *device,
gdouble *win_x,
gdouble *win_y)
gdk_device_get_surface_at_position (GdkDevice *device,
double *win_x,
double *win_y)
{
gdouble tmp_x, tmp_y;
GdkSurface *surface;
@@ -642,43 +616,6 @@ gdk_device_get_surface_at_position_double (GdkDevice *device,
return surface;
}
/**
* gdk_device_get_surface_at_position:
* @device: pointer #GdkDevice to query info to.
* @win_x: (out) (allow-none): return location for the X coordinate of the device location,
* relative to the surface origin, or %NULL.
* @win_y: (out) (allow-none): return location for the Y coordinate of the device location,
* relative to the surface origin, or %NULL.
*
* Obtains the surface underneath @device, returning the location of the device in @win_x and @win_y. Returns
* %NULL if the surface tree under @device is not known to GDK (for example, belongs to another application).
*
* As a slave device coordinates are those of its master pointer, This
* function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
* unless there is an ongoing grab on them, see gdk_device_grab().
*
* Returns: (nullable) (transfer none): the #GdkSurface under the
* device position, or %NULL.
**/
GdkSurface *
gdk_device_get_surface_at_position (GdkDevice *device,
gint *win_x,
gint *win_y)
{
gdouble tmp_x, tmp_y;
GdkSurface *surface;
surface =
gdk_device_get_surface_at_position_double (device, &tmp_x, &tmp_y);
if (win_x)
*win_x = round (tmp_x);
if (win_y)
*win_y = round (tmp_y);
return surface;
}
/**
* gdk_device_get_history: (skip)
* @device: a #GdkDevice
@@ -1425,34 +1362,6 @@ gdk_device_ungrab (GdkDevice *device,
GDK_DEVICE_GET_CLASS (device)->ungrab (device, time_);
}
/**
* gdk_device_warp:
* @device: the device to warp.
* @x: the X coordinate of the destination.
* @y: the Y coordinate of the destination.
*
* Warps @device in @display to the point @x,@y,
* unless the device is confined to a surface by a grab,
* in which case it will be moved
* as far as allowed by the grab. Warping the pointer
* creates events as if the user had moved the mouse
* instantaneously to the destination.
*
* Note that the pointer should normally be under the
* control of the user. This function was added to cover
* some rare use cases like keyboard navigation support
* for the color picker in the #GtkColorSelectionDialog.
**/
void
gdk_device_warp (GdkDevice *device,
gint x,
gint y)
{
g_return_if_fail (GDK_IS_DEVICE (device));
GDK_DEVICE_GET_CLASS (device)->warp (device, x, y);
}
/* Private API */
void
_gdk_device_reset_axes (GdkDevice *device)
+6 -23
View File
@@ -167,25 +167,13 @@ void gdk_device_get_state (GdkDevice *device,
gdouble *axes,
GdkModifierType *mask);
GDK_AVAILABLE_IN_ALL
void gdk_device_get_position (GdkDevice *device,
gint *x,
gint *y);
void gdk_device_get_position (GdkDevice *device,
double *x,
double *y);
GDK_AVAILABLE_IN_ALL
GdkSurface *
gdk_device_get_surface_at_position
(GdkDevice *device,
gint *win_x,
gint *win_y);
GDK_AVAILABLE_IN_ALL
void gdk_device_get_position_double (GdkDevice *device,
gdouble *x,
gdouble *y);
GDK_AVAILABLE_IN_ALL
GdkSurface *
gdk_device_get_surface_at_position_double
(GdkDevice *device,
gdouble *win_x,
gdouble *win_y);
GdkSurface * gdk_device_get_surface_at_position (GdkDevice *device,
double *win_x,
double *win_y);
GDK_AVAILABLE_IN_ALL
gboolean gdk_device_get_history (GdkDevice *device,
GdkSurface *surface,
@@ -236,11 +224,6 @@ GDK_DEPRECATED_FOR(gdk_seat_ungrab)
void gdk_device_ungrab (GdkDevice *device,
guint32 time_);
GDK_AVAILABLE_IN_ALL
void gdk_device_warp (GdkDevice *device,
gint x,
gint y);
GDK_AVAILABLE_IN_ALL
GdkSurface *gdk_device_get_last_event_surface (GdkDevice *device);
-3
View File
@@ -86,9 +86,6 @@ struct _GdkDeviceClass
GdkSurface *surface,
GdkCursor *cursor);
void (* warp) (GdkDevice *device,
gdouble x,
gdouble y);
void (* query_state) (GdkDevice *device,
GdkSurface *surface,
GdkSurface **child_surface,
+1475 -1552
View File
File diff suppressed because it is too large Load Diff
+21 -30
View File
@@ -570,9 +570,6 @@ GDK_AVAILABLE_IN_ALL
void gdk_surface_set_title (GdkSurface *surface,
const gchar *title);
GDK_AVAILABLE_IN_ALL
void gdk_surface_set_role (GdkSurface *surface,
const gchar *role);
GDK_AVAILABLE_IN_ALL
void gdk_surface_set_startup_id (GdkSurface *surface,
const gchar *startup_id);
GDK_AVAILABLE_IN_ALL
@@ -640,18 +637,12 @@ GDK_AVAILABLE_IN_ALL
gint gdk_surface_get_scale_factor (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
GdkSurface * gdk_surface_get_device_position (GdkSurface *surface,
GdkSurface * gdk_surface_get_device_position (GdkSurface *surface,
GdkDevice *device,
gint *x,
gint *y,
double *x,
double *y,
GdkModifierType *mask);
GDK_AVAILABLE_IN_ALL
GdkSurface * gdk_surface_get_device_position_double (GdkSurface *surface,
GdkDevice *device,
gdouble *x,
gdouble *y,
GdkModifierType *mask);
GDK_AVAILABLE_IN_ALL
GdkSurface * gdk_surface_get_parent (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
GdkSurface * gdk_surface_get_toplevel (GdkSurface *surface);
@@ -731,31 +722,31 @@ void gdk_surface_register_dnd (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gdk_surface_begin_resize_drag (GdkSurface *surface,
GdkSurfaceEdge edge,
gint button,
gint root_x,
gint root_y,
guint32 timestamp);
gint button,
gint x,
gint y,
guint32 timestamp);
GDK_AVAILABLE_IN_ALL
void gdk_surface_begin_resize_drag_for_device (GdkSurface *surface,
GdkSurfaceEdge edge,
GdkDevice *device,
gint button,
gint root_x,
gint root_y,
guint32 timestamp);
GdkDevice *device,
gint button,
gint x,
gint y,
guint32 timestamp);
GDK_AVAILABLE_IN_ALL
void gdk_surface_begin_move_drag (GdkSurface *surface,
gint button,
gint root_x,
gint root_y,
guint32 timestamp);
gint button,
gint x,
gint y,
guint32 timestamp);
GDK_AVAILABLE_IN_ALL
void gdk_surface_begin_move_drag_for_device (GdkSurface *surface,
GdkDevice *device,
gint button,
gint root_x,
gint root_y,
guint32 timestamp);
GdkDevice *device,
gint button,
gint x,
gint y,
guint32 timestamp);
/* Interface for dirty-region queueing */
GDK_AVAILABLE_IN_ALL
-2
View File
@@ -136,8 +136,6 @@ struct _GdkSurfaceImplClass
GdkSurfaceHints geom_mask);
void (* set_title) (GdkSurface *surface,
const gchar *title);
void (* set_role) (GdkSurface *surface,
const gchar *role);
void (* set_startup_id) (GdkSurface *surface,
const gchar *startup_id);
void (* set_transient_for) (GdkSurface *surface,
+1 -1
View File
@@ -125,7 +125,7 @@ gdk_quartz_device_core_get_state (GdkDevice *device,
{
gdouble x_pos, y_pos;
gdk_surface_get_device_position_double (window, device, &x_pos, &y_pos, mask);
gdk_surface_get_device_position (window, device, &x_pos, &y_pos, mask);
if (axes)
{
-12
View File
@@ -1739,17 +1739,6 @@ gdk_quartz_surface_set_title (GdkSurface *window,
}
}
static void
gdk_quartz_surface_set_role (GdkSurface *window,
const gchar *role)
{
if (GDK_SURFACE_DESTROYED (window) ||
SURFACE_IS_TOPLEVEL (window))
return;
/* FIXME: Implement */
}
static void
gdk_quartz_surface_set_startup_id (GdkSurface *window,
const gchar *startup_id)
@@ -2754,7 +2743,6 @@ gdk_surface_impl_quartz_class_init (GdkSurfaceImplQuartzClass *klass)
impl_class->set_urgency_hint = gdk_quartz_surface_set_urgency_hint;
impl_class->set_geometry_hints = gdk_quartz_surface_set_geometry_hints;
impl_class->set_title = gdk_quartz_surface_set_title;
impl_class->set_role = gdk_quartz_surface_set_role;
impl_class->set_startup_id = gdk_quartz_surface_set_startup_id;
impl_class->set_transient_for = gdk_quartz_surface_set_transient_for;
impl_class->get_frame_extents = gdk_quartz_surface_get_frame_extents;
+4 -12
View File
@@ -321,7 +321,7 @@ gdk_wayland_device_get_state (GdkDevice *device,
{
gdouble x, y;
gdk_surface_get_device_position_double (surface, device, &x, &y, mask);
gdk_surface_get_device_position (surface, device, &x, &y, mask);
if (axes)
{
@@ -517,13 +517,6 @@ gdk_wayland_device_set_surface_cursor (GdkDevice *device,
gdk_wayland_device_update_surface_cursor (device);
}
static void
gdk_wayland_device_warp (GdkDevice *device,
gdouble x,
gdouble y)
{
}
static void
get_coordinates (GdkDevice *device,
double *x,
@@ -621,9 +614,9 @@ emulate_crossing (GdkSurface *surface,
gdk_event_set_device (event, device);
gdk_event_set_source_device (event, device);
gdk_surface_get_device_position_double (surface, device,
&event->crossing.x, &event->crossing.y,
&event->crossing.state);
gdk_surface_get_device_position (surface, device,
&event->crossing.x, &event->crossing.y,
&event->crossing.state);
event->crossing.x_root = event->crossing.x;
event->crossing.y_root = event->crossing.y;
@@ -871,7 +864,6 @@ gdk_wayland_device_class_init (GdkWaylandDeviceClass *klass)
device_class->get_history = gdk_wayland_device_get_history;
device_class->get_state = gdk_wayland_device_get_state;
device_class->set_surface_cursor = gdk_wayland_device_set_surface_cursor;
device_class->warp = gdk_wayland_device_warp;
device_class->query_state = gdk_wayland_device_query_state;
device_class->grab = gdk_wayland_device_grab;
device_class->ungrab = gdk_wayland_device_ungrab;
+12 -15
View File
@@ -2447,8 +2447,7 @@ gdk_wayland_surface_map (GdkSurface *surface)
GDK_SURFACE_IMPL_WAYLAND (attached_grab_surface->impl);
grab_device = gdk_seat_get_pointer (attached_impl->grab_input_seat);
transient_for =
gdk_device_get_surface_at_position (grab_device,
NULL, NULL);
gdk_device_get_surface_at_position (grab_device, NULL, NULL);
}
}
else
@@ -2465,8 +2464,13 @@ gdk_wayland_surface_map (GdkSurface *surface)
* position of the device that holds the grab.
*/
if (impl->position_method == POSITION_METHOD_NONE && grab_device)
gdk_surface_get_device_position (transient_for, grab_device,
&surface->x, &surface->y, NULL);
{
double px, py;
gdk_surface_get_device_position (transient_for, grab_device,
&px, &py, NULL);
surface->x = round (px);
surface->y = round (py);
}
}
else
{
@@ -3182,12 +3186,6 @@ gdk_wayland_surface_set_title (GdkSurface *surface,
gdk_wayland_surface_sync_title (surface);
}
static void
gdk_wayland_surface_set_role (GdkSurface *surface,
const gchar *role)
{
}
static void
gdk_wayland_surface_set_startup_id (GdkSurface *surface,
const gchar *startup_id)
@@ -3556,8 +3554,8 @@ gdk_wayland_surface_begin_resize_drag (GdkSurface *surface,
GdkSurfaceEdge edge,
GdkDevice *device,
gint button,
gint root_x,
gint root_y,
gint x,
gint y,
guint32 timestamp)
{
GdkSurfaceImplWayland *impl;
@@ -3646,8 +3644,8 @@ static void
gdk_wayland_surface_begin_move_drag (GdkSurface *surface,
GdkDevice *device,
gint button,
gint root_x,
gint root_y,
gint x,
gint y,
guint32 timestamp)
{
GdkSurfaceImplWayland *impl;
@@ -3854,7 +3852,6 @@ _gdk_surface_impl_wayland_class_init (GdkSurfaceImplWaylandClass *klass)
impl_class->set_urgency_hint = gdk_wayland_surface_set_urgency_hint;
impl_class->set_geometry_hints = gdk_wayland_surface_set_geometry_hints;
impl_class->set_title = gdk_wayland_surface_set_title;
impl_class->set_role = gdk_wayland_surface_set_role;
impl_class->set_startup_id = gdk_wayland_surface_set_startup_id;
impl_class->set_transient_for = gdk_wayland_surface_set_transient_for;
impl_class->get_frame_extents = gdk_wayland_surface_get_frame_extents;
-9
View File
@@ -112,14 +112,6 @@ gdk_device_virtual_set_surface_cursor (GdkDevice *device,
g_set_object (&GDK_SURFACE_IMPL_WIN32 (window->impl)->cursor, win32_hcursor);
}
static void
gdk_device_virtual_warp (GdkDevice *device,
gdouble x,
gdouble y)
{
SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
}
static void
gdk_device_virtual_query_state (GdkDevice *device,
GdkSurface *window,
@@ -198,7 +190,6 @@ gdk_device_virtual_class_init (GdkDeviceVirtualClass *klass)
device_class->get_history = gdk_device_virtual_get_history;
device_class->get_state = gdk_device_virtual_get_state;
device_class->set_surface_cursor = gdk_device_virtual_set_surface_cursor;
device_class->warp = gdk_device_virtual_warp;
device_class->query_state = gdk_device_virtual_query_state;
device_class->grab = gdk_device_virtual_grab;
device_class->ungrab = gdk_device_virtual_ungrab;
+5 -12
View File
@@ -21,6 +21,7 @@
#include <windowsx.h>
#include <objbase.h>
#include <math.h>
#include "gdkdevice-win32.h"
#include "gdkwin32.h"
@@ -45,14 +46,14 @@ gdk_device_win32_get_state (GdkDevice *device,
gdouble *axes,
GdkModifierType *mask)
{
gint x_int, y_int;
double x, y;
gdk_surface_get_device_position (window, device, &x_int, &y_int, mask);
gdk_surface_get_device_position (window, device, &x, &y, mask);
if (axes)
{
axes[0] = x_int;
axes[1] = y_int;
axes[0] = round (x);
axes[1] = round (y);
}
}
@@ -63,13 +64,6 @@ gdk_device_win32_set_surface_cursor (GdkDevice *device,
{
}
static void
gdk_device_win32_warp (GdkDevice *device,
gdouble x,
gdouble y)
{
}
static GdkModifierType
get_current_mask (void)
{
@@ -286,7 +280,6 @@ gdk_device_win32_class_init (GdkDeviceWin32Class *klass)
device_class->get_history = gdk_device_win32_get_history;
device_class->get_state = gdk_device_win32_get_state;
device_class->set_surface_cursor = gdk_device_win32_set_surface_cursor;
device_class->warp = gdk_device_win32_warp;
device_class->query_state = gdk_device_win32_query_state;
device_class->grab = gdk_device_win32_grab;
device_class->ungrab = gdk_device_win32_ungrab;
-8
View File
@@ -99,13 +99,6 @@ gdk_device_wintab_set_surface_cursor (GdkDevice *device,
{
}
static void
gdk_device_wintab_warp (GdkDevice *device,
gdouble x,
gdouble y)
{
}
static void
gdk_device_wintab_query_state (GdkDevice *device,
GdkSurface *window,
@@ -291,7 +284,6 @@ gdk_device_wintab_class_init (GdkDeviceWintabClass *klass)
device_class->get_history = gdk_device_wintab_get_history;
device_class->get_state = gdk_device_wintab_get_state;
device_class->set_surface_cursor = gdk_device_wintab_set_surface_cursor;
device_class->warp = gdk_device_wintab_warp;
device_class->query_state = gdk_device_wintab_query_state;
device_class->grab = gdk_device_wintab_grab;
device_class->ungrab = gdk_device_wintab_ungrab;
+2 -5
View File
@@ -883,15 +883,12 @@ gdk_input_other_event (GdkDisplay *display,
GdkDeviceManagerWin32 *device_manager;
GdkDeviceWintab *source_device = NULL;
GdkDeviceGrabInfo *last_grab;
GdkEventMask masktest;
guint key_state;
POINT pt;
GdkSurfaceImplWin32 *impl;
PACKET packet;
gint root_x, root_y;
gint num_axes;
gint x, y;
double x, y;
guint translated_buttons, button_diff, button_mask;
/* Translation from tablet button state to GDK button state for
* buttons 1-3 - swap button 2 and 3.
@@ -911,7 +908,7 @@ gdk_input_other_event (GdkDisplay *display,
g_object_ref (window);
GDK_NOTE (EVENTS_OR_INPUT,
g_print ("gdk_input_other_event: window=%p %+d%+d\n",
g_print ("gdk_input_other_event: window=%p %+g%+g\n",
window ? GDK_SURFACE_HWND (window) : NULL, x, y));
if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
+4
View File
@@ -38,6 +38,8 @@
#include <dwmapi.h>
#include "gdkwin32langnotification.h"
static int debug_indent = 0;
/**
@@ -536,6 +538,7 @@ _gdk_win32_display_open (const gchar *display_name)
NULL);
_gdk_device_manager->display = _gdk_display;
_gdk_win32_lang_notification_init ();
_gdk_drag_init ();
_gdk_drop_init ();
@@ -701,6 +704,7 @@ gdk_win32_display_finalize (GObject *object)
_gdk_win32_display_finalize_cursors (display_win32);
_gdk_win32_dnd_exit ();
_gdk_win32_lang_notification_exit ();
g_ptr_array_free (display_win32->monitors, TRUE);
+5 -5
View File
@@ -29,6 +29,7 @@
#include <io.h>
#include <fcntl.h>
#include <math.h>
/*
* Support for OLE-2 drag and drop added at Archaeopteryx Software, 2001
@@ -1717,6 +1718,7 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
GdkDrag *drag;
GdkWin32Drag *drag_win32;
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
double px, py;
int x_root, y_root;
g_return_val_if_fail (surface != NULL, NULL);
@@ -1731,9 +1733,9 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
GDK_NOTE (DND, g_print ("_gdk_win32_surface_drag_begin\n"));
gdk_device_get_position (device, &x_root, &y_root);
x_root += dx;
y_root += dy;
gdk_device_get_position (device, &px, &px);
x_root = round (px) + dx;
y_root = round (py) + dy;
drag_win32->start_x = x_root;
drag_win32->start_y = y_root;
@@ -1840,7 +1842,6 @@ gdk_win32_drag_find_window (GdkDrag *drag,
{
GdkWin32Drag *drag_win32 = GDK_WIN32_DRAG (drag);
find_window_enum_arg a;
HWND result;
g_assert (_win32_main_thread == NULL ||
_win32_main_thread == g_thread_self ());
@@ -2439,7 +2440,6 @@ gdk_dnd_handle_key_event (GdkDrag *drag,
{
drag_win32->util_data.last_x += dx;
drag_win32->util_data.last_y += dy;
gdk_device_warp (pointer, drag_win32->util_data.last_x, drag_win32->util_data.last_y);
}
if (drag_win32->drag_surface)
-7
View File
@@ -1090,7 +1090,6 @@ static void
gdk_win32_drop_finish (GdkDrop *drop,
GdkDragAction action)
{
GdkDrag *drag;
GdkWin32Drop *drop_win32 = GDK_WIN32_DROP (drop);
g_return_if_fail (drop != NULL);
@@ -1103,12 +1102,6 @@ gdk_win32_drop_finish (GdkDrop *drop,
if (drop_win32->protocol == GDK_DRAG_PROTO_OLE2)
return;
/* FIXME: remove?
drag = gdk_drop_get_drag (drop);
if (drag != NULL)
_gdk_win32_local_drag_drop_response (drag, action);
*/
}
#if 0
+14 -2
View File
@@ -1331,7 +1331,6 @@ _gdk_win32_do_emit_configure_event (GdkSurface *window,
RECT rect)
{
GdkSurfaceImplWin32 *impl = GDK_SURFACE_IMPL_WIN32 (window->impl);
GdkEvent *event;
impl->unscaled_width = rect.right - rect.left;
impl->unscaled_height = rect.bottom - rect.top;
@@ -2113,7 +2112,6 @@ gdk_event_translate (MSG *msg,
case WM_INPUTLANGCHANGE:
_gdk_input_locale = (HKL) msg->lParam;
_gdk_win32_keymap_set_active_layout (GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display)), _gdk_input_locale);
_gdk_input_locale_is_ime = ImmIsIME (_gdk_input_locale);
GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE,
buf, sizeof (buf));
@@ -2125,6 +2123,20 @@ gdk_event_translate (MSG *msg,
(gpointer) msg->lParam, _gdk_input_locale_is_ime ? " (IME)" : "",
_gdk_input_codepage));
gdk_display_setting_changed (display, "gtk-im-module");
/* Generate a dummy key event to "nudge" IMContext */
event = gdk_event_new (GDK_KEY_PRESS);
event->any.surface = window;
event->key.time = _gdk_win32_get_next_tick (msg->time);
event->key.keyval = GDK_KEY_VoidSymbol;
event->key.hardware_keycode = 0;
event->key.group = 0;
gdk_event_set_scancode (event, 0);
gdk_event_set_device (event, device_manager_win32->core_keyboard);
gdk_event_set_source_device (event, device_manager_win32->system_keyboard);
event->key.is_modifier = FALSE;
event->key.state = 0;
_gdk_win32_append_event (event);
break;
case WM_SYSKEYUP:
+1 -1
View File
@@ -39,7 +39,7 @@ HINSTANCE _gdk_app_hmodule;
gint _gdk_input_ignore_core;
HKL _gdk_input_locale;
gboolean _gdk_input_locale_is_ime;
gboolean _gdk_input_locale_is_ime = FALSE;
UINT _gdk_input_codepage;
gint _gdk_input_ignore_wintab = FALSE;
-1
View File
@@ -83,7 +83,6 @@ _gdk_win32_surfaceing_init (void)
_gdk_display_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
_gdk_input_locale = GetKeyboardLayout (0);
_gdk_win32_keymap_set_active_layout (GDK_WIN32_KEYMAP (_gdk_win32_display_get_keymap (_gdk_display)), _gdk_input_locale);
_gdk_input_locale_is_ime = ImmIsIME (_gdk_input_locale);
GetLocaleInfo (MAKELCID (LOWORD (_gdk_input_locale), SORT_DEFAULT),
LOCALE_IDEFAULTANSICODEPAGE,
buf, sizeof (buf));
+2 -2
View File
@@ -215,9 +215,9 @@ _gdk_win32_get_setting (const gchar *name,
else if (strcmp ("gtk-im-module", name) == 0)
{
if (_gdk_input_locale_is_ime)
g_value_set_string (value, "ime");
g_value_set_static_string (value, "ime");
else
g_value_set_string (value, "");
g_value_set_static_string (value, "");
return TRUE;
}
+1 -27
View File
@@ -1626,18 +1626,6 @@ gdk_win32_surface_set_title (GdkSurface *window,
GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
}
static void
gdk_win32_surface_set_role (GdkSurface *window,
const gchar *role)
{
g_return_if_fail (GDK_IS_SURFACE (window));
GDK_NOTE (MISC, g_print ("gdk_surface_set_role: %p: %s\n",
GDK_SURFACE_HWND (window),
(role ? role : "NULL")));
/* XXX */
}
static void
gdk_win32_surface_set_transient_for (GdkSurface *window,
GdkSurface *parent)
@@ -1953,19 +1941,6 @@ gdk_surface_win32_get_device_state (GdkSurface *window,
return (child != NULL);
}
void
gdk_display_warp_device (GdkDisplay *display,
GdkDevice *device,
gint x,
gint y)
{
g_return_if_fail (display == gdk_display_get_default ());
g_return_if_fail (GDK_IS_DEVICE (device));
g_return_if_fail (display == gdk_device_get_display (device));
GDK_DEVICE_GET_CLASS (device)->warp (device, x, y);
}
static void
gdk_win32_surface_set_accept_focus (GdkSurface *window,
gboolean accept_focus)
@@ -4125,7 +4100,7 @@ setup_drag_move_resize_context (GdkSurface *window,
* the titlebar is, if any.
*/
root_y = wy + wheight / 2;
gdk_device_warp (device, root_x, root_y);
SetCursorPos (root_x - _gdk_offset_x, root_y - _gdk_offset_y);
}
}
@@ -5341,7 +5316,6 @@ gdk_surface_impl_win32_class_init (GdkSurfaceImplWin32Class *klass)
impl_class->set_urgency_hint = gdk_win32_surface_set_urgency_hint;
impl_class->set_geometry_hints = gdk_win32_surface_set_geometry_hints;
impl_class->set_title = gdk_win32_surface_set_title;
impl_class->set_role = gdk_win32_surface_set_role;
//impl_class->set_startup_id = gdk_x11_surface_set_startup_id;
impl_class->set_transient_for = gdk_win32_surface_set_transient_for;
impl_class->get_frame_extents = gdk_win32_surface_get_frame_extents;
+172
View File
@@ -0,0 +1,172 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2019 Руслан Ижбулатов <lrn1986@gmail.com>
*
* 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"
#define COBJMACROS
#include <msctf.h>
#include <gdk/gdk.h>
#include "gdkprivate-win32.h"
struct _GdkWin32ALPNSink
{
ITfActiveLanguageProfileNotifySink itf_alpn_sink;
gint ref_count;
};
typedef struct _GdkWin32ALPNSink GdkWin32ALPNSink;
static GdkWin32ALPNSink *actlangchangenotify = NULL;
static ITfSource *itf_source = NULL;
static DWORD actlangchangenotify_id = 0;
static ULONG STDMETHODCALLTYPE
alpn_sink_addref (ITfActiveLanguageProfileNotifySink *This)
{
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
int ref_count = ++alpn_sink->ref_count;
return ref_count;
}
static HRESULT STDMETHODCALLTYPE
alpn_sink_queryinterface (ITfActiveLanguageProfileNotifySink *This,
REFIID riid,
LPVOID *ppvObject)
{
*ppvObject = NULL;
if (IsEqualGUID (riid, &IID_IUnknown))
{
ITfActiveLanguageProfileNotifySink_AddRef (This);
*ppvObject = This;
return S_OK;
}
if (IsEqualGUID (riid, &IID_ITfActiveLanguageProfileNotifySink))
{
ITfActiveLanguageProfileNotifySink_AddRef (This);
*ppvObject = This;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE
alpn_sink_release (ITfActiveLanguageProfileNotifySink *This)
{
GdkWin32ALPNSink *alpn_sink = (GdkWin32ALPNSink *) This;
int ref_count = --alpn_sink->ref_count;
if (ref_count == 0)
{
g_free (This);
}
return ref_count;
}
static HRESULT STDMETHODCALLTYPE
alpn_sink_on_activated (ITfActiveLanguageProfileNotifySink *This,
REFCLSID clsid,
REFGUID guidProfile,
BOOL fActivated)
{
_gdk_input_locale_is_ime = fActivated;
return S_OK;
}
static ITfActiveLanguageProfileNotifySinkVtbl alpn_sink_vtbl = {
alpn_sink_queryinterface,
alpn_sink_addref,
alpn_sink_release,
alpn_sink_on_activated,
};
static GdkWin32ALPNSink *
alpn_sink_new ()
{
GdkWin32ALPNSink *result;
result = g_new0 (GdkWin32ALPNSink, 1);
result->itf_alpn_sink.lpVtbl = &alpn_sink_vtbl;
result->ref_count = 0;
ITfActiveLanguageProfileNotifySink_AddRef (&result->itf_alpn_sink);
return result;
}
void
_gdk_win32_lang_notification_init ()
{
HRESULT hr;
ITfThreadMgr *itf_threadmgr;
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
if (actlangchangenotify != NULL)
return;
hr = CoCreateInstance (&CLSID_TF_ThreadMgr,
NULL,
CLSCTX_INPROC_SERVER,
&IID_ITfThreadMgr,
(LPVOID *) &itf_threadmgr);
if (!SUCCEEDED (hr))
return;
hr = ITfThreadMgr_QueryInterface (itf_threadmgr, &IID_ITfSource, (VOID **) &itf_source);
ITfThreadMgr_Release (itf_threadmgr);
if (!SUCCEEDED (hr))
return;
actlangchangenotify = alpn_sink_new ();
hr = ITfSource_AdviseSink (itf_source,
&IID_ITfActiveLanguageProfileNotifySink,
(IUnknown *) actlangchangenotify,
&actlangchangenotify_id);
if (!SUCCEEDED (hr))
{
ITfActiveLanguageProfileNotifySink_Release (&actlangchangenotify->itf_alpn_sink);
actlangchangenotify = NULL;
ITfSource_Release (itf_source);
itf_source = NULL;
}
}
void
_gdk_win32_lang_notification_exit ()
{
if (actlangchangenotify != NULL && itf_source != NULL)
{
ITfSource_UnadviseSink (itf_source, actlangchangenotify_id);
ITfSource_Release (itf_source);
ITfActiveLanguageProfileNotifySink_Release (&actlangchangenotify->itf_alpn_sink);
}
CoUninitialize ();
}
+26
View File
@@ -0,0 +1,26 @@
/*
* gdkwin32langnotification.h
*
* Copyright 2019 Руслан Ижбулатов <lrn1986@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_WIN32_LANGNOTIFICATION_H__
#define __GDK_WIN32_LANGNOTIFICATION_H__
void _gdk_win32_lang_notification_init (void);
void _gdk_win32_lang_notification_exit (void);
#endif
+1
View File
@@ -17,6 +17,7 @@ gdk_win32_sources = files([
'gdkglobals-win32.c',
'gdkhdataoutputstream-win32.c',
'gdkkeys-win32.c',
'gdkwin32langnotification.c',
'gdkmain-win32.c',
'gdkmonitor-win32.c',
'gdkproperty-win32.c',
+1 -25
View File
@@ -52,9 +52,6 @@ static void gdk_x11_device_core_get_state (GdkDevice *device,
static void gdk_x11_device_core_set_surface_cursor (GdkDevice *device,
GdkSurface *surface,
GdkCursor *cursor);
static void gdk_x11_device_core_warp (GdkDevice *device,
gdouble x,
gdouble y);
static void gdk_x11_device_core_query_state (GdkDevice *device,
GdkSurface *surface,
GdkSurface **child_surface,
@@ -88,7 +85,6 @@ gdk_x11_device_core_class_init (GdkX11DeviceCoreClass *klass)
device_class->get_history = gdk_x11_device_core_get_history;
device_class->get_state = gdk_x11_device_core_get_state;
device_class->set_surface_cursor = gdk_x11_device_core_set_surface_cursor;
device_class->warp = gdk_x11_device_core_warp;
device_class->query_state = gdk_x11_device_core_query_state;
device_class->grab = gdk_x11_device_core_grab;
device_class->ungrab = gdk_x11_device_core_ungrab;
@@ -196,7 +192,7 @@ gdk_x11_device_core_get_state (GdkDevice *device,
{
gdouble x, y;
gdk_surface_get_device_position_double (surface, device, &x, &y, mask);
gdk_surface_get_device_position (surface, device, &x, &y, mask);
if (axes)
{
@@ -223,26 +219,6 @@ gdk_x11_device_core_set_surface_cursor (GdkDevice *device,
xcursor);
}
static void
gdk_x11_device_core_warp (GdkDevice *device,
gdouble x,
gdouble y)
{
GdkDisplay *display;
Display *xdisplay;
Window dest;
GdkX11Screen *screen;
display = gdk_device_get_display (device);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
screen = GDK_X11_DISPLAY (display)->screen;
dest = GDK_SCREEN_XROOTWIN (screen);
XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0,
round (x * screen->surface_scale),
round (y * screen->surface_scale));
}
static void
gdk_x11_device_core_query_state (GdkDevice *device,
GdkSurface *surface,
-22
View File
@@ -77,9 +77,6 @@ static void gdk_x11_device_xi2_get_state (GdkDevice *device,
static void gdk_x11_device_xi2_set_surface_cursor (GdkDevice *device,
GdkSurface *surface,
GdkCursor *cursor);
static void gdk_x11_device_xi2_warp (GdkDevice *device,
gdouble x,
gdouble y);
static void gdk_x11_device_xi2_query_state (GdkDevice *device,
GdkSurface *surface,
GdkSurface **child_surface,
@@ -123,7 +120,6 @@ gdk_x11_device_xi2_class_init (GdkX11DeviceXI2Class *klass)
device_class->get_state = gdk_x11_device_xi2_get_state;
device_class->set_surface_cursor = gdk_x11_device_xi2_set_surface_cursor;
device_class->warp = gdk_x11_device_xi2_warp;
device_class->query_state = gdk_x11_device_xi2_query_state;
device_class->grab = gdk_x11_device_xi2_grab;
device_class->ungrab = gdk_x11_device_xi2_ungrab;
@@ -292,24 +288,6 @@ gdk_x11_device_xi2_set_surface_cursor (GdkDevice *device,
GDK_SURFACE_XID (surface));
}
static void
gdk_x11_device_xi2_warp (GdkDevice *device,
gdouble x,
gdouble y)
{
GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
GdkDisplay *display = gdk_device_get_display (device);
GdkX11Screen *screen = GDK_X11_DISPLAY (display)->screen;
Window dest = GDK_DISPLAY_XROOTWIN (display);
XIWarpPointer (GDK_SCREEN_XDISPLAY (screen),
device_xi2->device_id,
None, dest,
0, 0, 0, 0,
round (x * screen->surface_scale),
round (y * screen->surface_scale));
}
static void
gdk_x11_device_xi2_query_state (GdkDevice *device,
GdkSurface *surface,
+19 -4
View File
@@ -41,6 +41,7 @@
#include "gdkselectioninputstream-x11.h"
#include "gdkselectionoutputstream-x11.h"
#include <math.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
@@ -2076,6 +2077,7 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
GdkX11Drag *x11_drag;
GdkDrag *drag;
GdkDisplay *display;
double px, py;
int x_root, y_root;
Atom xselection;
GdkSurface *ipc_surface;
@@ -2096,9 +2098,9 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
precache_target_list (drag);
gdk_device_get_position (device, &x_root, &y_root);
x_root += dx;
y_root += dy;
gdk_device_get_position (device, &px, &py);
x_root = round (px) + dx;
y_root = round (py) + dy;
x11_drag->start_x = x_root;
x11_drag->start_y = y_root;
@@ -2342,9 +2344,22 @@ gdk_dnd_handle_key_event (GdkDrag *drag,
if (dx != 0 || dy != 0)
{
GdkDisplay *display;
Display *xdisplay;
GdkX11Screen *screen;
Window dest;
x11_drag->last_x += dx;
x11_drag->last_y += dy;
gdk_device_warp (pointer, x11_drag->last_x, x11_drag->last_y);
display = gdk_event_get_display ((GdkEvent *)event);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
screen = GDK_X11_DISPLAY (display)->screen;
dest = GDK_SCREEN_XROOTWIN (screen);
XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0,
round (x11_drag->last_x * screen->surface_scale),
round (x11_drag->last_y * screen->surface_scale));
}
gdk_drag_update (drag, x11_drag->last_x, x11_drag->last_y, state,
+24 -39
View File
@@ -2231,27 +2231,6 @@ gdk_x11_surface_set_title (GdkSurface *surface,
}
}
static void
gdk_x11_surface_set_role (GdkSurface *surface,
const gchar *role)
{
GdkDisplay *display;
display = gdk_surface_get_display (surface);
if (GDK_SURFACE_DESTROYED (surface) ||
!SURFACE_IS_TOPLEVEL (surface))
return;
if (role)
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_SURFACE_XID (surface),
gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
XA_STRING, 8, PropModeReplace, (guchar *)role, strlen (role));
else
XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_SURFACE_XID (surface),
gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
}
static void
gdk_x11_surface_set_startup_id (GdkSurface *surface,
const gchar *startup_id)
@@ -4293,12 +4272,12 @@ emulate_resize_drag (GdkSurface *surface,
}
static void
emulate_move_drag (GdkSurface *surface,
GdkDevice *device,
gint button,
gint root_x,
gint root_y,
guint32 timestamp)
emulate_move_drag (GdkSurface *surface,
GdkDevice *device,
gint button,
gint root_x,
gint root_y,
guint32 timestamp)
{
MoveResizeData *mv_resize = get_move_resize_data (GDK_SURFACE_DISPLAY (surface), TRUE);
@@ -4338,17 +4317,21 @@ _should_perform_ewmh_drag (GdkSurface *surface,
static void
gdk_x11_surface_begin_resize_drag (GdkSurface *surface,
GdkSurfaceEdge edge,
GdkDevice *device,
gint button,
gint root_x,
gint root_y,
guint32 timestamp)
GdkSurfaceEdge edge,
GdkDevice *device,
gint button,
gint x,
gint y,
guint32 timestamp)
{
int root_x, root_y;
if (GDK_SURFACE_DESTROYED (surface) ||
!SURFACE_IS_TOPLEVEL (surface))
return;
gdk_surface_x11_get_root_coords (surface, x, y, &root_x, &root_y);
/* Avoid EWMH for touch devices */
if (_should_perform_ewmh_drag (surface, device))
wmspec_resize_drag (surface, edge, device, button, root_x, root_y, timestamp);
@@ -4358,12 +4341,13 @@ gdk_x11_surface_begin_resize_drag (GdkSurface *surface,
static void
gdk_x11_surface_begin_move_drag (GdkSurface *surface,
GdkDevice *device,
gint button,
gint root_x,
gint root_y,
guint32 timestamp)
GdkDevice *device,
gint button,
gint x,
gint y,
guint32 timestamp)
{
int root_x, root_y;
gint direction;
if (GDK_SURFACE_DESTROYED (surface) || !SURFACE_IS_TOPLEVEL (surface))
@@ -4374,6 +4358,8 @@ gdk_x11_surface_begin_move_drag (GdkSurface *surface,
else
direction = _NET_WM_MOVERESIZE_MOVE;
gdk_surface_x11_get_root_coords (surface, x, y, &root_x, &root_y);
/* Avoid EWMH for touch devices */
if (_should_perform_ewmh_drag (surface, device))
wmspec_moveresize (surface, direction, device, button, root_x, root_y, timestamp);
@@ -4677,7 +4663,6 @@ gdk_surface_impl_x11_class_init (GdkSurfaceImplX11Class *klass)
impl_class->set_urgency_hint = gdk_x11_surface_set_urgency_hint;
impl_class->set_geometry_hints = gdk_x11_surface_set_geometry_hints;
impl_class->set_title = gdk_x11_surface_set_title;
impl_class->set_role = gdk_x11_surface_set_role;
impl_class->set_startup_id = gdk_x11_surface_set_startup_id;
impl_class->set_transient_for = gdk_x11_surface_set_transient_for;
impl_class->get_frame_extents = gdk_x11_surface_get_frame_extents;
+394 -446
View File
File diff suppressed because it is too large Load Diff
-444
View File
@@ -1,444 +0,0 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gskcssparserprivate.h"
#define GTK_COMPILATION
#include "gtk/gtkcssprovider.h"
struct _GskCssParser
{
volatile int ref_count;
GskCssParserErrorFunc error_func;
gpointer user_data;
GDestroyNotify user_destroy;
GSList *sources;
GSList *blocks;
GskCssLocation location;
GskCssToken token;
};
GskCssParser *
gsk_css_parser_new (GskCssParserErrorFunc error_func,
gpointer user_data,
GDestroyNotify user_destroy)
{
GskCssParser *self;
self = g_slice_new0 (GskCssParser);
self->ref_count = 1;
self->error_func = error_func;
self->user_data = user_data;
self->user_destroy = user_destroy;
return self;
}
static void
gsk_css_parser_finalize (GskCssParser *self)
{
g_slist_free_full (self->sources, (GDestroyNotify) gsk_css_tokenizer_unref);
if (self->user_destroy)
self->user_destroy (self->user_data);
g_slice_free (GskCssParser, self);
}
GskCssParser *
gsk_css_parser_ref (GskCssParser *self)
{
g_atomic_int_inc (&self->ref_count);
return self;
}
void
gsk_css_parser_unref (GskCssParser *self)
{
if (g_atomic_int_dec_and_test (&self->ref_count))
gsk_css_parser_finalize (self);
}
void
gsk_css_parser_add_tokenizer (GskCssParser *self,
GskCssTokenizer *tokenizer)
{
self->sources = g_slist_prepend (self->sources, gsk_css_tokenizer_ref (tokenizer));
}
void
gsk_css_parser_add_bytes (GskCssParser *self,
GBytes *bytes)
{
GskCssTokenizer *tokenizer;
tokenizer = gsk_css_tokenizer_new (bytes);
gsk_css_parser_add_tokenizer (self, tokenizer);
gsk_css_tokenizer_unref (tokenizer);
}
static void
gsk_css_parser_ensure_token (GskCssParser *self)
{
GskCssTokenizer *tokenizer;
GError *error = NULL;
if (!gsk_css_token_is (&self->token, GSK_CSS_TOKEN_EOF))
return;
if (self->sources == NULL)
return;
tokenizer = self->sources->data;
self->location = *gsk_css_tokenizer_get_location (tokenizer);
if (!gsk_css_tokenizer_read_token (tokenizer, &self->token, &error))
{
g_clear_error (&error);
}
}
const GskCssToken *
gsk_css_parser_peek_token (GskCssParser *self)
{
static const GskCssToken eof_token = { GSK_CSS_TOKEN_EOF, };
gsk_css_parser_ensure_token (self);
if (self->blocks && gsk_css_token_is (&self->token, GPOINTER_TO_UINT (self->blocks->data)))
return &eof_token;
return &self->token;
}
const GskCssToken *
gsk_css_parser_get_token (GskCssParser *self)
{
const GskCssToken *token;
for (token = gsk_css_parser_peek_token (self);
gsk_css_token_is (token, GSK_CSS_TOKEN_COMMENT) ||
gsk_css_token_is (token, GSK_CSS_TOKEN_WHITESPACE);
token = gsk_css_parser_peek_token (self))
{
gsk_css_parser_consume_token (self);
}
return token;
}
void
gsk_css_parser_consume_token (GskCssParser *self)
{
gsk_css_parser_ensure_token (self);
/* unpreserved tokens MUST be consumed via start_block() */
g_assert (gsk_css_token_is_preserved (&self->token, NULL));
gsk_css_token_clear (&self->token);
}
void
gsk_css_parser_start_block (GskCssParser *self)
{
GskCssTokenType end_token_type;
gsk_css_parser_ensure_token (self);
if (gsk_css_token_is_preserved (&self->token, &end_token_type))
{
g_critical ("gsk_css_parser_start_block() may only be called for non-preserved tokens");
return;
}
self->blocks = g_slist_prepend (self->blocks, GUINT_TO_POINTER (end_token_type));
gsk_css_token_clear (&self->token);
}
void
gsk_css_parser_end_block (GskCssParser *self)
{
g_return_if_fail (self->blocks != NULL);
gsk_css_parser_skip_until (self, GSK_CSS_TOKEN_EOF);
if (gsk_css_token_is (&self->token, GSK_CSS_TOKEN_EOF))
gsk_css_parser_warn_syntax (self, "Unterminated block at end of document");
self->blocks = g_slist_remove (self->blocks, self->blocks->data);
gsk_css_token_clear (&self->token);
}
/*
* gsk_css_parser_skip:
* @self: a #GskCssParser
*
* Skips a component value.
*
* This means that if the token is a preserved token, only
* this token will be skipped. If the token starts a block,
* the whole block will be skipped.
**/
void
gsk_css_parser_skip (GskCssParser *self)
{
const GskCssToken *token;
token = gsk_css_parser_get_token (self);
if (gsk_css_token_is_preserved (token, NULL))
{
gsk_css_parser_consume_token (self);
}
else
{
gsk_css_parser_start_block (self);
gsk_css_parser_end_block (self);
}
}
/*
* gsk_css_parser_skip_until:
* @self: a #GskCssParser
* @token_type: type of token to skip to
*
* Repeatedly skips a token until a certain type is reached.
* After this called, gsk_css_parser_get_token() will either
* return a token of this type or the eof token.
*
* This function is useful for resyncing a parser after encountering
* an error.
*
* If you want to skip until the end, use %GSK_TOKEN_TYPE_EOF
* as the token type.
**/
void
gsk_css_parser_skip_until (GskCssParser *self,
GskCssTokenType token_type)
{
const GskCssToken *token;
for (token = gsk_css_parser_get_token (self);
!gsk_css_token_is (token, token_type) &&
!gsk_css_token_is (token, GSK_CSS_TOKEN_EOF);
token = gsk_css_parser_get_token (self))
{
gsk_css_parser_skip (self);
}
}
void
gsk_css_parser_emit_error (GskCssParser *self,
const GError *error)
{
self->error_func (self,
&self->location,
&self->token,
error,
self->user_data);
}
void
gsk_css_parser_error_syntax (GskCssParser *self,
const char *format,
...)
{
va_list args;
GError *error;
va_start (args, format);
error = g_error_new_valist (GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_SYNTAX,
format, args);
gsk_css_parser_emit_error (self, error);
g_error_free (error);
va_end (args);
}
void
gsk_css_parser_error_value (GskCssParser *self,
const char *format,
...)
{
va_list args;
GError *error;
va_start (args, format);
error = g_error_new_valist (GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE,
format, args);
gsk_css_parser_emit_error (self, error);
g_error_free (error);
va_end (args);
}
void
gsk_css_parser_warn_syntax (GskCssParser *self,
const char *format,
...)
{
va_list args;
GError *error;
va_start (args, format);
error = g_error_new_valist (GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_WARN_GENERAL,
format, args);
gsk_css_parser_emit_error (self, error);
g_error_free (error);
va_end (args);
}
gboolean
gsk_css_parser_consume_function (GskCssParser *self,
guint min_args,
guint max_args,
guint (* parse_func) (GskCssParser *, guint, gpointer),
gpointer data)
{
const GskCssToken *token;
gboolean result = FALSE;
char *function_name;
guint arg;
token = gsk_css_parser_get_token (self);
g_return_val_if_fail (gsk_css_token_is (token, GSK_CSS_TOKEN_FUNCTION), FALSE);
function_name = g_strdup (token->string.string);
gsk_css_parser_start_block (self);
arg = 0;
while (TRUE)
{
guint parse_args = parse_func (self, arg, data);
if (parse_args == 0)
break;
arg += parse_args;
token = gsk_css_parser_get_token (self);
if (gsk_css_token_is (token, GSK_CSS_TOKEN_EOF))
{
if (arg < min_args)
{
gsk_css_parser_error_syntax (self, "%s() requires at least %u arguments", function_name, min_args);
break;
}
else
{
result = TRUE;
break;
}
}
else if (gsk_css_token_is (token, GSK_CSS_TOKEN_COMMA))
{
if (arg >= max_args)
{
gsk_css_parser_error_syntax (self, "Expected ')' at end of %s()", function_name);
break;
}
gsk_css_parser_consume_token (self);
continue;
}
else
{
gsk_css_parser_error_syntax (self, "Unexpected data at end of %s() argument", function_name);
break;
}
}
gsk_css_parser_end_block (self);
g_free (function_name);
return result;
}
/**
* gsk_css_parser_consume_if:
* @self: a #GskCssParser
* @token_type: type of token to check for
*
* Consumes the next token if it matches the given @token_type.
*
* This function can be used in loops like this:
* do {
* ... parse one element ...
* } while (gsk_css_parser_consume_if (parser, GSK_CSS_TOKEN_COMMA);
*
* Returns: %TRUE if a token was consumed
**/
gboolean
gsk_css_parser_consume_if (GskCssParser *self,
GskCssTokenType token_type)
{
const GskCssToken *token;
token = gsk_css_parser_get_token (self);
if (!gsk_css_token_is (token, token_type))
return FALSE;
gsk_css_parser_consume_token (self);
return TRUE;
}
gboolean
gsk_css_parser_consume_number (GskCssParser *self,
double *number)
{
const GskCssToken *token;
token = gsk_css_parser_get_token (self);
if (gsk_css_token_is (token, GSK_CSS_TOKEN_SIGNED_NUMBER) ||
gsk_css_token_is (token, GSK_CSS_TOKEN_SIGNLESS_NUMBER) ||
gsk_css_token_is (token, GSK_CSS_TOKEN_SIGNED_INTEGER) ||
gsk_css_token_is (token, GSK_CSS_TOKEN_SIGNLESS_INTEGER))
{
*number = token->number.number;
gsk_css_parser_consume_token (self);
return TRUE;
}
/* FIXME: Implement calc() */
return FALSE;
}
gboolean
gsk_css_parser_consume_percentage (GskCssParser *self,
double *number)
{
const GskCssToken *token;
token = gsk_css_parser_get_token (self);
if (gsk_css_token_is (token, GSK_CSS_TOKEN_PERCENTAGE))
{
*number = token->number.number;
gsk_css_parser_consume_token (self);
return TRUE;
}
/* FIXME: Implement calc() */
return FALSE;
}
-83
View File
@@ -1,83 +0,0 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GSK_CSS_PARSER_H__
#define __GSK_CSS_PARSER_H__
#include "gskcsstokenizerprivate.h"
G_BEGIN_DECLS
typedef struct _GskCssParser GskCssParser;
typedef void (* GskCssParserErrorFunc) (GskCssParser *parser,
const GskCssLocation *location,
const GskCssToken *token,
const GError *error,
gpointer user_data);
GskCssParser * gsk_css_parser_new (GskCssParserErrorFunc error_func,
gpointer user_data,
GDestroyNotify user_destroy);
GskCssParser * gsk_css_parser_ref (GskCssParser *self);
void gsk_css_parser_unref (GskCssParser *self);
void gsk_css_parser_add_tokenizer (GskCssParser *self,
GskCssTokenizer *tokenizer);
void gsk_css_parser_add_bytes (GskCssParser *self,
GBytes *bytes);
const GskCssToken * gsk_css_parser_peek_token (GskCssParser *self);
const GskCssToken * gsk_css_parser_get_token (GskCssParser *self);
void gsk_css_parser_consume_token (GskCssParser *self);
void gsk_css_parser_start_block (GskCssParser *self);
void gsk_css_parser_end_block (GskCssParser *self);
void gsk_css_parser_skip (GskCssParser *self);
void gsk_css_parser_skip_until (GskCssParser *self,
GskCssTokenType token_type);
void gsk_css_parser_emit_error (GskCssParser *self,
const GError *error);
void gsk_css_parser_error_syntax (GskCssParser *self,
const char *format,
...) G_GNUC_PRINTF(2, 3);
void gsk_css_parser_error_value (GskCssParser *self,
const char *format,
...) G_GNUC_PRINTF(2, 3);
void gsk_css_parser_warn_syntax (GskCssParser *self,
const char *format,
...) G_GNUC_PRINTF(2, 3);
gboolean gsk_css_parser_consume_if (GskCssParser *self,
GskCssTokenType token_type);
gboolean gsk_css_parser_consume_number (GskCssParser *self,
double *number);
gboolean gsk_css_parser_consume_percentage (GskCssParser *self,
double *number);
gboolean gsk_css_parser_consume_function (GskCssParser *self,
guint min_args,
guint max_args,
guint (* parse_func) (GskCssParser *, guint, gpointer),
gpointer data);
G_END_DECLS
#endif /* __GSK_CSS_PARSER_H__ */
File diff suppressed because it is too large Load Diff
-153
View File
@@ -1,153 +0,0 @@
/* GSK - The GIMP Toolkit
* Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GSK_CSS_TOKENIZER_PRIVATE_H__
#define __GSK_CSS_TOKENIZER_PRIVATE_H__
#include <glib.h>
G_BEGIN_DECLS
typedef enum {
/* no content */
GSK_CSS_TOKEN_EOF,
GSK_CSS_TOKEN_WHITESPACE,
GSK_CSS_TOKEN_OPEN_PARENS,
GSK_CSS_TOKEN_CLOSE_PARENS,
GSK_CSS_TOKEN_OPEN_SQUARE,
GSK_CSS_TOKEN_CLOSE_SQUARE,
GSK_CSS_TOKEN_OPEN_CURLY,
GSK_CSS_TOKEN_CLOSE_CURLY,
GSK_CSS_TOKEN_COMMA,
GSK_CSS_TOKEN_COLON,
GSK_CSS_TOKEN_SEMICOLON,
GSK_CSS_TOKEN_CDO,
GSK_CSS_TOKEN_CDC,
GSK_CSS_TOKEN_INCLUDE_MATCH,
GSK_CSS_TOKEN_DASH_MATCH,
GSK_CSS_TOKEN_PREFIX_MATCH,
GSK_CSS_TOKEN_SUFFIX_MATCH,
GSK_CSS_TOKEN_SUBSTRING_MATCH,
GSK_CSS_TOKEN_COLUMN,
GSK_CSS_TOKEN_BAD_STRING,
GSK_CSS_TOKEN_BAD_URL,
GSK_CSS_TOKEN_COMMENT,
/* delim */
GSK_CSS_TOKEN_DELIM,
/* string */
GSK_CSS_TOKEN_STRING,
GSK_CSS_TOKEN_IDENT,
GSK_CSS_TOKEN_FUNCTION,
GSK_CSS_TOKEN_AT_KEYWORD,
GSK_CSS_TOKEN_HASH_UNRESTRICTED,
GSK_CSS_TOKEN_HASH_ID,
GSK_CSS_TOKEN_URL,
/* number */
GSK_CSS_TOKEN_SIGNED_INTEGER,
GSK_CSS_TOKEN_SIGNLESS_INTEGER,
GSK_CSS_TOKEN_SIGNED_NUMBER,
GSK_CSS_TOKEN_SIGNLESS_NUMBER,
GSK_CSS_TOKEN_PERCENTAGE,
/* dimension */
GSK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION,
GSK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION,
GSK_CSS_TOKEN_DIMENSION
} GskCssTokenType;
typedef union _GskCssToken GskCssToken;
typedef struct _GskCssTokenizer GskCssTokenizer;
typedef struct _GskCssLocation GskCssLocation;
typedef struct _GskCssStringToken GskCssStringToken;
typedef struct _GskCssDelimToken GskCssDelimToken;
typedef struct _GskCssNumberToken GskCssNumberToken;
typedef struct _GskCssDimensionToken GskCssDimensionToken;
typedef void (* GskCssTokenizerErrorFunc) (GskCssTokenizer *parser,
const GskCssToken *token,
const GError *error,
gpointer user_data);
struct _GskCssStringToken {
GskCssTokenType type;
char *string;
};
struct _GskCssDelimToken {
GskCssTokenType type;
gunichar delim;
};
struct _GskCssNumberToken {
GskCssTokenType type;
double number;
};
struct _GskCssDimensionToken {
GskCssTokenType type;
double value;
char *dimension;
};
union _GskCssToken {
GskCssTokenType type;
GskCssStringToken string;
GskCssDelimToken delim;
GskCssNumberToken number;
GskCssDimensionToken dimension;
};
struct _GskCssLocation
{
gsize bytes;
gsize chars;
gsize lines;
gsize line_bytes;
gsize line_chars;
};
void gsk_css_token_clear (GskCssToken *token);
gboolean gsk_css_token_is_finite (const GskCssToken *token);
gboolean gsk_css_token_is_preserved (const GskCssToken *token,
GskCssTokenType *out_closing);
#define gsk_css_token_is(token, _type) ((token)->type == (_type))
gboolean gsk_css_token_is_ident (const GskCssToken *token,
const char *ident);
gboolean gsk_css_token_is_function (const GskCssToken *token,
const char *ident);
gboolean gsk_css_token_is_delim (const GskCssToken *token,
gunichar delim);
void gsk_css_token_print (const GskCssToken *token,
GString *string);
char * gsk_css_token_to_string (const GskCssToken *token);
GskCssTokenizer * gsk_css_tokenizer_new (GBytes *bytes);
GskCssTokenizer * gsk_css_tokenizer_ref (GskCssTokenizer *tokenizer);
void gsk_css_tokenizer_unref (GskCssTokenizer *tokenizer);
const GskCssLocation * gsk_css_tokenizer_get_location (GskCssTokenizer *tokenizer);
gboolean gsk_css_tokenizer_read_token (GskCssTokenizer *tokenizer,
GskCssToken *token,
GError **error);
G_END_DECLS
#endif /* __GSK_CSS_TOKENIZER_PRIVATE_H__ */
+39 -5
View File
@@ -42,7 +42,6 @@
#include "gskdebugprivate.h"
#include "gskrendererprivate.h"
#include "gskrendernodeparserprivate.h"
#include <graphene-gobject.h>
@@ -329,11 +328,19 @@ gsk_render_node_diff (GskRenderNode *node1,
GBytes *
gsk_render_node_serialize (GskRenderNode *node)
{
GVariant *node_variant, *variant;
GBytes *result;
char *str;
str = gsk_render_node_serialize_to_string (node);
result = g_bytes_new_take (str, strlen (str));
node_variant = gsk_render_node_serialize_node (node);
variant = g_variant_new ("(suuv)",
GSK_RENDER_NODE_SERIALIZATION_ID,
(guint32) GSK_RENDER_NODE_SERIALIZATION_VERSION,
(guint32) gsk_render_node_get_node_type (node),
node_variant);
result = g_variant_get_data_as_bytes (variant);
g_variant_unref (variant);
return result;
}
@@ -390,9 +397,36 @@ GskRenderNode *
gsk_render_node_deserialize (GBytes *bytes,
GError **error)
{
char *id_string;
guint32 version, node_type;
GVariant *variant, *node_variant;
GskRenderNode *node = NULL;
node = gsk_render_node_deserialize_from_bytes (bytes);
variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("(suuv)"), bytes, FALSE);
g_variant_get (variant, "(suuv)", &id_string, &version, &node_type, &node_variant);
if (!g_str_equal (id_string, GSK_RENDER_NODE_SERIALIZATION_ID))
{
g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_FORMAT,
"Data not in GskRenderNode serialization format.");
goto out;
}
if (version != GSK_RENDER_NODE_SERIALIZATION_VERSION)
{
g_set_error (error, GSK_SERIALIZATION_ERROR, GSK_SERIALIZATION_UNSUPPORTED_VERSION,
"Format version %u not supported.", version);
goto out;
}
node = gsk_render_node_deserialize_node (node_type, node_variant, error);
out:
g_free (id_string);
g_variant_unref (node_variant);
g_variant_unref (variant);
return node;
}
+4 -4
View File
@@ -3060,10 +3060,10 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
if (alpha > 0.0)
{
alpha = MIN (alpha, 1.0);
pixel_data[x] = (((guint32) (alpha * 255)) << 24) |
(((guint32) (CLAMP (graphene_vec4_get_x (&pixel), 0, 1) * alpha * 255)) << 16) |
(((guint32) (CLAMP (graphene_vec4_get_y (&pixel), 0, 1) * alpha * 255)) << 8) |
((guint32) (CLAMP (graphene_vec4_get_z (&pixel), 0, 1) * alpha * 255));
pixel_data[x] = (((guint32) roundf (alpha * 255)) << 24) |
(((guint32) roundf (CLAMP (graphene_vec4_get_x (&pixel), 0, 1) * alpha * 255)) << 16) |
(((guint32) roundf (CLAMP (graphene_vec4_get_y (&pixel), 0, 1) * alpha * 255)) << 8) |
((guint32) roundf (CLAMP (graphene_vec4_get_z (&pixel), 0, 1) * alpha * 255));
}
else
{
File diff suppressed because it is too large Load Diff
-10
View File
@@ -1,10 +0,0 @@
#ifndef __GSK_RENDER_NODE_PARSER_PRIVATE_H__
#define __GSK_RENDER_NODE_PARSER_PRIVATE_H__
#include "gskrendernode.h"
GskRenderNode * gsk_render_node_deserialize_from_bytes (GBytes *bytes);
char * gsk_render_node_serialize_to_string (GskRenderNode *root);
#endif
+2 -253
View File
@@ -1264,8 +1264,8 @@ gsk_transform_unref (GskTransform *self)
* @self: (allow-none): a #GskTransform
* @string: The string to print into
*
* Converts @self into a human-readable string representation suitable
* for printing that can later be parsed with gsk_transform_from_string().
* Converts @self into a string representation suitable for printing that
* can later be parsed with gsk_transform_parse().
**/
void
gsk_transform_print (GskTransform *self,
@@ -1651,254 +1651,3 @@ gsk_transform_transform_bounds (GskTransform *self,
break;
}
}
static guint
gsk_transform_parse_float (GskCssParser *parser,
guint n,
gpointer data)
{
float *f = data;
double d;
if (!gsk_css_parser_consume_number (parser, &d))
return 0;
f[n] = d;
return 1;
}
static guint
gsk_transform_parse_scale (GskCssParser *parser,
guint n,
gpointer data)
{
float *f = data;
double d;
if (!gsk_css_parser_consume_number (parser, &d))
return 0;
f[n] = d;
f[1] = d;
return 1;
}
gboolean
gsk_transform_parse (GskCssParser *parser,
GskTransform **out_transform)
{
const GskCssToken *token;
GskTransform *transform = NULL;
float f[16] = { 0, };
token = gsk_css_parser_get_token (parser);
if (gsk_css_token_is_ident (token, "none"))
{
gsk_css_parser_consume_token (parser);
*out_transform = NULL;
return TRUE;
}
while (TRUE)
{
if (gsk_css_token_is_function (token, "matrix"))
{
graphene_matrix_t matrix;
if (!gsk_css_parser_consume_function (parser, 6, 6, gsk_transform_parse_float, f))
goto fail;
graphene_matrix_init_from_2d (&matrix, f[0], f[1], f[2], f[3], f[4], f[5]);
transform = gsk_transform_matrix_with_category (transform,
&matrix,
GSK_TRANSFORM_CATEGORY_2D);
}
else if (gsk_css_token_is_function (token, "matrix3d"))
{
graphene_matrix_t matrix;
if (!gsk_css_parser_consume_function (parser, 16, 16, gsk_transform_parse_float, f))
goto fail;
graphene_matrix_init_from_float (&matrix, f);
transform = gsk_transform_matrix (transform, &matrix);
}
else if (gsk_css_token_is_function (token, "perspective"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_perspective (transform, f[0]);
}
else if (gsk_css_token_is_function (token, "rotate") ||
gsk_css_token_is_function (token, "rotateZ"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_rotate (transform, f[0]);
}
else if (gsk_css_token_is_function (token, "rotate3d"))
{
graphene_vec3_t axis;
if (!gsk_css_parser_consume_function (parser, 4, 4, gsk_transform_parse_float, f))
goto fail;
graphene_vec3_init (&axis, f[0], f[1], f[2]);
transform = gsk_transform_rotate_3d (transform, f[3], &axis);
}
else if (gsk_css_token_is_function (token, "rotateX"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_rotate_3d (transform, f[0], graphene_vec3_x_axis ());
}
else if (gsk_css_token_is_function (token, "rotateY"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_rotate_3d (transform, f[0], graphene_vec3_y_axis ());
}
else if (gsk_css_token_is_function (token, "scale"))
{
if (!gsk_css_parser_consume_function (parser, 1, 2, gsk_transform_parse_scale, f))
goto fail;
transform = gsk_transform_scale (transform, f[0], f[1]);
}
else if (gsk_css_token_is_function (token, "scale3d"))
{
if (!gsk_css_parser_consume_function (parser, 3, 3, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_scale_3d (transform, f[0], f[1], f[2]);
}
else if (gsk_css_token_is_function (token, "scaleX"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_scale (transform, f[0], 1.f);
}
else if (gsk_css_token_is_function (token, "scaleY"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_scale (transform, 1.f, f[0]);
}
else if (gsk_css_token_is_function (token, "scaleZ"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_scale_3d (transform, 1.f, 1.f, f[0]);
}
else if (gsk_css_token_is_function (token, "translate"))
{
f[1] = 0.f;
if (!gsk_css_parser_consume_function (parser, 1, 2, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (f[0], f[1]));
}
else if (gsk_css_token_is_function (token, "translate3d"))
{
if (!gsk_css_parser_consume_function (parser, 3, 3, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (f[0], f[1], f[2]));
}
else if (gsk_css_token_is_function (token, "translateX"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (f[0], 0.f));
}
else if (gsk_css_token_is_function (token, "translateY"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (0.f, f[0]));
}
else if (gsk_css_token_is_function (token, "translateZ"))
{
if (!gsk_css_parser_consume_function (parser, 1, 1, gsk_transform_parse_float, f))
goto fail;
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0.f, 0.f, f[0]));
}
#if 0
/* FIXME: add these */
else if (gsk_css_token_is_function (token, "skew"))
{
}
else if (gsk_css_token_is_function (token, "skewX"))
{
}
else if (gsk_css_token_is_function (token, "skewY"))
{
}
#endif
else
{
break;
}
token = gsk_css_parser_get_token (parser);
}
if (transform == NULL)
{
gsk_css_parser_error_syntax (parser, "Expected a transform");
goto fail;
}
*out_transform = transform;
return TRUE;
fail:
gsk_transform_unref (transform);
*out_transform = NULL;
return FALSE;
}
/**
* gsk_transform_from_string:
* @string: the string to parse
* @out_transform: (out): The location to put the transform in
*
* Parses the given @string into a transform and puts it in
* @out_transform. Strings printed via gsk_transform_to_string()
* can be read in again successfully using this function.
*
* If @string does not describe a valid transform, %FALSE is
* returned and %NULL is put in @out_transform.
*
* Returns: %TRUE if @string described a valid transform.
**/
gboolean
gsk_transform_from_string (const char *string,
GskTransform **out_transform)
{
GskCssParser *parser;
GBytes *bytes;
gboolean result;
g_return_val_if_fail (string != NULL, FALSE);
g_return_val_if_fail (out_transform != NULL, FALSE);
bytes = g_bytes_new_static (string, strlen (string));
parser = gsk_css_parser_new (NULL, NULL, NULL);
gsk_css_parser_add_bytes (parser, bytes);
result = gsk_transform_parse (parser, out_transform);
gsk_css_parser_unref (parser);
g_bytes_unref (bytes);
return result;
}
-3
View File
@@ -46,9 +46,6 @@ void gsk_transform_print (GskTransform
GDK_AVAILABLE_IN_ALL
char * gsk_transform_to_string (GskTransform *self);
GDK_AVAILABLE_IN_ALL
gboolean gsk_transform_from_string (const char *string,
GskTransform **out_transform);
GDK_AVAILABLE_IN_ALL
void gsk_transform_to_matrix (GskTransform *self,
graphene_matrix_t *out_matrix);
GDK_AVAILABLE_IN_ALL
+1 -5
View File
@@ -23,7 +23,7 @@
#include "gsktransform.h"
#include "gsk/gskcssparserprivate.h"
#include <gsk/gsk.h>
#include "gsk/gskrendernodeprivate.h"
G_BEGIN_DECLS
@@ -32,10 +32,6 @@ GskTransform * gsk_transform_matrix_with_category (GskTransform
const graphene_matrix_t*matrix,
GskTransformCategory category);
gboolean gsk_transform_parse (GskCssParser *parser,
GskTransform **out_transform);
G_END_DECLS
#endif /* __GSK_TRANSFORM_PRIVATE_H__ */
-3
View File
@@ -31,12 +31,9 @@ gsk_public_sources = files([
gsk_private_sources = files([
'gskcairoblur.c',
'gskcairorenderer.c',
'gskcssparser.c',
'gskcsstokenizer.c',
'gskdebug.c',
'gskprivate.c',
'gskprofiler.c',
'gskrendernodeparser.c',
'gl/gskshaderbuilder.c',
'gl/gskglprofiler.c',
'gl/gskglrenderer.c',
+8 -2
View File
@@ -876,12 +876,18 @@ static gint
gtk_entry_accessible_get_caret_offset (AtkText *text)
{
GtkWidget *widget;
gboolean result;
int cursor_position;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
return 0;
return -1;
return gtk_editable_get_position (GTK_EDITABLE (widget));
result = gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), NULL, &cursor_position);
if (!result)
return -1;
return cursor_position;
}
static gboolean
+5 -1
View File
@@ -822,7 +822,11 @@ gtk_label_accessible_get_caret_offset (AtkText *text)
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
return 0;
return -1;
/* Non-selectable labels cannot have a caret. */
if (!gtk_label_get_selectable (GTK_LABEL (widget)))
return -1;
return _gtk_label_get_cursor_position (GTK_LABEL (widget));
}
+8 -2
View File
@@ -317,12 +317,18 @@ static gint
gtk_text_accessible_get_caret_offset (AtkText *text)
{
GtkWidget *widget;
gboolean result;
int cursor_position;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
return 0;
return -1;
return gtk_editable_get_position (GTK_EDITABLE (widget));
result = gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), NULL, &cursor_position);
if (!result)
return -1;
return cursor_position;
}
static gboolean
+1
View File
@@ -198,6 +198,7 @@ static void
gtk_text_cell_accessible_init (GtkTextCellAccessible *text_cell)
{
text_cell->priv = gtk_text_cell_accessible_get_instance_private (text_cell);
text_cell->priv->caret_pos = -1;
}
static gchar *
+1 -1
View File
@@ -412,7 +412,7 @@ gtk_text_view_accessible_get_caret_offset (AtkText *text)
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
if (widget == NULL)
return 0;
return -1;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
return get_insert_offset (buffer);
+2 -76
View File
@@ -625,39 +625,7 @@ gtk_widget_accessible_set_extents (AtkComponent *component,
gint height,
AtkCoordType coord_type)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
if (widget == NULL)
return FALSE;
if (!gtk_widget_is_toplevel (widget))
return FALSE;
if (coord_type == ATK_XY_WINDOW)
{
gint x_current, y_current;
GdkSurface *surface = gtk_widget_get_surface (widget);
gdk_surface_get_origin (surface, &x_current, &y_current);
x_current += x;
y_current += y;
if (x_current < 0 || y_current < 0)
return FALSE;
else
{
gtk_window_move (GTK_WINDOW (widget), x_current, y_current);
gtk_widget_set_size_request (widget, width, height);
return TRUE;
}
}
else if (coord_type == ATK_XY_SCREEN)
{
gtk_window_move (GTK_WINDOW (widget), x, y);
gtk_widget_set_size_request (widget, width, height);
return TRUE;
}
return FALSE;
return FALSE;
}
static gboolean
@@ -666,37 +634,7 @@ gtk_widget_accessible_set_position (AtkComponent *component,
gint y,
AtkCoordType coord_type)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
if (widget == NULL)
return FALSE;
if (gtk_widget_is_toplevel (widget))
{
if (coord_type == ATK_XY_WINDOW)
{
gint x_current, y_current;
GdkSurface *surface = gtk_widget_get_surface (widget);
gdk_surface_get_origin (surface, &x_current, &y_current);
x_current += x;
y_current += y;
if (x_current < 0 || y_current < 0)
return FALSE;
else
{
gtk_window_move (GTK_WINDOW (widget), x_current, y_current);
return TRUE;
}
}
else if (coord_type == ATK_XY_SCREEN)
{
gtk_window_move (GTK_WINDOW (widget), x, y);
return TRUE;
}
}
return FALSE;
return FALSE;
}
static gboolean
@@ -704,18 +642,6 @@ gtk_widget_accessible_set_size (AtkComponent *component,
gint width,
gint height)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
if (widget == NULL)
return FALSE;
if (gtk_widget_is_toplevel (widget))
{
gtk_widget_set_size_request (widget, width, height);
return TRUE;
}
else
return FALSE;
}
-5
View File
@@ -46,11 +46,6 @@ xml += '\n'
for f in get_files('theme/HighContrast/assets', '.svg'):
xml += ' <file>theme/HighContrast/assets/{0}</file>\n'.format(f)
xml += '''
<file>theme/win32/gtk-win32-base.css</file>
<file>theme/win32/gtk.css</file>
'''
for f in get_files('gesture', '.symbolic.png'):
xml += ' <file alias=\'icons/64x64/actions/{0}\'>gesture/{0}</file>\n'.format(f)
+6
View File
@@ -45,8 +45,10 @@
#include <gtk/gtkaspectframe.h>
#include <gtk/gtkassistant.h>
#include <gtk/gtkbin.h>
#include <gtk/gtkbinlayout.h>
#include <gtk/gtkbindings.h>
#include <gtk/gtkborder.h>
#include <gtk/gtkboxlayout.h>
#include <gtk/gtkbox.h>
#include <gtk/gtkbuildable.h>
#include <gtk/gtkbuilder.h>
@@ -80,6 +82,7 @@
#include <gtk/gtkcontainer.h>
#include <gtk/gtkcssprovider.h>
#include <gtk/gtkcsssection.h>
#include <gtk/gtkcustomlayout.h>
#include <gtk/gtkdebug.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkdnd.h>
@@ -98,6 +101,7 @@
#include <gtk/gtkeventcontrollerscroll.h>
#include <gtk/gtkexpander.h>
#include <gtk/gtkfixed.h>
#include <gtk/gtkfixedlayout.h>
#include <gtk/gtkfilechooser.h>
#include <gtk/gtkfilechooserbutton.h>
#include <gtk/gtkfilechooserdialog.h>
@@ -134,6 +138,8 @@
#include <gtk/gtkinfobar.h>
#include <gtk/gtklabel.h>
#include <gtk/gtklayout.h>
#include <gtk/gtklayoutmanager.h>
#include <gtk/gtklayoutchild.h>
#include <gtk/gtklevelbar.h>
#include <gtk/gtklinkbutton.h>
#include <gtk/gtklistbox.h>
+5 -88
View File
@@ -61,11 +61,6 @@ struct _GtkActionBarPrivate
GtkWidget *revealer;
};
enum {
CHILD_PROP_0,
CHILD_PROP_PACK_TYPE,
};
enum {
PROP_0,
PROP_REVEALED,
@@ -139,78 +134,6 @@ gtk_action_bar_child_type (GtkContainer *container)
return GTK_TYPE_WIDGET;
}
static void
gtk_action_bar_get_child_property (GtkContainer *container,
GtkWidget *child,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (container));
switch (property_id)
{
case CHILD_PROP_PACK_TYPE:
if (gtk_widget_get_parent (child) == priv->start_box)
g_value_set_enum (value, GTK_PACK_START);
else if (gtk_widget_get_parent (child) == priv->end_box)
g_value_set_enum (value, GTK_PACK_END);
else /* Center widget */
g_value_set_enum (value, GTK_PACK_START);
break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
}
}
static void
gtk_action_bar_set_child_property (GtkContainer *container,
GtkWidget *child,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (container));
switch (property_id)
{
case CHILD_PROP_PACK_TYPE:
if (gtk_widget_get_parent (child) == priv->start_box)
{
if (g_value_get_enum (value) == GTK_PACK_END)
{
g_object_ref (child);
gtk_container_remove (GTK_CONTAINER (priv->start_box), child);
gtk_box_insert_child_after (GTK_BOX (priv->end_box), child, NULL);
g_object_unref (child);
}
}
else if (gtk_widget_get_parent (child) == priv->end_box)
{
if (g_value_get_enum (value) == GTK_PACK_START)
{
g_object_ref (child);
gtk_container_remove (GTK_CONTAINER (priv->end_box), child);
gtk_container_add (GTK_CONTAINER (priv->start_box), child);
g_object_unref (child);
}
}
else
{
/* Ignore the center widget */
}
break;
default:
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
break;
}
}
static void
gtk_action_bar_size_allocate (GtkWidget *widget,
int width,
@@ -322,16 +245,6 @@ gtk_action_bar_class_init (GtkActionBarClass *klass)
container_class->remove = gtk_action_bar_remove;
container_class->forall = gtk_action_bar_forall;
container_class->child_type = gtk_action_bar_child_type;
container_class->set_child_property = gtk_action_bar_set_child_property;
container_class->get_child_property = gtk_action_bar_get_child_property;
gtk_container_class_install_child_property (container_class,
CHILD_PROP_PACK_TYPE,
g_param_spec_enum ("pack-type",
P_("Pack type"),
P_("A GtkPackType indicating whether the child is packed with reference to the start or end of the parent"),
GTK_TYPE_PACK_TYPE, GTK_PACK_START,
G_PARAM_READWRITE));
props[PROP_REVEALED] =
g_param_spec_boolean ("revealed",
@@ -380,8 +293,12 @@ gtk_action_bar_buildable_add_child (GtkBuildable *buildable,
{
GtkActionBar *action_bar = GTK_ACTION_BAR (buildable);
if (type && strcmp (type, "center") == 0)
if (g_strcmp0 (type, "center") == 0)
gtk_action_bar_set_center_widget (action_bar, GTK_WIDGET (child));
else if (g_strcmp0 (type, "start") == 0)
gtk_action_bar_pack_start (action_bar, GTK_WIDGET (child));
else if (g_strcmp0 (type, "end") == 0)
gtk_action_bar_pack_end (action_bar, GTK_WIDGET (child));
else
parent_buildable_iface->add_child (buildable, builder, child, type);
}
+124
View File
@@ -0,0 +1,124 @@
/* gtkbinlayout.c: Layout manager for bin-like widgets
* Copyright 2019 GNOME Foundation
*
* 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:gtkbinlayout
* @Title: GtkBinLayout
* @Short_description: A layout manager for bin-like widgets
* @Include: gtk/gtk.h
*
* GtkBinLayout is a #GtkLayoutManager subclass useful for create "bins" of
* widgets. GtkBinLayout will stack each child of a widget on top of each
* other, using the #GtkWidget:hexpand, #GtkWidget:vexpand, #GtkWidget:halign,
* and #GtkWidget:valign properties of each child to determine where they
* should be positioned.
*/
#include "config.h"
#include "gtkbinlayout.h"
#include "gtkwidgetprivate.h"
struct _GtkBinLayout
{
GtkLayoutManager parent_instance;
};
G_DEFINE_TYPE (GtkBinLayout, gtk_bin_layout, GTK_TYPE_LAYOUT_MANAGER)
static void
gtk_bin_layout_measure (GtkLayoutManager *layout_manager,
GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkWidget *child;
for (child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (gtk_widget_get_visible (child))
{
int child_min = 0;
int child_nat = 0;
int child_min_baseline = -1;
int child_nat_baseline = -1;
gtk_widget_measure (child, orientation, for_size,
&child_min, &child_nat,
&child_min_baseline, &child_nat_baseline);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
if (child_min_baseline > -1)
*minimum_baseline = MAX (*minimum_baseline, child_min_baseline);
if (child_nat_baseline > -1)
*natural_baseline = MAX (*natural_baseline, child_nat_baseline);
}
}
}
static void
gtk_bin_layout_allocate (GtkLayoutManager *layout_manager,
GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkWidget *child;
for (child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (child && gtk_widget_get_visible (child))
gtk_widget_allocate (child, width, height, baseline, NULL);
}
}
static void
gtk_bin_layout_class_init (GtkBinLayoutClass *klass)
{
GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass);
layout_manager_class->measure = gtk_bin_layout_measure;
layout_manager_class->allocate = gtk_bin_layout_allocate;
}
static void
gtk_bin_layout_init (GtkBinLayout *self)
{
}
/**
* gtk_bin_layout_new:
*
* Creates a new #GtkBinLayout instance.
*
* Returns: the newly created #GtkBinLayout
*/
GtkLayoutManager *
gtk_bin_layout_new (void)
{
return g_object_new (GTK_TYPE_BIN_LAYOUT, NULL);
}
+14 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright © 2019 Benjamin Otte
/* gtkbinlayout.h: Layout manager for bin-like widgets
* Copyright 2019 GNOME Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -13,16 +13,19 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#pragma once
#include "config.h"
#include <gtk/gtklayoutmanager.h>
#include <node-editor-application.h>
G_BEGIN_DECLS
int
main (int argc, char *argv[])
{
return g_application_run (G_APPLICATION (node_editor_application_new ()), argc, argv);
}
#define GTK_TYPE_BIN_LAYOUT (gtk_bin_layout_get_type ())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkBinLayout, gtk_bin_layout, GTK, BIN_LAYOUT, GtkLayoutManager)
GDK_AVAILABLE_IN_ALL
GtkLayoutManager * gtk_bin_layout_new (void);
G_END_DECLS
+45 -578
View File
@@ -57,6 +57,7 @@
#include "config.h"
#include "gtkbox.h"
#include "gtkboxlayout.h"
#include "gtkcsspositionvalueprivate.h"
#include "gtkintl.h"
#include "gtkorientable.h"
@@ -92,11 +93,6 @@ typedef struct
static GParamSpec *props[LAST_PROP] = { NULL, };
static void gtk_box_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline);
static void gtk_box_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -116,13 +112,6 @@ static GType gtk_box_child_type (GtkContainer *container);
static GtkWidgetPath * gtk_box_get_path_for_child
(GtkContainer *container,
GtkWidget *child);
static void gtk_box_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline);
G_DEFINE_TYPE_WITH_CODE (GtkBox, gtk_box, GTK_TYPE_CONTAINER,
G_ADD_PRIVATE (GtkBox)
@@ -138,9 +127,6 @@ gtk_box_class_init (GtkBoxClass *class)
object_class->set_property = gtk_box_set_property;
object_class->get_property = gtk_box_get_property;
widget_class->size_allocate = gtk_box_size_allocate;
widget_class->measure = gtk_box_measure;
container_class->add = gtk_box_add;
container_class->remove = gtk_box_remove;
container_class->forall = gtk_box_forall;
@@ -187,6 +173,7 @@ gtk_box_set_property (GObject *object,
{
GtkBox *box = GTK_BOX (object);
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkLayoutManager *box_layout = gtk_widget_get_layout_manager (GTK_WIDGET (box));
switch (prop_id)
{
@@ -196,8 +183,9 @@ gtk_box_set_property (GObject *object,
if (priv->orientation != orientation)
{
priv->orientation = orientation;
gtk_orientable_set_orientation (GTK_ORIENTABLE (box_layout),
priv->orientation);
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (box));
gtk_widget_queue_resize (GTK_WIDGET (box));
g_object_notify (object, "orientation");
}
}
@@ -225,6 +213,7 @@ gtk_box_get_property (GObject *object,
{
GtkBox *box = GTK_BOX (object);
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkBoxLayout *box_layout = GTK_BOX_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (box)));
switch (prop_id)
{
@@ -232,13 +221,13 @@ gtk_box_get_property (GObject *object,
g_value_set_enum (value, priv->orientation);
break;
case PROP_SPACING:
g_value_set_int (value, priv->spacing);
g_value_set_int (value, gtk_box_layout_get_spacing (box_layout));
break;
case PROP_BASELINE_POSITION:
g_value_set_enum (value, priv->baseline_pos);
g_value_set_enum (value, gtk_box_layout_get_baseline_position (box_layout));
break;
case PROP_HOMOGENEOUS:
g_value_set_boolean (value, priv->homogeneous);
g_value_set_boolean (value, gtk_box_layout_get_homogeneous (box_layout));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -246,285 +235,6 @@ gtk_box_get_property (GObject *object,
}
}
static void
count_expand_children (GtkBox *box,
gint *visible_children,
gint *expand_children)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkWidget *child;
*visible_children = *expand_children = 0;
for (child = _gtk_widget_get_first_child (GTK_WIDGET (box));
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (_gtk_widget_get_visible (child))
{
*visible_children += 1;
if (gtk_widget_compute_expand (child, priv->orientation))
*expand_children += 1;
}
}
}
static gint
get_spacing (GtkBox *box)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkCssValue *border_spacing;
gint css_spacing;
border_spacing = _gtk_style_context_peek_property (gtk_widget_get_style_context (GTK_WIDGET (box)), GTK_CSS_PROPERTY_BORDER_SPACING);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
css_spacing = _gtk_css_position_value_get_x (border_spacing, 100);
else
css_spacing = _gtk_css_position_value_get_y (border_spacing, 100);
return css_spacing + priv->spacing;
}
static void
gtk_box_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkBox *box = GTK_BOX (widget);
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkWidget *child;
gint nvis_children;
gint nexpand_children;
GtkTextDirection direction;
GtkAllocation child_allocation;
GtkRequestedSize *sizes;
gint child_minimum_baseline, child_natural_baseline;
gint minimum_above, natural_above;
gint minimum_below, natural_below;
gboolean have_baseline;
gint extra_space;
gint children_minimum_size = 0;
gint size_given_to_child;
gint n_extra_widgets = 0; /* Number of widgets that receive 1 extra px */
gint x = 0, y = 0, i;
gint child_size;
gint spacing;
count_expand_children (box, &nvis_children, &nexpand_children);
/* If there is no visible child, simply return. */
if (nvis_children <= 0)
return;
direction = _gtk_widget_get_direction (widget);
sizes = g_newa (GtkRequestedSize, nvis_children);
spacing = get_spacing (box);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
extra_space = width - (nvis_children - 1) * spacing;
else
extra_space = height - (nvis_children - 1) * spacing;
have_baseline = FALSE;
minimum_above = natural_above = 0;
minimum_below = natural_below = 0;
/* Retrieve desired size for visible children. */
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (!_gtk_widget_get_visible (child))
continue;
gtk_widget_measure (child,
priv->orientation,
priv->orientation == GTK_ORIENTATION_HORIZONTAL ? height : width,
&sizes[i].minimum_size, &sizes[i].natural_size,
NULL, NULL);
children_minimum_size += sizes[i].minimum_size;
sizes[i].data = child;
i++;
}
if (priv->homogeneous)
{
/* We still need to run the above loop to populate the minimum sizes for
* children that aren't going to fill.
*/
size_given_to_child = extra_space / nvis_children;
n_extra_widgets = extra_space % nvis_children;
}
else
{
/* Bring children up to size first */
extra_space -= children_minimum_size;
extra_space = MAX (0, extra_space);
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
/* Calculate space which hasn't distributed yet,
* and is available for expanding children.
*/
if (nexpand_children > 0)
{
size_given_to_child = extra_space / nexpand_children;
n_extra_widgets = extra_space % nexpand_children;
}
else
{
size_given_to_child = 0;
}
}
/* Allocate child sizes. */
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
/* If widget is not visible, skip it. */
if (!_gtk_widget_get_visible (child))
continue;
/* Assign the child's size. */
if (priv->homogeneous)
{
child_size = size_given_to_child;
if (n_extra_widgets > 0)
{
child_size++;
n_extra_widgets--;
}
}
else
{
child_size = sizes[i].minimum_size;
if (gtk_widget_compute_expand (child, priv->orientation))
{
child_size += size_given_to_child;
if (n_extra_widgets > 0)
{
child_size++;
n_extra_widgets--;
}
}
}
sizes[i].natural_size = child_size;
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL &&
gtk_widget_get_valign (child) == GTK_ALIGN_BASELINE)
{
int child_allocation_width;
int child_minimum_height, child_natural_height;
child_allocation_width = child_size;
child_minimum_baseline = -1;
child_natural_baseline = -1;
gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL,
child_allocation_width,
&child_minimum_height, &child_natural_height,
&child_minimum_baseline, &child_natural_baseline);
if (child_minimum_baseline >= 0)
{
have_baseline = TRUE;
minimum_below = MAX (minimum_below, child_minimum_height - child_minimum_baseline);
natural_below = MAX (natural_below, child_natural_height - child_natural_baseline);
minimum_above = MAX (minimum_above, child_minimum_baseline);
natural_above = MAX (natural_above, child_natural_baseline);
}
}
i++;
}
if (priv->orientation == GTK_ORIENTATION_VERTICAL)
baseline = -1;
/* we only calculate our own baseline if we don't get one passed from the parent
* and any of the child widgets explicitly request one */
if (baseline == -1 && have_baseline)
{
/* TODO: This is purely based on the minimum baseline, when things fit we should
use the natural one? */
switch (priv->baseline_pos)
{
case GTK_BASELINE_POSITION_TOP:
baseline = minimum_above;
break;
case GTK_BASELINE_POSITION_CENTER:
baseline = minimum_above + (height - (minimum_above + minimum_below)) / 2;
break;
case GTK_BASELINE_POSITION_BOTTOM:
baseline = height - minimum_below;
break;
default:
break;
}
}
/* Allocate child positions. */
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
child_allocation.y = 0;
child_allocation.height = height;
x = 0;
}
else
{
child_allocation.x = 0;
child_allocation.width = width;
y = 0;
}
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
/* If widget is not visible, skip it. */
if (!_gtk_widget_get_visible (child))
continue;
child_size = sizes[i].natural_size;
/* Assign the child's position. */
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
child_allocation.width = child_size;
child_allocation.x = x;
x += child_size + spacing;
if (direction == GTK_TEXT_DIR_RTL)
child_allocation.x = width - child_allocation.x - child_allocation.width;
}
else /* (priv->orientation == GTK_ORIENTATION_VERTICAL) */
{
child_allocation.height = child_size;
child_allocation.y = y;
y += child_size + spacing;
}
gtk_widget_size_allocate (child, &child_allocation, baseline);
i++;
}
}
static GType
gtk_box_child_type (GtkContainer *container)
{
@@ -630,263 +340,17 @@ gtk_box_get_path_for_child (GtkContainer *container,
return path;
}
static void
gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
int for_size,
gint *minimum_size,
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkWidget *widget = GTK_WIDGET (box);
GtkWidget *child;
gint nvis_children;
gint nexpand_children;
gint computed_minimum = 0, computed_natural = 0;
gint computed_minimum_above = 0, computed_natural_above = 0;
gint computed_minimum_below = 0, computed_natural_below = 0;
gint computed_minimum_baseline = -1, computed_natural_baseline = -1;
GtkRequestedSize *sizes;
gint extra_space, size_given_to_child, i;
gint children_minimum_size = 0;
gint child_size, child_minimum, child_natural;
gint child_minimum_baseline, child_natural_baseline;
gint n_extra_widgets = 0;
gint spacing;
gboolean have_baseline;
count_expand_children (box, &nvis_children, &nexpand_children);
if (nvis_children <= 0)
return;
spacing = get_spacing (box);
sizes = g_newa (GtkRequestedSize, nvis_children);
extra_space = MAX (0, for_size - (nvis_children - 1) * spacing);
/* Retrieve desired size for visible children */
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (_gtk_widget_get_visible (child))
{
gtk_widget_measure (child,
priv->orientation,
-1,
&sizes[i].minimum_size, &sizes[i].natural_size,
NULL, NULL);
children_minimum_size += sizes[i].minimum_size;
i += 1;
}
}
if (priv->homogeneous)
{
/* We still need to run the above loop to populate the minimum sizes for
* children that aren't going to fill.
*/
size_given_to_child = extra_space / nvis_children;
n_extra_widgets = extra_space % nvis_children;
}
else
{
/* Bring children up to size first */
extra_space -= children_minimum_size;
extra_space = MAX (0, extra_space);
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
/* Calculate space which hasn't distributed yet,
* and is available for expanding children.
*/
if (nexpand_children > 0)
{
size_given_to_child = extra_space / nexpand_children;
n_extra_widgets = extra_space % nexpand_children;
}
else
{
size_given_to_child = 0;
}
}
have_baseline = FALSE;
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
/* If widget is not visible, skip it. */
if (!_gtk_widget_get_visible (child))
continue;
/* Assign the child's size. */
if (priv->homogeneous)
{
child_size = size_given_to_child;
if (n_extra_widgets > 0)
{
child_size++;
n_extra_widgets--;
}
}
else
{
child_size = sizes[i].minimum_size;
if (gtk_widget_compute_expand (child, priv->orientation))
{
child_size += size_given_to_child;
if (n_extra_widgets > 0)
{
child_size++;
n_extra_widgets--;
}
}
}
child_minimum_baseline = child_natural_baseline = -1;
/* Assign the child's position. */
gtk_widget_measure (child,
OPPOSITE_ORIENTATION (priv->orientation),
child_size,
&child_minimum, &child_natural,
&child_minimum_baseline, &child_natural_baseline);
if (child_minimum_baseline >= 0)
{
have_baseline = TRUE;
computed_minimum_below = MAX (computed_minimum_below, child_minimum - child_minimum_baseline);
computed_natural_below = MAX (computed_natural_below, child_natural - child_natural_baseline);
computed_minimum_above = MAX (computed_minimum_above, child_minimum_baseline);
computed_natural_above = MAX (computed_natural_above, child_natural_baseline);
}
else
{
computed_minimum = MAX (computed_minimum, child_minimum);
computed_natural = MAX (computed_natural, child_natural);
}
i += 1;
}
if (have_baseline)
{
computed_minimum = MAX (computed_minimum, computed_minimum_below + computed_minimum_above);
computed_natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
switch (priv->baseline_pos)
{
case GTK_BASELINE_POSITION_TOP:
computed_minimum_baseline = computed_minimum_above;
computed_natural_baseline = computed_natural_above;
break;
case GTK_BASELINE_POSITION_CENTER:
computed_minimum_baseline = computed_minimum_above + MAX((computed_minimum - (computed_minimum_above + computed_minimum_below)) / 2, 0);
computed_natural_baseline = computed_natural_above + MAX((computed_natural - (computed_natural_above + computed_natural_below)) / 2, 0);
break;
case GTK_BASELINE_POSITION_BOTTOM:
computed_minimum_baseline = computed_minimum - computed_minimum_below;
computed_natural_baseline = computed_natural - computed_natural_below;
break;
default:
break;
}
}
*minimum_size = computed_minimum;
*natural_size = MAX (computed_natural, computed_natural_below + computed_natural_above);
*minimum_baseline = computed_minimum_baseline;
*natural_baseline = computed_natural_baseline;
}
static void
gtk_box_compute_size_for_orientation (GtkBox *box,
int for_size,
int *minimum_size,
int *natural_size)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkWidget *child;
const int spacing = get_spacing (box);
int nvis_children = 0;
int required_size = 0, required_natural = 0;
int largest_child = 0, largest_natural = 0;
for (child = _gtk_widget_get_first_child (GTK_WIDGET (box));
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (_gtk_widget_get_visible (child))
{
int child_size, child_natural;
gtk_widget_measure (child,
priv->orientation,
for_size,
&child_size, &child_natural,
NULL, NULL);
largest_child = MAX (largest_child, child_size);
largest_natural = MAX (largest_natural, child_natural);
required_size += child_size;
required_natural += child_natural;
nvis_children += 1;
}
}
if (nvis_children > 0)
{
if (priv->homogeneous)
{
required_size = largest_child * nvis_children;
required_natural = largest_natural * nvis_children;
}
required_size += (nvis_children - 1) * spacing;
required_natural += (nvis_children - 1) * spacing;
}
*minimum_size = required_size;
*natural_size = required_natural;
}
static void
gtk_box_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkBox *box = GTK_BOX (widget);
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
if (priv->orientation != orientation)
gtk_box_compute_size_for_opposing_orientation (box, for_size, minimum, natural, minimum_baseline, natural_baseline);
else
gtk_box_compute_size_for_orientation (box, for_size, minimum, natural);
}
static void
gtk_box_init (GtkBox *box)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkLayoutManager *box_layout = gtk_box_layout_new (GTK_ORIENTATION_HORIZONTAL);
gtk_widget_set_has_surface (GTK_WIDGET (box), FALSE);
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
priv->homogeneous = FALSE;
priv->spacing = 0;
priv->baseline_pos = GTK_BASELINE_POSITION_CENTER;
gtk_widget_set_layout_manager (GTK_WIDGET (box), box_layout);
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (box));
}
@@ -905,7 +369,7 @@ gtk_box_new (GtkOrientation orientation,
{
return g_object_new (GTK_TYPE_BOX,
"orientation", orientation,
"spacing", spacing,
"spacing", spacing,
NULL);
}
@@ -923,18 +387,18 @@ void
gtk_box_set_homogeneous (GtkBox *box,
gboolean homogeneous)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkBoxLayout *box_layout;
g_return_if_fail (GTK_IS_BOX (box));
homogeneous = homogeneous != FALSE;
homogeneous = !!homogeneous;
if (priv->homogeneous != homogeneous)
{
priv->homogeneous = homogeneous;
g_object_notify_by_pspec (G_OBJECT (box), props[PROP_HOMOGENEOUS]);
gtk_widget_queue_resize (GTK_WIDGET (box));
}
box_layout = GTK_BOX_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (box)));
if (homogeneous == gtk_box_layout_get_homogeneous (box_layout))
return;
gtk_box_layout_set_homogeneous (box_layout, homogeneous);
g_object_notify_by_pspec (G_OBJECT (box), props[PROP_HOMOGENEOUS]);
}
/**
@@ -949,11 +413,13 @@ gtk_box_set_homogeneous (GtkBox *box,
gboolean
gtk_box_get_homogeneous (GtkBox *box)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkLayoutManager *box_layout;
g_return_val_if_fail (GTK_IS_BOX (box), FALSE);
return priv->homogeneous;
box_layout = gtk_widget_get_layout_manager (GTK_WIDGET (box));
return gtk_box_layout_get_homogeneous (GTK_BOX_LAYOUT (box_layout));
}
/**
@@ -968,18 +434,16 @@ void
gtk_box_set_spacing (GtkBox *box,
gint spacing)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkBoxLayout *box_layout;
g_return_if_fail (GTK_IS_BOX (box));
if (priv->spacing != spacing)
{
priv->spacing = spacing;
box_layout = GTK_BOX_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (box)));
if (spacing == gtk_box_layout_get_spacing (box_layout))
return;
g_object_notify_by_pspec (G_OBJECT (box), props[PROP_SPACING]);
gtk_widget_queue_resize (GTK_WIDGET (box));
}
gtk_box_layout_set_spacing (box_layout, spacing);
g_object_notify_by_pspec (G_OBJECT (box), props[PROP_SPACING]);
}
/**
@@ -993,10 +457,13 @@ gtk_box_set_spacing (GtkBox *box,
gint
gtk_box_get_spacing (GtkBox *box)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkLayoutManager *box_layout;
g_return_val_if_fail (GTK_IS_BOX (box), 0);
return priv->spacing;
box_layout = gtk_widget_get_layout_manager (GTK_WIDGET (box));
return gtk_box_layout_get_spacing (GTK_BOX_LAYOUT (box_layout));
}
/**
@@ -1015,18 +482,16 @@ void
gtk_box_set_baseline_position (GtkBox *box,
GtkBaselinePosition position)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkBoxLayout *box_layout;
g_return_if_fail (GTK_IS_BOX (box));
if (priv->baseline_pos != position)
{
priv->baseline_pos = position;
box_layout = GTK_BOX_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (box)));
if (position == gtk_box_layout_get_baseline_position (box_layout))
return;
g_object_notify_by_pspec (G_OBJECT (box), props[PROP_BASELINE_POSITION]);
gtk_widget_queue_resize (GTK_WIDGET (box));
}
gtk_box_layout_set_baseline_position (box_layout, position);
g_object_notify_by_pspec (G_OBJECT (box), props[PROP_BASELINE_POSITION]);
}
/**
@@ -1040,11 +505,13 @@ gtk_box_set_baseline_position (GtkBox *box,
GtkBaselinePosition
gtk_box_get_baseline_position (GtkBox *box)
{
GtkBoxPrivate *priv = gtk_box_get_instance_private (box);
GtkLayoutManager *box_layout;
g_return_val_if_fail (GTK_IS_BOX (box), GTK_BASELINE_POSITION_CENTER);
return priv->baseline_pos;
box_layout = gtk_widget_get_layout_manager (GTK_WIDGET (box));
return gtk_box_layout_get_baseline_position (GTK_BOX_LAYOUT (box_layout));
}
static void
+879
View File
@@ -0,0 +1,879 @@
/* gtkboxlayout.c: Box layout manager
*
* Copyright 2019 GNOME Foundation
*
* 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 "gtkboxlayout.h"
#include "gtkcsspositionvalueprivate.h"
#include "gtkintl.h"
#include "gtkorientableprivate.h"
#include "gtkprivate.h"
#include "gtksizerequest.h"
#include "gtkstylecontextprivate.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
/**
* SECTION:gtkboxlayout
* @Title: GtkBoxLayout
* @Short_description: Layout manager for placing all children in a single row or column
*
* A GtkBoxLayout is a layout manager that arranges the children of any
* widget using it into a single row or column, depending on the value
* of its #GtkOrientable:orientation property. Within the other dimension
* all children all allocated the same size. The GtkBoxLayout will respect
* the #GtkWidget:halign and #GtkWidget:valign properties of each child
* widget.
*
* If you want all children to be assigned the same size, you can use
* the #GtkBoxLayout:homogeneous property.
*
* If you want to specify the amount of space placed between each child,
* you can use the #GtkBoxLayout:spacing property.
*/
struct _GtkBoxLayout
{
GtkLayoutManager parent_instance;
gboolean homogeneous;
guint spacing;
GtkOrientation orientation;
GtkBaselinePosition baseline_position;
};
G_DEFINE_TYPE_WITH_CODE (GtkBoxLayout, gtk_box_layout, GTK_TYPE_LAYOUT_MANAGER,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
enum {
PROP_HOMOGENEOUS = 1,
PROP_SPACING,
PROP_BASELINE_POSITION,
/* From GtkOrientable */
PROP_ORIENTATION,
N_PROPS = PROP_ORIENTATION
};
static GParamSpec *box_layout_props[N_PROPS];
static void
gtk_box_layout_set_orientation (GtkBoxLayout *self,
GtkOrientation orientation)
{
GtkLayoutManager *layout_manager = GTK_LAYOUT_MANAGER (self);
GtkWidget *widget;
if (self->orientation == orientation)
return;
self->orientation = orientation;
widget = gtk_layout_manager_get_widget (layout_manager);
if (widget != NULL && GTK_IS_ORIENTABLE (widget))
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (widget));
gtk_layout_manager_layout_changed (layout_manager);
g_object_notify (G_OBJECT (self), "orientation");
}
static void
gtk_box_layout_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkBoxLayout *self = GTK_BOX_LAYOUT (gobject);
switch (prop_id)
{
case PROP_HOMOGENEOUS:
gtk_box_layout_set_homogeneous (self, g_value_get_boolean (value));
break;
case PROP_SPACING:
gtk_box_layout_set_spacing (self, g_value_get_int (value));
break;
case PROP_BASELINE_POSITION:
gtk_box_layout_set_baseline_position (self, g_value_get_enum (value));
break;
case PROP_ORIENTATION:
gtk_box_layout_set_orientation (self, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
gtk_box_layout_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkBoxLayout *box_layout = GTK_BOX_LAYOUT (gobject);
switch (prop_id)
{
case PROP_HOMOGENEOUS:
g_value_set_boolean (value, box_layout->homogeneous);
break;
case PROP_SPACING:
g_value_set_int (value, box_layout->spacing);
break;
case PROP_BASELINE_POSITION:
g_value_set_enum (value, box_layout->baseline_position);
break;
case PROP_ORIENTATION:
g_value_set_enum (value, box_layout->orientation);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
count_expand_children (GtkWidget *widget,
GtkOrientation orientation,
gint *visible_children,
gint *expand_children)
{
GtkWidget *child;
*visible_children = *expand_children = 0;
for (child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (_gtk_widget_get_visible (child))
{
*visible_children += 1;
if (gtk_widget_compute_expand (child, orientation))
*expand_children += 1;
}
}
}
static gint
get_spacing (GtkBoxLayout *self,
GtkStyleContext *style_context)
{
GtkCssValue *border_spacing;
gint css_spacing;
border_spacing = _gtk_style_context_peek_property (style_context, GTK_CSS_PROPERTY_BORDER_SPACING);
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
css_spacing = _gtk_css_position_value_get_x (border_spacing, 100);
else
css_spacing = _gtk_css_position_value_get_y (border_spacing, 100);
return css_spacing + self->spacing;
}
static GtkSizeRequestMode
gtk_box_layout_get_request_mode (GtkLayoutManager *layout_manager,
GtkWidget *widget)
{
GtkBoxLayout *self = GTK_BOX_LAYOUT (layout_manager);
return self->orientation == GTK_ORIENTATION_HORIZONTAL
? GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT
: GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
}
static void
gtk_box_layout_compute_size (GtkBoxLayout *self,
GtkWidget *widget,
int for_size,
int *minimum,
int *natural)
{
GtkWidget *child;
int n_visible_children = 0;
int required_min = 0, required_nat = 0;
int largest_min = 0, largest_nat = 0;
int spacing = get_spacing (self, _gtk_widget_get_style_context (widget));
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
int child_min = 0;
int child_nat = 0;
if (!_gtk_widget_get_visible (child))
continue;
gtk_widget_measure (child, self->orientation,
for_size,
&child_min, &child_nat,
NULL, NULL);
largest_min = MAX (largest_min, child_min);
largest_nat = MAX (largest_nat, child_nat);
required_min += child_min;
required_nat += child_nat;
n_visible_children += 1;
}
if (n_visible_children > 0)
{
if (self->homogeneous)
{
required_min = largest_min * n_visible_children;
required_nat = largest_nat * n_visible_children;
}
required_min += (n_visible_children - 1) * spacing;
required_nat += (n_visible_children - 1) * spacing;
}
if (minimum != NULL)
*minimum = required_min;
if (natural != NULL)
*natural = required_nat;
}
static void
gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
GtkWidget *widget,
int for_size,
int *minimum,
int *natural,
int *min_baseline,
int *nat_baseline)
{
GtkWidget *child;
int nvis_children;
int nexpand_children;
int computed_minimum = 0, computed_natural = 0;
int computed_minimum_above = 0, computed_natural_above = 0;
int computed_minimum_below = 0, computed_natural_below = 0;
int computed_minimum_baseline = -1, computed_natural_baseline = -1;
GtkRequestedSize *sizes;
int extra_space, size_given_to_child, i;
int children_minimum_size = 0;
int child_size, child_minimum, child_natural;
int child_minimum_baseline, child_natural_baseline;
int n_extra_widgets = 0;
int spacing;
gboolean have_baseline;
count_expand_children (widget, self->orientation, &nvis_children, &nexpand_children);
if (nvis_children <= 0)
return;
spacing = get_spacing (self, _gtk_widget_get_style_context (widget));
sizes = g_newa (GtkRequestedSize, nvis_children);
extra_space = MAX (0, for_size - (nvis_children - 1) * spacing);
/* Retrieve desired size for visible children */
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (_gtk_widget_get_visible (child))
{
gtk_widget_measure (child,
self->orientation,
-1,
&sizes[i].minimum_size, &sizes[i].natural_size,
NULL, NULL);
children_minimum_size += sizes[i].minimum_size;
i += 1;
}
}
if (self->homogeneous)
{
/* We still need to run the above loop to populate the minimum sizes for
* children that aren't going to fill.
*/
size_given_to_child = extra_space / nvis_children;
n_extra_widgets = extra_space % nvis_children;
}
else
{
/* Bring children up to size first */
extra_space -= children_minimum_size;
extra_space = MAX (0, extra_space);
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
/* Calculate space which hasn't distributed yet,
* and is available for expanding children.
*/
if (nexpand_children > 0)
{
size_given_to_child = extra_space / nexpand_children;
n_extra_widgets = extra_space % nexpand_children;
}
else
{
size_given_to_child = 0;
}
}
have_baseline = FALSE;
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
/* If widget is not visible, skip it. */
if (!_gtk_widget_get_visible (child))
continue;
/* Assign the child's size. */
if (self->homogeneous)
{
child_size = size_given_to_child;
if (n_extra_widgets > 0)
{
child_size++;
n_extra_widgets--;
}
}
else
{
child_size = sizes[i].minimum_size;
if (gtk_widget_compute_expand (child, self->orientation))
{
child_size += size_given_to_child;
if (n_extra_widgets > 0)
{
child_size++;
n_extra_widgets--;
}
}
}
child_minimum_baseline = child_natural_baseline = -1;
/* Assign the child's position. */
gtk_widget_measure (child,
OPPOSITE_ORIENTATION (self->orientation),
child_size,
&child_minimum, &child_natural,
&child_minimum_baseline, &child_natural_baseline);
if (child_minimum_baseline >= 0)
{
have_baseline = TRUE;
computed_minimum_below = MAX (computed_minimum_below, child_minimum - child_minimum_baseline);
computed_natural_below = MAX (computed_natural_below, child_natural - child_natural_baseline);
computed_minimum_above = MAX (computed_minimum_above, child_minimum_baseline);
computed_natural_above = MAX (computed_natural_above, child_natural_baseline);
}
else
{
computed_minimum = MAX (computed_minimum, child_minimum);
computed_natural = MAX (computed_natural, child_natural);
}
i += 1;
}
if (have_baseline)
{
computed_minimum = MAX (computed_minimum, computed_minimum_below + computed_minimum_above);
computed_natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
switch (self->baseline_position)
{
case GTK_BASELINE_POSITION_TOP:
computed_minimum_baseline = computed_minimum_above;
computed_natural_baseline = computed_natural_above;
break;
case GTK_BASELINE_POSITION_CENTER:
computed_minimum_baseline = computed_minimum_above + MAX((computed_minimum - (computed_minimum_above + computed_minimum_below)) / 2, 0);
computed_natural_baseline = computed_natural_above + MAX((computed_natural - (computed_natural_above + computed_natural_below)) / 2, 0);
break;
case GTK_BASELINE_POSITION_BOTTOM:
computed_minimum_baseline = computed_minimum - computed_minimum_below;
computed_natural_baseline = computed_natural - computed_natural_below;
break;
default:
break;
}
}
if (minimum != NULL)
*minimum = computed_minimum;
if (natural != NULL)
*natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
if (min_baseline != NULL)
*min_baseline = computed_minimum_baseline;
if (nat_baseline != NULL)
*nat_baseline = computed_natural_baseline;
}
static void
gtk_box_layout_measure (GtkLayoutManager *layout_manager,
GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *min_baseline,
int *nat_baseline)
{
GtkBoxLayout *self = GTK_BOX_LAYOUT (layout_manager);
if (self->orientation != orientation)
{
gtk_box_layout_compute_opposite_size (self, widget, for_size,
minimum, natural,
min_baseline, nat_baseline);
}
else
{
gtk_box_layout_compute_size (self, widget, for_size,
minimum, natural);
}
}
static void
gtk_box_layout_allocate (GtkLayoutManager *layout_manager,
GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkBoxLayout *self = GTK_BOX_LAYOUT (layout_manager);
GtkWidget *child;
gint nvis_children;
gint nexpand_children;
GtkTextDirection direction;
GtkAllocation child_allocation;
GtkRequestedSize *sizes;
gint child_minimum_baseline, child_natural_baseline;
gint minimum_above, natural_above;
gint minimum_below, natural_below;
gboolean have_baseline;
gint extra_space;
gint children_minimum_size = 0;
gint size_given_to_child;
gint n_extra_widgets = 0; /* Number of widgets that receive 1 extra px */
gint x = 0, y = 0, i;
gint child_size;
gint spacing;
count_expand_children (widget, self->orientation, &nvis_children, &nexpand_children);
/* If there is no visible child, simply return. */
if (nvis_children <= 0)
return;
direction = _gtk_widget_get_direction (widget);
sizes = g_newa (GtkRequestedSize, nvis_children);
spacing = get_spacing (self, _gtk_widget_get_style_context (widget));
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
extra_space = width - (nvis_children - 1) * spacing;
else
extra_space = height - (nvis_children - 1) * spacing;
have_baseline = FALSE;
minimum_above = natural_above = 0;
minimum_below = natural_below = 0;
/* Retrieve desired size for visible children. */
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (!_gtk_widget_get_visible (child))
continue;
gtk_widget_measure (child,
self->orientation,
self->orientation == GTK_ORIENTATION_HORIZONTAL ? height : width,
&sizes[i].minimum_size, &sizes[i].natural_size,
NULL, NULL);
children_minimum_size += sizes[i].minimum_size;
sizes[i].data = child;
i++;
}
if (self->homogeneous)
{
/* We still need to run the above loop to populate the minimum sizes for
* children that aren't going to fill.
*/
size_given_to_child = extra_space / nvis_children;
n_extra_widgets = extra_space % nvis_children;
}
else
{
/* Bring children up to size first */
extra_space -= children_minimum_size;
extra_space = MAX (0, extra_space);
extra_space = gtk_distribute_natural_allocation (extra_space, nvis_children, sizes);
/* Calculate space which hasn't distributed yet,
* and is available for expanding children.
*/
if (nexpand_children > 0)
{
size_given_to_child = extra_space / nexpand_children;
n_extra_widgets = extra_space % nexpand_children;
}
else
{
size_given_to_child = 0;
}
}
/* Allocate child sizes. */
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
/* If widget is not visible, skip it. */
if (!_gtk_widget_get_visible (child))
continue;
/* Assign the child's size. */
if (self->homogeneous)
{
child_size = size_given_to_child;
if (n_extra_widgets > 0)
{
child_size++;
n_extra_widgets--;
}
}
else
{
child_size = sizes[i].minimum_size;
if (gtk_widget_compute_expand (child, self->orientation))
{
child_size += size_given_to_child;
if (n_extra_widgets > 0)
{
child_size++;
n_extra_widgets--;
}
}
}
sizes[i].natural_size = child_size;
if (self->orientation == GTK_ORIENTATION_HORIZONTAL &&
gtk_widget_get_valign (child) == GTK_ALIGN_BASELINE)
{
int child_allocation_width;
int child_minimum_height, child_natural_height;
child_allocation_width = child_size;
child_minimum_baseline = -1;
child_natural_baseline = -1;
gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL,
child_allocation_width,
&child_minimum_height, &child_natural_height,
&child_minimum_baseline, &child_natural_baseline);
if (child_minimum_baseline >= 0)
{
have_baseline = TRUE;
minimum_below = MAX (minimum_below, child_minimum_height - child_minimum_baseline);
natural_below = MAX (natural_below, child_natural_height - child_natural_baseline);
minimum_above = MAX (minimum_above, child_minimum_baseline);
natural_above = MAX (natural_above, child_natural_baseline);
}
}
i++;
}
if (self->orientation == GTK_ORIENTATION_VERTICAL)
baseline = -1;
/* we only calculate our own baseline if we don't get one passed from the parent
* and any of the child widgets explicitly request one */
if (baseline == -1 && have_baseline)
{
/* TODO: This is purely based on the minimum baseline, when things fit we should
use the natural one? */
switch (self->baseline_position)
{
case GTK_BASELINE_POSITION_TOP:
baseline = minimum_above;
break;
case GTK_BASELINE_POSITION_CENTER:
baseline = minimum_above + (height - (minimum_above + minimum_below)) / 2;
break;
case GTK_BASELINE_POSITION_BOTTOM:
baseline = height - minimum_below;
break;
default:
break;
}
}
/* Allocate child positions. */
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
{
child_allocation.y = 0;
child_allocation.height = height;
x = 0;
}
else
{
child_allocation.x = 0;
child_allocation.width = width;
y = 0;
}
for (i = 0, child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
/* If widget is not visible, skip it. */
if (!_gtk_widget_get_visible (child))
continue;
child_size = sizes[i].natural_size;
/* Assign the child's position. */
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
{
child_allocation.width = child_size;
child_allocation.x = x;
x += child_size + spacing;
if (direction == GTK_TEXT_DIR_RTL)
child_allocation.x = width - child_allocation.x - child_allocation.width;
}
else /* (self->orientation == GTK_ORIENTATION_VERTICAL) */
{
child_allocation.height = child_size;
child_allocation.y = y;
y += child_size + spacing;
}
gtk_widget_size_allocate (child, &child_allocation, baseline);
i++;
}
}
static void
gtk_box_layout_class_init (GtkBoxLayoutClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass);
gobject_class->set_property = gtk_box_layout_set_property;
gobject_class->get_property = gtk_box_layout_get_property;
layout_manager_class->get_request_mode = gtk_box_layout_get_request_mode;
layout_manager_class->measure = gtk_box_layout_measure;
layout_manager_class->allocate = gtk_box_layout_allocate;
/**
* GtkBoxLayout:homogeneous:
*
* Whether the box layout should distribute the available space
* homogeneously among the children of the widget using it as a
* layout manager.
*/
box_layout_props[PROP_HOMOGENEOUS] =
g_param_spec_boolean ("homogeneous",
P_("Homogeneous"),
P_("Distribute space homogeneously"),
FALSE,
GTK_PARAM_READWRITE |
G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkBoxLayout:spacing:
*
* The space between each child of the widget using the box
* layout as its layout manager.
*/
box_layout_props[PROP_SPACING] =
g_param_spec_int ("spacing",
P_("Spacing"),
P_("Spacing between widgets"),
0, G_MAXINT, 0,
GTK_PARAM_READWRITE |
G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkBoxLayout:baseline-position:
*
* The position of the allocated baseline within the extra space
* allocated to each child of the widget using a box layout
* manager.
*
* This property is only relevant for horizontal layouts containing
* at least one child with a baseline alignment.
*/
box_layout_props[PROP_BASELINE_POSITION] =
g_param_spec_enum ("baseline-position",
P_("Baseline position"),
P_("The position of the baseline aligned widgets if extra space is available"),
GTK_TYPE_BASELINE_POSITION,
GTK_BASELINE_POSITION_CENTER,
GTK_PARAM_READWRITE |
G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (gobject_class, N_PROPS, box_layout_props);
g_object_class_override_property (gobject_class, PROP_ORIENTATION, "orientation");
}
static void
gtk_box_layout_init (GtkBoxLayout *self)
{
self->homogeneous = FALSE;
self->spacing = 0;
self->orientation = GTK_ORIENTATION_HORIZONTAL;
self->baseline_position = GTK_BASELINE_POSITION_CENTER;
}
GtkLayoutManager *
gtk_box_layout_new (GtkOrientation orientation)
{
return g_object_new (GTK_TYPE_BOX_LAYOUT,
"orientation", orientation,
NULL);
}
void
gtk_box_layout_set_homogeneous (GtkBoxLayout *box_layout,
gboolean homogeneous)
{
g_return_if_fail (GTK_IS_BOX_LAYOUT (box_layout));
homogeneous = !!homogeneous;
if (box_layout->homogeneous == homogeneous)
return;
box_layout->homogeneous = homogeneous;
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (box_layout));
g_object_notify_by_pspec (G_OBJECT (box_layout), box_layout_props[PROP_HOMOGENEOUS]);
}
gboolean
gtk_box_layout_get_homogeneous (GtkBoxLayout *box_layout)
{
g_return_val_if_fail (GTK_IS_BOX_LAYOUT (box_layout), FALSE);
return box_layout->homogeneous;
}
void
gtk_box_layout_set_spacing (GtkBoxLayout *box_layout,
guint spacing)
{
g_return_if_fail (GTK_IS_BOX_LAYOUT (box_layout));
if (box_layout->spacing == spacing)
return;
box_layout->spacing = spacing;
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (box_layout));
g_object_notify_by_pspec (G_OBJECT (box_layout), box_layout_props[PROP_SPACING]);
}
guint
gtk_box_layout_get_spacing (GtkBoxLayout *box_layout)
{
g_return_val_if_fail (GTK_IS_BOX_LAYOUT (box_layout), 0);
return box_layout->spacing;
}
/**
* gtk_box_layout_set_baseline_position:
* @box_layout: a #GtkBoxLayout
* @position: a #GtkBaselinePosition
*
* Sets the baseline position of a box layout.
*
* The baseline position affects only horizontal boxes with at least one
* baseline aligned child. If there is more vertical space available than
* requested, and the baseline is not allocated by the parent then the
* given @position is used to allocate the baseline within the extra
* space available.
*/
void
gtk_box_layout_set_baseline_position (GtkBoxLayout *box_layout,
GtkBaselinePosition position)
{
g_return_if_fail (GTK_IS_BOX_LAYOUT (box_layout));
if (box_layout->baseline_position != position)
{
box_layout->baseline_position = position;
g_object_notify_by_pspec (G_OBJECT (box_layout), box_layout_props[PROP_BASELINE_POSITION]);
gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (box_layout));
}
}
/**
* gtk_box_layout_get_baseline_position:
* @box_layout: a #GtkBoxLayout
*
* Gets the value set by gtk_box_layout_set_baseline_position().
*
* Returns: the baseline position
*/
GtkBaselinePosition
gtk_box_layout_get_baseline_position (GtkBoxLayout *box_layout)
{
g_return_val_if_fail (GTK_IS_BOX_LAYOUT (box_layout), GTK_BASELINE_POSITION_CENTER);
return box_layout->baseline_position;
}
+54
View File
@@ -0,0 +1,54 @@
/* gtkboxlayout.h: Box layout manager
*
* Copyright 2019 GNOME Foundation
*
* 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/>.
*/
#pragma once
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkenums.h>
#include <gtk/gtklayoutmanager.h>
G_BEGIN_DECLS
#define GTK_TYPE_BOX_LAYOUT (gtk_box_layout_get_type())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkBoxLayout, gtk_box_layout, GTK, BOX_LAYOUT, GtkLayoutManager)
GDK_AVAILABLE_IN_ALL
GtkLayoutManager * gtk_box_layout_new (GtkOrientation orientation);
GDK_AVAILABLE_IN_ALL
void gtk_box_layout_set_homogeneous (GtkBoxLayout *box_layout,
gboolean homogeneous);
GDK_AVAILABLE_IN_ALL
gboolean gtk_box_layout_get_homogeneous (GtkBoxLayout *box_layout);
GDK_AVAILABLE_IN_ALL
void gtk_box_layout_set_spacing (GtkBoxLayout *box_layout,
guint spacing);
GDK_AVAILABLE_IN_ALL
guint gtk_box_layout_get_spacing (GtkBoxLayout *box_layout);
GDK_AVAILABLE_IN_ALL
void gtk_box_layout_set_baseline_position (GtkBoxLayout *box_layout,
GtkBaselinePosition position);
GDK_AVAILABLE_IN_ALL
GtkBaselinePosition gtk_box_layout_get_baseline_position (GtkBoxLayout *box_layout);
G_END_DECLS
-1
View File
@@ -356,7 +356,6 @@ color_picked (GObject *source,
color = gtk_color_picker_pick_finish (picker, res, &error);
if (color == NULL)
{
g_warning ("Picking color failed: %s", error->message);
g_error_free (error);
}
else
+2 -128
View File
@@ -23,8 +23,6 @@
#include "gtkcssstylepropertyprivate.h"
#include "gtkhslaprivate.h"
#include "gtkstylepropertyprivate.h"
#include "gtkwin32drawprivate.h"
#include "gtkwin32themeprivate.h"
#include "gtkprivate.h"
@@ -34,7 +32,6 @@ typedef enum {
COLOR_TYPE_SHADE,
COLOR_TYPE_ALPHA,
COLOR_TYPE_MIX,
COLOR_TYPE_WIN32,
COLOR_TYPE_CURRENT_COLOR
} ColorType;
@@ -60,12 +57,6 @@ struct _GtkCssValue
GtkCssValue *color2;
gdouble factor;
} mix;
struct
{
GtkWin32Theme *theme;
gint id;
} win32;
} sym_col;
};
@@ -90,9 +81,6 @@ gtk_css_value_color_free (GtkCssValue *color)
_gtk_css_value_unref (color->sym_col.mix.color1);
_gtk_css_value_unref (color->sym_col.mix.color2);
break;
case COLOR_TYPE_WIN32:
gtk_win32_theme_unref (color->sym_col.win32.theme);
break;
case COLOR_TYPE_LITERAL:
case COLOR_TYPE_CURRENT_COLOR:
default:
@@ -240,18 +228,6 @@ _gtk_css_color_value_resolve (GtkCssValue *color,
value =_gtk_css_rgba_value_new_from_rgba (&res);
}
break;
case COLOR_TYPE_WIN32:
{
GdkRGBA res;
gtk_win32_theme_get_color (color->sym_col.win32.theme,
color->sym_col.win32.id,
&res);
value = _gtk_css_rgba_value_new_from_rgba (&res);
}
break;
case COLOR_TYPE_CURRENT_COLOR:
if (current)
@@ -350,9 +326,6 @@ gtk_css_value_color_equal (const GtkCssValue *value1,
value2->sym_col.mix.color1) &&
_gtk_css_value_equal (value1->sym_col.mix.color2,
value2->sym_col.mix.color2);
case COLOR_TYPE_WIN32:
return gtk_win32_theme_equal (value1->sym_col.win32.theme, value2->sym_col.win32.theme) &&
value1->sym_col.win32.id == value2->sym_col.win32.id;
case COLOR_TYPE_CURRENT_COLOR:
return TRUE;
default:
@@ -421,20 +394,6 @@ gtk_css_value_color_print (const GtkCssValue *value,
g_string_append (string, ")");
}
break;
case COLOR_TYPE_WIN32:
{
const char *name;
g_string_append (string, GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME"(");
gtk_win32_theme_print (value->sym_col.win32.theme, string);
g_string_append (string, ", ");
name = gtk_win32_get_sys_color_name_for_id (value->sym_col.win32.id);
if (name)
g_string_append (string, name);
else
g_string_append_printf (string, "%d", value->sym_col.win32.id);
g_string_append (string, ")");
}
break;
case COLOR_TYPE_CURRENT_COLOR:
g_string_append (string, "currentColor");
break;
@@ -543,38 +502,6 @@ _gtk_css_color_value_new_mix (GtkCssValue *color1,
return value;
}
static GtkCssValue *
gtk_css_color_value_new_win32_for_theme (GtkWin32Theme *theme,
gint id)
{
GtkCssValue *value;
gtk_internal_return_val_if_fail (theme != NULL, NULL);
value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_COLOR);
value->type = COLOR_TYPE_WIN32;
value->sym_col.win32.theme = gtk_win32_theme_ref (theme);
value->sym_col.win32.id = id;
return value;
}
GtkCssValue *
_gtk_css_color_value_new_win32 (const gchar *theme_class,
gint id)
{
GtkWin32Theme *theme;
GtkCssValue *value;
gtk_internal_return_val_if_fail (theme_class != NULL, NULL);
theme = gtk_win32_theme_lookup (theme_class);
value = gtk_css_color_value_new_win32_for_theme (theme, id);
gtk_win32_theme_unref (theme);
return value;
}
GtkCssValue *
_gtk_css_color_value_new_current_color (void)
{
@@ -590,54 +517,9 @@ typedef enum {
COLOR_DARKER,
COLOR_SHADE,
COLOR_ALPHA,
COLOR_MIX,
COLOR_WIN32
COLOR_MIX
} ColorParseType;
static GtkCssValue *
gtk_css_color_parse_win32 (GtkCssParser *parser)
{
GtkCssValue *color;
GtkWin32Theme *theme;
char *name;
int id;
theme = gtk_win32_theme_parse (parser);
if (theme == NULL)
return NULL;
if (! _gtk_css_parser_try (parser, ",", TRUE))
{
gtk_win32_theme_unref (theme);
_gtk_css_parser_error (parser,
"Expected ','");
return NULL;
}
name = _gtk_css_parser_try_ident (parser, TRUE);
if (name)
{
id = gtk_win32_get_sys_color_id_for_name (name);
if (id == -1)
{
_gtk_css_parser_error (parser, "'%s' is not a win32 color name.", name);
g_free (name);
return NULL;
}
g_free (name);
}
else if (!_gtk_css_parser_try_int (parser, &id))
{
gtk_win32_theme_unref (theme);
_gtk_css_parser_error (parser, "Expected a valid integer value");
return NULL;
}
color = gtk_css_color_value_new_win32_for_theme (theme, id);
gtk_win32_theme_unref (theme);
return color;
}
static GtkCssValue *
_gtk_css_color_value_parse_function (GtkCssParser *parser,
ColorParseType color)
@@ -704,12 +586,6 @@ _gtk_css_color_value_parse_function (GtkCssParser *parser,
value = _gtk_css_color_value_new_literal (&rgba);
}
else if (color == COLOR_WIN32)
{
value = gtk_css_color_parse_win32 (parser);
if (value == NULL)
return NULL;
}
else
{
child1 = _gtk_css_color_value_parse (parser);
@@ -775,7 +651,6 @@ _gtk_css_color_value_parse_function (GtkCssParser *parser,
break;
case COLOR_RGB:
case COLOR_RGBA:
case COLOR_WIN32:
default:
g_assert_not_reached ();
value = NULL;
@@ -802,8 +677,7 @@ _gtk_css_color_value_parse (GtkCssParser *parser)
GtkCssValue *value;
GdkRGBA rgba;
guint color;
const char *names[] = {"rgba", "rgb", "lighter", "darker", "shade", "alpha", "mix",
GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME};
const char *names[] = {"rgba", "rgb", "lighter", "darker", "shade", "alpha", "mix"};
char *name;
if (_gtk_css_parser_try (parser, "currentColor", TRUE))

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