Compare commits

...

388 Commits

Author SHA1 Message Date
Matthias Clasen 80bfd895a4 atspi: Implement Selection for notebook tabs
This is a bit different from the way things were done
in GTK 3 - we follow what was done for GtkStackSwitcher,
and make the tab bar carry the GTK_ACCESSIBLE_TAB_LIST
role, and implement Selection there.
2020-10-14 20:52:33 -04:00
Matthias Clasen fdca39205c notebook: Set accessible roles and properties
Set up the necessary roles, relations and properties
for the tab patterns. This parallels what we have done
for GtkStackSwitcher, and implements the Tabs pattern
as described in the ARIA authoring guidelines.
2020-10-14 20:52:15 -04:00
Matthias Clasen c676977cec atspi: Don't crash on unnamed stack pages
GtkNotebook creates unnamed stack pages, and we should
not crash when that happens.
2020-10-14 19:05:36 -04:00
Matthias Clasen 144f549cc6 gizmo: Add a way to set accessible role
This will be used for some of the gizmo used
inside GtkNotebook.
2020-10-14 18:37:14 -04:00
Matthias Clasen b13b7e63a3 atspi: Implement Selection for GtkStackSwitcher 2020-10-14 01:06:04 -04:00
Matthias Clasen 5d962412c7 stackswitcher: Set up relations and states
Set up a CONTROLS relation between each tab button
and its page, and update the SELECTED property of
the buttons to match their active state.
2020-10-14 00:34:30 -04:00
Matthias Clasen 359881df8a stackswitcher: Use the tablist and tab roles
Set the tablist role on the stackswitcher itself, and
the tab role on the buttons. This is another step towards
implementing the tabs pattern for GtkStack.
2020-10-14 00:18:02 -04:00
Matthias Clasen 342f7db5db accessible: Avoid realizing the context prematurely
platform change is called from gtk_widget_set_focusable
which is likely to be called early on in init(). We don't
want to create an AT context that early if we can help
it, e.g. since it makes it impossible to override the
accessible-role with a construct property.
2020-10-14 00:16:23 -04:00
Matthias Clasen de3fabd38f Make stack pages accessibles
This requires some cleanup to remove assumptions
about accessibles being widgets in the backend,
and some code to navigate the tree with these
extra objects in between widgets.

The accessibles for stack pages have the role
GTK_ACCESSIBLE_ROLE_TAB_PANEL. This is the first
step towards implementing the tabs patterns
as described in the aria authoring guidelines
for GtkStack.
2020-10-13 23:44:50 -04:00
Matthias Clasen b818b34143 Cosmetics
Fix a few copy-paste errors.
2020-10-13 21:27:56 -04:00
Matthias Clasen 32d8db103a Cosmetics
Avoid typo-prone repetition of the full interface names.
We have them in the introspection data already.
2020-10-13 18:58:25 -04:00
Matthias Clasen 9955d900db dropdown: Use the combox accessible role
Its really just a combobox with another name.
2020-10-13 18:31:53 -04:00
Matthias Clasen e3620bdc22 combobox: Use the combobox accessible role
Makes sense.
2020-10-13 17:53:39 -04:00
Matthias Clasen b15328e0d6 atspi: Implement Selection for GtkFlowBox
This is a copy of the listbox implementation.
2020-10-13 17:24:06 -04:00
Matthias Clasen 2664c29454 flowbox: Update accessible state for children
Set the SELECTED state to reflect whether the selected
is selected, unselected, or unselectable. This is
enough to make selection changes appear in Accerciser.

While we are at it, also set the multi-selectable
property for the flowbox itself.
2020-10-13 17:24:06 -04:00
Matthias Clasen db97f99359 atspi: Implement Selection for GtkComboBox
This doesn't really work in Accerciser. But then,
neither does the GTK 3 implementation from which
this is copied.
2020-10-13 17:24:06 -04:00
Matthias Clasen caeea0e368 Remove excessively spammy debug messages
Non need to announce the same things for every context
we create, and the path is not really that interesting.
without knowing what it belongs to. I would suggest to
make it visible in the inspector instead, so you can
look it up for the widgets you are interested in.
2020-10-13 17:24:06 -04:00
Matthias Clasen d0753f645e Fix compiler warnings 2020-10-13 17:24:06 -04:00
Matthias Clasen 81e107885c Remove some unused code 2020-10-13 17:24:06 -04:00
Matthias Clasen 8f4bc4a65d atspi: Fix a variant parser oversight
When you pass a variant, the format needs an @.
GVariant is not your friend.
2020-10-13 17:24:06 -04:00
Matthias Clasen 08f57d5c3d atspi: Implement Selection for listbox
Implement the selection interface for GtkListBox.

This also includes a convenience api for context
addresses: gtk_at_spi_context_to_ref.
2020-10-13 17:24:06 -04:00
Matthias Clasen 3cc9ac406d listbox: Update accessible state for rows
Set the SELECTED state to reflect whether the row
is selected, unselected, or unselectable. This is
enough to make selection changes appear in Accerciser.

While we are at it, also set the multi-selectable
property for the listbox itself.
2020-10-13 17:24:06 -04:00
Matthias Clasen ccbacb5cce Fix the build
I forgot a few casts in a02c50e72f.
2020-10-13 11:23:13 -04:00
Matthias Clasen b909455154 atspi: Fix up the role for password entries
We use to set the the 'password text' role for entries with
visibility = FALSE. Nowadays, we have a separate class for
password entries, so fix up the role mapping based on that.
2020-10-13 10:52:43 -04:00
Matthias Clasen bf0f3a82cf atspi: Make text change notification work
Make text change notification work for editables, by connecting
to the ::insert-text and ::delete-text signals on the wrapped
GtkText widget, and for GtkTextView by connecting to the
corresponding GtkTextBuffer signals.

This code is more or less directly copied from GtkTextViewAccessible
and GtkEntryAccessible in GTK 3.
2020-10-13 09:44:04 -04:00
Matthias Clasen a02c50e72f text: Make editable signals work again
Since the big editable reorg, GtkText was not emitting
::insert-text and ::delete-text, as is expected of
editables. We want to use those signals for a11y
change notification, so make them work again.
2020-10-13 00:49:10 -04:00
Matthias Clasen 81440675af atspi: Set placeholder-text attribute
This is how GTK3 passes placeholder-text to orca,
and it works - orca reads it.
2020-10-12 23:31:03 -04:00
Matthias Clasen 3af56f5216 atspi: Implement EditableText interface for the entry wrappers
Drop the EditableText implementation for GtkText,
and implement it for all the wrapper widgets instead.
2020-10-12 22:07:18 -04:00
Matthias Clasen 63dd0405c7 accessible: Add some docs
Explain briefly how a11y works for entry wrappers
(since I won't remember a few months from now).
2020-10-12 21:58:49 -04:00
Matthias Clasen b7ac660f37 atspi: Implement Text interface for the entry wrappers
Drop the Text implementation for GtkText, and implement
it for all the wrapper widgets instead.
2020-10-12 21:45:48 -04:00
Matthias Clasen 76b87272a6 spinbutton: Implement GtkAccessible
This copies what was done for GtkEntry: get
the focused state from the GtkText within.

We also add a private getter for the text widget,
which was missing here.
2020-10-12 21:45:48 -04:00
Matthias Clasen 852c72fa28 passwordentry: Implement GtkAccessible
This copies what was done for GtkEntry: get
the focused state from the GtkText within.
2020-10-12 21:45:48 -04:00
Matthias Clasen f796d02fea searchentry: Implement GtkAccessible
This copies what was done for GtkEntry: get
the focused state from the GtkText within.
2020-10-12 21:45:48 -04:00
Matthias Clasen 8faf1f64ee entry: Implement GtkAccessible
Override the get_platform_state vfunc to get
the focused state from the GtkText widget within.
2020-10-12 21:45:48 -04:00
Matthias Clasen 8182fab4d9 text: Ignore text widgets for a11y
We want to implement the Text interface on the
wrapper entries.
2020-10-12 21:45:48 -04:00
Matthias Clasen d0d7848cf2 atspi: Use gtk_accessible_get_platform_state 2020-10-12 21:45:48 -04:00
Matthias Clasen ade9e4b82a accessible: Add gtk_accessible_get_platform_state
As a companion to go with the platform_change api,
add a gtk_accessible_get_platform_state() function
that can be used by backends to get the platform
state.

This is in preparation for making entries inherit
their focus states from the text widget within.
2020-10-12 21:45:41 -04:00
Matthias Clasen 663934b2dc atspi: Use gtk_accessible_should_present
Replace explicit visibility check by this
more general method of determining whether
an accessible should be presented to the
a11y layer.
2020-10-12 21:43:17 -04:00
Matthias Clasen d9adc1b5aa accessible: Add a way to hide accessibles
Similar to gtk_widget_should_layout(), add a
gtk_accessible_should_present() function that backends can
use to determine whether an accessible should be presented
or not.

Ways to make a widget not presented in a11y:
- hide the widget
- set its role to NONE
- make it have a NULL AT context

We will use this in future to hide the GtkText inside
an entry, since the Text implementation will be done
by the wrapper.
2020-10-12 21:43:17 -04:00
Matthias Clasen 3bfb32e699 Cosmetics 2020-10-12 21:43:17 -04:00
Matthias Clasen 5eb482ebaa atspi: Treat all entries the same for collecting state
We are determining editable state based on the
accessible role (although we could make it platform
state now), so cover all the roles that we use for
entry wrappers.
2020-10-12 21:43:17 -04:00
Matthias Clasen 61474b5a94 atspi: Fix collecting states
This is somewhat embarrassing.
2020-10-12 21:42:51 -04:00
Matthias Clasen 8f63443393 Fix the build 2020-10-12 21:37:09 -04:00
Matthias Clasen dd650ff90e atspi: D-Bus methods return tuples
I've learned this the hard way: When returning a
value from a D-Bus call, the variant construct must
*always* be g_variant_new ("(...)"...
2020-10-12 15:50:36 -04:00
Matthias Clasen 101cbe690e Don't unref a floating variant
It gets consumed somewhere along the way.
2020-10-12 15:10:40 -04:00
Matthias Clasen 62747eb243 atspi: Unregister objects on the bus
When a widget is going away, we need to remove
the context from the bus, or else ATs might have
the idea to call methods on them, leading to badness.
2020-10-12 15:10:40 -04:00
Matthias Clasen d432cbb02b atspi: Emit property changes for focus
With this orca, actually speaks \o/.  Sadly, it only
says 'gtk modelbutton widget' so far, but its a start.
2020-10-12 15:10:40 -04:00
Matthias Clasen 45e82adf87 atspi: Cosmetics
Use simple wrappers instead of opencoding bit twiddling
all over the place.
2020-10-12 15:10:40 -04:00
Matthias Clasen a2d220edfa widget: Notify a11y of focus changes
This is using the new 'platform changes' mechanism
to tell the a11y backends when focus changes.
2020-10-12 15:10:40 -04:00
Matthias Clasen b5ee73d299 a11y: Pass on platform changes
Add an enum for 'platform changes' to the at context
change notification mechanism. This will let us pass
along things that ARIA considers 'platform state' such
as focus or editability. The difference between the
platform state and other ARIA states is that we don't
keep the platform state separately in the at context
- backends are expected to just query the widgets.

This is just about avoiding notify listeners for
change notification.
2020-10-12 15:10:40 -04:00
Matthias Clasen 578c8b5068 atspi: Be more careful about indexes
Don't return a number for IndexInParent when we
don't have one.
2020-10-12 15:10:40 -04:00
Matthias Clasen f9ee23825e atspi: Set some more atspi states
Pass on more of the states that are represented
as properties in aria: modal, multi-line, orientation.
2020-10-12 15:10:40 -04:00
Matthias Clasen 35f70d5a99 Pass orientation property to accessible
We should set the accessible properties we have,
where they make sense. So set orientation, if the
widget is orientable.
2020-10-12 15:10:40 -04:00
Matthias Clasen 54f1eb4c04 wip: Emit StateChanged signals
This is not fully baked, but it is enough to make accerciser
notice when a text entry goes from editable to not editable.
2020-10-12 15:10:40 -04:00
Matthias Clasen 66a81f1187 atspi: Derive readonly state from aria properties
We can use the read-only property, together with the
accessible role, to determine whether to set editable
and read-only states for at-spi. This lets us avoid
directly poking at the widgets.
2020-10-12 15:10:40 -04:00
Matthias Clasen 2a5af4e1d6 text: Set the readonly accessible property
This mirrors what we already do for GtkTextView.
2020-10-12 15:10:40 -04:00
Matthias Clasen d37b0357b3 atspi: Set editable state
ATs look at not just the implemented interfaces, but
also the states to decide what to do. It turns out that
the EditableText interface is only used by accerciser
if the editable state is set. So set it.
2020-10-12 15:10:40 -04:00
Matthias Clasen aea25cbbe5 atspi: Implement EditableText interface
Implement EditableText for GtkText and GtkTextView.
2020-10-12 15:10:40 -04:00
Matthias Clasen a72a7d4aeb atspi: Break out the Value implementation
This isn't necessarily very big, but it keeps
the widget checks out of gtkatspicontext.c, and
it is a nice pattern.
2020-10-12 15:10:40 -04:00
Matthias Clasen d38182bb5d atspi: Break out the Text implementations
Move the implementation of the Text interface
to its own source file, and split it up along
widget lines, to avoid it becoming too messy.
2020-10-12 15:10:40 -04:00
Matthias Clasen f22edccb2a scalebutton: Set accessible value properties
This is what we did in GTK 3.
2020-10-12 15:10:40 -04:00
Matthias Clasen dc9fee6185 paned: Set accessible value properties
This is what we did in GTK 3.
2020-10-12 15:10:40 -04:00
Matthias Clasen 776b4aee0c Simplify GetInterfaces handling
It is error prone to keep the same conditions in sync
in two places. Instead, just assemble the list of interfaces
as we register objects, and use when GetInterfaces is called.
2020-10-12 15:10:40 -04:00
Matthias Clasen d37782c533 atspi: Implement Value for more widgets
Apply the Value implementation to the widgets where
we had one in GTK 3: GtkLevelBar, GtkRange, GtkScaleButton,
GtkSpinButton, GtkPaned, GtkProgressBar. To make these
work, the widgets need to set the accessible value properties.
2020-10-12 15:10:40 -04:00
Matthias Clasen 8c3e5124c2 atspi: Implement Value interface for ranges 2020-10-12 15:10:40 -04:00
Matthias Clasen 190059dca1 atspi: Implement Text interface for text views
With this, all relevant widgets support the
Text interface.
2020-10-12 15:10:40 -04:00
Matthias Clasen 925ef1f90f atspi: Add textview utilities
These are very similar to the pango utilities,
and are copying code from the textview accessible
implementation in GTK 3.
2020-10-12 15:10:40 -04:00
Matthias Clasen ba63daa1d2 atspi: Export more pango utils
We are going to reuse some of the code that does
the pango -> atspi attribute conversion for text
tags.
2020-10-12 15:10:40 -04:00
Matthias Clasen 5b076fee12 atspi: Implement text for GtkText widgets too
There is some open question here whether the interface
should be implemented on the outer or the inner widget
of the entry-text pairs. For now, our hand is forced,
since only GtkText provides access to the layout that
we need for implementing many of the interface methods.
2020-10-12 15:10:40 -04:00
Matthias Clasen b80272a7e7 atspi: Implement Text interface for labels
This is a not-quite-complete implementation of the
Text interface for GtkLabel. The missing parts are
anything around extents and positions, as well as
the ScrollSubstring apis.
2020-10-12 15:10:40 -04:00
Matthias Clasen 7c8a16812e atspi: Add pango utilities
This code is more or less a direct copy of what
we had in gtkpango.c in 3.x.
2020-10-12 15:10:40 -04:00
Matthias Clasen ddb72accc0 atspicontext: Fix GetIndexInParent for toplevels
For toplevels, we need to return the index in the
list of toplevels, since that is what GtkAtspiRoot
is using.
2020-10-12 15:10:40 -04:00
Matthias Clasen 824ab7e4ed atcontext: labelled-by has a reference list
This is unclear - our docs state that all the
relations have value type reference, but in fact
they all have value type reference list.
2020-10-12 15:10:40 -04:00
Matthias Clasen 3a867e26d0 atspicontext: Implement GetRelationSet
This translates relations as far as the match.

I'm not sure yet what we can do about the fact that
atspi expects relations to be bidirectional (ie have
label-for *and* labelled-by) while aria has only one
direction.
2020-10-12 15:10:40 -04:00
Matthias Clasen e269cb7a81 atspiroot: Stub out GetRelationSet
This needs to be fully implemented, for now sending
an empty relation set back prevents accerciser from
getting hung up.
2020-10-12 15:10:40 -04:00
Matthias Clasen 0ae2ae7944 atspi: Add the AtspiRelationType enum
This is what we need to map the aria relation
types to.
2020-10-12 15:10:40 -04:00
Matthias Clasen 5db6c4b038 Move atspi enums to gtkatspiprivate.h 2020-10-12 15:10:40 -04:00
Matthias Clasen db6bd018ca Add a GetInterfaces method
It turns out that accerciser depends on this undocumented
method that is not in the xml at all, otherwise interface
sections in the accerciser ui never get enabled.
2020-10-12 15:10:40 -04:00
Matthias Clasen 9d43e5bd59 Don't pass NULL to g_variant_new_string
That does not work.
2020-10-12 15:10:40 -04:00
Matthias Clasen edfc55ae89 atspi utils: Fix an oversight
gtk_accessible_role_to_atspi_role must always return
an atspi role. The fallback was returning an aria
role.
2020-10-12 15:10:40 -04:00
Matthias Clasen d6b64b5e29 Fixup: Add a forgotten #pragma once 2020-10-12 15:10:40 -04:00
Emmanuele Bassi 9ce790032d a11y: Convenience API for referencing ATSPI root node
We turn the root node into a reference fairly often, so it's worth it to
have a utility function that does this for us.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 35163bd7cc a11y: Add utility function for null refs
ATSPI was written for CORBA, which allows passing around "nil"
as valid object references.
2020-10-12 16:19:32 +01:00
Matthias Clasen 9d0952bd7f atspicontext: Implement GetState
Translate the aria states to at-spi's interpretation
of atk states.
2020-10-12 16:19:32 +01:00
Matthias Clasen e189ccc8ed atspiroot: Fix GetState implementation
When the GetState signature says 'au', it actually
means a bitset that is sent as a pair of 32bit integers.
2020-10-12 16:19:32 +01:00
Matthias Clasen 762fbf34fc atspiroot: Implement GetIndexInParent
Just for good measure
2020-10-12 16:19:32 +01:00
Matthias Clasen 9f73638d43 atspicontext: Implement GetIndexInParent
This is needed for ATs to take our tree seriously.
2020-10-12 16:19:32 +01:00
Matthias Clasen 057b447137 atspicontext: Implement more accessible api
Implement GetChildAtIndex, GetChildren and ChildCount.
2020-10-12 16:19:32 +01:00
Matthias Clasen 78690845b1 atspiroot: Implement GetChildren
No surprises here.
2020-10-12 16:19:32 +01:00
Matthias Clasen 2ea338a8cf atspiroot: Don't leak references
The reffing getter trap, lurking behind g_list_model_get_item().
2020-10-12 16:19:32 +01:00
Matthias Clasen e2f3039663 atspiroot: Implement GetLocale 2020-10-12 16:19:32 +01:00
Matthias Clasen 8f20133769 atspicontext: Print out the a11y bus address
Make our debug spew useful: Having the bus address
makes it easy to jump on the a11y bus to look around
with dbus tools.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 55b1fbd0f3 a11y: Localise the role name of the root node 2020-10-12 16:19:32 +01:00
Emmanuele Bassi b57f1588df a11y: Register the Accessible interface on all AtSpiContext instances
This is not a complement implementation.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 60acdb9cad a11y: Implement more ATSPI methods on the root node 2020-10-12 16:19:32 +01:00
Emmanuele Bassi 07759b158a a11y: Add method to extract desktop data
We are going to need the desktop name and path to populate the parent
property of AtSpiContexts associated to top level widgets.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 9511c8273a a11y: Validate the DBus context path
UUIDs use dashes to separate the various blocks; unfortunately, this
results in an invalid DBus object path. Replace the dashes with an
underscore.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi b85b1f5b51 a11y: Turn accessible roles to string
Add a simple utility function to turn GtkAccessibleRole values into the
appropriate string, including localization.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 716024d882 a11y: Convert GTK roles to ATSPI ones
There's not a precise, 1:1 mapping between the newer ARIA roles and the
older ATSPI ones. We make do with what we have.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 21482e8264 a11y: Compute the label for a GtkATContext
The ARIA spec defines the mechanism for determining the name of an
accessible element—see §4.3 of the WAI-ARIA spec.

We follow the specification as much as it makes sense for GTK to do
so:

 1. if the element is hidden, return an empty string
 1. if the element has a labelled-by relation set, retrieve the
    label of the related element
 2. if the element has a label property set, use the value of
    the property
 3. if neither labelled-by nor label attributes are set, we use
    the role to compute the name:
   - for a `range` role, we return the contents of the value of
     the `value-text` or `value-now` properties
   - for any other role, we return a textual representation of
     the GtkAccessibleRole enumeration value
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 88113956a3 tests: Use the test ATContext for every test
Otherwise we're going to need a full desktop session in order to run the
test suite.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi e6c5d57ffe a11y: Return the ATSPI role for the root element 2020-10-12 16:19:32 +01:00
Emmanuele Bassi d7ebf18723 a11y: Add AT-SPI cache object
Right now, the cache is unused, and we still need to implement the
serialisation method and emit the signals.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 658d910967 a11y: Ignore widgets during destruction
There's no point in creating a GtkATContext when a widget is getting
destroyed.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi bd43e9cfc5 a11y: Register the accessible root object
When we create the first AT-SPI context we also need to register the
accessible root on the accessibility bus. The accessible root object is
the main entry point of an accessible application, and it holds the
global state to present to the ATs that connect to the bus.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 8c18480092 a11y: Add a display to GtkATContext
Since we need to check at run time what kind of AT context to use, we
need a hook into the whole GDK backend machinery. The display connection
seems to be the best choice, in this case, as it allows us to determine
whether we're running on an X11 or Wayland system, and thus whether we
should create a GtkAtSpiContext.

This requires some surgery to fix the GtkATContext creation function, in
order to include a GdkDisplay instance.
2020-10-12 16:19:32 +01:00
Emmanuele Bassi 8f19bb0832 a11y: Add dummy AT-SPI context
Does not do anything, at the moment, but it's going to get filled out
soon.

The backend is selected depending on the platform being compiled in;
since we're using AT-SPI on X11 and Wayland, and we don't have other
accessibility implementations, we currently don't care about run time
selection, but we're going to have to deal with that.
2020-10-12 16:19:31 +01:00
Emmanuele Bassi c50916d27b a11y: Add the AT-SPI DBus descriptions
And generate the code for the DBus interfaces.

We don't want the full object manager experience, here, because we're
going to have a single object responding to various interfaces and
remote method calls. For this reason, we're not using the gnome module
in Meson to call gdbus-codegen for us: we need to use the interface info
command line arguments, and those are not available from Meson.
2020-10-12 16:19:31 +01:00
Emmanuele Bassi 4b60e7470a Use test AT context with installed tests
Otherwise we're going to need an AT-SPI service on the session, and the
accessibility bus.
2020-10-12 16:19:31 +01:00
Matthias Clasen 77d4729483 Merge branch 'ebassi/for-master' into 'master'
Ebassi/for master

See merge request GNOME/gtk!2683
2020-10-12 14:39:39 +00:00
Emmanuele Bassi daac36ea4c Generate introspection for GdkWayland API
Like we do for GdkX11. We can't use all of the public C API, but we can
expose enough type information to allow non-C developers to actually
check if they are running the Wayland GDK backend or not—plus some
additional Wayland-specific API.
2020-10-12 14:07:26 +01:00
Emmanuele Bassi f83ee2ab6a Add type annotations for GdkWayland API
The GdkWayland API takes generic GDK types and performs a run time
check, which means we need to properly annotate the actual expected
type in order to have methods recognised as such.
2020-10-12 14:07:26 +01:00
Emmanuele Bassi 33e84edf0c Skip GdkWayland symbols that use wayland-client types
The wayland-client API does not have introspection annotations, so we
can't use these types anyway.
2020-10-12 14:07:26 +01:00
Aurimas Černius 08fb8c1c2a Updated Lithuanian translation 2020-10-11 17:25:45 +03:00
Matthias Clasen 035e303f83 Merge branch 'wip/chergert/gdk-macos-fixes' into 'master'
various build fixes for GDK/GTK on macos

See merge request GNOME/gtk!2680
2020-10-10 11:55:01 +00:00
Piotr Drąg 91ba0a31e7 Update Polish translation 2020-10-10 12:45:37 +02:00
Marek Černocký 72ea3a1655 Updated Czech translation 2020-10-10 12:17:27 +02:00
Christian Hergert 07bb07abbe macos: port gtk to GDK_WINDOWING_MACOS
For the various uses of GDK_WINDOWING_QUARTZ, we need to use
alternatives from GDK_WINDOWING_MACOS.

Some minor loss of functionality is here, such as icons sent with
application menus. That can certainly be added back at a future
point.
2020-10-09 20:08:23 -07:00
Christian Hergert 41101673c3 gtk: use GDK_WINDOWING_MACOS in gentypefuncs.py 2020-10-09 20:05:20 -07:00
Christian Hergert 97f03edae4 gdk: remove quartz subdirectory from backends 2020-10-09 20:04:27 -07:00
Christian Hergert d8ba916586 macos: add key equivalent helper
This is needed by quartz code in gtk/.
2020-10-09 20:03:52 -07:00
Christian Hergert 3f519e4d9b macos: remove workaround for scroll delta
This gets handled differently in gtk/ and so we shouldn't translate it here.
2020-10-09 20:02:38 -07:00
Christian Hergert 58f9413464 macos: track various changes in GDK 2020-10-09 20:02:18 -07:00
Christian Hergert 59cdd7ae69 macos: lookup NSEvent by translated GdkEvent
This will be needed by the quartz imcontext.
2020-10-09 19:59:21 -07:00
Christian Hergert a30adfe1e0 macos: move input method names to private header 2020-10-09 19:56:21 -07:00
Christian Hergert 6706623731 demo: fix out of bounds array index usage 2020-10-09 19:55:25 -07:00
Matthias Clasen 758675f44e Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #3242 and #3240

See merge request GNOME/gtk!2679
2020-10-09 13:35:57 +00:00
Matthias Clasen 8fcd4ac0f9 gtk-demo: Keep undisplayable resources out of view
No point in showing an apologetic tab for a blob of binary data.
gtk4-demo shows the resources under /DEMONAME/ for each demo,
so move the data to /DEMONAME_data/.
2020-10-09 07:52:29 -04:00
Matthias Clasen 4c3eb7c6f7 Merge branch 'ebassi/for-master' into 'master'
Tone down a user visible message

See merge request GNOME/gtk!2678
2020-10-09 11:47:38 +00:00
Matthias Clasen 115ed005e6 Send focus events to the root
We are not propagating focus change events, and that is the only
place where we are listening for focus change events. If GtkWindow
does not see focus-in events for its popovers, we end up with
inadvertendly inactive windows.

Fixes: #3240
2020-10-09 07:43:40 -04:00
Matthias Clasen 6a0704aeb4 window: Be more careful when looking for focus
When passing focus up to a parent, make sure the
newly chosen focus widget actually accepts the focus.
2020-10-09 07:43:25 -04:00
Matthias Clasen eb647299d4 build: Require sysprof 3.38.0
We use sysprof_collector_request_counters, which
was introduced in sysprof 3.38.0.
2020-10-09 07:43:25 -04:00
Matthias Clasen e7aa10342b gtk-demo: Ellipsize columns in the characters demo
some of the columns have uneven widths, causing them
to bounce around as you scroll. Ellipsize them and
give them a fixed with.
2020-10-09 07:43:25 -04:00
Matthias Clasen c835df5602 docs: Add more details to the migration guide
Add some details about GdkSurface and GtkWindow api changes.

Fixes: #3242
2020-10-09 07:43:25 -04:00
Emmanuele Bassi 43300b4047 Tone down a user visible message
Self-deprecating humour badly translates to a demo message.
2020-10-09 10:14:41 +01:00
Timm Bäder cdd2a2af1b Merge branch 'kjellahl/gdkseat' into 'master'
gdkseat: Make gdk_seat_get_tools() public

Closes #3241

See merge request GNOME/gtk!2677
2020-10-08 15:05:57 +00:00
Kjell Ahlstedt cb98a732e4 gdkseat: Make gdk_seat_get_tools() public
Fixes #3241
2020-10-08 16:22:05 +02:00
Timm Bäder 4450f64421 Merge branch 'fix.builder.msvc' into 'master'
testsuite/gtk/builder.c: Fix running on Visual Studio

See merge request GNOME/gtk!2676
2020-10-08 09:42:04 +00:00
Chun-wei Fan 1e4d3b6ca1 testsuite/gtk/builder.c: Fix running on Visual Studio
Explicitly say in the code that we are exporting the symbols so that when the
test program runs, it can find the required builder symbols.
2020-10-08 16:11:35 +08:00
Matthias Clasen 08ecf779f9 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

See merge request GNOME/gtk!2674
2020-10-08 02:19:42 +00:00
Matthias Clasen 5d7907caa5 gdk: Drop gdk_surface_new_temp
It is not used anymore.
2020-10-07 21:18:25 -04:00
Matthias Clasen 606ab611bd win32: Stop using gdk_surface_new_temp
No need to roundtrip through the frontend to create
one of our own surfaces.
2020-10-07 21:07:40 -04:00
Matthias Clasen 27ef9d9e5e broadway: Stop using gdk_surface_new_temp
No need to roundtrip through the frontend to create
one of our own surfaces.
2020-10-07 21:04:05 -04:00
Matthias Clasen 839baf2bef x11: Stop using gdk_surface_new_temp
No need to roundtrip through the frontend to create
one of our own surfaces.
2020-10-07 21:02:22 -04:00
Matthias Clasen e602d67e59 wayland: Stop using gdk_surface_new_temp
No need to roundtrip through the frontend to create
one of our own surfaces.
2020-10-07 21:02:22 -04:00
Matthias Clasen ba108f261f gdk: Drop some unused private api
No users of gdk_display_peek_event, gdk_display_has_pending
_gdk_display_event_data_copy or _gdk_display_event_data_free,
so drop all of these, and related vfuncs.
2020-10-07 21:02:22 -04:00
Matthias Clasen 668868fb1f Merge branch 'master' into 'master'
Allow LPR backend to print PDF and PS file formats

See merge request GNOME/gtk!418
2020-10-07 20:51:40 +00:00
Benjamin Otte bc5723a846 Merge branch 'wip/otte/for-master' into 'master'
textbuffer: Don't serialize the \0 byte

See merge request GNOME/gtk!2672
2020-10-07 20:33:25 +00:00
Matthias Clasen 98c7de4aa3 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #3237

See merge request GNOME/gtk!2673
2020-10-07 20:30:52 +00:00
Benjamin Otte 0fdb33e82a textbuffer: Don't serialize the \0 byte
... when converting to text/plain.
2020-10-07 22:14:18 +02:00
Matthias Clasen cfb316799a colorchooser: Bring color names back
These are useful for accessibility.

Fixes: #3237
2020-10-07 15:56:11 -04:00
Jan Alexander Steffens (heftig) fb0c062506 gtkplacessidebar: Disconnect and unref cloud_manager in dispose
The manager's providers-changed signal can fire after the sidebar has
been freed. Make sure we disconnect the sidebar from the manager.

https://bugs.archlinux.org/task/57984
https://bugs.archlinux.org/task/68123
2020-10-07 15:16:31 -04:00
Matthias Clasen 3d9eb61bba gtk-demo: Fix an off-by-one error
This was found by the asan build in our ci.
2020-10-07 15:16:31 -04:00
Timm Bäder 4993cde0cb Merge branch 'migration-guide-fix' into 'master'
migration guide: Remove stray html tags

See merge request GNOME/gtk!2670
2020-10-07 08:00:43 +00:00
Nicola Fontana 35b0796a1f migration guide: Remove stray html tags 2020-10-07 08:38:26 +02:00
Matthias Clasen d839c1beab Merge branch 'svg-demo' into 'master'
Svg demo

See merge request GNOME/gtk!2668
2020-10-06 20:55:28 +00:00
Matthias Clasen 5a9547da41 gtk-demo: Add an svg paintable demo
It is a little annoying that this demo will not show up
if we don't find librsvg, but I think showing how easy
this paintable is outweights the annoyance.
2020-10-06 15:12:09 -04:00
Matthias Clasen 25cbc1a15a gtk-demo: Recognize .svg as images
We can't guarantee that we can load it, but worst
case you'll get a missing image.
2020-10-06 15:11:08 -04:00
Matthias Clasen 043207133d Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #3235

See merge request GNOME/gtk!2667
2020-10-06 18:25:48 +00:00
Matthias Clasen 490163efcd Merge branch 'aboutwindow' into 'master'
gtkaboutdialog: Directly specialize GtkWindow

See merge request GNOME/gtk!2666
2020-10-06 18:25:27 +00:00
Matthias Clasen 44fd0c18c8 aboutdialog: Fix updating license tab
We need to update the license button visibility
whenever the license type changes.
2020-10-06 12:53:46 -04:00
Adrien Plazas a17f33b1fe gtkaboutdialog: Directly specialize GtkWindow
As it doesn't act as a dialog, there is no point specializing GtkDialog,
so his makes it specialize GtkWindow directly.
2020-10-06 18:46:48 +02:00
Matthias Clasen 22eac2f407 window: Fix setting min size
We were inadvertedly setting the windows min size
to the default size, making it so that you can never
shrink a window below its default size.

Fixes: #3235
2020-10-06 11:06:36 -04:00
Matthias Clasen bdbfaef4d8 gdk: Tweak our GL debug message callback
Go back to installing our debug message callback
unconditionally if G_ENABLE_CONSISTENCY_CHECKS is
defined, and allow opting into it using GDK_DEBUG=gl-debug
otherwise.
2020-10-06 10:34:30 -04:00
Matthias Clasen 214c35ffc7 gdk: Docs tweaks
We don't have library initialization api anymore,
update the section title to reflect that.
2020-10-06 07:58:01 -04:00
Matthias Clasen 7698b4dd63 treelistrowsorter: Add a bandaid
The GtkTreeListRowSortKeys implementation doesn't
know how it wants to cache its keys, and just crashes.

Since that is not cool, add a bandaid fix that forces
it to recreate its keys instead. Extra work, but hey,
no crash.

Related: #3228
2020-10-06 07:58:01 -04:00
Emmanuele Bassi e532f2322b Merge branch 'FixWin32PopupFocus' into 'master'
Gtk4/Win32: Fix popup focus stealing when CSD is disabled

See merge request GNOME/gtk!2665
2020-10-06 10:30:07 +00:00
firox263 f0a8c6311e Fix Win32 popup focus when using SSD
Prevents GDK Popups from stealing focus from the parent window when
using Server Side Decorations on win32.

It uses `ShowWindow` and the `SW_SHOWNOACTIVATE` flag.
2020-10-06 22:37:35 +13:00
Matthias Clasen b6d4067717 Merge branch 'wip/carlosg/for-master' into 'master'
gtkpopover: Revert focus to parent on hide()

Closes #3214

See merge request GNOME/gtk!2653
2020-10-06 02:14:54 +00:00
Matthias Clasen ac164d240b Cosmetic
Don't call gtk_root_get_focus when we already have
the GtkWindowPrivate struct at hand. And use
gtk_window_set_focus to update the focus, like the
old code did.
2020-10-05 21:53:05 -04:00
Carlos Garnacho 38547120b2 gtkwindow: Ensure to revert focus to a parent on hide()
When a widget is hidden, check harder for the keyboard focus being
contained in that widget, in order to reset it. Portions of the
focus child hierarchy may be outdated at the time, so it is more
reliable to check GtkRoot::focus (i.e. the property we intend to
update here).

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3214
2020-10-06 03:29:13 +02:00
Matthias Clasen 7f5deed2eb Merge branch 'simple-resizing-fixes' into 'master'
Simple resizing fixes

Closes #3076

See merge request GNOME/gtk!2661
2020-10-06 01:25:25 +00:00
Matthias Clasen ccdc10d9df Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #3196

See merge request GNOME/gtk!2662
2020-10-06 00:57:30 +00:00
Timm Bäder 982ebf1b69 gradient shaders: Reduce out values as well
We only do 6 color stops here now. Also works around a driver bug.

Fixes #3196
2020-10-05 20:35:34 -04:00
Matthias Clasen 20fb7812df window: Fix window size snapping back
We were not updating the remembered size at all when
the window is interactively resized, causing it to
snap back to its default size the next time we call
gdk_toplevel_present().

This is a bandaid fix to prevent very broken resizing
behavior, until we have properly redone toplevel sizing.

Fixes: #3076
2020-10-05 20:24:19 -04:00
Matthias Clasen 082edd957e wayland: Don't forget to reapply margins
When using the saved size because the compositor
told us to, we were forgetting to readd the margins.

The visible symptom of this was the window getting
smaller every time we went to tiled state and back.
2020-10-05 20:17:50 -04:00
Matthias Clasen e5cd2568c8 wayland: Don't save size when tiled
Don't remember the surface size when we are in tiled
state either. This matches the 'fixed_size' condition
in gdk_wayland_surface_configure_toplevel.

This change fixes an issue where moving a window first
to tiled, then to maximized state and back would lead
to the unmaximized window having the tiled dimensions.
2020-10-05 20:15:33 -04:00
Matthias Clasen d51608a2c9 wayland: Don't emit premature configure events
We should not emit configure events before we are realized - size
changes at this point are not relevant.

This gets rid of a mysterious emission of GdkSurface::size-changed
with a size of 52x52, that is happening when GtkWindow sets the
shadow_width before the window is mapped.
2020-10-05 17:18:14 -04:00
Matthias Clasen 67c6f0a08a gtk-demo: Mention dataset size for Characters 2020-10-05 14:43:38 -04:00
Matthias Clasen 7311464c67 gl: Install the debug message callback for gl-debug
Always install the debug message callback when we can
and GDK_DEBUG=gl-debug is specified. Previously, we
were only installing the callback when the build was
a non-optimized debug build.
2020-10-05 14:43:31 -04:00
Matthias Clasen aaab461c27 Merge branch 'fix-texture-cache' into 'master'
gl renderer: Fix up texture cache key

See merge request GNOME/gtk!2659
2020-10-05 14:58:20 +00:00
Matthias Clasen 6b0c65cc38 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

See merge request GNOME/gtk!2660
2020-10-05 14:23:08 +00:00
Matthias Clasen 74d99766e4 gtk-demo: Fix up the Characters demo
Move the Unicode names to a separate source file,
and only build the demo if we have harfbuzz (since
we use script names, and those are only available
with harfbuzz).

Also, fix a forgotten type name.
2020-10-05 09:56:04 -04:00
Alexander Larsson 24a27ba44f gl renderer: Fix up texture cache key
The commit e14d2be1 forgot to actually set the parent_rect in the texture
key in the case it is necessary.
2020-10-05 15:43:04 +02:00
Matthias Clasen 6156c3583d NEWS: Updates
Trying a new scheme - when updating NEWS outside of doing
a release, keep the version out, to make the it clear that
this is just about the tip of the branch, not a complete
release.
2020-10-05 08:18:56 -04:00
Matthias Clasen 2b03674464 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

See merge request GNOME/gtk!2658
2020-10-05 11:29:10 +00:00
Matthias Clasen 5d26d11868 gtk-demo: Add a column view demo
Make a column view that is showing some Unicode data.
2020-10-04 22:53:45 -04:00
Matthias Clasen 34f33b36f8 Prevent a crash with script names
We can't pass NULL to gettext().
2020-10-04 21:20:48 -04:00
Matthias Clasen bea3bc5d27 Update the copy in gtk-demo too 2020-10-04 19:48:46 -04:00
Matthias Clasen 5d5625dec8 Update script names to Unicode 13
It would be better if this was provided elsewhere...
2020-10-04 16:15:09 -04:00
Matthias Clasen cb833d52fb Merge branch 'emoji-data-cldr' into 'master'
Update Emoji data

Closes #1511 and #950

See merge request GNOME/gtk!2656
2020-10-04 13:56:40 +00:00
Matthias Clasen 9007d153c8 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

See merge request GNOME/gtk!2657
2020-10-04 13:56:30 +00:00
Matthias Clasen 8ca612c966 scale: Make draw-value default to FALSE
This is rarely what you want, so lets turn it off
by default.

Update the one place in our demos where we want to
draw a value, add support for this to gtk-builder-tool,
add a test and mention this change in the migration
guide.
2020-10-04 08:26:44 -04:00
Matthias Clasen 452c909b64 Redo the handling of Emoji data
Use the data files from https://github.com/milesj/emojibase.git
as source for our Emoji data. Slightly change our data format by
adding a group to each item, in both the Emoji data and in the
setting for recent-emoji.

Install translated versions of the data as separate resource
bundles in $prefix/gtk-4.0/emoji, and load them when appropriate.

Currently, we have data for de, en, es, fr, zh, with data taken
from Unicode 13 and CLDR 13.

Fixes: #950 #1511
2020-10-04 01:14:42 -04:00
Matthias Clasen 7ef5921022 Emoji: Drop the shortname field from emoji.data
Match the name for Emoji completion, and display
it too. 'man worker' looks a lot more natural in
the UI than ':man_worker:'.
2020-10-03 20:06:31 -04:00
Matthias Clasen 1d9d5fcf39 Do case-folding and tokenization when creating emoji.data
We can avoid doing the extra work of case-folding and
tokenization whenever we filter in the Emoji chooser.
2020-10-03 19:46:46 -04:00
Matthias Clasen ed724ebc35 emoji: Add keywords to the data
And use them for matching in the Emoji chooser.
2020-10-03 19:46:46 -04:00
Matthias Clasen 44448016e8 emoji: Some work on the conversion tool
Document the variant format, and write out json
format if asked to.
2020-10-03 19:46:46 -04:00
Matthias Clasen a4284569c0 Fix Emoji completion
This is some late fallout from the container removal.
2020-10-03 19:42:19 -04:00
Matthias Clasen 9a2faf2197 widget-factory: Enable emoji completion somewhere
Without a quick way to test this, it is bound to
fall apart. As it has.
2020-10-03 19:41:26 -04:00
Matthias Clasen 6e594da5f2 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #506

See merge request GNOME/gtk!2655
2020-10-03 19:27:15 +00:00
Matthias Clasen ac79c0e799 textbuffer: Improve some get_iter apis
Make these functions return FALSE if they did not
return the exact position that was requested.

Adapt tests.

Based on a patch by Sebastien Wilmet

Fixes: #506
2020-10-03 14:29:07 -04:00
Matthias Clasen d0b7a4a4ec testsuite: Add a test that checks for property accessors
Make sure that every object property in GTK has accessors for getting
its value (if the property is readable) or setting it (if it is
writable).

Since we are still missing accessors, the test is allowed to
fail for now. Sadly, mesons xfail support is busted, so we just
disable the test entirely :(

Based on initial work by Benjamin Otte.

Related: #2440
2020-10-03 14:28:37 -04:00
Matthias Clasen 60b1b4669e spinbutton: Add some missing accessors
Add a setter and getter for the climb-rate property.
2020-10-03 13:11:20 -04:00
Matthias Clasen 9d0d4cef03 Cosmetics 2020-10-03 13:11:20 -04:00
Matthias Clasen 1b1bf6c90a text: Add some missing setters and getters
Add getters and setters for the enable-emoji-completion,
propagate-text-width and truncate-multiline properties.
2020-10-03 13:11:20 -04:00
Matthias Clasen 38bd4439e8 directorylist: Drop the item-type property
No need for this to be a property.
This showed up in a test for missing accessors.
2020-10-03 13:11:20 -04:00
Matthias Clasen 9fdb71cbd2 icontheme: Add a missing getter
We want to have a get_display() method on every object
that is tied to the display, so add one here.
2020-10-03 13:11:20 -04:00
Matthias Clasen ff7bcf738c colorbutton: Properly override interface properties
This showed up in a test for missing property accessors.
2020-10-03 13:11:20 -04:00
Matthias Clasen 5640208f31 node-editor: Don't insert hyphens
This can be a bit confusing in multi-line strings.
2020-10-03 13:11:20 -04:00
Matthias Clasen cef1cd19ff gsk: Avoid long lines in serialized nodes
When encoding big blobs of data in base64, insert newlines.
Base64 allows it, CSS allows it, so not need to make GtkTextView
struggle with multi-megabyte lines.

Update nodeparser tests to reflect this change.
2020-10-03 13:10:55 -04:00
Matthias Clasen 279d3c08a9 gtk-demo: Rename the transition shader files
Easier to find them when their name matches the title
that we show in the UI.
2020-10-03 00:01:25 -04:00
Matthias Clasen 949f22b8b2 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #2261 and #1002

See merge request GNOME/gtk!2654
2020-10-03 03:55:32 +00:00
Matthias Clasen 19d760f9dd gtk-demo: Fix a typo 2020-10-02 23:54:15 -04:00
Matthias Clasen a9809b0f67 Allow inserting newlines in css strings
Rename _gtk_css_print_string to strip the _ and add
an insert_newlines argument to it. Update all callers,
and make the render node serializer insert newlines.
2020-10-02 23:40:16 -04:00
Matthias Clasen 9033336a23 css: Move _gtk_css_print_string around
Move this to a separate header, since it is not
parser functionality, and kill the duplicate
gtkcssparserprivate.h header.
2020-10-02 23:40:16 -04:00
Jakub Steiner 68ae8506d5 Merge branch 'stackswitcher-button-styling' into 'master'
Adwaita: Simplify stackswitcher button styling

See merge request GNOME/gtk!2498
2020-10-02 15:09:07 +00:00
Matthias Clasen da8ee53e2d emojichooser: Allow inserting multiple Emoji
Don't close the Emoji chooser when the Control
key is held while clicking. So you can insert
multiple Emoji without having to reopen the
chooser every time.

Fixes: #1002
2020-10-01 23:45:05 -04:00
Matthias Clasen f6bd2f4d3f Add a test for gsk_gl_shader_compile
This is not super useful, but at least we can
test that we get an error message including the
shader text.
2020-10-01 23:45:05 -04:00
Matthias Clasen c9f3034e82 gdk: Remove an unused variable 2020-10-01 19:33:43 -04:00
Matthias Clasen 3cf8904d0b Add GTK_INPUT_HINT_PRIVATE
Add a flag that requests that input methods should not
update personalized data (such as typing history).

Fixes: #2261
2020-10-01 17:14:58 -04:00
Matthias Clasen c43d535aab docs: Fix a copy-paste error 2020-10-01 17:07:53 -04:00
Matthias Clasen f4bfa16136 Update the release script
If things go according to plan, we don't need to include
gtk-doc as a subproject in the next snapshot.
2020-10-01 15:14:33 -04:00
Matthias Clasen 4d90259b9b Use gtk-doc from master
I've merged the relevant parts from the gtk-doc-for-gtk4
branch.
2020-10-01 15:11:37 -04:00
Matthias Clasen ffb51b6888 Require gtk-doc 1.33
We'll hopefully get a gtk-doc release out with that
version number soon.
2020-10-01 15:09:26 -04:00
Matthias Clasen dc3b140fd7 Cosmetics 2020-10-01 13:48:24 -04:00
Matthias Clasen ce29545470 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #3220

See merge request GNOME/gtk!2652
2020-10-01 14:21:34 +00:00
Matthias Clasen cbe3de9ce7 Merge branch 'master' into 'matthiasc/for-master'
# Conflicts:
#   .gitlab-ci/test-msys2.sh
2020-10-01 13:56:37 +00:00
Matthias Clasen 6de7022458 Merge branch 'ci-win32-introspection-enabled' into 'master'
CI: Enable introspection again for the Windows build

See merge request GNOME/gtk!2651
2020-10-01 13:50:02 +00:00
Christoph Reiter 9601863569 CI: Enable introspection again for the Windows build
The underlying bug was fixed in glib and backported in MSYS2:
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1665
2020-10-01 15:16:18 +02:00
Matthias Clasen c278261be0 Merge branch 'wip/jimmac/infosearch-close' into 'master'
Adwaita: close button for infobar, searchbar

Closes #3215

See merge request GNOME/gtk!2650
2020-10-01 12:01:23 +00:00
Matthias Clasen 028cd1e23a Revert "Fix the build with cups < 2.3"
This reverts commit d761e3cf2c.

I am seeing PPD_CUSTOM_UNKNOWN in the cups headers in our
ci images, and that is cups 2.2.12. So this commit was
mistaken.
2020-10-01 07:59:30 -04:00
Matthias Clasen 6e7c0ce06b ci: Give up on sysprof for now
Using sysprof and glib as subprojects of the same
project sadly does not work. Subprojects are not
as robust as they should be.
2020-10-01 07:37:44 -04:00
Jakub Steiner 81cfcba5ad Adwaita: close button for infobar, searchbar
fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3215
2020-10-01 13:14:25 +02:00
Matthias Clasen 9bac129707 ci: Try to get everything building again
It turns out that the sysprof meson setup does not
work with meson 0.54 :( So version 25 of our ci images
bumps the meson version to 0.55.3.
2020-09-30 23:43:03 -04:00
Matthias Clasen 91c8f6b7df build: Try to fix docs+subprojects
Apparently, subprojects don't have pkgconfig variables :(
2020-09-30 16:21:39 -04:00
Matthias Clasen 103080c384 build: Remove an unneeded version check
We are requiring a newer meson than we were checking
for here.
2020-09-30 16:09:56 -04:00
Matthias Clasen b936419125 ci: Remove --fatal-meson-warnings
meson adds features that then trigger warnings when we run
a newer meson over some of our subprojects. This is all too
fragile.
2020-09-30 15:53:15 -04:00
Matthias Clasen 72eb89eda7 gtk-demo: Add the shader paintable sources
This is currently not public GTK api, just part of
the demo. So we should show it here.
2020-09-30 15:41:05 -04:00
Matthias Clasen b0da095944 gsk: Fix compiler warnings
We forgot to teach the broadway renderer about new enum
values, and our ci didn't catch it because werror didn't
actually work there until now.
2020-09-30 15:39:30 -04:00
Matthias Clasen 21c8bc2b47 build: Require meson 0.54 2020-09-30 15:26:20 -04:00
Matthias Clasen 7780b89e8a ci: Really enable werror
We wanted to enable werror for gtk without enabling it
for all our subprojects. Sadly, we failed. Try again
2020-09-30 15:26:20 -04:00
Matthias Clasen 517a8406b0 ci: Use the v24 images
These images have meson 0.54.
2020-09-30 15:26:20 -04:00
Matthias Clasen dfd16e3982 ci: Use a newer meson in images
We need meson 0.54.
2020-09-30 15:26:20 -04:00
Xavier Claessens fd1e8afe9d meson: Change introspection option to yielding feature
Yielding option means that if pango is built as a subproject, it will
take the value of that option from the parent project (e.g. gst-build).
For that to work it must be of the same type, which is "feature" instead
of "boolean" in all GStreamer modules.
2020-09-30 15:11:27 -04:00
Benjamin Otte 5829bc7c91 Use correct child widget when measuring
Fixes a copy/paste error.

Fixed #3220
2020-09-30 15:11:27 -04:00
Matthias Clasen 5a3aed8ade Merge branch 'introspection' into 'master'
meson: Change introspection option to yielding feature

See merge request GNOME/gtk!2648
2020-09-30 17:50:21 +00:00
Benjamin Otte 5b89253fd9 Use correct child widget when measuring
Fixes a copy/paste error.

Fixed #3220
2020-09-30 17:48:24 +00:00
Matthias Clasen fd631937f3 transition demo: Make buttons symbolic
It looks better.
2020-09-30 13:43:36 -04:00
Matthias Clasen 77ec961126 Merge branch 'ebassi/for-master' into 'master'
demo: Replace g_print with g_debug

See merge request GNOME/gtk!2645
2020-09-30 15:22:57 +00:00
Matthias Clasen 924e510512 gtk-demo: Update text for the transitions demo
The fire is gone, but we have wobbly widgets!
2020-09-30 11:19:12 -04:00
Matthias Clasen 97ffd94d20 Merge branch 'snazzy-demo' into 'master'
gtk-demo: Make gltransitions demo a bit snazzier

See merge request GNOME/gtk!2644
2020-09-30 15:00:58 +00:00
Alexander Larsson d6648871b1 gtk-demo/gltransition: Replace fire background with more mellow blobs 2020-09-30 16:38:50 +02:00
Alexander Larsson 5d4a6940fa gtk-demo: Use duck in transitions to get some alpha example 2020-09-30 16:25:30 +02:00
Xavier Claessens 0e5dac8c25 meson: Change introspection option to yielding feature
Yielding option means that if pango is built as a subproject, it will
take the value of that option from the parent project (e.g. gst-build).
For that to work it must be of the same type, which is "feature" instead
of "boolean" in all GStreamer modules.
2020-09-30 09:50:24 -04:00
Matthias Clasen 2dcf750198 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

See merge request GNOME/gtk!2647
2020-09-30 13:42:55 +00:00
Matthias Clasen 5fa765b284 Mention icon theme in the migration guide
This was requested in #3216.
2020-09-30 08:55:39 -04:00
Matthias Clasen 9d701129cc icontheme: Clarify the docs
Mention that icons directly in /$app_id/icons/ are treated
as unthemed icons.

See #3216
2020-09-30 08:55:39 -04:00
Alexander Larsson e14d2be1e8 gl renderer: Fix render node texture cache
We're caching two things, either a node itself being rendered, or a
parent storing a cached version of a child as rendered to an offscreen
the size and location of the parent.

If both the parent and child uses the cache this will cause a conflict in
the cache as it is currently use keying of a node pointer which will have
the same value for the node-as-itself and the child-node-of-the-parent.

We fix this by adding another part to the key "pointer_is_child" which means
we can have the same node pointer twice in the cache.

Additionally, in the child-is-rendered-offscreen case the offscreen
result actually depends on the position and size of the parent viewport,
so we need to store the parent bounds in that case.
2020-09-30 14:53:13 +02:00
Emmanuele Bassi b0a0f07bd7 demo: Replace g_print with g_debug
The GtkGears widget is a bit too chatty, especially when used inside
demos like the fishbowl. Let's use g_debug() instead of g_print() for
the GL debugging message.
2020-09-30 12:35:31 +01:00
Matthias Clasen 7defc3b759 Fix the release script some more
Still trying to master the tar commandline.
2020-09-30 06:51:46 -04:00
Alexander Larsson e9885f9cde gtk-demo: Make gltransitions demo a bit snazzier
This adds a bunch of snazz to the gltransitions demo. It is perhaps
a bit overloaded now, but it demos everything that we can do.

Changes:
 * The fire shader is now not a bin, it just renders an animating
   background with no textures involved.
 * The stacks don't all start on the same page.
 * The shaderbin passes the mouse coordinate to the shader.
 * The shaderbin allows specifying a "border" so that you can
   cause effects outside the bin child (something that is new to gtk4).
 * All the buttons and the stacks are now in shader-bins that runs
   a wobbly-widget effect based on the mouse position that
   wobbles outside the child allocation.
2020-09-30 11:40:37 +02:00
Matthias Clasen 87393c7fb6 Merge branch 'small-cleanup' into 'master'
menubutton: Remove obsolete private method

See merge request GNOME/gtk!2643
2020-09-29 21:52:37 +00:00
Matthias Clasen 76d616909f Merge branch 'ebassi/for-master' into 'master'
Ebassi/for master

See merge request GNOME/gtk!2642
2020-09-29 20:45:00 +00:00
Matthias Clasen 31069d5e96 release script: Fix doc tarball generation
Strip one level from the directories.
2020-09-29 15:07:13 -04:00
Florian Müllner 7ad42df727 menubutton: Remove obsolete private method
It was only added for the fallback app menu in headerbars, which
has been removed in the meantime.
2020-09-29 20:58:25 +02:00
Emmanuele Bassi c6cedf608a Add annotations for GtkBuildable virtual functions
Now that the functions that wrap them have gone away from the public
API, we need proper annotations for the virtual functions, otherwise
languages will not have enough information on nullable arguments and
ownership transfer.
2020-09-29 19:48:55 +01:00
Matthias Clasen 218b905a88 3.99.2 2020-09-29 14:44:31 -04:00
Matthias Clasen 00c6340777 gsk: Add some more shader docs
Do a pass over the docs and address minor inconsistencies,
cosmetics and formatting differences.

Mention GSK_DEBUG=shaders.
2020-09-29 14:44:31 -04:00
Matthias Clasen 687ed74d46 Merge branch 'snapshot-stack-optimize' into 'master'
Minor optimizations to GtkSnapshot state stack

See merge request GNOME/gtk!2641
2020-09-29 18:44:07 +00:00
Emmanuele Bassi 97276a5cd4 Remove gtk-doc stanzas from private GtkBuildable API
Various functions were moved to the private GtkBuildable header by
commit 2715b3ec31, but the functions still
have gtk-doc stanzas.
2020-09-29 19:39:34 +01:00
Alexander Larsson 796e6ee306 snapshot: Preallocate and don't memset the state stack
Most of the time the snapshot is less than 16 levels deep (did some testing
in gtk-demo), so lets pre-allocate 16 levels of state stack to avoid the
extra allocation most of the time.
2020-09-29 16:03:06 +02:00
Alexander Larsson 18b8b499de gdkarray: Add support for GDK_ARRAY_NO_MEMSET
If all your callers already initialize the array element as needed,
then we don't need to memset it to zero first.

This is pretty useful for the snapshot state stack, because due
to the per-node-type data area the elements on the stack are
quite large, but often a lot of it is not used.
2020-09-29 16:02:59 +02:00
Alexander Larsson 8a0dd452d2 gdkarray: Inline splice and reserve
This inlines the splice and reserver GdkArray calls. These are
typically only called from the gdk_array_(append/set_size) functions
anyway, and inlining the caller means we can constant propagate the
constant arguments in those calls. Its hard to get exact numbers, but
in fishbowl i noticed a significant decrease in the time spent in
the array code when pushing and poping states.
2020-09-29 15:57:33 +02:00
Matthias Clasen 4cfa9ee19f Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

See merge request GNOME/gtk!2639
2020-09-29 12:57:36 +00:00
Matthias Clasen 719c44a610 Merge branch 'glshader-track-uniform-state' into 'master'
gl: Track the current uniform state for custom programs

See merge request GNOME/gtk!2638
2020-09-29 12:49:22 +00:00
Matthias Clasen 4a2c817690 docs: Document various entry ::activate signals 2020-09-29 07:04:07 -04:00
Matthias Clasen aac9414117 statusbar: Remove a misleading doc comment 2020-09-29 07:04:07 -04:00
Matthias Clasen c897daf797 snapshot: Document radial gradient apis 2020-09-29 07:04:07 -04:00
Matthias Clasen f1299410bf docs: Fix a typo 2020-09-29 07:04:07 -04:00
Matthias Clasen 165768b6ad wayland: Match header and doc arguments
gtk-doc doesn't take this lightly.
2020-09-29 07:04:07 -04:00
Matthias Clasen 07c338b487 gsk: Document radial gradient api 2020-09-29 07:04:07 -04:00
Matthias Clasen 3af249c046 Silence a compiler warning
These variables are not used anymore since
commit 11e4a46967.
2020-09-29 07:04:07 -04:00
Matthias Clasen 91c3edba35 NEWS: Updates 2020-09-29 07:04:07 -04:00
Alexander Larsson 51ab56d33a gl: Track the current uniform state for custom programs
This allows us to avoid updating uniforms if that is not necessary. This
in turn allows us to sometimes reuse the same draw op by just extending the
vertex array size we draw rather than doing a separate glDraw call.

For example, in the fishbowl demo, all the icons added at the same
time will have the same time and size, so we emit single draw calls
with 100s of triangles instead of 100s of draw calls with 2 triangles.
2020-09-29 11:52:39 +02:00
Alexander Larsson 2e5caa68bc Merge branch 'glshader-node' into 'master'
Add support for GLShader nodes

See merge request GNOME/gtk!2594
2020-09-29 08:30:48 +00:00
Matthias Clasen 4e55220d76 Add some shader tests
These are just basic api usage tests, no rendering.
They found the issues fixed in the preceding commits.
2020-09-29 09:51:16 +02:00
Alexander Larsson e76cb3e1e4 gtk-demo: Add a shader paintable to the fishbowl
This gets around 500 instances at 60fps on my system.
2020-09-29 09:51:16 +02:00
Alexander Larsson 8bcb031418 gtk-demo: Add GskGLShaderNode demo
Add adds a demo showing off GskGLShaderNode in various ways.

It has a transistion widget, using some examples from
gl-transitions.com, with child widgets being both images, a GL area
and real widgets (that let you edit the transition shaders
themselves.

It also has a fancy fire effect on hove on the buttons.
2020-09-29 09:51:16 +02:00
Alexander Larsson 4d697283ae Support GLShaderNode in backends
For vulkan/broadway this just means to ignore it, but for the gl
backend we support (with up to 4 texture inputs, which is similar to
what shadertoy does, so should be widely supported).
2020-09-29 09:51:16 +02:00
Alexander Larsson 950cc41e15 GtkSnapshot: Add gtk_snapshot_push_glshader() 2020-09-29 09:51:16 +02:00
Alexander Larsson 7ea755e206 Add GskGLShaderNode and GskGLShader
A GskGLShader is an abstraction of a GLSL fragment shader that
can produce pixel values given inputs:
 * N (currently max 4) textures
 * Current arguments for the shader uniform
Uniform types are: float,(u)int,bool,vec234)
There is also a builder for the uniform arguments which are
passed around as immutable GBytes in the built form.

A GskGLShaderNode is a render node that renders a GskGLShader inside a
specified rectangular bounds. It renders its child nodes as textures
and passes those as texture arguments to the shader. You also pass it
a uniform arguments object.
2020-09-29 09:51:16 +02:00
Matthias Clasen 6e9b58b6f0 gsk: Add more shader debug spew
Print out the full assembled shader sources when
GSK_DEBUG=shaders is given. This is very verbose,
but may be useful to see what we actually pass
to the compiler.
2020-09-29 09:51:16 +02:00
Alexander Larsson 645fc6a9a5 GtkWindow: Create renderer before realizing child widgets
This way the child widgets can rely on the renderer (for example what
type it is) to decide details about how they render (such as if they
should use OpenGL shaders).
2020-09-29 09:51:16 +02:00
Matthias Clasen a91b6b4786 css: Move the last parser api to the new header
This lets us use it from the render node parser
in gsk.
2020-09-29 09:51:16 +02:00
Alexander Larsson 16cdb33c6c shadertoy demo: Fix GLSL on GLES
I was getting "assignment to varying fragColor" errors
2020-09-29 09:51:16 +02:00
Alexander Larsson bacb3affb3 gl: Add some namespacing to the preamble symbols
This adds a gsk prefix to the stuff in the preamble, as we want to
avoid it conflicting with things in the main shader. Especially once
we start allow some customization of shaders.
2020-09-29 09:51:16 +02:00
Alexander Larsson 9460d0131f gl backend: Add line numbers to source in glsl compilation errors
Almost always the source is created by combining various sources, which
means the line numbers in the error messages are hard to use. Adding
the line numbers to the source in the error message helps with this.
2020-09-29 09:51:16 +02:00
Alexander Larsson 7edcd1748c gl: Properly report error if shader linking fails
In gsk_gl_shader_builder_create_program(), if linking fails we
need to return -1 to indicate error, rather than the old deleted
program id.
2020-09-29 09:51:16 +02:00
Alexander Larsson 6887d0ce24 glrenderer: Move ProgramState into Program
There is no real reason to have this on the side indexed via the
index, as it is stored next to each other anyway. Plus, storing them
together lets use use `Program` structures not in the array.
2020-09-29 09:51:10 +02:00
Matthias Clasen e29c586b7c Merge branch 'arnaudb/menubutton-direction' into 'master'
Make GtkMenuButton::direction more useful.

Closes #2811

See merge request GNOME/gtk!2636
2020-09-29 01:55:24 +00:00
Matthias Clasen 4f8a211c51 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #3202

See merge request GNOME/gtk!2637
2020-09-29 01:53:02 +00:00
Matthias Clasen 30b7545fb5 Add a reftest for flipping transforms
Verify that a scale of -1 does in fact cause a
gradient to go the other direction.
2020-09-28 21:07:51 -04:00
Matthias Clasen a799c86edb textbuffer: Elaborate docs
Explain a bit more what gtk_text_buffer_get_content_provider()
is for.

Fixes: #3202
2020-09-28 20:51:13 -04:00
Matthias Clasen 68bb532290 window: Don't get surfaces needlessly
There is a 1-1 correspondence between natives and
surfaces, so we can just compare the natives, no
need to get the surface for every single one.
2020-09-28 20:51:13 -04:00
Matthias Clasen d2f0e3fa6b doc: Document some apis as widget implementor only
A better solution for this would be nice. For the
time being, just add a sentence to the docs.
2020-09-28 20:51:13 -04:00
Arnaud Bonatti 4684082232 Make GtkMenuButton::direction more useful.
This property was only used until now when
there was neither an icon nor a label set,
for arrow direction and popover placement.

Starting with Gtk4, a GtkMenuButton with a
label shows an arrow at the right (in LTR)
of the label. Allow disabling the arrow or
changing its direction using the direction
property, to have a way to restore a Gtk3-
like look or to improve popover placement.

Fixes #2811.
2020-09-29 02:26:13 +02:00
Matthias Clasen 5536a2ffe6 Merge branch 'wip/carlosg/for-master' into 'master'
gtkeventcontrollerscroll: Drop device type checks

Closes #3210

See merge request GNOME/gtk!2635
2020-09-28 22:03:36 +00:00
Carlos Garnacho 11e4a46967 gtkeventcontrollerscroll: Drop device type checks
Kinetic scrolling (and begin/end tracking) broke with commit cab1dcb696
since the pointing device used on X11 does not get as much GdkInputSource
granularity as the source device used to have in GTK3.

Actually this is kinda pointless, devices incapable of smooth scroll
should send discrete events, without those devices in the picture, we
want kinetic scroll to apply on every other device capable of smooth
scroll, so just do that.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3210
2020-09-28 23:35:36 +02:00
Yosef Or Boczko 01ddc181f9 Update Hebrew translation
(cherry picked from commit f6e3dfd73e)
2020-09-28 19:00:52 +00:00
Yosef Or Boczko 2b3c2962ab Update Hebrew translation
(cherry picked from commit 02d1d9714e)
2020-09-28 18:59:32 +00:00
Matthias Clasen 27b3bb59eb Merge branch 'another-attempt-to-fix-shadertoy' into 'master'
Flip GLArea textures

See merge request GNOME/gtk!2634
2020-09-28 16:16:51 +00:00
Matthias Clasen ff61f35b77 Merge branch 'cloudproviders-ci' into 'master'
Cloudproviders ci

Closes #2480

See merge request GNOME/gtk!2632
2020-09-28 15:45:08 +00:00
Matthias Clasen 5206cfa837 Merge branch 'wip/otte/for-master' into 'master'
snapshot: Don't flip textures

See merge request GNOME/gtk!2633
2020-09-28 15:43:02 +00:00
Matthias Clasen b711c12bbe glarea: Flip our texture
The texture that produce is upside-down, compared to what
GSK expects, so flip things around with a transform.

This fixes the shadertoy demo being upside-down after a
recent fix to avoid downloading and reuploading the texture.
2020-09-28 11:34:23 -04:00
Matthias Clasen 431f144f37 gsk: Normalize when transforming bounds
Bounds are assumed to be normalized, and transforms
with negative scales or 3d rotations can make us get
negative sizes.

Fix by Benjamin Otte.
2020-09-28 11:34:16 -04:00
Benjamin Otte 651c92c0ed snapshot: Don't flip textures
... or gradients or borders or shadows. Instead, ensure that affines
have non-negative scale factors. Otherwise add a transform node.

The only place where this check is not necessary is color nodes, but
special casing them seems not worth it.
2020-09-28 16:14:28 +02:00
Milo Casagrande 8487e82133 Update Italian translation 2020-09-28 07:41:47 +00:00
Aurimas Černius 15b635d7bd Updated Lithuanian translation 2020-09-27 22:06:30 +03:00
Matthias Clasen 3aa2519c2b ci: Use v23 images
I added libcloudproviders to the base image, but
now I see that we already enabled libcloudproviders
in the build anyway, so I'm a bit confused.

Fixes: #2480
2020-09-27 11:48:19 -04:00
Matthias Clasen 55bd6d08d4 ci: Add libcloudproviders to the image
Add libcloudproviders to fedora-base:v23 and fedora:v23.
This is so we can enable the cloud-providers feature in
our ci builds.
2020-09-27 11:41:04 -04:00
Matthias Clasen 536e1a1954 Merge branch 'patch-1' into 'master'
treestore: Document the fact that iter is modified by the function, in a machine-readable fashion.

See merge request GNOME/gtk!2613
2020-09-27 15:03:04 +00:00
Danny Milosavljevic 32baa0a549 Update gtktreestore.c: gtk_tree_store_remove didn't have the proper comment annotation
"inout" for the parameter ITER passed.  This means that bindings would misjudge what
the function does.  In the case of guile-gi, it would be misjudged for a predicate,
see gulie-gi bug 87.
2020-09-27 15:03:03 +00:00
Matthias Clasen 6f823cd0bd Merge branch 'issue2627-gtk4' into 'master'
gdk/wayland: Replace gtk-primary-selection with primary-selection-unstable-v1

See merge request GNOME/gtk!2630
2020-09-27 14:51:23 +00:00
Matthias Clasen 97d052ef1b Merge branch 'avoid-gl-texture-download' into 'master'
gsk: Avoid downloading GL textures when possible

See merge request GNOME/gtk!2628
2020-09-27 14:47:52 +00:00
Robert Mader 9ea0469ab0 gdk/wayland: Replace gtk-primary-selection with primary-selection-unstable-v1
The later is the public upstream version, while identical implementation wise.

https://gitlab.gnome.org/GNOME/gtk/-/issues/2591
2020-09-27 16:23:42 +02:00
Matthias Clasen 895c1681f0 Merge branch 'fontchooser-no-lang' into 'master'
fontchooser: Fix builds without PangoFT2

See merge request GNOME/gtk!2629
2020-09-27 12:42:42 +00:00
Matthias Clasen 9ca9f42452 gsk: Avoid downloading GL textures when possible
I found that the gears demo was spending 40% cpu
downloading a GL texture every frame, only to
upload it again to another context.

While the GSK rendering and the GtkGLArea use different
GL contexts, they are (usually) connected by sharing data
with the same global context, so we can just use the
texture without the download/upload dance. This brings
gears down to < 10% cpu.
2020-09-26 21:55:28 -04:00
Matthias Clasen 752270253f fontchooser: Fix builds without PangoFT2
Currently, only if PangoFT2 is present and used it is supported
to retrieve the languages that are supported by a particular font.

If we don't have PangoFT2, remove the language filtering and the
sample text selection.

Based on earlier work by Chun-wei Fan, see
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2614
2020-09-26 19:15:45 -04:00
Matthias Clasen 92e551f895 Merge branch 'BUG_gtktreeview_headers_focus_on_click_GTK4' into 'master'
GtkTreeviewColumn: don't focus-on-click header buttons

See merge request GNOME/gtk!1806
2020-09-26 22:50:23 +00:00
Matthias Clasen 593907f7b0 testupload: Test more formats
Copy the format conversion code from GdkMemoryTexture
so we can produce all formats, and test them all.

The upload fast paths assume that the stride is a
multiple of four, so some of the padding values cause
it to fail. Apart from that, things seem to work for
all combinations.
2020-09-26 17:26:12 -04:00
Matthias Clasen 34ec226852 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

See merge request GNOME/gtk!2626
2020-09-26 14:00:32 +00:00
Matthias Clasen d56ad7c40c Add a test for various texture uploads
Create textures with various characteristics (alpha, premultiplication,
stride) that trigger different code paths in the gl texture upload
function, and show the resulting images. If all goes well, they all
should look the same.

On my system, this tests texture upload for memory formats
GDK_MEMORY_B8G8R8A8_PREMULTIPLIED, GDK_MEMORY_R8G8B8A8, and
GDK_MEMORY_R8G8B8, and it works with both gl and gles.
2020-09-26 09:20:00 -04:00
Matthias Clasen ae09e20e8a NEWS: Updates 2020-09-26 09:04:42 -04:00
Matthias Clasen 54944c9cea Merge branch 'fix-texture-upload-more' into 'master'
More texture upload fixes

Closes #3198

See merge request GNOME/gtk!2624
2020-09-26 12:52:25 +00:00
Matthias Clasen fe8986f2d5 Merge branch 'matthiasc/for-master' into 'master'
gl: Make debug spew more complete

Closes #3197

See merge request GNOME/gtk!2623
2020-09-26 02:02:13 +00:00
Matthias Clasen d6912a6791 More texture upload fixes
In some cases, with bpp == 3 and a rowstride
that is divisible by 4, we were passing invalid
parameters to GL.

Fixes: #3198
2020-09-25 21:59:33 -04:00
Matthias Clasen db4b7e3d11 Merge branch 'add-child-clash' into 'master'
Make GtkBuildable vfunc accessor functions private

Closes #3191

See merge request GNOME/gtk!2619
2020-09-26 01:17:08 +00:00
Matthias Clasen 6cdbf1a352 popup: Fix up a doc blurb
The GdkPopup:autohide property was mis-documented.

Fixes: #3197
2020-09-25 20:43:01 -04:00
Matthias Clasen 3d881752bf gl: Make debug spew more complete
List GL_EXT_unpack_subimage among the extensions
we check for.
2020-09-25 20:42:01 -04:00
Matthias Clasen 1b93108d10 Merge branch 'fix-rgb-upload' into 'master'
gl: Fix RGB uploads

Closes #3194

See merge request GNOME/gtk!2620
2020-09-26 00:30:31 +00:00
Florian Müllner e4d4b50d6d docs: Document GtkBuildable changes in migration guide
https://gitlab.gnome.org/GNOME/gtk/-/issues/3191
2020-09-26 02:16:57 +02:00
Florian Müllner 2715b3ec31 buildable: Make vfunc accessor functions private
With the exception of gtk_buildable_get_id(), those are only used
to construct objects from XML descriptions, which is functionality
internal to GTK.

The API is therefore unlikely to be missed, and keeping it internal
means they can no longer unintentionally shadow object methods in
bindings with less namespacing; for example it's currently ambiguous
whether `infoBar.add_child()` refers to gtk_info_bar_add_child() or
gtk_buildable_add_child().

https://gitlab.gnome.org/GNOME/gtk/-/issues/3191
2020-09-26 02:16:57 +02:00
Florian Müllner 12189bc10f buildable: Rename set_name() to set_buildable_id()
GtkBuildable's get_name()/set_name() methods may shadow
GtkWidget's methods. Avoid that by renaming the API to
get_buildable_id()/set_buildable_id(), which also reflects
the name of the XML attribute the API refers to.

https://gitlab.gnome.org/GNOME/gtk/-/issues/3191
2020-09-26 02:16:05 +02:00
Matthias Clasen 3db217ab7a gl: Reset GL_UNPACK_ALIGNMENT
Reset GL_UNPACK_ALIGNMENT to its initial value of 4 after
changing it for a glTexImage2D call.
2020-09-25 16:17:45 -04:00
Matthias Clasen a9de1d702e Merge branch 'matthiasc/for-master' into 'master'
columnview: Simplify column constructors

See merge request GNOME/gtk!2622
2020-09-25 18:25:09 +00:00
Matthias Clasen 0c3f42e06e columnview: Simplify column constructors
Drop gtk_column_view_column_new_with_factory and
just make gtk_column_view_column_new accept a
nullable factory. This follows what we've been
doing elsewhere.

Update all callers.
2020-09-25 13:57:10 -04:00
Matthias Clasen d4b740ce62 Merge branch 'wip/carlosg/for-master' into 'master'
Wip/carlosg/for master

Closes #3125 and #3121

See merge request GNOME/gtk!2621
2020-09-25 17:49:59 +00:00
Carlos Garnacho d9d494826f gtkbutton: Clean up priv->in_button
This is now only toggled around, may be cleaned up.
2020-09-25 19:20:27 +02:00
Carlos Garnacho ea6e575901 gtkbutton: Check release coordinates on all release event types
The priv->in_button state that used to be relied upon for pointer
events has been reduced over time to a broken state, since the button
does not track crossing events anymore.

Make the coordinate-based checks apply for pointer events too, besides
touch events. This fixes GtkButton mistakenly emitting ::clicked with
pointer button releases outside the widget.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3121
2020-09-25 19:20:04 +02:00
Matthias Clasen 12f05e80aa gl: Fix RGB uploads
I don't really know what to say, other than:
OpenGL is terrible

Fixes: #3194
2020-09-25 13:16:47 -04:00
Carlos Garnacho 0ccdbfd802 gtktextview: Avoid GtkGestureClick claiming on touch press
We still want the drag gesture (and text selection) to work. Avoid claiming
the gesture early, like it's done in the pointer case.
2020-09-25 19:02:26 +02:00
Carlos Garnacho 7d5accc69f gtkscrolledwindow: Do not eagerly claim touch press event
Claiming early makes the contents unable to react to the touch press
event. Do this on GtkGestureDrag::update past a threshold, so the
child widget(s) can claim before the scrolledwindow does.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3125
2020-09-25 18:58:44 +02:00
Carlos Garnacho b1606db839 gtkscrolledwindow: Drop gtk_scrolled_window_set_capture_button_press()
This API is kinda stuck in the GdkEvent days, we now negotiate ownership
of the input sequence via GtkGestures. Remove it as it reflects a way to
work that was not exactly accurate and it will turn plainly wrong soon.
2020-09-25 18:57:40 +02:00
Matthias Clasen c9f6a9f7c5 Merge branch 'gles-texture-colors' into 'master'
Fix uploads of textures in GLES (and make texture uploads better)

See merge request GNOME/gtk!2616
2020-09-25 14:53:19 +00:00
Timm Bäder 09564a5798 Merge branch 'wip/baedert/for-master' into 'master'
Wip/baedert/for master

See merge request GNOME/gtk!2617
2020-09-25 13:35:20 +00:00
Alexander Larsson a299bbfc58 Drop gdk_cairo_surface_upload_to_gl() helper
There is nothing really special about this code, its just a helper for
uploading pixel data to opengl, and we're not really in the business
of doing opengl-specific helper functions.
2020-09-25 15:00:07 +02:00
Alexander Larsson 90fc671ef8 gl backend: Avoid roundtripping via surface when updloading
Do custom uploads rather than using gdk_cairo_surface_upload_to_gl(),
because this way we avoids a roundtrip (memcpy and possibly conversion)
to the cairo image surface format.
2020-09-25 10:04:48 +02:00
Alexander Larsson c71921a6be gdk_gl_context_upload_texture() avoid conversion for pixbuf format
The gdk-pixbuf non-rgba format can be directly uploaded without
conversion.

The rgba format needs alpha premultiplication though, which is not
supported by GL during upload.
2020-09-25 09:31:43 +02:00
Alexander Larsson 1001995d49 Correctly upload textures for GLES
GLES doesn't support the GL_BGRA +  GL_UNSIGNED_INT_24_8 hack that
we use on desktop OpenGL to upload textures directly in the cairo
pixel format. This adds the required conversions to all the places
that currently need it.

We also add a data_format to the internal gdk_gl_context_upload_texture()
function to make it clearer what the format are. Currently it is always
the cairo image surface format, but eventually we want to support other
formats so that we can avoid some of the unnecessary conversions we do.

Also, the current gdk_gl_context_upload_texture() code always converts
to a cairo format and uploads that like we did before. Later commits
will allow this to use other upload formats that gl supports to avoid
conversions.
2020-09-25 09:31:43 +02:00
Alexander Larsson 8e59cdabac Add GDK_MEMORY_R8G8B8A8_PREMULTIPLIED
This is the default OpenGL format, and in fact the only pixel format
that GLES supports uploading as. Actually, the premultiplied part is
really just about how we use the textures, but all textures in GTK
are premultiplied.
2020-09-25 09:31:43 +02:00
Alexander Larsson 88b709d5ec texture: Unvirtualize download_surface
We only have one implementation, so why do all this vfunc work?
2020-09-25 09:31:43 +02:00
Matthias Clasen e6d5a3c4e8 Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #3180, #3178, and #3179

See merge request GNOME/gtk!2618
2020-09-24 18:50:26 +00:00
Matthias Clasen e70ed905d1 columview: Don't overdraw
Just always tell the title and cell widgets to
clip their children to the right size. Otherwise
we risk things getting out of sync and unintended
overdraw.

Fixes: #3179
2020-09-24 14:30:40 -04:00
Matthias Clasen 7eb0ae39c5 columview: Fix column resizing
We were not handling the fixed_width quite right,
and that was causing screaming from the GTK size
allocation machinery.

Fixes: #3178
2020-09-24 14:18:38 -04:00
Timm Bäder 2f93287473 cssimagefallback: Whitespace 2020-09-24 19:08:22 +02:00
Timm Bäder 484dcc043b cssimagefallback: Avoid allocating GPtrArray for colors
If we just parse a color, like image(#FFF), avoid allocating the
GPtrArray to store images. This happens in Adwaita for background images
of backdrop buttons. We save around 70 GPtrArrays this way.
2020-09-24 19:08:22 +02:00
Timm Bäder 716b5afe6a Adwaita: Fix calendar header button backdrop bg color 2020-09-24 19:08:22 +02:00
Timm Bäder fd728ea8bc gl renderer: Lower maximum gradient stop count
6 is still plenty according to my market research.

Should help with #2624
2020-09-24 19:08:22 +02:00
Timm Bäder 8d7b3bade3 gl renderer: Fall back to cairo if gradients use too many stops 2020-09-24 19:08:22 +02:00
Timm Bäder 12cc178756 textbuffer: Don't try to inset NULL text from clipboard
That used to generate a critical error message.

Also free() the data.
2020-09-24 19:08:22 +02:00
Timm Bäder 9eaa8bd1e7 gl renderer: Only return error if creating programs failed 2020-09-24 19:08:22 +02:00
Timm Bäder 15994db74d gl renderer: Use scale_x/y when rendering clipped nodes 2020-09-24 19:08:22 +02:00
Timm Bäder 467be0b7dc gl renderer: Don't use ops_get_scale() when rendering clip nodes
Differentiate between scale_x and scale_y. This works better for e.g.
transform nodes using scaleX().
2020-09-24 19:08:22 +02:00
Timm Bäder 84d2a33c10 gl renderer: Support scaleX/Y better when rendering radial gradients
We should do this everywhere, but this is a start.
2020-09-24 19:08:22 +02:00
Matthias Clasen 9fde0137a0 listview: Avoid a critical when reordering
When sorting a cell into the place its already at,
we were triggering criticals. Avoid that.

Fixes: #3180
2020-09-23 22:53:21 -04:00
Matthias Clasen 9dab51e7be Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master

Closes #3188

See merge request GNOME/gtk!2612
2020-09-23 22:44:22 +00:00
Matthias Clasen 810218b2f5 fontchooser: Don't center the list
The centered layout of the font previews don't look appealing
and make it harder to judge the relative width and weight of
the individual styles.

Fixes: #3188
2020-09-23 16:32:48 -04:00
Balázs Úr 7acbbd6bdd Update Hungarian translation 2020-09-23 15:25:12 +00:00
Balázs Úr a364ab1efb Update Hungarian translation 2020-09-23 14:39:40 +00:00
Thomas Holder 4325c20013 gtktreeview: Fix child access after TEST_EXPAND_ROW
In gtk_tree_view_build_tree with recurse=TRUE, the TEST_EXPAND_ROW
signal might invalidate the child iterator. Getting the iterator after
the signal (instead of before) fixes the issue.

Fixes https://gitlab.com/inkscape/inkscape/-/issues/1879
2020-09-23 07:53:33 -04:00
Matthias Clasen 7bae48335f Merge branch 'wip/jimmac/osd-spinbutton' into 'master'
Adwaita: osd spinbutton specificity bump

Closes #2769

See merge request GNOME/gtk!2610
2020-09-23 11:47:01 +00:00
Matthias Clasen 571f15cac6 Merge branch 'make-claiming-button-release-work' into 'master'
gestures: Make claiming button release work

See merge request GNOME/gtk!2576
2020-09-23 11:35:59 +00:00
Jakub Steiner 78236bfdbe Adwaita: osd spinbutton specificity bump
- mimic the peculiar selector from the normal style onto osd to
  override.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/2769
2020-09-23 10:16:55 +02:00
Matthias Clasen 53dddf163d gestures: Make claiming button release work
When claiming a sequence in a gesture signal handler,
the expected result is that GtkGesture::handle-event
returns TRUE, causing the event to not be propagated
further.

This doesn't work for button release events, since
gtk_gesture_handle_event does the following:
  add point
  emit ::update
  remove point
  check claimed status
The ::update signal is where the application code
claims the sequence. But removing the point purges
the sequence from the gestures memory, so checking
the claimed status returns FALSE.

This patch fixes things to behave as expected, by
checking the claimed status before removing the point.
2020-09-14 08:35:44 -04:00
nana-4 68379c3ff7 Adwaita: Simplify stackswitcher button styling
Simply use negative margins against the padding.

Also remove the indicator only when the .needs-attention style class is
removed.
2020-08-28 22:06:44 +09:00
Nelson Benítez León ba9b4f418d GtkTreeviewColumn: don't focus-on-click header buttons
currently when mouse clicking on a column header
to sort it it is grabbing keyboard focus, this
should not happen, keyboard focus should remain
where it was before. This can be seen on the
GtkFileChooser widget, when having the keyboard
focus on the file list items and clicking on a
column header to sort it the keyboard focus is
now on the header.
2020-04-30 22:59:08 -04:00
Sean Farley 99dfdfcd5e Allow LPR backend to print PDF and PS file formats
At least from GTK v3.22.30, the code disallows attempts to print PDF and
PS files using the LPR backend. Although it is not easy or possible for
GTK to determine if the printer can print these formats by querying lpr,
the print backend should allow lpr to try.

There are two uses cases:
- A filter is being used by lpr, specified in the printcap file, to process the
  files prior to printing them.
- The printer can print PDF and PS files directly. There are many printers that
  can print these formats, so GTK should allow for the possibility.
2018-11-17 13:04:35 -05:00
399 changed files with 30730 additions and 61128 deletions
+5 -5
View File
@@ -16,13 +16,13 @@ stages:
# Common variables
variables:
COMMON_MESON_FLAGS: "--fatal-meson-warnings -Dgtk:werror=true"
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false"
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:v22"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v25"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v25"
.only-default:
only:
@@ -74,7 +74,6 @@ fedora-x86_64:
script:
- meson subprojects update
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
-Dsysprof=enabled
_build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build x11
@@ -100,6 +99,7 @@ installed-tests:
needs: []
variables:
EXTRA_MESON_FLAGS: "--prefix=/usr --libdir=/usr/lib64 -Dinstall-tests=true"
G_TEST_ACCESSIBLE: 1
script:
- meson subprojects update
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
@@ -223,7 +223,7 @@ asan-build:
needs: []
variables:
script:
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=false _build
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled _build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland
artifacts:
+2 -1
View File
@@ -44,6 +44,7 @@ RUN dnf -y install \
lcov \
libasan \
libattr-devel \
libcloudproviders-devel \
libepoxy-devel \
libffi-devel \
libmount-devel \
@@ -86,5 +87,5 @@ RUN dnf -y install \
xorg-x11-server-Xvfb \
&& dnf clean all
RUN pip3 install meson==0.53.1
RUN pip3 install meson==0.55.3
+1 -1
View File
@@ -1,4 +1,4 @@
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v25
RUN dnf -y install pandoc
+1 -1
View File
@@ -1,4 +1,4 @@
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v21
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v25
# Enable sudo for wheel users
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
+1 -1
View File
@@ -22,7 +22,7 @@ flatpak build ${builddir} meson \
-Dprint-backends=file \
-Dbuild-tests=false \
-Dbuild-examples=false \
-Dintrospection=false \
-Dintrospection=disabled \
-Ddemos=true \
_flatpak_build
+1 -3
View File
@@ -60,14 +60,12 @@ pkg-config --modversion pango
ccache --zero-stats
ccache --show-stats
export CCACHE_DISABLE=true
# FIXME: introspection disabled for now because of
# https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/340
meson \
-Dx11-backend=false \
-Dwayland-backend=false \
-Dwin32-backend=true \
-Dvulkan=disabled \
-Dintrospection=false \
-Dintrospection=enabled \
-Dgtk:werror=true \
_build
unset CCACHE_DISABLE
+72 -19
View File
@@ -1,19 +1,74 @@
Overview of Changes
===================
* GtkEmojiChooser:
- Allow inserting multiple Emoji by pressing Control
- Update Emoji data to Unicode 13 / CLDR 37
- Use translations
- The recent-emoji setting type changed. Call
gsettings reset org.gtk.gtk4.Settings.EmojiChooser recent-emoji
* GtkTextBuffer:
- Add boolean returns to some get_iter functions
* GtkScale:
- Change the default value of the :draw-value property
* Input methods:
- Add a 'private' input hint
* GL Renderer:
- Fix issues with texture caching
* Build:
- Use meson yield feature for some options
- Require gtk-doc 1.33
* Demos:
- Add another column view demo
Overview of Changes in GTK 3.99.2
=================================
* GtkButton:
- Check coordinates for button releases
* GtkColorChooser:
- Update the default palette
* GtkEntry:
- Fix issues with Emoji insertion
- Fix issues with dnd
- Set correct hotspot for dnd icon
* GtkFileChooser:
- Fix a crash
- Fix setting unlisted filters
* GtkFontChooser:
- Determine sample text based on font coverage (requires fontconfig)
- Allow filtering by language (requires fontconfig)
- Don't center the list
* GtkMenuButton:
- Always use the direction property for the arrow
* GtkPasswordEntry:
- Use non-pageable memory
- Add an ::activate signal
* GtkRevealer:
- Fix clipping issues in the swing transitions
* GtkScrolledWindow:
- Fix kinetic scrolling in X11
* GtkSearchEntry:
- Don't handle forwarded events twice
* GtkPasswordEntry:
- Add an ::activate signal
* GtkStack:
- Add gtk_stack_add_child
* GtkTextView:
- Fix dnd
@@ -22,28 +77,12 @@ Overview of Changes in GTK 3.99.2
- Make clickable links work again
- Fix handling of anchored children
* GtkRevealer:
- Fix clipping issues in the swing transitions
* GtkColorChooser:
- Update the default palette
* GtkFileChooser:
- Fix a crash
- Fix setting unlisted filters
* GtkFontChooser:
- Determine sample text based on font coverage
- Allow filtering by language
* GtkStack:
- Add gtk_stack_add_child
* GtkVideo:
- Make autoplay work
* CSS:
- Allow more than 64 selectors per rule
- Avoid some allocation overhead
* Adwaita:
- Improve gesture graphics
@@ -52,15 +91,20 @@ Overview of Changes in GTK 3.99.2
* GDK:
- Add gdk_frame_clock_get_fps
- GLES: Fix color channel mixup in textures
- GL: Reduce image copying for texture uploads
* GSK:
- Add radial gradient nodes
- Add GskGLShader and shader nodes
* GL renderer:
- Fix clipping with projective transforms
- Use linear interpolation for offscreen rendering
with non-axis-aligned transforms
- Fix texture caching to avoid size mismatches
- Avoid downloading GL textures when possible,
improving GtkGLArea performance
* Vulkan renderer:
- Fix swapchain creation
@@ -70,18 +114,26 @@ Overview of Changes in GTK 3.99.2
* Wayland
- Always ack configure to avoid jumping windows
- Use the primary-selection-unstable-v1 protocol
* API cleanups:
- Make filter and sorter constructors return exact types
- Rename GdkSurfaceState to GdkToplevelState
- Remove GdkWaylandSurface::committed
- Make Wayland backend api take GdkToplevel
- Drop gtk_widget_new
- Drop cairo_surface_upload_to_gl
- Drop gtk_scrolled_window_set_capture_button_press
- Drop gtk_column_view_column_new_with_factory
- Rename gtk_buildable_set_name to gtk_buildable_set_buildable_id
- Drop other GtkBuildable api
* Demos:
- Bug and crash fixes
- Cosmetic improvements for several demos
- Improve search in the sidebar
- Add a Shadertoy demo
- Add a OpenGL transitions demo
- Add an Emblem demo
- Add a demo for input validation and error states
- Add a demo for context menus
@@ -101,6 +153,7 @@ Overview of Changes in GTK 3.99.2
French
Galician
German
Hebrew
Hungarian
Indonesian
Italian
+26
View File
@@ -0,0 +1,26 @@
uniform float u_time;
void
mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
vec2 pos = (fragCoord.xy * 2.0 - resolution.xy)/ min (resolution.x, resolution.y) ;
float t0 = sin ((u_time + 0.00)*1.0);
float t1 = sin ((u_time + 0.30)*0.4);
float t2 = cos ((u_time + 0.23)*0.9);
float t3 = cos ((u_time + 0.41)*0.6);
float t4 = cos ((u_time + 0.11)*0.3);
vec2 p0 = vec2 (t1, t0) ;
vec2 p1 = vec2 (t2, t3) ;
vec2 p2 = vec2 (t4, t3) ;
float r = 1.0/distance (pos, p0);
float g = 1.0/distance (pos, p1);
float b = 1.0/distance (pos, p2);
float sum = r + g + b;
float alpha = 1.0 - pow (1.0/(sum), 40)*pow (10.0, 40*0.7);
fragColor = vec4 (r*0.5, g*0.5, b*0.5, 1.0) * alpha;
}
+226
View File
@@ -0,0 +1,226 @@
uniform float iTime;
// Originally from: https://www.shadertoy.com/view/3ljyDD
// License CC0: Hexagonal tiling + cog wheels
// Nothing fancy, just hexagonal tiling + cog wheels
#define PI 3.141592654
#define TAU (2.0*PI)
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
float hash(in vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
}
float pcos(float a) {
return 0.5 + 0.5*cos(a);
}
void rot(inout vec2 p, float a) {
float c = cos(a);
float s = sin(a);
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
}
float modPolar(inout vec2 p, float repetitions) {
float angle = 2.0*PI/repetitions;
float a = atan(p.y, p.x) + angle/2.;
float r = length(p);
float c = floor(a/angle);
a = mod(a,angle) - angle/2.;
p = vec2(cos(a), sin(a))*r;
// For an odd number of repetitions, fix cell index of the cell in -x direction
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
if (abs(c) >= (repetitions/2.0)) c = abs(c);
return c;
}
float pmin(float a, float b, float k) {
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
return mix( b, a, h ) - k*h*(1.0-h);
}
const vec2 sz = vec2(1.0, sqrt(3.0));
const vec2 hsz = 0.5*sz;
const float smallCount = 16.0;
vec2 hextile(inout vec2 p) {
// See Art of Code: Hexagonal Tiling Explained!
// https://www.youtube.com/watch?v=VmrIDyYiJBA
vec2 p1 = mod(p, sz)-hsz;
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
vec2 n = p3 - p;
p = p3;
return n;
}
float circle(vec2 p, float r) {
return length(p) - r;
}
float box(vec2 p, vec2 b) {
vec2 d = abs(p)-b;
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}
float unevenCapsule(vec2 p, float r1, float r2, float h) {
p.x = abs(p.x);
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(p,vec2(-b,a));
if( k < 0.0 ) return length(p) - r1;
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
return dot(p, vec2(a,b) ) - r1;
}
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
float cogWidth = 0.25*innerRadius*TAU/cogs;
float d0 = circle(p, innerRadius);
vec2 icp = p;
modPolar(icp, holes);
icp -= vec2(innerRadius*0.55, 0.0);
float d1 = circle(icp, innerRadius*0.25);
vec2 cp = p;
modPolar(cp, cogs);
cp -= vec2(innerRadius, 0.0);
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
float d3 = circle(p, innerRadius*0.20);
float d = 1E6;
d = min(d, d0);
d = pmin(d, d2, 0.5*cogWidth);
d = min(d, d2);
d = max(d, -d1);
d = max(d, -d3);
return d;
}
float ccell1(vec2 p, float r) {
float d = 1E6;
const float bigCount = 60.0;
vec2 cp0 = p;
rot(cp0, -iTime*TAU/bigCount);
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
vec2 cp1 = p;
float nm = modPolar(cp1, 6.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
d = min(d, d0);
d = min(d, d1);
return d;
}
float ccell2(vec2 p, float r) {
float d = 1E6;
vec2 cp0 = p;
float nm = modPolar(cp0, 6.0);
vec2 cp1 = cp0;
const float off = 0.275;
const float count = smallCount + 2.0;
cp0 -= vec2(off, 0.0);
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
float l = length(p);
float d2 = l - (off+0.055);
float d3 = d2 + 0.020;;
vec2 tp0 = p;
modPolar(tp0, 60.0);
tp0.x -= off;
float d4 = box(tp0, vec2(0.0125, 0.005));
float ctime = -(iTime*0.05 + r)*TAU;
vec2 tp1 = p;
rot(tp1, ctime*12.0);
tp1.x -= 0.13;
float d5 = box(tp1, vec2(0.125, 0.005));
vec2 tp2 = p;
rot(tp2, ctime);
tp2.x -= 0.13*0.5;
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
float d7 = l - 0.025;
float d8 = l - 0.0125;
d = min(d, d0);
d = min(d, d1);
d = min(d, d2);
d = max(d, -d3);
d = min(d, d4);
d = min(d, d5);
d = min(d, d6);
d = min(d, d7);
d = max(d, -d8);
return d;
}
float df(vec2 p, float scale, inout vec2 nn) {
p /= scale;
nn = hextile(p);
nn = round(nn);
float r = hash(nn);
float d;;
if (r < 0.5) {
d = ccell1(p, r);
} else {
d = ccell2(p, r);
}
return d*scale;
}
vec3 postProcess(vec3 col, vec2 q) {
//col = saturate(col);
col=pow(clamp(col,0.0,1.0),vec3(0.75));
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
return col;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv) {
vec2 q = fragCoord/resolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= resolution.x/resolution.y;
float tm = iTime*0.1;
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
float aa = 4.0 / resolution.y;
vec2 nn = vec2(0.0);
float d = df(p, z, nn);
vec3 col = vec3(160.0)/vec3(255.0);
vec3 baseCol = vec3(0.3);
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
col = postProcess(col, q);
fragColor = vec4(col, 1.0);
}
+27
View File
@@ -0,0 +1,27 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/crosswarp
// Author: Eke Péter <peterekepeter@gmail.com>
// License: MIT
vec4 transition(vec2 p) {
float x = progress;
x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));
return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
+24
View File
@@ -133,6 +133,21 @@
<file>cogs.glsl</file>
<file>glowingstars.glsl</file>
</gresource>
<gresource prefix="/gltransition">
<file>gtkshaderstack.c</file>
<file>gtkshaderstack.h</file>
<file>gtkshaderbin.h</file>
<file>gtkshaderbin.c</file>
<file>gskshaderpaintable.h</file>
<file>gskshaderpaintable.c</file>
<file>wind.glsl</file>
<file>radial.glsl</file>
<file>crosswarp.glsl</file>
<file>kaleidoscope.glsl</file>
<file>cogs2.glsl</file>
<file>ripple.glsl</file>
<file>background.glsl</file>
</gresource>
<gresource prefix="/iconscroll">
<file>iconscroll.ui</file>
</gresource>
@@ -169,6 +184,9 @@
<gresource prefix="/listview_settings">
<file>listview_settings.ui</file>
</gresource>
<gresource prefix="/listview_ucd_data/">
<file>ucdnames.data</file>
</gresource>
<gresource prefix="/listview_weather">
<file compressed="true">listview_weather.txt</file>
</gresource>
@@ -186,6 +204,9 @@
<file>demo3widget.h</file>
<file>demo3widget.ui</file>
</gresource>
<gresource prefix="/paintable_svg">
<file>org.gtk.gtk4.NodeEditor.Devel.svg</file>
</gresource>
<gresource prefix="/shortcuts">
<file>shortcuts.ui</file>
<file>shortcuts-builder.ui</file>
@@ -247,6 +268,7 @@
<file>gears.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>gltransition.c</file>
<file>headerbar.c</file>
<file>hypertext.c</file>
<file>iconscroll.c</file>
@@ -265,6 +287,7 @@
<file>listview_filebrowser.c</file>
<file>listview_minesweeper.c</file>
<file>listview_settings.c</file>
<file>listview_ucd.c</file>
<file>listview_weather.c</file>
<file>listview_words.c</file>
<file>list_store.c</file>
@@ -279,6 +302,7 @@
<file>paintable_animated.c</file>
<file>paintable_emblem.c</file>
<file>paintable_mediastream.c</file>
<file>paintable_svg.c</file>
<file>panes.c</file>
<file>password_entry.c</file>
<file>peg_solitaire.c</file>
+34
View File
@@ -9,6 +9,7 @@
#include "gtkfishbowl.h"
#include "gtkgears.h"
#include "gskshaderpaintable.h"
const char *const css =
".blurred-button {"
@@ -149,6 +150,38 @@ create_switch (void)
return w;
}
static gboolean
update_paintable (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GskShaderPaintable *paintable;
gint64 frame_time;
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
gsk_shader_paintable_update_time (paintable, 0, frame_time);
return G_SOURCE_CONTINUE;
}
static GtkWidget *
create_cogs (void)
{
GtkWidget *picture;
static GskGLShader *cog_shader = NULL;
GdkPaintable *paintable;
if (cog_shader == NULL)
cog_shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
paintable = gsk_shader_paintable_new (g_object_ref (cog_shader), NULL);
picture = gtk_picture_new_for_paintable (paintable);
gtk_widget_set_size_request (picture, 150, 75);
gtk_widget_add_tick_callback (picture, update_paintable, NULL, NULL);
return picture;
}
static void
mapped (GtkWidget *w)
{
@@ -185,6 +218,7 @@ static const struct {
{ "Gears", create_gears },
{ "Switch", create_switch },
{ "Menubutton", create_menu_button },
{ "Shader", create_cogs },
};
static int selected_widget_type = -1;
+350
View File
@@ -0,0 +1,350 @@
/* OpenGL/Transitions
* #Keywords: OpenGL, shader, effect
*
* Create transitions between pages using a custom fragment shader.
*
* The example transitions here are taken from gl-transitions.com, and you
* can edit the shader code itself on the last page of the stack.
*
* The transitions work with arbitrary content. We use images, shaders
* GL areas and plain old widgets to demonstrate this.
*
* The demo also shows some over-the-top effects like wobbly widgets,
* and animated backgrounds.
*/
#include <math.h>
#include <gtk/gtk.h>
#include "gtkshaderstack.h"
#include "gtkshaderbin.h"
#include "gtkshadertoy.h"
#include "gskshaderpaintable.h"
static GtkWidget *demo_window = NULL;
static void
close_window (GtkWidget *widget)
{
/* Reset the state */
demo_window = NULL;
}
static void
text_changed (GtkTextBuffer *buffer,
GtkWidget *button)
{
gtk_widget_show (button);
}
static void
apply_text (GtkWidget *button,
GtkTextBuffer *buffer)
{
GtkWidget *stack;
GskGLShader *shader;
GtkTextIter start, end;
char *text;
stack = g_object_get_data (G_OBJECT (button), "the-stack");
gtk_text_buffer_get_bounds (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
GBytes *bytes = g_bytes_new_take (text, strlen (text));
shader = gsk_gl_shader_new_from_bytes (bytes);
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
g_object_unref (shader);
g_bytes_unref (bytes);
gtk_widget_hide (button);
}
static void
go_back (GtkWidget *button,
GtkWidget *stack)
{
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), FALSE);
}
static void
go_forward (GtkWidget *button,
GtkWidget *stack)
{
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), TRUE);
}
static void
clicked_cb (GtkGestureClick *gesture,
guint n_pressed,
double x,
double y,
gpointer data)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static GtkWidget *
ripple_bin_new (void)
{
GtkWidget *bin = gtk_shader_bin_new ();
static GskGLShader *shader = NULL;
if (shader == NULL)
shader = gsk_gl_shader_new_from_resource ("/gltransition/ripple.glsl");
gtk_shader_bin_add_shader (GTK_SHADER_BIN (bin), shader, GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_PRELIGHT, 20);
return bin;
}
static GtkWidget *
new_shadertoy (const char *path)
{
GBytes *shader;
GtkWidget *toy;
toy = gtk_shadertoy_new ();
shader = g_resources_lookup_data (path, 0, NULL);
gtk_shadertoy_set_image_shader (GTK_SHADERTOY (toy),
g_bytes_get_data (shader, NULL));
g_bytes_unref (shader);
return toy;
}
static gboolean
update_paintable (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GskShaderPaintable *paintable;
gint64 frame_time;
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
gsk_shader_paintable_update_time (paintable, 0, frame_time);
return G_SOURCE_CONTINUE;
}
static GtkWidget *
make_shader_stack (const char *name,
const char *resource_path,
int active_child,
GtkWidget *scale)
{
GtkWidget *stack, *child, *widget, *vbox, *hbox, *bin;
GtkWidget *label, *button, *tv;
GskGLShader *shader;
GObjectClass *class;
GParamSpecFloat *pspec;
GtkAdjustment *adjustment;
GtkTextBuffer *buffer;
GBytes *bytes;
GtkEventController *controller;
GtkCssProvider *provider;
GdkPaintable *paintable;
stack = gtk_shader_stack_new ();
shader = gsk_gl_shader_new_from_resource (resource_path);
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
g_object_unref (shader);
child = gtk_picture_new_for_resource ("/css_blendmodes/ducky.png");
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
paintable = gsk_shader_paintable_new (shader, NULL);
child = gtk_picture_new_for_paintable (paintable);
gtk_widget_add_tick_callback (child, update_paintable, NULL, NULL);
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = new_shadertoy ("/shadertoy/neon.glsl");
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
class = g_type_class_ref (GTK_TYPE_SHADER_STACK);
pspec = G_PARAM_SPEC_FLOAT (g_object_class_find_property (class, "duration"));
adjustment = gtk_range_get_adjustment (GTK_RANGE (scale));
if (gtk_adjustment_get_lower (adjustment) == 0.0 &&
gtk_adjustment_get_upper (adjustment) == 0.0)
{
gtk_adjustment_configure (adjustment,
pspec->default_value,
pspec->minimum,
pspec->maximum,
0.1, 0.5, 0);
}
g_type_class_unref (class);
g_object_bind_property (adjustment, "value",
stack, "duration",
G_BINDING_DEFAULT);
widget = gtk_scrolled_window_new ();
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (widget), TRUE);
gtk_widget_set_hexpand (widget, TRUE);
gtk_widget_set_vexpand (widget, TRUE);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), 0);
g_signal_connect (controller, "released", G_CALLBACK (clicked_cb), NULL);
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
gtk_widget_add_controller (GTK_WIDGET (widget), controller);
tv = gtk_text_view_new ();
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_top_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_bottom_margin (GTK_TEXT_VIEW (tv), 4);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
bytes = g_resources_lookup_data (resource_path, 0, NULL);
gtk_text_buffer_set_text (buffer,
(const char *)g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes));
g_bytes_unref (bytes);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (widget), tv);
gtk_box_append (GTK_BOX (child), widget);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
gtk_shader_stack_set_active (GTK_SHADER_STACK (stack), active_child);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
widget = gtk_center_box_new ();
label = gtk_label_new (name);
gtk_widget_add_css_class (label, "title-4");
gtk_widget_set_size_request (label, -1, 26);
gtk_center_box_set_center_widget (GTK_CENTER_BOX (widget), label);
button = gtk_button_new_from_icon_name ("view-refresh-symbolic");
g_signal_connect (buffer, "changed", G_CALLBACK (text_changed), button);
g_object_set_data (G_OBJECT (button), "the-stack", stack);
g_signal_connect (button, "clicked", G_CALLBACK (apply_text), buffer);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, "button.small { padding: 0; }", -1);
gtk_style_context_add_provider (gtk_widget_get_style_context (button),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_widget_add_css_class (button, "small");
gtk_widget_hide (button);
gtk_center_box_set_end_widget (GTK_CENTER_BOX (widget), button);
gtk_box_append (GTK_BOX (vbox), widget);
GtkWidget *bin2 = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin2), stack);
gtk_box_append (GTK_BOX (vbox), bin2);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), hbox);
button = gtk_button_new_from_icon_name ("go-previous-symbolic");
g_signal_connect (button, "clicked", G_CALLBACK (go_back), stack);
bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
button = gtk_button_new_from_icon_name ("go-next-symbolic");
g_signal_connect (button, "clicked", G_CALLBACK (go_forward), stack);
bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
return vbox;
}
static GtkWidget *
create_gltransition_window (GtkWidget *do_widget)
{
GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
GdkPaintable *paintable;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Transitions");
headerbar = gtk_header_bar_new ();
scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
gtk_widget_set_size_request (scale, 100, -1);
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), scale);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
outer_grid = gtk_grid_new ();
gtk_window_set_child (GTK_WINDOW (window), outer_grid);
paintable = gsk_shader_paintable_new (gsk_gl_shader_new_from_resource ("/gltransition/background.glsl"), NULL);
background = gtk_picture_new_for_paintable (paintable);
gtk_widget_add_tick_callback (background, update_paintable, NULL, NULL);
gtk_grid_attach (GTK_GRID (outer_grid),
background,
0, 0, 1, 1);
grid = gtk_grid_new ();
gtk_grid_attach (GTK_GRID (outer_grid),
grid,
0, 0, 1, 1);
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start (grid, 12);
gtk_widget_set_margin_end (grid, 12);
gtk_widget_set_margin_top (grid, 12);
gtk_widget_set_margin_bottom (grid, 12);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Wind", "/gltransition/wind.glsl", 0, scale),
0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Radial", "/gltransition/radial.glsl", 1, scale),
1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Crosswarp", "/gltransition/crosswarp.glsl", 2, scale),
0, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Kaleidoscope", "/gltransition/kaleidoscope.glsl", 3, scale),
1, 1, 1, 1);
return window;
}
GtkWidget *
do_gltransition (GtkWidget *do_widget)
{
if (!demo_window)
demo_window = create_gltransition_window (do_widget);
if (!gtk_widget_get_visible (demo_window))
gtk_widget_show (demo_window);
else
gtk_window_destroy (GTK_WINDOW (demo_window));
return demo_window;
}
+337
View File
@@ -0,0 +1,337 @@
/*
* Copyright © 2020 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gskshaderpaintable.h"
/**
* 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.
*
* You can set the uniform data that the shader needs for rendering
* using gsk_shader_paintable_set_args(). This function can
* be called repeatedly to change the uniform data for the next
* snapshot.
*
* 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
* to update the time based on the frame time of the frame clock.
*/
struct _GskShaderPaintable
{
GObject parent_instance;
GskGLShader *shader;
GBytes *args;
gint64 start_time;
};
struct _GskShaderPaintableClass
{
GObjectClass parent_class;
};
enum {
PROP_0,
PROP_SHADER,
PROP_ARGS,
N_PROPS,
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gsk_shader_paintable_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (paintable);
gtk_snapshot_push_gl_shader (snapshot, self->shader, &GRAPHENE_RECT_INIT(0, 0, width, height), g_bytes_ref (self->args));
gtk_snapshot_pop (snapshot);
}
static void
gsk_shader_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gsk_shader_paintable_paintable_snapshot;
}
G_DEFINE_TYPE_EXTENDED (GskShaderPaintable, gsk_shader_paintable, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gsk_shader_paintable_paintable_init))
static void
gsk_shader_paintable_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
switch (prop_id)
{
case PROP_SHADER:
gsk_shader_paintable_set_shader (self, g_value_get_object (value));
break;
case PROP_ARGS:
gsk_shader_paintable_set_args (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gsk_shader_paintable_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
switch (prop_id)
{
case PROP_SHADER:
g_value_set_object (value, self->shader);
break;
case PROP_ARGS:
g_value_set_boxed (value, self->args);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gsk_shader_paintable_finalize (GObject *object)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
g_clear_pointer (&self->args, g_bytes_unref);
g_clear_object (&self->shader);
G_OBJECT_CLASS (gsk_shader_paintable_parent_class)->finalize (object);
}
static void
gsk_shader_paintable_class_init (GskShaderPaintableClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gsk_shader_paintable_get_property;
gobject_class->set_property = gsk_shader_paintable_set_property;
gobject_class->finalize = gsk_shader_paintable_finalize;
properties[PROP_SHADER] =
g_param_spec_object ("shader", "Shader", "The shader",
GSK_TYPE_GL_SHADER,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_ARGS] =
g_param_spec_boxed ("args", "Arguments", "The uniform arguments",
G_TYPE_BYTES,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gsk_shader_paintable_init (GskShaderPaintable *self)
{
}
/**
* gsk_shader_paintable_new:
* @shader: (transfer full) (nullable): the shader to use
* @data: (transfer full) (nullable): uniform data
*
* Creates a paintable that uses the @shader to create
* 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
*/
GdkPaintable *
gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data)
{
GdkPaintable *ret;
g_return_val_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader), NULL);
if (shader && !data)
{
int size = gsk_gl_shader_get_args_size (shader);
data = g_bytes_new_take (g_new0 (guchar, size), size);
}
ret = g_object_new (GSK_TYPE_SHADER_PAINTABLE,
"shader", shader,
"args", data,
NULL);
g_clear_object (&shader);
g_clear_pointer (&data, g_bytes_unref);
return ret;
}
/**
* gsk_shader_paintable_set_shader:
* @self: a #GskShaderPaintable
* @shader: the #GskGLShader to use
*
* Sets the shader that the paintable will use
* to create pixels. The shader must not require
* input textures.
*/
void
gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader)
{
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
g_return_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader));
g_return_if_fail (shader == NULL || gsk_gl_shader_get_n_textures (shader) == 0);
if (!g_set_object (&self->shader, shader))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHADER]);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
g_clear_pointer (&self->args, g_bytes_unref);
}
/**
* gsk_shader_paintable_get_shader:
* @self: a #GskShaderPaintable
*
* Returns the shader that the paintable is using.
*
* Returns: (transfer none): the #GskGLShader that is used
*/
GskGLShader *
gsk_shader_paintable_get_shader (GskShaderPaintable *self)
{
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
return self->shader;
}
/**
* gsk_shader_paintable_set_args:
* @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.
*
* Note that the @data should be considered immutable
* after it has been passed to this function.
*/
void
gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data)
{
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
g_return_if_fail (data == NULL || g_bytes_get_size (data) == gsk_gl_shader_get_args_size (self->shader));
g_clear_pointer (&self->args, g_bytes_unref);
if (data)
self->args = g_bytes_ref (data);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ARGS]);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
/**
* gsk_shader_paintable_get_args:
* @self: a #GskShaderPaintable
*
* Returns the uniform data set with
* gsk_shader_paintable_get_args().
*
* Returns: (transfer none): the uniform data
*/
GBytes *
gsk_shader_paintable_get_args (GskShaderPaintable *self)
{
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
return self->args;
}
/**
* gsk_shader_paintable_update_time:
* @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
*
* This function is a convenience wrapper for
* gsk_shader_paintable_set_args() that leaves all
* uniform values unchanged, except for the uniform with
* 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.
*/
void
gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time)
{
GskShaderArgsBuilder *builder;
GBytes *args;
float time;
if (self->start_time == 0)
self->start_time = frame_time;
time = (frame_time - self->start_time) / (float)G_TIME_SPAN_SECOND;
builder = gsk_shader_args_builder_new (self->shader, self->args);
gsk_shader_args_builder_set_float (builder, time_idx, time);
args = gsk_shader_args_builder_free_to_args (builder);
gsk_shader_paintable_set_args (self, args);
g_bytes_unref (args);
}
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#ifndef __GSK_SHADER_PAINTABLE_H__
#define __GSK_SHADER_PAINTABLE_H__
#include <gdk/gdk.h>
#include <gsk/gsk.h>
G_BEGIN_DECLS
#define GSK_TYPE_SHADER_PAINTABLE (gsk_shader_paintable_get_type ())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GskShaderPaintable, gsk_shader_paintable, GSK, SHADER_PAINTABLE, GObject)
GDK_AVAILABLE_IN_ALL
GdkPaintable * gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data);
GDK_AVAILABLE_IN_ALL
GskGLShader * gsk_shader_paintable_get_shader (GskShaderPaintable *self);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader);
GDK_AVAILABLE_IN_ALL
GBytes * gsk_shader_paintable_get_args (GskShaderPaintable *self);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time);
G_END_DECLS
#endif /* __GSK_SHADER_PAINTABLE_H__ */
+3 -3
View File
@@ -764,7 +764,7 @@ gtk_gears_realize (GtkWidget *widget)
glShaderSource(v, 1, &p, NULL);
glCompileShader(v);
glGetShaderInfoLog(v, sizeof msg, NULL, msg);
g_print ("vertex shader info: %s\n", msg);
g_debug ("vertex shader info: %s\n", msg);
/* Compile the fragment shader */
if (gdk_gl_context_get_use_es (context))
@@ -775,7 +775,7 @@ gtk_gears_realize (GtkWidget *widget)
glShaderSource(f, 1, &p, NULL);
glCompileShader(f);
glGetShaderInfoLog(f, sizeof msg, NULL, msg);
g_print ("fragment shader info: %s\n", msg);
g_debug ("fragment shader info: %s\n", msg);
/* Create and link the shader program */
program = glCreateProgram();
@@ -786,7 +786,7 @@ gtk_gears_realize (GtkWidget *widget)
glLinkProgram(program);
glGetProgramInfoLog(program, sizeof msg, NULL, msg);
g_print ("program info: %s\n", msg);
g_debug ("program info: %s\n", msg);
glDeleteShader (v);
glDeleteShader (f);
+264
View File
@@ -0,0 +1,264 @@
#include "gtkshaderbin.h"
typedef struct {
GskGLShader *shader;
GtkStateFlags state;
GtkStateFlags state_mask;
float extra_border;
gboolean compiled;
gboolean compiled_ok;
} ShaderInfo;
struct _GtkShaderBin
{
GtkWidget parent_instance;
GtkWidget *child;
ShaderInfo *active_shader;
GPtrArray *shaders;
guint tick_id;
float time;
float mouse_x, mouse_y;
gint64 first_frame_time;
};
struct _GtkShaderBinClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkShaderBin, gtk_shader_bin, GTK_TYPE_WIDGET)
static void
shader_info_free (ShaderInfo *info)
{
g_object_unref (info->shader);
g_free (info);
}
static void
gtk_shader_bin_finalize (GObject *object)
{
GtkShaderBin *self = GTK_SHADER_BIN (object);
g_ptr_array_free (self->shaders, TRUE);
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->finalize (object);
}
static void
gtk_shader_bin_dispose (GObject *object)
{
GtkShaderBin *self = GTK_SHADER_BIN (object);
g_clear_pointer (&self->child, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->dispose (object);
}
static gboolean
gtk_shader_bin_tick (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer unused)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
gint64 frame_time;
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
if (self->first_frame_time == 0)
self->first_frame_time = frame_time;
self->time = (frame_time - self->first_frame_time) / (float)G_USEC_PER_SEC;
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
motion_cb (GtkEventControllerMotion *controller,
double x,
double y,
GtkShaderBin *self)
{
self->mouse_x = x;
self->mouse_y = y;
}
static void
gtk_shader_bin_init (GtkShaderBin *self)
{
GtkEventController *controller;
self->shaders = g_ptr_array_new_with_free_func ((GDestroyNotify)shader_info_free);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
void
gtk_shader_bin_update_active_shader (GtkShaderBin *self)
{
GtkStateFlags new_state = gtk_widget_get_state_flags (GTK_WIDGET (self));
ShaderInfo *new_shader = NULL;
for (int i = 0; i < self->shaders->len; i++)
{
ShaderInfo *info = g_ptr_array_index (self->shaders, i);
if ((info->state_mask & new_state) == info->state)
{
new_shader = info;
break;
}
}
if (self->active_shader == new_shader)
return;
self->active_shader = new_shader;
self->first_frame_time = 0;
if (self->active_shader)
{
if (self->tick_id == 0)
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
gtk_shader_bin_tick,
NULL, NULL);
}
else
{
if (self->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
self->tick_id = 0;
}
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_shader_bin_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state_flags)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
gtk_shader_bin_update_active_shader (self);
}
void
gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
GtkStateFlags state_mask,
float extra_border)
{
ShaderInfo *info = g_new0 (ShaderInfo, 1);
info->shader = g_object_ref (shader);
info->state = state;
info->state_mask = state_mask;
info->extra_border = extra_border;
g_ptr_array_add (self->shaders, info);
gtk_shader_bin_update_active_shader (self);
}
void
gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child)
{
if (self->child == child)
return;
g_clear_pointer (&self->child, gtk_widget_unparent);
if (child)
{
self->child = child;
gtk_widget_set_parent (child, GTK_WIDGET (self));
}
}
GtkWidget *
gtk_shader_bin_get_child (GtkShaderBin *self)
{
return self->child;
}
static void
gtk_shader_bin_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
if (self->active_shader)
{
if (!self->active_shader->compiled)
{
GtkNative *native = gtk_widget_get_native (widget);
GskRenderer *renderer = gtk_native_get_renderer (native);
GError *error = NULL;
self->active_shader->compiled = TRUE;
self->active_shader->compiled_ok =
gsk_gl_shader_compile (self->active_shader->shader,
renderer, &error);
if (!self->active_shader->compiled_ok)
{
g_warning ("GtkShaderBin failed to compile shader: %s", error->message);
g_error_free (error);
}
}
if (self->active_shader->compiled_ok)
{
float border = self->active_shader->extra_border;
graphene_vec2_t mouse;
graphene_vec2_init (&mouse, self->mouse_x + border, self->mouse_y + border);
gtk_snapshot_push_gl_shader (snapshot, self->active_shader->shader,
&GRAPHENE_RECT_INIT(-border, -border, width+2*border, height+2*border),
gsk_gl_shader_format_args (self->active_shader->shader,
"u_time", self->time,
"u_mouse", &mouse,
NULL));
gtk_widget_snapshot_child (widget, self->child, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot);
gtk_snapshot_pop (snapshot);
return;
}
}
/* Non-shader fallback */
gtk_widget_snapshot_child (widget, self->child, snapshot);
}
static void
gtk_shader_bin_class_init (GtkShaderBinClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gtk_shader_bin_finalize;
object_class->dispose = gtk_shader_bin_dispose;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
widget_class->snapshot = gtk_shader_bin_snapshot;
widget_class->state_flags_changed = gtk_shader_bin_state_flags_changed;
}
GtkWidget *
gtk_shader_bin_new (void)
{
GtkShaderBin *self;
self = g_object_new (GTK_TYPE_SHADER_BIN, NULL);
return GTK_WIDGET (self);
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef __GTK_SHADER_BIN_H__
#define __GTK_SHADER_BIN_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_BIN (gtk_shader_bin_get_type ())
G_DECLARE_FINAL_TYPE (GtkShaderBin, gtk_shader_bin, GTK, SHADER_BIN, GtkWidget)
GtkWidget *gtk_shader_bin_new (void);
void gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
GtkStateFlags state_mask,
float extra_border);
void gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child);
GtkWidget *gtk_shader_bin_get_child (GtkShaderBin *self);
G_END_DECLS
#endif /* __GTK_SHADER_BIN_H__ */
+361
View File
@@ -0,0 +1,361 @@
#include "gtkshaderstack.h"
struct _GtkShaderStack
{
GtkWidget parent_instance;
GskGLShader *shader;
GPtrArray *children;
int current;
int next;
gboolean backwards;
guint tick_id;
float time;
float duration;
gint64 start_time;
};
struct _GtkShaderStackClass
{
GtkWidgetClass parent_class;
};
enum {
PROP_DURATION = 1,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL };
G_DEFINE_TYPE (GtkShaderStack, gtk_shader_stack, GTK_TYPE_WIDGET)
static void
gtk_shader_stack_finalize (GObject *object)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
g_object_unref (self->shader);
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->finalize (object);
}
static void
update_child_visible (GtkShaderStack *self)
{
int i;
for (i = 0; i < self->children->len; i++)
{
GtkWidget *child = g_ptr_array_index (self->children, i);
gtk_widget_set_child_visible (child,
i == self->current || i == self->next);
}
}
static gboolean
transition_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer unused)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
gint64 frame_time;
frame_time = gdk_frame_clock_get_frame_time (clock);
if (self->start_time == 0)
self->start_time = frame_time;
self->time = (frame_time - self->start_time) / (float)G_USEC_PER_SEC;
gtk_widget_queue_draw (widget);
if (self->time >= self->duration)
{
self->current = self->next;
self->next = -1;
update_child_visible (self);
return G_SOURCE_REMOVE;
}
else
return G_SOURCE_CONTINUE;
}
static void
start_transition (GtkShaderStack *self)
{
self->start_time = 0;
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
transition_cb,
NULL, NULL);
}
static void
stop_transition (GtkShaderStack *self)
{
if (self->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
self->tick_id = 0;
}
if (self->next != -1)
self->current = self->next;
self->next = -1;
update_child_visible (self);
}
static void
gtk_shader_stack_dispose (GObject *object)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
stop_transition (self);
g_clear_pointer (&self->children, g_ptr_array_unref);
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->dispose (object);
}
void
gtk_shader_stack_transition (GtkShaderStack *self,
gboolean forward)
{
stop_transition (self);
self->backwards = !forward;
if (self->backwards)
self->next = (self->current + self->children->len - 1) % self->children->len;
else
self->next = (self->current + 1) % self->children->len;
update_child_visible (self);
start_transition (self);
}
static void
gtk_shader_stack_init (GtkShaderStack *self)
{
self->children = g_ptr_array_new_with_free_func ((GDestroyNotify)gtk_widget_unparent);
self->current = -1;
self->next = -1;
self->backwards = FALSE;
self->duration = 1.0;
}
static void
gtk_shader_stack_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
int i;
*minimum = 0;
*natural = 0;
for (i = 0; i < self->children->len; i++)
{
GtkWidget *child = g_ptr_array_index (self->children, i);
int child_min, child_nat;
if (gtk_widget_get_visible (child))
{
gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
}
}
}
static void
gtk_shader_stack_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
GtkAllocation child_allocation;
GtkWidget *child;
int i;
child_allocation.x = 0;
child_allocation.y = 0;
child_allocation.width = width;
child_allocation.height = height;
for (i = 0; i < self->children->len; i++)
{
child = g_ptr_array_index (self->children, i);
if (gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation, -1);
}
}
static void
gtk_shader_stack_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
int width, height;
GtkWidget *current, *next;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
current = g_ptr_array_index (self->children, self->current);
if (self->next == -1)
{
gtk_widget_snapshot_child (widget, current, snapshot);
}
else
{
GtkNative *native = gtk_widget_get_native (widget);
GskRenderer *renderer = gtk_native_get_renderer (native);
float progress;
next = g_ptr_array_index (self->children, self->next);
progress = self->time / self->duration;
if (self->backwards)
{
GtkWidget *tmp = next;
next = current;
current = tmp;
progress = 1. - progress;
}
if (gsk_gl_shader_compile (self->shader, renderer, NULL))
{
gtk_snapshot_push_gl_shader (snapshot,
self->shader,
&GRAPHENE_RECT_INIT(0, 0, width, height),
gsk_gl_shader_format_args (self->shader,
"progress", progress,
NULL));
gtk_widget_snapshot_child (widget, current, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot); /* current child */
gtk_widget_snapshot_child (widget, next, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot); /* next child */
gtk_snapshot_pop (snapshot);
}
else
{
/* Non-shader fallback */
gtk_widget_snapshot_child (widget, current, snapshot);
}
}
}
static void
gtk_shader_stack_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
switch (prop_id)
{
case PROP_DURATION:
g_value_set_float (value, self->duration);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shader_stack_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
switch (prop_id)
{
case PROP_DURATION:
self->duration = g_value_get_float (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shader_stack_class_init (GtkShaderStackClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gtk_shader_stack_finalize;
object_class->dispose = gtk_shader_stack_dispose;
object_class->get_property = gtk_shader_stack_get_property;
object_class->set_property = gtk_shader_stack_set_property;
widget_class->snapshot = gtk_shader_stack_snapshot;
widget_class->measure = gtk_shader_stack_measure;
widget_class->size_allocate = gtk_shader_stack_size_allocate;
properties[PROP_DURATION] =
g_param_spec_float ("duration", "Duration", "Duration",
0.1, 3.0, 1.0,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
}
GtkWidget *
gtk_shader_stack_new (void)
{
return g_object_new (GTK_TYPE_SHADER_STACK, NULL);
}
void
gtk_shader_stack_set_shader (GtkShaderStack *self,
GskGLShader *shader)
{
g_set_object (&self->shader, shader);
}
void
gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child)
{
g_ptr_array_add (self->children, child);
gtk_widget_set_parent (child, GTK_WIDGET (self));
gtk_widget_queue_resize (GTK_WIDGET (self));
if (self->current == -1)
self->current = 0;
else
gtk_widget_set_child_visible (child, FALSE);
}
void
gtk_shader_stack_set_active (GtkShaderStack *self,
int index)
{
stop_transition (self);
self->current = MIN (index, self->children->len);
update_child_visible (self);
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef __GTK_SHADER_STACK_H__
#define __GTK_SHADER_STACK_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_STACK (gtk_shader_stack_get_type ())
G_DECLARE_FINAL_TYPE (GtkShaderStack, gtk_shader_stack, GTK, SHADER_STACK, GtkWidget)
GtkWidget * gtk_shader_stack_new (void);
void gtk_shader_stack_set_shader (GtkShaderStack *self,
GskGLShader *shader);
void gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child);
void gtk_shader_stack_transition (GtkShaderStack *self,
gboolean forward);
void gtk_shader_stack_set_active (GtkShaderStack *self,
int index);
G_END_DECLS
#endif /* __GTK_SHADER_STACK_H__ */
+4 -2
View File
@@ -56,13 +56,15 @@ const char *fragment_prefix =
"uniform float iSampleRate; // sound sample rate (i.e., 44100)\n"
"\n"
"in vec2 fragCoord;\n"
"out vec4 fragColor;\n";
"out vec4 vFragColor;\n";
// Fragment shader suffix
const char *fragment_suffix =
" void main() {\n"
" mainImage(fragColor, fragCoord);\n"
" vec4 c;\n"
" mainImage(c, fragCoord);\n"
" vFragColor = c;\n"
" }\n";
typedef struct {
+41
View File
@@ -0,0 +1,41 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/kaleidoscope
// Author: nwoeanhinnogaehr
// License: MIT
const float speed = 1.0;
const float angle = 1.0;
const float power = 1.5;
vec4 transition(vec2 uv) {
vec2 p = uv.xy / vec2(1.0).xy;
vec2 q = p;
float t = pow(progress, power)*speed;
p = p -0.5;
for (int i = 0; i < 7; i++) {
p = vec2(sin(t)*p.x + cos(t)*p.y, sin(t)*p.y - cos(t)*p.x);
t += angle;
p = abs(mod(p, 2.0) - 1.0);
}
abs(mod(p, 1.0));
return mix(
mix(getFromColor(q), getToColor(q), progress),
mix(getFromColor(p), getToColor(p), progress), 1.0 - 2.0*abs(progress - 0.5));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
+374
View File
@@ -0,0 +1,374 @@
/* Lists/Characters
*
* This demo shows a multi-column representation of some parts
* of the Unicode Character Database, or UCD.
*
* The dataset used here has 33796 items.
*/
#include <gtk/gtk.h>
#include "script-names.h"
#include "unicode-names.h"
#define UCD_TYPE_ITEM (ucd_item_get_type ())
G_DECLARE_FINAL_TYPE (UcdItem, ucd_item, UCD, ITEM, GObject)
struct _UcdItem
{
GObject parent_instance;
gunichar codepoint;
const char *name;
};
struct _UcdItemClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE (UcdItem, ucd_item, G_TYPE_OBJECT)
static void
ucd_item_init (UcdItem *item)
{
}
static void
ucd_item_class_init (UcdItemClass *class)
{
}
static UcdItem *
ucd_item_new (gunichar codepoint,
const char *name)
{
UcdItem *item;
item = g_object_new (UCD_TYPE_ITEM, NULL);
item->codepoint = codepoint;
item->name = name;
return item;
}
static gunichar
ucd_item_get_codepoint (UcdItem *item)
{
return item->codepoint;
}
static const char *
ucd_item_get_name (UcdItem *item)
{
return item->name;
}
static GListModel *
ucd_model_new (void)
{
GBytes *bytes;
GVariant *v;
GVariantIter *iter;
GListStore *store;
guint u;
char *name;
bytes = g_resources_lookup_data ("/listview_ucd_data/ucdnames.data", 0, NULL);
v = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(us)"), bytes, TRUE));
iter = g_variant_iter_new (v);
store = g_list_store_new (G_TYPE_OBJECT);
while (g_variant_iter_next (iter, "(us)", &u, &name))
{
if (u == 0)
continue;
UcdItem *item = ucd_item_new (u, name);
g_list_store_append (store, item);
g_object_unref (item);
}
g_variant_iter_free (iter);
g_variant_unref (v);
g_bytes_unref (bytes);
return G_LIST_MODEL (store);
}
static void
setup_centered_label (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
label = gtk_label_new ("");
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
}
static void
setup_label (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
}
static void
setup_ellipsizing_label (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_width_chars (GTK_LABEL (label), 20);
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
}
static void
bind_codepoint (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
GObject *item;
gunichar codepoint;
char buffer[16] = { 0, };
label = gtk_list_item_get_child (GTK_LIST_ITEM (listitem));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
g_snprintf (buffer, 10, "%#06x", codepoint);
gtk_label_set_label (GTK_LABEL (label), buffer);
}
static void
bind_char (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
GObject *item;
gunichar codepoint;
char buffer[16] = { 0, };
label = gtk_list_item_get_child (GTK_LIST_ITEM (listitem));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
if (g_unichar_isprint (codepoint))
g_unichar_to_utf8 (codepoint, buffer);
gtk_label_set_label (GTK_LABEL (label), buffer);
}
static void
bind_name (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
GObject *item;
const char *name;
label = gtk_list_item_get_child (GTK_LIST_ITEM (listitem));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
name = ucd_item_get_name (UCD_ITEM (item));
gtk_label_set_label (GTK_LABEL (label), name);
}
static void
bind_type (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
GObject *item;
gunichar codepoint;
label = gtk_list_item_get_child (GTK_LIST_ITEM (listitem));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
gtk_label_set_label (GTK_LABEL (label), get_unicode_type_name (g_unichar_type (codepoint)));
}
static void
bind_break_type (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
GObject *item;
gunichar codepoint;
label = gtk_list_item_get_child (GTK_LIST_ITEM (listitem));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
gtk_label_set_label (GTK_LABEL (label), get_break_type_name (g_unichar_break_type (codepoint)));
}
static void
bind_combining_class (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
GObject *item;
gunichar codepoint;
label = gtk_list_item_get_child (GTK_LIST_ITEM (listitem));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
gtk_label_set_label (GTK_LABEL (label), get_combining_class_name (g_unichar_combining_class (codepoint)));
}
static void
bind_script (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
GObject *item;
gunichar codepoint;
GUnicodeScript script;
label = gtk_list_item_get_child (GTK_LIST_ITEM (listitem));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
script = g_unichar_get_script (codepoint);
gtk_label_set_label (GTK_LABEL (label), get_script_name (script));
}
static void
selection_changed (GObject *object,
GParamSpec *pspec,
GtkWidget *label)
{
UcdItem *item;
guint codepoint;
char buffer[16] = { 0, };
item = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (object));
codepoint = ucd_item_get_codepoint (item);
if (g_unichar_isprint (codepoint))
g_unichar_to_utf8 (codepoint, buffer);
gtk_label_set_label (GTK_LABEL (label), buffer);
}
static GtkWidget *
create_ucd_view (GtkWidget *label)
{
GtkWidget *cv;
GListModel *ucd_model;
GtkSingleSelection *selection;
GtkListItemFactory *factory;
GtkColumnViewColumn *column;
ucd_model = ucd_model_new ();
selection = gtk_single_selection_new (ucd_model);
gtk_single_selection_set_autoselect (selection, TRUE);
gtk_single_selection_set_can_unselect (selection, FALSE);
g_signal_connect (selection, "notify::selected", G_CALLBACK (selection_changed), label);
cv = gtk_column_view_new (GTK_SELECTION_MODEL (selection));
gtk_column_view_set_show_column_separators (GTK_COLUMN_VIEW (cv), TRUE);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_centered_label), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_codepoint), NULL);
column = gtk_column_view_column_new ("Codepoint", factory);
gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_centered_label), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_char), NULL);
column = gtk_column_view_column_new ("Char", factory);
gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_ellipsizing_label), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_name), NULL);
column = gtk_column_view_column_new ("Name", factory);
gtk_column_view_column_set_resizable (column, TRUE);
gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_ellipsizing_label), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_type), NULL);
column = gtk_column_view_column_new ("Type", factory);
gtk_column_view_column_set_resizable (column, TRUE);
gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_ellipsizing_label), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_break_type), NULL);
column = gtk_column_view_column_new ("Break Type", factory);
gtk_column_view_column_set_resizable (column, TRUE);
gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_label), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_combining_class), NULL);
column = gtk_column_view_column_new ("Combining Class", factory);
gtk_column_view_column_set_resizable (column, TRUE);
gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_label), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_script), NULL);
column = gtk_column_view_column_new ("Script", factory);
gtk_column_view_column_set_resizable (column, TRUE);
gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);
return cv;
}
static GtkWidget *window;
GtkWidget *
do_listview_ucd (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *listview, *sw;
GtkWidget *box, *label;
GtkCssProvider *provider;
window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 800, 400);
gtk_window_set_title (GTK_WINDOW (window), "Characters");
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
label = gtk_label_new ("");
gtk_label_set_width_chars (GTK_LABEL (label), 2);
gtk_widget_add_css_class (label, "enormous");
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, "label.enormous { font-size: 80px; }", -1);
gtk_style_context_add_provider (gtk_widget_get_style_context (label), GTK_STYLE_PROVIDER (provider), 800);
gtk_widget_set_hexpand (label, TRUE);
gtk_box_append (GTK_BOX (box), label);
sw = gtk_scrolled_window_new ();
gtk_scrolled_window_set_propagate_natural_width (GTK_SCROLLED_WINDOW (sw), TRUE);
listview = create_ucd_view (label);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
gtk_box_prepend (GTK_BOX (box), sw);
gtk_window_set_child (GTK_WINDOW (window), box);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+2 -1
View File
@@ -391,7 +391,7 @@ display_nothing (const char *resource)
GtkWidget *widget;
char *str;
str = g_strdup_printf ("The lazy GTK developers forgot to add a way to display the resource '%s'", resource);
str = g_strdup_printf ("The contents of the resource at '%s' cannot be displayed", resource);
widget = gtk_label_new (str);
gtk_label_set_wrap (GTK_LABEL (widget), TRUE);
@@ -410,6 +410,7 @@ static struct {
{ ".gif", NULL, display_image },
{ ".jpg", NULL, display_image },
{ ".png", NULL, display_image },
{ ".svg", NULL, display_image },
{ ".c", "c", display_text },
{ ".css", "css", display_text },
{ ".glsl", NULL, display_text },
+13 -2
View File
@@ -32,6 +32,7 @@ demos = files([
'gears.c',
'gestures.c',
'glarea.c',
'gltransition.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
@@ -102,7 +103,10 @@ extra_demo_sources = files(['main.c',
'gtkfishbowl.c',
'fontplane.c',
'gtkgears.c',
'gtkshaderbin.c',
'gtkshadertoy.c',
'gtkshaderstack.c',
'gskshaderpaintable.c',
'puzzlepiece.c',
'bluroverlay.c',
'demoimage.c',
@@ -117,8 +121,8 @@ extra_demo_sources = files(['main.c',
'demo3widget.c'])
if harfbuzz_dep.found() and pangoft_dep.found()
demos += files('font_features.c')
extra_demo_sources += files(['script-names.c', 'language-names.c'])
demos += files(['font_features.c', 'listview_ucd.c'])
extra_demo_sources += files(['script-names.c', 'language-names.c', 'unicode-names.c'])
gtkdemo_deps += [ harfbuzz_dep, epoxy_dep ]
endif
@@ -126,6 +130,13 @@ if os_unix
demos += files('pagesetup.c')
endif
librsvg_dep = dependency('librsvg-2.0', version: '>= 2.46.0', required: false)
if librsvg_dep.found()
demos += files('paintable_svg.c')
gtkdemo_deps += [ librsvg_dep ]
endif
gtkdemo_args = [ '-DGDK_DISABLE_DEPRECATED', '-DGTK_DISABLE_DEPRECATED', ]
demos_h = custom_target('gtk4 demo header',
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="43.000351" x2="85.000351" y1="39.000164" y2="39.000164">
<stop offset="0" stop-color="#26a269"/>
<stop offset="0.0934161" stop-color="#84e3b7"/>
<stop offset="0.330831" stop-color="#26a269"/>
<stop offset="0.686952" stop-color="#26a269"/>
<stop offset="0.89736" stop-color="#175e3c"/>
<stop offset="1" stop-color="#26a269"/>
</linearGradient>
<linearGradient id="b" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#c0bfbc"/>
<stop offset="0.154754" stop-color="#ffffff"/>
<stop offset="0.433722" stop-color="#bdbbb5"/>
<stop offset="0.650505" stop-color="#c1c0ba"/>
<stop offset="0.825253" stop-color="#ffffff"/>
<stop offset="1" stop-color="#c0bfbc"/>
</linearGradient>
<linearGradient id="c" gradientTransform="matrix(0.0811899 -0.046875 0.069079 0.119648 307.03142 127.069456)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
<linearGradient id="d" gradientTransform="matrix(-0.0811899 -0.046875 -0.069079 0.119648 -177.242852 127.069447)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
<linearGradient id="e" gradientUnits="userSpaceOnUse" x1="14" x2="56" y1="94.999964" y2="94.999964">
<stop offset="0" stop-color="#813d9c"/>
<stop offset="0.109119" stop-color="#b378ca"/>
<stop offset="0.241583" stop-color="#813d9c"/>
<stop offset="0.731841" stop-color="#813d9c"/>
<stop offset="0.872163" stop-color="#4d255d"/>
<stop offset="1" stop-color="#813d9c"/>
</linearGradient>
<linearGradient id="f" gradientUnits="userSpaceOnUse" x1="72" x2="114" y1="94.999964" y2="94.999964">
<stop offset="0" stop-color="#e66100"/>
<stop offset="0.0678478" stop-color="#ff903e"/>
<stop offset="0.168852" stop-color="#e66100"/>
<stop offset="0.886626" stop-color="#e66100"/>
<stop offset="1" stop-color="#9d4200"/>
</linearGradient>
<clipPath id="g">
<rect height="128" width="128"/>
</clipPath>
<clipPath id="h">
<rect height="128" width="128"/>
</clipPath>
<filter id="i" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="j">
<g clip-path="url(#h)" filter="url(#i)">
<g clip-path="url(#g)">
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
</g>
</g>
</mask>
<mask id="k">
<g filter="url(#i)">
<rect fill-opacity="0.8" height="128" width="128"/>
</g>
</mask>
<linearGradient id="l" gradientTransform="matrix(0 0.37 -0.98462 0 295.38501 -30.360001)" gradientUnits="userSpaceOnUse" x1="300" x2="428" y1="235" y2="235">
<stop offset="0" stop-color="#f9f06b"/>
<stop offset="1" stop-color="#f5c211"/>
</linearGradient>
<clipPath id="m">
<rect height="128" width="128"/>
</clipPath>
<clipPath id="n">
<rect height="128" width="128"/>
</clipPath>
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
<g clip-path="url(#n)" mask="url(#j)">
<g clip-path="url(#m)" mask="url(#k)">
<path d="m 128 80.640625 v 47.359375 h -128 v -47.359375 z m 0 0" fill="url(#l)"/>
<path d="m 13.308594 80.640625 l 47.355468 47.359375 h 21.214844 l -47.359375 -47.359375 z m 42.421875 0 l 47.363281 47.359375 h 21.214844 l -47.363282 -47.359375 z m 42.429687 0 l 29.839844 29.839844 v -21.210938 l -8.628906 -8.628906 z m -98.160156 7.90625 v 21.214844 l 18.238281 18.238281 h 21.214844 z m 0 0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

+241
View File
@@ -0,0 +1,241 @@
/* Paintable/SVG
*
* This demo shows wrapping a librsvg RsvgHandle in a GdkPaintable
* to display an SVG image that can be scaled by resizing the window.
*
* This demo relies on librsvg, which GTK itself does not link against.
*/
#include <gtk/gtk.h>
#include <librsvg/rsvg.h>
#define SVG_TYPE_PAINTABLE (svg_paintable_get_type ())
G_DECLARE_FINAL_TYPE (SvgPaintable, svg_paintable, SVG, PAINTABLE, GObject)
struct _SvgPaintable
{
GObject parent_instance;
GFile *file;
RsvgHandle *handle;
};
struct _SvgPaintableClass
{
GObjectClass parent_class;
};
enum {
PROP_FILE = 1,
NUM_PROPERTIES
};
static void
svg_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
SvgPaintable *self = SVG_PAINTABLE (paintable);
cairo_t *cr;
GError *error = NULL;
cr = gtk_snapshot_append_cairo (GTK_SNAPSHOT (snapshot),
&GRAPHENE_RECT_INIT (0, 0, width, height));
if (!rsvg_handle_render_document (self->handle, cr,
&(RsvgRectangle) {0, 0, width, height},
&error))
{
g_error ("%s", error->message);
}
cairo_destroy (cr);
}
static int
svg_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
SvgPaintable *self = SVG_PAINTABLE (paintable);
RsvgDimensionData data;
rsvg_handle_get_dimensions (self->handle, &data);
return data.width;
}
static int
svg_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
SvgPaintable *self = SVG_PAINTABLE (paintable);
RsvgDimensionData data;
rsvg_handle_get_dimensions (self->handle, &data);
return data.height;
}
static void
svg_paintable_init_interface (GdkPaintableInterface *iface)
{
iface->snapshot = svg_paintable_snapshot;
iface->get_intrinsic_width = svg_paintable_get_intrinsic_width;
iface->get_intrinsic_height = svg_paintable_get_intrinsic_height;
}
G_DEFINE_TYPE_WITH_CODE (SvgPaintable, svg_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
svg_paintable_init_interface))
static void
svg_paintable_init (SvgPaintable *self)
{
}
static void
svg_paintable_dispose (GObject *object)
{
SvgPaintable *self = SVG_PAINTABLE (object);
g_clear_object (&self->file);
g_clear_object (&self->handle);
G_OBJECT_CLASS (svg_paintable_parent_class)->dispose (object);
}
static void
svg_paintable_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SvgPaintable *self = SVG_PAINTABLE (object);
switch (prop_id)
{
case PROP_FILE:
{
GFile *file = g_value_get_object (value);
RsvgHandle *handle = rsvg_handle_new_from_gfile_sync (file,
RSVG_HANDLE_FLAGS_NONE,
NULL,
NULL);
rsvg_handle_set_dpi (handle, 90);
g_set_object (&self->file, file);
g_set_object (&self->handle, handle);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
svg_paintable_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SvgPaintable *self = SVG_PAINTABLE (object);
switch (prop_id)
{
case PROP_FILE:
g_value_set_object (value, self->file);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
svg_paintable_class_init (SvgPaintableClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = svg_paintable_dispose;
object_class->set_property = svg_paintable_set_property;
object_class->get_property = svg_paintable_get_property;
g_object_class_install_property (object_class, PROP_FILE,
g_param_spec_object ("file", "File", "File",
G_TYPE_FILE,
G_PARAM_READWRITE));
}
static SvgPaintable *
svg_paintable_new (GFile *file)
{
return g_object_new (SVG_TYPE_PAINTABLE,
"file", file,
NULL);
}
static void
file_set (GtkFileChooserButton *button,
GtkWidget *picture)
{
GFile *file;
SvgPaintable *paintable;
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
paintable = svg_paintable_new (file);
gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (paintable));
g_object_unref (paintable);
g_object_unref (file);
}
static GtkWidget *window;
GtkWidget *
do_paintable_svg (GtkWidget *do_widget)
{
GtkWidget *header;
GtkWidget *picture;
GtkFileFilter *filter;
GtkWidget *button;
GFile *file;
SvgPaintable *paintable;
if (!window)
{
window = gtk_window_new ();
header = gtk_header_bar_new ();
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_default_size (GTK_WINDOW (window), 300, 200);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
button = gtk_file_chooser_button_new ("Select an SVG file", GTK_FILE_CHOOSER_ACTION_OPEN);
filter = gtk_file_filter_new ();
gtk_file_filter_add_mime_type (filter, "image/svg+xml");
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (button), filter);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
picture = gtk_picture_new ();
gtk_picture_set_can_shrink (GTK_PICTURE (picture), TRUE);
gtk_widget_set_size_request (picture, 16, 16);
g_signal_connect (button, "file-set", G_CALLBACK (file_set), picture);
gtk_window_set_child (GTK_WINDOW (window), picture);
file = g_file_new_for_uri ("resource:///paintable_svg/org.gtk.gtk4.NodeEditor.Devel.svg");
paintable = svg_paintable_new (file);
gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (paintable));
g_object_unref (paintable);
g_object_unref (file);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+34
View File
@@ -0,0 +1,34 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/Radial
// License: MIT
// Author: Xaychru
const float smoothness = 1.0;
const float PI = 3.141592653589;
vec4 transition(vec2 p) {
vec2 rp = p*2.-1.;
return mix(
getToColor(p),
getFromColor(p),
smoothstep(0., smoothness, atan(rp.y,rp.x) - (progress-.5) * PI * 2.5)
);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
+43
View File
@@ -0,0 +1,43 @@
uniform float u_time;
uniform vec2 u_mouse;
uniform sampler2D u_texture1;
#define PI 3.141592654
float decay(float v, float t)
{
return v * (1.0 / (1.0 + t*t));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
// Temporary to loop time every 1 sec
float time = u_time;
// we normalize all the effects according to the min height/width
float size = min(resolution.x, resolution.y);
// Animate one wave over size in 0.3 sec
float wave_speed = size / 0.3;
float wave_length = size / 1.0;
float wave_height = size * 0.1;
vec2 center = u_mouse;
vec2 direction_from_center = fragCoord - center;
float distance_from_center = length(direction_from_center);
/* Normalize direction */
direction_from_center = direction_from_center / distance_from_center;
float propagation_length = time * wave_speed;
float t = (propagation_length - distance_from_center) / wave_length;
float offset_magnitude = 0;
if (t > 0.0)
offset_magnitude = decay(wave_height * sin(t * 2.0 * PI), t);
vec2 offset = direction_from_center * min(offset_magnitude, distance_from_center);
vec2 source = fragCoord - offset;
vec2 uv2 = source / resolution;
fragColor = GskTexture(u_texture1, vec2(uv2.x, 1.0-uv2.y));
}
+42 -7
View File
@@ -91,7 +91,7 @@ static struct {
{ G_UNICODE_SCRIPT_LYDIAN, HB_SCRIPT_LYDIAN, NC_("Script", "Lydian") },
{ G_UNICODE_SCRIPT_AVESTAN, HB_SCRIPT_AVESTAN, NC_("Script", "Avestan") },
{ G_UNICODE_SCRIPT_BAMUM, HB_SCRIPT_BAMUM, NC_("Script", "Bamum") },
{ G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS, HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, NC_("Script", "Egyptian Hieroglpyhs") },
{ G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS, HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, NC_("Script", "Egyptian Hieroglyphs") },
{ G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC, HB_SCRIPT_IMPERIAL_ARAMAIC, NC_("Script", "Imperial Aramaic") },
{ G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI, HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, NC_("Script", "Inscriptional Pahlavi") },
{ G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN, HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, NC_("Script", "Inscriptional Parthian") },
@@ -119,7 +119,7 @@ static struct {
{ G_UNICODE_SCRIPT_DUPLOYAN, HB_SCRIPT_DUPLOYAN, NC_("Script", "Duployan") },
{ G_UNICODE_SCRIPT_ELBASAN, HB_SCRIPT_ELBASAN, NC_("Script", "Elbasan") },
{ G_UNICODE_SCRIPT_GRANTHA, HB_SCRIPT_GRANTHA, NC_("Script", "Grantha") },
{ G_UNICODE_SCRIPT_KHOJKI, HB_SCRIPT_KHOJKI, NC_("Script", "Kjohki") },
{ G_UNICODE_SCRIPT_KHOJKI, HB_SCRIPT_KHOJKI, NC_("Script", "Khojki") },
{ G_UNICODE_SCRIPT_KHUDAWADI, HB_SCRIPT_KHUDAWADI, NC_("Script", "Khudawadi, Sindhi") },
{ G_UNICODE_SCRIPT_LINEAR_A, HB_SCRIPT_LINEAR_A, NC_("Script", "Linear A") },
{ G_UNICODE_SCRIPT_MAHAJANI, HB_SCRIPT_MAHAJANI, NC_("Script", "Mahajani") },
@@ -149,10 +149,40 @@ static struct {
{ G_UNICODE_SCRIPT_NEWA, HB_SCRIPT_NEWA, NC_("Script", "Newa") },
{ G_UNICODE_SCRIPT_OSAGE, HB_SCRIPT_OSAGE, NC_("Script", "Osage") },
{ G_UNICODE_SCRIPT_TANGUT, HB_SCRIPT_TANGUT, NC_("Script", "Tangut") },
{ G_UNICODE_SCRIPT_MASARAM_GONDI, HB_SCRIPT_INVALID, NC_("Script", "Masaram Gondi") },
{ G_UNICODE_SCRIPT_NUSHU, HB_SCRIPT_INVALID, NC_("Script", "Nushu") },
{ G_UNICODE_SCRIPT_SOYOMBO, HB_SCRIPT_INVALID, NC_("Script", "Soyombo") },
{ G_UNICODE_SCRIPT_ZANABAZAR_SQUARE, HB_SCRIPT_INVALID, NC_("Script", "Zanabazar Square") },
{ G_UNICODE_SCRIPT_MASARAM_GONDI, HB_SCRIPT_MASARAM_GONDI, NC_("Script", "Masaram Gondi") },
{ G_UNICODE_SCRIPT_NUSHU, HB_SCRIPT_NUSHU, NC_("Script", "Nushu") },
{ G_UNICODE_SCRIPT_SOYOMBO, HB_SCRIPT_SOYOMBO, NC_("Script", "Soyombo") },
{ G_UNICODE_SCRIPT_ZANABAZAR_SQUARE, HB_SCRIPT_ZANABAZAR_SQUARE, NC_("Script", "Zanabazar Square") },
{ G_UNICODE_SCRIPT_DOGRA, HB_SCRIPT_DOGRA, NC_("Script", "Dogra") },
{ G_UNICODE_SCRIPT_GUNJALA_GONDI, HB_SCRIPT_GUNJALA_GONDI, NC_("Script", "Gunjala Gondi") },
{ G_UNICODE_SCRIPT_HANIFI_ROHINGYA, HB_SCRIPT_HANIFI_ROHINGYA, NC_("Script", "Hanifi Rohingya") },
{ G_UNICODE_SCRIPT_MAKASAR, HB_SCRIPT_MAKASAR, NC_("Script", "Makasar") },
{ G_UNICODE_SCRIPT_MEDEFAIDRIN, HB_SCRIPT_MEDEFAIDRIN, NC_("Script", "Medefaidrin") },
{ G_UNICODE_SCRIPT_OLD_SOGDIAN, HB_SCRIPT_OLD_SOGDIAN, NC_("Script", "Old Sogdian") },
{ G_UNICODE_SCRIPT_SOGDIAN, HB_SCRIPT_SOGDIAN, NC_("Script", "Sogdian") },
#if HB_VERSION_ATLEAST(2,4,0)
{ G_UNICODE_SCRIPT_ELYMAIC, HB_SCRIPT_ELYMAIC, NC_("Script", "Elym") },
{ G_UNICODE_SCRIPT_NANDINAGARI, HB_SCRIPT_NANDINAGARI, NC_("Script", "Nand") },
{ G_UNICODE_SCRIPT_NYIAKENG_PUACHUE_HMONG, HB_SCRIPT_NYIAKENG_PUACHUE_HMONG, NC_("Script", "Rohg") },
{ G_UNICODE_SCRIPT_WANCHO, HB_SCRIPT_WANCHO, NC_("Script", "Wcho") },
#else
{ G_UNICODE_SCRIPT_ELYMAIC, HB_SCRIPT_INVALID, NC_("Script", "Elym") },
{ G_UNICODE_SCRIPT_NANDINAGARI, HB_SCRIPT_INVALID, NC_("Script", "Nand") },
{ G_UNICODE_SCRIPT_NYIAKENG_PUACHUE_HMONG, HB_SCRIPT_INVALID, NC_("Script", "Rohg") },
{ G_UNICODE_SCRIPT_WANCHO, HB_SCRIPT_INVALID, NC_("Script", "Wcho") },
#endif
#if HB_VERSION_ATLEAST(2,6,7)
{ G_UNICODE_SCRIPT_CHORASMIAN, HB_SCRIPT_CHORASMIAN, NC_("Script", "Chorasmian") },
{ G_UNICODE_SCRIPT_DIVES_AKURU, HB_SCRIPT_DIVES_AKURU, NC_("Script", "Dives Akuru") },
{ G_UNICODE_SCRIPT_KHITAN_SMALL_SCRIPT, HB_SCRIPT_KHITAN_SMALL_SCRIPT, NC_("Script", "Khitan small script") },
{ G_UNICODE_SCRIPT_YEZIDI, HB_SCRIPT_YEZIDI, NC_("Script", "Yezidi") },
#else
{ G_UNICODE_SCRIPT_CHORASMIAN, HB_SCRIPT_INVALID, NC_("Script", "Chorasmian") },
{ G_UNICODE_SCRIPT_DIVES_AKURU, HB_SCRIPT_INVALID, NC_("Script", "Dives Akuru") },
{ G_UNICODE_SCRIPT_KHITAN_SMALL_SCRIPT, HB_SCRIPT_INVALID, NC_("Script", "Khitan small script") },
{ G_UNICODE_SCRIPT_YEZIDI, HB_SCRIPT_INVALID, NC_("Script", "Yezidi") },
#endif
};
const char *
@@ -163,7 +193,12 @@ get_script_name (GUnicodeScript script)
for (i = 0; i < G_N_ELEMENTS (scripts); i++)
{
if (scripts[i].script == script)
return g_dpgettext2 (GETTEXT_PACKAGE, "Script", scripts[i].name);
{
if (scripts[i].name)
return g_dpgettext2 (GETTEXT_PACKAGE, "Script", scripts[i].name);
else
return "";
}
}
return NULL;
Binary file not shown.
+174
View File
@@ -0,0 +1,174 @@
#include "unicode-names.h"
const char *
get_unicode_type_name (GUnicodeType type)
{
const char *names[] = {
"Other, Control",
"Other, Format",
"Other, Not Assigned",
"Other, Private Use",
"Other, Surrogate",
"Letter, Lowercase",
"Letter, Modifier",
"Letter, Other",
"Letter, Titlecase",
"Letter, Uppercase",
"Mark, Spacing",
"Mark, Enclosing",
"Mark, Nonspacing",
"Number, Decimal Digit",
"Number, Letter",
"Number, Other",
"Punctuation, Connector",
"Punctuation, Dash",
"Punctuation, Close",
"Punctuation, Final quote",
"Punctuation, Initial quote",
"Punctuation, Other",
"Punctuation, Open",
"Symbol, Currency",
"Symbol, Modifier",
"Symbol, Math",
"Symbol, Other",
"Separator, Line",
"Separator, Paragraph",
"Separator, Space",
};
if (type < G_N_ELEMENTS (names))
return names[type];
return "Unknown";
}
const char *
get_break_type_name (GUnicodeBreakType type)
{
const char *names[] = {
"Mandatory Break",
"Carriage Return",
"Line Feed",
"Attached Characters and Combining Marks",
"Surrogates",
"Zero Width Space",
"Inseparable",
"Non-breaking (\"Glue\")",
"Contingent Break Opportunity",
"Space",
"Break Opportunity After",
"Break Opportunity Before",
"Break Opportunity Before and After",
"Hyphen",
"Nonstarter",
"Opening Punctuation",
"Closing Punctuation",
"Ambiguous Quotation",
"Exclamation/Interrogation",
"Ideographic",
"Numeric",
"Infix Separator (Numeric)",
"Symbols Allowing Break After",
"Ordinary Alphabetic and Symbol Characters",
"Prefix (Numeric)",
"Postfix (Numeric)",
"Complex Content Dependent (South East Asian)",
"Ambiguous (Alphabetic or Ideographic)",
"Unknown",
"Next Line",
"Word Joiner",
"Hangul L Jamo",
"Hangul V Jamo",
"Hangul T Jamo",
"Hangul LV Syllable",
"Hangul LVT Syllable",
"Closing Parenthesis",
"Conditional Japanese Starter",
"Hebrew Letter",
"Regional Indicator",
"Emoji Base",
"Emoji Modifier",
"Zero Width Joiner",
};
if (type < G_N_ELEMENTS (names))
return names[type];
return "Unknown";
}
const char *
get_combining_class_name (int cclass)
{
const char *classes[256] = { 0, };
classes[0] = "Not Reordered";
classes[1] = "Overlay";
classes[7] = "Nukta";
classes[8] = "Kana Voicing";
classes[9] = "Virama";
classes[10] = "CCC10 (Hebrew)";
classes[11] = "CCC11 (Hebrew)";
classes[12] = "CCC12 (Hebrew)";
classes[13] = "CCC13 (Hebrew)";
classes[14] = "CCC14 (Hebrew)";
classes[15] = "CCC15 (Hebrew)";
classes[16] = "CCC16 (Hebrew)";
classes[17] = "CCC17 (Hebrew)";
classes[18] = "CCC18 (Hebrew)";
classes[19] = "CCC19 (Hebrew)";
classes[20] = "CCC20 (Hebrew)";
classes[21] = "CCC21 (Hebrew)";
classes[22] = "CCC22 (Hebrew)";
classes[23] = "CCC23 (Hebrew)";
classes[24] = "CCC24 (Hebrew)";
classes[25] = "CCC25 (Hebrew)";
classes[26] = "CCC26 (Hebrew)";
classes[27] = "CCC27 (Arabic)";
classes[28] = "CCC28 (Arabic)";
classes[29] = "CCC29 (Arabic)";
classes[30] = "CCC30 (Arabic)";
classes[31] = "CCC31 (Arabic)";
classes[32] = "CCC32 (Arabic)";
classes[33] = "CCC33 (Arabic)";
classes[34] = "CCC34 (Arabic)";
classes[35] = "CCC35 (Arabic)";
classes[36] = "CCC36 (Syriac)";
classes[84] = "CCC84 (Telugu)";
classes[85] = "CCC85 (Telugu)";
classes[103] = "CCC103 (Thai)";
classes[107] = "CCC107 (Thai)";
classes[118] = "CCC118 (Lao)";
classes[122] = "CCC122 (Lao)";
classes[129] = "CCC129 (Tibetan)";
classes[130] = "CCC130 (Tibetan)";
classes[133] = "CCC133 (Tibetan)";
classes[200] = "Attached Below Left";
classes[202] = "Attached Below";
classes[214] = "Attached Above";
classes[216] = "Attached Above Right";
classes[218] = "Below Left";
classes[220] = "Below";
classes[222] = "Below Right";
classes[224] = "Left";
classes[226] = "Right";
classes[228] = "Above Left";
classes[230] = "Above";
classes[232] = "Above Right";
classes[233] = "Double Below";
classes[234] = "Double Above";
classes[240] = "Iota Subscript";
classes[255] = "Invalid";
if (cclass < 256 && classes[cclass] != NULL)
return classes[cclass];
return "Unknown";
}
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <glib.h>
const char * get_unicode_type_name (GUnicodeType type);
const char * get_break_type_name (GUnicodeBreakType type);
const char * get_combining_class_name (int cclass);
+33
View File
@@ -0,0 +1,33 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/wind
// Author: gre
// License: MIT
const float size = 0.2;
float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
vec4 transition(vec2 p) {
float r = rand(vec2(0, p.y));
float m = smoothstep(0.0, -size, p.x*(1.0-size) + size*r - (progress * (1.0 + size)));
return mix(getFromColor(p), getToColor(p), m);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
+11 -2
View File
@@ -171,6 +171,8 @@ text_changed (GtkTextBuffer *buffer,
GskRenderNode *node;
char *text;
GBytes *bytes;
GtkTextIter iter;
GtkTextIter start, end;
g_array_remove_range (self->errors, 0, self->errors->len);
text = get_current_text (self->text_buffer);
@@ -208,8 +210,6 @@ text_changed (GtkTextBuffer *buffer,
gtk_picture_set_paintable (GTK_PICTURE (self->picture), NULL);
}
GtkTextIter iter;
gtk_text_buffer_get_start_iter (self->text_buffer, &iter);
while (!gtk_text_iter_is_end (&iter))
@@ -272,6 +272,10 @@ text_changed (GtkTextBuffer *buffer,
gtk_text_iter_forward_char (&iter);
}
gtk_text_buffer_get_bounds (self->text_buffer, &start, &end);
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "no-hyphens",
&start, &end);
}
static gboolean
@@ -898,6 +902,11 @@ node_editor_window_init (NodeEditorWindow *self)
"name", "number",
"foreground-rgba", &(GdkRGBA) { 0.8, 0.52, 0.43, 1},
NULL));
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
"name", "no-hyphens",
"insert-hyphens", FALSE,
NULL));
self->text_buffer = gtk_text_buffer_new (self->tag_table);
g_signal_connect (self->text_buffer, "changed", G_CALLBACK (text_changed), self);
+4 -4
View File
@@ -1398,7 +1398,7 @@ handle_insert (GtkWidget *button, GtkWidget *textview)
const char *id;
const char *text;
id = gtk_buildable_get_name (GTK_BUILDABLE (button));
id = gtk_buildable_get_buildable_id (GTK_BUILDABLE (button));
if (strcmp (id, "toolbutton1") == 0)
text = "";
@@ -1424,7 +1424,7 @@ handle_cutcopypaste (GtkWidget *button, GtkWidget *textview)
clipboard = gtk_widget_get_clipboard (textview);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
id = gtk_buildable_get_name (GTK_BUILDABLE (button));
id = gtk_buildable_get_buildable_id (GTK_BUILDABLE (button));
if (strcmp (id, "cutbutton") == 0)
gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
@@ -1442,7 +1442,7 @@ clipboard_formats_notify (GdkClipboard *clipboard, GdkEvent *event, GtkWidget *b
const char *id;
gboolean has_text;
id = gtk_buildable_get_name (GTK_BUILDABLE (button));
id = gtk_buildable_get_buildable_id (GTK_BUILDABLE (button));
has_text = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_TEXT_BUFFER);
if (strcmp (id, "pastebutton") == 0)
@@ -1455,7 +1455,7 @@ textbuffer_notify_selection (GObject *object, GParamSpec *pspec, GtkWidget *butt
const char *id;
gboolean has_selection;
id = gtk_buildable_get_name (GTK_BUILDABLE (button));
id = gtk_buildable_get_buildable_id (GTK_BUILDABLE (button));
has_selection = gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (object));
if (strcmp (id, "cutbutton") == 0 ||
+3 -2
View File
@@ -517,7 +517,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<child>
<object class="GtkEntry" id="entry2">
<property name="sensitive">0</property>
<property name="invisible-char">•</property>
<property name="text" translatable="yes">entry</property>
</object>
</child>
@@ -528,7 +527,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</style>
<child>
<object class="GtkEntry" id="entry24">
<property name="invisible-char"></property>
<property name="enable-emoji-completion">1</property>
<property name="text" translatable="yes">entry</property>
<property name="hexpand">1</property>
</object>
@@ -1012,6 +1011,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="restrict-to-fill-level">0</property>
<property name="fill-level">75</property>
<property name="digits">-1</property>
<property name="draw-value">1</property>
<property name="halign">end</property>
</object>
</child>
@@ -1024,6 +1024,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="restrict-to-fill-level">0</property>
<property name="fill-level">75</property>
<property name="digits">-1</property>
<property name="draw-value">1</property>
<property name="halign">start</property>
</object>
</child>
-1
View File
@@ -300,7 +300,6 @@ gdk_cairo_rectangle
gdk_cairo_region
gdk_cairo_region_create_from_surface
gdk_cairo_draw_from_gl
gdk_cairo_surface_upload_to_gl
</SECTION>
<SECTION>
+1
View File
@@ -20,6 +20,7 @@
<xi:include href="xml/GskRenderNode.xml" />
<xi:include href="xml/GskRoundedRect.xml" />
<xi:include href="xml/GskTransform.xml" />
<xi:include href="xml/GskGLShader.xml" />
</reference>
<index id="api-index-full">
+51
View File
@@ -48,6 +48,7 @@ GskShadowNode
GskTextNode
GskTextureNode
GskTransformNode
GskGLShaderNode
gsk_render_node_ref
gsk_render_node_unref
GskRenderNodeType
@@ -152,6 +153,11 @@ gsk_blur_node_get_radius
gsk_debug_node_new
gsk_debug_node_get_child
gsk_debug_node_get_message
gsk_gl_shader_node_new
gsk_gl_shader_node_get_n_children
gsk_gl_shader_node_get_child
gsk_gl_shader_node_get_args
gsk_gl_shader_node_get_shader
<SUBSECTION Standard>
GSK_IS_RENDER_NODE
GSK_RENDER_NODE
@@ -177,6 +183,7 @@ GSK_TYPE_SHADOW_NODE
GSK_TYPE_TEXT_NODE
GSK_TYPE_TEXTURE_NODE
GSK_TYPE_TRANSFORM_NODE
GSK_TYPE_GLSHADER_NODE
GskRenderNodeClass
gsk_blend_node_get_type
gsk_blur_node_get_type
@@ -202,6 +209,7 @@ gsk_shadow_node_get_type
gsk_text_node_get_type
gsk_texture_node_get_type
gsk_transform_node_get_type
gsk_gl_shader_node_get_type
GSK_TYPE_BLEND_MODE
<SUBSECTION Standard>
gsk_serialization_error_quark
@@ -266,3 +274,46 @@ gsk_transform_get_type
gsk_transform_new
</SECTION>
<SECTION>
<FILE>GskGLShader</FILE>
GskGLShader
gsk_gl_shader_new_from_bytes
gsk_gl_shader_new_from_resource
gsk_gl_shader_compile
gsk_gl_shader_get_source
gsk_gl_shader_get_n_textures
gsk_gl_shader_get_n_uniforms
gsk_gl_shader_get_uniform_name
gsk_gl_shader_find_uniform_by_name
gsk_gl_shader_get_uniform_type
gsk_gl_shader_get_uniform_offset
gsk_gl_shader_get_args_size
<SUBSECTION Uniform Data>
gsk_gl_shader_get_arg_float
gsk_gl_shader_get_arg_int
gsk_gl_shader_get_arg_uint
gsk_gl_shader_get_arg_bool
gsk_gl_shader_get_arg_vec2
gsk_gl_shader_get_arg_vec3
gsk_gl_shader_get_arg_vec4
gsk_gl_shader_format_args_va
gsk_gl_shader_format_args
<SUBSECTION Shader Args Builder>
GskShaderArgsBuilder
gsk_shader_args_builder_new
gsk_shader_args_builder_to_args
gsk_shader_args_builder_free_to_args
gsk_shader_args_builder_unref
gsk_shader_args_builder_ref
gsk_shader_args_builder_set_float
gsk_shader_args_builder_set_int
gsk_shader_args_builder_set_uint
gsk_shader_args_builder_set_bool
gsk_shader_args_builder_set_vec2
gsk_shader_args_builder_set_vec3
gsk_shader_args_builder_set_vec4
</SECTION>
+1
View File
@@ -1,2 +1,3 @@
gsk_render_node_get_type
gsk_renderer_get_type
gsk_gl_shader_get_type
+24 -26
View File
@@ -555,7 +555,6 @@ gtk_column_view_get_type
<TITLE>GtkColumnViewColumn</TITLE>
GtkColumnViewColumn
gtk_column_view_column_new
gtk_column_view_column_new_with_factory
gtk_column_view_column_get_column_view
gtk_column_view_column_set_factory
gtk_column_view_column_get_factory
@@ -618,16 +617,7 @@ gtk_grid_view_get_type
GtkBuildable
GtkBuildableIface
GtkBuildableParser
gtk_buildable_set_name
gtk_buildable_get_name
gtk_buildable_add_child
gtk_buildable_set_buildable_property
gtk_buildable_construct_child
gtk_buildable_custom_tag_start
gtk_buildable_custom_tag_end
gtk_buildable_custom_finished
gtk_buildable_parser_finished
gtk_buildable_get_internal_child
gtk_buildable_get_buildable_id
<SUBSECTION Standard>
GTK_BUILDABLE
GTK_IS_BUILDABLE
@@ -1040,6 +1030,12 @@ gtk_text_get_tabs
gtk_text_grab_focus_without_selecting
gtk_text_set_extra_menu
gtk_text_get_extra_menu
gtk_text_set_enable_emoji_completion
gtk_text_get_enable_emoji_completion
gtk_text_set_propagate_text_width
gtk_text_get_propagate_text_width
gtk_text_set_truncate_multiline
gtk_text_get_truncate_multiline
<SUBSECTION Private>
gtk_text_get_type
</SECTION>
@@ -2491,8 +2487,6 @@ gtk_scrolled_window_get_has_frame
gtk_scrolled_window_set_has_frame
gtk_scrolled_window_get_kinetic_scrolling
gtk_scrolled_window_set_kinetic_scrolling
gtk_scrolled_window_get_capture_button_press
gtk_scrolled_window_set_capture_button_press
gtk_scrolled_window_get_overlay_scrolling
gtk_scrolled_window_set_overlay_scrolling
gtk_scrolled_window_get_min_content_width
@@ -2792,24 +2786,26 @@ gtk_spin_button_new_with_range
gtk_spin_button_set_adjustment
gtk_spin_button_get_adjustment
gtk_spin_button_set_digits
gtk_spin_button_get_digits
gtk_spin_button_set_increments
gtk_spin_button_get_increments
gtk_spin_button_set_range
gtk_spin_button_get_range
gtk_spin_button_get_value_as_int
gtk_spin_button_set_value
gtk_spin_button_set_update_policy
gtk_spin_button_set_numeric
gtk_spin_button_spin
gtk_spin_button_set_wrap
gtk_spin_button_set_snap_to_ticks
gtk_spin_button_update
gtk_spin_button_get_digits
gtk_spin_button_get_increments
gtk_spin_button_get_numeric
gtk_spin_button_get_range
gtk_spin_button_get_snap_to_ticks
gtk_spin_button_get_update_policy
gtk_spin_button_get_value
gtk_spin_button_set_update_policy
gtk_spin_button_get_update_policy
gtk_spin_button_set_numeric
gtk_spin_button_get_numeric
gtk_spin_button_set_wrap
gtk_spin_button_get_wrap
gtk_spin_button_set_snap_to_ticks
gtk_spin_button_get_snap_to_ticks
gtk_spin_button_set_climb_rate
gtk_spin_button_get_climb_rate
gtk_spin_button_spin
gtk_spin_button_update
GTK_INPUT_ERROR
<SUBSECTION Standard>
GTK_SPIN_BUTTON
@@ -4311,6 +4307,7 @@ gtk_snapshot_push_blend
gtk_snapshot_push_blur
gtk_snapshot_push_shadow
gtk_snapshot_push_debug
gtk_snapshot_push_gl_shader
gtk_snapshot_pop
gtk_snapshot_save
gtk_snapshot_restore
@@ -4752,7 +4749,7 @@ gtk_is_initialized
GTK_PRIORITY_RESIZE
<SUBSECTION>
GtkDebugFlag
GtkDebugFlags
gtk_get_debug_flags
gtk_set_debug_flags
@@ -4939,6 +4936,7 @@ GTK_TYPE_ICON_LOOKUP_FLAGS
GtkIconThemeError
gtk_icon_theme_new
gtk_icon_theme_get_for_display
gtk_icon_theme_get_display
gtk_icon_theme_set_search_path
gtk_icon_theme_get_search_path
gtk_icon_theme_add_search_path
+62 -11
View File
@@ -220,6 +220,18 @@ replace many uses of gtk_container_add() with equivalent container-specific
APIs such as gtk_box_pack_start() or gtk_grid_attach(), and thereby reduce
the amount of work you have to do at the time of the switch.
### Review your use of icon resources
When using icons as resources, the behavior of GTK 4 is different in one
respect: Icons that are directly in $APP_ID/icons/ are treated as unthemed
icons, which also means that symbolic icons are not recolored. If you want
your icon resources to have icon theme semantics, they need to be placed
into theme subdirectories such as $APP_ID/icons/16x16/actions or
$APP_ID/icons/scalable/status.
This location works fine in GTK 3 too, so you can prepare for this change
before switching to GTK 4.
## Changes that need to be done at the time of the switch
This section outlines porting tasks that you need to tackle when
@@ -265,15 +277,22 @@ with surfaces, you may have to change it to call the API in these
interfaces, depending on whether the surface you are dealing with
is a toplevel or a popup.
As part of this reorganization, X11-only concepts such as sticky or
keep-below have been removed. If you need to use them on your X11 windows,
you will have to set the corresponding X11 properties (as specified in the
EWMH) yourself. Subsurfaces are only supported with the Wayland backend,
using gdk_wayland_surface_new_subsurface(). Native and foreign subwindows
are no longer supported. These concepts were complicating the code and
could not be supported across backends.
As part of this reorganization, X11-only concepts such as sticky,
keep-below, urgency, skip-taskbar or window groups have either been
removed or moved to X11 backend api. If you need to use them on your
X11 windows, you will have to use those backend apis or set the
corresponding X11 properties (as specified in the EWMH) yourself.
gdk_window_reparent() is no longer available.
Subsurfaces are only supported with the Wayland backend, using
gdk_wayland_surface_new_subsurface(). Native and foreign subwindows
are no longer supported. These concepts were complicating the code
and could not be supported across backends.
A number of GdkWindow APIs are no longer available. This includes
gdk_window_reparent(), gdk_window_set_geometry_hints(), gdk_window_raise(),
gdk_window_restack(), gdk_window_move(), gdk_window_resize(). If
you need to manually control the position or stacking of your X11
windows, you you will have to use Xlib apis.
A number of minor API cleanups have happened in GdkSurface
as well. For example, gdk_surface_input_shape_combine_region()
@@ -286,9 +305,9 @@ gdk_toplevel_begin_resize().
The %GDK_TOPLEVEL_STATE_ICONIFIED value of the #GdkSurfaceState enumeration
is now %GDK_TOPLEVEL_STATE_MINIMIZED in the #GdkToplevelState enumeration.
The #GdkWindow functions <function>gdk_window_iconify()</function>
and <function>gdk_window_deiconify()</function> have been renamed to
gdk_toplevel_minimize() and gdk_toplevel_present(), respectively.
The #GdkWindow functions gdk_window_iconify() and gdk_window_deiconify()
have been renamed to gdk_toplevel_minimize() and gdk_toplevel_present(),
respectively.
The behavior of the minimization and unminimization operations have
not been changed, and they still require support from the underlying
@@ -447,6 +466,17 @@ GtkButtonBox has been removed. Use a GtkBox instead.
The GtkBox pack-start and -end methods have been replaced by gtk_box_prepend()
and gtk_box_append(). You can also reorder box children as necessary.
### Adapt to GtkWindow API changes
Following the GdkSurface changes, a number of GtkWindow APIs that were
X11-specific have been removed. This includes gtk_window_set_geometry_hints(),
gtk_window_set_gravity(), gtk_window_move(), gtk_window_parse_geometry(),
gtk_window_set_keep_above(), gtk_window_set_keep_below(),
gtk_window_begin_resize_drag(), gtk_window_begin_move_drag().
Most likely, you should just stop using them. In some cases, you can
fall back to using the underlying #GdkToplevel APIS (for example,
gdk_toplevel_begin_resize()).
### Adapt to GtkHeaderBar and GtkActionBar API changes
The gtk_header_bar_set_show_close_button() function has been renamed to
@@ -879,6 +909,15 @@ gtk_search_entry_handle_event() has been dropped and replaced by
gtk_search_entry_set_key_capture_widget() and
gtk_event_controller_key_forward().
### Adapt to GtkScale changes
The default value of #GtkScale:draw-value has been changed to %FALSE.
If you want your scales to draw values, you will have to set this
property explicitly now.
gtk4-builder-tool can help with this conversion, with the --3to4 option
of the simplify command.
### Stop using gtk_window_activate_default()
The handling of default widgets has been changed, and activating
@@ -1041,6 +1080,18 @@ You can replace calls to gtk_dialog_run() by specifying that the
%GTK_DIALOG_MODAL flag, and connecting to the #GtkDialog::response
signal.
### Stop using GtkBuildable API
All the GtkBuildable API was made private, except for the
getter function to retrieve the buildable ID. If you are
using gtk_buildable_get_name() you should replace it with
gtk_buildable_get_buildable_id().
### Adapt to GtkAboutDialog API changes
GtkAboutDialog now directly derives from GtkWindow, the GtkDialog API can no
longer be used on it.
## Changes to consider after the switch
GTK 4 has a number of new features that you may want to take
+3 -7
View File
@@ -1,15 +1,11 @@
if get_option('gtk_doc')
if not meson.version().version_compare('>=0.52.0')
error('Building the GTK documentation requires Meson 0.52.0')
endif
glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
glib_prefix = dependency('glib-2.0').get_variable(pkgconfig: 'prefix', default_value: '/usr')
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
cairo_prefix = dependency('cairo-gobject').get_pkgconfig_variable('prefix')
cairo_prefix = dependency('cairo-gobject').get_variable(pkgconfig: 'prefix', default_value: '/usr')
cairo_docpath = join_paths(cairo_prefix, 'share', 'gtk-doc', 'html', 'cairo')
gdkpixbuf_prefix = dependency('gdk-pixbuf-2.0').get_pkgconfig_variable('prefix')
gdkpixbuf_prefix = dependency('gdk-pixbuf-2.0').get_variable(pkgconfig: 'prefix', default_value: '/usr')
gdkpixbuf_docpath = join_paths(gdkpixbuf_prefix, 'share', 'gtk-doc', 'html', 'gdk-pixbuf')
docpath = join_paths(gtk_datadir, 'gtk-doc', 'html')
+5 -2
View File
@@ -1101,11 +1101,14 @@ create_moveresize_surface (MoveResizeData *mv_resize,
GdkGrabStatus status;
GdkSeat *seat;
GdkDevice *pointer;
GdkRectangle rect = { -100, -100, 1, 1 };
g_assert (mv_resize->moveresize_emulation_surface == NULL);
mv_resize->moveresize_emulation_surface = gdk_surface_new_temp (mv_resize->display, &rect);
mv_resize->moveresize_emulation_surface =
_gdk_broadway_display_create_surface (mv_resize->display,
GDK_SURFACE_TEMP,
NULL,
-100, -100, 1, 1);
gdk_broadway_surface_show (mv_resize->moveresize_emulation_surface, FALSE);
+3 -3
View File
@@ -49,11 +49,11 @@
/**
* SECTION:general
* @Short_description: Library initialization and miscellaneous functions
* @Short_description: Library initialization and versioning
* @Title: General
*
* This section describes the GDK initialization functions and miscellaneous
* utility functions, as well as deprecation facilities.
* This section describes miscellaneous macros and utility functions
* related to library versioning, as well as deprecation facilities.
*
* The GDK and GTK headers annotate deprecated APIs in a way that produces
* compiler warnings if these deprecated APIs are used. The warnings
+5 -3
View File
@@ -141,7 +141,7 @@ gdk_array(is_empty) (const GdkArray *self)
return self->end == self->start;
}
G_GNUC_UNUSED static void
G_GNUC_UNUSED static inline void
gdk_array(reserve) (GdkArray *self,
gsize n)
{
@@ -178,7 +178,7 @@ gdk_array(reserve) (GdkArray *self,
#endif
}
G_GNUC_UNUSED static void
G_GNUC_UNUSED static inline void
gdk_array(splice) (GdkArray *self,
gsize pos,
gsize removed,
@@ -208,8 +208,10 @@ gdk_array(splice) (GdkArray *self,
memcpy (gdk_array(index) (self, pos),
additions,
added * sizeof (_T_));
#ifndef GDK_ARRAY_NO_MEMSET
else
memset (gdk_array(index) (self, pos), 0, added * sizeof (_T_));
#endif
}
@@ -279,5 +281,5 @@ gdk_array(get) (const GdkArray *self,
#undef GDK_ARRAY_NULL_TERMINATED
#undef GDK_ARRAY_PREALLOC
#undef GDK_ARRAY_TYPE_NAME
#undef GDK_ARRAY_NO_MEMSET
#endif
-7
View File
@@ -61,13 +61,6 @@ void gdk_cairo_draw_from_gl (cairo_t *cr,
int width,
int height);
GDK_AVAILABLE_IN_ALL
void gdk_cairo_surface_upload_to_gl (cairo_surface_t *surface,
int target,
int width,
int height,
GdkGLContext *context);
G_END_DECLS
#endif /* __GDK_CAIRO_H__ */
+3 -77
View File
@@ -131,19 +131,6 @@ gdk_display_real_opened (GdkDisplay *display)
_gdk_display_manager_add_display (gdk_display_manager_get (), display);
}
static void
gdk_display_real_event_data_copy (GdkDisplay *display,
GdkEvent *src,
GdkEvent *dst)
{
}
static void
gdk_display_real_event_data_free (GdkDisplay *display,
GdkEvent *dst)
{
}
static GdkSeat *
gdk_display_real_get_default_seat (GdkDisplay *display)
{
@@ -165,8 +152,6 @@ gdk_display_class_init (GdkDisplayClass *class)
class->get_app_launch_context = gdk_display_real_get_app_launch_context;
class->opened = gdk_display_real_opened;
class->make_default = gdk_display_real_make_default;
class->event_data_copy = gdk_display_real_event_data_copy;
class->event_data_free = gdk_display_real_event_data_free;
class->get_default_seat = gdk_display_real_get_default_seat;
/**
@@ -408,13 +393,13 @@ gdk_display_is_closed (GdkDisplay *display)
return display->closed;
}
/**
/*<private>
* gdk_display_get_event:
* @display: a #GdkDisplay
*
*
* Gets the next #GdkEvent to be processed for @display, fetching events from the
* windowing system if necessary.
*
*
* Returns: (nullable) (transfer full): the next #GdkEvent to be processed,
* or %NULL if no events are pending
*/
@@ -429,33 +414,6 @@ gdk_display_get_event (GdkDisplay *display)
return _gdk_event_unqueue (display);
}
/**
* gdk_display_peek_event:
* @display: a #GdkDisplay
*
* Gets a copy of the first #GdkEvent in the @displays event queue, without
* removing the event from the queue. (Note that this function will
* not get more events from the windowing system. It only checks the events
* that have already been moved to the GDK event queue.)
*
* Returns: (nullable) (transfer full): the first #GdkEvent on the
* event queue
**/
GdkEvent *
gdk_display_peek_event (GdkDisplay *display)
{
GList *tmp_list;
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
tmp_list = _gdk_event_queue_find_first (display);
if (tmp_list != NULL)
return gdk_event_ref (tmp_list->data);
return NULL;
}
/**
* gdk_display_put_event:
* @display: a #GdkDisplay
@@ -1113,23 +1071,6 @@ gdk_display_open (const char *display_name)
display_name);
}
/**
* gdk_display_has_pending:
* @display: a #GdkDisplay
*
* Returns whether the display has events that are waiting
* to be processed.
*
* Returns: %TRUE if there are events ready to be processed.
*/
gboolean
gdk_display_has_pending (GdkDisplay *display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
return GDK_DISPLAY_GET_CLASS (display)->has_pending (display);
}
gulong
_gdk_display_get_next_serial (GdkDisplay *display)
{
@@ -1193,21 +1134,6 @@ _gdk_display_unpause_events (GdkDisplay *display)
display->event_pause_count--;
}
void
_gdk_display_event_data_copy (GdkDisplay *display,
GdkEvent *event,
GdkEvent *new_event)
{
GDK_DISPLAY_GET_CLASS (display)->event_data_copy (display, event, new_event);
}
void
_gdk_display_event_data_free (GdkDisplay *display,
GdkEvent *event)
{
GDK_DISPLAY_GET_CLASS (display)->event_data_free (display, event);
}
GdkSurface *
gdk_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
-12
View File
@@ -135,11 +135,6 @@ struct _GdkDisplayClass
const char *startup_id);
const char * (*get_startup_notification_id) (GdkDisplay *display);
void (*event_data_copy) (GdkDisplay *display,
GdkEvent *event,
GdkEvent *new_event);
void (*event_data_free) (GdkDisplay *display,
GdkEvent *event);
GdkSurface * (*create_surface) (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
@@ -208,11 +203,6 @@ void _gdk_display_pointer_info_foreach (GdkDisplay *display
gulong _gdk_display_get_next_serial (GdkDisplay *display);
void _gdk_display_pause_events (GdkDisplay *display);
void _gdk_display_unpause_events (GdkDisplay *display);
void _gdk_display_event_data_copy (GdkDisplay *display,
GdkEvent *event,
GdkEvent *new_event);
void _gdk_display_event_data_free (GdkDisplay *display,
GdkEvent *event);
GdkSurface * gdk_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
@@ -241,8 +231,6 @@ void gdk_display_setting_changed (GdkDisplay *display
const char *name);
GdkEvent * gdk_display_get_event (GdkDisplay *display);
GdkEvent * gdk_display_peek_event (GdkDisplay *display);
gboolean gdk_display_has_pending (GdkDisplay *display);
GdkKeymap * gdk_display_get_keymap (GdkDisplay *display);
-4
View File
@@ -147,10 +147,6 @@ value_event_lcopy_value (const GValue *value,
static void
gdk_event_finalize (GdkEvent *self)
{
GdkDisplay *display = gdk_event_get_display (self);
if (display != NULL)
_gdk_display_event_data_free (display, self);
g_clear_object (&self->surface);
g_clear_object (&self->device);
-48
View File
@@ -438,51 +438,3 @@ out:
if (clip_region)
cairo_region_destroy (clip_region);
}
/**
* gdk_cairo_surface_upload_to_gl:
* @surface: a Cairo surface
* @target: a GL texture target
* @width: the width of the texture @target
* @height: the height of the texture @target
* @context: (nullable): a #GdkGLContext, or %NULL to use the currently
* bound context
*
* Uploads the contents of a Cairo @surface to a GL texture @target.
*/
void
gdk_cairo_surface_upload_to_gl (cairo_surface_t *surface,
int target,
int width,
int height,
GdkGLContext *context)
{
cairo_rectangle_int_t rect;
cairo_surface_t *tmp;
double device_x_offset, device_y_offset;
g_return_if_fail (surface != NULL);
g_return_if_fail (context == NULL || GDK_IS_GL_CONTEXT (context));
if (context == NULL)
context = gdk_gl_context_get_current ();
cairo_surface_flush (surface);
cairo_surface_get_device_offset (surface, &device_x_offset, &device_y_offset);
rect.x = (int) device_x_offset;
rect.y = (int) device_y_offset;
rect.width = width;
rect.height = height;
tmp = cairo_surface_map_to_image (surface, &rect);
gdk_gl_context_upload_texture (context,
cairo_image_surface_get_data (tmp),
rect.width,
rect.height,
cairo_image_surface_get_stride (tmp),
target);
cairo_surface_unmap_image (surface, tmp);
}
+81 -35
View File
@@ -87,6 +87,7 @@
#include "gdkglcontextprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkinternals.h"
#include "gdkintl.h"
@@ -227,49 +228,92 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
int width,
int height,
int stride,
GdkMemoryFormat data_format,
guint texture_target)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
guchar *copy = NULL;
guint gl_format;
guint gl_type;
guint bpp;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (priv->use_es)
{
/* GLES only supports rgba, so convert if necessary */
if (data_format != GDK_MEMORY_R8G8B8A8_PREMULTIPLIED)
{
copy = g_malloc (width * height * 4);
gdk_memory_convert (copy, width * 4,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
data, stride, data_format,
width, height);
stride = width * 4;
data = copy;
}
bpp = 4;
gl_format = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE;
}
else
{
if (data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */
{
gl_format = GL_BGRA;
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
bpp = 4;
}
else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */
{
gl_format = GL_RGB;
gl_type = GL_UNSIGNED_BYTE;
bpp = 3;
}
else /* Fall-back, convert to cairo-surface-format */
{
copy = g_malloc (width * height * 4);
gdk_memory_convert (copy, width * 4,
GDK_MEMORY_DEFAULT,
data, stride, data_format,
width, height);
stride = width * 4;
bpp = 4;
data = copy;
gl_format = GL_BGRA;
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
}
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
* the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
*/
if (!priv->use_es ||
(priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage)))
if (stride == width * bpp)
{
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / 4);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
if (priv->use_es)
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
data);
else
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
data);
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
}
else if ((!priv->use_es ||
(priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage))))
{
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, data);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
}
else
{
int i;
if (priv->use_es)
{
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
for (i = 0; i < height; i++)
glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, data + (i * stride));
}
else
{
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
for (i = 0; i < height; i++)
glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data + (i * stride));
}
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, gl_format, gl_type, NULL);
for (i = 0; i < height; i++)
glTexSubImage2D (texture_target, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
}
g_free (copy);
}
static gboolean
@@ -820,7 +864,6 @@ gdk_gl_context_get_use_es (GdkGLContext *context)
return priv->use_es > 0;
}
#ifdef G_ENABLE_CONSISTENCY_CHECKS
static void
gl_debug_message_callback (GLenum source,
GLenum type,
@@ -911,7 +954,6 @@ gl_debug_message_callback (GLenum source,
g_warning ("OPENGL:\n Source: %s\n Type: %s\n Severity: %s\n Message: %s",
message_source, message_type, message_severity, message);
}
#endif
/**
* gdk_gl_context_realize:
@@ -964,15 +1006,22 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_debug_output = epoxy_has_gl_extension ("GL_ARB_debug_output") ||
epoxy_has_gl_extension ("GL_KHR_debug");
#ifdef G_ENABLE_CONSISTENCY_CHECKS
if (priv->has_debug_output)
#ifdef G_ENABLE_DEBUG
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
gl_debug = GDK_DISPLAY_DEBUG_CHECK (display, GL_DEBUG);
#endif
if (priv->has_debug_output
#ifndef G_ENABLE_CONSISTENCY_CHECKS
&& gl_debug
#endif
)
{
gdk_gl_context_make_current (context);
glEnable (GL_DEBUG_OUTPUT);
glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback (gl_debug_message_callback, NULL);
}
#endif
if (priv->use_es)
{
@@ -995,11 +1044,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->is_legacy = TRUE;
}
#ifdef G_ENABLE_DEBUG
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
gl_debug = GDK_DISPLAY_DEBUG_CHECK (display, GL_DEBUG);
#endif
if (priv->has_khr_debug && gl_debug)
{
priv->use_khr_debug = TRUE;
@@ -1021,6 +1065,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
" - GL_ARB_texture_non_power_of_two: %s\n"
" - GL_ARB_texture_rectangle: %s\n"
" - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %s\n"
"* Using texture rectangle: %s",
priv->use_es ? "OpenGL ES" : "OpenGL",
priv->gl_version / 10, priv->gl_version % 10,
@@ -1029,6 +1074,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
has_npot ? "yes" : "no",
has_texture_rectangle ? "yes" : "no",
priv->has_khr_debug ? "yes" : "no",
priv->has_unpack_subimage ? "yes" : "no",
priv->use_texture_rectangle ? "yes" : "no"));
priv->extensions_checked = TRUE;
+2
View File
@@ -23,6 +23,7 @@
#include "gdkglcontext.h"
#include "gdkdrawcontextprivate.h"
#include "gdkmemorytexture.h"
G_BEGIN_DECLS
@@ -84,6 +85,7 @@ void gdk_gl_context_upload_texture (GdkGLContext
int width,
int height,
int stride,
GdkMemoryFormat data_format,
guint texture_target);
GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext *context);
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
-1
View File
@@ -30,4 +30,3 @@
#include <stdio.h>
guint _gdk_debug_flags = 0;
GList *_gdk_default_filters = NULL;
+20 -11
View File
@@ -38,13 +38,14 @@ struct _GdkMemoryTextureClass
G_DEFINE_TYPE (GdkMemoryTexture, gdk_memory_texture, GDK_TYPE_TEXTURE)
static gsize
gsize
gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
{
switch (format)
{
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
@@ -199,6 +200,9 @@ convert_swizzle ## A ## R ## G ## B (guchar *dest_data, \
}
SWIZZLE(3,2,1,0)
SWIZZLE(2,1,0,3)
SWIZZLE(3,0,1,2)
SWIZZLE(1,2,3,0)
#define SWIZZLE_OPAQUE(A,R,G,B) \
static void \
@@ -267,6 +271,10 @@ SWIZZLE_PREMULTIPLY (3,2,1,0, 3,0,1,2)
SWIZZLE_PREMULTIPLY (0,1,2,3, 3,0,1,2)
SWIZZLE_PREMULTIPLY (3,2,1,0, 0,3,2,1)
SWIZZLE_PREMULTIPLY (0,1,2,3, 0,3,2,1)
SWIZZLE_PREMULTIPLY (3,0,1,2, 3,2,1,0)
SWIZZLE_PREMULTIPLY (3,0,1,2, 0,1,2,3)
SWIZZLE_PREMULTIPLY (3,0,1,2, 3,0,1,2)
SWIZZLE_PREMULTIPLY (3,0,1,2, 0,3,2,1)
typedef void (* ConversionFunc) (guchar *dest_data,
gsize dest_stride,
@@ -275,16 +283,17 @@ typedef void (* ConversionFunc) (guchar *dest_data,
gsize width,
gsize height);
static ConversionFunc converters[GDK_MEMORY_N_FORMATS][2] =
static ConversionFunc converters[GDK_MEMORY_N_FORMATS][3] =
{
{ convert_memcpy, convert_swizzle3210 },
{ convert_swizzle3210, convert_memcpy },
{ convert_swizzle_premultiply_3210_3210, convert_swizzle_premultiply_0123_3210 },
{ convert_swizzle_premultiply_3210_0123, convert_swizzle_premultiply_0123_0123 },
{ convert_swizzle_premultiply_3210_3012, convert_swizzle_premultiply_0123_3012 },
{ convert_swizzle_premultiply_3210_0321, convert_swizzle_premultiply_0123_0321 },
{ convert_swizzle_opaque_3210, convert_swizzle_opaque_0123 },
{ convert_swizzle_opaque_3012, convert_swizzle_opaque_0321 }
{ convert_memcpy, convert_swizzle3210, convert_swizzle2103 },
{ convert_swizzle3210, convert_memcpy, convert_swizzle3012 },
{ convert_swizzle2103, convert_swizzle1230, convert_memcpy },
{ convert_swizzle_premultiply_3210_3210, convert_swizzle_premultiply_0123_3210, convert_swizzle_premultiply_3012_3210, },
{ convert_swizzle_premultiply_3210_0123, convert_swizzle_premultiply_0123_0123, convert_swizzle_premultiply_3012_0123 },
{ convert_swizzle_premultiply_3210_3012, convert_swizzle_premultiply_0123_3012, convert_swizzle_premultiply_3012_3012 },
{ convert_swizzle_premultiply_3210_0321, convert_swizzle_premultiply_0123_0321, convert_swizzle_premultiply_3012_0321 },
{ convert_swizzle_opaque_3210, convert_swizzle_opaque_0123, convert_swizzle_opaque_3012 },
{ convert_swizzle_opaque_3012, convert_swizzle_opaque_0321, convert_swizzle_opaque_3210 }
};
void
@@ -297,7 +306,7 @@ gdk_memory_convert (guchar *dest_data,
gsize width,
gsize height)
{
g_assert (dest_format < 2);
g_assert (dest_format < 3);
g_assert (src_format < GDK_MEMORY_N_FORMATS);
converters[src_format][dest_format] (dest_data, dest_stride, src_data, src_stride, width, height);
+3
View File
@@ -34,6 +34,8 @@ G_BEGIN_DECLS
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: 4 bytes; for alpha, red, green, blue.
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: 4 bytes; for red, green, blue, alpha
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_B8G8R8A8: 4 bytes; for blue, green, red, alpha.
* @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue.
* @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha.
@@ -58,6 +60,7 @@ G_BEGIN_DECLS
typedef enum {
GDK_MEMORY_B8G8R8A8_PREMULTIPLIED,
GDK_MEMORY_A8R8G8B8_PREMULTIPLIED,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
GDK_MEMORY_B8G8R8A8,
GDK_MEMORY_A8R8G8B8,
GDK_MEMORY_R8G8B8A8,
+2
View File
@@ -31,6 +31,8 @@ G_BEGIN_DECLS
#define GDK_MEMORY_CAIRO_FORMAT_ARGB32 GDK_MEMORY_DEFAULT
gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format);
GdkMemoryFormat gdk_memory_texture_get_format (GdkMemoryTexture *self);
const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
+1 -1
View File
@@ -94,7 +94,7 @@ gdk_popup_default_init (GdkPopupInterface *iface)
g_object_interface_install_property (iface,
g_param_spec_boolean ("autohide",
P_("Autohide"),
P_("The parent surface"),
P_("Whether to hide on outside clicks"),
FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+1
View File
@@ -78,6 +78,7 @@ GDK_AVAILABLE_IN_ALL
GList * gdk_seat_get_devices (GdkSeat *seat,
GdkSeatCapabilities capabilities);
GDK_AVAILABLE_IN_ALL
GList * gdk_seat_get_tools (GdkSeat *seat);
GDK_AVAILABLE_IN_ALL
-23
View File
@@ -816,29 +816,6 @@ gdk_surface_new_toplevel (GdkDisplay *display)
NULL, 0, 0, 1, 1);
}
/**
* gdk_surface_new_temp: (constructor)
* @display: the display to create the surface on
* @position: position of the surface on screen
*
* Creates a new temporary surface.
* The surface will bypass surface management.
*
* Returns: (transfer full): the new #GdkSurface
**/
GdkSurface *
gdk_surface_new_temp (GdkDisplay *display,
const GdkRectangle *position)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
g_return_val_if_fail (position != NULL, NULL);
return gdk_surface_new (display, GDK_SURFACE_TEMP,
NULL,
position->x, position->y,
position->width, position->height);
}
/**
* gdk_surface_new_popup: (constructor)
* @parent: the parent surface to attach the surface to
-3
View File
@@ -277,9 +277,6 @@ void gdk_surface_enter_monitor (GdkSurface *surface,
void gdk_surface_leave_monitor (GdkSurface *surface,
GdkMonitor *monitor);
GdkSurface * gdk_surface_new_temp (GdkDisplay *display,
const GdkRectangle *position);
void gdk_surface_destroy_notify (GdkSurface *surface);
void gdk_synthesize_surface_state (GdkSurface *surface,
+17 -24
View File
@@ -130,28 +130,6 @@ gdk_texture_real_download (GdkTexture *self,
GDK_TEXTURE_WARN_NOT_IMPLEMENTED_METHOD (self, download);
}
static cairo_surface_t *
gdk_texture_real_download_surface (GdkTexture *texture)
{
cairo_surface_t *surface;
cairo_status_t surface_status;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
texture->width, texture->height);
surface_status = cairo_surface_status (surface);
if (surface_status != CAIRO_STATUS_SUCCESS)
g_warning ("%s: surface error: %s", __FUNCTION__,
cairo_status_to_string (surface_status));
gdk_texture_download (texture,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_stride (surface));
cairo_surface_mark_dirty (surface);
return surface;
}
static void
gdk_texture_set_property (GObject *gobject,
guint prop_id,
@@ -216,7 +194,6 @@ gdk_texture_class_init (GdkTextureClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
klass->download = gdk_texture_real_download;
klass->download_surface = gdk_texture_real_download_surface;
gobject_class->set_property = gdk_texture_set_property;
gobject_class->get_property = gdk_texture_get_property;
@@ -438,7 +415,23 @@ gdk_texture_get_height (GdkTexture *texture)
cairo_surface_t *
gdk_texture_download_surface (GdkTexture *texture)
{
return GDK_TEXTURE_GET_CLASS (texture)->download_surface (texture);
cairo_surface_t *surface;
cairo_status_t surface_status;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
texture->width, texture->height);
surface_status = cairo_surface_status (surface);
if (surface_status != CAIRO_STATUS_SUCCESS)
g_warning ("%s: surface error: %s", __FUNCTION__,
cairo_status_to_string (surface_status));
gdk_texture_download (texture,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_stride (surface));
cairo_surface_mark_dirty (surface);
return surface;
}
void
-1
View File
@@ -28,7 +28,6 @@ struct _GdkTextureClass {
const GdkRectangle *area,
guchar *data,
gsize stride);
cairo_surface_t * (* download_surface) (GdkTexture *texture);
};
gpointer gdk_texture_new (const GdkTextureClass *klass,
-13
View File
@@ -30,19 +30,6 @@
#include "gdkmacosdisplay-private.h"
#include "gdkmacossurface-private.h"
/* Text Input Client */
#define TIC_MARKED_TEXT "tic-marked-text"
#define TIC_SELECTED_POS "tic-selected-pos"
#define TIC_SELECTED_LEN "tic-selected-len"
#define TIC_INSERT_TEXT "tic-insert-text"
#define TIC_IN_KEY_DOWN "tic-in-key-down"
/* GtkIMContext */
#define GIC_CURSOR_RECT "gic-cursor-rect"
#define GIC_FILTER_KEY "gic-filter-key"
#define GIC_FILTER_PASSTHRU 0
#define GIC_FILTER_FILTERED 1
@implementation GdkMacosBaseView
-(id)initWithFrame:(NSRect)frameRect
+2 -1
View File
@@ -28,6 +28,7 @@
#import "GdkMacosWindow.h"
#include "gdkmacosdisplay-private.h"
#include "gdkmacosmonitor-private.h"
#include "gdkmacossurface-private.h"
#include "gdkmacospopupsurface-private.h"
#include "gdkmacostoplevelsurface-private.h"
@@ -352,7 +353,7 @@
monitor = _gdk_macos_display_get_monitor_at_display_coords ([self gdkDisplay],
currentLocation.x,
currentLocation.y);
gdk_macos_monitor_get_geometry (monitor, &geometry);
gdk_monitor_get_geometry (monitor, &geometry);
gdk_macos_monitor_get_workarea (monitor, &workarea);
_edge_snapping_set_monitor (&self->snapping, &geometry, &workarea);
+2 -1
View File
@@ -28,8 +28,9 @@
#include "gdkmacoscursor-private.h"
#include "gdkmacosdevice.h"
#include "gdkmacosdisplay-private.h"
#include "gdkmacosdevice-private.h"
#include "gdkmacosdisplay-private.h"
#include "gdkmacossurface-private.h"
struct _GdkMacosDevice
{
+14
View File
@@ -30,6 +30,19 @@
G_BEGIN_DECLS
/* Text Input Client */
#define TIC_MARKED_TEXT "tic-marked-text"
#define TIC_SELECTED_POS "tic-selected-pos"
#define TIC_SELECTED_LEN "tic-selected-len"
#define TIC_INSERT_TEXT "tic-insert-text"
#define TIC_IN_KEY_DOWN "tic-in-key-down"
/* GtkIMContext */
#define GIC_CURSOR_RECT "gic-cursor-rect"
#define GIC_FILTER_KEY "gic-filter-key"
#define GIC_FILTER_PASSTHRU 0
#define GIC_FILTER_FILTERED 1
struct _GdkMacosDisplay
{
GdkDisplay parent_instance;
@@ -148,6 +161,7 @@ void _gdk_macos_display_send_button_event (GdkMacosDisp
void _gdk_macos_display_warp_pointer (GdkMacosDisplay *self,
int x,
int y);
NSEvent *_gdk_macos_display_get_nsevent (GdkEvent *event);
G_END_DECLS
+2 -18
View File
@@ -242,7 +242,6 @@ fill_button_event (GdkMacosDisplay *display,
GDK_SURFACE (surface),
gdk_seat_get_pointer (seat),
NULL,
NULL,
get_time_from_ns_event (nsevent),
state,
get_mouse_button_from_ns_event (nsevent),
@@ -283,7 +282,6 @@ synthesize_crossing_event (GdkMacosDisplay *display,
return gdk_crossing_event_new (event_type,
GDK_SURFACE (surface),
gdk_seat_get_pointer (seat),
NULL,
get_time_from_ns_event (nsevent),
state,
x,
@@ -410,7 +408,6 @@ fill_key_event (GdkMacosDisplay *display,
return gdk_key_event_new (type,
GDK_SURFACE (surface),
gdk_seat_get_keyboard (seat),
NULL,
get_time_from_ns_event (nsevent),
[nsevent keyCode],
state,
@@ -526,7 +523,6 @@ fill_pinch_event (GdkMacosDisplay *display,
return gdk_touchpad_event_new_pinch (GDK_SURFACE (surface),
gdk_seat_get_pointer (seat),
NULL,
get_time_from_ns_event (nsevent),
get_keyboard_modifiers_from_ns_event (nsevent),
phase,
@@ -570,7 +566,6 @@ fill_motion_event (GdkMacosDisplay *display,
return gdk_motion_event_new (GDK_SURFACE (surface),
gdk_seat_get_pointer (seat),
NULL,
NULL,
get_time_from_ns_event (nsevent),
state,
x,
@@ -609,21 +604,13 @@ fill_scroll_event (GdkMacosDisplay *self,
double sx;
double sy;
/*
* TODO: We probably need another event type for the
* high precision scroll events since sx and dy
* are in a unit we don't quite support. For now,
* to slow it down multiply by .1.
*/
sx = [nsevent scrollingDeltaX] * .1;
sy = [nsevent scrollingDeltaY] * .1;
sx = [nsevent scrollingDeltaX];
sy = [nsevent scrollingDeltaY];
if (sx != 0.0 || dx != 0.0)
ret = gdk_scroll_event_new (GDK_SURFACE (surface),
pointer,
NULL,
NULL,
get_time_from_ns_event (nsevent),
state,
-sx,
@@ -661,7 +648,6 @@ fill_scroll_event (GdkMacosDisplay *self,
emulated = gdk_scroll_event_new_discrete (GDK_SURFACE (surface),
pointer,
NULL,
NULL,
get_time_from_ns_event (nsevent),
state,
direction,
@@ -675,7 +661,6 @@ fill_scroll_event (GdkMacosDisplay *self,
ret = gdk_scroll_event_new (GDK_SURFACE (surface),
pointer,
NULL,
NULL,
get_time_from_ns_event (nsevent),
state,
dx,
@@ -1188,7 +1173,6 @@ _gdk_macos_display_synthesize_motion (GdkMacosDisplay *self,
event = gdk_motion_event_new (GDK_SURFACE (surface),
gdk_seat_get_pointer (seat),
NULL,
NULL,
get_time_from_ns_event ([NSApp currentEvent]),
state,
x,
+59 -10
View File
@@ -74,7 +74,17 @@
G_DEFINE_TYPE (GdkMacosDisplay, gdk_macos_display, GDK_TYPE_DISPLAY)
#define EVENT_MAP_MAX_SIZE 10
typedef struct
{
GList link;
GdkEvent *gdk_event;
NSEvent *nsevent;
} GdkToNSEventMap;
static GSource *event_source;
static GQueue event_map = G_QUEUE_INIT;
static GdkMacosMonitor *
get_monitor (GdkMacosDisplay *self,
@@ -387,6 +397,28 @@ gdk_macos_display_notify_startup_complete (GdkDisplay *display,
/* Not Supported */
}
static void
push_nsevent (GdkEvent *gdk_event,
NSEvent *nsevent)
{
GdkToNSEventMap *map = g_slice_new0 (GdkToNSEventMap);
map->link.data = map;
map->gdk_event = gdk_event_ref (gdk_event);
map->nsevent = g_steal_pointer (&nsevent);
g_queue_push_tail_link (&event_map, &map->link);
if (event_map.length > EVENT_MAP_MAX_SIZE)
{
map = g_queue_pop_head_link (&event_map)->data;
gdk_event_unref (map->gdk_event);
[map->nsevent release];
g_slice_free (GdkToNSEventMap, map);
}
}
static void
gdk_macos_display_queue_events (GdkDisplay *display)
{
@@ -400,14 +432,18 @@ gdk_macos_display_queue_events (GdkDisplay *display)
GdkEvent *event = _gdk_macos_display_translate (self, nsevent);
if (event != NULL)
_gdk_windowing_got_event (GDK_DISPLAY (self),
_gdk_event_queue_append (GDK_DISPLAY (self), event),
event,
0);
{
push_nsevent (event, nsevent);
_gdk_windowing_got_event (GDK_DISPLAY (self),
_gdk_event_queue_append (GDK_DISPLAY (self), event),
event,
0);
}
else
[NSApp sendEvent:nsevent];
[nsevent release];
{
[NSApp sendEvent:nsevent];
[nsevent release];
}
}
}
@@ -467,7 +503,7 @@ _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
keyboard = gdk_seat_get_keyboard (seat);
event = gdk_focus_event_new (GDK_SURFACE (surface), keyboard, NULL, TRUE);
event = gdk_focus_event_new (GDK_SURFACE (surface), keyboard, TRUE);
_gdk_event_queue_append (GDK_DISPLAY (self), event);
/* We just became the active window. Unlike X11, Mac OS X does
@@ -493,7 +529,7 @@ _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
keyboard = gdk_seat_get_keyboard (seat);
event = gdk_focus_event_new (GDK_SURFACE (surface), keyboard, NULL, FALSE);
event = gdk_focus_event_new (GDK_SURFACE (surface), keyboard, FALSE);
_gdk_event_queue_append (GDK_DISPLAY (self), event);
}
@@ -861,7 +897,6 @@ _gdk_macos_display_break_all_grabs (GdkMacosDisplay *self,
event = gdk_grab_broken_event_new (grab->surface,
device,
NULL,
grab->surface,
TRUE);
node = _gdk_event_queue_append (GDK_DISPLAY (self), event);
@@ -1069,3 +1104,17 @@ _gdk_macos_display_warp_pointer (GdkMacosDisplay *self,
CGWarpMouseCursorPosition ((CGPoint) { x, y });
}
NSEvent *
_gdk_macos_display_get_nsevent (GdkEvent *event)
{
for (const GList *iter = event_map.head; iter; iter = iter->next)
{
const GdkToNSEventMap *map = iter->data;
if (map->gdk_event == event)
return map->nsevent;
}
return NULL;
}
+1
View File
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
GdkMacosKeymap *_gdk_macos_keymap_new (GdkMacosDisplay *display);
GdkEventType _gdk_macos_keymap_get_event_type (NSEvent *event);
gboolean _gdk_macos_keymap_is_modifier (guint keycode);
gunichar _gdk_macos_keymap_get_equivalent (guint key);
G_END_DECLS
+147
View File
@@ -696,3 +696,150 @@ _gdk_macos_keymap_is_modifier (guint keycode)
return FALSE;
}
/*
* Code for key code conversion
*
* Copyright (C) 2009 Paul Davis
*/
gunichar
_gdk_macos_keymap_get_equivalent (guint key)
{
if (key >= GDK_KEY_A && key <= GDK_KEY_Z)
return key + (GDK_KEY_a - GDK_KEY_A);
if (key >= GDK_KEY_space && key <= GDK_KEY_asciitilde)
return key;
switch (key)
{
case GDK_KEY_BackSpace:
return NSBackspaceCharacter;
case GDK_KEY_Delete:
return NSDeleteFunctionKey;
case GDK_KEY_Pause:
return NSPauseFunctionKey;
case GDK_KEY_Scroll_Lock:
return NSScrollLockFunctionKey;
case GDK_KEY_Sys_Req:
return NSSysReqFunctionKey;
case GDK_KEY_Home:
return NSHomeFunctionKey;
case GDK_KEY_Left:
case GDK_KEY_leftarrow:
return NSLeftArrowFunctionKey;
case GDK_KEY_Up:
case GDK_KEY_uparrow:
return NSUpArrowFunctionKey;
case GDK_KEY_Right:
case GDK_KEY_rightarrow:
return NSRightArrowFunctionKey;
case GDK_KEY_Down:
case GDK_KEY_downarrow:
return NSDownArrowFunctionKey;
case GDK_KEY_Page_Up:
return NSPageUpFunctionKey;
case GDK_KEY_Page_Down:
return NSPageDownFunctionKey;
case GDK_KEY_End:
return NSEndFunctionKey;
case GDK_KEY_Begin:
return NSBeginFunctionKey;
case GDK_KEY_Select:
return NSSelectFunctionKey;
case GDK_KEY_Print:
return NSPrintFunctionKey;
case GDK_KEY_Execute:
return NSExecuteFunctionKey;
case GDK_KEY_Insert:
return NSInsertFunctionKey;
case GDK_KEY_Undo:
return NSUndoFunctionKey;
case GDK_KEY_Redo:
return NSRedoFunctionKey;
case GDK_KEY_Menu:
return NSMenuFunctionKey;
case GDK_KEY_Find:
return NSFindFunctionKey;
case GDK_KEY_Help:
return NSHelpFunctionKey;
case GDK_KEY_Break:
return NSBreakFunctionKey;
case GDK_KEY_Mode_switch:
return NSModeSwitchFunctionKey;
case GDK_KEY_F1:
return NSF1FunctionKey;
case GDK_KEY_F2:
return NSF2FunctionKey;
case GDK_KEY_F3:
return NSF3FunctionKey;
case GDK_KEY_F4:
return NSF4FunctionKey;
case GDK_KEY_F5:
return NSF5FunctionKey;
case GDK_KEY_F6:
return NSF6FunctionKey;
case GDK_KEY_F7:
return NSF7FunctionKey;
case GDK_KEY_F8:
return NSF8FunctionKey;
case GDK_KEY_F9:
return NSF9FunctionKey;
case GDK_KEY_F10:
return NSF10FunctionKey;
case GDK_KEY_F11:
return NSF11FunctionKey;
case GDK_KEY_F12:
return NSF12FunctionKey;
case GDK_KEY_F13:
return NSF13FunctionKey;
case GDK_KEY_F14:
return NSF14FunctionKey;
case GDK_KEY_F15:
return NSF15FunctionKey;
case GDK_KEY_F16:
return NSF16FunctionKey;
case GDK_KEY_F17:
return NSF17FunctionKey;
case GDK_KEY_F18:
return NSF18FunctionKey;
case GDK_KEY_F19:
return NSF19FunctionKey;
case GDK_KEY_F20:
return NSF20FunctionKey;
case GDK_KEY_F21:
return NSF21FunctionKey;
case GDK_KEY_F22:
return NSF22FunctionKey;
case GDK_KEY_F23:
return NSF23FunctionKey;
case GDK_KEY_F24:
return NSF24FunctionKey;
case GDK_KEY_F25:
return NSF25FunctionKey;
case GDK_KEY_F26:
return NSF26FunctionKey;
case GDK_KEY_F27:
return NSF27FunctionKey;
case GDK_KEY_F28:
return NSF28FunctionKey;
case GDK_KEY_F29:
return NSF29FunctionKey;
case GDK_KEY_F30:
return NSF30FunctionKey;
case GDK_KEY_F31:
return NSF31FunctionKey;
case GDK_KEY_F32:
return NSF32FunctionKey;
case GDK_KEY_F33:
return NSF33FunctionKey;
case GDK_KEY_F34:
return NSF34FunctionKey;
case GDK_KEY_F35:
return NSF35FunctionKey;
default:
break;
}
return '\0';
}
+7 -4
View File
@@ -36,10 +36,13 @@ typedef struct _GdkMacosMonitorClass GdkMacosMonitorClass;
#define GDK_IS_MACOS_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_MONITOR))
GDK_AVAILABLE_IN_ALL
GType gdk_macos_monitor_get_type (void);
void gdk_macos_monitor_get_workarea (GdkMonitor *monitor,
GdkRectangle *geometry);
GType gdk_macos_monitor_get_type (void);
GDK_AVAILABLE_IN_ALL
void gdk_macos_monitor_get_geometry (GdkMonitor *self,
GdkRectangle *geometry);
GDK_AVAILABLE_IN_ALL
void gdk_macos_monitor_get_workarea (GdkMonitor *self,
GdkRectangle *geometry);
G_END_DECLS
+2 -1
View File
@@ -25,6 +25,7 @@
#include "gdkpopupprivate.h"
#include "gdkmacosdisplay-private.h"
#include "gdkmacosmonitor.h"
#include "gdkmacospopupsurface-private.h"
#include "gdkmacosutils-private.h"
@@ -60,7 +61,7 @@ gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
self->layout = gdk_popup_layout_ref (layout);
}
monitor = gdk_surface_get_layout_monitor (surface, layout,
monitor = gdk_surface_get_layout_monitor (GDK_SURFACE (self), layout,
gdk_macos_monitor_get_workarea);
gdk_macos_monitor_get_workarea (monitor, &bounds);
+1 -2
View File
@@ -84,7 +84,7 @@ _gdk_macos_surface_reposition_children (GdkMacosSurface *self)
_gdk_macos_popup_surface_reposition (GDK_MACOS_POPUP_SURFACE (child));
}
if (GDK_IS_POPUP (self) || self->did_initial_present)
if (GDK_IS_POPUP (self))
g_signal_emit_by_name (self, "popup-layout-changed");
}
@@ -820,7 +820,6 @@ _gdk_macos_surface_synthesize_null_key (GdkMacosSurface *self)
event = gdk_key_event_new (GDK_KEY_PRESS,
GDK_SURFACE (self),
gdk_seat_get_keyboard (seat),
NULL,
GDK_CURRENT_TIME,
0,
0,
+4 -1
View File
@@ -25,6 +25,7 @@
#include "gdktoplevelprivate.h"
#include "gdkmacosdisplay-private.h"
#include "gdkmacosmonitor-private.h"
#include "gdkmacostoplevelsurface-private.h"
#include "gdkmacosutils-private.h"
@@ -95,6 +96,7 @@ static gboolean
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)toplevel;
NSWindow *nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
GdkDisplay *display = gdk_surface_get_display (surface);
@@ -190,10 +192,11 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
(GDK_MACOS_SURFACE (self)->shadow_left ||
GDK_MACOS_SURFACE (self)->shadow_top))
{
GdkMonitor *monitor = _gdk_macos_surface_get_best_monitor (GDK_MACOS_SURFACE (self));
int x = GDK_SURFACE (self)->x;
int y = GDK_SURFACE (self)->y;
monitor = _gdk_macos_surface_get_best_monitor (GDK_MACOS_SURFACE (self));
if (monitor != NULL)
{
GdkRectangle visible;
+1
View File
@@ -43,6 +43,7 @@ gdk_macos_frameworks = [
'Carbon',
'CoreVideo',
'CoreServices',
'Foundation',
'OpenGL',
'QuartzCore',
]
+1 -1
View File
@@ -227,7 +227,7 @@ libgdk_c_args = [
gdk_backends = []
gdk_backends_gen_headers = [] # non-public generated headers
foreach backend : ['broadway', 'quartz', 'wayland', 'win32', 'x11', 'macos']
foreach backend : ['broadway', 'wayland', 'win32', 'x11', 'macos']
if get_variable('@0@_enabled'.format(backend))
subdir(backend)
gdk_deps += get_variable('gdk_@0@_deps'.format(backend))
+24 -10
View File
@@ -942,7 +942,7 @@ gdk_wayland_device_pad_init (GdkWaylandDevicePad *pad)
}
/**
* gdk_wayland_device_get_wl_seat:
* gdk_wayland_device_get_wl_seat: (skip)
* @device: (type GdkWaylandDevice): a #GdkDevice
*
* Returns the Wayland wl_seat of a #GdkDevice.
@@ -961,7 +961,7 @@ gdk_wayland_device_get_wl_seat (GdkDevice *device)
}
/**
* gdk_wayland_device_get_wl_pointer:
* gdk_wayland_device_get_wl_pointer: (skip)
* @device: (type GdkWaylandDevice): a #GdkDevice
*
* Returns the Wayland wl_pointer of a #GdkDevice.
@@ -980,7 +980,7 @@ gdk_wayland_device_get_wl_pointer (GdkDevice *device)
}
/**
* gdk_wayland_device_get_wl_keyboard:
* gdk_wayland_device_get_wl_keyboard: (skip)
* @device: (type GdkWaylandDevice): a #GdkDevice
*
* Returns the Wayland wl_keyboard of a #GdkDevice.
@@ -4971,6 +4971,12 @@ gdk_wayland_seat_set_drag (GdkSeat *seat,
g_set_object (&wayland_seat->drag, drag);
}
/**
* gdk_wayland_device_get_data_device: (skip)
* @gdk_device: (type GdkWaylandDevice): a #GdkDevice
*
* ...
*/
struct wl_data_device *
gdk_wayland_device_get_data_device (GdkDevice *gdk_device)
{
@@ -4982,6 +4988,13 @@ gdk_wayland_device_get_data_device (GdkDevice *gdk_device)
return seat->data_device;
}
/**
* gdk_wayland_device_set_selection: (skip)
* @gdk_device: (type GdkWaylandDevice): a #GdkDevice
* @source: the data source for the selection
*
* ...
*/
void
gdk_wayland_device_set_selection (GdkDevice *gdk_device,
struct wl_data_source *source)
@@ -4999,8 +5012,8 @@ gdk_wayland_device_set_selection (GdkDevice *gdk_device,
}
/**
* gdk_wayland_seat_get_wl_seat:
* @seat: (type GdkWaylandSeat): a #GdkSeat
* gdk_wayland_seat_get_wl_seat: (skip)
* @seat: a #GdkSeat
*
* Returns the Wayland wl_seat of a #GdkSeat.
*
@@ -5016,9 +5029,10 @@ gdk_wayland_seat_get_wl_seat (GdkSeat *seat)
/**
* gdk_wayland_device_get_node_path:
* @device: a #GdkDevice
* @device: (type GdkWaylandDevice): a #GdkDevice
*
* Returns the `/dev/input/event*` path of this device.
*
* Returns the /dev/input/event* path of this device.
* For #GdkDevices that possibly coalesce multiple hardware
* devices (eg. mouse, keyboard, touch,...), this function
* will return %NULL.
@@ -5026,8 +5040,8 @@ gdk_wayland_seat_get_wl_seat (GdkSeat *seat)
* This is most notably implemented for devices of type
* %GDK_SOURCE_PEN, %GDK_SOURCE_TABLET_PAD.
*
* Returns: the /dev/input/event* path of this device
**/
* Returns: (nullable) (transfer none): the `/dev/input/event*` path of this device
*/
const char *
gdk_wayland_device_get_node_path (GdkDevice *device)
{
@@ -5052,7 +5066,7 @@ gdk_wayland_device_get_node_path (GdkDevice *device)
/**
* gdk_wayland_device_pad_set_feedback:
* @device: a %GDK_SOURCE_TABLET_PAD device
* @device: (type GdkWaylandDevice): a %GDK_SOURCE_TABLET_PAD device
* @feature: Feature to set the feedback label for
* @feature_idx: 0-indexed index of the feature to set the feedback label for
* @label: Feedback label
+24 -9
View File
@@ -384,6 +384,15 @@ static const struct org_kde_kwin_server_decoration_manager_listener server_decor
.default_mode = server_decoration_manager_default_mode
};
/**
* gdk_wayland_display_prefers_ssd:
* @display: (type GdkWaylandDisplay): a #GdkDisplay
*
* Checks whether the Wayland compositor prefers to draw the window
* decorations or if it leaves decorations to the application.
*
* Returns: %TRUE if the compositor prefers server-side decorations
*/
gboolean
gdk_wayland_display_prefers_ssd (GdkDisplay *display)
{
@@ -497,11 +506,11 @@ gdk_registry_handle_global (void *data,
wl_registry_bind (display_wayland->wl_registry,
id, &zwp_pointer_gestures_v1_interface, version);
}
else if (strcmp (interface, "gtk_primary_selection_device_manager") == 0)
else if (strcmp (interface, "zwp_primary_selection_device_manager_v1") == 0)
{
display_wayland->primary_selection_manager =
wl_registry_bind(display_wayland->wl_registry, id,
&gtk_primary_selection_device_manager_interface, 1);
&zwp_primary_selection_device_manager_v1_interface, 1);
}
else if (strcmp (interface, "zwp_tablet_manager_v2") == 0)
{
@@ -859,7 +868,7 @@ gdk_wayland_display_get_next_serial (GdkDisplay *display)
/**
* gdk_wayland_display_get_startup_notification_id:
* @display: (type GdkX11Display): a #GdkDisplay
* @display: (type GdkWaylandDisplay): a #GdkDisplay
*
* Gets the startup notification ID for a Wayland display, or %NULL
* if no ID has been defined.
@@ -1064,10 +1073,16 @@ get_cursor_theme (GdkWaylandDisplay *display_wayland,
return wl_cursor_theme_create ("/usr/share/icons/default/cursors", size, display_wayland->shm);
}
/**
* gdk_wayland_display_set_cursor_theme:
* @display: (type GdkWaylandDisplay): a #GdkDisplay
*
* Sets the cursor theme for the given @display.
*/
void
gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
const char *name,
int size)
int size)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY(display);
struct wl_cursor_theme *theme;
@@ -1154,7 +1169,7 @@ _gdk_wayland_display_update_serial (GdkWaylandDisplay *display_wayland,
}
/**
* gdk_wayland_display_get_wl_display:
* gdk_wayland_display_get_wl_display: (skip)
* @display: (type GdkWaylandDisplay): a #GdkDisplay
*
* Returns the Wayland wl_display of a #GdkDisplay.
@@ -1170,7 +1185,7 @@ gdk_wayland_display_get_wl_display (GdkDisplay *display)
}
/**
* gdk_wayland_display_get_wl_compositor:
* gdk_wayland_display_get_wl_compositor: (skip)
* @display: (type GdkWaylandDisplay): a #GdkDisplay
*
* Returns the Wayland global singleton compositor of a #GdkDisplay.
@@ -2617,11 +2632,11 @@ gdk_wayland_display_get_output_scale (GdkWaylandDisplay *display_wayland,
/**
* gdk_wayland_display_query_registry:
* @display: a wayland #GdkDisplay
* @display: (type GdkWaylandDisplay): a #GdkDisplay
* @global: global interface to query in the registry
*
* Returns %TRUE if the the interface was found in the display
* wl_registry.global handler.
* `wl_registry.global` handler.
*
* Returns: %TRUE if the global is offered by the compositor
**/
+2 -1
View File
@@ -36,6 +36,7 @@
#include <gdk/wayland/server-decoration-client-protocol.h>
#include <gdk/wayland/xdg-output-unstable-v1-client-protocol.h>
#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
#include <gdk/wayland/primary-selection-unstable-v1-client-protocol.h>
#include <glib.h>
#include <gdk/gdkkeys.h>
@@ -103,7 +104,7 @@ struct _GdkWaylandDisplay
struct wl_data_device_manager *data_device_manager;
struct wl_subcompositor *subcompositor;
struct zwp_pointer_gestures_v1 *pointer_gestures;
struct gtk_primary_selection_device_manager *primary_selection_manager;
struct zwp_primary_selection_device_manager_v1 *primary_selection_manager;
struct zwp_tablet_manager_v2 *tablet_manager;
struct zxdg_exporter_v1 *xdg_exporter;
struct zxdg_importer_v1 *xdg_importer;
+1 -1
View File
@@ -49,7 +49,7 @@ gdk_wayland_monitor_class_init (GdkWaylandMonitorClass *class)
}
/**
* gdk_wayland_monitor_get_wl_output:
* gdk_wayland_monitor_get_wl_output: (skip)
* @monitor: (type GdkWaylandMonitor): a #GdkMonitor
*
* Returns the Wayland wl_output of a #GdkMonitor.
+42 -42
View File
@@ -35,15 +35,15 @@ struct _GdkWaylandPrimary
{
GdkClipboard parent;
struct gtk_primary_selection_device *primary_data_device;
struct zwp_primary_selection_device_v1 *primary_data_device;
struct gtk_primary_selection_offer *pending;
struct zwp_primary_selection_offer_v1 *pending;
GdkContentFormatsBuilder *pending_builder;
struct gtk_primary_selection_offer *offer;
struct zwp_primary_selection_offer_v1 *offer;
GdkContentFormats *offer_formats;
struct gtk_primary_selection_source *source;
struct zwp_primary_selection_source_v1 *source;
};
struct _GdkWaylandPrimaryClass
@@ -62,20 +62,20 @@ gdk_wayland_primary_discard_pending (GdkWaylandPrimary *cb)
gdk_content_formats_unref (ignore);
cb->pending_builder = NULL;
}
g_clear_pointer (&cb->pending, gtk_primary_selection_offer_destroy);
g_clear_pointer (&cb->pending, zwp_primary_selection_offer_v1_destroy);
}
static void
gdk_wayland_primary_discard_offer (GdkWaylandPrimary *cb)
{
g_clear_pointer (&cb->offer_formats, gdk_content_formats_unref);
g_clear_pointer (&cb->offer, gtk_primary_selection_offer_destroy);
g_clear_pointer (&cb->offer, zwp_primary_selection_offer_v1_destroy);
}
static void
gdk_wayland_primary_discard_source (GdkWaylandPrimary *cb)
{
g_clear_pointer (&cb->source, gtk_primary_selection_source_destroy);
g_clear_pointer (&cb->source, zwp_primary_selection_source_v1_destroy);
}
static void
@@ -91,9 +91,9 @@ gdk_wayland_primary_finalize (GObject *object)
}
static void
gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
struct gtk_primary_selection_offer *offer,
GdkContentFormats *formats)
gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
struct zwp_primary_selection_offer_v1 *offer,
GdkContentFormats *formats)
{
g_return_if_fail (GDK_IS_WAYLAND_PRIMARY (cb));
@@ -117,9 +117,9 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
}
static void
primary_offer_offer (void *data,
struct gtk_primary_selection_offer *offer,
const char *type)
primary_offer_offer (void *data,
struct zwp_primary_selection_offer_v1 *offer,
const char *type)
{
GdkWaylandPrimary *cb = data;
@@ -133,14 +133,14 @@ primary_offer_offer (void *data,
gdk_content_formats_builder_add_mime_type (cb->pending_builder, type);
}
static const struct gtk_primary_selection_offer_listener primary_offer_listener = {
static const struct zwp_primary_selection_offer_v1_listener primary_offer_listener = {
primary_offer_offer,
};
static void
primary_selection_data_offer (void *data,
struct gtk_primary_selection_device *device,
struct gtk_primary_selection_offer *offer)
primary_selection_data_offer (void *data,
struct zwp_primary_selection_device_v1 *device,
struct zwp_primary_selection_offer_v1 *offer)
{
GdkWaylandPrimary *cb = data;
@@ -150,17 +150,17 @@ primary_selection_data_offer (void *data,
gdk_wayland_primary_discard_pending (cb);
cb->pending = offer;
gtk_primary_selection_offer_add_listener (offer,
&primary_offer_listener,
cb);
zwp_primary_selection_offer_v1_add_listener (offer,
&primary_offer_listener,
cb);
cb->pending_builder = gdk_content_formats_builder_new ();
}
static void
primary_selection_selection (void *data,
struct gtk_primary_selection_device *device,
struct gtk_primary_selection_offer *offer)
primary_selection_selection (void *data,
struct zwp_primary_selection_device_v1 *device,
struct zwp_primary_selection_offer_v1 *offer)
{
GdkWaylandPrimary *cb = data;
GdkContentFormats *formats;
@@ -185,7 +185,7 @@ primary_selection_selection (void *data,
gdk_wayland_primary_claim_remote (cb, offer, formats);
}
static const struct gtk_primary_selection_device_listener primary_selection_device_listener = {
static const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = {
primary_selection_data_offer,
primary_selection_selection,
};
@@ -205,10 +205,10 @@ gdk_wayland_primary_write_done (GObject *clipboard,
}
static void
gdk_wayland_primary_data_source_send (void *data,
struct gtk_primary_selection_source *source,
const char *mime_type,
int32_t fd)
gdk_wayland_primary_data_source_send (void *data,
struct zwp_primary_selection_source_v1 *source,
const char *mime_type,
int32_t fd)
{
GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (data);
GOutputStream *stream;
@@ -230,8 +230,8 @@ gdk_wayland_primary_data_source_send (void *data,
}
static void
gdk_wayland_primary_data_source_cancelled (void *data,
struct gtk_primary_selection_source *source)
gdk_wayland_primary_data_source_cancelled (void *data,
struct zwp_primary_selection_source_v1 *source)
{
GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (data);
@@ -244,7 +244,7 @@ gdk_wayland_primary_data_source_cancelled (void *
}
}
static const struct gtk_primary_selection_source_listener primary_source_listener = {
static const struct zwp_primary_selection_source_v1_listener primary_source_listener = {
gdk_wayland_primary_data_source_send,
gdk_wayland_primary_data_source_cancelled,
};
@@ -266,18 +266,18 @@ gdk_wayland_primary_claim (GdkClipboard *clipboard,
gdk_wayland_primary_discard_offer (cb);
gdk_wayland_primary_discard_source (cb);
cb->source = gtk_primary_selection_device_manager_create_source (wdisplay->primary_selection_manager);
gtk_primary_selection_source_add_listener (cb->source, &primary_source_listener, cb);
cb->source = zwp_primary_selection_device_manager_v1_create_source (wdisplay->primary_selection_manager);
zwp_primary_selection_source_v1_add_listener (cb->source, &primary_source_listener, cb);
mime_types = gdk_content_formats_get_mime_types (formats, &n_mime_types);
for (i = 0; i < n_mime_types; i++)
{
gtk_primary_selection_source_offer (cb->source, mime_types[i]);
zwp_primary_selection_source_v1_offer (cb->source, mime_types[i]);
}
gtk_primary_selection_device_set_selection (cb->primary_data_device,
cb->source,
_gdk_wayland_display_get_serial (wdisplay));
zwp_primary_selection_device_v1_set_selection (cb->primary_data_device,
cb->source,
_gdk_wayland_display_get_serial (wdisplay));
}
return GDK_CLIPBOARD_CLASS (gdk_wayland_primary_parent_class)->claim (clipboard, formats, local, content);
@@ -323,7 +323,7 @@ gdk_wayland_primary_read_async (GdkClipboard *clipboard,
return;
}
gtk_primary_selection_offer_receive (cb->offer, mime_type, pipe_fd[1]);
zwp_primary_selection_offer_v1_receive (cb->offer, mime_type, pipe_fd[1]);
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
close (pipe_fd[1]);
g_task_return_pointer (task, stream, g_object_unref);
@@ -390,10 +390,10 @@ gdk_wayland_primary_new (GdkWaylandSeat *seat)
NULL);
cb->primary_data_device =
gtk_primary_selection_device_manager_get_device (wdisplay->primary_selection_manager,
gdk_wayland_seat_get_wl_seat (GDK_SEAT (seat)));
gtk_primary_selection_device_add_listener (cb->primary_data_device,
&primary_selection_device_listener, cb);
zwp_primary_selection_device_manager_v1_get_device (wdisplay->primary_selection_manager,
gdk_wayland_seat_get_wl_seat (GDK_SEAT (seat)));
zwp_primary_selection_device_v1_add_listener (cb->primary_data_device,
&primary_selection_device_listener, cb);
return GDK_CLIPBOARD (cb);
}
-1
View File
@@ -22,7 +22,6 @@
#include "gdkseat-wayland.h"
#include <wayland-client.h>
#include "gtk-primary-selection-client-protocol.h"
G_BEGIN_DECLS
-1
View File
@@ -39,7 +39,6 @@
#include <xkbcommon/xkbcommon.h>
#include "gdkinternals.h"
#include "wayland/gtk-primary-selection-client-protocol.h"
#define WL_SURFACE_HAS_BUFFER_SCALE 3
#define WL_POINTER_HAS_FRAME 5
+60 -27
View File
@@ -333,7 +333,9 @@ _gdk_wayland_surface_save_size (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN | GDK_TOPLEVEL_STATE_MAXIMIZED))
if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_TILED))
return;
impl->saved_width = surface->width - impl->margin_left - impl->margin_right;
@@ -881,24 +883,6 @@ gdk_wayland_surface_finalize (GObject *object)
G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->finalize (object);
}
static void
gdk_wayland_surface_resize (GdkSurface *surface,
int width,
int height,
int scale)
{
GdkDisplay *display;
GdkEvent *event;
event = gdk_configure_event_new (surface, width, height);
gdk_wayland_surface_update_size (surface, width, height, scale);
_gdk_surface_update_size (surface);
display = gdk_surface_get_display (surface);
_gdk_wayland_display_deliver_event (display, event);
}
static gboolean
is_realized_shell_surface (GdkWaylandSurface *impl)
{
@@ -920,6 +904,26 @@ is_realized_popup (GdkWaylandSurface *impl)
impl->display_server.zxdg_popup_v6);
}
static void
gdk_wayland_surface_resize (GdkSurface *surface,
int width,
int height,
int scale)
{
gdk_wayland_surface_update_size (surface, width, height, scale);
_gdk_surface_update_size (surface);
if (is_realized_shell_surface (GDK_WAYLAND_SURFACE (surface)))
{
GdkDisplay *display;
GdkEvent *event;
event = gdk_configure_event_new (surface, width, height);
display = gdk_surface_get_display (surface);
_gdk_wayland_display_deliver_event (display, event);
}
}
static void gdk_wayland_surface_show (GdkSurface *surface,
gboolean already_mapped);
static void gdk_wayland_surface_hide (GdkSurface *surface);
@@ -1350,6 +1354,11 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
/* Save size for next time we get 0x0 */
_gdk_wayland_surface_save_size (surface);
}
else
{
width += impl->margin_left + impl->margin_right;
height += impl->margin_top + impl->margin_bottom;
}
gdk_wayland_surface_resize (surface, width, height, impl->scale);
}
@@ -1685,6 +1694,13 @@ create_zxdg_toplevel_v6_resources (GdkSurface *surface)
surface);
}
/**
* gdk_wayland_toplevel_set_application_id:
* @toplevel: (type GdkWaylandToplevel): a #GdkToplevel
* @application_id: the application id for the @toplevel
*
* Sets the application id on a #GdkToplevel.
*/
void
gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel,
const char *application_id)
@@ -4024,7 +4040,7 @@ _gdk_wayland_surface_set_grab_seat (GdkSurface *surface,
}
/**
* gdk_wayland_surface_get_wl_surface:
* gdk_wayland_surface_get_wl_surface: (skip)
* @surface: (type GdkWaylandSurface): a #GdkSurface
*
* Returns the Wayland surface of a #GdkSurface.
@@ -4216,12 +4232,12 @@ static const struct zxdg_exported_v1_listener xdg_exported_listener = {
/**
* GdkWaylandToplevelExported:
* @toplevel: the #GdkToplevel that is exported
* @toplevel: (type GdkWaylandToplevel): the #GdkToplevel that is exported
* @handle: the handle
* @user_data: user data that was passed to gdk_wayland_toplevel_export_handle()
*
* Callback that gets called when the handle for a surface has been
* obtained from the Wayland compositor. The handle can be passed
* obtained from the Wayland compositor. The @handle can be passed
* to other processes, for the purpose of marking surfaces as transient
* for out-of-process surfaces.
*/
@@ -4234,7 +4250,7 @@ gdk_wayland_surface_is_exported (GdkWaylandSurface *impl)
/**
* gdk_wayland_toplevel_export_handle:
* @toplevel: the #GdkToplevel to obtain a handle for
* @toplevel: (type GdkWaylandToplevel): the #GdkToplevel to obtain a handle for
* @callback: callback to call with the handle
* @user_data: (closure): user data for @callback
* @destroy_func: destroy notify for @user_data
@@ -4298,7 +4314,7 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel,
/**
* gdk_wayland_toplevel_unexport_handle:
* @toplevel: the #GdkToplevel to unexport
* @toplevel: (type GdkWaylandToplevel): the #GdkToplevel to unexport
*
* Destroys the handle that was obtained with
* gdk_wayland_toplevel_export_handle().
@@ -4352,7 +4368,7 @@ static const struct zxdg_imported_v1_listener xdg_imported_listener = {
/**
* gdk_wayland_toplevel_set_transient_for_exported:
* @toplevel: the #GdkToplevel to make as transient
* @toplevel: (type GdkWaylandToplevel): the #GdkToplevel to make as transient
* @parent_handle_str: an exported handle for a surface
*
* Marks @toplevel as transient for the surface to which the given
@@ -4405,6 +4421,13 @@ gdk_wayland_surface_get_inhibitor (GdkWaylandSurface *impl,
return g_hash_table_lookup (impl->shortcuts_inhibitors, gdk_seat);
}
/*
* gdk_wayland_surface_inhibit_shortcuts:
* @surface: (type GdkWaylandSurface): a #GdkSurface
* @seat: the seat to inhibit
*
* Inhibits the shortcuts coming from the given @seat.
*/
void
gdk_wayland_surface_inhibit_shortcuts (GdkSurface *surface,
GdkSeat *gdk_seat)
@@ -4428,6 +4451,14 @@ gdk_wayland_surface_inhibit_shortcuts (GdkSurface *surface,
g_hash_table_insert (impl->shortcuts_inhibitors, gdk_seat, inhibitor);
}
/*
* gdk_wayland_surface_restore_shortcuts:
* @surface: (type GdkWaylandSurface): a #GdkSurface
* @seat: the seat to inhibit
*
* Restores the shortcuts on the given @seat inhibited by calling
* gdk_wayland_surface_inhibit_shortcuts().
*/
void
gdk_wayland_surface_restore_shortcuts (GdkSurface *surface,
GdkSeat *gdk_seat)
@@ -4448,8 +4479,10 @@ create_dnd_surface (GdkDisplay *display)
{
GdkSurface *surface;
surface = gdk_surface_new_temp (display, &(GdkRectangle){ 0, 0, 100, 100 });
surface = _gdk_wayland_display_create_surface (display,
GDK_SURFACE_TEMP,
NULL,
0, 0, 100, 100);
GDK_WAYLAND_SURFACE (surface)->is_drag_surface = TRUE;
return surface;
+2 -2
View File
@@ -60,8 +60,8 @@ const char *gdk_wayland_device_get_node_path (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
void gdk_wayland_device_pad_set_feedback (GdkDevice *device,
GdkDevicePadFeature element,
guint idx,
GdkDevicePadFeature feature,
guint feature_idx,
const char *label);
G_END_DECLS
+1 -1
View File
@@ -45,7 +45,7 @@ wayland_scanner = find_program('wayland-scanner')
# - protocol version (if stability is 'unstable')
proto_sources = [
['gtk-shell', 'private', ],
['gtk-primary-selection', 'private', ],
['primary-selection', 'unstable', 'v1', ],
['pointer-gestures', 'unstable', 'v1', ],
['xdg-shell', 'unstable', 'v6', ],
['xdg-shell', 'stable', ],
@@ -1,225 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="gtk_primary_selection">
<copyright>
Copyright © 2015, 2016 Red Hat
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="Primary selection protocol">
This protocol provides the ability to have a primary selection device to
match that of the X server. This primary selection is a shortcut to the
common clipboard selection, where text just needs to be selected in order
to allow copying it elsewhere. The de facto way to perform this action
is the middle mouse button, although it is not limited to this one.
Clients wishing to honor primary selection should create a primary
selection source and set it as the selection through
wp_primary_selection_device.set_selection whenever the text selection
changes. In order to minimize calls in pointer-driven text selection,
it should happen only once after the operation finished. Similarly,
a NULL source should be set when text is unselected.
wp_primary_selection_offer objects are first announced through the
wp_primary_selection_device.data_offer event. Immediately after this event,
the primary data offer will emit wp_primary_selection_offer.offer events
to let know of the mime types being offered.
When the primary selection changes, the client with the keyboard focus
will receive wp_primary_selection_device.selection events. Only the client
with the keyboard focus will receive such events with a non-NULL
wp_primary_selection_offer. Across keyboard focus changes, previously
focused clients will receive wp_primary_selection_device.events with a
NULL wp_primary_selection_offer.
In order to request the primary selection data, the client must pass
a recent serial pertaining to the press event that is triggering the
operation, if the compositor deems the serial valid and recent, the
wp_primary_selection_source.send event will happen in the other end
to let the transfer begin. The client owning the primary selection
should write the requested data, and close the file descriptor
immediately.
If the primary selection owner client disappeared during the transfer,
the client reading the data will receive a
wp_primary_selection_device.selection event with a NULL
wp_primary_selection_offer, the client should take this as a hint
to finish the reads related to the no longer existing offer.
The primary selection owner should be checking for errors during
writes, merely cancelling the ongoing transfer if any happened.
</description>
<interface name="gtk_primary_selection_device_manager" version="1">
<description summary="X primary selection emulation">
The primary selection device manager is a singleton global object that
provides access to the primary selection. It allows to create
wp_primary_selection_source objects, as well as retrieving the per-seat
wp_primary_selection_device objects.
</description>
<request name="create_source">
<description summary="create a new primary selection source">
Create a new primary selection source.
</description>
<arg name="id" type="new_id" interface="gtk_primary_selection_source"/>
</request>
<request name="get_device">
<description summary="create a new primary selection device">
Create a new data device for a given seat.
</description>
<arg name="id" type="new_id" interface="gtk_primary_selection_device"/>
<arg name="seat" type="object" interface="wl_seat"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the primary selection device manager">
Destroy the primary selection device manager.
</description>
</request>
</interface>
<interface name="gtk_primary_selection_device" version="1">
<request name="set_selection">
<description summary="set the primary selection">
Replaces the current selection. The previous owner of the primary selection
will receive a wp_primary_selection_source.cancelled event.
To unset the selection, set the source to NULL.
</description>
<arg name="source" type="object" interface="gtk_primary_selection_source" allow-null="true"/>
<arg name="serial" type="uint" summary="serial of the event that triggered this request"/>
</request>
<event name="data_offer">
<description summary="introduce a new wp_primary_selection_offer">
Introduces a new wp_primary_selection_offer object that may be used
to receive the current primary selection. Immediately following this
event, the new wp_primary_selection_offer object will send
wp_primary_selection_offer.offer events to describe the offered mime
types.
</description>
<arg name="offer" type="new_id" interface="gtk_primary_selection_offer"/>
</event>
<event name="selection">
<description summary="advertise a new primary selection">
The wp_primary_selection_device.selection event is sent to notify the
client of a new primary selection. This event is sent after the
wp_primary_selection.data_offer event introducing this object, and after
the offer has announced its mimetypes through
wp_primary_selection_offer.offer.
The data_offer is valid until a new offer or NULL is received
or until the client loses keyboard focus. The client must destroy the
previous selection data_offer, if any, upon receiving this event.
</description>
<arg name="id" type="object" interface="gtk_primary_selection_offer" allow-null="true"/>
</event>
<request name="destroy" type="destructor">
<description summary="destroy the primary selection device">
Destroy the primary selection device.
</description>
</request>
</interface>
<interface name="gtk_primary_selection_offer" version="1">
<description summary="offer to transfer primary selection contents">
A wp_primary_selection_offer represents an offer to transfer the contents
of the primary selection clipboard to the client. Similar to
wl_data_offer, the offer also describes the mime types that the source
will transferthat the
data can be converted to and provides the mechanisms for transferring the
data directly to the client.
</description>
<request name="receive">
<description summary="request that the data is transferred">
To transfer the contents of the primary selection clipboard, the client
issues this request and indicates the mime type that it wants to
receive. The transfer happens through the passed file descriptor
(typically created with the pipe system call). The source client writes
the data in the mime type representation requested and then closes the
file descriptor.
The receiving client reads from the read end of the pipe until EOF and
closes its end, at which point the transfer is complete.
</description>
<arg name="mime_type" type="string"/>
<arg name="fd" type="fd"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the primary selection offer">
Destroy the primary selection offer.
</description>
</request>
<event name="offer">
<description summary="advertise offered mime type">
Sent immediately after creating announcing the wp_primary_selection_offer
through wp_primary_selection_device.data_offer. One event is sent per
offered mime type.
</description>
<arg name="mime_type" type="string"/>
</event>
</interface>
<interface name="gtk_primary_selection_source" version="1">
<description summary="offer to replace the contents of the primary selection">
The source side of a wp_primary_selection_offer, it provides a way to
describe the offered data and respond to requests to transfer the
requested contents of the primary selection clipboard.
</description>
<request name="offer">
<description summary="add an offered mime type">
This request adds a mime type to the set of mime types advertised to
targets. Can be called several times to offer multiple types.
</description>
<arg name="mime_type" type="string"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the primary selection source">
Destroy the primary selection source.
</description>
</request>
<event name="send">
<description summary="send the primary selection contents">
Request for the current primary selection contents from the client.
Send the specified mime type over the passed file descriptor, then
close it.
</description>
<arg name="mime_type" type="string"/>
<arg name="fd" type="fd"/>
</event>
<event name="cancelled">
<description summary="request for primary selection contents was canceled">
This primary selection source is no longer valid. The client should
clean up and destroy this primary selection source.
</description>
</event>
</interface>
</protocol>
+6 -1
View File
@@ -427,7 +427,12 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
ndevices, ncursors));
#endif
/* Create a dummy window to receive wintab events */
wintab_window = gdk_surface_new_temp (display, &(GdkRectangle) { -100, -100, 2, 2 });
wintab_window =
_gdk_win32_display_create_surface (display,
GDK_SURFACE_TEMP,
NULL,
-100, -100, 2, 2);
g_object_ref (wintab_window);
for (devix = 0; devix < ndevices; devix++)
+4 -1
View File
@@ -1700,7 +1700,10 @@ create_drag_surface (GdkDisplay *display)
{
GdkSurface *surface;
surface = gdk_surface_new_temp (display, &(GdkRectangle) { 0, 0, 100, 100 });
surface = _gdk_win32_display_create_surface (display,
GDK_SURFACE_TEMP,
NULL,
0, 0, 100, 100);
return surface;
}
+3
View File
@@ -1327,6 +1327,9 @@ gdk_win32_surface_raise (GdkSurface *window)
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window), HWND_TOPMOST,
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER));
else if (GDK_IS_POPUP (window))
ShowWindow (GDK_SURFACE_HWND (window), SW_SHOWNOACTIVATE);
else
/* Do not wrap this in an API_CALL macro as SetForegroundWindow might
* fail when for example dragging a window belonging to a different
+5 -4
View File
@@ -1441,10 +1441,11 @@ gdk_x11_display_open (const char *display_name)
gdk_event_init (display);
{
GdkRectangle rect = { -100, -100, 1, 1 };
display_x11->leader_gdk_surface = gdk_surface_new_temp (display, &rect);
}
display_x11->leader_gdk_surface =
_gdk_x11_display_create_surface (display,
GDK_SURFACE_TEMP,
NULL,
-100, -100, 1, 1);
(_gdk_x11_surface_get_toplevel (display_x11->leader_gdk_surface))->is_leader = TRUE;
+8 -2
View File
@@ -1269,7 +1269,10 @@ create_drag_surface (GdkDisplay *display)
{
GdkSurface *surface;
surface = gdk_surface_new_temp (display, &(GdkRectangle) { 0, 0, 100, 100 });
surface = _gdk_x11_display_create_surface (display,
GDK_SURFACE_TEMP,
NULL,
0, 0, 100, 100);
return surface;
}
@@ -1999,7 +2002,10 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
display = gdk_surface_get_display (surface);
ipc_surface = gdk_surface_new_temp (display, &(GdkRectangle) { -99, -99, 1, 1 });
ipc_surface = _gdk_x11_display_create_surface (display,
GDK_SURFACE_TEMP,
NULL,
-99, -99, 1, 1);
drag = (GdkDrag *) g_object_new (GDK_TYPE_X11_DRAG,
"surface", ipc_surface,
+6 -2
View File
@@ -4114,11 +4114,15 @@ create_moveresize_surface (MoveResizeData *mv_resize,
guint32 timestamp)
{
GdkGrabStatus status;
GdkRectangle rect = { -100, -100, 1, 1 };
g_assert (mv_resize->moveresize_emulation_surface == NULL);
mv_resize->moveresize_emulation_surface = gdk_surface_new_temp (mv_resize->display, &rect);
mv_resize->moveresize_emulation_surface =
_gdk_x11_display_create_surface (mv_resize->display,
GDK_SURFACE_TEMP,
NULL,
-100, -100, 1, 1);
gdk_x11_surface_show (mv_resize->moveresize_emulation_surface, FALSE);
status = gdk_seat_grab (gdk_device_get_seat (mv_resize->device),
+6
View File
@@ -258,9 +258,12 @@ collect_reused_child_nodes (GskRenderer *renderer,
case GSK_LINEAR_GRADIENT_NODE:
/* Fallbacks (=> leaf for now */
case GSK_GL_SHADER_NODE:
case GSK_COLOR_MATRIX_NODE:
case GSK_TEXT_NODE:
case GSK_RADIAL_GRADIENT_NODE:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
case GSK_REPEAT_NODE:
case GSK_BLEND_NODE:
case GSK_CROSS_FADE_NODE:
@@ -842,11 +845,14 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
break; /* Fallback */
case GSK_TEXT_NODE:
case GSK_RADIAL_GRADIENT_NODE:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
case GSK_REPEAT_NODE:
case GSK_BLEND_NODE:
case GSK_CROSS_FADE_NODE:
case GSK_BLUR_NODE:
case GSK_GL_SHADER_NODE:
default:
break; /* Fallback */
}
+85 -43
View File
@@ -7,6 +7,7 @@
#include "gdk/gdkglcontextprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkgltextureprivate.h"
#include "gdkmemorytextureprivate.h"
#include <gdk/gdk.h>
#include <epoxy/gl.h>
@@ -58,6 +59,54 @@ struct _GskGLDriver
G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT)
static void
upload_gdk_texture (GdkTexture *source_texture,
int target,
int x_offset,
int y_offset,
int width,
int height)
{
cairo_surface_t *surface = NULL;
GdkMemoryFormat data_format;
const guchar *data;
gsize data_stride;
gsize bpp;
g_return_if_fail (source_texture != NULL);
g_return_if_fail (x_offset + width <= gdk_texture_get_width (source_texture));
g_return_if_fail (y_offset + height <= gdk_texture_get_height (source_texture));
/* Note: GdkGLTextures are already handled before we reach this and reused as-is */
if (GDK_IS_MEMORY_TEXTURE (source_texture))
{
GdkMemoryTexture *memory_texture = GDK_MEMORY_TEXTURE (source_texture);
data = gdk_memory_texture_get_data (memory_texture);
data_format = gdk_memory_texture_get_format (memory_texture);
data_stride = gdk_memory_texture_get_stride (memory_texture);
}
else
{
/* Fall back to downloading to a surface */
surface = gdk_texture_download_surface (source_texture);
cairo_surface_flush (surface);
data = cairo_image_surface_get_data (surface);
data_format = GDK_MEMORY_DEFAULT;
data_stride = cairo_image_surface_get_stride (surface);
}
bpp = gdk_memory_format_bytes_per_pixel (data_format);
gdk_gl_context_upload_texture (gdk_gl_context_get_current (),
data + x_offset * bpp + y_offset * data_stride,
width, height, data_stride,
data_format, target);
if (surface)
cairo_surface_destroy (surface);
}
static Texture *
texture_new (void)
{
@@ -408,32 +457,15 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
slices = g_new0 (TextureSlice, cols * rows);
/* TODO: (Perf):
* We still create a surface here, which should obviously be unnecessary
* and we should eventually remove it and upload the data directly.
*/
for (col = 0; col < cols; col ++)
{
const int slice_width = MIN (max_texture_size, texture->width - x);
const int stride = slice_width * 4;
for (row = 0; row < rows; row ++)
{
const int slice_height = MIN (max_texture_size, texture->height - y);
const int slice_index = (col * rows) + row;
guchar *data;
guint texture_id;
cairo_surface_t *surface;
data = g_malloc (sizeof (guchar) * stride * slice_height);
gdk_texture_download_area (texture,
&(GdkRectangle){x, y, slice_width, slice_height},
data, stride);
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
slice_width, slice_height,
stride);
glGenTextures (1, &texture_id);
@@ -442,7 +474,7 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
#endif
glBindTexture (GL_TEXTURE_2D, texture_id);
gsk_gl_driver_set_texture_parameters (self, GL_NEAREST, GL_NEAREST);
gdk_cairo_surface_upload_to_gl (surface, GL_TEXTURE_2D, slice_width, slice_height, NULL);
upload_gdk_texture (texture, GL_TEXTURE_2D, x, y, slice_width, slice_height);
#ifdef G_ENABLE_DEBUG
gsk_profiler_counter_inc (self->profiler, self->counters.surface_uploads);
@@ -451,9 +483,6 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
slices[slice_index].rect = (GdkRectangle){x, y, slice_width, slice_height};
slices[slice_index].texture_id = texture_id;
g_free (data);
cairo_surface_destroy (surface);
y += slice_height;
}
@@ -486,27 +515,36 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
int mag_filter)
{
Texture *t;
cairo_surface_t *surface;
GdkTexture *downloaded_texture = NULL;
GdkTexture *source_texture;
if (GDK_IS_GL_TEXTURE (texture))
{
GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture);
GdkGLContext *shared_context = gdk_gl_context_get_shared_context (self->gl_context);
if (texture_context != self->gl_context)
if (texture_context == self->gl_context ||
(gdk_gl_context_get_shared_context (texture_context) == shared_context && shared_context != NULL))
{
/* A GL texture from the same GL context is a simple task... */
return gdk_gl_texture_get_id ((GdkGLTexture *)texture);
}
else
{
cairo_surface_t *surface;
/* In this case, we have to temporarily make the texture's context the current one,
* download its data into our context and then create a texture from it. */
if (texture_context)
gdk_gl_context_make_current (texture_context);
surface = gdk_texture_download_surface (texture);
downloaded_texture = gdk_texture_new_for_surface (surface);
cairo_surface_destroy (surface);
gdk_gl_context_make_current (self->gl_context);
}
else
{
/* A GL texture from the same GL context is a simple task... */
return gdk_gl_texture_get_id ((GdkGLTexture *)texture);
source_texture = downloaded_texture;
}
}
else
@@ -519,7 +557,7 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
return t->texture_id;
}
surface = gdk_texture_download_surface (texture);
source_texture = texture;
}
t = create_texture (self, gdk_texture_get_width (texture), gdk_texture_get_height (texture));
@@ -528,15 +566,16 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
t->user = texture;
gsk_gl_driver_bind_source_texture (self, t->texture_id);
gsk_gl_driver_init_texture_with_surface (self,
t->texture_id,
surface,
min_filter,
mag_filter);
gsk_gl_driver_init_texture (self,
t->texture_id,
source_texture,
min_filter,
mag_filter);
gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, t->texture_id,
"GdkTexture<%p> %d", texture, t->texture_id);
cairo_surface_destroy (surface);
if (downloaded_texture)
g_object_unref (downloaded_texture);
return t->texture_id;
}
@@ -548,7 +587,8 @@ texture_key_hash (gconstpointer v)
return GPOINTER_TO_UINT (k->pointer)
+ (guint)(k->scale*100)
+ (guint)k->filter;
+ (guint)k->filter * 2 +
+ (guint)k->pointer_is_child;
}
static gboolean
@@ -559,7 +599,9 @@ texture_key_equal (gconstpointer v1, gconstpointer v2)
return k1->pointer == k2->pointer &&
k1->scale == k2->scale &&
k1->filter == k2->filter;
k1->filter == k2->filter &&
k1->pointer_is_child == k2->pointer_is_child &&
(!k1->pointer_is_child || graphene_rect_equal (&k1->parent_rect, &k2->parent_rect));
}
int
@@ -769,11 +811,11 @@ filter_uses_mipmaps (int filter)
}
void
gsk_gl_driver_init_texture_with_surface (GskGLDriver *self,
int texture_id,
cairo_surface_t *surface,
int min_filter,
int mag_filter)
gsk_gl_driver_init_texture (GskGLDriver *self,
int texture_id,
GdkTexture *texture,
int min_filter,
int mag_filter)
{
Texture *t;
@@ -794,7 +836,7 @@ gsk_gl_driver_init_texture_with_surface (GskGLDriver *self,
gsk_gl_driver_set_texture_parameters (self, min_filter, mag_filter);
gdk_cairo_surface_upload_to_gl (surface, GL_TEXTURE_2D, t->width, t->height, NULL);
upload_gdk_texture (texture, GL_TEXTURE_2D, 0, 0, t->width, t->height);
#ifdef G_ENABLE_DEBUG
gsk_profiler_counter_inc (self->profiler, self->counters.surface_uploads);
+4 -2
View File
@@ -25,6 +25,8 @@ typedef struct {
gpointer pointer;
float scale;
int filter;
int pointer_is_child;
graphene_rect_t parent_rect; /* Only set if pointer_is_child */
} GskTextureKey;
GskGLDriver * gsk_gl_driver_new (GdkGLContext *context);
@@ -63,9 +65,9 @@ void gsk_gl_driver_init_texture_empty (GskGLDriver *driver
int texture_id,
int min_filter,
int max_filter);
void gsk_gl_driver_init_texture_with_surface (GskGLDriver *driver,
void gsk_gl_driver_init_texture (GskGLDriver *driver,
int texture_id,
cairo_surface_t *surface,
GdkTexture *texture,
int min_filter,
int mag_filter);
+23 -6
View File
@@ -7,6 +7,7 @@
#include "gskgltextureatlasprivate.h"
#include "gdk/gdkglcontextprivate.h"
#include "gdk/gdkmemorytextureprivate.h"
#include <graphene.h>
#include <cairo.h>
@@ -186,6 +187,10 @@ upload_glyph (GlyphCacheKey *key,
GskGLCachedGlyph *value)
{
GskImageRegion r;
guchar *pixel_data;
guchar *free_data = NULL;
guint gl_format;
guint gl_type;
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
"Uploading glyph %d",
@@ -197,15 +202,27 @@ upload_glyph (GlyphCacheKey *key,
glBindTexture (GL_TEXTURE_2D, value->texture_id);
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
GL_RGBA, GL_UNSIGNED_BYTE,
r.data);
{
pixel_data = free_data = g_malloc (r.width * r.height * 4);
gdk_memory_convert (pixel_data, r.width * 4,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
r.data, r.width * 4,
GDK_MEMORY_DEFAULT, r.width, r.height);
gl_format = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE;
}
else
glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
r.data);
{
pixel_data = r.data;
gl_format = GL_BGRA;
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
gl_format, gl_type, pixel_data);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
g_free (r.data);
g_free (free_data);
}
gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
+37 -21
View File
@@ -1,6 +1,7 @@
#include "gskgliconcacheprivate.h"
#include "gskgltextureatlasprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkmemorytextureprivate.h"
#include "gdk/gdkglcontextprivate.h"
#include <epoxy/gl.h>
@@ -134,7 +135,10 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
int packed_y = 0;
cairo_surface_t *surface;
unsigned char *surface_data;
unsigned char *pixel_data;
guchar *free_data = NULL;
guint gl_format;
guint gl_type;
gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
@@ -158,36 +162,47 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
"Uploading texture");
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
gl_format = GL_RGBA;
{
pixel_data = free_data = g_malloc (width * height * 4);
gdk_memory_convert (pixel_data, width * 4,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
surface_data, cairo_image_surface_get_stride (surface),
GDK_MEMORY_DEFAULT, width, height);
gl_format = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE;
}
else
gl_format = GL_BGRA;
{
pixel_data = surface_data;
gl_format = GL_BGRA;
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + 1, packed_y + 1,
width, height,
gl_format,
GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Padding top */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + 1, packed_y,
width, 1,
gl_format, GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Padding left */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x, packed_y + 1,
1, height,
gl_format, GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Padding top left */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x, packed_y,
1, 1,
gl_format, GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Padding right */
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
@@ -195,14 +210,14 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + width + 1, packed_y + 1,
1, height,
gl_format, GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Padding top right */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + width + 1, packed_y,
1, 1,
gl_format, GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Padding bottom */
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
@@ -210,22 +225,22 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + 1, packed_y + 1 + height,
width, 1,
gl_format, GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Padding bottom left */
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x, packed_y + 1 + height,
1, 1,
gl_format, GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Padding bottom right */
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
glTexSubImage2D (GL_TEXTURE_2D, 0,
packed_x + 1 + width, packed_y + 1 + height,
1, 1,
gl_format, GL_UNSIGNED_BYTE,
surface_data);
gl_format, gl_type,
pixel_data);
/* Reset this */
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
@@ -236,6 +251,7 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
*out_icon_data = icon_data;
cairo_surface_destroy (surface);
g_free (free_data);
#if 0
{

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