Compare commits

..

91 Commits

Author SHA1 Message Date
Matthias Clasen
ba44668478 4.2.1 2021-05-03 21:37:09 -04:00
Matthias Clasen
2f921ab667 dragsource: Keep the source alive long enough
When a drop causes the event controller to be finalized
(directly or indirectly), we end up segfaulting while
trying to wrap up the drag operation. So, keep a reference
on the GtkDragSource from when the drag begins to when
it is done.

This fixes a crash in gnome-todo when dragging tasks.
2021-05-03 21:20:54 -04:00
Matthias Clasen
d9784df92e inspector: Improve monitor information display
Avoid a nested listbox, show the connector,
don't show information we don't have. Also,
disconnect all signal handlers from the display
when the inspector is going away.
2021-05-03 21:20:08 -04:00
Matthias Clasen
6a5f93ff95 shortcuts: Ignore consumed modifiers for mnemonics
This is necessary to make mnemonics like Alt-1 work in
layouts where numeric keys are shifted, like AZERTY.

Fixes: #3912
2021-05-03 21:19:43 -04:00
Matthias Clasen
7578a18cd6 contentdeserializer: Fix an oversight
The argument passed with string_deserializer must be
a charset name. Passing the mimetype there does not
make sense.
2021-05-03 21:19:28 -04:00
Ivan Molodetskikh
a5895b5995 gtkgstmediafile: Fix callback argument type 2021-05-03 21:19:14 -04:00
Matthias Clasen
37582c6bf9 wayland: Rewrite shm format debug spew
Rewrite this in a way that doesn't depend on kernel
header defines at the time the wayland scanner was run.

This was causing the build to break on Centos 8, where
a bunch of fourcc formats are missing.
2021-05-03 21:19:07 -04:00
Matthias Clasen
84f02c633c Check for root being a GtkWindow in a few places
These things were showing up as crashes during DND,
when the root is a GtkDragIcon. I'm sure there's more.
2021-05-03 21:18:59 -04:00
Bilal Elmoussaoui
fdb2776577 gdk: add zero-terminated annotation to content_formats_get_gtypes 2021-05-03 21:18:48 -04:00
Bilal Elmoussaoui
94539d469c gdk: fix content_formats_get_mime_types annotation 2021-05-03 21:18:42 -04:00
Chun-wei Fan
f6a2d8148b gdkglcontext-win32.c: Fix running with Mesa drivers
Some GL drivers such as Mesa-D3D12 do not allow one to call SetPixelFormat() on
a given HDC if one pixel format has been already set for it, so first check the
HDC with GetPixelFormat() to see whether a pixel format has already been set
with the HDC, and only attempt to acquire the pixel format if one has not been
set.

This will fix running with GL/NGL on Windows using the Mesa drivers.
2021-05-03 21:18:26 -04:00
Geyslan G. Bem
35e3eaf8cb gtkplacessidebar.c: fix coding style
Signed-off-by: Geyslan G. Bem <geyslan@gmail.com>
2021-05-03 21:18:20 -04:00
Emmanuele Bassi
2bc7b64004 docs: Add missing extra files for gdk4 sub-references
The Wayland and X11 references need the gtk-logo.svg and the urlmap.js
extra files.

Fixes: #3905
2021-05-03 21:18:03 -04:00
David Lechner
2df07f0564 gdk/wayland/cursor/os-compatibility: fix build when memfd_create is not available
When building for homebrew/linuxbrew on Ubuntu 16.04, memfd_create() is
not available and causes the build to fail.

This adds a proper check for the function.
2021-05-03 21:17:53 -04:00
Geyslan G. Bem
2d747cca3c gtkplacessidebar.c: add bookmark null checking
This fixes nautilus crash and perhaps other callers issues.
Nautilus (and sometimes glib) crashes with malformed URI inside of the
bookmarks file .config/gtk-3.0/bookmarks when it has no LABEL.

This is result from the closed glib MR #2065 analysis and agreement.
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2065#note_1091979

Signed-off-by: Geyslan G. Bem <geyslan@gmail.com>
2021-05-03 21:17:48 -04:00
Matthias Clasen
f795a75d2b x11: Try harder to find the right monitor
If we deal with a panel, we end up with no monitor,
and crash, which isn't great and isn't necessary.

Fixes: #3900
2021-05-03 21:17:37 -04:00
Benjamin Otte
8748d9511b clipboard: Fix reading of files
Make sure writing a terminating null byte actually works and we don't
just ignore the error message.
2021-05-03 21:17:27 -04:00
Benjamin Otte
0fe3a26122 clipboard: Make sure G_TYPE_STRING is nul-terminated
When reading text, we need to check we terminate the G_TYPE_STRING
string with a null byte, because the clipboard does not guarantee one.

So just append a \0 to the stream.

Fixes #3899
2021-05-03 21:17:21 -04:00
Matthias Clasen
9145365331 window: Don't let solid-csd linger
Just from reading the code, it seems that we
should unset .csd and .solid-csd at the same
time, since the are mutually exclusive and
we unset them here so realize() can set one
of them again.
2021-05-03 21:17:03 -04:00
Matthias Clasen
84295147fd Simplify shadow conditions
The code in gtkwindow.c for dealing with the various
combinations of client-side decorations and client-side
shadows is entirely too complicated.

This commit does not really clean it up, but simplifies
one of the shadow conditions far enough to make some
sense.

With this change, I get the expected decorations in
all the cases I can easily reproduce locally.
2021-05-03 21:16:55 -04:00
Matthias Clasen
7ec50b1dd3 x11: Fix shadows
Commit a2cd21cab6 changed a condition and inadvertedly
broke client-side shadows on X11. Change this back.

Fixes: #3896
2021-05-03 21:16:44 -04:00
Matthias Clasen
a5b4c2bb48 a11y: Don't sent redundant property changes
We were sending a property changed event for every set
property whenever we were sending any updates.
2021-05-03 21:16:35 -04:00
Matthias Clasen
d26a3c28d0 gdk: Avoid synthetic motion confusion
Don't emit a synthetic motion event on a surface
that is grab-shadowed by a popup. This has been
known to confuse GTK, at times.

Fixes: #3439
2021-05-03 21:16:22 -04:00
Matthias Clasen
e75df3dcd3 window: Make resize border size independent
Deriving the resize border size from the shadows
carries the risk that we might end up with uneven
resize borders (or none at all, on some sides).

So, justs enforce that we have a big enough shadow
width on all sides.
2021-05-03 21:12:16 -04:00
Ulli Kehrle
db5eef5a81 imcontextsimple: Ignore more modifiers in compose
Previously it was impossible to compose characters on higher levels of
some keyboard layouts as pressing the level selection key would just
exit compose mode.

Examples for affected keyboard layouts include the Latvian
apostrophe-variant "lv(apostrophe)" (latched third level), the extended
German keyboard layout "de(e1)" (latched fifth level) as well as the
multilingual Canadian keyboard layout "ca(multix)" and the German
neo-layout "de(neo)" and its descendants (shifted fifth level).

To reproduce, set a compose key and select the Latvian apostrophe layout.
Notice that you now can input [ by pressing first the ' and then the 8-key.
Then pressing <compose>'8'8 should produce ⟦, but prior to this patch it
did not.
2021-05-03 21:12:07 -04:00
Matthias Clasen
0b0d7d3877 window: Tweak resize borders
Make windows resizable in the padding and border
area of the css box as well. This naturally makes
solid-csd borders work again.
2021-05-03 21:12:01 -04:00
Matthias Clasen
10b302ac29 window: Fix up resize borders
The invisible resize borders have been wider than they
should, for a while. Go back to a size close to what
we have in GTK3.

To summarize: resize borders will be at most 12 pixels
on each size, but never wider than the windows shadow.
The resize corners have 'legs' of 24 pixels where you
still get a corner resize cursor.

Fixes: #3856
2021-05-03 21:11:53 -04:00
John Renner
f1bfbeba45 Allow repeated selection extension on gktlistbox 2021-05-03 21:11:46 -04:00
Emmanuele Bassi
ca405f1060 a11y: Update the labelled-by relation of GtkTreeExpander
Whenever we change the :child property, we need to update the
labelled-by relation.
2021-05-03 21:11:36 -04:00
Emmanuele Bassi
4baec1ef22 a11y: Set state on the GtkTreeExpander widget
Instead of setting it on its internal child.
2021-05-03 21:11:21 -04:00
Matthias Clasen
d35e069436 imcontext: Fix cursor positions
gtk_im_context_get_preedit_string is documented to
return the cursor position as a character offset,
not a byte count. So return that.

Fixed: #3885
2021-05-03 21:11:12 -04:00
Emmanuele Bassi
6a95ca6995 a11y: Pair window:activate with window:deactivate signal
Orca needs both events in order to decide whether or not to subscribe to
other event/state changes in a window.
2021-05-03 21:11:01 -04:00
Matthias Clasen
268c174506 x11: Don't beep on untrusted displays
This can trigger BadAccess, and we don't
want that.

Fixes: #3862
2021-05-03 21:10:56 -04:00
Matthias Clasen
7e3493b15e a11y: Realize notebook tabs when switching
We're not moving focus here, so we can't rely
on that to conjure the a11y objects into existence.
2021-05-03 21:10:46 -04:00
Alberts Muktupāvels
be65bab5f6 theme: fix solid-csd style
Move .solid-csd style out of .csd parent and adjust it so windows
look similar / same to GTK 3 windows:
- 4px padding.
- extra shadow.

https://gitlab.gnome.org/GNOME/gtk/-/issues/3879#note_1086351
https://gitlab.gnome.org/GNOME/gtk/-/issues/3879#note_1086377
2021-05-03 21:10:39 -04:00
Matthias Clasen
c04139405a a11y: Avoid spurious selection changed events
Only send selection-changed events when we either
had a non-empty selection before, or have one now.

This should help orca speak the right things, and
not the wrong things.

Related: #3549
2021-05-03 21:10:29 -04:00
Emmanuele Bassi
5fc008024b a11y: Emit window:activate event
Orca uses the window:activate event type to track top levels, and avoid
being spammed by events coming from non-focused windows.
2021-05-03 21:10:24 -04:00
Matthias Clasen
f6bec2edf2 stackswitcher: Set accessible label properties
This makes the tabs in about dialogs come out as
'About', 'Credits', and 'System', instead of
'Tab', 'Tab', 'Tab'.
2021-05-03 21:10:14 -04:00
Matthias Clasen
c1e68f6044 a11y: Emit focus events
Orca relies on these to keep track of the focus location,
ignoring the focused state. With this change, orca can
once again speak text in entries as I type.
2021-05-03 21:10:08 -04:00
Matthias Clasen
549e5a8e3a a11y: Make things appear on focus in
We are starting with a pretty empty a11y object tree,
and we want orca to bring more of it into existence
by navigating the tree. But that only happens when we
send it events. Primarily focus events, which come in
from GTK via the platform_change mechanism. So realize
the context when we are sending platform_changes,
otherwise, orca never gets the mesage.
2021-05-03 21:10:03 -04:00
Matthias Clasen
5783d8af91 Fix a possible crash in gtk_show_uri
g_file_get_basename can return NULL.
Deal with it somehow.

Fixes: #3883
2021-05-03 21:09:54 -04:00
Matthias Clasen
1926d91e1d a11y: Actually set accessible roles
With most context realization happening inside
GtkAtspiContext in response to D-Bus calls, the
code in gtk_widget_realize_at_context that sets
the role is not executed for most accessibles,
causing them to be stuck with the 'filler' role
that makes orca ignore them.

To fix this, split gtk_widget_realize_at_context
into the actual context realization (getting on
the bus) and the setting of widget-specific
properties, and do the latter part when the
widget is rooted.

This makes accerciser report proper roles for
entries and buttons. Orca still has an issue
with getting the hierarchy populated.
2021-05-03 21:08:11 -04:00
Matthias Clasen
0441101786 a11y: Track window states more closely
Orca ignores events unless the object is inside an object
with role window and states ACTIVE and SHOWING. To arrange
for this, introduce a new ACTIVE platform state, and set it
for windows when they are active.

This gets orca to be a lot more talkative.
2021-05-03 21:07:53 -04:00
Matthias Clasen
eb8fce3645 a11y: Add the root object to the cache
Not 100% sure this is necessary, but maybe it helps
to get orca up to speed.
2021-05-03 21:06:36 -04:00
Matthias Clasen
016294ba6e atspicontext: Remove an unused field
We don't make any use of the cache field, so drop it.
2021-05-03 21:06:31 -04:00
Jason Francis
b9ce81b912 meson: check for madvise() 2021-05-03 21:06:03 -04:00
Matthew Garrett
a9d0563085 gtksecurememory: Request that secure memory not be dumped to disk
Linux 3.4 added support for the MADV_DONTDUMP option to madvise(), which
requests that the covered memory not be included in coredumps. It makes
sense to use this to prevent cases where application crashes could
result in secrets being persisted to disk or included in dumps that are
uploaded to remote servers for analysis. I've avoided making this fatal
since there's a chance this code could be built on systems that have
MADV_DONTDUMP but run on systems that don't.
2021-05-03 21:05:57 -04:00
Matthias Clasen
e6bab9b64c placesview: Fix server mount feedback
We weren't properly resetting the in-entry progress.
2021-05-03 21:05:44 -04:00
Matthias Clasen
513aa20f76 placesview: Fix mounting remote locations
This was broken by a stupid copy-paste error.
2021-05-03 21:05:37 -04:00
Matthias Clasen
83b38e55c0 window: Fix deferred focus unsetting
In commit 4a76abffd4, we deferred unsetting focus
and default until after the next draw, overlooking the
case where the focus is set to another widget before we
ever get to the unsetting.

Fixes: #3413
2021-05-03 21:05:14 -04:00
Chun-wei Fan
22b23a6d19 GTK: Fix builds against latest stable GLib with MSVC
GLib-2.68.x now considers warning C4098 ('void' function returning a value) as
an error, so avoid doing that.
2021-05-03 21:05:04 -04:00
Chun-wei Fan
908f5dc142 GSK: Fix builds against latest stable GLib with MSVC
GLib-2.68.x now considers warning C4098 ('void' function returning a value) as
an error, so avoid doing that.
2021-05-03 21:04:58 -04:00
Chun-wei Fan
7ef493ec88 GDK: Fix builds against latest stable GLib with MSVC
GLib-2.68.x now considers warning C4098 ('void' function returning a value) as
an error, so avoid doing that.
2021-05-03 21:04:51 -04:00
Matthias Clasen
6edfd29df0 imcontext: Eat key events during preedit
Avoid passing through random key press or release
events while we are showing preedit. That prevents
'accidents' like typing Ctrl-. bringing up the
Emoji chooser during preedit, or hitting Ctrl-a
after the Compose key moving the 'dot' around in
vim in terminals.
2021-05-03 21:04:38 -04:00
nana-4
eabbc0ef30 theme: Use -gtk-icon-filter for full-color icons
Not for symbolic icons.

Don't apply `-gtk-icon-filter: opacity(0.5);` to the symbolic icons as
they already have the "gray" colors indicating the disabled state.
Symbolic icons can be styled using the `color` property.

Also remove the obsolete comment.
2021-05-03 21:04:26 -04:00
Eli Schwartz
bfcd5f4881 meson: only build demo manpages when demos are enabled
Installing them even when manpages are enabled, but the demos are
disabled, produces manpages for unavailable programs...
2021-05-03 21:04:13 -04:00
Matthias Clasen
201fc28a67 x11: Be quiet on exit by default
The condition we check for to catch X servers going away
may not be accurate anymore, and the warning shows up in
logs, causing customers to be concerned. So, be quiet by
default, unless the user explicitly asked for a message.
2021-05-03 21:04:02 -04:00
Ondrej Holy
0026f74dbe placesview: Open location even if mount was not found
Some locations have to be mounted, but their mounts are not user-visible
(e.g. smb-browse). Though this is maybe a bit weird, it is how it works
for years. The problem is that the commit 267ea755, which tries to get the
default location for opening, caused regression as it doesn't expect such
possibility. Before this commit, such locations were opened without any
issue, but nothing happens currently after clicking to "Connect" except of
clearing the "Connect to Server" entry. Let's fallback to the original
location if the mount was not found to fix this regression.

Fixes: https://gitlab.gnome.org/GNOME/nautilus/-/issues/1811
2021-05-03 21:03:56 -04:00
Matthias Clasen
d116ba348f ngl: Fix a rare assertion violation
When we clean up the uniform allocations after a frame,
it can happen that our space requirements actually increase,
due to padding that depends on the order of allocations.

Instead of asserting that it doesn't happen, just make
it work by growing our allocation.

Fixes: #3853
2021-05-03 21:03:40 -04:00
Matthias Clasen
06c0012dd4 togglebutton: Fix expected group behavior
The expectation is that a grouped button stays
active when you click it. Grouped check buttons
behave this way, and grouped toggle buttons should
too.
2021-05-03 21:02:53 -04:00
Matthias Clasen
7b84ffd378 icon browser: Make header buttons not steal focus
This is rarely useful, and is confusing when it
happens as side-effect of dragging the window.
2021-05-03 21:02:45 -04:00
Matthias Clasen
cc5d2f24e8 widget-factory: Make header buttons not steal focus
This is rarely useful, and is confusing when it
happens as side-effect of dragging the window.
2021-05-03 21:02:38 -04:00
Matthias Clasen
c06462aec0 gtk-demo: Make header buttons not steal focus
This is rarely useful, and is confusing when it
happens as side-effect of dragging the window.
2021-05-03 21:02:32 -04:00
Matthias Clasen
a4aaab2e5b menubutton: Propagate focus-on-click
Propagate the focus-on-click setting to the button
inside, so that setting menubuttons as !focus-on-click
works as expected. This helps for menubuttons in
header bars, where dragging on the button will otherwise
steal focus from the content.
2021-05-03 21:02:26 -04:00
Matthias Clasen
fe237c4030 roundedrect: Speed up contains_rect and friends
gsk_rounded_rect_contains_rect was calling
gsk_rounded_rect_contains_point, which potentially
checks all four corners, for a total of up to 16
corner/point checks. But there is no need to do
more than 4 such checks to answer the question.
2021-05-03 21:02:08 -04:00
Matthias Clasen
ff8f32bf10 nodeeditor: Make the help window wide enough
Make the help window wide enough to show the
tables without wrapping.
2021-05-03 21:01:54 -04:00
Matthias Clasen
8a8edde78d media: Fix a memory leak
This was introduced in e7dc82fa32.
2021-05-03 21:01:46 -04:00
Matthias Clasen
3852512446 gsk: Don't overshadow
Reduce the cairo shadows to the same size as their GL brethren.
2021-05-03 21:01:39 -04:00
Matthias Clasen
c926f9491a window: Defer focus setting until after paint
Commit 3dbf5038fa tried to defer focus changes
until after rendering is done. But it failed to do so, since
the toplevel ::render handler is still before rendering of
popups that are attached to that toplevel. To do this
properly, we need to do it in the AFTER_PAINT frame clock
phase.

Fixes: #3725
2021-05-03 21:01:28 -04:00
Matthias Clasen
03176fe23c scrolledwindow: Stop using scroll cursors
We used to override cursor to use all-scroll while the
content is being scrolled. Unfortunately, there is several
problems with this:
- It is really only expected certain devices, and we don't
  have the device information on Wayland
- With the way cursor setting works in GTK4, non-NULL cursors
  of the content (eg the text views ibeam) win, making the
  scroll cursor not show up
- Under X11, we seem to miss scroll end events and then
  the scroll cursor gets stuck
Therefore, just remove this feature.
2021-05-03 21:01:13 -04:00
Matthias Clasen
d0cb76fff4 ngl: Fix an oversight
All the rest of debug spew goes to stderr here.
2021-05-03 21:00:57 -04:00
Matthias Clasen
d76e106382 wayland: Improve font setting fallback more
We may get a response from the portal that contains
no useful settings at all. In that case, we should
fallback as well.

Fixes: #3838
2021-05-03 21:00:32 -04:00
Carlos Garnacho
f7ab0b19c7 surface: Always set PHASE_PAINT as pending when updates are scheduled
At times (most often when closing subsurfaces that are scheduling
relayouts) the PHASE_PAINT handling gets broken with the following
sequence:

1. Surface receives wl_callback.done for the previous frame.
   Surface is thawed.
2. A new update on the surface is scheduled. PHASE_PAINT is
   requested directly on the frame clock. priv->pending_phase is
   left unset in the surface.
3. Surface gets frozen
4. Frame clock processes the update scheduled at 2. The surface
   is frozen, so paint is prevented. PHASE_PAINT is considered
   handled.
5. Compositor emits wl_callback.done again. Surface is thawed.
6. At this point the machinery is off
   - The surface didn't paint but has pending update regions
   - priv->draw_needed is set in the toplevel and other portions
     of the widget tree
   - So queueing redraws is ineffective at eventually calling
     gdk_surface_schedule_update() again on the toplevel surface.
   - We don't paint anymore, so this broken state is not flushed
     until other subsurface changes manage to schedule the missing
     update.

To fix this, always set PHASE_PAINT in priv->pending_phase when
doing gdk_surface_schedule_update(). If the frame clock turns
around before the surface is thawed, it will still be waiting to
be processed the next iteration.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3750
2021-05-03 21:00:19 -04:00
Emmanuele Bassi
b50df28e38 Install documentation in the appropriate place
We're already installing each reference into its own namespaced
directory, so we don't need to add further path elements.

Additionally, with the changes in:

  https://gitlab.gnome.org/GNOME/devhelp/-/merge_requests/20
  https://gitlab.gnome.org/GNOME/gi-docgen/-/merge_requests/54

we can browse the GTK API references in DevHelp.
2021-05-03 21:00:06 -04:00
Matthias Clasen
f97d32e253 wayland: Improve font setting fallback
When we don't get stettings from the portal, the current
fallback is 'awful fonts'. There is no need for that. Instead,
set the fallback values to grayscale antialiasing with slight
hinting.
2021-05-03 20:59:46 -04:00
Matthias Clasen
b7a0744324 modelbutton: Avoid a crash
We may not have a popover menu ancestor. The check for
this was forgotten in one of the branches here.

Fixes: #3831
2021-05-03 20:59:32 -04:00
Matthias Clasen
3ef8ff2a43 window: Actually enable the inspector by default
427d216081 changed the default in the schema,
but didn't handle cases where the schema isn't found.
2021-05-03 20:59:25 -04:00
Matthias Clasen
b4844e2ace ngl: Fix an oversight
We were special-casing 2D affine transforms,
but overlooked even simpler transforms.
2021-05-03 20:59:16 -04:00
Matthias Clasen
610f5ce75c settings: Make font-size changes apply immediately
We need to invalidate the style when font-size changes,
because we propagate this value through the initial
value of the CSS font-size property, and it will not
be recomputed otherwise.
2021-05-03 20:58:20 -04:00
Matthias Clasen
3c4c7896fc immulticontext: Unset client widget on delegate change
Forgetting to do so was causing the Wayland im context
to leave behind a dead event controller. This was showing
up as a crash when closing the inspector after changing
the im-module property of a GtkText widget. The crash
was delayed until closing the inspector because the
inspector keeps a ref on the event controllers of the
currently shown widget.
2021-05-03 20:58:13 -04:00
Matthias Clasen
686752a852 comboboxtext: Remove misleading docs
The entry is no longer accessible.
The docs were outdated.

Fixes: #3824
2021-05-03 20:57:38 -04:00
Matthias Clasen
8bb1b8da57 ngl: Avoid huge intermediate textures
Instead of rendering the unclipped child to a texture
(and risking blowing the texture size limit, and bad
downscaling), just render the clipped region, and live
with the fact that we can't cache the rendered texture.

This avoid bad artifacts when scrolling long textviews
in rounded clips.
2021-05-03 20:57:16 -04:00
Matthias Clasen
1b81af591d ngl: Plug a memory leak
This was introduced in f9457af128.
2021-05-03 20:57:10 -04:00
Matthias Clasen
88a8287c1d ngl: Fix downscaled textures
It is not pretty, but at least it works now.
2021-05-03 20:57:05 -04:00
Chris Mayo
8cc2dbe6f8 button: Style .keyboard-activating on frameless buttons
The use of the keyboard-activating CSS class for buttons was added
in [1], but the style did not apply to buttons with has-frame=FALSE.

[1] 00923615f4 ("button: Add back visual feedback for keynav", 2021-04-01)
2021-05-03 20:56:56 -04:00
Matthias Clasen
aec29503bf fontchooser: Fix initial font selection
The change in 740559a54f to populate the list incrementally
broke initial font selection. Fix that, by trying to select
until the incremental filling is done.

Fixes: #3687
2021-05-03 20:56:36 -04:00
Matthias Clasen
1506a41448 button: Add back visual feedback for keynav
We lost the visual feedback for activating a button
via Space or Enter when the :active pseudo-state became
managed. Bring it back with a style class.

Fixes: #3813
2021-05-03 20:56:01 -04:00
Matthias Clasen
63622923f0 Add one more compose test 2021-05-03 20:55:56 -04:00
Matthias Clasen
59c87b8387 Add more compose tests
Test the sequences whose demise made people
unhappy.
2021-05-03 20:55:46 -04:00
Matthias Clasen
fdf71e13c4 Revert Compose sequence changes
This was breaking muscle memory of people with
the us intl keyboard layout, for important keys
such as '. The unfortunate side-effect is that
our handling of <dead_acute> is a bit hampered
by sequences that don't fit the pattern. But
such is life.

Fixes: #3807
2021-05-03 20:55:32 -04:00
Chris Mayo
5d49dabade docs: Escape tags in GtkBuilder description
Fixes the tags and the rest of the gi-docgen created HTML page not being
visible in a browser.
2021-05-03 20:55:24 -04:00
2216 changed files with 260105 additions and 309734 deletions

View File

@@ -1,32 +0,0 @@
# SPDX-FileCopyrightText: 2021 The GTK Authors
# SPDX-License-Identifier: CC0-1.0
root = true
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
[*.[ch]]
indent_size = 2
indent_style = space
insert_final_newline = true
# For the legacy tabs which still exist in the code:
tab_width = 8
[*.ui]
indent_size = 2
indent_style = space
insert_final_newline = true
[*.xml]
indent_size = 2
indent_style = space
[meson.build]
indent_size = 2
indent_style = space
[*.md]
max_line_length = 80

View File

@@ -7,7 +7,6 @@ stages:
- analysis
- docs
- flatpak
- publish
- deploy
.cache-paths: &cache-paths
@@ -25,8 +24,9 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v36"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v28"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v27"
.only-default:
only:
@@ -58,10 +58,8 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/report*.xml"
- "${CI_PROJECT_DIR}/_build/report*.html"
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
cache:
key: "$CI_JOB_NAME"
paths:
@@ -79,19 +77,12 @@ fedora-x86_64:
variables:
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
script:
- .gitlab-ci/show-info-linux.sh
- meson subprojects update
- mkdir _install
- meson --prefix=${CI_PROJECT_DIR}/_install
${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
_build
- meson compile -C _build
- meson install -C _build
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- ninja -C _build
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build waylandgles
- .gitlab-ci/run-tests.sh _build broadway
release-build:
@@ -101,7 +92,6 @@ release-build:
variables:
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- .gitlab-ci/show-info-linux.sh
- meson subprojects update
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
_build
@@ -116,7 +106,6 @@ installed-tests:
EXTRA_MESON_FLAGS: "--prefix=/usr --libdir=/usr/lib64 -Dinstall-tests=true"
G_TEST_ACCESSIBLE: 1
script:
- .gitlab-ci/show-info-linux.sh
- meson subprojects update
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
_build
@@ -156,11 +145,6 @@ msys2-mingw64:
variables:
MSYSTEM: "MINGW64"
CHERE_INVOKING: "yes"
artifacts:
when: always
expose_as: 'Windows_DLL_MSYS2_64_bit_toolchain'
paths:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos:
extends: .only-default
@@ -171,16 +155,13 @@ macos:
- macos
needs: []
before_script:
- bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson==0.59
- bash .gitlab-ci/show-execution-environment.sh
- pip3 install --user meson==0.56
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
script:
- meson -Dx11-backend=false
-Dbroadway-backend=true
-Dmacos-backend=true
-Dmedia-gstreamer=disabled
-Dintrospection=disabled
-Dcpp_std=c++11
-Dpixman:tests=disabled
@@ -191,22 +172,6 @@ macos:
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
vs2017-x64:
extends: .only-default
# TODO: Uncomment this when ready to merge.
#only:
# - branches@GNOME/gtk
stage: build
tags:
- win32-ps
needs: []
script:
- .gitlab-ci/test-msvc.bat
artifacts:
when: always
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
.flatpak-defaults:
image: $FLATPAK_IMAGE
stage: flatpak
@@ -226,11 +191,11 @@ vs2017-x64:
extends: .flatpak-defaults
when: manual
# Only build Flatpak bundles automatically on main
.flatpak-main:
# Only build Flatpak bundles automatically on master
.flatpak-master:
extends: .flatpak-defaults
only:
- main
- master
flatpak-manual:demo:
extends: .flatpak-manual
@@ -238,8 +203,8 @@ flatpak-manual:demo:
variables:
APPID: org.gtk.Demo4
flatpak-main:demo:
extends: .flatpak-main
flatpak-master:demo:
extends: .flatpak-master
needs: []
variables:
APPID: org.gtk.Demo4
@@ -250,8 +215,8 @@ flatpak-manual:widget-factory:
variables:
APPID: org.gtk.WidgetFactory4
flatpak-main:widget-factory:
extends: .flatpak-main
flatpak-master:widget-factory:
extends: .flatpak-master
needs: []
variables:
APPID: org.gtk.WidgetFactory4
@@ -262,8 +227,8 @@ flatpak-manual:icon-browser:
variables:
APPID: org.gtk.IconBrowser4
flatpak-main:icon-browser:
extends: .flatpak-main
flatpak-master:icon-browser:
extends: .flatpak-master
needs: []
variables:
APPID: org.gtk.IconBrowser4
@@ -273,18 +238,18 @@ flatpak-main:icon-browser:
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
nightly demo:
extends: '.publish_nightly'
dependencies: ['flatpak-main:demo']
needs: ['flatpak-main:demo']
dependencies: ['flatpak-master:demo']
needs: ['flatpak-master:demo']
nightly factory:
extends: '.publish_nightly'
dependencies: ['flatpak-main:widget-factory']
needs: ['flatpak-main:widget-factory']
dependencies: ['flatpak-master:widget-factory']
needs: ['flatpak-master:widget-factory']
nightly icon-browser:
extends: '.publish_nightly'
dependencies: ['flatpak-main:icon-browser']
needs: ['flatpak-main:icon-browser']
dependencies: ['flatpak-master:icon-browser']
needs: ['flatpak-master:icon-browser']
static-scan:
image: $FEDORA_IMAGE
@@ -318,7 +283,7 @@ asan-build:
allow_failure: true
reference:
image: $FEDORA_IMAGE
image: $DOCS_IMAGE
stage: docs
needs: []
variables:
@@ -344,11 +309,14 @@ reference:
paths:
- _reference
publish-docs:
stage: publish
pages:
stage: deploy
needs: ['reference']
script:
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
- mv _reference/ public/
- cp .gitlab-ci/pages/* public/
artifacts:
paths:
- public
only:
refs:
- main
- master

View File

@@ -0,0 +1,89 @@
FROM fedora:33
RUN dnf -y install \
adwaita-icon-theme \
atk-devel \
at-spi2-atk-devel \
avahi-gobject-devel \
cairo-devel \
cairo-gobject-devel \
ccache \
clang \
clang-analyzer \
colord-devel \
cups-devel \
dbus-daemon \
dbus-x11 \
dejavu-sans-mono-fonts \
desktop-file-utils \
diffutils \
elfutils-libelf-devel \
fribidi-devel \
gcc \
gcc-c++ \
gdk-pixbuf2-devel \
gdk-pixbuf2-modules \
gettext \
git \
glib2-devel \
glib2-static \
glibc-devel \
glibc-headers \
gnome-desktop-testing \
gobject-introspection-devel \
graphene-devel \
gstreamer1-devel \
gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \
gtk-doc \
hicolor-icon-theme \
iso-codes \
itstool \
json-glib-devel \
lcov \
libasan \
libattr-devel \
libcloudproviders-devel \
libepoxy-devel \
libffi-devel \
libmount-devel \
librsvg2 \
libselinux-devel \
libubsan \
libXcomposite-devel \
libXcursor-devel \
libXcursor-devel \
libXdamage-devel \
libXfixes-devel \
libXi-devel \
libXinerama-devel \
libxkbcommon-devel \
libXrandr-devel \
libXrender-devel \
libXtst-devel \
libxslt \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libGLES-devel \
meson \
ninja-build \
pango-devel \
pcre-devel \
pcre-static \
python3 \
python3-jinja2 \
python3-pip \
python3-pygments \
python3-wheel \
redhat-rpm-config \
sassc \
systemtap-sdt-devel \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
weston \
weston-libs \
which \
xorg-x11-server-Xvfb \
&& dnf clean all

View File

@@ -0,0 +1,18 @@
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v28
RUN dnf -y install \
graphviz \
python3-jinja2 \
python3-markdown \
python3-pygments \
python3-toml \
python3-typogrify
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
USER user
WORKDIR /home/user
ENV LANG C.UTF-8

View File

@@ -1,103 +1,4 @@
FROM fedora:34
RUN dnf -y install \
adwaita-icon-theme \
atk-devel \
at-spi2-atk-devel \
avahi-gobject-devel \
cairo-devel \
cairo-gobject-devel \
ccache \
clang \
clang-analyzer \
clang-tools-extra \
colord-devel \
cups-devel \
dbus-daemon \
dbus-x11 \
dejavu-sans-mono-fonts \
desktop-file-utils \
diffutils \
elfutils-libelf-devel \
fribidi-devel \
gcc \
gcc-c++ \
gdk-pixbuf2-devel \
gdk-pixbuf2-modules \
gettext \
git \
glib2-devel \
glib2-static \
glibc-devel \
glibc-headers \
gnome-desktop-testing \
gobject-introspection-devel \
graphene-devel \
graphviz \
gstreamer1-devel \
gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \
hicolor-icon-theme \
iso-codes \
itstool \
json-glib-devel \
lcov \
libasan \
libattr-devel \
libcloudproviders-devel \
libepoxy-devel \
libffi-devel \
libjpeg-turbo-devel \
libmount-devel \
libpng-devel \
librsvg2 \
libselinux-devel \
libtiff-devel \
libubsan \
libXcomposite-devel \
libXcursor-devel \
libXcursor-devel \
libXdamage-devel \
libXfixes-devel \
libXi-devel \
libXinerama-devel \
libxkbcommon-devel \
libXrandr-devel \
libXrender-devel \
libXtst-devel \
libxslt \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libGLES-devel \
meson \
ninja-build \
pango-devel \
pcre-devel \
pcre-static \
python3 \
python3-docutils \
python3-gobject \
python3-jinja2 \
python3-markdown \
python3-pip \
python3-pygments \
python3-toml \
python3-typogrify \
python3-wheel \
redhat-rpm-config \
sassc \
systemtap-sdt-devel \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
weston \
weston-libs \
which \
xorg-x11-server-Xvfb \
&& dnf install -y 'dnf-command(builddep)' \
&& dnf builddep -y wayland \
&& dnf clean all
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v28
# Enable sudo for wheel users
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers

View File

@@ -24,7 +24,6 @@ flatpak build ${builddir} meson \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Ddemos=true \
-Dprofile=devel \
_flatpak_build
flatpak build ${builddir} ninja -C _flatpak_build install
@@ -43,6 +42,6 @@ flatpak build-bundle \
${appid}
# to be consumed by the nightly publish jobs
if [[ $CI_COMMIT_BRANCH == main ]]; then
if [[ $CI_COMMIT_BRANCH == master ]]; then
tar cf repo.tar ${repodir}
fi

View File

@@ -268,7 +268,7 @@ aparser.add_argument('--job-id', metavar='ID',
default=None)
aparser.add_argument('--branch', metavar='NAME',
help='Branch of the project being tested',
default='main')
default='master')
aparser.add_argument('--output', metavar='FILE',
help='The output HTML file, stdout by default',
type=argparse.FileType('w', encoding='UTF-8'),

View File

@@ -27,7 +27,7 @@ aparser.add_argument('--job-id', metavar='ID',
default='Unknown')
aparser.add_argument('--branch', metavar='NAME',
help='Branch of the project being tested',
default='main')
default='master')
aparser.add_argument('--output', metavar='FILE',
help='The output file, stdout by default',
type=argparse.FileType('w', encoding='UTF-8'),

View File

@@ -2,7 +2,7 @@
set -e
# We need to add a new remote for the upstream main, since this script could
# We need to add a new remote for the upstream master, since this script could
# be running in a personal fork of the repository which has out of date branches.
if [ "${CI_PROJECT_NAMESPACE}" != "GNOME" ]; then
echo "Retrieving the current upstream repository from ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}..."
@@ -16,7 +16,7 @@ fi
# Work out the newest common ancestor between the detached HEAD that this CI job
# has checked out, and the upstream target branch (which will typically be
# `upstream/main` or `upstream/gtk-3-24`).
# `upstream/master` or `upstream/gtk-3-24`).
#
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if were running in
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
@@ -36,7 +36,7 @@ exit_status=$?
echo ""
echo "Note that clang-format output is advisory and cannot always match the"
echo "GTK coding style, documented at:"
echo " https://gitlab.gnome.org/GNOME/gtk/blob/main/docs/CODING-STYLE"
echo " https://gitlab.gnome.org/GNOME/gtk/blob/master/docs/CODING-STYLE"
echo "Warnings from this tool can be ignored in favour of the documented "
echo "coding style, or in favour of matching the style of existing"
echo "surrounding code."

View File

@@ -44,24 +44,6 @@ case "${backend}" in
kill ${compositor}
;;
waylandgles)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
weston --backend=headless-backend.so --socket=wayland-6 --idle-time=0 &
compositor=$!
export WAYLAND_DISPLAY=wayland-6
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
--no-suite=gsk-compare-broadway
exit_code=$?
kill ${compositor}
;;
broadway)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
@@ -80,12 +62,6 @@ case "${backend}" in
exit_code=0
kill ${server}
;;
*)
echo "Failed to add ${backend} to .gitlab-ci/run-tests.sh"
exit 1
;;
esac
cd ${builddir}

View File

@@ -1,5 +0,0 @@
#! /bin/sh
. /etc/os-release
echo $PRETTY_NAME

View File

@@ -15,7 +15,7 @@ meson \
-Dx11-backend=true \
-Dwayland-backend=true \
-Dbroadway-backend=true \
-Dvulkan=enabled \
-Dvulkan=yes \
-Dprofiler=true \
--werror \
${EXTRA_MESON_FLAGS:-} \

View File

@@ -1,14 +0,0 @@
@echo on
:: vcvarsall.bat sets various env vars like PATH, INCLUDE, LIB, LIBPATH for the
:: specified build architecture
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
@echo on
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson==0.59 || goto :error
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
ninja -C _build || goto :error
goto :EOF
:error
exit /b 1

View File

@@ -15,9 +15,9 @@ pacman --noconfirm -Suy
pacman --noconfirm -S --needed \
base-devel \
git \
mingw-w64-$MSYS2_ARCH-cc \
mingw-w64-$MSYS2_ARCH-toolchain \
mingw-w64-$MSYS2_ARCH-ccache \
mingw-w64-$MSYS2_ARCH-pkgconf \
mingw-w64-$MSYS2_ARCH-pkg-config \
mingw-w64-$MSYS2_ARCH-gobject-introspection \
mingw-w64-$MSYS2_ARCH-meson \
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
@@ -30,9 +30,8 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-libepoxy \
mingw-w64-$MSYS2_ARCH-pango \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \
mingw-w64-$MSYS2_ARCH-python-gobject
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
mingw-w64-$MSYS2_ARCH-shared-mime-info
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"
@@ -41,7 +40,7 @@ export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
# https://gitlab.gnome.org/GNOME/gtk/-/issues/2243
# https://gitlab.gnome.org/GNOME/gtk/-/issues/3002
if ! pkg-config --atleast-version=2.66.0 glib-2.0; then
if ! pkg-config --atleast-version=2.65.0 glib-2.0; then
git clone https://gitlab.gnome.org/GNOME/glib.git _glib
meson setup _glib_build _glib
meson compile -C _glib_build
@@ -49,7 +48,7 @@ if ! pkg-config --atleast-version=2.66.0 glib-2.0; then
fi
pkg-config --modversion glib-2.0
if ! pkg-config --atleast-version=1.50.0 pango; then
if ! pkg-config --atleast-version=1.47.0 pango; then
git clone https://gitlab.gnome.org/GNOME/pango.git _pango
meson setup _pango_build _pango
meson compile -C _pango_build
@@ -73,5 +72,3 @@ unset CCACHE_DISABLE
ninja -C _build
ccache --show-stats
tar zcf _build/gtkdll.tar.gz _build/gtk/libgtk*.dll

View File

@@ -1,7 +1,7 @@
<!--
Please, read the CONTRIBUTING.md guide on how to file a new issue.
https://gitlab.gnome.org/GNOME/gtk/-/blob/main/CONTRIBUTING.md
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
-->
## Steps to reproduce
<!--

View File

@@ -1,7 +1,7 @@
<!--
Please, read the CONTRIBUTING.md guide on how to file a new issue.
https://gitlab.gnome.org/GNOME/gtk/-/blob/main/CONTRIBUTING.md
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
-->
## Steps to reproduce

View File

@@ -256,7 +256,7 @@ people committing to GTK to follow a few rules:
0. Always write a meaningful commit message. Changes without a sufficient
commit message will be reverted.
0. Never push to the `main` branch, or any stable branches, directly; you
0. Never push to the `master` branch, or any stable branches, directly; you
should always go through a merge request, to ensure that the code is
tested on the CI infrastructure at the very least. A merge request is
also the proper place to get a comprehensive code review from the core

619
NEWS
View File

@@ -1,593 +1,3 @@
Overview of Changes in 4.6.1, 11-02-2022
========================================
* GtkFontChooser:
- Stop using PangoFc api
- Fix a crash
- Use new HarfBuzz api
* GtkMenuButton:
- Update accessible description
* GtkTextView:
- Fix intra-widget dnd
* Printing:
- Fix an fd leak
* Input:
- Make sure input methods get focus-in events
- Always flush events to avoid scroll event pileup
- Support hold events
- Update keysyms from libxkbcommon
* Theme:
- Improve text selection legibility
* Introspection:
- Add missing nullable annotations everywhere
* Build:
- Make stack noexec again
- Avoid symbol leaks
- Drop unneeded script data
* Windows:
- Stop using WM_SYNCPAINT
- Relax check for GL 3.x legacy contexts
- Use native apis for language names
- Rewrite the keymap code
- Use the GL renderer by default
* Wayland:
- Fix support for the new high-contrast setting
- Avoid redundant scale changes
- Fix DND hotspot handling
- Don't always restore the saved size when floating
* MacOS:
- Various performance improvements
* Translation updates:
Brazilian Portuguese
Catalan
Chinese (China)
Galician
Hebrew
Japanese
Lithuanian
Persian
Polish
Portuguese
Russian
Slovenian
Spanish
Ukrainian
Overview of Changes in 4.6.0, 30-12-2021
========================================
* GtkProgressBar:
- Fix handling of "inverted"
* GtkLabel:
- Add a "natural wrap mode" property to influence how
natural width is determined
* GtkTextView
- Scroll insertion on-screen after undo / redo
* gsk:
- Abort region diffing when changes are too complex
* gdk:
- Avoid compressing discrete scroll events
- Fix problems with hiding windows
- Improve GL and GLES version checks
* Wayland:
- Support new high-contrast setting
* Inspector:
- Add DND inspection support
* build:
- Avoid deprecated meson apis
* Translation updates
Galician
Portuguese
Ukrainian
Overview of Changes in 4.5.1, 16-12-2021
========================================
* GtkWidget sizing has been rewritten to implement
width-for-height more properly. This had some fallout,
and some widgets may still not react kindly to the
new way of doing things.
See https://blog.gtk.org/2021/12/03/sizable-news/
for details, and please file issues if you notice fallout.
* Rename git `master` branch to `main`
* Css:
- Fully support font-variant-caps
- Fix a crash with gradients
* Make various widgets activatable:
- GtkComboBox
- GtkDropDown
* GtkPopover:
- Make focus indicators not disappear
* GtkTextView:
- Don't leave embedded children stranded when scrolling
- Don't insert Emoji into non-editable textviews
- Fix Emoji chooser positioning
- Fix problems with pasting text
- Improve scroll-to-mark behavior
- Support right-aligned, centered and decimal tabs
- Make child anchor replacement character settable
- Provide more context to input methods
* GtkDragIcon:
- Provide default icons for paintables and files
* GtkBuilder:
- Speed up template precompilation
* Actions:
- Reduce allocations during signal emissions
- Avoid duplication and unnecessary recursion
* Inspector:
- Show the selected im-module in the General tab
- Add a clipboard viewer
- Make the recorder record events too
- Add a graph visualizing gtk_widget_measure()
* Gsk:
- Fix hexbox rendering
- Fix transformed linear gradient rendering
* Printing:
- Fix dialog-less printing
* Windows:
- Use the common EGL setup code
- Respect GDK_DEBUG=gl-egl
- Fix AeroSnap indicator and positioning
* X11:
- Improve behavior of windows drags on headerbar controls
- Trap errors for RANDR changes
- Fix problems with drag icons
* Wayland:
- Ensure we prefer the Wayland im-module over others
* Translation updates
Basque
Catalan
Croatian
Friulian
Galician
Hebrew
Icelandic
Italian
Latvian
Lithuanian
Occitan
Persian
Portuguese
Spanish
Swedish
Ukrainian
Overview of Changes in 4.5.0
============================
* gsk:
- Drop the GL renderer in favor of NGL
- Rename NGL to GL
- Fix some coordinate overflow issues
- Reimplement texture upload and download for better
support of image formats and color spaces
- New api:
gsk_transform_skew
gsk_transform_to_2d_components
* gdk:
- Support HSL in gdk_rgba_parse
- Use libpng, libjpeg and libtiff directly when loading
textures, and support more image formats (including 16bit
and float formats)
- New apis:
gdk_texture_new_from_bytes
gdk_texture_new_from_filename
gdk_texture_download_float
gdk_texture_save_to_png_bytes
gdk_texture_save_to_tiff
gdk_texture_save_to_tiff_bytes
gdk_display_create_gl_context
- Implement GIcon and GLoadableIcon in GdkTexture
- Move EGL initialization to the frontend
- Use configless EGL contexts, if supported
- Use >8bit pixel formats, if supported and requested
* css:
- Add support for line-height
- Add support for text-transform
* theme:
- Fixes for buttons in toolbars
* input:
- Update compose sequences from libX11 1.7.2
- Accept replacement string longer than 20 characters
* text:
- Implement sloped caret drawing
- Add a gtk-hint-font-metrics setting to switch
font rendering to be more similar to GTK3
* GtkTextView:
- Add support for line height
- Add support for text transforms
- Misc fixes for css->pango attribute translations
- Invalidate pango contexts when font settings change
- Improve undo grouping when overwriting
* GtkListView:
- Make tree indentation more flexible with
GtkTreeExpander:indent-for-icon
* GtkMenuButton:
- Support custom children
* GtkFlowBox:
- Add prepend and append
* GtkCalendar:
- Fix handling of weeks starting on Monday
* GtkWindow:
- Add a titlebar property
* GtkDropDown:
- Add a show-arrow property
* GtkPopoverMenu:
- Support a use-markup attribute in menu models
* Add GtkSymbolicPaintable
* Tools:
- Support DND in gtk4-node-editor and the inspector's recorder
* Demos:
- Improve the font rendering demo
* Build:
- Require Pango 1.49
- Require libpng, libtiff and libjpeg
- Speed up handling of resources during build
* X11:
- Support touchpad gestures with XInput 2.4
* Windows:
- Fix DND coordinates
* Translation updates:
Basque
Brazilian Portuguese
Catalan
Chinese (China)
Croatian
Czech
Dutch
Finnish
French
Galician
German
Hebrew
Hungarian
Icelandic
Indonesian
Kazakh
Korean
Latvian
Lithuanian
Persian
Portuguese
Romanian
Serbian
Slovak
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.4.0
============================
* Input:
- Match IBus for display of Compose sequences
- Match IBus for handling of mismatches
- Handle Escape in Compose sequences
- Allow multiple dead keys
- Support 32bit keysyms
* GtkCheckButton:
- Activate when moving focus
* GtkLabel:
- Propertly ignore double underscores for mnemonics
* GtkPopoverMenu:
- Fix focus cycling
* GtkTextView:
- Improve word selection
- Fix block cursors on empty lines
* GdkToplevel:
- Support the gnome-shell titlebar gesture protocol
* GdkDropTarget:
- Allow creating drop targets in ui files
* gsk:
- Handle partial color fonts correctly
- Use harfbuzz for color font information
- Avoid pango for glyph cache rendering
- Shrink shadow extents
* Settings:
- Change the default for gtk-split-cursor to FALSE
* Demos:
- Small improvements to widget-factory
- gtk-demo: Improve the hypertext demo
- gtk-dem: Improve the clipboard demo
* X11:
- Set WM_CLASS on toplevels
* Wayland:
- Support wl_seat v7
* Windows:
- Drop the local DND protocol
- Avoid WGL if shaders don't work
- Use WinPointer API
* Translation updates:
Belarusian
Friulian
Hebrew
Khmer
Persian
Polish
Overview of Changes in 4.3.2
============================
* GtkToggleButton:
- Fix the actionable implementation
* GtkCheckButton:
- Fix the actionable implementation
- Cancel activation on when the pointer leaves
* GtkMenuButton:
- Make activatable again
- Add a way to have an icon + arrow
* GtkColorButton:
- Make activatable again
* GtkFontButton:
- Make activatable again
* GtkAppChooserButton:
- Make activatable again
* GtkColumnView:
- Fix double activation
* GtkLabel:
- Fix mnemonics without markup
* GtkTreeView:
- Clip header buttons
* GtkTextView:
- Add api to get the RTL and LTR contexts
- Fix some errors in text history grouping
* GtkText:
- Don't show placeholder text on top of entry text
- Add api to compute the cursor extents
- Fix y coordinates for text selection
* GtkFileChooser:
- Don't show Trash in the side bar
* GtkPopoverMenu:
- Add scrollbars to long menus
* GtkActionMuxer:
- Fix propagation of accel changes
* Introspection:
- Annotate all filename arguments
- Rename GtkMediaStream apis to avoid name collisions
- Rename GtkDropTarget properties to avoid name collisions
- Make GtkPasswordEntryBuffer introspectable
* Printing:
- Remove the Google Cloud Print backend
* Theme:
- Sync included icons with the Adwaita icon theme
* GSK:
- Avoid overflowing the vertex counter
- Handle negative scales correctly in the ngl renderer
* GDK:
- Cleanup and simplify OpenGL setup code
- Add a GdkDisplay::init_gl vfunc and gdk_display_prepare_gl() api
- Require EGL 1.4
- Fix EGL + NVidia
* Build:
- Enable gstreamer by default
- Disable Vulkan by default
- Remove the sassc option
- Remove options and checks for X11 extensions
* X11:
- Stop using XComposite
- Remove the Visual cache
* Wayland:
- Fix some DND corner cases
- Work with version 2 of pointer-gestures-v1
- Look for cursor themes in $HOME/.icons
* Windows:
- Fix SIGILL on x64 due to popcnt
- Fix popup placement
- Fix drag icon placement
- Clean up HiDPI and WGL support
- Default to WGL
* MacOs:
- Fix input method support
- Register known clipboard types for drop targets
- Add initial DND support
* Translation updates:
Brazilian Portuguese
Portuguese
Romanian
Turkish
Ukrainian
Overview of Changes in 4.3.1
============================
* GtkEmojiChooser:
- Update data from CLDR 39
- Load Emoji data for both language and territory
* GtkCalendar:
- Fix an off-by-one error in day numbers
* GtkListView:
- Add .activatable style class to activatable items
* GtkCheckButton:
- Don't allow unchecking grouped radio buttons
*GtkToggleButton:
- Fix mnemonic activation propagation
* GtkLabel:
- Make mnemonics work even when invisible
- Fix mnemonic activation propagation
* GtkMenuButton:
- Add a property to mark primary menus and make F10 work
* GtkApplication:
- Fix initial screensaver state async
* GtkEntry:
- Apply xalign to placeholder text (as it was in GTK 3)
* GtkSpinButton:
- Fix swipe gestures
* GtkStackSwitcher:
- Implement GtkOrientable (as it was in GTK 3)
- Fix a use-after-free problem with drag timeouts
* GtkFileChooser:
- Add support for (case-insensitive) suffix matches in GtkFileFilter
* GtkPasswordEntry:
- Make GtkPasswordEntryBuffer public, to make it easier
to write your own password entry widget
* Input:
- Fix interference between various obscure XKB features
(e.g. overlays) and Compose sequences
* Action support:
- Fix submenu-action handling
* Theme:
- Update icons from the Adwaita icon theme
- Fix icon names for GtkSwitch
- Fix switch-off icon
* GSK:
- Improve transformed offscreen rendering
- Add padding between cached glyphs
* Wayland:
- Fix monitor sizes in the presence of transforms
- Add a getter for the EGLDisplay
- Fix click-drag-release sequences for popovers
* X11:
- Support EGL for X11. Fall back to GLX if EGL isn't available
- Always fall back to GLX on NVidia
- Add a getter for the EGLDisplay
* Broadway:
- Add a setter for display scale
* Windows:
- Add a getter for the EGLDisplay
- Make GL work for media playback
* MacOS:
- Fix menubar appearance
* Tools:
- gtk4-builder-tool: Replace can-focus with focusable in 3-to-4 conversion
* Introspection:
- Add missing annotations in a few places (e.g. gtk_free_view_row_activated)
* Build:
- Only build one source file with -mf16c
- Fix devel styling for ci flatpak builds
- Generate appdata for demo flatpaks
* Docs:
- Numerous fixes and additions
* Translation updates:
Friulian
Nepali
Norwegian Bokmål
Ukrainian
Overview of Changes in 4.3.0
============================
@@ -604,12 +14,8 @@ Overview of Changes in 4.3.0
- Fix initial font selection
* Text widgets:
- Replace squiggly error underlines by dotted lines
- Support translucent selections
* GtkTextView:
- Various improvements to rendering performance
* GtkScrolledWindow:
- Stop using scroll cursors
@@ -626,12 +32,6 @@ Overview of Changes in 4.3.0
- Allow repeated selection extension for MULTIPLE
* Themes:
- Reorganize and rename included themes. The theme is now
called Default, with dark, hc and hc-dark variants.
Visually, the themes are unchanged.
- The theme variants are also available as standalone
themes called Default-dark, etc.
- The theme named Adwaita is moving to libadwaita
- Fix resize border sizing
- Fix solid-csd window decorations
@@ -653,10 +53,6 @@ Overview of Changes in 4.3.0
- Fix offscreen rendering with transforms
- Fix downscaled textures
- Avoid huge intermediate textures
- Use fp16 for colors
- Optimize handling of underlines in text
- Fix corner cases of shadow rendering
- Reorganize shader resources
- Make shadow rendering match across renderers
* Accessibility:
@@ -665,7 +61,6 @@ Overview of Changes in 4.3.0
* Wayland:
- Improve font settings fallback
- Avoid unintentional rendering freezes with popovers
- Support the xdg_activation_v1 protocol
* X11:
- Don't beep on untrusted displays
@@ -674,24 +69,10 @@ Overview of Changes in 4.3.0
* Windows:
- Fix using GL rendering with Mesa drivers
* Tools:
- Add support for copy/paste in gtk4-node-editor
- Make syntax highlighting work in the gtk4-demo flatpak
* Inspector:
- Enable the inspector by default, in all cases
- Show keyboard layouts
- Improve monitor information
* Translation updates:
Catalan
Chinese (Taiwan)
Dutch
Nepali
Polish
Swedish
Ukrainian
Overview of Changes in 4.2.0
============================

View File

@@ -1,7 +1,7 @@
GTK — The GTK toolkit
=====================
[![Build status](https://gitlab.gnome.org/GNOME/gtk/badges/main/pipeline.svg)](https://gitlab.gnome.org/GNOME/gtk/-/commits/main)
[![Build status](https://gitlab.gnome.org/GNOME/gtk/badges/master/pipeline.svg)](https://gitlab.gnome.org/GNOME/gtk/-/commits/master)
General information
-------------------
@@ -10,12 +10,10 @@ GTK is a multi-platform toolkit for creating graphical user interfaces.
Offering a complete set of widgets, GTK is suitable for projects ranging
from small one-off projects to complete application suites.
GTK is a free and open-source software project. The licensing terms
for GTK, the GNU LGPL, allow it to be used by all developers, including those
developing proprietary software, without any license fees or royalties.
GTK is hosted by the GNOME project (thanks!) and used by a wide variety
of applications and projects.
GTK is free software and part of the GNU Project. However, the
licensing terms for GTK, the GNU LGPL, allow it to be used by all
developers, including those developing proprietary software, without any
license fees or royalties.
The official download location
@@ -38,13 +36,6 @@ Nightly documentation can be found at
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk4/
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk4/
Nightly flatpaks of our demos can be installed from the
[GNOME Nightly](https://wiki.gnome.org/Apps/Nightly) repository:
- `flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo`
- `flatpak install gnome-nightly org.gtk.Demo4`
- `flatpak install gnome-nightly org.gtk.WidgetFactory4`
- `flatpak install gnome-nightly org.gtk.IconBrowser4`
Building and installing
-----------------------
@@ -114,21 +105,7 @@ can be found in the file:
docs/reference/gtk/html/gtk-building.html
```
Or [online](https://docs.gtk.org/gtk4/building.html)
Default branch renamed to `main`
--------------------------------
The default development branch of GTK has been renamed to `main`.
To update your local checkout, use:
```sh
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/main
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
Or [online](https://developer.gnome.org/gtk4/stable/gtk-building.html)
How to report bugs
------------------
@@ -167,17 +144,14 @@ Contributing to GTK
Please, follow the [contribution guide](./CONTRIBUTING.md) to know how to
start contributing to GTK.
If you want to support GTK financially, please consider donating to
the GNOME project, which runs the infrastructure hosting GTK.
Release notes
-------------
The release notes for GTK are part of the migration guide in the API
reference. See:
- [3.x release notes](https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html)
- [4.x release notes](https://docs.gtk.org/gtk4/migrating-3to4.html)
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
- [4.x release notes](https://developer.gnome.org/gtk4/unstable/gtk-migrating-3-to-4.html)
Licensing terms
---------------

View File

@@ -1,43 +0,0 @@
diff -ur lua-5.1.4/src/Makefile lua-5.1.4-new/src/Makefile
--- lua-5.1.4/src/Makefile 2008-01-19 20:37:58.000000000 +0100
+++ lua-5.1.4-new/src/Makefile 2012-02-23 18:26:43.000000000 +0100
@@ -23,6 +23,7 @@
PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
+LUA_SO= liblua.so
CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
lundump.o lvm.o lzio.o
@@ -36,7 +37,7 @@
LUAC_O= luac.o print.o
ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
+ALL_T= $(LUA_A) $(LUA_SO) $(LUA_T) $(LUAC_T)
ALL_A= $(LUA_A)
default: $(PLAT)
@@ -51,6 +52,11 @@
$(AR) $@ $?
$(RANLIB) $@
+$(LUA_SO): $(CORE_O) $(LIB_O)
+ $(CC) -shared -ldl -Wl,-soname,$(LUA_SO).$(V) -o $@.$(R) $? -lm $(MYLDFLAGS)
+ ln -sf $(LUA_SO).$(R) $(LUA_SO).$(V)
+ ln -sf $(LUA_SO).$(R) $(LUA_SO)
+
$(LUA_T): $(LUA_O) $(LUA_A)
$(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
--- lua-5.1.4/Makefile 2008-08-12 02:40:48.000000000 +0200
+++ lua-5.1.4-new/Makefile 2012-02-23 19:06:32.000000000 +0100
@@ -53,7 +53,7 @@
all: $(PLAT)
$(PLATS) clean:
- cd src && $(MAKE) $@
+ cd src && $(MAKE) $@ V=$(V) R=$(R)
test: dummy
src/lua test/hello.lua

View File

@@ -43,8 +43,7 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
}
]
},
@@ -94,92 +93,6 @@
}
]
},
{
"name": "boost",
"buildsystem": "simple",
"build-commands": [
"./bootstrap.sh --prefix=/app --with-libraries=date_time,filesystem,iostreams,locale,regex,system,thread,python,program_options,test,serialization",
"./b2 --build-type=minimal link=shared -j $FLATPAK_BUILDER_N_JOBS",
"./b2 --build-type=minimal link=shared install"
],
"sources": [
{
"type": "archive",
"url": "https://boostorg.jfrog.io/artifactory/main/release/1.69.0/source/boost_1_69_0.tar.bz2",
"sha256": "8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406"
}
]
},
{
"name": "lua-5.1",
"buildsystem": "simple",
"build-commands": [
"make -j $FLATPAK_BUILDER_N_JOBS CFLAGS=\"$CFLAGS -fPIC -DLUA_USE_LINUX\" linux",
"make INSTALL_TOP=$FLATPAK_DEST TO_LIB='liblua.a liblua.so.5.1.5' install",
"ln -sf liblua.so.5.1.5 $FLATPAK_DEST/lib/liblua.so",
"ln -sf liblua.so.5.1.5 $FLATPAK_DEST/lib/liblua.so.5.1",
"install -Dm0644 etc/lua.pc $FLATPAK_DEST/lib/pkgconfig/lua.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua51.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua5.1.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua-5.1.pc"
],
"sources": [
{
"type": "archive",
"url": "https://www.lua.org/ftp/lua-5.1.5.tar.gz",
"sha256": "2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333"
},
{
"type": "patch",
"path": "lua-5.1.5-so.patch"
},
{
"type": "shell",
"commands": [
"sed -i \"s|/usr/local|$FLATPAK_DEST|\" etc/lua.pc src/luaconf.h"
]
}
],
"cleanup": [
"*.a",
"/bin",
"/include",
"/lib/pkgconfig",
"/man"
]
},
{
"name" : "highlight",
"buildsystem" : "simple",
"builddir" : true,
"build-commands" : [
"sed -i -e 's#^PREFIX = /usr#PREFIX = /app#' makefile",
"make",
"make install"
],
"sources" : [
{
"type" : "archive",
"url" : "http://www.andre-simon.de/zip/highlight-4.0.tar.bz2",
"sha256" : "f40dcba26e011a2c67df874f4d9b0238c2c6b065163ce8de3d8371b9dfce864d"
}
]
},
{
"name" : "pango",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
"branch" : "main"
}
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
@@ -193,8 +106,7 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
"branch" : "main"
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}

View File

@@ -43,8 +43,7 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
}
]
},
@@ -94,21 +93,6 @@
}
]
},
{
"name" : "pango",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
"branch" : "main"
}
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
@@ -122,8 +106,7 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
"branch" : "main"
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}

View File

@@ -43,8 +43,7 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
}
]
},
@@ -94,21 +93,6 @@
}
]
},
{
"name" : "pango",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
"branch" : "main"
}
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
@@ -122,8 +106,7 @@
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
"branch" : "main"
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}

View File

@@ -8,10 +8,10 @@ from pathlib import PurePath
stylesheets = [
'gtk/theme/Default/Default-light.css',
'gtk/theme/Default/Default-dark.css',
'gtk/theme/Default/Default-hc.css',
'gtk/theme/Default/Default-hc-dark.css',
'gtk/theme/Adwaita/Adwaita.css',
'gtk/theme/Adwaita/Adwaita-dark.css',
'gtk/theme/HighContrast/HighContrast.css',
'gtk/theme/HighContrast/HighContrast-dark.css',
]
references = [

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
repodir = sys.argv[1]
profile = sys.argv[2]
sys.stdout.write("/* This file is auto-generated. Do not edit. */\n")
sys.stdout.write("#pragma once\n")
sys.stdout.write("\n")
sys.stdout.write(f"#define PROFILE \"{profile}\"\n")
short_sha = os.environ.get('CI_COMMIT_SHORT_SHA')
if short_sha is None:
cmd = ["git", "-C", repodir, "rev-parse", "--short", "HEAD"]
try:
with subprocess.Popen(cmd, stdout=subprocess.PIPE) as p:
short_sha = p.stdout.read().decode('utf-8').rstrip("\n")
except FileNotFoundError:
short_sha = ''
if profile != 'default':
short_sha = 'devel'
sys.stdout.write(f"#define VCS_TAG \"{short_sha}\"\n")

View File

@@ -13,7 +13,7 @@ if 'DESTDIR' not in os.environ:
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
gtk_mediamodule_dir = os.path.join(gtk_moduledir, 'media')
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
print('Compiling GSettings schemas...')
glib_compile_schemas = subprocess.check_output(['pkg-config',
@@ -40,6 +40,6 @@ if 'DESTDIR' not in os.environ:
gio_querymodules = 'gio-querymodules'
subprocess.call([gio_querymodules, gtk_printmodule_dir])
print('Updating module cache for media backends...')
os.makedirs(gtk_mediamodule_dir, exist_ok=True)
subprocess.call([gio_querymodules, gtk_mediamodule_dir])
print('Updating module cache for input methods...')
os.makedirs(gtk_immodule_dir, exist_ok=True)
subprocess.call([gio_querymodules, gtk_immodule_dir])

284
config.h.meson Normal file
View File

@@ -0,0 +1,284 @@
/* always defined to indicate that i18n is enabled */
#define ENABLE_NLS 1
/* Use structured logging */
#define G_LOG_STRUCTURED 1
/* The prefix for our gettext translation domains. */
#mesondefine GETTEXT_PACKAGE
/* Disable deprecation warnings from glib */
#mesondefine GLIB_DISABLE_DEPRECATION_WARNINGS
/* Define the location where the catalogs will be installed */
#mesondefine GTK_LOCALEDIR
/* Define to 1 if you have the `bind_textdomain_codeset' function. */
#mesondefine HAVE_BIND_TEXTDOMAIN_CODESET
/* Have the cloudproviders library */
#mesondefine HAVE_CLOUDPROVIDERS
/* define if we have colord */
#mesondefine HAVE_COLORD
/* Define to 1 if you have the <crt_externs.h> header file. */
#mesondefine HAVE_CRT_EXTERNS_H
/* Define to 1 if you have the `dcgettext' function. */
#mesondefine HAVE_DCGETTEXT
/* Define to 1 if you have the <dlfcn.h> header file. */
#mesondefine HAVE_DLFCN_H
/* Have the ffmpeg library */
#mesondefine HAVE_FFMPEG
/* Define to 1 if you have the <ftw.h> header file. */
#mesondefine HAVE_FTW_H
/* Define to 1 if you have the `getpagesize' function. */
#mesondefine HAVE_GETPAGESIZE
/* Define to 1 if you have the `getresuid' function. */
#mesondefine HAVE_GETRESUID
/* Define if gio-unix is available */
#mesondefine HAVE_GIO_UNIX
/* Define if GStreamer support is available */
#mesondefine HAVE_GSTREAMER
/* Define to 1 if you have the <inttypes.h> header file. */
#mesondefine HAVE_INTTYPES_H
/* Define to 1 if the system has the type `IPrintDialogCallback'. */
#mesondefine HAVE_IPRINTDIALOGCALLBACK
/* Define to 1 if you have the <locale.h> header file. */
#mesondefine HAVE_LOCALE_H
/* Define to 1 if you have the `lstat' function. */
#mesondefine HAVE_LSTAT
/* Define to 1 if you have the `mallinfo' function. */
#mesondefine HAVE_MALLINFO
/* Define to 1 if you have the <memory.h> header file. */
#mesondefine HAVE_MEMORY_H
/* Define to 1 if you have the `mkstemp' function. */
#mesondefine HAVE_MKSTEMP
/* Define to 1 if you have the `mlock` function. */
#mesondefine HAVE_MLOCK
/* Define to 1 if you have a working `mmap' system call. */
#mesondefine HAVE_MMAP
/* Define to 1 if you have a working `madvise' system call. */
#mesondefine HAVE_MADVISE
/* Define to 1 if you have the `posix_fallocate' function. */
#mesondefine HAVE_POSIX_FALLOCATE
/* Have the Xrandr extension library */
#mesondefine HAVE_RANDR
/* Have the Xrandr 1.5 extension library */
#mesondefine HAVE_RANDR15
/* Define to 1 if you have the `sincos' function. */
#mesondefine HAVE_SINCOS
/* Define to 1 if you have the <stdint.h> header file. */
#mesondefine HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#mesondefine HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#mesondefine HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#mesondefine HAVE_STRING_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#mesondefine HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/param.h> header file. */
#mesondefine HAVE_SYS_PARAM_H
/* Have the sysprof-capture library */
#mesondefine HAVE_SYSPROF
/* Define to 1 if you have the <sys/stat.h> header file. */
#mesondefine HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#mesondefine HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#mesondefine HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#mesondefine HAVE_UNISTD_H
/* Have the XCOMPOSITE X extension */
#mesondefine HAVE_XCOMPOSITE
/* Have the Xcursor library */
#mesondefine HAVE_XCURSOR
/* Have the XDAMAGE X extension */
#mesondefine HAVE_XDAMAGE
/* Have the XFIXES X extension */
#mesondefine HAVE_XFIXES
/* Define to 1 if XFree Xinerama is available */
#mesondefine HAVE_XFREE_XINERAMA
/* Have XGenericEvent */
#mesondefine HAVE_XGENERICEVENTS
/* Define to use XKB extension */
#mesondefine HAVE_XKB
/* Have the SYNC extension library */
#mesondefine HAVE_XSYNC
/* Define to 1 if you have the `_lock_file' function */
#mesondefine HAVE__LOCK_FILE
/* Define to 1 if you have the `flockfile' function */
#mesondefine HAVE_FLOCKFILE
/* Define if _NL_MEASUREMENT_MEASUREMENT is available */
#mesondefine HAVE__NL_MEASUREMENT_MEASUREMENT
/* Define if _NL_PAPER_HEIGHT is available */
#mesondefine HAVE__NL_PAPER_HEIGHT
/* Define if _NL_PAPER_WIDTH is available */
#mesondefine HAVE__NL_PAPER_WIDTH
/* Define if _NL_TIME_FIRST_WEEKDAY is available */
#mesondefine HAVE__NL_TIME_FIRST_WEEKDAY
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#mesondefine LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#mesondefine NO_MINUS_C_MINUS_O
/* Define to the address where bug reports for this package should be sent. */
#mesondefine PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#mesondefine PACKAGE_NAME
/* Define to the full name and version of this package. */
#mesondefine PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#mesondefine PACKAGE_TARNAME
/* Define to the home page for this package. */
#mesondefine PACKAGE_URL
/* Define to the version of this package. */
#mesondefine PACKAGE_VERSION
/* Use NSBundle functions to determine load paths for libraries, translations,
etc. */
#mesondefine QUARTZ_RELOCATION
/* Define to 1 if you have the ANSI C header files. */
#mesondefine STDC_HEADERS
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Define to 1 if XInput 2.2 is available */
#mesondefine XINPUT_2_2
/* Define to 1 if the X Window System is missing or not being used. */
#mesondefine X_DISPLAY_MISSING
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#mesondefine _FILE_OFFSET_BITS
/* defines how to decorate public symbols while building */
#mesondefine _GDK_EXTERN
/* Define for large files, on AIX-style hosts. */
#mesondefine _LARGE_FILES
/* Define to 1 if on MINIX. */
#mesondefine _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#mesondefine _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#mesondefine _POSIX_SOURCE
/* Define to `int' if <sys/types.h> doesn't define. */
#mesondefine gid_t
/* Define to `int' if <sys/types.h> doesn't define. */
#mesondefine uid_t
/* Define to 1 if linux/memfd.h exists */
#mesondefine HAVE_LINUX_MEMFD_H
#mesondefine HAVE_LINUX_INPUT_H
#mesondefine HAVE_DEV_EVDEV_INPUT_H
#mesondefine GTK_SYSCONFDIR
#mesondefine GTK_LOCALEDIR
#mesondefine GTK_DATADIR
#mesondefine GTK_LIBDIR
#mesondefine GTK_PRINT_BACKENDS
#mesondefine HAVE_CAIRO_SCRIPT_INTERPRETER
#mesondefine HAVE_HARFBUZZ
#mesondefine HAVE_PANGOFT
#mesondefine ISO_CODES_PREFIX
/* Define if tracker3 is available */
#mesondefine HAVE_TRACKER3

View File

@@ -17,7 +17,7 @@ executable('gtk4-constraint-editor',
c_args: common_cflags,
dependencies: libgtk_dep,
include_directories: confinc,
win_subsystem: 'windows',
gui_app: true,
link_args: extra_demo_ldflags,
install: false,
)

View File

@@ -1,10 +1,12 @@
/* Clipboard
*
* GdkClipboard is used for clipboard handling. This demo shows how to
* copy and paste text, images, colors or files to and from the clipboard.
* copy and paste text to and from the clipboard.
*
* You can also use Drag-And-Drop to copy the data from the source to the
* target.
* It also shows how to transfer images via the clipboard or via
* drag-and-drop, and how to make clipboard contents persist after
* the application exits. Clipboard persistence requires a clipboard
* manager to run.
*/
#include <glib/gi18n.h>
@@ -12,103 +14,22 @@
#include <string.h>
#include "demoimage.h"
static GtkWidget *window = NULL;
static void
copy_button_clicked (GtkStack *source_stack,
gpointer user_data)
copy_button_clicked (GtkWidget *button,
gpointer user_data)
{
GtkWidget *entry;
GdkClipboard *clipboard;
const char *visible_child_name;
GtkWidget *visible_child;
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (source_stack));
entry = GTK_WIDGET (user_data);
visible_child = gtk_stack_get_visible_child (source_stack);
visible_child_name = gtk_stack_get_visible_child_name (source_stack);
/* Get the clipboard object */
clipboard = gtk_widget_get_clipboard (entry);
if (strcmp (visible_child_name, "Text") == 0)
{
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (visible_child)));
}
else if (strcmp (visible_child_name, "Image") == 0)
{
GtkWidget *child;
for (child = gtk_widget_get_first_child (visible_child); child; child = gtk_widget_get_next_sibling (child))
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (child)))
{
GtkWidget *image = gtk_widget_get_first_child (child);
GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
if (GDK_IS_TEXTURE (paintable))
gdk_clipboard_set (clipboard, GDK_TYPE_TEXTURE, paintable);
else
gdk_clipboard_set (clipboard, GDK_TYPE_PAINTABLE, paintable);
break;
}
}
}
else if (strcmp (visible_child_name, "Color") == 0)
{
GdkRGBA color;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (visible_child), &color);
gdk_clipboard_set (clipboard, GDK_TYPE_RGBA, &color);
}
else if (strcmp (visible_child_name, "File") == 0)
{
gdk_clipboard_set (clipboard, G_TYPE_FILE, g_object_get_data (G_OBJECT (visible_child), "file"), NULL);
}
else
{
g_print ("TODO");
}
}
static void
present_value (GtkStack *dest_stack,
const GValue *value)
{
GtkWidget *child;
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
GFile *file;
gtk_stack_set_visible_child_name (dest_stack, "File");
child = gtk_stack_get_visible_child (dest_stack);
file = g_value_get_object (value);
g_object_set (child, "label", g_file_peek_path (file), NULL);
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_RGBA))
{
GdkRGBA *color;
gtk_stack_set_visible_child_name (dest_stack, "Color");
child = gtk_widget_get_first_child (gtk_stack_get_visible_child (dest_stack));
color = g_value_get_boxed (value);
g_object_set (child, "rgba", color, NULL);
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE) ||
G_VALUE_HOLDS (value, GDK_TYPE_PAINTABLE))
{
GdkPaintable *paintable;
gtk_stack_set_visible_child_name (dest_stack, "Image");
child = gtk_stack_get_visible_child (dest_stack);
paintable = g_value_get_object (value);
g_object_set (child, "paintable", paintable, NULL);
}
else if (G_VALUE_HOLDS (value, G_TYPE_STRING))
{
gtk_stack_set_visible_child_name (dest_stack, "Text");
child = gtk_stack_get_visible_child (dest_stack);
gtk_label_set_label (GTK_LABEL (child), g_value_get_string (value));
}
/* Set clipboard text */
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (entry)));
}
static void
@@ -116,259 +37,149 @@ paste_received (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GtkStack *dest_stack = user_data;
GdkClipboard *clipboard;
const GValue *value;
GtkWidget *entry;
char *text;
GError *error = NULL;
clipboard = GDK_CLIPBOARD (source_object);
entry = GTK_WIDGET (user_data);
value = gdk_clipboard_read_value_finish (clipboard, result, &error);
if (value)
/* Get the resulting text of the read operation */
text = gdk_clipboard_read_text_finish (clipboard, result, &error);
if (text)
{
present_value (dest_stack, value);
/* Set the entry text */
gtk_editable_set_text (GTK_EDITABLE (entry), text);
g_free (text);
}
else
{
g_print ("%s\n", error->message);
GtkWidget *dialog;
/* Show an error about why pasting failed.
* Usually you probably want to ignore such failures,
* but for demonstration purposes, we show the error.
*/
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Could not paste text: %s",
error->message);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy), NULL);
gtk_widget_show (dialog);
g_error_free (error);
}
}
static void
paste_button_clicked (GtkStack *dest_stack,
gpointer user_data)
paste_button_clicked (GtkWidget *button,
gpointer user_data)
{
GtkWidget *entry;
GdkClipboard *clipboard;
GdkContentFormats *formats;
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (dest_stack));
formats = gdk_clipboard_get_formats (clipboard);
entry = GTK_WIDGET (user_data);
if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_TEXTURE))
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_TEXTURE, 0, NULL, paste_received, dest_stack);
else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_PAINTABLE))
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_PAINTABLE, 0, NULL, paste_received, dest_stack);
else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_RGBA))
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_RGBA, 0, NULL, paste_received, dest_stack);
else if (gdk_content_formats_contain_gtype (formats, G_TYPE_FILE))
gdk_clipboard_read_value_async (clipboard, G_TYPE_FILE, 0, NULL, paste_received, dest_stack);
else if (gdk_content_formats_contain_gtype (formats, G_TYPE_STRING))
gdk_clipboard_read_value_async (clipboard, G_TYPE_STRING, 0, NULL, paste_received, dest_stack);
}
/* Get the clipboard object */
clipboard = gtk_widget_get_clipboard (entry);
static void
update_copy_button_sensitivity (GtkWidget *source_stack)
{
GtkButton *copy_button;
const char *visible_child_name;
GtkWidget *visible_child;
gboolean sensitive;
copy_button = GTK_BUTTON (g_object_get_data (G_OBJECT (source_stack), "copy-button"));
visible_child = gtk_stack_get_visible_child (GTK_STACK (source_stack));
visible_child_name = gtk_stack_get_visible_child_name (GTK_STACK (source_stack));
if (strcmp (visible_child_name, "Text") == 0)
{
sensitive = strlen (gtk_editable_get_text (GTK_EDITABLE (visible_child))) > 0;
}
else if (strcmp (visible_child_name, "Color") == 0 ||
strcmp (visible_child_name, "Image") == 0)
{
sensitive = TRUE;
}
else if (strcmp (visible_child_name, "File") == 0)
{
sensitive = g_object_get_data (G_OBJECT (visible_child), "file") != NULL;
}
else
{
sensitive = FALSE;
}
gtk_widget_set_sensitive (GTK_WIDGET (copy_button), sensitive);
}
static void
source_changed_cb (GtkButton *copy_button,
GParamSpec *pspec,
GtkWidget *source_stack)
{
update_copy_button_sensitivity (source_stack);
}
static void
text_changed_cb (GtkButton *copy_button,
GParamSpec *pspec,
GtkWidget *entry)
{
update_copy_button_sensitivity (gtk_widget_get_ancestor (entry, GTK_TYPE_STACK));
}
static void
file_button_set_file (GtkButton *button,
GFile *file)
{
gtk_label_set_label (GTK_LABEL (gtk_button_get_child (button)), g_file_peek_path (file));
g_object_set_data_full (G_OBJECT (button), "file", g_object_ref (file), g_object_unref);
}
static void
file_chooser_response (GtkNativeDialog *dialog,
int response,
GtkButton *button)
{
gtk_native_dialog_hide (dialog);
if (response == GTK_RESPONSE_ACCEPT)
{
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
file_button_set_file (button, file);
g_object_unref (file);
update_copy_button_sensitivity (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK));
}
gtk_native_dialog_destroy (dialog);
}
static void
open_file_cb (GtkWidget *button)
{
GtkFileChooserNative *chooser;
chooser = gtk_file_chooser_native_new ("Choose a file",
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Open",
"_Cancel");
g_signal_connect (chooser, "response", G_CALLBACK (file_chooser_response), button);
gtk_native_dialog_show (GTK_NATIVE_DIALOG (chooser));
}
static void
update_paste_button_sensitivity (GdkClipboard *clipboard,
GtkWidget *paste_button)
{
GdkContentFormats *formats;
gboolean sensitive = FALSE;
formats = gdk_clipboard_get_formats (clipboard);
if (gdk_content_formats_contain_gtype (formats, G_TYPE_FILE) ||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_RGBA) ||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_TEXTURE) ||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_PAINTABLE) ||
gdk_content_formats_contain_gtype (formats, G_TYPE_STRING))
sensitive = TRUE;
gtk_widget_set_sensitive (paste_button, sensitive);
}
static void
unset_clipboard_handler (gpointer data)
{
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
g_signal_handlers_disconnect_by_func (clipboard, update_paste_button_sensitivity, data);
}
static gboolean
on_drop (GtkStack *dest_stack,
const GValue *value,
double x,
double y,
gpointer data)
{
present_value (dest_stack, value);
return TRUE;
}
static GdkContentProvider *
drag_prepare (GtkDragSource *drag_source,
double x,
double y,
gpointer data)
{
GtkWidget *button;
GValue value = G_VALUE_INIT;
button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag_source));
if (GTK_IS_TOGGLE_BUTTON (button))
{
GtkWidget *image = gtk_widget_get_first_child (button);
GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
if (GDK_IS_TEXTURE (paintable))
{
g_value_init (&value, GDK_TYPE_TEXTURE);
g_value_set_object (&value, paintable);
}
else
{
g_value_init (&value, GDK_TYPE_PAINTABLE);
g_value_set_object (&value, paintable);
}
}
else
{
GFile *file = g_object_get_data (G_OBJECT (button), "file");
if (file)
{
g_value_init (&value, G_TYPE_FILE);
g_value_set_object (&value, file);
}
else
return NULL;
}
return gdk_content_provider_new_for_value (&value);
/* Request the contents of the clipboard, contents_received will be
called when we do get the contents.
*/
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
}
GtkWidget *
do_clipboard (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilderScope *scope;
GtkBuilder *builder;
GtkWidget *button;
GtkWidget *vbox, *hbox;
GtkWidget *label;
GtkWidget *entry, *button;
GtkWidget *image;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"copy_button_clicked", G_CALLBACK (copy_button_clicked),
"paste_button_clicked", G_CALLBACK (paste_button_clicked),
"source_changed_cb", G_CALLBACK (source_changed_cb),
"text_changed_cb", G_CALLBACK (text_changed_cb),
"open_file_cb", G_CALLBACK (open_file_cb),
"on_drop", G_CALLBACK (on_drop),
"drag_prepare", G_CALLBACK (drag_prepare),
NULL);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Clipboard");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
button = GTK_WIDGET (gtk_builder_get_object (builder, "copy_button"));
g_object_set_data (gtk_builder_get_object (builder, "source_stack"), "copy-button", button);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_margin_start (vbox, 8);
gtk_widget_set_margin_end (vbox, 8);
gtk_widget_set_margin_top (vbox, 8);
gtk_widget_set_margin_bottom (vbox, 8);
button = GTK_WIDGET (gtk_builder_get_object (builder, "paste_button"));
g_signal_connect (gtk_widget_get_clipboard (button), "changed",
G_CALLBACK (update_paste_button_sensitivity), button);
g_object_set_data_full (G_OBJECT (button), "clipboard-handler", button, unset_clipboard_handler);
gtk_window_set_child (GTK_WINDOW (window), vbox);
g_object_unref (builder);
g_object_unref (scope);
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
gtk_box_append (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox);
/* Create the first entry */
entry = gtk_entry_new ();
gtk_box_append (GTK_BOX (hbox), entry);
/* Create the button */
button = gtk_button_new_with_mnemonic (_("_Copy"));
gtk_box_append (GTK_BOX (hbox), button);
g_signal_connect (button, "clicked",
G_CALLBACK (copy_button_clicked), entry);
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
gtk_box_append (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox);
/* Create the second entry */
entry = gtk_entry_new ();
gtk_box_append (GTK_BOX (hbox), entry);
/* Create the button */
button = gtk_button_new_with_mnemonic (_("_Paste"));
gtk_box_append (GTK_BOX (hbox), button);
g_signal_connect (button, "clicked",
G_CALLBACK (paste_button_clicked), entry);
label = gtk_label_new ("Images can be transferred via the clipboard, too");
gtk_box_append (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox);
/* Create the first image */
image = demo_image_new ("dialog-warning");
gtk_box_append (GTK_BOX (hbox), image);
/* Create the second image */
image = demo_image_new ("process-stop");
gtk_box_append (GTK_BOX (hbox), image);
/* Create the third image */
image = demo_image_new ("weather-clear");
gtk_box_append (GTK_BOX (hbox), image);
}
if (!gtk_widget_get_visible (window))

View File

@@ -1,288 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="resizable">1</property>
<property name="title">Clipboard</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
<property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the current clipboard contents. You can also drag the data to the bottom.</property>
<property name="wrap">1</property>
<property name="max-width-chars">40</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">12</property>
<child>
<object class="GtkDropDown" id="source_chooser">
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
<items>
<item>Text</item>
<item>Color</item>
<item>Image</item>
<item>File</item>
</items>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStack" id="source_stack">
<signal name="notify::visible-child" handler="source_changed_cb" object="copy_button"/>
<property name="vexpand">1</property>
<binding name="visible-child-name">
<lookup name="string" type="GtkStringObject">
<lookup name="selected-item">
source_chooser
</lookup>
</lookup>
</binding>
<child>
<object class="GtkStackPage">
<property name="name">Text</property>
<property name="child">
<object class="GtkEntry" id="source_text">
<property name="valign">center</property>
<signal name="notify::text" handler="text_changed_cb" object="copy_button"/>
<property name="text">Copy this!</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Color</property>
<property name="child">
<object class="GtkColorButton" id="source_color">
<property name="valign">center</property>
<property name="rgba">purple</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Image</property>
<property name="child">
<object class="GtkBox">
<property name="valign">center</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkToggleButton" id="image_rose">
<property name="active">1</property>
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<child>
<object class="GtkImage">
<style>
<class name="large-icons"/>
</style>
<property name="paintable">resource:///transparent/portland-rose.jpg</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="image_floppy">
<property name="group">image_rose</property>
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<child>
<object class="GtkImage">
<style>
<class name="large-icons"/>
</style>
<property name="paintable">resource:///images/floppybuddy.gif</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="image_logo">
<property name="group">image_floppy</property>
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<child>
<object class="GtkImage">
<style>
<class name="large-icons"/>
</style>
<property name="paintable">resource:///images/org.gtk.Demo4.svg</property>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">File</property>
<property name="child">
<object class="GtkButton" id="source_file">
<child>
<object class="GtkDragSource">
<property name="propagation-phase">capture</property>
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<property name="valign">center</property>
<property name="child">
<object class="GtkLabel">
<property name="label">—</property>
<property name="xalign">0</property>
<property name="ellipsize">start</property>
</object>
</property>
<signal name="clicked" handler="open_file_cb"/>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="copy_button">
<property name="valign">center</property>
<property name="label" translatable="yes">_Copy</property>
<signal name="clicked" handler="copy_button_clicked" object="source_stack"/>
<property name="use-underline">1</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator">
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">12</property>
<child>
<object class="GtkDropTarget">
<property name="actions">copy</property>
<property name="formats">GdkTexture GdkPaintable GFile GdkRGBA gchararray</property>
<signal name="drop" handler="on_drop" object="dest_stack"/>
</object>
</child>
<child>
<object class="GtkButton" id="paste_button">
<property name="label" translatable="yes">_Paste</property>
<signal name="clicked" handler="paste_button_clicked" object="dest_stack"/>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="visible-child-name" type="GtkStack">
dest_stack
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkStack" id="dest_stack">
<property name="halign">end</property>
<property name="valign">center</property>
<child>
<object class="GtkStackPage">
<property name="name"></property>
<property name="child">
<object class="GtkLabel">
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Text</property>
<property name="child">
<object class="GtkLabel">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="xalign">0</property>
<property name="ellipsize">end</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Image</property>
<property name="child">
<object class="GtkImage">
<property name="halign">end</property>
<property name="valign">center</property>
<style>
<class name="large-icons"/>
</style>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Color</property>
<property name="child">
<object class="GtkBox">
<property name="halign">end</property>
<property name="valign">center</property>
<child>
<object class="GtkColorSwatch">
<property name="accessible-role">img</property>
<property name="can-focus">0</property>
<property name="selectable">0</property>
<property name="has-menu">0</property>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">File</property>
<property name="child">
<object class="GtkLabel">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="xalign">0</property>
<property name="hexpand">1</property>
<property name="ellipsize">start</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -24,7 +24,6 @@ do_cursors (GtkWidget *do_widget)
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
@@ -35,7 +34,9 @@ do_cursors (GtkWidget *do_widget)
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
{
gtk_window_destroy (GTK_WINDOW (window));
}
return window;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +0,0 @@
#pragma once
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define CURVE_TYPE_EDITOR (curve_editor_get_type ())
G_DECLARE_FINAL_TYPE (CurveEditor, curve_editor, CURVE, EDITOR, GtkWidget)
GtkWidget * curve_editor_new (void);
void curve_editor_set_edit (CurveEditor *self,
gboolean edit);
void curve_editor_set_path (CurveEditor *self,
GskPath *path);
GskPath * curve_editor_get_path (CurveEditor *self);
void curve_editor_set_stroke (CurveEditor *self,
GskStroke *stroke);
const GskStroke * curve_editor_get_stroke (CurveEditor *self);
void curve_editor_set_color (CurveEditor *self,
GdkRGBA *color);
const GdkRGBA * curve_editor_get_color (CurveEditor *self);
gboolean curve_editor_get_show_outline (CurveEditor *self);
void curve_editor_set_show_outline (CurveEditor *self,
gboolean show_outline);
G_END_DECLS

View File

@@ -1,272 +0,0 @@
/* Path/Curve Editor
*
* This demo shows an elaborate curve editor that you would expect to find
* in a vector graphics editor. It is built on top of GTK's path APIs.
*/
#include <gtk/gtk.h>
#include "curve-editor.h"
static GskPath *
make_circle_path (void)
{
float w = 310;
float h = 310;
float cx = w / 2;
float cy = h / 2;
float pad = 20;
float r = (w - 2 * pad) / 2;
float k = 0.55228;
float kr = k * r;
GskPathBuilder *builder;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, cx, pad);
gsk_path_builder_curve_to (builder, cx + kr, pad,
w - pad, cy - kr,
w - pad, cy);
gsk_path_builder_curve_to (builder, w - pad, cy + kr,
cx + kr, h - pad,
cx, h - pad);
gsk_path_builder_curve_to (builder, cx - kr, h - pad,
pad, cy + kr,
pad, cy);
gsk_path_builder_curve_to (builder, pad, cy - kr,
cx - kr, pad,
cx, pad);
gsk_path_builder_close (builder);
return gsk_path_builder_free_to_path (builder);
}
static void
edit_changed (GtkToggleButton *button,
GParamSpec *pspec,
CurveEditor *editor)
{
curve_editor_set_edit (editor, gtk_toggle_button_get_active (button));
}
static void
reset (GtkButton *button,
CurveEditor *editor)
{
GskPath *path;
path = make_circle_path ();
curve_editor_set_path (editor, path);
gsk_path_unref (path);
}
static void
line_width_changed (GtkSpinButton *spin,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_width (stroke, gtk_spin_button_get_value (spin));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
cap_changed (GtkDropDown *combo,
GParamSpec *pspec,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_cap (stroke, (GskLineCap)gtk_drop_down_get_selected (combo));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
join_changed (GtkDropDown *combo,
GParamSpec *pspec,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_join (stroke, (GskLineJoin)gtk_drop_down_get_selected (combo));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
color_changed (GtkColorChooser *chooser,
GParamSpec *pspec,
CurveEditor *editor)
{
GdkRGBA color;
gtk_color_chooser_get_rgba (chooser, &color);
curve_editor_set_color (editor, &color);
}
static void
stroke_toggled (GtkCheckButton *button,
CurveEditor *editor)
{
curve_editor_set_show_outline (editor, gtk_check_button_get_active (button));
gtk_widget_queue_draw (GTK_WIDGET (editor));
}
static void
limit_changed (GtkSpinButton *spin,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_miter_limit (stroke, gtk_spin_button_get_value (spin));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
dashes_changed (GtkEntry *entry,
GParamSpec *spec,
CurveEditor *editor)
{
const char *text;
char **split;
GArray *dash;
GskStroke *stroke;
text = gtk_editable_get_text (GTK_EDITABLE (entry));
split = g_strsplit (text, " ", 0);
dash = g_array_new (FALSE, FALSE, sizeof (float));
for (int i = 0; split[i] != NULL; i++)
{
double d;
char *endp = 0;
d = g_strtod (split[i], &endp);
if (*endp == '\0')
g_array_append_vals (dash, (float[1]) { d }, 1);
}
g_strfreev (split);
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_dash (stroke, (const float *)dash->data, dash->len);
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
g_array_free (dash, TRUE);
}
GtkWidget *
do_curve (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *demo;
GtkWidget *edit_toggle;
GtkWidget *reset_button;
GtkWidget *titlebar;
GtkWidget *stroke_toggle;
GtkWidget *line_width_spin;
GtkWidget *stroke_button;
GtkWidget *popover;
GtkWidget *grid;
GtkWidget *cap_combo;
GtkWidget *join_combo;
GtkWidget *color_button;
GtkWidget *limit_spin;
GtkWidget *dash_entry;
if (!window)
{
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Curve Editor");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_default_size (GTK_WINDOW (window), 315, 350);
edit_toggle = gtk_toggle_button_new ();
gtk_button_set_icon_name (GTK_BUTTON (edit_toggle), "document-edit-symbolic");
reset_button = gtk_button_new_from_icon_name ("edit-undo-symbolic");
stroke_button = gtk_menu_button_new ();
gtk_menu_button_set_icon_name (GTK_MENU_BUTTON (stroke_button), "open-menu-symbolic");
popover = gtk_popover_new ();
gtk_menu_button_set_popover (GTK_MENU_BUTTON (stroke_button), popover);
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_popover_set_child (GTK_POPOVER (popover), grid);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Color:"), 0, 0, 1, 1);
color_button = gtk_color_button_new_with_rgba (&(GdkRGBA){ 0., 0., 0., 1.});
gtk_grid_attach (GTK_GRID (grid), color_button, 1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line width:"), 0, 1, 1, 1);
line_width_spin = gtk_spin_button_new_with_range (1, 20, 1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (line_width_spin), 1);
gtk_grid_attach (GTK_GRID (grid), line_width_spin, 1, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line cap:"), 0, 2, 1, 1);
cap_combo = gtk_drop_down_new_from_strings ((const char *[]){"Butt", "Round", "Square", NULL});
gtk_grid_attach (GTK_GRID (grid), cap_combo, 1, 2, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line join:"), 0, 3, 1, 1);
join_combo = gtk_drop_down_new_from_strings ((const char *[]){"Miter", "Miter-clip", "Round", "Bevel", "Arcs", NULL});
gtk_grid_attach (GTK_GRID (grid), join_combo, 1, 3, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Miter limit:"), 0, 4, 1, 1);
limit_spin = gtk_spin_button_new_with_range (0, 10, 1);
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (limit_spin), 1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (limit_spin), 4);
gtk_grid_attach (GTK_GRID (grid), limit_spin, 1, 4, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Dashes:"), 0, 5, 1, 1);
dash_entry = gtk_entry_new ();
gtk_grid_attach (GTK_GRID (grid), dash_entry, 1, 5, 1, 1);
stroke_toggle = gtk_check_button_new_with_label ("Show outline");
gtk_grid_attach (GTK_GRID (grid), stroke_toggle, 1, 6, 1, 1);
titlebar = gtk_header_bar_new ();
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), edit_toggle);
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), reset_button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), stroke_button);
gtk_window_set_titlebar (GTK_WINDOW (window), titlebar);
demo = curve_editor_new ();
g_signal_connect (stroke_toggle, "toggled", G_CALLBACK (stroke_toggled), demo);
g_signal_connect (edit_toggle, "notify::active", G_CALLBACK (edit_changed), demo);
g_signal_connect (reset_button, "clicked", G_CALLBACK (reset), demo);
g_signal_connect (cap_combo, "notify::selected", G_CALLBACK (cap_changed), demo);
g_signal_connect (join_combo, "notify::selected", G_CALLBACK (join_changed), demo);
g_signal_connect (color_button, "notify::rgba", G_CALLBACK (color_changed), demo);
g_signal_connect (line_width_spin, "value-changed", G_CALLBACK (line_width_changed), demo);
g_signal_connect (limit_spin, "value-changed", G_CALLBACK (limit_changed), demo);
g_signal_connect (dash_entry, "notify::text", G_CALLBACK (dashes_changed), demo);
reset (NULL, CURVE_EDITOR (demo));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (line_width_spin), 6);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (color_button), &(GdkRGBA) { 1, 0, 0, 1 });
gtk_drop_down_set_selected (GTK_DROP_DOWN (cap_combo), GSK_LINE_CAP_ROUND);
gtk_editable_set_text (GTK_EDITABLE (dash_entry), "0 8");
gtk_window_set_child (GTK_WINDOW (window), demo);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -15,7 +15,6 @@
<file>demo.ui</file>
</gresource>
<gresource prefix="/clipboard">
<file>clipboard.ui</file>
<file>demoimage.c</file>
<file>demoimage.h</file>
</gresource>
@@ -128,7 +127,6 @@
<file>fishbowl.ui</file>
<file>gtkfishbowl.c</file>
<file>gtkfishbowl.h</file>
<file>tiger.node</file>
</gresource>
<gresource prefix="/frames">
<file>frames.ui</file>
@@ -251,10 +249,6 @@
<gresource prefix="/video-player">
<file>bbb.png</file>
</gresource>
<gresource prefix="/curve">
<file>curve-editor.c</file>
<file>curve-editor.h</file>
</gresource>
<gresource prefix="/sources">
<file>application_demo.c</file>
<file>assistant.c</file>
@@ -272,7 +266,6 @@
<file>css_pixbufs.c</file>
<file>css_shadows.c</file>
<file>cursors.c</file>
<file>curve.c</file>
<file>dialog.c</file>
<file>drawingarea.c</file>
<file>dropdown.c</file>
@@ -293,7 +286,6 @@
<file>gears.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>glyphs.c</file>
<file>gltransition.c</file>
<file>headerbar.c</file>
<file>hypertext.c</file>
@@ -329,12 +321,8 @@
<file>paintable_emblem.c</file>
<file>paintable_mediastream.c</file>
<file>paintable_svg.c</file>
<file>paintable_symbolic.c</file>
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_maze.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
<file>printing.c</file>
@@ -419,9 +407,6 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>

View File

@@ -100,11 +100,7 @@ prepare_drag (GtkDragSource *source,
DemoImage *demo = DEMO_IMAGE (widget);
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
/* Textures can be serialized, paintables can't, so special case the textures */
if (GDK_IS_TEXTURE (paintable))
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
else
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
}
static gboolean
@@ -133,11 +129,7 @@ copy_image (GtkWidget *widget,
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
GValue value = G_VALUE_INIT;
/* Textures can be serialized, paintables can't, so special case the textures */
if (GDK_IS_TEXTURE (paintable))
g_value_init (&value, GDK_TYPE_TEXTURE);
else
g_value_init (&value, GDK_TYPE_PAINTABLE);
g_value_init (&value, GDK_TYPE_PAINTABLE);
g_value_set_object (&value, paintable);
gdk_clipboard_set_value (clipboard, &value);
g_value_unset (&value);
@@ -146,46 +138,24 @@ copy_image (GtkWidget *widget,
g_object_unref (paintable);
}
static void
paste_image_cb (GObject *source,
GAsyncResult *result,
gpointer data)
{
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
DemoImage *demo = DEMO_IMAGE (data);
const GValue *value;
value = gdk_clipboard_read_value_finish (clipboard, result, NULL);
if (value == NULL)
{
gtk_widget_error_bell (GTK_WIDGET (demo));
g_object_unref (demo);
return;
}
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), g_value_get_object (value));
g_object_unref (demo);
}
static void
paste_image (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
GType type;
DemoImage *demo = DEMO_IMAGE (widget);
GdkContentProvider *content = gdk_clipboard_get_content (clipboard);
GValue value = G_VALUE_INIT;
GdkPaintable *paintable;
if (gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GDK_TYPE_TEXTURE))
type = GDK_TYPE_TEXTURE;
else
type = GDK_TYPE_PAINTABLE;
g_value_init (&value, GDK_TYPE_PAINTABLE);
if (!gdk_content_provider_get_value (content, &value, NULL))
return;
gdk_clipboard_read_value_async (clipboard,
type,
G_PRIORITY_DEFAULT,
NULL,
paste_image_cb,
g_object_ref (widget));
paintable = GDK_PAINTABLE (g_value_get_object (&value));
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
g_value_unset (&value);
}
static void

View File

@@ -11,9 +11,6 @@
#include "gtkgears.h"
#include "gskshaderpaintable.h"
#include "nodewidget.h"
#include "graphwidget.h"
const char *const css =
".blurred-button {"
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
@@ -204,18 +201,6 @@ create_menu_button (void)
return w;
}
static GtkWidget *
create_tiger (void)
{
return node_widget_new ("/fishbowl/tiger.node");
}
static GtkWidget *
create_graph (void)
{
return graph_widget_new ();
}
static const struct {
const char *name;
GtkWidget * (*create_func) (void);
@@ -233,8 +218,6 @@ static const struct {
{ "Switch", create_switch },
{ "Menubutton", create_menu_button },
{ "Shader", create_cogs },
{ "Tiger", create_tiger },
{ "Graph", create_graph },
};
static int selected_widget_type = -1;

View File

@@ -13,13 +13,13 @@
</style>
<child>
<object class="GtkButton">
<property name="icon-name">go-previous-symbolic</property>
<property name="icon-name">pan-start-symbolic</property>
<signal name="clicked" handler="fishbowl_prev_button_clicked_cb" object="bowl" swapped="no"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">go-next-symbolic</property>
<property name="icon-name">pan-end-symbolic</property>
<signal name="clicked" handler="fishbowl_next_button_clicked_cb" object="bowl" swapped="no"/>
</object>
</child>

View File

@@ -10,8 +10,12 @@
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
<child>
<object class="GtkImage">
<property name="icon-name">view-refresh-symbolic</property>
</object>
</child>
</object>
</child>
</object>

View File

@@ -12,6 +12,7 @@
*/
#include <gtk/gtk.h>
#include <pango/pangofc-font.h>
#include <hb.h>
#include <hb-ot.h>
#include <glib/gi18n.h>
@@ -1135,7 +1136,7 @@ done:
g_free (design_coords);
}
G_MODULE_EXPORT void
void
font_features_font_changed (void)
{
update_script_combo ();
@@ -1143,14 +1144,14 @@ font_features_font_changed (void)
update_font_variations ();
}
G_MODULE_EXPORT void
void
font_features_script_changed (void)
{
update_features ();
update_display ();
}
G_MODULE_EXPORT void
void
font_features_reset_features (void)
{
GList *l;
@@ -1196,7 +1197,7 @@ switch_to_label (void)
update_display ();
}
G_MODULE_EXPORT void
void
font_features_toggle_edit (void)
{
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (stack)), "label") == 0)
@@ -1205,7 +1206,7 @@ font_features_toggle_edit (void)
switch_to_label ();
}
G_MODULE_EXPORT void
void
font_features_stop_edit (void)
{
g_signal_emit_by_name (edit_toggle, "clicked");

View File

@@ -131,19 +131,6 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define VOID_ATTR(attr_name) \
{ \
tag = gtk_text_tag_table_lookup (table, #attr_name); \
if (!tag) \
{ \
tag = gtk_text_tag_new (#attr_name); \
g_object_set (tag, #attr_name, TRUE, NULL); \
gtk_text_tag_table_add (table, tag); \
g_object_unref (tag); \
} \
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
fg_alpha = bg_alpha = 1.;
attrs = pango_attr_iterator_get_attrs (iter);
@@ -268,29 +255,6 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
INT_ATTR (insert_hyphens);
break;
case PANGO_ATTR_LINE_HEIGHT:
FLOAT_ATTR (line_height);
break;
case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
break;
case PANGO_ATTR_WORD:
VOID_ATTR (word);
break;
case PANGO_ATTR_SENTENCE:
VOID_ATTR (sentence);
break;
case PANGO_ATTR_BASELINE_SHIFT:
INT_ATTR (baseline_shift);
break;
case PANGO_ATTR_FONT_SCALE:
INT_ATTR (font_scale);
break;
case PANGO_ATTR_SHAPE:
case PANGO_ATTR_ABSOLUTE_SIZE:
case PANGO_ATTR_GRAVITY:
@@ -299,10 +263,6 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
case PANGO_ATTR_BACKGROUND_ALPHA:
break;
case PANGO_ATTR_TEXT_TRANSFORM:
INT_ATTR (text_transform);
break;
case PANGO_ATTR_INVALID:
default:
g_assert_not_reached ();

View File

@@ -1,11 +1,6 @@
/* Pango/Font Rendering
*
* Demonstrates various aspects of font rendering,
* such as hinting, antialiasing and grid alignment.
*
* The demo lets you explore font rendering options
* interactively to get a feeling for they affect the
* shape and positioning of the glyphs.
* Demonstrates various aspects of font rendering.
*/
#include <gtk/gtk.h>
@@ -15,21 +10,16 @@ static GtkWidget *font_button = NULL;
static GtkWidget *entry = NULL;
static GtkWidget *image = NULL;
static GtkWidget *hinting = NULL;
static GtkWidget *anti_alias = NULL;
static GtkWidget *hint_metrics = NULL;
static GtkWidget *up_button = NULL;
static GtkWidget *down_button = NULL;
static GtkWidget *text_radio = NULL;
static GtkWidget *show_grid = NULL;
static GtkWidget *show_extents = NULL;
static GtkWidget *show_pixels = NULL;
static GtkWidget *show_outlines = NULL;
static PangoContext *context;
static int scale = 7;
static double pixel_alpha = 1.0;
static double outline_alpha = 0.0;
static int scale = 9;
static void
update_image (void)
@@ -37,7 +27,7 @@ update_image (void)
const char *text;
PangoFontDescription *desc;
PangoLayout *layout;
PangoRectangle ink, logical;
PangoRectangle ink, pink, logical;
int baseline;
cairo_surface_t *surface;
cairo_t *cr;
@@ -47,8 +37,6 @@ update_image (void)
cairo_font_options_t *fopt;
cairo_hint_style_t hintstyle;
cairo_hint_metrics_t hintmetrics;
cairo_antialias_t antialias;
cairo_path_t *path;
if (!context)
context = gtk_widget_create_pango_context (image);
@@ -59,18 +47,16 @@ update_image (void)
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
if (hint)
{
if (strcmp (hint, "none") == 0)
hintstyle = CAIRO_HINT_STYLE_NONE;
else if (strcmp (hint, "slight") == 0)
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
else if (strcmp (hint, "medium") == 0)
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
else if (strcmp (hint, "full") == 0)
hintstyle = CAIRO_HINT_STYLE_FULL;
}
if (strcmp (hint, "none") == 0)
hintstyle = CAIRO_HINT_STYLE_NONE;
else if (strcmp (hint, "slight") == 0)
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
else if (strcmp (hint, "medium") == 0)
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
else if (strcmp (hint, "full") == 0)
hintstyle = CAIRO_HINT_STYLE_FULL;
else
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
cairo_font_options_set_hint_style (fopt, hintstyle);
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (hint_metrics)))
@@ -79,13 +65,6 @@ update_image (void)
hintmetrics = CAIRO_HINT_METRICS_OFF;
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (anti_alias)))
antialias = CAIRO_ANTIALIAS_GRAY;
else
antialias = CAIRO_ANTIALIAS_NONE;
cairo_font_options_set_antialias (fopt, antialias);
pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango_context_changed (context);
@@ -96,6 +75,7 @@ update_image (void)
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, text, -1);
pango_layout_get_extents (layout, &ink, &logical);
pink = ink;
baseline = pango_layout_get_baseline (layout);
pango_extents_to_pixels (&ink, NULL);
@@ -105,14 +85,10 @@ update_image (void)
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
cairo_set_source_rgba (cr, 0, 0, 0, pixel_alpha);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_move_to (cr, 10, 10);
pango_cairo_show_layout (cr, layout);
pango_cairo_layout_path (cr, layout);
path = cairo_copy_path (cr);
cairo_destroy (cr);
g_object_unref (layout);
@@ -151,7 +127,7 @@ update_image (void)
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (show_extents)))
{
cairo_set_source_rgb (cr, 0, 0, 1);
cairo_set_source_rgba (cr, 0, 0, 1, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
@@ -164,45 +140,17 @@ update_image (void)
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_stroke (cr);
cairo_set_source_rgb (cr, 1, 0, 0);
cairo_set_source_rgba (cr, 1, 0, 0, 1);
cairo_rectangle (cr,
scale * (10 + ink.x) - 0.5,
scale * (10 + ink.y) - 0.5,
scale * ink.width + 1,
scale * ink.height + 1);
scale * (10 + pango_units_to_double (pink.x)) + 0.5,
scale * (10 + pango_units_to_double (pink.y)) + 0.5,
scale * pango_units_to_double (pink.width) - 1,
scale * pango_units_to_double (pink.height) - 1);
cairo_stroke (cr);
}
for (int i = 0; i < path->num_data; i += path->data[i].header.length)
{
cairo_path_data_t *data = &path->data[i];
switch (data->header.type)
{
case CAIRO_PATH_CURVE_TO:
data[3].point.x *= scale; data[3].point.y *= scale;
data[2].point.x *= scale; data[2].point.y *= scale;
data[1].point.x *= scale; data[1].point.y *= scale;
break;
case CAIRO_PATH_LINE_TO:
case CAIRO_PATH_MOVE_TO:
data[1].point.x *= scale; data[1].point.y *= scale;
break;
case CAIRO_PATH_CLOSE_PATH:
break;
default:
g_assert_not_reached ();
}
}
cairo_set_source_rgba (cr, 0, 0, 0, outline_alpha);
cairo_move_to (cr, scale * 20 - 0.5, scale * 20 - 0.5);
cairo_append_path (cr, path);
cairo_stroke (cr);
cairo_surface_destroy (surface);
cairo_destroy (cr);
cairo_path_destroy (path);
}
else
{
@@ -210,26 +158,10 @@ update_image (void)
PangoLayoutRun *run;
PangoGlyphInfo *g;
int i, j;
GString *str;
gunichar ch;
if (*text == '\0')
text = " ";
ch = g_utf8_get_char (text);
str = g_string_new ("");
for (i = 0; i < 4; i++)
{
g_string_append_unichar (str, ch);
g_string_append_unichar (str, 0x200c);
}
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, str->str, -1);
g_string_free (str, TRUE);
pango_layout_set_text (layout, "aaaa", -1);
pango_layout_get_extents (layout, &ink, &logical);
pango_extents_to_pixels (&logical, NULL);
@@ -244,7 +176,7 @@ update_image (void)
cairo_set_source_rgb (cr, 0, 0, 0);
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[2*i]);
g = &(run->glyphs->glyphs[i]);
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
}
@@ -252,7 +184,7 @@ update_image (void)
{
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[2*i]);
g = &(run->glyphs->glyphs[i]);
g->geometry.x_offset = i * (PANGO_SCALE / 4);
g->geometry.y_offset = j * (PANGO_SCALE / 4);
}
@@ -271,6 +203,7 @@ update_image (void)
cairo_surface_destroy (surface);
}
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
g_object_unref (pixbuf2);
@@ -278,78 +211,6 @@ update_image (void)
pango_font_description_free (desc);
}
static gboolean fading = FALSE;
static double start_pixel_alpha;
static double end_pixel_alpha;
static double start_outline_alpha;
static double end_outline_alpha;
static gint64 start_time;
static gint64 end_time;
static double
ease_out_cubic (double t)
{
double p = t - 1;
return p * p * p + 1;
}
static gboolean
change_alpha (GtkWidget *widget,
GdkFrameClock *clock,
gpointer user_data)
{
gint64 now = g_get_monotonic_time ();
double t;
t = ease_out_cubic ((now - start_time) / (double) (end_time - start_time));
pixel_alpha = start_pixel_alpha + (end_pixel_alpha - start_pixel_alpha) * t;
outline_alpha = start_outline_alpha + (end_outline_alpha - start_outline_alpha) * t;
update_image ();
if (now >= end_time)
{
fading = FALSE;
return G_SOURCE_REMOVE;
}
return G_SOURCE_CONTINUE;
}
static void
start_alpha_fade (void)
{
gboolean pixels;
gboolean outlines;
if (fading)
return;
pixels = gtk_check_button_get_active (GTK_CHECK_BUTTON (show_pixels));
outlines = gtk_check_button_get_active (GTK_CHECK_BUTTON (show_outlines));
start_pixel_alpha = pixel_alpha;
if (pixels && outlines)
end_pixel_alpha = 0.5;
else if (pixels)
end_pixel_alpha = 1;
else
end_pixel_alpha = 0;
start_outline_alpha = outline_alpha;
if (outlines)
end_outline_alpha = 1.0;
else
end_outline_alpha = 0.0;
start_time = g_get_monotonic_time ();
end_time = start_time + G_TIME_SPAN_SECOND / 2;
fading = TRUE;
gtk_widget_add_tick_callback (window, change_alpha, NULL, NULL);
}
static void
update_buttons (void)
{
@@ -357,26 +218,20 @@ update_buttons (void)
gtk_widget_set_sensitive (down_button, scale > 1);
}
static gboolean
scale_up (GtkWidget *widget,
GVariant *args,
gpointer user_data)
static void
scale_up (void)
{
scale += 1;
update_buttons ();
update_image ();
return TRUE;
}
static gboolean
scale_down (GtkWidget *widget,
GVariant *args,
gpointer user_data)
static void
scale_down (void)
{
scale -= 1;
update_buttons ();
update_image ();
return TRUE;
}
GtkWidget *
@@ -397,26 +252,20 @@ do_fontrendering (GtkWidget *do_widget)
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
anti_alias = GTK_WIDGET (gtk_builder_get_object (builder, "antialias"));
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
show_extents = GTK_WIDGET (gtk_builder_get_object (builder, "show_extents"));
show_pixels = GTK_WIDGET (gtk_builder_get_object (builder, "show_pixels"));
show_outlines = GTK_WIDGET (gtk_builder_get_object (builder, "show_outlines"));
g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL);
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (anti_alias, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_extents, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_pixels, "notify::active", G_CALLBACK (start_alpha_fade), NULL);
g_signal_connect (show_outlines, "notify::active", G_CALLBACK (start_alpha_fade), NULL);
update_image ();

View File

@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="scale_adj">
<property name="upper">24</property>
<property name="step-increment">1</property>
<property name="page-increment">4</property>
</object>
<object class="GtkWindow" id="window">
<property name="default-width">1024</property>
<property name="default-height">768</property>
<property name="default-width">1080</property>
<property name="default-height">430</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="title">
@@ -82,119 +87,69 @@
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_pixels">
<property name="label">Show _Pixels</property>
<property name="use-underline">1</property>
<property name="active">1</property>
<object class="GtkLabel">
<property name="label">Hinting</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="column">3</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_outlines">
<property name="label">Show _Outline</property>
<property name="use-underline">1</property>
<layout>
<property name="column">3</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="label">_Hinting</property>
<property name="use-underline">1</property>
<property name="mnemonic-widget">hinting</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="hinting">
<property name="active">0</property>
<property name="valign">center</property>
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="slight">Slight</item>
<item translatable="yes" id="medium">Medium</item>
<item translatable="yes" id="full">Full</item>
</items>
</object>
</child>
<object class="GtkComboBoxText" id="hinting">
<property name="active">0</property>
<property name="valign">center</property>
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="slight">Slight</item>
<item translatable="yes" id="medium">Medium</item>
<item translatable="yes" id="full">Full</item>
</items>
<layout>
<property name="column">4</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="antialias">
<property name="label">_Antialias</property>
<property name="use-underline">1</property>
<property name="active">1</property>
<layout>
<property name="column">4</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="hint_metrics">
<property name="label">Hint _Metrics</property>
<property name="use-underline">1</property>
<property name="label">Hint Metrics</property>
<layout>
<property name="column">4</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_extents">
<property name="label">Show Extents</property>
<property name="active">1</property>
<layout>
<property name="column">5</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_grid">
<property name="active">1</property>
<property name="label">Show Grid</property>
<layout>
<property name="column">5</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_extents">
<property name="label">Show _Extents</property>
<property name="use-underline">1</property>
<layout>
<property name="column">6</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_grid">
<property name="label">Show _Grid</property>
<property name="use-underline">1</property>
<layout>
<property name="column">6</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="up_button">
<property name="icon-name">list-add-symbolic</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<child>
<object class="GtkShortcutController">
<property name="scope">managed</property>
<child>
<object class="GtkShortcut">
<property name="trigger">&lt;Control&gt;plus</property>
<property name="action">activate</property>
</object>
</child>
</object>
</child>
<layout>
<property name="column">7</property>
<property name="column">6</property>
<property name="row">0</property>
</layout>
</object>
@@ -202,24 +157,11 @@
<child>
<object class="GtkButton" id="down_button">
<property name="icon-name">list-remove-symbolic</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<child>
<object class="GtkShortcutController">
<property name="scope">managed</property>
<child>
<object class="GtkShortcut">
<property name="trigger">&lt;Control&gt;minus</property>
<property name="action">activate</property>
</object>
</child>
</object>
</child>
<layout>
<property name="column">7</property>
<property name="column">6</property>
<property name="row">1</property>
</layout>
</object>
@@ -228,7 +170,7 @@
<object class="GtkLabel">
<property name="hexpand">1</property>
<layout>
<property name="column">8</property>
<property name="column">7</property>
</layout>
</object>
</child>

File diff suppressed because it is too large Load Diff

View File

@@ -1,164 +0,0 @@
#include "graphwidget.h"
struct _GraphWidget
{
GtkWidget parent_instance;
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
GskPath *stroke_path;
guint tick_cb;
guint64 start_time;
double period;
double amplitude;
};
struct _GraphWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GraphWidget, graph_widget, GTK_TYPE_WIDGET)
static void
update_path (GraphWidget *self,
float amplitude)
{
graphene_point_t p[20];
GskPathBuilder *builder;
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->stroke_path, gsk_path_unref);
for (int i = 0; i < 20; i++)
{
p[i].x = 10 * i;
p[i].y = 50;
if (i % 4 == 1 || i % 4 == 2)
{
if (i % 8 < 4)
p[i].y += amplitude;
else
p[i].y -= amplitude;
}
}
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, p[0].x, p[0].y);
for (int i = 0; i < 20; i += 4)
gsk_path_builder_curve_to (builder,
p[i+1].x, p[i+1].y,
p[i+2].x, p[i+2].y,
p[i+3].x, p[i+3].y);
self->path = gsk_path_builder_free_to_path (builder);
self->stroke_path = gsk_path_stroke (self->path, self->stroke);
}
static gboolean
tick_cb (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GraphWidget *self = GRAPH_WIDGET (widget);
guint64 now;
double angle;
now = gdk_frame_clock_get_frame_time (frame_clock);
if (self->start_time == 0)
self->start_time = now;
angle = 360 * (now - self->start_time) / (double)(self->period * G_TIME_SPAN_MINUTE);
update_path (self, sin (angle) * self->amplitude);
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
graph_widget_init (GraphWidget *self)
{
self->color.red = g_random_double_range (0, 1);
self->color.green = g_random_double_range (0, 1);
self->color.blue = g_random_double_range (0, 1);
self->color.alpha = 1;
self->period = g_random_double_range (0.5, 1);
self->amplitude = g_random_double_range (10, 25);
self->stroke = gsk_stroke_new (2);
update_path (self, 0);
self->start_time = 0;
self->tick_cb = gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_cb, NULL, NULL);
}
static void
graph_widget_dispose (GObject *object)
{
GraphWidget *self = GRAPH_WIDGET (object);
gsk_path_unref (self->path);
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (graph_widget_parent_class)->dispose (object);
}
static void
graph_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GraphWidget *self = GRAPH_WIDGET (widget);
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_snapshot_push_fill (snapshot, self->stroke_path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot,
&self->color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
static void
graph_widget_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = 200;
else
*minimum = *natural = 100;
}
static void
graph_widget_class_init (GraphWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = graph_widget_dispose;
widget_class->snapshot = graph_widget_snapshot;
widget_class->measure = graph_widget_measure;
}
GtkWidget *
graph_widget_new (void)
{
return g_object_new (GRAPH_TYPE_WIDGET, NULL);
}

View File

@@ -1,8 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define GRAPH_TYPE_WIDGET (graph_widget_get_type ())
G_DECLARE_FINAL_TYPE (GraphWidget, graph_widget, GRAPH, WIDGET, GtkWidget)
GtkWidget * graph_widget_new (void);

View File

@@ -23,10 +23,13 @@
#include "gskshaderpaintable.h"
/**
* GskShaderPaintable:
* SECTION:gskshaderpaintable
* @Short_description: Drawing with shaders
* @Title: GskShaderPaintable
* @see_also: #GdkPaintable
*
* `GskShaderPaintable` is an implementation of the `GdkPaintable` interface
* that uses a `GskGLShader` to create pixels.
* GskShaderPaintable is an implementation of the #GdkPaintable interface
* that uses a #GskGLShader to create pixels.
*
* You can set the uniform data that the shader needs for rendering
* using gsk_shader_paintable_set_args(). This function can
@@ -35,7 +38,7 @@
*
* Commonly, time is passed to shaders as a float uniform containing
* the elapsed time in seconds. The convenience API
* gsk_shader_paintable_update_time() can be called from a `GtkTickCallback`
* gsk_shader_paintable_update_time() can be called from a #GtkTickCallback
* to update the time based on the frame time of the frame clock.
*/
@@ -183,7 +186,7 @@ gsk_shader_paintable_init (GskShaderPaintable *self)
* pixels. The shader must not require input textures.
* If @data is %NULL, all uniform values are set to zero.
*
* Returns: (transfer full): a new `GskShaderPaintable`
* Returns: (transfer full): a new #GskShaderPaintable
*/
GdkPaintable *
gsk_shader_paintable_new (GskGLShader *shader,
@@ -212,8 +215,8 @@ gsk_shader_paintable_new (GskGLShader *shader,
/**
* gsk_shader_paintable_set_shader:
* @self: a `GskShaderPaintable`
* @shader: the `GskGLShader` to use
* @self: a #GskShaderPaintable
* @shader: the #GskGLShader to use
*
* Sets the shader that the paintable will use
* to create pixels. The shader must not require
@@ -238,11 +241,11 @@ gsk_shader_paintable_set_shader (GskShaderPaintable *self,
/**
* gsk_shader_paintable_get_shader:
* @self: a `GskShaderPaintable`
* @self: a #GskShaderPaintable
*
* Returns the shader that the paintable is using.
*
* Returns: (transfer none): the `GskGLShader` that is used
* Returns: (transfer none): the #GskGLShader that is used
*/
GskGLShader *
gsk_shader_paintable_get_shader (GskShaderPaintable *self)
@@ -254,12 +257,12 @@ gsk_shader_paintable_get_shader (GskShaderPaintable *self)
/**
* gsk_shader_paintable_set_args:
* @self: a `GskShaderPaintable`
* @self: a #GskShaderPaintable
* @data: Data block with uniform data for the shader
*
* Sets the uniform data that will be passed to the
* shader when rendering. The @data will typically
* be produced by a `GskUniformDataBuilder`.
* be produced by a #GskUniformDataBuilder.
*
* Note that the @data should be considered immutable
* after it has been passed to this function.
@@ -281,7 +284,7 @@ gsk_shader_paintable_set_args (GskShaderPaintable *self,
/**
* gsk_shader_paintable_get_args:
* @self: a `GskShaderPaintable`
* @self: a #GskShaderPaintable
*
* Returns the uniform data set with
* gsk_shader_paintable_get_args().
@@ -298,9 +301,9 @@ gsk_shader_paintable_get_args (GskShaderPaintable *self)
/**
* gsk_shader_paintable_update_time:
* @self: a `GskShaderPaintable`
* @self: a #GskShaderPaintable
* @time_idx: the index of the uniform for time in seconds as float
* @frame_time: the current frame time, as returned by `GdkFrameClock`
* @frame_time: the current frame time, as returned by #GdkFrameClock
*
* This function is a convenience wrapper for
* gsk_shader_paintable_set_args() that leaves all
@@ -308,7 +311,7 @@ gsk_shader_paintable_get_args (GskShaderPaintable *self)
* index @time_idx, which will be set to the elapsed time
* in seconds, since the first call to this function.
*
* This function is usually called from a `GtkTickCallback`.
* This function is usually called from a #GtkTickCallback.
*/
void
gsk_shader_paintable_update_time (GskShaderPaintable *self,

View File

@@ -74,9 +74,9 @@ gtk_fishbowl_init (GtkFishbowl *fishbowl)
/**
* gtk_fishbowl_new:
*
* Creates a new `GtkFishbowl`.
* Creates a new #GtkFishbowl.
*
* Returns: a new `GtkFishbowl`.
* Returns: a new #GtkFishbowl.
*/
GtkWidget*
gtk_fishbowl_new (void)

View File

@@ -874,8 +874,8 @@ gtk_gears_tick (GtkWidget *widget,
{
GtkGears *gears = GTK_GEARS (widget);
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
GdkFrameTimings *previous_timings;
gint64 previous_frame_time;
GdkFrameTimings *timings, *previous_timings;
gint64 previous_frame_time = 0;
gint64 frame_time;
gint64 history_start, history_len;
gint64 frame;
@@ -915,6 +915,12 @@ gtk_gears_tick (GtkWidget *widget,
}
}
timings = gdk_frame_clock_get_current_timings (frame_clock);
previous_timings = gdk_frame_clock_get_timings (frame_clock,
gdk_frame_timings_get_frame_counter (timings) - 1);
if (previous_timings != NULL)
previous_frame_time = gdk_frame_timings_get_frame_time (previous_timings);
return G_SOURCE_CONTINUE;
}

View File

@@ -163,8 +163,8 @@ drag_update_cb (GtkGestureDrag *drag,
static void
drag_end_cb (GtkGestureDrag *drag,
double dx,
double dy,
gdouble dx,
gdouble dy,
gpointer user_data)
{
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);

View File

@@ -18,6 +18,8 @@ do_headerbar (GtkWidget *do_widget)
GtkWidget *header;
GtkWidget *button;
GtkWidget *box;
GtkWidget *image;
GIcon *icon;
if (!window)
{
@@ -30,14 +32,20 @@ do_headerbar (GtkWidget *do_widget)
header = gtk_header_bar_new ();
button = gtk_button_new_from_icon_name ("mail-send-receive-symbolic");
button = gtk_button_new ();
icon = g_themed_icon_new ("mail-send-receive-symbolic");
image = gtk_image_new_from_gicon (icon);
g_object_unref (icon);
gtk_button_set_child (GTK_BUTTON (button), image);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_add_css_class (box, "linked");
button = gtk_button_new_from_icon_name ("go-previous-symbolic");
button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (button), gtk_image_new_from_icon_name ("pan-start-symbolic"));
gtk_box_append (GTK_BOX (box), button);
button = gtk_button_new_from_icon_name ("go-next-symbolic");
button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (button), gtk_image_new_from_icon_name ("pan-end-symbolic"));
gtk_box_append (GTK_BOX (box), button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), box);

View File

@@ -7,8 +7,7 @@
* shows.
*
* We also demonstrate adding other things to a text view, such as
* clickable icons and widgets which can also replace a character
* (try copying the ghost text).
* clickable icons.
*/
#include <gtk/gtk.h>
@@ -62,26 +61,12 @@ show_page (GtkTextView *text_view,
int page)
{
GtkTextBuffer *buffer;
GtkTextIter iter, start;
GtkTextMark *mark;
GtkTextIter iter;
GtkWidget *child;
GtkTextChildAnchor *anchor;
GtkEventController *controller;
GtkTextTag *bold, *mono, *nobreaks;
buffer = gtk_text_view_get_buffer (text_view);
bold = gtk_text_buffer_create_tag (buffer, NULL,
"weight", PANGO_WEIGHT_BOLD,
"scale", PANGO_SCALE_X_LARGE,
NULL);
mono = gtk_text_buffer_create_tag (buffer, NULL,
"family", "monospace",
NULL);
nobreaks = gtk_text_buffer_create_tag (buffer, NULL,
"allow-breaks", FALSE,
NULL);
gtk_text_buffer_set_text (buffer, "", 0);
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
gtk_text_buffer_begin_irreversible_action (buffer);
@@ -95,12 +80,13 @@ show_page (GtkTextView *text_view,
gtk_text_buffer_insert (buffer, &iter, " can easily be realized with ", -1);
insert_link (buffer, &iter, "tags", 2);
gtk_text_buffer_insert (buffer, &iter, ".\n", -1);
gtk_text_buffer_insert (buffer, &iter, "Of course you can also embed Emoji 😋, ", -1);
gtk_text_buffer_insert (buffer, &iter, "icons ", -1);
gtk_text_buffer_insert (buffer, &iter,
"Of course you can also embed Emoji 😋, "
"icons ", -1);
theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (text_view)));
icon = gtk_icon_theme_lookup_icon (theme,
"eye-not-looking-symbolic",
"microphone-sensitivity-high-symbolic",
NULL,
16,
1,
@@ -114,31 +100,21 @@ show_page (GtkTextView *text_view,
gtk_level_bar_set_value (GTK_LEVEL_BAR (child), 50);
gtk_widget_set_size_request (child, 100, -1);
gtk_text_view_add_child_at_anchor (text_view, child, anchor);
gtk_text_buffer_insert (buffer, &iter, " and labels with ", -1);
anchor = gtk_text_child_anchor_new_with_replacement ("👻");
gtk_text_buffer_insert_child_anchor (buffer, &iter, anchor);
child = gtk_label_new ("ghost");
gtk_text_view_add_child_at_anchor (text_view, child, anchor);
gtk_text_buffer_insert (buffer, &iter, " text.", -1);
gtk_text_buffer_insert (buffer, &iter, ".", -1);
}
else if (page == 2)
{
mark = gtk_text_buffer_create_mark (buffer, "mark", &iter, TRUE);
GtkTextTag *tag;
gtk_text_buffer_insert_with_tags (buffer, &iter, "tag", -1, bold, NULL);
gtk_text_buffer_insert (buffer, &iter, " /", -1);
gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
gtk_text_buffer_apply_tag (buffer, nobreaks, &start, &iter);
gtk_text_buffer_insert (buffer, &iter, " ", -1);
gtk_text_buffer_move_mark (buffer, mark, &iter);
gtk_text_buffer_insert_with_tags (buffer, &iter, "tag", -1, mono, NULL);
gtk_text_buffer_insert (buffer, &iter, " /", -1);
gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
gtk_text_buffer_apply_tag (buffer, nobreaks, &start, &iter);
gtk_text_buffer_insert (buffer, &iter, " ", -1);
tag = gtk_text_buffer_create_tag (buffer, NULL,
"weight", PANGO_WEIGHT_BOLD,
"scale", PANGO_SCALE_X_LARGE,
NULL);
gtk_text_buffer_insert_with_tags (buffer, &iter, "tag", -1, tag, NULL);
tag = gtk_text_buffer_create_tag (buffer, NULL,
"family", "monospace",
NULL);
gtk_text_buffer_insert_with_tags (buffer, &iter, " /tag/ ", -1, tag, NULL);
anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);
child = gtk_image_new_from_icon_name ("audio-volume-high-symbolic");
@@ -156,26 +132,20 @@ show_page (GtkTextView *text_view,
"behavior of mouse and key presses, “lock” a range of text so the "
"user can't edit it, or countless other things.\n", -1);
insert_link (buffer, &iter, "Go back", 1);
gtk_text_buffer_delete_mark (buffer, mark);
}
else if (page == 3)
{
mark = gtk_text_buffer_create_mark (buffer, "mark", &iter, TRUE);
GtkTextTag *tag;
gtk_text_buffer_insert_with_tags (buffer, &iter, "hypertext", -1, bold, NULL);
gtk_text_buffer_insert (buffer, &iter, " /", -1);
gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
gtk_text_buffer_apply_tag (buffer, nobreaks, &start, &iter);
gtk_text_buffer_insert (buffer, &iter, " ", -1);
gtk_text_buffer_move_mark (buffer, mark, &iter);
gtk_text_buffer_insert_with_tags (buffer, &iter, "ˈhaɪ pərˌtɛkst", -1, mono, NULL);
gtk_text_buffer_insert (buffer, &iter, " /", -1);
gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
gtk_text_buffer_apply_tag (buffer, nobreaks, &start, &iter);
gtk_text_buffer_insert (buffer, &iter, " ", -1);
tag = gtk_text_buffer_create_tag (buffer, NULL,
"weight", PANGO_WEIGHT_BOLD,
"scale", PANGO_SCALE_X_LARGE,
NULL);
gtk_text_buffer_insert_with_tags (buffer, &iter, "hypertext", -1, tag, NULL);
tag = gtk_text_buffer_create_tag (buffer, NULL,
"family", "monospace",
NULL);
gtk_text_buffer_insert_with_tags (buffer, &iter, " /ˈhaɪ pərˌtɛkst/ ", -1, tag, NULL);
anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);
child = gtk_image_new_from_icon_name ("audio-volume-high-symbolic");
@@ -189,8 +159,6 @@ show_page (GtkTextView *text_view,
"Machine-readable text that is not sequential but is organized "
"so that related items of information are connected.\n", -1);
insert_link (buffer, &iter, "Go back", 1);
gtk_text_buffer_delete_mark (buffer, mark);
}
gtk_text_buffer_end_irreversible_action (buffer);
}
@@ -390,7 +358,7 @@ do_hypertext (GtkWidget *do_widget)
sw = gtk_scrolled_window_new ();
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_window_set_child (GTK_WINDOW (window), sw);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), view);

View File

@@ -116,25 +116,20 @@ populate_emoji_text (void)
GtkWidget *textview;
GtkTextBuffer *buffer;
GString *s;
GtkTextIter iter;
s = g_string_sized_new (500 * 30 * 4);
s = g_string_sized_new (1000 * 30 * 4);
for (int i = 0; i < 500; i++)
for (int i = 0; i < 1000; i++)
{
if (i % 2)
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
g_string_append (s, "x");
for (int j = 0; j < 30; j++)
{
g_string_append (s, "💓");
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
}
g_string_append (s, "💓x");
g_string_append (s, "\n");
}
buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_get_start_iter (buffer, &iter);
gtk_text_buffer_insert_markup (buffer, &iter, s->str, s->len);
gtk_text_buffer_set_text (buffer, s->str, s->len);
g_string_free (s, TRUE);

View File

@@ -13,13 +13,13 @@
</style>
<child>
<object class="GtkButton">
<property name="icon-name">go-previous-symbolic</property>
<property name="icon-name">pan-start-symbolic</property>
<signal name="clicked" handler="iconscroll_prev_clicked_cb"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">go-next-symbolic</property>
<property name="icon-name">pan-end-symbolic</property>
<signal name="clicked" handler="iconscroll_next_clicked_cb"/>
</object>
</child>

View File

@@ -18,81 +18,15 @@
#include "language-names.h"
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#ifndef ISO_CODES_PREFIX
#define ISO_CODES_PREFIX "/usr"
#endif
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
#endif
static GHashTable *language_map;
#ifdef G_OS_WIN32
/* if we are using native Windows use native Windows API for language names */
static BOOL CALLBACK
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
{
wchar_t *langname_w = NULL;
wchar_t locale_abbrev_w[9];
gchar *langname, *locale_abbrev, *locale, *p;
gint i;
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
GHashTable *ht_scripts_langs = (GHashTable *) param;
PangoLanguage *lang;
gint langname_size, locale_abbrev_size;
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
if (langname_size == 0)
return FALSE;
langname_w = g_new0 (wchar_t, langname_size);
if (langname_size == 0)
return FALSE;
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = pango_language_from_string (locale);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
/*
* Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL)
* ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME
* ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2
*/
for (i = 0; i < 2; i++)
{
locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0);
if (locale_abbrev_size > 0)
{
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
lang = pango_language_from_string (locale_abbrev);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
g_free (locale_abbrev);
}
}
g_free (locale);
g_free (langname_w);
return TRUE;
}
#else /* non-Windows */
static char *
get_first_item_in_semicolon_list (const char *list)
{
@@ -276,7 +210,6 @@ languages_variant_init (const char *variant)
g_free (filename);
g_free (buf);
}
#endif
static void
languages_init (void)
@@ -285,13 +218,8 @@ languages_init (void)
return;
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
#ifdef G_OS_WIN32
g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL));
#else
languages_variant_init ("iso_639");
languages_variant_init ("iso_639_3");
#endif
}
const char *

View File

@@ -8,7 +8,7 @@
#include <stdlib.h>
#include <string.h>
static GdkTexture *avatar_texture_other;
static GdkPixbuf *avatar_pixbuf_other;
static GtkWidget *window = NULL;
#define GTK_TYPE_MESSAGE (gtk_message_get_type ())
@@ -196,9 +196,12 @@ gtk_message_row_update (GtkMessageRow *row)
gtk_button_set_label (GTK_BUTTON (priv->resent_by_button), priv->message->resent_by);
if (strcmp (priv->message->sender_nick, "@GTKtoolkit") == 0)
gtk_image_set_from_icon_name (priv->avatar_image, "org.gtk.Demo4");
{
gtk_image_set_from_icon_name (priv->avatar_image, "org.gtk.Demo4");
gtk_image_set_icon_size (priv->avatar_image, GTK_ICON_SIZE_LARGE);
}
else
gtk_image_set_from_paintable (priv->avatar_image, GDK_PAINTABLE (avatar_texture_other));
gtk_image_set_from_pixbuf (priv->avatar_image, avatar_pixbuf_other);
}
@@ -341,7 +344,7 @@ do_listbox (GtkWidget *do_widget)
if (!window)
{
avatar_texture_other = gdk_texture_new_from_resource ("/listbox/apple-red.png");
avatar_pixbuf_other = gdk_pixbuf_new_from_resource_at_scale ("/listbox/apple-red.png", 32, 32, FALSE, NULL);
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),

View File

@@ -25,7 +25,6 @@
<property name="margin-start">8</property>
<property name="margin-end">8</property>
<property name="icon-name">image-missing</property>
<property name="icon-size">large</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>

View File

@@ -8,8 +8,8 @@
#include <gtk/gtk.h>
/* This is the function that creates the GListModel that we need.
* GTK list widgets need a GListModel to display, as models support change
/* This is the function that creates the #GListModel that we need.
* GTK list widgets need a #GListModel to display, as models support change
* notifications.
* Unfortunately various older APIs do not provide list models, so we create
* our own.
@@ -20,10 +20,10 @@ create_application_list (void)
GListStore *store;
GList *apps, *l;
/* We use a GListStore here, which is a simple array-like list implementation
/* We use a #GListStore here, which is a simple array-like list implementation
* for manual management.
* List models need to know what type of data they provide, so we need to
* provide the type here. As we want to do a list of applications, GAppInfo
* provide the type here. As we want to do a list of applications, #GAppInfo
* is the object we provide.
*/
store = g_list_store_new (G_TYPE_APP_INFO);
@@ -39,7 +39,7 @@ create_application_list (void)
}
/* This is the function we use for setting up new listitems to display.
* We add just an GtkImage and a GtkLabel here to display the application's
* We add just an #GtkImage and a #GtkLabel here to display the application's
* icon and name, as this is just a simple demo.
*/
static void
@@ -61,8 +61,8 @@ setup_listitem_cb (GtkListItemFactory *factory,
/* Here we need to prepare the listitem for displaying its item. We get the
* listitem already set up from the previous function, so we can reuse the
* GtkImage widget we set up above.
* We get the item - which we know is a GAppInfo because it comes out of
* #GtkImage widget we set up above.
* We get the item - which we know is a #GAppInfo because it comes out of
* the model we set up above, grab its icon and display it.
*/
static void
@@ -85,7 +85,7 @@ bind_listitem_cb (GtkListItemFactory *factory,
* the listitem, but this is simple code, so the default implementations are
* enough. If we had connected signals, this step would have been necessary.
*
* The GtkSignalListItemFactory documentation contains more information about
* The #GtkSignalListItemFactory documentation contains more information about
* this step.
*/
@@ -108,8 +108,8 @@ activate_cb (GtkListView *list,
app_info = g_list_model_get_item (G_LIST_MODEL (gtk_list_view_get_model (list)), position);
/* Prepare the context for launching the application and launch it. This
* code is explained in detail in the documentation for GdkAppLaunchContext
* and GAppInfo.
* code is explained in detail in the documentation for #GdkAppLaunchContext
* and #GAppInfo.
*/
context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (list)));
if (!g_app_info_launch (app_info,
@@ -155,13 +155,13 @@ do_listview_applauncher (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Application Launcher");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
/* The GtkListitemFactory is what is used to create GtkListItems
/* The #GtkListitemFactory is what is used to create #GtkListItems
* to display the data from the model. So it is absolutely necessary
* to create one.
* We will use a GtkSignalListItemFactory because it is the simplest
* We will use a #GtkSignalListItemFactory because it is the simplest
* one to use. Different ones are available for different use cases.
* The most powerful one is GtkBuilderListItemFactory which uses
* GtkBuilder .ui files, so it requires little code.
* The most powerful one is #GtkBuilderListItemFactory which uses
* #GtkBuilder .ui files, so it requires little code.
*/
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
@@ -184,7 +184,7 @@ do_listview_applauncher (GtkWidget *do_widget)
*/
g_signal_connect (list, "activate", G_CALLBACK (activate_cb), NULL);
/* List widgets should always be contained in a GtkScrolledWindow,
/* List widgets should always be contained in a #GtkScrolledWindow,
* because otherwise they might get too large or they might not
* be scrollable.
*/

View File

@@ -34,7 +34,6 @@ enum {
};
#define FILE_BROWSER_TYPE_VIEW (file_browser_view_get_type ())
G_MODULE_EXPORT
G_DECLARE_FINAL_TYPE (FileBrowserView, file_browser_view, FILE_BROWSER, VIEW, GObject);
G_DEFINE_TYPE (FileBrowserView, file_browser_view, G_TYPE_OBJECT);
@@ -160,7 +159,7 @@ static void file_browser_view_init (FileBrowserView *self)
{
}
G_MODULE_EXPORT char *
char *
filebrowser_get_display_name (GObject *object,
GFileInfo *info)
{
@@ -170,7 +169,7 @@ filebrowser_get_display_name (GObject *object,
return g_strdup (g_file_info_get_attribute_string (info, "standard::display-name"));
}
G_MODULE_EXPORT char *
char *
filebrowser_get_content_type (GObject *object,
GFileInfo *info)
{
@@ -180,7 +179,7 @@ filebrowser_get_content_type (GObject *object,
return g_strdup (g_file_info_get_attribute_string (info, "standard::content-type"));
}
G_MODULE_EXPORT char *
char *
filebrowser_get_size (GObject *object,
GFileInfo *info)
{
@@ -190,7 +189,7 @@ filebrowser_get_size (GObject *object,
return g_format_size (g_file_info_get_attribute_uint64 (info, "standard::size"));
}
G_MODULE_EXPORT GIcon *
GIcon *
filebrowser_get_icon (GObject *object,
GFileInfo *info)
{
@@ -207,7 +206,7 @@ filebrowser_get_icon (GObject *object,
return icon;
}
G_MODULE_EXPORT void
void
filebrowser_up_clicked_cb (GtkButton *button,
GtkDirectoryList *list)
{
@@ -220,7 +219,7 @@ filebrowser_up_clicked_cb (GtkButton *button,
gtk_directory_list_set_file (list, file);
}
G_MODULE_EXPORT void
void
filebrowser_view_activated_cb (GtkGridView *view,
guint pos,
GtkDirectoryList *list)

View File

@@ -192,7 +192,7 @@ activate_about (GSimpleAction *action,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
@@ -512,7 +512,7 @@ load_file (const char *demoname,
info_buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (info_buffer, "title",
"size", 18 * 1024,
"font", "Sans 18",
"pixels-below-lines", 10,
NULL);
@@ -751,6 +751,7 @@ demo_filter_by_name (gpointer item,
gpointer user_data)
{
GtkTreeListRow *row = item;
GtkFilterListModel *model = user_data;
GListModel *children;
GtkDemo *demo;
guint i, n;
@@ -761,7 +762,7 @@ demo_filter_by_name (gpointer item,
return TRUE;
g_assert (GTK_IS_TREE_LIST_ROW (row));
g_assert (GTK_IS_FILTER_LIST_MODEL (user_data));
g_assert (GTK_IS_FILTER_LIST_MODEL (model));
/* Show a row if itself of any parent matches */
for (parent = row; parent; parent = gtk_tree_list_row_get_parent (parent))
@@ -1040,7 +1041,7 @@ out:
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
}
else
gtk_window_present (GTK_WINDOW (window));
gtk_widget_show (GTK_WIDGET (window));
if (autoquit)
g_timeout_add_seconds (1, auto_quit, app);

View File

@@ -58,7 +58,7 @@ do_markup (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 600, 680);
gtk_window_set_default_size (GTK_WINDOW (window), 450, 450);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
stack = gtk_stack_new ();

View File

@@ -1,9 +1,5 @@
Text sizes: <span size="xx-small">tiny </span><span size="x-small">very small </span><span size="small">small </span><span size="medium">normal </span><span size="large">large </span><span size="x-large">very large </span><span size="xx-large">huge</span>
Text styles: <span style="normal">Normal</span> <span style="italic">Italic</span> <span style="oblique">Olique</span>
Text weights: <span weight="thin">thin</span> <span weight="light">light</span> <span weight="normal">normal</span> <span weight="bold">bold</span> <span weight="ultraheavy">ultraheavy</span>
Text sizes: <span size="xx-small">tiny</span> <span size="x-small">very small</span> <span size="small">small</span> <span size="medium">normal</span> <span size="large">large</span> <span size="x-large">very large</span> <span size="xx-large">huge</span>
Text <span color="gray">c<span color="green">o</span>l<span color="tomato">o</span>rs</span> and <span background="pink">backgrounds</span>
@@ -19,12 +15,6 @@ OpenType font features: <span font_desc="sans regular" font_features="dlig=0">fe
Shortcuts: <tt>Monospace</tt> <b>Bold</b> <i>Italic</i> <big>Big</big> <small>Small</small> <u>Underlined</u> <s>Strikethrough</s> Super<sup>script</sup> Sub<sub>script</sub>
hy­phen­ation al­go­rithm is a <span allow_breaks="false" style="italic">set of rules</span>, espe­ci­ally one co­di­fied for im­ple­men­tation in a com­pu­ter pro­gram, that de­ci­des at which points a word can be bro­ken over two lines with a hy­phen. For ex­am­ple, a hy­phen­ation al­go­rithm might de­cide that im­peach­ment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
<span allow_breaks="false">A</span> hy­phen­ation al­go­rithm is a set of rules, espe­ci­ally one co­di­fied for im­ple­men­tation in a com­pu­ter pro­gram, that de­ci­des at which points a word can be bro­ken over two lines with a hy­phen. For ex­am­ple, a hy­phen­ation al­go­rithm might de­cide that im­peach­ment can be broken as <span allow_breaks="false">impeach‧ment</span> or <span allow_breaks="false">im‧peachment</span> but not <span allow_breaks="false">impe‧achment.</span>
<span insert_hyphens="false">one/two three/four five/six seven/eight nine/ten</span>
<span line_height='1.33'>Line height: This is an example of widely spaced text. It was achieved by setting the line-height factor to 1.33. You can set the line-height factor to any value between 0 and 10.
Note that the line height affects the spacing between paragraphs as well as between the wrapped lines inside a paragraph.</span>
Transforms: <span text_transform='uppercase'>straße</span> <span text_transform='capitalize'>up, up and away</span>

View File

@@ -21,10 +21,8 @@ do_menu (GtkWidget *do_widget)
if (!window)
{
GtkWidget *box;
GtkWidget *sw;
GtkWidget *widget;
GtkWidget *scale;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Menu");
@@ -33,23 +31,11 @@ do_menu (GtkWidget *do_widget)
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
sw = gtk_scrolled_window_new ();
gtk_widget_set_vexpand (sw, TRUE);
gtk_box_append (GTK_BOX (box), sw);
gtk_window_set_child (GTK_WINDOW (window), sw);
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
gtk_range_set_value (GTK_RANGE (scale), 1.0);
gtk_box_append (GTK_BOX (box), scale);
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
widget, "scale",
G_BINDING_BIDIRECTIONAL);
}
if (!gtk_widget_get_visible (window))

View File

@@ -21,7 +21,7 @@
<item>
<attribute name="label" translatable="yes">Save _As...</attribute>
<attribute name="action">app.save-as</attribute>
<attribute name="accel">&lt;Control&gt;&lt;Shift&gt;s</attribute>
<attribute name="accel">&lt;Control&gt;s</attribute>
</item>
</section>
<section>

View File

@@ -17,7 +17,6 @@ demos = files([
'css_pixbufs.c',
'css_shadows.c',
'cursors.c',
'curve.c',
'dialog.c',
'drawingarea.c',
'dnd.c',
@@ -35,7 +34,6 @@ demos = files([
'gestures.c',
'glarea.c',
'gltransition.c',
'glyphs.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
@@ -69,12 +67,8 @@ demos = files([
'paintable_animated.c',
'paintable_emblem.c',
'paintable_mediastream.c',
'paintable_symbolic.c',
'panes.c',
'password_entry.c',
'path_fill.c',
'path_maze.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
'printing.c',
@@ -103,7 +97,6 @@ demos = files([
'transparent.c',
'tree_store.c',
'video_player.c',
'font_features.c',
])
gtkdemo_deps = [ libgtk_dep, ]
@@ -134,17 +127,19 @@ extra_demo_sources = files([
'script-names.c',
'unicode-names.c',
'suggestionentry.c',
'language-names.c',
'curve-editor.c',
'nodewidget.c',
'graphwidget.c',
])
if harfbuzz_dep.found() and pangoft_dep.found()
demos += files(['font_features.c'])
extra_demo_sources += files(['language-names.c'])
gtkdemo_deps += [ harfbuzz_dep, epoxy_dep ]
endif
if os_unix
demos += files('pagesetup.c')
endif
librsvg_dep = dependency('librsvg-2.0', version: '>= 2.52.0', required: false)
librsvg_dep = dependency('librsvg-2.0', version: '>= 2.46.0', required: false)
if librsvg_dep.found()
demos += files('paintable_svg.c')
@@ -160,85 +155,15 @@ demos_h = custom_target('gtk4 demo header',
command: [ find_program('geninclude.py'), '@OUTPUT@', '@INPUT@' ],
)
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help').stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
# Create the resource blob
gtkdemo_gresource = custom_target('gtkdemo.gresource',
input : 'demo.gresource.xml',
output : 'gtkdemo.gresource',
depfile : 'gtkdemo.gresource.d',
command : [glib_compile_resources,
'--generate',
'--internal',
'--target=@OUTPUT@',
'--dependency-file=@DEPFILE@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
'@INPUT@'])
# Create resource data file
gtkdemo_resources_c = custom_target('gtkdemo_resources.c',
input : 'demo.gresource.xml',
output : 'gtkdemo_resources.c',
depfile : 'gtkdemo_resources.c.d',
command : [glib_compile_resources,
'--generate-source',
'--internal',
'--target=@OUTPUT@',
'--dependency-file=@DEPFILE@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
'--external-data',
'--c-name', '_g_binary_gtkdemo',
'@INPUT@'])
# Create object file containing resource data
gtkdemo_resources_binary = custom_target('gtkdemo_resources.o',
input : gtkdemo_gresource,
output : 'gtkdemo_resources.o',
command : [ld,
'-z', 'noexecstack',
'-r',
'-b','binary',
'@INPUT@',
'-o','@OUTPUT@'])
# Rename symbol to match the one in the C file
gtkdemo_resources_o = custom_target('gtkdemo_resources2.o',
input : gtkdemo_resources_binary,
output : 'gtkdemo_resources2.o',
command : [objcopy,
'--strip-all',
'--add-symbol','_g_binary_gtkdemo_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])
gtkdemo_resources = [
gtkdemo_resources_c,
gtkdemo_resources_o,
]
else
gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
'demo.gresource.xml',
source_dir: '.',
)
endif
gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
'demo.gresource.xml',
source_dir: '.',
)
# Use a subset of compiler flags
demo_cflags = []
foreach flag: common_cflags
if flag not in ['-Werror=missing-prototypes', '-Wmissing-prototypes',
'-Werror=missing-declarations', '-Wmissing-declarations',
'-fvisibility=hidden']
if flag not in ['-Werror=missing-prototypes', '-Werror=missing-declarations', '-fvisibility=hidden']
demo_cflags += flag
endif
endforeach
@@ -250,7 +175,7 @@ executable('gtk4-demo',
c_args: gtkdemo_args + demo_cflags,
dependencies: gtkdemo_deps,
include_directories: confinc,
win_subsystem: 'windows',
gui_app: true,
link_args: extra_demo_ldflags,
install: true,
)
@@ -260,7 +185,7 @@ executable('gtk4-demo-application',
c_args: gtkdemo_args + common_cflags,
dependencies: gtkdemo_deps,
include_directories: confinc,
win_subsystem: 'windows',
gui_app: true,
link_args: extra_demo_ldflags,
install: true,
)
@@ -280,9 +205,4 @@ install_data('org.gtk.Demo4.gschema.xml', install_dir: gtk_schemasdir)
gnome.compile_schemas()
# appdata
configure_file(
input: 'org.gtk.Demo4.appdata.xml.in',
output: 'org.gtk.Demo4.appdata.xml',
configuration: appdata_config,
install_dir: gtk_appdatadir
)
install_data('org.gtk.Demo4.appdata.xml', install_dir: gtk_appdatadir)

View File

@@ -1,76 +0,0 @@
#include "nodewidget.h"
struct _NodeWidget
{
GtkWidget parent_instance;
GskRenderNode *node;
};
struct _NodeWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (NodeWidget, node_widget, GTK_TYPE_WIDGET)
static void
node_widget_init (NodeWidget *self)
{
}
static void
node_widget_dispose (GObject *object)
{
NodeWidget *self = NODE_WIDGET (object);
gsk_render_node_unref (self->node);
G_OBJECT_CLASS (node_widget_parent_class)->dispose (object);
}
static void
node_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
NodeWidget *self = NODE_WIDGET (widget);
gtk_snapshot_append_node (snapshot, self->node);
}
static void
node_widget_class_init (NodeWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = node_widget_dispose;
widget_class->snapshot = node_widget_snapshot;
}
GtkWidget *
node_widget_new (const char *resource)
{
NodeWidget *self;
GBytes *bytes;
GskRenderNode *node;
graphene_rect_t bounds;
float scale;
GskTransform *transform;
self = g_object_new (NODE_TYPE_WIDGET, NULL);
bytes = g_resources_lookup_data (resource, 0, NULL);
node = gsk_render_node_deserialize (bytes, NULL, NULL);
g_bytes_unref (bytes);
gsk_render_node_get_bounds (node, &bounds);
scale = MIN (100.0/bounds.size.width, 100.0/bounds.size.height);
transform = gsk_transform_scale (NULL, scale, scale);
self->node = gsk_transform_node_new (node, transform);
gsk_transform_unref (transform);
gsk_render_node_unref (node);
return GTK_WIDGET (self);
}

View File

@@ -1,8 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define NODE_TYPE_WIDGET (node_widget_get_type ())
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
GtkWidget * node_widget_new (const char *file);

View File

@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>org.gtk.Demo4</id>
<launchable type="desktop-id">org.gtk.Demo4.desktop</launchable>
<id>org.gtk.Demo4.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-2.1-or-later</project_license>
<project_license>LGPL-2.0+</project_license>
<name>GTK Demo</name>
<summary>Program to demonstrate GTK functions</summary>
<description>
@@ -31,11 +30,15 @@
<translation type="gettext">gtk-4.0</translation>
<update_contact>matthias.clasen_at_gmail.com</update_contact>
<developer_name>Matthias Clasen and others</developer_name>
<content_rating type="oars-1.1"/>
<releases>
<release version="@BUILD_VERSION@">
<release version="3.99.0" date="2020-07-30">
<description>
<p>A new build of GTK.</p>
<p>A new developers snapshot towards GTK 4.0.</p>
</description>
</release>
<release version="3.94.0" date="2018-06-25">
<description>
<p>A new developers snapshot towards GTK 4.0.</p>
</description>
</release>
</releases>

View File

@@ -45,27 +45,26 @@ struct _GtkNuclearIconClass
* so that it can be called from all the other demos, too.
*/
void
gtk_nuclear_snapshot (GtkSnapshot *snapshot,
const GdkRGBA *foreground,
const GdkRGBA *background,
double width,
double height,
double rotation)
gtk_nuclear_snapshot (GtkSnapshot *snapshot,
double width,
double height,
double rotation,
gboolean draw_background)
{
#define RADIUS 0.3
cairo_t *cr;
double size;
gtk_snapshot_append_color (snapshot,
background,
&GRAPHENE_RECT_INIT (0, 0, width, height));
if (draw_background)
gtk_snapshot_append_color (snapshot,
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 },
&GRAPHENE_RECT_INIT (0, 0, width, height));
size = MIN (width, height);
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT ((width - size) / 2.0,
(height - size) / 2.0,
size, size));
gdk_cairo_set_source_rgba (cr, foreground);
cairo_translate (cr, width / 2.0, height / 2.0);
cairo_scale (cr, size, size);
cairo_rotate (cr, rotation);
@@ -95,10 +94,9 @@ gtk_nuclear_icon_snapshot (GdkPaintable *paintable,
*/
gtk_nuclear_snapshot (snapshot,
&(GdkRGBA) { 0, 0, 0, 1 }, /* black */
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 }, /* yellow */
width, height,
nuclear->rotation);
nuclear->rotation,
TRUE);
}
static GdkPaintableFlags

View File

@@ -4,11 +4,10 @@
#include <gtk/gtk.h>
void gtk_nuclear_snapshot (GtkSnapshot *snapshot,
const GdkRGBA *foreground,
const GdkRGBA *background,
double width,
double height,
double rotation);
double rotation,
gboolean draw_background);
GdkPaintable * gtk_nuclear_icon_new (double rotation);
GdkPaintable * gtk_nuclear_animation_new (gboolean draw_background);

View File

@@ -65,12 +65,9 @@ gtk_nuclear_animation_snapshot (GdkPaintable *paintable,
/* We call the function from the previous example here. */
gtk_nuclear_snapshot (snapshot,
&(GdkRGBA) { 0, 0, 0, 1 }, /* black */
nuclear->draw_background
? &(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 } /* yellow */
: &(GdkRGBA) { 0, 0, 0, 0 }, /* transparent */
width, height,
2 * G_PI * nuclear->progress / MAX_PROGRESS);
2 * G_PI * nuclear->progress / MAX_PROGRESS,
nuclear->draw_background);
}
static GdkPaintable *

View File

@@ -73,10 +73,9 @@ gtk_nuclear_media_stream_snapshot (GdkPaintable *paintable,
/* We call the function from the previous example here. */
gtk_nuclear_snapshot (snapshot,
&(GdkRGBA) { 0, 0, 0, 1 }, /* black */
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 }, /* yellow */
width, height,
2 * G_PI * nuclear->progress / DURATION);
2 * G_PI * nuclear->progress / DURATION,
TRUE);
}
static GdkPaintable *
@@ -151,7 +150,7 @@ gtk_nuclear_media_stream_step (gpointer data)
* call our pause function to pause the stream.
*/
if (nuclear->progress >= DURATION)
gtk_media_stream_stream_ended (GTK_MEDIA_STREAM (nuclear));
gtk_media_stream_ended (GTK_MEDIA_STREAM (nuclear));
/* The timeout function is removed by the pause function,
* so we can just always return this value.
@@ -268,11 +267,11 @@ gtk_nuclear_media_stream_init (GtkNuclearMediaStream *nuclear)
* However, media streams need to tell GTK once they are initialized,
* so we do that here.
*/
gtk_media_stream_stream_prepared (GTK_MEDIA_STREAM (nuclear),
FALSE,
TRUE,
TRUE,
DURATION);
gtk_media_stream_prepared (GTK_MEDIA_STREAM (nuclear),
FALSE,
TRUE,
TRUE,
DURATION);
}
/* And finally, we add the simple constructor we declared in the header. */

View File

@@ -1,208 +0,0 @@
/* Paintable/Symbolic Paintable
*
* GdkPaintables can be made to follow the theme's colors. GTK calls
* icons that do this symbolic icons, paintables that want to have
* the same effect can implement the GtkSymbolicPaintable interface.
*
* We will adapt the original paintable example by adding the ability
* to recolor the paintable based on the symbolic colors.
*/
#include <gtk/gtk.h>
#include "paintable.h"
static GtkWidget *window = NULL;
/* First, add the boilerplate for the object itself.
* This part would normally go in the header.
*/
#define GTK_TYPE_NUCLEAR_SYMBOLIC (gtk_nuclear_symbolic_get_type ())
G_DECLARE_FINAL_TYPE (GtkNuclearSymbolic, gtk_nuclear_symbolic, GTK, NUCLEAR_SYMBOLIC, GObject)
/* Declare a few warning levels, so we can pick colors based on them */
typedef enum
{
WARNING_NONE,
WARNING_ALERT,
WARNING_EMERGENCY
} WarningLevel;
/* Declare the struct. */
struct _GtkNuclearSymbolic
{
GObject parent_instance;
WarningLevel warning_level;
};
struct _GtkNuclearSymbolicClass
{
GObjectClass parent_class;
};
/* Add a function to draw the nuclear icon in the given colors */
static void
gtk_nuclear_symbolic_snapshot_symbolic (GtkSymbolicPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height,
const GdkRGBA *colors,
gsize n_colors)
{
GtkNuclearSymbolic *self = GTK_NUCLEAR_SYMBOLIC (paintable);
static const GdkRGBA transparent = { 0, };
const GdkRGBA *bg_color;
/* select the right background color from the warning level */
switch (self->warning_level)
{
case WARNING_NONE:
bg_color = &transparent;
break;
case WARNING_ALERT:
bg_color = &colors[GTK_SYMBOLIC_COLOR_WARNING];
break;
case WARNING_EMERGENCY:
bg_color = &colors[GTK_SYMBOLIC_COLOR_ERROR];
break;
default:
/* This should never happen, but we better do defensive coding
* with this critical icon */
g_assert_not_reached ();
bg_color = &transparent;
break;
}
/* Draw the icon with the selected warning color */
gtk_nuclear_snapshot (snapshot,
&colors[GTK_SYMBOLIC_COLOR_FOREGROUND],
bg_color,
width, height,
0);
}
static void
gtk_nuclear_symbolic_symbolic_paintable_init (GtkSymbolicPaintableInterface *iface)
{
iface->snapshot_symbolic = gtk_nuclear_symbolic_snapshot_symbolic;
}
/* We need to implement the functionality required by the GdkPaintable interface */
static void
gtk_nuclear_symbolic_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
/* Calling this function without passing a color is a neat trick
* to make GTK use default colors and otherwise forward the call
* to the snapshotting function above.
*/
gtk_symbolic_paintable_snapshot_symbolic (GTK_SYMBOLIC_PAINTABLE (paintable),
snapshot,
width, height,
NULL, 0);
}
static GdkPaintableFlags
gtk_nuclear_symbolic_get_flags (GdkPaintable *paintable)
{
/* This image has a static size, but the contents may change:
* We draw different things when the warning level changes.
*/
return GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_nuclear_symbolic_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gtk_nuclear_symbolic_snapshot;
iface->get_flags = gtk_nuclear_symbolic_get_flags;
}
/* When defining the GType, we need to implement bot the GdkPaintable
* and the GtkSymbolicPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkNuclearSymbolic, gtk_nuclear_symbolic, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_nuclear_symbolic_paintable_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_SYMBOLIC_PAINTABLE,
gtk_nuclear_symbolic_symbolic_paintable_init))
static void
gtk_nuclear_symbolic_class_init (GtkNuclearSymbolicClass *klass)
{
}
static void
gtk_nuclear_symbolic_init (GtkNuclearSymbolic *nuclear)
{
}
/* And finally, we add the simple constructor we declared in the header. */
GdkPaintable *
gtk_nuclear_symbolic_new (void)
{
return g_object_new (GTK_TYPE_NUCLEAR_SYMBOLIC, NULL);
}
/* Add some fun feature to the button */
static void
nuclear_button_clicked (GtkButton *button,
GtkNuclearSymbolic *nuclear)
{
if (nuclear->warning_level >= WARNING_EMERGENCY)
{
/* On maximum warning level, reset the warning */
nuclear->warning_level = WARNING_NONE;
/* And sometimes (but not always to confuse people)
* close the window.
*/
if (g_random_boolean ())
gtk_window_close (GTK_WINDOW (window));
}
else
{
/* Otherwise just increase the warning level */
nuclear->warning_level++;
}
/* Don't forget to emit the signal causing the paintable to redraw.
* Changing the warning level changes the background color after all.
*/
gdk_paintable_invalidate_contents (GDK_PAINTABLE (nuclear));
}
GtkWidget *
do_paintable_symbolic (GtkWidget *do_widget)
{
GdkPaintable *nuclear;
GtkWidget *image, *button;
if (!window)
{
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Don't click!");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
button = gtk_button_new ();
gtk_window_set_child (GTK_WINDOW (window), button);
nuclear = gtk_nuclear_symbolic_new ();
image = gtk_image_new_from_paintable (nuclear);
gtk_button_set_child (GTK_BUTTON (button), image);
g_signal_connect (button, "clicked", G_CALLBACK (nuclear_button_clicked), nuclear);
g_object_unref (nuclear);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,348 +0,0 @@
/* Path/Text Fill
*
* This demo shows how to use PangoCairo to draw text with more than
* just a single color.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#include "gsk/gskpathdashprivate.h"
#define GTK_TYPE_PATH_PAINTABLE (gtk_path_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathPaintable, gtk_path_paintable, GTK, PATH_PAINTABLE, GObject)
struct _GtkPathPaintable
{
GObject parent_instance;
int width;
int height;
GskPath *path;
GdkPaintable *background;
};
struct _GtkPathPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_path_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return MAX (gdk_paintable_get_intrinsic_width (self->background), self->width);
else
return self->width;
}
static int
gtk_path_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return MAX (gdk_paintable_get_intrinsic_height (self->background), self->height);
else
return self->height;
}
static void
gtk_path_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
#if 0
gtk_snapshot_push_fill (snapshot, self->path, GSK_FILL_RULE_WINDING);
#else
GskStroke *stroke = gsk_stroke_new (2.0);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
#endif
if (self->background)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
(GskColorStop[8]) {
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
},
8);
}
gtk_snapshot_pop (snapshot);
}
static GdkPaintableFlags
gtk_path_paintable_get_flags (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return gdk_paintable_get_flags (self->background);
else
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_path_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = gtk_path_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_path_paintable_get_intrinsic_height;
iface->snapshot = gtk_path_paintable_snapshot;
iface->get_flags = gtk_path_paintable_get_flags;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkPathPaintable, gtk_path_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_path_paintable_paintable_init))
/* Here's the boilerplate for the GObject declaration.
* We don't need to do anything special here, because we keep no
* data of our own.
*/
static void
gtk_path_paintable_class_init (GtkPathPaintableClass *klass)
{
}
static void
gtk_path_paintable_init (GtkPathPaintable *self)
{
}
/* And finally, we add a simple constructor.
* It is declared in the header so that the other examples
* can use it.
*/
GdkPaintable *
gtk_path_paintable_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkPathPaintable *self;
self = g_object_new (GTK_TYPE_PATH_PAINTABLE, NULL);
self->path = path;
self->background = background;
if (self->background)
{
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
}
self->width = width;
self->height = height;
return GDK_PAINTABLE (self);
}
void
gtk_path_paintable_set_path (GtkPathPaintable *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
self->path = gsk_path_ref (path);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
static GskPath *
create_hexagon (GtkWidget *widget)
{
GskPathBuilder *builder;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, 120, 0);
gsk_path_builder_line_to (builder, 360, 0);
gsk_path_builder_line_to (builder, 480, 208);
gsk_path_builder_line_to (builder, 360, 416);
gsk_path_builder_line_to (builder, 120, 416);
gsk_path_builder_line_to (builder, 0, 208);
gsk_path_builder_close (builder);
return gsk_path_builder_free_to_path (builder);
}
static GskPath *
create_path_from_text (GtkWidget *widget)
{
PangoLayout *layout;
PangoFontDescription *desc;
GskPathBuilder *builder;
layout = gtk_widget_create_pango_layout (widget, "Pango power!\nPango power!\nPango power!");
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
builder = gsk_path_builder_new ();
gsk_path_builder_add_layout (builder, layout);
return gsk_path_builder_free_to_path (builder);
}
static gboolean
build_path (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder *builder = user_data;
switch (op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (builder);
break;
case GSK_PATH_LINE:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
break;
case GSK_PATH_CURVE:
gsk_path_builder_curve_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, weight);
break;
default:
g_assert_not_reached ();
break;
}
return TRUE;
}
static gboolean
update_path (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer measure)
{
float progress = gdk_frame_clock_get_frame_time (frame_clock) % (60 * G_USEC_PER_SEC) / (float) (30 * G_USEC_PER_SEC);
GskPathBuilder *builder;
GskPath *path;
graphene_point_t pos;
graphene_vec2_t tangent;
GskStroke *stroke;
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder,
measure,
#if 1
0.0, gsk_path_measure_get_length (measure));
#else
progress > 1 ? (progress - 1) * gsk_path_measure_get_length (measure) : 0.0,
(progress < 1 ? progress : 1.0) * gsk_path_measure_get_length (measure));
#endif
path = gsk_path_builder_free_to_path (builder);
stroke = gsk_stroke_new (1);
gsk_stroke_set_dash (stroke, (float[2]) { 10, 5 }, 2);
gsk_stroke_set_dash_offset (stroke, - (gdk_frame_clock_get_frame_time (frame_clock) % G_USEC_PER_SEC) * 15. / G_USEC_PER_SEC);
builder = gsk_path_builder_new ();
gsk_path_dash (path, stroke, 0.2, build_path, builder);
gsk_path_unref (path);
gsk_path_measure_get_point (measure,
(progress > 1 ? (progress - 1) : progress) * gsk_path_measure_get_length (measure),
&pos,
&tangent);
gsk_path_builder_move_to (builder, pos.x + 5 * graphene_vec2_get_x (&tangent), pos.y + 5 * graphene_vec2_get_y (&tangent));
gsk_path_builder_line_to (builder, pos.x + 3 * graphene_vec2_get_y (&tangent), pos.y + 3 * graphene_vec2_get_x (&tangent));
gsk_path_builder_line_to (builder, pos.x - 3 * graphene_vec2_get_y (&tangent), pos.y - 3 * graphene_vec2_get_x (&tangent));
gsk_path_builder_close (builder);
path = gsk_path_builder_free_to_path (builder);
gtk_path_paintable_set_path (GTK_PATH_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget))),
path);
gsk_path_unref (path);
return G_SOURCE_CONTINUE;
}
GtkWidget *
do_path_fill (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *picture;
GdkPaintable *paintable;
GtkMediaStream *stream;
GskPath *path;
graphene_rect_t bounds;
GskPathMeasure *measure;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#if 0
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
#else
stream = gtk_nuclear_media_stream_new ();
#endif
gtk_media_stream_play (stream);
gtk_media_stream_set_loop (stream, TRUE);
path = create_hexagon (window);
path = create_path_from_text (window);
gsk_path_get_bounds (path, &bounds);
paintable = gtk_path_paintable_new (path,
GDK_PAINTABLE (stream),
bounds.origin.x + bounds.size.width,
bounds.origin.y + bounds.size.height);
picture = gtk_picture_new_for_paintable (paintable);
measure = gsk_path_measure_new (path);
gtk_widget_add_tick_callback (picture, update_path, measure, (GDestroyNotify) gsk_path_measure_unref);
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (picture), FALSE);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
gtk_window_set_child (GTK_WINDOW (window), picture);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,339 +0,0 @@
/* Path/Maze
* #Keywords: game, mouse
*
* This demo shows how to use a GskPath to create a maze and use
* gsk_path_measure_get_closest_point() to check the mouse stays
* on the path.
*
* It also shows off the performance of GskPath (or not) as this
* is a rather complex path.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define MAZE_GRID_SIZE 20
#define MAZE_STROKE_SIZE_ACTIVE (MAZE_GRID_SIZE - 4)
#define MAZE_STROKE_SIZE_INACTIVE (MAZE_GRID_SIZE - 12)
#define MAZE_WIDTH 31
#define MAZE_HEIGHT 21
#define GTK_TYPE_MAZE (gtk_maze_get_type ())
G_DECLARE_FINAL_TYPE (GtkMaze, gtk_maze, GTK, MAZE, GtkWidget)
struct _GtkMaze
{
GtkWidget parent_instance;
int width;
int height;
GskPath *path;
GskPathMeasure *measure;
GdkPaintable *background;
gboolean active;
};
struct _GtkMazeClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkMaze, gtk_maze, GTK_TYPE_WIDGET)
static void
gtk_maze_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkMaze *self = GTK_MAZE (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = self->width;
else
*minimum = *natural = self->height;
}
static void
gtk_maze_snapshot (GtkWidget *widget,
GdkSnapshot *snapshot)
{
GtkMaze *self = GTK_MAZE (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskStroke *stroke;
stroke = gsk_stroke_new (MAZE_STROKE_SIZE_INACTIVE);
if (self->active)
gsk_stroke_set_line_width (stroke, MAZE_STROKE_SIZE_ACTIVE);
gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_ROUND);
gsk_stroke_set_line_cap (stroke, GSK_LINE_CAP_ROUND);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
if (self->background)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
(GskColorStop[8]) {
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
},
8);
}
gtk_snapshot_pop (snapshot);
}
static void
gtk_maze_dispose (GObject *object)
{
GtkMaze *self = GTK_MAZE (object);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
if (self->background)
{
g_signal_handlers_disconnect_matched (self->background, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
g_clear_object (&self->background);
}
G_OBJECT_CLASS (gtk_maze_parent_class)->dispose (object);
}
static void
gtk_maze_class_init (GtkMazeClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_maze_dispose;
widget_class->measure = gtk_maze_measure;
widget_class->snapshot = gtk_maze_snapshot;
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkMaze *self)
{
if (!self->active)
return;
if (gsk_path_measure_get_closest_point (self->measure, &GRAPHENE_POINT_INIT (x, y), NULL) <= MAZE_STROKE_SIZE_ACTIVE / 2.0f)
return;
self->active = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkMaze *self)
{
if (!self->active)
{
self->active = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
static void
gtk_maze_init (GtkMaze *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->active = TRUE;
}
static void
gtk_maze_set_path (GtkMaze *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
self->path = gsk_path_ref (path);
self->measure = gsk_path_measure_new (path);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
GtkWidget *
gtk_maze_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkMaze *self;
self = g_object_new (GTK_TYPE_MAZE, NULL);
gtk_maze_set_path (self, path);
gsk_path_unref (path);
self->background = background;
if (self->background)
{
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gtk_widget_queue_draw), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gtk_widget_queue_resize), self);
}
self->width = width;
self->height = height;
return GTK_WIDGET (self);
}
static void
add_point_to_maze (GtkBitset *maze,
GskPathBuilder *builder,
guint x,
guint y)
{
gboolean set[4] = { };
guint dir;
gtk_bitset_add (maze, y * MAZE_WIDTH + x);
while (TRUE)
{
set[0] = set[0] || x == 0 || gtk_bitset_contains (maze, y * MAZE_WIDTH + x - 1);
set[1] = set[1] || y == 0 || gtk_bitset_contains (maze, (y - 1) * MAZE_WIDTH + x);
set[2] = set[2] || x + 1 == MAZE_WIDTH || gtk_bitset_contains (maze, y * MAZE_WIDTH + x + 1);
set[3] = set[3] || y + 1 == MAZE_HEIGHT || gtk_bitset_contains (maze, (y + 1) * MAZE_WIDTH + x);
if (set[0] && set[1] && set[2] && set[3])
return;
do
{
dir = g_random_int_range (0, 4);
}
while (set[dir]);
switch (dir)
{
case 0:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x - 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x - 1, y);
break;
case 1:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y - 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y - 1);
break;
case 2:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 1.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x + 1, y);
break;
case 3:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 1.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y + 1);
break;
default:
g_assert_not_reached ();
break;
}
}
}
static GskPath *
create_path_for_maze (GtkWidget *widget)
{
GskPathBuilder *builder;
GtkBitset *maze;
builder = gsk_path_builder_new ();
maze = gtk_bitset_new_empty ();
/* make sure the outer lines are unreachable:
* Set the full range, then remove the center again. */
gtk_bitset_add_range (maze, 0, MAZE_WIDTH * MAZE_HEIGHT);
gtk_bitset_remove_rectangle (maze, MAZE_WIDTH + 1, MAZE_WIDTH - 2, MAZE_HEIGHT - 2, MAZE_WIDTH);
/* Fill the maze */
add_point_to_maze (maze, builder, MAZE_WIDTH / 2, MAZE_HEIGHT / 2);
/* Add start and stop lines */
gsk_path_builder_move_to (builder, 1.5 * MAZE_GRID_SIZE, -0.5 * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, 1.5 * MAZE_GRID_SIZE, 1.5 * MAZE_GRID_SIZE);
gsk_path_builder_move_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT - 1.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT + 0.5) * MAZE_GRID_SIZE);
gtk_bitset_unref (maze);
return gsk_path_builder_free_to_path (builder);
}
GtkWidget *
do_path_maze (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *maze;
GtkMediaStream *stream;
GskPath *path;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Follow the maze with the mouse");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#if 0
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
#else
stream = gtk_nuclear_media_stream_new ();
#endif
gtk_media_stream_play (stream);
gtk_media_stream_set_loop (stream, TRUE);
path = create_path_for_maze (window);
maze = gtk_maze_new (path,
GDK_PAINTABLE (stream),
MAZE_WIDTH * MAZE_GRID_SIZE,
MAZE_HEIGHT * MAZE_GRID_SIZE);
gtk_window_set_child (GTK_WINDOW (window), maze);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,594 +0,0 @@
/* Path/Curved Text
*
* This demo shows how to use GskPath to animate a path along another path.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_WIDGET (gtk_path_widget_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathWidget, gtk_path_widget, GTK, PATH_WIDGET, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_TEXT,
PROP_EDITABLE,
N_PROPS
};
struct _GtkPathWidget
{
GtkWidget parent_instance;
char *text;
gboolean editable;
graphene_point_t points[4];
guint active_point;
float line_closest;
GskPath *line_path;
GskPathMeasure *line_measure;
GskPath *text_path;
GdkPaintable *background;
};
struct _GtkPathWidgetClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWidget, gtk_path_widget, GTK_TYPE_WIDGET)
static GskPath *
create_path_from_text (GtkWidget *widget,
const char *text)
{
cairo_surface_t *surface;
cairo_t *cr;
cairo_path_t *path;
PangoLayout *layout;
PangoFontDescription *desc;
GskPath *result;
surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
cr = cairo_create (surface);
layout = gtk_widget_create_pango_layout (widget, text);
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
cairo_move_to (cr, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
pango_cairo_layout_path (cr, layout);
path = cairo_copy_path (cr);
result = gsk_path_new_from_cairo (path);
cairo_path_destroy (path);
g_object_unref (layout);
cairo_destroy (cr);
cairo_surface_destroy (surface);
return result;
}
typedef struct
{
GskPathMeasure *measure;
GskPathBuilder *builder;
double scale;
} GtkPathTransform;
static void
gtk_path_transform_point (GskPathMeasure *measure,
const graphene_point_t *pt,
float scale,
graphene_point_t *res)
{
graphene_vec2_t tangent;
gsk_path_measure_get_point (measure, pt->x * scale, res, &tangent);
res->x -= pt->y * scale * graphene_vec2_get_y (&tangent);
res->y += pt->y * scale * graphene_vec2_get_x (&tangent);
}
static gboolean
gtk_path_transform_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GtkPathTransform *transform = data;
switch (op)
{
case GSK_PATH_MOVE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[0], transform->scale, &res);
gsk_path_builder_move_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_LINE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res);
gsk_path_builder_line_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_CURVE:
{
graphene_point_t res[3];
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &pts[3], transform->scale, &res[2]);
gsk_path_builder_curve_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
}
break;
case GSK_PATH_CONIC:
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], transform->scale, &res[1]);
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, weight);
}
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (transform->builder);
break;
default:
g_assert_not_reached();
return FALSE;
}
return TRUE;
}
static GskPath *
gtk_path_transform (GskPathMeasure *measure,
GskPath *path)
{
GtkPathTransform transform = { measure, gsk_path_builder_new () };
graphene_rect_t bounds;
gsk_path_get_bounds (path, &bounds);
if (bounds.origin.x + bounds.size.width > 0)
transform.scale = gsk_path_measure_get_length (measure) / (bounds.origin.x + bounds.size.width);
else
transform.scale = 1.0f;
gsk_path_foreach (path, GSK_PATH_FOREACH_ALLOW_CURVE, gtk_path_transform_op, &transform);
return gsk_path_builder_free_to_path (transform.builder);
}
static void
gtk_path_widget_clear_text_path (GtkPathWidget *self)
{
g_clear_pointer (&self->text_path, gsk_path_unref);
}
static void
gtk_path_widget_clear_paths (GtkPathWidget *self)
{
gtk_path_widget_clear_text_path (self);
g_clear_pointer (&self->line_path, gsk_path_unref);
g_clear_pointer (&self->line_measure, gsk_path_measure_unref);
}
static void
gtk_path_widget_create_text_path (GtkPathWidget *self)
{
GskPath *path;
gtk_path_widget_clear_text_path (self);
if (self->line_measure == NULL)
return;
path = create_path_from_text (GTK_WIDGET (self), self->text);
self->text_path = gtk_path_transform (self->line_measure, path);
gsk_path_unref (path);
}
static void
gtk_path_widget_create_paths (GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
GskPathBuilder *builder;
gtk_path_widget_clear_paths (self);
if (width <= 0 || height <= 0)
return;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder,
self->points[0].x * width, self->points[0].y * height);
gsk_path_builder_curve_to (builder,
self->points[1].x * width, self->points[1].y * height,
self->points[2].x * width, self->points[2].y * height,
self->points[3].x * width, self->points[3].y * height);
self->line_path = gsk_path_builder_free_to_path (builder);
self->line_measure = gsk_path_measure_new (self->line_path);
gtk_path_widget_create_text_path (self);
}
static void
gtk_path_widget_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
GTK_WIDGET_CLASS (gtk_path_widget_parent_class)->size_allocate (widget, width, height, baseline);
gtk_path_widget_create_paths (self);
}
static void
gtk_path_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskPath *path;
GskStroke *stroke;
gsize i;
/* frosted glass the background */
gtk_snapshot_push_blur (snapshot, 100);
gdk_paintable_snapshot (self->background, snapshot, width, height);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 0.5 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the text */
if (self->text_path)
{
gtk_snapshot_push_fill (snapshot, self->text_path, GSK_FILL_RULE_WINDING);
gdk_paintable_snapshot (self->background, snapshot, width, height);
/* ... with an emboss effect */
stroke = gsk_stroke_new (2.0);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(1, 1));
gtk_snapshot_push_stroke (snapshot, self->text_path, stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 0.2 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gsk_stroke_free (stroke);
gtk_snapshot_pop (snapshot);
gtk_snapshot_pop (snapshot);
}
if (self->editable && self->line_path)
{
/* draw the control line */
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, self->line_path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
if (self->line_closest >= 0)
{
GskPathBuilder *builder;
graphene_point_t closest;
builder = gsk_path_builder_new ();
gsk_path_measure_get_point (self->line_measure, self->line_closest, &closest, NULL);
gsk_path_builder_add_circle (builder, &closest, POINT_SIZE);
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
if (self->editable && self->line_path)
{
GskPathBuilder *builder;
/* draw the points */
builder = gsk_path_builder_new ();
for (i = 0; i < 4; i++)
{
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), POINT_SIZE);
}
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
}
static void
gtk_path_widget_set_text (GtkPathWidget *self,
const char *text)
{
if (g_strcmp0 (self->text, text) == 0)
return;
g_free (self->text);
self->text = g_strdup (text);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
}
static void
gtk_path_widget_set_editable (GtkPathWidget *self,
gboolean editable)
{
if (self->editable == editable)
return;
self->editable = editable;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITABLE]);
}
static void
gtk_path_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
gtk_path_widget_set_text (self, g_value_get_string (value));
break;
case PROP_EDITABLE:
gtk_path_widget_set_editable (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
g_value_set_string (value, self->text);
break;
case PROP_EDITABLE:
g_value_set_boolean (value, self->editable);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_dispose (GObject *object)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
gtk_path_widget_clear_paths (self);
G_OBJECT_CLASS (gtk_path_widget_parent_class)->dispose (object);
}
static void
gtk_path_widget_class_init (GtkPathWidgetClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_widget_dispose;
object_class->set_property = gtk_path_widget_set_property;
object_class->get_property = gtk_path_widget_get_property;
widget_class->size_allocate = gtk_path_widget_allocate;
widget_class->snapshot = gtk_path_widget_snapshot;
properties[PROP_TEXT] =
g_param_spec_string ("text",
"text",
"Text transformed along a path",
NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_EDITABLE] =
g_param_spec_boolean ("editable",
"editable",
"If the path can be edited by the user",
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
drag_begin (GtkGestureDrag *gesture,
double x,
double y,
GtkPathWidget *self)
{
graphene_point_t mouse = GRAPHENE_POINT_INIT (x, y);
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
gsize i;
for (i = 0; i < 4; i++)
{
if (graphene_point_distance (&GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), &mouse, NULL, NULL) <= POINT_SIZE)
{
self->active_point = i;
break;
}
}
if (i == 4)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
drag_update (GtkGestureDrag *drag,
double offset_x,
double offset_y,
GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
double start_x, start_y;
gtk_gesture_drag_get_start_point (drag, &start_x, &start_y);
self->points[self->active_point] = GRAPHENE_POINT_INIT ((start_x + offset_x) / width,
(start_y + offset_y) / height);
self->points[self->active_point].x = CLAMP (self->points[self->active_point].x, 0, 1);
self->points[self->active_point].y = CLAMP (self->points[self->active_point].y, 0, 1);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkPathWidget *self)
{
gsk_path_measure_get_closest_point_full (self->line_measure,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
NULL, NULL,
&self->line_closest,
NULL);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkPathWidget *self)
{
self->line_closest = -1;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_path_widget_init (GtkPathWidget *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_update), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "enter", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->line_closest = -1;
self->points[0] = GRAPHENE_POINT_INIT (0.1, 0.9);
self->points[1] = GRAPHENE_POINT_INIT (0.3, 0.1);
self->points[2] = GRAPHENE_POINT_INIT (0.7, 0.1);
self->points[3] = GRAPHENE_POINT_INIT (0.9, 0.9);
self->background = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
gtk_path_widget_set_text (self, "It's almost working");
}
GtkWidget *
gtk_path_widget_new (void)
{
GtkPathWidget *self;
self = g_object_new (GTK_TYPE_PATH_WIDGET, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_text (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_WIDGET);
builder = gtk_builder_new_from_resource ("/path_text/path_text.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Text along a Path</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkToggleButton" id="edit-toggle">
<property name="icon-name">document-edit-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer">
<property name="reveal-child" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<child>
<object class="GtkEntry" id="text">
<property name="text">Through the looking glass</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPathWidget" id="view">
<property name="editable" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<property name="text" bind-source="text" bind-property="text" bind-flags="sync-create"></property>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,7 +1,7 @@
/* Peg Solitaire
* #Keywords: GtkGridView, game
*
* This demo demonstrates how to use drag-and-drop to implement peg solitaire.
* This demo demonstrates how to use drag'n'drop to implement peg solitaire.
*
*/
@@ -98,7 +98,7 @@ solitaire_peg_init (SolitairePeg *peg)
/* Add a little setter for the peg's position.
* We want to track those so that we can check for legal moves
* during drag-and-drop operations.
* during drag'n'drop operations.
*/
static void
solitaire_peg_set_position (SolitairePeg *peg,

View File

@@ -25,43 +25,43 @@ show_shortcuts (GtkWidget *window,
g_object_unref (builder);
}
G_MODULE_EXPORT void
void
shortcuts_builder_shortcuts (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-builder", NULL);
}
G_MODULE_EXPORT void
void
shortcuts_gedit_shortcuts (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-gedit", NULL);
}
G_MODULE_EXPORT void
void
shortcuts_clocks_shortcuts (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-clocks", NULL);
}
G_MODULE_EXPORT void
void
shortcuts_clocks_shortcuts_stopwatch (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-clocks", "stopwatch");
}
G_MODULE_EXPORT void
void
shortcuts_boxes_shortcuts (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-boxes", NULL);
}
G_MODULE_EXPORT void
void
shortcuts_boxes_shortcuts_wizard (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-boxes", "wizard");
}
G_MODULE_EXPORT void
void
shortcuts_boxes_shortcuts_display (GtkWidget *window)
{
show_shortcuts (window, "shortcuts-boxes", "display");

View File

@@ -2,7 +2,6 @@
#include <float.h>
#include <math.h>
#include <glib.h>
#include <assert.h>
/* See Golub and Reinsch,
* "Handbook for Automatic Computation vol II - Linear Algebra",
@@ -40,9 +39,6 @@ householder_reduction (double *A,
double *pu, *pui, *pv, *pvi;
double half_norm_squared;
assert (nrows >= 2);
assert (ncols >= 2);
memcpy (U, A, sizeof (double) * nrows * ncols);
diagonal[0] = 0.0;
@@ -209,9 +205,6 @@ givens_reduction (int nrows,
int rotation_test;
int iteration_count;
assert (nrows >= 2);
assert (ncols >= 2);
for (i = 0, x = 0.0; i < ncols; i++)
{
y = fabs (diagonal[i]) + fabs (superdiagonal[i]);
@@ -349,9 +342,6 @@ sort_singular_values (int nrows,
double temp;
double *p1, *p2;
assert (nrows >= 2);
assert (ncols >= 2);
for (i = 0; i < ncols - 1; i++)
{
max_index = i;
@@ -443,12 +433,9 @@ singular_value_decomposition_solve (double *U,
double d;
double tolerance;
assert (nrows >= 2);
assert (ncols >= 2);
tolerance = DBL_EPSILON * S[0] * (double) ncols;
for (i = 0, pv = V; i < ncols; i++, pv += ncols)
for ( i = 0, pv = V; i < ncols; i++, pv += ncols)
{
x[i] = 0.0;
for (j = 0; j < ncols; j++)

View File

@@ -12,7 +12,7 @@
#include <math.h>
#include <stdlib.h>
G_MODULE_EXPORT int
int
spinbutton_hex_spin_input (GtkSpinButton *spin_button,
double *new_val)
{
@@ -29,7 +29,7 @@ spinbutton_hex_spin_input (GtkSpinButton *spin_button,
return TRUE;
}
G_MODULE_EXPORT int
int
spinbutton_hex_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
@@ -49,7 +49,7 @@ spinbutton_hex_spin_output (GtkSpinButton *spin_button)
return TRUE;
}
G_MODULE_EXPORT int
int
spinbutton_time_spin_input (GtkSpinButton *spin_button,
double *new_val)
{
@@ -88,7 +88,7 @@ spinbutton_time_spin_input (GtkSpinButton *spin_button,
return TRUE;
}
G_MODULE_EXPORT int
int
spinbutton_time_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
@@ -122,7 +122,7 @@ static const char *month[12] = {
"December"
};
G_MODULE_EXPORT int
int
spinbutton_month_spin_input (GtkSpinButton *spin_button,
double *new_val)
{
@@ -151,7 +151,7 @@ spinbutton_month_spin_input (GtkSpinButton *spin_button,
return TRUE;
}
G_MODULE_EXPORT int
int
spinbutton_month_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;

View File

@@ -47,24 +47,22 @@ static int
svg_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
SvgPaintable *self = SVG_PAINTABLE (paintable);
double width;
RsvgDimensionData data;
if (!rsvg_handle_get_intrinsic_size_in_pixels (self->handle, &width, NULL))
return 0;
rsvg_handle_get_dimensions (self->handle, &data);
return ceil (width);
return data.width;
}
static int
svg_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
SvgPaintable *self = SVG_PAINTABLE (paintable);
double height;
RsvgDimensionData data;
if (!rsvg_handle_get_intrinsic_size_in_pixels (self->handle, NULL, &height))
return 0;
rsvg_handle_get_dimensions (self->handle, &data);
return ceil (height);
return data.height;
}
static void

View File

@@ -1,11 +1,6 @@
/* Text View/Tabs
*
* GtkTextView can position text at fixed positions, using tabs.
* Tabs can specify alignment, and also allow aligning numbers
* on the decimal point.
*
* The example here has three tabs, with left, numeric and right
* alignment.
*/
#include <gtk/gtk.h>
@@ -27,7 +22,7 @@ do_tabs (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Tabs");
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 330, 130);
gtk_window_set_default_size (GTK_WINDOW (window), 330, 330);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
@@ -40,18 +35,17 @@ do_tabs (GtkWidget *do_widget)
tabs = pango_tab_array_new (3, TRUE);
pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, 0);
pango_tab_array_set_tab (tabs, 1, PANGO_TAB_DECIMAL, 150);
pango_tab_array_set_decimal_point (tabs, 1, '.');
pango_tab_array_set_tab (tabs, 2, PANGO_TAB_RIGHT, 290);
pango_tab_array_set_tab (tabs, 1, PANGO_TAB_LEFT, 100);
pango_tab_array_set_tab (tabs, 2, PANGO_TAB_LEFT, 200);
gtk_text_view_set_tabs (GTK_TEXT_VIEW (view), tabs);
pango_tab_array_free (tabs);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_text (buffer, "one\t2.0\tthree\nfour\t5.555\tsix\nseven\t88.88\tnine", -1);
gtk_text_buffer_set_text (buffer, "one\ttwo\tthree\nfour\tfive\tsix\nseven\teight\tnine", -1);
sw = gtk_scrolled_window_new ();
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_window_set_child (GTK_WINDOW (window), sw);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), view);

File diff suppressed because it is too large Load Diff

View File

@@ -72,7 +72,7 @@ about_activated (GSimpleAction *action,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());

View File

@@ -16,7 +16,7 @@ executable('gtk4-icon-browser',
c_args: common_cflags,
dependencies: [ libgtk_dep, demo_conf_h ],
include_directories: confinc,
win_subsystem: 'windows',
gui_app: true,
link_args: extra_demo_ldflags,
install: true,
)
@@ -32,10 +32,5 @@ endforeach
install_data('org.gtk.IconBrowser4.desktop', install_dir: gtk_applicationsdir)
# appdata
configure_file(
input: 'org.gtk.IconBrowser4.appdata.xml.in',
output: 'org.gtk.IconBrowser4.appdata.xml',
configuration: appdata_config,
install_dir: gtk_appdatadir
)
install_data('org.gtk.IconBrowser4.appdata.xml', install_dir: gtk_appdatadir)

View File

@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>org.gtk.IconBrowser4</id>
<launchable type="desktop-id">org.gtk.IconBrowser4.desktop</launchable>
<id>org.gtk.IconBrowser4.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-2.1-or-later</project_license>
<project_license>LGPL-2.0+</project_license>
<name>GTK Icon Browser</name>
<summary>Program to browse themed icons</summary>
<description>
@@ -30,11 +29,15 @@
<translation type="gettext">gtk-4.0</translation>
<update_contact>matthias.clasen_at_gmail.com</update_contact>
<developer_name>Matthias Clasen and others</developer_name>
<content_rating type="oars-1.1"/>
<releases>
<release version="@BUILD_VERSION@">
<release version="3.99.0" date="2020-07-30">
<description>
<p>A new build of GTK.</p>
<p>A new developers snapshot towards GTK 4.0.</p>
</description>
</release>
<release version="3.94.0" date="2018-06-25">
<description>
<p>A new developers snapshot towards GTK 4.0.</p>
</description>
</release>
</releases>

View File

@@ -1,21 +1,19 @@
gen_demo_header = find_program('../build-aux/meson/gen-demo-header.py')
demo_profile = get_option('profile')
demo_conf = configuration_data()
demo_conf.set_quoted('PROFILE', get_option('profile'))
demo_conf.set_quoted('VCS_TAG', '@VCS_TAG@')
demo_conf_h = declare_dependency(
sources: custom_target('demo-header',
command: [gen_demo_header, meson.project_source_root(), demo_profile],
capture: true,
output: 'demo_conf.h',
build_by_default: true,
build_always_stale: true,
)
sources: vcs_tag(
command: [ 'git', 'rev-parse', '--short', 'HEAD' ],
fallback: get_option('profile') != 'default' ? 'devel' : '',
input: configure_file(
output: 'demo_conf.h.in',
configuration: demo_conf
),
output: 'demo_conf.h'
)
)
# appdata
appdata_config = configuration_data()
appdata_config.set('BUILD_VERSION', meson.project_version())
subdir('constraint-editor')
subdir('gtk-demo')
subdir('icon-browser')

View File

@@ -17,7 +17,7 @@ executable('gtk4-node-editor',
c_args: [
'-DNODE_EDITOR_SOURCE_DIR="@0@/../../testsuite/gsk/compare/"'.format(meson.current_source_dir())
] + common_cflags,
win_subsystem: 'windows',
gui_app: true,
link_args: extra_demo_ldflags,
install: false,
)

View File

@@ -79,7 +79,7 @@ activate_about (GSimpleAction *action,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());

View File

@@ -25,6 +25,7 @@
#include "gsk/gskrendernodeparserprivate.h"
#include "gsk/gl/gskglrenderer.h"
#include "gsk/ngl/gsknglrenderer.h"
#ifdef GDK_WINDOWING_BROADWAY
#include "gsk/broadway/gskbroadwayrenderer.h"
#endif
@@ -60,7 +61,7 @@ struct _NodeEditorWindow
GtkWidget *renderer_listbox;
GListStore *renderers;
GskRenderNode *node;
GdkPaintable *paintable;
GFileMonitor *file_monitor;
@@ -167,6 +168,7 @@ static void
text_changed (GtkTextBuffer *buffer,
NodeEditorWindow *self)
{
GskRenderNode *node;
char *text;
GBytes *bytes;
GtkTextIter iter;
@@ -177,12 +179,10 @@ text_changed (GtkTextBuffer *buffer,
text_buffer_remove_all_tags (self->text_buffer);
bytes = g_bytes_new_take (text, strlen (text));
g_clear_pointer (&self->node, gsk_render_node_unref);
/* If this is too slow, go fix the parser performance */
self->node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
g_bytes_unref (bytes);
if (self->node)
if (node)
{
/* XXX: Is this code necessary or can we have API to turn nodes into paintables? */
GtkSnapshot *snapshot;
@@ -191,9 +191,10 @@ text_changed (GtkTextBuffer *buffer,
guint i;
snapshot = gtk_snapshot_new ();
gsk_render_node_get_bounds (self->node, &bounds);
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, self->node);
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);
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i++)
@@ -337,38 +338,17 @@ text_view_query_tooltip_cb (GtkWidget *widget,
}
static gboolean
load_bytes (NodeEditorWindow *self,
GBytes *bytes);
static void
load_error (NodeEditorWindow *self,
const char *error_message)
load_file_contents (NodeEditorWindow *self,
GFile *file)
{
PangoLayout *layout;
GtkSnapshot *snapshot;
GskRenderNode *node;
GBytes *bytes;
layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), error_message);
pango_layout_set_width (layout, 300 * PANGO_SCALE);
snapshot = gtk_snapshot_new ();
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA) { 0.7, 0.13, 0.13, 1.0 });
node = gtk_snapshot_free_to_node (snapshot);
bytes = gsk_render_node_serialize (node);
bytes = g_file_load_bytes (file, NULL, NULL, NULL);
if (bytes == NULL)
return FALSE;
load_bytes (self, bytes);
gsk_render_node_unref (node);
g_object_unref (layout);
}
static gboolean
load_bytes (NodeEditorWindow *self,
GBytes *bytes)
{
if (!g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
{
load_error (self, "Invalid UTF-8");
g_bytes_unref (bytes);
return FALSE;
}
@@ -382,110 +362,6 @@ load_bytes (NodeEditorWindow *self,
return TRUE;
}
static gboolean
load_file_contents (NodeEditorWindow *self,
GFile *file)
{
GError *error = NULL;
GBytes *bytes;
bytes = g_file_load_bytes (file, NULL, NULL, &error);
if (bytes == NULL)
{
load_error (self, error->message);
g_clear_error (&error);
return FALSE;
}
return load_bytes (self, bytes);
}
static GdkContentProvider *
on_picture_drag_prepare_cb (GtkDragSource *source,
double x,
double y,
NodeEditorWindow *self)
{
if (self->node == NULL)
return NULL;
return gdk_content_provider_new_typed (GSK_TYPE_RENDER_NODE, self->node);
}
static void
on_picture_drop_read_done_cb (GObject *source,
GAsyncResult *res,
gpointer data)
{
NodeEditorWindow *self = data;
GOutputStream *stream = G_OUTPUT_STREAM (source);
GdkDrop *drop = g_object_get_data (source, "drop");
GdkDragAction action = 0;
GBytes *bytes;
if (g_output_stream_splice_finish (stream, res, NULL) >= 0)
{
bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (stream));
if (load_bytes (self, bytes))
action = GDK_ACTION_COPY;
}
g_object_unref (self);
gdk_drop_finish (drop, action);
g_object_unref (drop);
return;
}
static void
on_picture_drop_read_cb (GObject *source,
GAsyncResult *res,
gpointer data)
{
NodeEditorWindow *self = data;
GdkDrop *drop = GDK_DROP (source);
GInputStream *input;
GOutputStream *output;
input = gdk_drop_read_finish (drop, res, NULL, NULL);
if (input == NULL)
{
g_object_unref (self);
gdk_drop_finish (drop, 0);
return;
}
output = g_memory_output_stream_new_resizable ();
g_object_set_data (G_OBJECT (output), "drop", drop);
g_object_ref (drop);
g_output_stream_splice_async (output,
input,
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
G_PRIORITY_DEFAULT,
NULL,
on_picture_drop_read_done_cb,
self);
g_object_unref (output);
g_object_unref (input);
}
static gboolean
on_picture_drop_cb (GtkDropTargetAsync *dest,
GdkDrop *drop,
double x,
double y,
NodeEditorWindow *self)
{
gdk_drop_read_async (drop,
(const char *[2]) { "application/x-gtk-render-node", NULL },
G_PRIORITY_DEFAULT,
NULL,
on_picture_drop_read_cb,
g_object_ref (self));
return TRUE;
}
static void
file_changed_cb (GFileMonitor *monitor,
GFile *file,
@@ -505,18 +381,17 @@ node_editor_window_load (NodeEditorWindow *self,
{
GError *error = NULL;
g_clear_object (&self->file_monitor);
if (!load_file_contents (self, file))
return FALSE;
g_clear_object (&self->file_monitor);
self->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
if (error)
{
g_warning ("couldn't monitor file: %s", error->message);
g_error_free (error);
g_clear_object (&self->file_monitor);
}
else
{
@@ -679,6 +554,7 @@ create_cairo_texture (NodeEditorWindow *self)
GskRenderer *renderer;
GskRenderNode *node;
GdkTexture *texture;
GdkSurface *surface;
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
if (paintable == NULL ||
@@ -691,8 +567,9 @@ create_cairo_texture (NodeEditorWindow *self)
if (node == NULL)
return NULL;
surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (self)));
renderer = gsk_cairo_renderer_new ();
gsk_renderer_realize (renderer, NULL, NULL);
gsk_renderer_realize (renderer, surface, NULL);
texture = gsk_renderer_render_texture (renderer, node, NULL);
gsk_render_node_unref (node);
@@ -758,24 +635,6 @@ export_image_cb (GtkWidget *button,
gtk_widget_show (dialog);
}
static void
clip_image_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GdkTexture *texture;
GdkClipboard *clipboard;
texture = create_texture (self);
if (texture == NULL)
return;
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (self));
gdk_clipboard_set_texture (clipboard, texture);
g_object_unref (texture);
}
static void
testcase_name_entry_changed_cb (GtkWidget *button,
GParamSpec *pspec,
@@ -859,7 +718,6 @@ node_editor_window_finalize (GObject *object)
g_array_free (self->errors, TRUE);
g_clear_pointer (&self->node, gsk_render_node_unref);
g_clear_object (&self->renderers);
G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object);
@@ -870,18 +728,16 @@ node_editor_window_add_renderer (NodeEditorWindow *self,
GskRenderer *renderer,
const char *description)
{
GdkSurface *surface;
GdkPaintable *paintable;
if (!gsk_renderer_realize (renderer, NULL, NULL))
{
GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (self));
g_assert (surface != NULL);
surface = gtk_native_get_surface (GTK_NATIVE (self));
g_assert (surface != NULL);
if (!gsk_renderer_realize (renderer, surface, NULL))
{
g_object_unref (renderer);
return;
}
if (renderer != NULL && !gsk_renderer_realize (renderer, surface, NULL))
{
g_object_unref (renderer);
return;
}
paintable = gtk_renderer_paintable_new (renderer, gtk_picture_get_paintable (GTK_PICTURE (self->picture)));
@@ -907,6 +763,9 @@ node_editor_window_realize (GtkWidget *widget)
node_editor_window_add_renderer (self,
gsk_gl_renderer_new (),
"OpenGL");
node_editor_window_add_renderer (self,
gsk_ngl_renderer_new (),
"NGL");
#ifdef GDK_RENDERING_VULKAN
node_editor_window_add_renderer (self,
gsk_vulkan_renderer_new (),
@@ -967,12 +826,9 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
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);
gtk_widget_class_bind_template_callback (widget_class, clip_image_cb);
gtk_widget_class_bind_template_callback (widget_class, testcase_save_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, testcase_name_entry_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, dark_mode_cb);
gtk_widget_class_bind_template_callback (widget_class, on_picture_drag_prepare_cb);
gtk_widget_class_bind_template_callback (widget_class, on_picture_drop_cb);
}
static GtkWidget *

View File

@@ -102,7 +102,6 @@
<object class="GtkHeaderBar" id="header">
<child type="start">
<object class="GtkButton">
<property name="focus-on-click">0</property>
<property name="icon-name">document-open-symbolic</property>
<property name="tooltip-text">Open node file</property>
<signal name="clicked" handler="open_cb"/>
@@ -110,7 +109,6 @@
</child>
<child type="start">
<object class="GtkButton">
<property name="focus-on-click">0</property>
<property name="icon-name">document-save-symbolic</property>
<property name="tooltip-text">Save to node file</property>
<signal name="clicked" handler="save_cb"/>
@@ -118,30 +116,24 @@
</child>
<child type="start">
<object class="GtkButton">
<property name="focus-on-click">0</property>
<property name="icon-name">insert-image-symbolic</property>
<property name="tooltip-text">Export to image</property>
<signal name="clicked" handler="export_image_cb"/>
</object>
</child>
<child type="start">
<object class="GtkButton">
<property name="focus-on-click">0</property>
<property name="icon-name">edit-copy-symbolic</property>
<property name="tooltip-text">Copy image to clipboard</property>
<signal name="clicked" handler="clip_image_cb"/>
<object class="GtkSeparator">
<property name="orientation">vertical</property>
</object>
</child>
<child type="start">
<object class="GtkMenuButton">
<property name="focus-on-click">0</property>
<property name="label">Save Testcase</property>
<property name="popover">testcase_popover</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gear_menu_button">
<property name="focus-on-click">0</property>
<property name="valign">center</property>
<property name="menu-model">gear_menu</property>
<property name="icon-name">open-menu-symbolic</property>
@@ -149,7 +141,6 @@
</child>
<child type="end">
<object class="GtkToggleButton" id="dark_bg_button">
<property name="focus-on-click">0</property>
<property name="valign">center</property>
<property name="has-frame">0</property>
<property name="icon-name">display-brightness-symbolic</property>
@@ -161,10 +152,9 @@
</child>
<child>
<object class="GtkPaned">
<property name="shrink-start-child">false</property>
<property name="shrink-end-child">false</property>
<property name="position">400</property>
<property name="start-child">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="hexpand">1</property>
@@ -185,8 +175,8 @@
</object>
</child>
</object>
</property>
<property name="end-child">
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
@@ -199,22 +189,8 @@
<child>
<object class="GtkPicture" id="picture">
<property name="can-shrink">0</property>
<property name="keep-aspect-ratio">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkDragSource">
<property name="actions">copy</property>
<signal name="prepare" handler="on_picture_drag_prepare_cb" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkDropTargetAsync">
<property name="actions">copy</property>
<property name="formats">application/x-gtk-render-node</property>
<signal name="drop" handler="on_picture_drop_cb" swapped="no"/>
</object>
</child>
</object>
@@ -232,7 +208,7 @@
</object>
</child>
</object>
</property>
</child>
</object>
</child>
</template>

View File

@@ -3,7 +3,7 @@ executable('gtk4-print-editor',
c_args: common_cflags,
dependencies: [ libgtk_dep, demo_conf_h ],
include_directories: confinc,
win_subsystem: 'windows',
gui_app: true,
link_args: extra_demo_ldflags,
install: true,
)

View File

@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>org.gtk.PrintEditor4</id>
<launchable type="desktop-id">org.gtk.PrintEditor4.desktop</launchable>
<id>org.gtk.PrintEditor4.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-2.1-or-later</project_license>
<project_license>LGPL-2.0+</project_license>
<name>GTK Print Editor</name>
<summary>Program to demonstrate GTK printing</summary>
<description>
@@ -25,7 +24,6 @@
<translation type="gettext">gtk-4.0</translation>
<update_contact>matthias.clasen_at_gmail.com</update_contact>
<developer_name>Matthias Clasen and others</developer_name>
<content_rating type="oars-1.1"/>
<releases>
<release version="3.99.0" date="2020-07-30">
<description>

View File

@@ -42,7 +42,7 @@ update_statusbar (void)
const char *print_str;
gtk_statusbar_pop (GTK_STATUSBAR (statusbar), 0);
gtk_text_buffer_get_iter_at_mark (buffer,
&iter,
gtk_text_buffer_get_insert (buffer));
@@ -56,7 +56,7 @@ update_statusbar (void)
GtkPrintOperation *op = active_prints->data;
print_str = gtk_print_operation_get_status_string (op);
}
msg = g_strdup_printf ("%d, %d%s %s",
row, col,
file_changed?" - Modified":"",
@@ -159,7 +159,7 @@ save_file (GFile *save_filename)
error = NULL;
g_file_replace_contents (save_filename,
text, strlen (text),
text, -1,
NULL, FALSE,
G_FILE_CREATE_NONE,
NULL,
@@ -188,10 +188,10 @@ save_file (GFile *save_filename)
"Error saving to file %s:\n%s",
display_name,
error->message);
g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
gtk_widget_show (error_dialog);
g_error_free (error);
g_object_unref (info);
}
@@ -229,7 +229,7 @@ begin_print (GtkPrintOperation *operation,
pango_font_description_free (desc);
pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
pango_layout_set_text (print_data->layout, print_data->text, -1);
num_lines = pango_layout_get_line_count (print_data->layout);
@@ -241,7 +241,7 @@ begin_print (GtkPrintOperation *operation,
{
PangoRectangle ink_rect, logical_rect;
double line_height;
layout_line = pango_layout_get_line (print_data->layout, line);
pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
@@ -258,7 +258,7 @@ begin_print (GtkPrintOperation *operation,
page_breaks = g_list_reverse (page_breaks);
gtk_print_operation_set_n_pages (operation, g_list_length (page_breaks) + 1);
print_data->page_breaks = page_breaks;
}
@@ -287,11 +287,11 @@ draw_page (GtkPrintOperation *operation,
end = pango_layout_get_line_count (print_data->layout);
else
end = GPOINTER_TO_INT (pagebreak->data);
cr = gtk_print_context_get_cairo_context (context);
cairo_set_source_rgb (cr, 0, 0, 0);
i = 0;
start_pos = 0;
iter = pango_layout_get_iter (print_data->layout);
@@ -307,12 +307,12 @@ draw_page (GtkPrintOperation *operation,
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
if (i == start)
start_pos = logical_rect.y / 1024.0;
cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
pango_cairo_show_layout_line (cr, line);
}
i++;
@@ -383,9 +383,9 @@ print_done (GtkPrintOperation *op,
{
GtkWidget *error_dialog;
gtk_print_operation_get_error (op, &error);
error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
@@ -405,13 +405,13 @@ print_done (GtkPrintOperation *op,
g_free (print_data->text);
g_free (print_data->font);
g_free (print_data);
if (!gtk_print_operation_is_finished (op))
{
g_object_ref (op);
active_prints = g_list_append (active_prints, op);
update_statusbar ();
/* This ref is unref:ed when we get the final state change */
g_signal_connect (op, "status_changed",
G_CALLBACK (status_changed_cb), NULL);
@@ -628,7 +628,7 @@ activate_about (GSimpleAction *action,
glib_micro_version);
g_string_append_printf (sysinfo, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (sysinfo, "\tGTK \t%d.%d.%d\n",
g_string_append_printf (sysinfo, "\tGTK\t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
@@ -721,6 +721,7 @@ static const char ui_info[] =
" <item>"
" <attribute name='label'>_New</attribute>"
" <attribute name='action'>app.new</attribute>"
" <attribute name='accel'>&lt;Primary&gt;n</attribute>"
" </item>"
" <item>"
" <attribute name='label'>_Open</attribute>"
@@ -729,10 +730,12 @@ static const char ui_info[] =
" <item>"
" <attribute name='label'>_Save</attribute>"
" <attribute name='action'>app.save</attribute>"
" <attribute name='accel'>&lt;Primary&gt;s</attribute>"
" </item>"
" <item>"
" <attribute name='label'>Save _As...</attribute>"
" <attribute name='action'>app.save-as</attribute>"
" <attribute name='accel'>&lt;Primary&gt;s</attribute>"
" </item>"
" </section>"
" <section>"
@@ -753,6 +756,7 @@ static const char ui_info[] =
" <item>"
" <attribute name='label'>_Quit</attribute>"
" <attribute name='action'>app.quit</attribute>"
" <attribute name='accel'>&lt;Primary&gt;q</attribute>"
" </item>"
" </section>"
" </submenu>"
@@ -762,6 +766,7 @@ static const char ui_info[] =
" <item>"
" <attribute name='label'>_About Print Editor</attribute>"
" <attribute name='action'>app.about</attribute>"
" <attribute name='accel'>&lt;Primary&gt;a</attribute>"
" </item>"
" </section>"
" </submenu>"
@@ -789,15 +794,6 @@ startup (GApplication *app)
{
GtkBuilder *builder;
GMenuModel *menubar;
struct {
const char *action_and_target;
const char *accelerators[2];
} accels[] = {
{ "app.new", { "<Control>n", NULL } },
{ "app.quit", { "<Control>q", NULL } },
{ "app.save", { "<Control>s", NULL } },
{ "app.about", { "<Control>a", NULL } },
};
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, ui_info, -1, NULL);
@@ -806,9 +802,6 @@ startup (GApplication *app)
gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
for (int i = 0; i < G_N_ELEMENTS (accels); i++)
gtk_application_set_accels_for_action (GTK_APPLICATION (app), accels[i].action_and_target, accels[i].accelerators);
g_object_unref (builder);
}
@@ -871,7 +864,7 @@ activate (GApplication *app)
update_ui ();
gtk_window_present (GTK_WINDOW (main_window));
gtk_widget_show (main_window);
}
static void

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

View File

@@ -1,84 +1,16 @@
# demos/widget-factory
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help').stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
# Create the resource blob
widgetfactory_gresource = custom_target('widgetfactory.gresource',
input : 'widget-factory.gresource.xml',
output : 'widgetfactory.gresource',
depfile: 'widgetfactory.gresource.d',
command : [glib_compile_resources,
'--generate',
'--internal',
'--target=@OUTPUT@',
'--dependency-file=@DEPFILE@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
'@INPUT@'])
# Create resource data file
widgetfactory_resources_c = custom_target('widgetfactory_resources.c',
input : 'widget-factory.gresource.xml',
output : 'widgetfactory_resources.c',
depfile: 'widgetfactory_resources.c.d',
command : [glib_compile_resources,
'--generate-source',
'--internal',
'--target=@OUTPUT@',
'--dependency-file=@DEPFILE@',
'--sourcedir=' + meson.current_source_dir(),
'--sourcedir=' + meson.current_build_dir(),
'--external-data',
'--c-name', '_g_binary_widgetfactory',
'@INPUT@'])
# Create object file containing resource data
widgetfactory_resources_binary = custom_target('widgetfactory_resources.o',
input : widgetfactory_gresource,
output : 'widgetfactory_resources.o',
command : [ld,
'-z', 'noexecstack',
'-r',
'-b','binary',
'@INPUT@',
'-o','@OUTPUT@'])
# Rename symbol to match the one in the C file
widgetfactory_resources_o = custom_target('widgetfactory_resources2.o',
input : widgetfactory_resources_binary,
output : 'widgetfactory_resources2.o',
command : [objcopy,
'--strip-all',
'--add-symbol','_g_binary_widgetfactory_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])
widgetfactory_resources = [
widgetfactory_resources_c,
widgetfactory_resources_o,
]
else
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
'widget-factory.gresource.xml',
source_dir: '.',
)
endif
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
'widget-factory.gresource.xml',
source_dir: '.',
)
executable('gtk4-widget-factory',
sources: ['widget-factory.c', widgetfactory_resources],
c_args: common_cflags,
dependencies: [ libgtk_dep, demo_conf_h ],
include_directories: confinc,
win_subsystem: 'windows',
gui_app: true,
link_args: extra_demo_ldflags,
install: true,
)
@@ -94,9 +26,4 @@ foreach size: ['scalable', 'symbolic']
endforeach
# appdata
configure_file(
input: 'org.gtk.WidgetFactory4.appdata.xml.in',
output: 'org.gtk.WidgetFactory4.appdata.xml',
configuration: appdata_config,
install_dir: gtk_appdatadir
)
install_data('org.gtk.WidgetFactory4.appdata.xml', install_dir: gtk_appdatadir)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

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