Compare commits

...

547 Commits

Author SHA1 Message Date
Florian Müllner
d03deb006c Bump version to 3.36.4
Update NEWS.
2020-07-07 20:41:54 +02:00
Jonas Dreßler
c2146b457e clutter/box-layout: Request the correct size for homogeneous layouts
In case the layout is homogeneous, all children aligned by the box
layout must be allocated the same size. In order to fit them all inside
the container, the size request of the box layout has to look for the
child with the largest size and use that size for all children.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2737

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1333
2020-07-06 18:19:35 +02:00
Jonas Dreßler
77dc3a5065 clutter/box-layout: Add spacing when computing opposite orientation size
ClutterBoxLayout calculates the preferred size of the opposite
orientation (so for example the height if the orientation is horizontal)
by getting the preferred size of the real orientation first, and then
the preferred size of the opposite orientation, using the other size as
for_width/height when doing the request.

Right now, for non-homogeneous layouts this for_width/height does not
adjust for the spacing set on the box layout. This leads to children
being passed a slightly larger for_width/height, which in case of
ClutterText might cause the line to not wrap when it actually should.
This in turn means we can end up with an incorrect preferred size for
the opposite orientation, leading to a wrong allocation.

So fix that and adjust for the spacing just as we do for homogeneous
layouts by subtracting the total spacing from the available size that is
distributed between children.

This fixes the wrong height of the checkbox label reported in
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2574.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1333
2020-07-06 18:19:35 +02:00
Carlos Garnacho
454875248a x11: Look up reason for selection clear events from XFixes
If the event originates from a XSetSelectionOwner request, the event
will contain a XFixesSetSelectionOwnerNotify subtype. The other
subtypes (meant for the selection window being destroyed, and the
client closing) are the situations where we mean to replace the
selection.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1268

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1350

(cherry picked from commit 2f1f47d257)
2020-07-03 18:40:48 +02:00
Robert Mader
ae8acc9980 surface-actor: Add culling offset for geometry scale - take 2
41130b08eb added a fix for culling subsurfaces with geometry scale.
Unfortunately it only did so for the opaque regions, not for clip and
unobscured regions, as the effect was hidden by bug that was only
fixed by 3187fe8ebc.

Apply the same fix to clip and unobscured regions and use the chance
to move most of the slightly hackish geometry scale related code
into a single place.

We need to scale slightly differently in the two cases, indicated by
the new `ScalePerspectiveType` enum, as the scale is dependent on the
perspective - once from outside, once from inside of the scaled actor.

Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/1312

(cherry picked from commit 86646679f1)
2020-06-30 22:33:52 +02:00
Olivier Fourdan
86d9cd1a66 remote-desktop: Check for screencast only when required
The portal API requires a screencast session only for absolution motion
with remote desktop, other methods including relative motion do not
require a screencast session.

There is no reason to be more strict than the API actually is, check for
a screencast session only when required, like for absolute motion events
and touch events.

Tested with https://gitlab.gnome.org/snippets/1122

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1307


(cherry picked from commit b8524504f4)
2020-06-29 18:38:28 +00:00
Daniel van Vugt
3a70ba7ae2 shaped-texture: Use the REPLACE combine function on opaque areas
We were setting the pipeline colour to all white (1.0, 1.0, 1.0, 1.0)
and so the default layer combine function multiplied each pixel
(R, G, B, A) by all ones. Obviously multiplying by one four times per
pixel is a waste of effort so we remove the colour setting *and* set
the layer combine function to a trivial shader that will ignore whatever
the current pipeline colour is set to. So now we do **zero** multiplies
per pixel.

On an i7-7700 at UHD 3840x2160 this results in 5% faster render times
and 10% lower power usage (says intel_gpu_top). The benefit is probably
much higher for virtual machines though, as they're no longer being
asked to do CPU-based math on every pixel of a window.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1331

(cherry picked from commit e5542c3210)
2020-06-27 12:31:02 +02:00
Jonas Ådahl
36a6235f3a wayland/xdg-shell: Don't use xdg_surface private to get window geometry
We already used the actual API in the same function, move that call a
bit higher up to and use the variable in more places.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1295

(cherry picked from commit 4c0aa2afca)
2020-06-26 10:15:58 +02:00
Jonas Ådahl
9b349cb25b wayland/shell: Apply geometry after subsurface state application
The subsurface state may affect the geometry end result, e.g. when
window decoration enlarging the toplevel window are applied. If we don't
wait with calculating the window geometry, intersecting the set region
with the subsurface tree extents will not include the subsurfaces.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/928

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1295

(cherry picked from commit d6af59612c)
2020-06-26 10:15:46 +02:00
Jonas Ådahl
a83d83f087 wayland: Remove a couple of stray newlines
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1295

(cherry picked from commit be59b514ca)
2020-06-26 10:15:28 +02:00
Sebastian Keller
b8bd39793a wayland/data-device: Don't create and leak unused memory on dnd
"offer" is overwritten with the result of meta_wayland_data_offer_new a
few lines later.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1293

(cherry picked from commit 99c9f4c1fa)
2020-06-24 22:02:34 +02:00
Sebastian Keller
70072c39dd wayland: Free selection streams streams after transfer
They were only being closed but never freed.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1293

(cherry picked from commit dd32ff018a)
2020-06-24 22:02:34 +02:00
Sebastian Keller
bb4bd4b5c0 core: Free clipboard selection source on shutdown
The clipboard manager is the only code to ever set the display selection
source, so it should also be responsible for unsetting it when the
clipboard manager gets shut down.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1293

(cherry picked from commit 019643bad0)
2020-06-24 22:02:34 +02:00
Sebastian Keller
ef848f10d1 core: Fix memory selection source leak after clipboard owner disappears
When an app disappears after some data from it has been copied to the
clipboard, the owner of the clipboard selection becomes a new memory
selection source. The initial reference this new selection source is
never unref'ed, which leads to this being leaked on the next clipboard
selection owner change.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1293

(cherry picked from commit a031ac067e)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
59cb259fdd wayland: Add support for wayland-protocols primary selection protocol
This protocol was added some time ago. Supporting it fell through the
cracks. Add new data device/source/offer implementations for it,
interoperation between primary selection protocols (and X11 primary
selection for that matter) comes for free.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/943

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1255

(cherry picked from commit 2becb3dd29)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
76e4b5de7a build: Build scaffolding for primary-selection wayland protocol
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1255

(cherry picked from commit 55f5177fe0)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
9acb823603 wayland: Rename gtk primary protocol files to "legacy"
We want to make room for the wayland-protocols primary selection
protocol. Rename our private protocol as "legacy".

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1255

(cherry picked from commit 037b68ab8e)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
d721750417 wayland: Send primary offer to all data devices from the same client
Make the data device track the keyboard focus, and use that list to
forward the primary selection to all data devices from the same
client.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1253

(cherry picked from commit b45d5ef3f5)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
1ec91cc8ee wayland: Send clipboard offers to all data devices from the same client
Make the data device track the keyboard focus, and use that list to
forward the clipboard selection to all data devices from the same
client.

This is however not the case of DnD data offers, as the semantics
of multiple in-flight offers is unclear.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1250

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1253

(cherry picked from commit 7e4e371466)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
5c7b5ef0d9 wayland: Drop unused struct variable
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1193

(cherry picked from commit b7366b5b53)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
e98e1c13dd wayland: Move the primary data device manager to its own file
Instead of having everything clumped at MetaWaylandDataManager,
split the primary selection to its own struct. This manager is
handled separately from wl_data_device_manager and other selection
managers, so they would be able to interoperate between them, even.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1193

(cherry picked from commit 5e8d8b9ade)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
8b69e7902a wayland: Move primary data offers to their own file
Following the MetaWaylandDataOffer split.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1193

(cherry picked from commit 4726f3d5d3)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
b52a0be288 wayland: Move MetaWaylandDataOffer to its own file
This is still an openly defined struct, as we will need accessed
by "subclasses". Same principle applies than with the
MetaWaylandDataSource refactor, this is not meant to introduce
functional changes, so just go with it.

On the bright side, the interactions are now clearer, so it could
be made saner in the future.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1193

(cherry picked from commit 91ef7515de)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
1eb0812f0a wayland: Move MetaWaylandDataSourcePrimary to its own file
Following the MetaWaylandDataSource split, this goes next.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1193

(cherry picked from commit 317f6c0910)
2020-06-24 22:02:34 +02:00
Carlos Garnacho
b98125a330 wayland: Split MetaWaylandDataSource into a separate file
The split wasn't 100% clean, and some extra private API had to be
added for it (but well, looking at the API, it's already evident
there's a cleanup/streamlining task due). This is meant to be a
refactor with no functional changes, so just go with it.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1193

(cherry picked from commit 6a3d521466)
2020-06-24 22:02:34 +02:00
Robert Mader
78248d8dd3 Revert "wayland: Send clipboard offers to all data devices from the same client"
This reverts commit 36f5a0a491.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1330
2020-06-24 22:02:29 +02:00
Robert Mader
849d8dfae9 Revert "wayland: Send primary offer to all data devices from the same client"
This reverts commit 493aeb65c8.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1330
2020-06-24 22:02:25 +02:00
Jonas Ådahl
1f896c9735 gpu-kms: Fix compilation issues from backport
The backport applied cleanly, but didn't build as function type
signatures called changed. This fixes the compilation issues.
2020-06-23 16:25:51 +02:00
Michel Dänzer
cc617b059c gpu/kms: Turn off CRTCs as well for DPMS
This avoids some issues which could happen on some setups[0] due to
meta-native-renderer.c:dummy_power_save_page_flip →
meta_onscreen_native_swap_drm_fb implicitly turning of the primary
plane (by destroying the KMS framebuffer assigned to it):

* drmModeObjectSetProperty could return an "Invalid argument" error
  between setting a non-empty cursor with drmModeSetCursor(2) and
  enabling the primary plane again:

  Failed to DPMS: Failed to set connector 69 property 2: Invalid argument

  (This was harmless other than the error message, as we always re-set
  a mode on the CRTC after setting the DPMS property to on, which
  enables the primary plane and implicitly sets the DRM property to on)

* drmModeSetCursor(2) could return an "Invalid argument" error between
  setting the DPMS property to on and enabling the primary plane again:

  Failed to set hardware cursor (drmModeSetCursor failed: Invalid argument), using OpenGL from now on

[0] E.g. with the amdgpu DC display code.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1240


(cherry picked from commit 2e5b767c01)
2020-06-23 14:13:39 +00:00
Robert Mader
44a3358125 shaped-texture: Reintroduce clip_region
In commit 4c1fde9d MetaCullable related code was moved out of
MetaShapedTexture into MetaSurfaceActor. While generally desirable,
this removed drawing optimizations in MetaShapedTexture for partial
redraws. The common case for fully obscured actors was still supposed
to work, but it was now discovered that it actually did not.

This commit revert parts of 4c1fde9d: it reintroduces clipping
to MetaShapedTexture but leaves all culling and actor related logic
in MetaSurfaceActor.

Thanks to Daniel van Vugt for uncovering the issue.

Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/850
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1295

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1326


(cherry picked from commit 3187fe8ebc)
2020-06-22 16:16:37 +00:00
Sebastian Keller
81deb99435 clutter/stage: Make paint_to_buffer use the correct texture/buffer size
The size of the buffer the texture will be written to by
paint_to_buffer() is determined based on
meta_screen_cast_area_stream_src_get_specs() which uses roundf() to
calculate the width and height after scaling. Because the size of the
texture to be written to that buffer is calculated using ceilf(), it
might exceed the allocated buffer when using fractional scaling.

In 3.36 paint_to_buffer() is used from capture_view() which also uses
roundf() to allocate its buffer. Here this leads to a memory corruption
resulting in a crash when taking screenshots of an area.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2842

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1320


(cherry picked from commit e216d9c6ad)
2020-06-17 19:36:46 +00:00
Sebastian Keller
f25417efcf clutter/paint-context: Fix NO_PAINT_SIGNAL flag enum value
This flag was using the same value as the NO_CURSORS flag.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1321
2020-06-17 17:52:24 +02:00
Corentin Noël
ecc2b91016 window-actor-x11: switch the signal callback argument and data on shadow factory change
invalidate_shadow takes the MetaWindowActorX11 as argument and not the MetaShadowFactory.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1314


(cherry picked from commit e09ac67698)
2020-06-16 16:04:38 +00:00
Jonas Ådahl
b002343dca stage/x11: Check that message is WM_PROTOCOLS before assuming so
When a touch sequence was rejected, we'd update the event timestamps of
incoming touch events to help with implementing grabs. This was done by
sending a ClientMessage with a counter, and comparing the counter to
decide whether we're seing a replayed event or not.

This had the unforseen consequence that we would potentially end up
destroying all actors including the stage, since, when mutter receives a
ClientMessage event, it would assume that it's a WM_PROTOCOLS event, and
handle it as such. The problem with this approach is that it would
ignore fact that there might be other ClientMessage types sent to it,
for example the touch synchronization one. What could happen is that the
touch count value would match up with the value of the WM_DELETE_WINDOW
atom, clutter would treat this as WM_PROTOCOLS:WM_DELETE_WINDOW, which
it'd translate to clutter_actor_destroy(stage).

Destroying the stage in such a way is not expected, and caused wierd
crashes in different places depending on what was going on.

This commit make sure we only treat WM_PROTOCOLS client messages as
WM_PROTOCOLS client messages effectively avoiding the issue.

This fixes crashes such as:

 #0  meta_window_get_buffer_rect (window=0x0, rect=rect@entry=0x7ffd7fc62e40) at core/window.c:4396
 #1  0x00007f1e2634837f in get_top_visible_window_actor (compositor=0x297d700, compositor=0x297d700) at compositor/compositor.c:1059
 #2  meta_compositor_sync_stack (compositor=0x297d700, stack=<optimized out>, stack@entry=0x26e3140) at compositor/compositor.c:1176
 #3  0x00007f1e263757ac in meta_stack_tracker_sync_stack (tracker=0x297dbc0) at core/stack-tracker.c:871
 #4  0x00007f1e26375899 in stack_tracker_sync_stack_later (data=<optimized out>) at core/stack-tracker.c:881
 #5  0x00007f1e26376914 in run_repaint_laters (laters_list=0x7f1e2663b7d8 <laters+24>) at core/util.c:809
 #6  run_all_repaint_laters (data=<optimized out>) at core/util.c:826
 #7  0x00007f1e26b18325 in _clutter_run_repaint_functions (flags=flags@entry=CLUTTER_REPAINT_FLAGS_PRE_PAINT) at clutter-main.c:3448
 #8  0x00007f1e26b18fc5 in master_clock_update_stages (master_clock=0x32d6a80, stages=0x4e5a740) at clutter-master-clock-default.c:437
 #9  clutter_clock_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at clutter-master-clock-default.c:567
 #10 0x00007f1e27e48049 in g_main_dispatch (context=0x225b8d0) at gmain.c:3175
 #11 g_main_context_dispatch (context=context@entry=0x225b8d0) at gmain.c:3828
 #12 0x00007f1e27e483a8 in g_main_context_iterate (context=0x225b8d0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3901
 #13 0x00007f1e27e4867a in g_main_loop_run (loop=0x24e29f0) at gmain.c:4097
 #14 0x00007f1e2636a3dc in meta_run () at core/main.c:666
 #15 0x000000000040219c in main (argc=1, argv=0x7ffd7fc63238) at ../src/main.c:534

and

 #0  0x00007f93943c1f25 in raise () at /usr/lib/libc.so.6
 #1  0x00007f93943ab897 in abort () at /usr/lib/libc.so.6
 #2  0x00007f9393e1e062 in g_assertion_message (domain=<optimized out>, file=<optimized out>, line=<optimized out>, func=0x7f93933e6860 <__func__.116322> "meta_x11_get_stage_window",
 #3  0x00007f9393e4ab1d in g_assertion_message_expr ()
 #4  0x00007f939338ecd7 in meta_x11_get_stage_window (stage=<optimized out>) at ../mutter/src/backends/x11/meta-stage-x11.c:923
 #5  0x00007f939339e599 in meta_backend_x11_cm_translate_device_event (x11=<optimized out>, device_event=0x55bc8bcfd6b0) at ../mutter/src/backends/x11/cm/meta-backend-x11-cm.c:381
 #6  0x00007f939339f2e2 in meta_backend_x11_translate_device_event (device_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:179
 #7  0x00007f939339f2e2 in translate_device_event (device_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:208
 #8  0x00007f939339f2e2 in maybe_spoof_event_as_stage_event (input_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:284
 #9  0x00007f939339f2e2 in handle_input_event (event=0x7fff62d60490, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:309
 #10 0x00007f939339f2e2 in handle_host_xevent (event=0x7fff62d60490, backend=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:413
 #11 0x00007f939339f2e2 in x_event_source_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at ../mutter/src/backends/x11/meta-backend-x11.c:467
 #12 0x00007f9393e6c39e in g_main_dispatch (context=0x55bc89dd03e0) at ../glib/glib/gmain.c:3179
 #13 0x00007f9393e6c39e in g_main_context_dispatch (context=context@entry=0x55bc89dd03e0) at ../glib/glib/gmain.c:3844
 #14 0x00007f9393e6e1b1 in g_main_context_iterate (context=0x55bc89dd03e0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:3917
 #15 0x00007f9393e6f0c3 in g_main_loop_run (loop=0x55bc8a042640) at ../glib/glib/gmain.c:4111
 #16 0x00007f9393369a0c in meta_run () at ../mutter/src/core/main.c:676
 #17 0x000055bc880f2426 in main (argc=<optimized out>, argv=<optimized out>) at ../gnome-shell/src/main.c:552

Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/338
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/951

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1317
(cherry picked from commit e5ea8f5483)
2020-06-16 16:18:23 +02:00
Jonas Ådahl
0d9ded403f renderer-native: Don't leak DMA buffer CoglFramebuffer
When we created the DMA buffer backed CoglFramebuffer, we handed it over
to CoglDmaBufHandle which took its own reference. What we failed to do
was to release our own reference to it, effectively leaking it.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1283
(cherry picked from commit c823b5ddba)
2020-06-03 08:27:37 +02:00
Florian Müllner
dc75c7d297 Bump version to 3.36.3
Update NEWS.
2020-06-03 01:35:15 +02:00
Jonas Dreßler
33c008b90a clutter/actor: Sanity check new allocations
Apparently some shell extensions are setting invalid NaN allocations,
leading to weird crashes like
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1849.

Even though an implementation error like this probably deserves a crash,
those can be hard to debug since the crash can happen anywhere the
allocation is being used later. So let Clutter be the good guy and
prevent implementations from setting invalid allocations by
sanity-checking the ClutterActorBoxes using g_return_if_fail.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1849

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1280
2020-06-03 01:35:15 +02:00
Jonas Ådahl
98a0c5cb35 screen-cast-src: Destroy hash dmabuf table after stream
The stream will clean up the buffers, so let it do that before we
destroy them under its feet. Note that it'll only do this after the
following PipeWire commit:

    commit fbaa4ddedd84afdffca16f090dcc4b0db8ccfc29
    Author: Wim Taymans <wtaymans@redhat.com>
    Date:   Mon Jun 1 15:36:09 2020 +0200

        stream: allow NULL param and 0 buffers in disconnect

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1283


(cherry picked from commit 97175f8fa1)
2020-06-02 19:01:01 +00:00
Carlos Garnacho
b425f11536 backends/native: Drop external keyboard detection for ::touch-mode
This cannot be made to work reliably. Some factoids:

- Internal devices may be connected via USB.
- The ACPI spec provides the _PLD (Physical location of device) hook to
  determine how is an USB device connected, with an anecdotal success
  rate. Internal devices may be seen as external and vice-versa, there is
  also an "unknown" value that is widely used.
- There may be non-USB keyboards, the old "AT Translated Set 2 Keyboard"
  interface does not change on hotplugging.
- Libinput has an internal series of quirks to classify keyboards as
  internal of external, also with an "unknown" value.

These heuristics are kinda hopeless to get right by our own hand. Drop
this external keyboard detection in the hope that there will be something
more deterministic to rely on in the future (e.g. the libinput quirks
made available to us directly or indirectly).

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2378
Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2353

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1277


(cherry picked from commit f8e2234ce5)
2020-05-29 14:53:18 +00:00
Carlos Garnacho
a1bc2e0adc backends/x11: Implement ClutterSeat::touch-mode for the X11 backend
This only checks touchscreen availability as we have no access to
tablet-mode switch events as we do on the native backend.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1242

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1278


(cherry picked from commit 38bbd9593b)
2020-05-29 14:52:34 +00:00
Jonas Ådahl
63fc71f05b screen-cast-src: Notify about the stream being closed after dispatch
We're iterating inside the PipeWire loop when detecting PipeWire errors,
and shouldn't destroy the PipeWire objects mid-iteration. Avoid this by
first disabling the stream src (effectively stopping the recording),
then notifying about it being closed in an idle callback. The
notification eventually makes the rest of the screen cast code clean up
the objects, including the src and the associated PipeWire objects, but
will do so outside the PipeWire loop iteration.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1251

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1251
(cherry picked from commit c8e12ead08)
2020-05-23 00:04:10 +02:00
Jonas Ådahl
31307720bf stage-x11: Move view management to renderer
In the native backend, the MetaRenderer manages the view by creating one
per CRTC, but until now the MetaStageX11 managed the view for the X11
backend. This caused some issues as it meant meta_renderer_get_views()
not returning anything, and that the view of the X11 screen not being a
MetaRendererView, while in the other backends, all views are.

Fix this by moving the view management responsibility to
MetaRendererX11Cm, and have MetaStageX11 only operate on it via
meta_renderer_x11_cm_*() API. The MetaRendererX11Cm takes care of making
sure the view is always added to the list in the renderer, and turning
X11 screen sizes into "layouts" etc.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1251
(cherry picked from commit 8a541c08fb)
2020-05-23 00:04:10 +02:00
Jonas Ådahl
cb7ba2e90f stage-x11: Clean up include macros
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1251
(cherry picked from commit dfed5f6a11)
2020-05-23 00:04:10 +02:00
Jonas Ådahl
ba1f4221e9 screen-cast-stream-src: Don't throttle if max framerate is 1/0
The max framerate 1/0 means variable without any particular max, so
don't throttle if that was set.

Not doing this would end up with a floating point exception.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1251
(cherry picked from commit 96dd794fd1)
2020-05-23 00:04:10 +02:00
Jonas Ådahl
6e6183ec08 renderer: Change 'set_legacy_view()' to 'add_view()'
"Legacy" is a misleading name, it's just how the native backend and the
X11 backend behaves differently. Instead rename it to 'add_view()' and
add the sanity check to the caller.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1251
(cherry picked from commit 73a436362a)
2020-05-23 00:04:10 +02:00
Carlos Garnacho
493aeb65c8 wayland: Send primary offer to all data devices from the same client
Make the data device track the keyboard focus, and use that list to
forward the primary selection to all data devices from the same
client.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1253

(cherry-pick of commit b45d5ef3f5)

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1262
2020-05-20 11:28:23 +00:00
Carlos Garnacho
36f5a0a491 wayland: Send clipboard offers to all data devices from the same client
Make the data device track the keyboard focus, and use that list to
forward the clipboard selection to all data devices from the same
client.

This is however not the case of DnD data offers, as the semantics
of multiple in-flight offers is unclear.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1250

(cherry-pick of commit 7e4e371466)

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1262
2020-05-20 11:28:23 +00:00
Carlos Garnacho
3daf912449 backends: Make uniform checks on remote desktop input dbus methods
They all checked that the remote session service talked with the
correct peer, and some of them did check that there is an associated
screencast session.

Add a new check for the session being started (as it's state is
decoupled with screencast session availability) and move all checks
to a function that is called from all input-oriented DBus methods.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1254

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1258


(cherry picked from commit c8837a8de5)
2020-05-20 11:05:51 +00:00
Carlos Garnacho
fadfca2e16 backends: Ensure remote desktop dbus interface state
Ensure that it does receive Start and Stop orderly, and error out
otherwise.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1258


(cherry picked from commit 283cccbe9f)
2020-05-20 11:05:41 +00:00
Daniel van Vugt
b1df6d08a5 backend-x11: Reintroduce XInitThreads
It was removed in 3.34 as part of 6ed5d2e2. And we thought that was the
only thread that might exist and use X11. But the top gnome-shell crasher
in 3.36 seems to suggest otherwise.

We don't know what or where the offending thread is, but since:

 1. We used XInitThreads for years already prior to 3.34; and

 2. Extensions or any change to mutter/gnome-shell could conceivably use
    threads to make X calls, directly or indirectly,

it's probably a good idea to reintroduce XInitThreads. The failing assertion
in libx11 is also accompanied by a strong hint:

```
fprintf(stderr, "[xcb] Most likely this is a multi-threaded client " \
                "and XInitThreads has not been called\n");
```

https://bugs.launchpad.net/bugs/1877075

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1252

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1256

(cherry picked from commit 1d5f9b6917)
2020-05-15 12:49:12 +02:00
Florian Müllner
63bf5f1150 Bump version to 3.36.2
Update NEWS.
2020-04-29 22:22:12 +02:00
Jonas Ådahl
d9d8732096 clutter/stage: Use new paint API to implement capture()
This changes the semantics a bit, e.g. we will never include the pointer
cursor sprite, as there is no way to know whether the caller wants to or
not.

We also change things a bit so that when we render to an offscreen paint
context, we don't emit the "paint" signal on actors, as doing so would
end up recursing in gnome-shell's screenshot and screencast code.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2567

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1222
2020-04-29 18:18:50 +02:00
Jonas Ådahl
797c349245 clutter/paint-context: Add 'no-cursors' paint flag
Will be used by the stage to not paint the overlays. We skip all
overlays since overlays are only ever used for pointer cursors when the
hardware cursors cannot or should not be used.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1222
2020-04-29 18:14:58 +02:00
Jonas Ådahl
b5691d6bf0 stage: Only invoke paint phase callbacks when painting views
These phase callbacks are not intended to be inovked when something
secondary is painting the stage, such as a screen cast stream, or
similar. Thus, only invoke the callbacks when there is a view associated
with the paint context, which will not be the case for offscreen
painting.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1222
2020-04-29 18:14:58 +02:00
Jonas Ådahl
c7ad9b33c2 clutter/stage: Add API to paint to a custom target
Either onto a framebuffer, or into a CPU memory buffer. The latter will
use an former API and then copy the result to CPU memory. The former
allocates an offscreen framebuffer, sets up the relevant framebuffer
matrices and paints part of the stage defined by the passed rectangle.

This will be used by a RecordArea screen cast API. The former to paint
directly onto PipeWire handled dma-buf framebuffers, and the latter for
PipeWire handled shared memory buffers.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1222
2020-04-29 18:14:58 +02:00
Jonas Ådahl
e49297975a stage: Pass paint context in phase callbacks
If there is a paint context available (i.e. for the phases that are
during the actual stage paint), pass it along the callbacks, so that
the callback implementations can change their operation depending on the
paint context state.

This also means we can get the current view from the paint context,
instead of the temporarily used field in the instance struct.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1222
2020-04-29 18:14:58 +02:00
Jonas Ådahl
858c12e73f clutter/paint-context: Add paint flag
A paint flag affects a paint operation in ways defined by the flags.
Currently no flags are defined, so no semantical changes are defined
yet. Eventually a flag aiming to avoid painting of cursors is going to
be added, so that screen cast streams can decide whether to include a
cursor or not.

Changes for gnome-3-36: Removed flag from offscreen context.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1222
2020-04-29 18:14:58 +02:00
Jonas Dreßler
b80b465a65 clutter/stage-cogl: Fix painting the redraw clip with the damage region
The redraw clip that's painted together with the damage region has to be
copied earlier than we do right now. That's because if
PAINT_DAMAGE_REGION is enabled, buffer age is disabled and thus
use_clipped_redraw is FALSE. That means the redraw_clip is updated and
set to the full view-rect. If we copy the queued_redraw_clip after that,
it's also going to be set to the full view-rect. So copy the redraw clip
a bit earlier to make sure we're actually passing the real redraw clip
to paint_damage_region().

Also keep the queued_redraw_clip around a bit longer so it can actually
be used by paint_damage_region() and isn't freed before that.

While at it, move paint_damage_region() from swap_framebuffer() into
clutter_stage_cogl_redraw_view() so we don't have to pass things to
swap_framebuffer() only for debugging.

Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1104

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1208


(cherry picked from commit 793a9d45e1)
2020-04-28 16:46:28 +00:00
Olivier Fourdan
2cc8061f35 keybindings: Mask out the reserved modifiers mask
When switching layouts, special modifiers bits may be be set for
internal use by Xkb.

As we now ignore a set of modifiers when processing the special
modifiers keys, we ought to also mask out those reserved modifiers
otherwise we would discard the [Super] key after switching layouts
in X11.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1144
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1219

(cherry picked from commit 61356caa06)
2020-04-27 18:28:19 +02:00
Laurent Bigonville
dbecb93233 compositor: Only include meta-window-actor-wayland.h when building with wayland
https://gitlab.gnome.org/GNOME/mutter/-/issues/1074

(cherry picked from commit d26dc4ae44)
2020-04-27 16:05:45 +02:00
Olivier Fourdan
adbe09afc3 window-actor/x11: Cache the frame bounds
When resizing an X11 window with client side decorations, the shadow is
clipped by the frame bounds so that we don't need to paint the shadow
under the opaque areas covered by the window and its frame.

When the X11 client uses the EMWH synchronization mechanism (like all
gtk-3 based clients), the actual window may not be updated so that the
actual window and it frame may be behind the expected window frame
bounds, which gives the impression of de-synchronized shadows.

To avoid the issue, keep a copy of the frame bounds as a cache and only
update it when the client is not frozen so that the clipping occurs on
the actual content.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1178
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1214

(cherry picked from commit bd45a00fa3)
2020-04-27 13:19:08 +02:00
Christian Kirbach
bfe9b333c0 Update German translation 2020-04-24 22:37:32 +00:00
Pekka Paalanen
06b0d41baf kms-impl/simple: Fix page_flip_data ref leak on fallback
If drmModePageFlip() or custom_page_flip_func fails, process_page_flip() was
forgetting to undo the ref taken for that call. This would leak page_flip_data.

The reference counting works like this:
- when created, ref count is 1
- when calling drmModePageFlip, ref count is increased to 2
- new: if flip failed, ref count is decreased back to 1
- if calling schedule_retry_page_flip(), it takes a ref internally
- if calling mode_set_fallback(), it takes a ref internally
- all return FALSE paths have an explicit unref
- return TRUE path has an explicit unref

This issue was found by code inspection and while debugging an unrelated issue
with debug prints sprinkled around. I am not aware of any end-user visible
issues being fixed by this, as the leak is small and probably very rare.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209
(cherry picked from commit 36111270aa)
2020-04-24 14:19:44 +03:00
Pekka Paalanen
a62fe66a25 kms: Make GSource ready by default
When testing a laptop with intel and DisplayLink devices, attempting to set the
DL output as the only active output resulted in GNOME/Wayland freezing. The
main event loop was running fine, but nothing on screen would get updated once
the DL output become the only one. This patch fixes that issue.

DisplayLink USB 3 devices use an out-of-tree kernel DRM driver called EVDI.
EVDI can sometimes fail drmModePageFlip(). For me, the flip fails reliably when
hotplugging the DL dock and when changing display configuration to DL only.
Mutter has a workaround for failing flips, it just calls drmModeSetCrtc() and
that succeeds.

What does not work reliably in the fallback path is Mutter keeping track of the
pageflip. Since drmModePageFlip() failed, there will not be a pageflip event
coming and instead Mutter queues a callback in its stead. When you have more
than one output, some other output repainting will attempt to swap buffers and
calls wait_for_pending_flips() which has the side-effect of dispatching any
queued flip callbacks. With multiple outputs, you don't get stuck (unless they
all fail the exact same way at the same time?). When you have only one output,
it cannot proceed to repaint and buffer swap because the pageflip is not marked
complete yet. Nothing dispatches the flip callback, leading to the freeze.

The flip callback is intended to be an idle callback, implemented with a
GSource. It is supposed to be called as soon as execution returns to the main
event loop. The setup of the GSource is incomplete, so it will never dispatch.

Fix the GSource setup by setting its ready-time to be always in the past. That
gets it dispatched on the next cycle of the main event loop. This is now the
default behavior for all sources created by meta_kms_add_source_in_impl().
Sources that need a delay continue to do that by overriding the ready-time
explicitly.

An alternative solution could have been to implement GSource prepare and check
callbacks returning TRUE. However, since meta_kms_add_source_in_impl() is used
by flip retry code as well, and that code needs a delay through the ready-time,
I was afraid I might break the flip retry code. Hence I decided to use
ready-time instead.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209
(cherry picked from commit 6e0cfd3e55)
2020-04-24 14:19:44 +03:00
Carlos Garnacho
5f40493c84 core: Add private function to get the current selection owner
This is a bit untidy to expose, however may be necessary internally.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1186

(cherry picked from commit fbd6366edd)
2020-04-22 01:33:10 +02:00
Carlos Garnacho
e8d9996c9c x11: Allow X11 clients to clear the selection
According to the XSetSelectionOwner libX11 documentation:

  [...] If the owner window it has specified in the request is later
  destroyed, the owner of the selection automatically reverts to None,
  but the last-change time is not affected.

This is indeed visible through the selection_timestamp field in
XFixesSelectionNotify events.

Use this to check whether the selection time is recent-ish (thus
likely coming from an explicit XSetSelectionOwner request) and honor
the client intent by setting a "NULL" owner. If the selection time
is too old, it's definitely an indication of the owner client being
closed, the scenario where we do want the clipboard manager to take
over.

This fixes two usecases:
- X11 LibreOffice / WPS clear the selection each time before copying
  its own content. Mutter's clipboard manager would see each of those
  as a hint to take over, competing with the client over selection
  ownership. This would simply no longer happen
- Password managers may want to clear the selection, which would be
  frustrated by our clipboard manager.

There's a slight window of opportunity for the heuristics to fail
though, if a X11 client sets the selection and closes within 50ms, we
would miss the clipboard manager taking over.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1206

(cherry picked from commit 5671f0a284)
2020-04-22 01:20:11 +02:00
Carlos Garnacho
5465c912c7 x11: Generalize x11 selection owner checks
Shuffle things so the x11 selection can check the current owner directly,
instead of its type.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1206

(cherry picked from commit a7e63bea6c)
2020-04-22 01:20:11 +02:00
Carlos Garnacho
a32bb758f7 x11: Clear X11 selection source after unsetting owner
The X11 selection source was being preserved after unsetting its
ownership. This is no leak as it would be eventually replaced by
another source, or destroyed on finalize. But it's pointless to
keep it.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1206

(cherry picked from commit 94b3c334e5)
2020-04-22 01:20:11 +02:00
Carlos Garnacho
ac8075bbf5 x11: Forward current selection state when initializing X11 selections
Most visible with xwayland-on-demand, at the time of setting things up
for X11 selections, we don't forward the current state. This makes the
first started X11 app oblivious to eg. the current clipboard.

Syncing selections up at the time of initializing the X11 selection
stuff ensures that doesn't happen.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1186

(cherry picked from commit 167fd07e01)
2020-04-22 01:20:11 +02:00
Carlos Garnacho
da9eb4718b wayland: Rely on MetaSelection::owner-changed for .selection event emission
We already have a signal callback that translates selection ownership changes to
data_device/primary .selection events. Given both will be run when a data source
is being replaced, and this event emission being deleted is kinda short sighted
in that in only knows about Wayland, rely entirely on MetaSelection::owner-changed
emission.

Fixes spurious .selection(null) events being sent when a compositor-local source
takes over the selection without the focus changing (eg. screenshot to clipboard).

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1160

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1204

(cherry picked from commit 1363246d44)
2020-04-19 21:51:33 +02:00
Carlos Garnacho
9ad61fe02f wayland: Do not cancel old data source when setting new selection
This is taken care already by the MetaSelection machinery, by
deactivating the previous selection source when setting a new one.
That works across X11 and internal selection sources. This
only works when replacing one wayland source with another, and
actually results in doubly .cancelled events due to the other
paths.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1177

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1203

(cherry picked from commit 0b6560fac4)
2020-04-19 21:51:06 +02:00
Carlos Garnacho
7a09d07b9c wayland: Shuffle wl_data_source.cancelled version checks on DnD
We are meant to send a .cancelled event after the drop is performed
in certain situations, but only for version>3 clients. Since this is
all version 3 business, only set the drop_performed flag for v3
clients. This drops the need to perform version checks at the time
of cancelling (which is present for other usecases in v1).

Fixes emission of wl_data_source.cancelled for v1 clients.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1177

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1203

(cherry picked from commit d4c3870286)
2020-04-19 21:50:48 +02:00
Carlos Garnacho
456e6f345d core: Cater for reading selection in chunks
For the cases where we read a fixed size from the selection (eg. imposing
limits for the clipboard manager), g_input_stream_read_bytes_async() might
not read up to this given size if the other side is spoonfeeding it content.

Cater for multiple read/write cycles here, until (maximum) transfer size is
reached.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 4bdf9a1e70)
2020-04-19 21:48:31 +02:00
Carlos Garnacho
20cf6b630d x11: Do not trust there is task in error paths
Flushing the X11 selection output stream may happen synchronously or
implicitly, in which case there is not a task to complete. Check there
is actually a task before returning errors. We additionally set the
pipe_error flag, so future operations will fail with an error, albeit
with a more generic message.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 1909977a67)
2020-04-19 21:48:09 +02:00
Carlos Garnacho
1e17f8813b x11: Don't stall on write_async()
If a write_async() comes up while we are flushing on the background,
the task will be queued, but not deemed a reason on itself to keep
flushing (and finish the task) after a property delete event.

To fix this, do not ever queue up write_async tasks (this leaves
priv->pending_task only used for flush(), so the "flush to end"
behavior in the background is consistent). We only start a
background flush if there's reasons to do it, but the tasks are
immediately finished.

All data will still be ensured to be transfered on flush/close,
this makes the caller in this situation still able to reach to it.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 655a783891)
2020-04-19 21:47:49 +02:00
Carlos Garnacho
d985517573 x11: Fix iterative INCR property checks
It does not make sense to check for the stream not being closed,
this might happen multiple times during the lifetime of the stream
for a single transfer. We want to notify the INCR transfer just
once.

Check for the explicit conditions that we want, that the remaining
data is bigger than we can transfer at once, and that we are not
yet within the INCR transfer.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit a4596becc4)
2020-04-19 21:47:27 +02:00
Carlos Garnacho
107bb3d9c2 x11: Don't exceed transfer size in INCR chunks
The stream automatically flushes after data size exceeds the
size we deem for INCR chunks, but we still try to copy it all.
Actually limit the data we copy, and leave the rest for future
INCR chunks.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 7015bb3efd)
2020-04-19 21:47:06 +02:00
Carlos Garnacho
b1c47c6213 x11: Don't invariably queue a pending delete request
We don't need doing this roundtrip for non-INCR transfers.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit d2c762cc66)
2020-04-19 21:46:36 +02:00
Carlos Garnacho
c43f178495 x11: Finish INCR transfers properly
INCR transfers are mandated to finish with a final 0-size XChangeProperty
roundtrip after the final data chunk. Actually honor this and ensure we
iterate just once more for this.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 04d429b743)
2020-04-19 21:46:14 +02:00
Carlos Garnacho
c46bea9dff x11: Wait till data is flushed before notifying on the pending task
It does not make sense to notify flushes mid-transfer. We should wait
till the data is actually finished before notifying on the pending
task.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 0b21dcfe08)
2020-04-19 21:45:36 +02:00
Carlos Garnacho
622e8c348f x11: Only send SelectionNotify on first INCR chunk
This should only be sent if the selection can be sent at once, or
if we are right about to notify on the first chunk of an INCR
transfer.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 7c939d78c2)
2020-04-19 21:45:15 +02:00
Carlos Garnacho
51b65b98f5 x11: Ensure flush() Flushes all output stream data
This seemed to work under the assumption that a flush() call can
only result in one INCR roundtrip. This is evidently not true, so
we should hold things off until all pending data is actually flushed.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 8a2b82897d)
2020-04-19 21:44:42 +02:00
Carlos Garnacho
7ec0a9dd68 x11: Unset pending flush flag right before notifying on task
Together with some other state. We can do this altogether on task
notification, instead of lost somewhere in this function flow.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit e95c365cf0)
2020-04-19 21:44:23 +02:00
Carlos Garnacho
6ce42e100f x11: Intern INCR atom
We want to use it, despite it not existing previously.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit a32cb7133b)
2020-04-19 21:44:06 +02:00
Carlos Garnacho
13a23f16c1 x11: Flag flushes despite having less than the element size
If say we want 32bit data, but have 2 bytes stored, we would simply
ignore flush requests. Allow (and don't clear) the needs_flush flag
if we have less than the element size accumulated.

Instead handle this in can_flush(), so it's triggered whenever we
have enough data to fill 1 element, or if the stream is closing
(seems a broken situation, but triggered by the caller).

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 967966cdee)
2020-04-19 21:43:45 +02:00
Carlos Garnacho
40dc22659b x11: XMaxRequestSize returns 4-byte units
XMaxRequestSize/XMaxExtendedRequestSize are documented to return
the maximum size in 4-byte units, whereas we are comparing this
to byte lenghts. We can afford 4x the data here.

Since I don't know the payload size of the XChangeProperty request,
be generous and allot 400 bytes for it, we have some to spare.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198

(cherry picked from commit 06d67b6abf)
2020-04-19 21:43:20 +02:00
Marco Trevisan (Treviño)
fdcb68f4d0 monitor-unit-tests: Ensure configuration is preserved in laptop with closed lid
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1200


(cherry picked from commit f15ce01e2b)
2020-04-16 16:09:54 +00:00
Marco Trevisan (Treviño)
17491bae06 monitor-config-manager: Fallback to closed laptop lid configuration
When closing the lid of a laptop, we reconfigure all the monitors in order
to update the CRTCs and (if enabled) the global UI scaling factor.

To do this, we try first to reuse the current configuration for the usable
monitors, but if we have only monitor enabled and this one is on the laptop
lid we just end up creating a new configuration where the primary monitor is
the laptop one (as per find_primary_monitor() in MetaMonitorConfigManager),
but ignoring the user parameters.

In case the user selected a different resolution / scaling compared to the
default one, while the laptop lid is closed we might change the monitors
layout, causing applications to rescale or reposition.

To avoid this, when creating the monitors configuration from the current
current state, in case we have only one monitor available and that one is
the laptop panel, let's just reuse this configuration.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1200


(cherry picked from commit e48516679c)
2020-04-16 16:09:38 +00:00
Jonas Ådahl
568876da95 cursor-renderer-native: Take CRTC transform into account
The CRTC level transform (not necessarily the hw transform) must be
taken into account when calculating the position of the CRTC in the
stage coordinate space, when placing the hw cursor, otherwise we'll
place the cursor as if the monitor was not rotated.

This wasn't a problem in the past, as with rotation, we always used the
OpenGL cursor, so the issue newer showed.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199
2020-04-15 17:53:50 +02:00
Jonas Ådahl
ea546a8b90 renderer-native: Use CRTC layout in stage view
The port to per CRTC views was incomplete; we still used the logical
monitor layout as the stage view layout, while still using one view per
CRTC.

This worked fine for most cases, e.g. regular monitors, tiled or
non-tiled, transformed or non-transformed. Where it broke, however, was
when a monitor consists of multiple CRTCs. We already have the layout a
CRTC corresponds to on the stage kept with the CRTC metadata, so use
this directly.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1170

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199`
2020-04-15 17:53:50 +02:00
Jonas Ådahl
e8f29a3336 tests/monitor-unit-tests: Test non-hw-transform rotated tiled monitors
Should affect the assigned transform, but not the layout, as that is the
layout on the stage, not the coordinates in any buffer.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199
2020-04-15 17:53:50 +02:00
Jonas Ådahl
5e9986bbcb monitor-config-manager: Only use crtc transform for assignment
The CRTC level transform (i.e. not necessarily the one set on the
hardware) is what is relevant for calculating the layout the CRTC will
have on the stage, so only use the one that can be handled by the
hardware for the CRTC assignment.

This makes the CRTC layout valid for tiled monitors.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199
2020-04-15 17:53:50 +02:00
Jonas Ådahl
3edf6a5292 monitor: Fix tile coordinate calculation
Previously the tile coordinate was used to offset a CRTC scanout
coordinate within a larger framebuffer. Since 3.36 we're always
scanning out from (0, 0) as we always have one framebuffer per CRTC; we
instead use the tile coordinate to calculate the coordinate the tile has
in the stage view. Adapt calculation to fulfil this promise instead of
the old one.

This also corrects the tiled custom monitor test case.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199
2020-04-15 17:53:50 +02:00
Phillip Wood
ad500ef4e5 input-settings: fix device list iteration
Dereference the loop variable rather than the original list head. This
fixes a regression introduced in 4413b86a3 ("backends: Replace
ClutterDeviceManager usage in favor of ClutterSeat", 2019-10-04) which
broke button scrolling with trackballs.

Closes:https://gitlab.gnome.org/GNOME/mutter/-/issues/1120

(cherry picked from commit 3e967d731a)
2020-04-12 23:43:01 +02:00
Olivier Fourdan
9a2471db47 wayland: preserve xkb_state on VT switch
On VT switch, the devices are removed, which means for Wayland disabling
the keyboard.

When the keyboard is disabled, the associated `xkb_state` is freed and
recreated whenever the keyboard is re-enabled when switching back to the
compositor VT.

That means the `xkb_state` for Wayland is lost whereas the same for
clutter is kept, which causes to a discrepancy with locked modifiers on
VT switch.

To avoid that issue, preserve the XKB info only to dispose it when the
keyboard is eventually finalized.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/344
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1185


(cherry picked from commit 5b30a52bbd)
2020-04-08 14:04:02 +00:00
Carlos Garnacho
db164bcfa2 wayland/xdnd: Add error traps around Xdnd* IPC
Make all of them spew criticals, except for XdndLeave as it's feasible
to expect the window we are sending the event to did disappear in the
way (eg. if the window is destroyed while the DnD operation is ongoing
and the pointer is over the window).

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2590

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1184
2020-04-07 20:38:02 +02:00
Jonas Troeger
83553e3f6e backends/native: Translate coordinates of absolute motion events
The motion events of tablets for example need to be mapped on the
selected screen area if the input device is configured to use only a
part of the active logical monitor.
To achieve this behavior each motion event is transformed using the
transformation matrix set for the input device.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1118
2020-04-07 20:37:53 +02:00
Carlos Garnacho
3b2f6ae93d backends/x11: Fix access to WacomDevice
At some point we crossed the streams... In a short timespan we had
1f00aba92c merged, pushing WacomDevice to a common parent object,
and dcaa45fc0c implementing device grouping for X11.

The latter did not rely on the former, and just happened to
merge/compile without issues, but would promptly trigger a crash
whenever the API would be used.

Drop all traces of the WacomDevice internal to MetaInputDeviceX11.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1183


(cherry picked from commit f0718c7d95)
2020-04-07 17:48:09 +00:00
Jonas Dreßler
bc47f0a1ac clutter/stage: Don't assume stage relayouts reallocate everything
With the introduction of "shallow" relayouts, we are now able to enter
allocation cycles not only at the stage but also deeper down the
hierarchy if we know an actors allocation isn't affected by its children
since the NO_LAYOUT flag is set.

Now that means when queuing relayouts it's possible that
`priv->needs_allocation` gets set to TRUE for some actors down the
hierarchy, but not for actors higher up in the hierarchy. An actor tree
where that happens could look like that:

stage -> container -> container2 (NO_LAYOUT) -> textActor

With that tree, if the "textActor" queues a relayout, "container2" will
be added to the relayout hashtable of the stage and the actors "stage"
and "container" will have `priv->needs_allocation` set to FALSE.

Now if another relayout on the stage actor is queued,
`clutter_stage_queue_actor_relayout()` currently removes all the other
hashtable entries in favour of the stage entry, (wrongly) assuming that
will allocate everything. It doesn't allocate everything because in the
example above "container" has `priv->needs_allocation` set to FALSE,
which makes clutter_actor_allocate() return early before allocating its
children, so in the end "container2" will never get a new allocation.

To fix this, stop flushing the relayout hashtable when queuing a
stage-relayout and still add new entries to the hashtable if a stage
relayout is already queued to make sure we still go through all the
previously queued "shallow" relayouts. That shouldn't hurt performance,
too, because as soon as an actor got allocated once, it doesn't need an
allocation anymore and should bail out in clutter_actor_allocate() as
long as it's absolute position didn't change.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1173


(cherry picked from commit e74c2e42cf)
2020-04-07 16:47:32 +00:00
Jonas Ådahl
c8986d19e5 window: Check aliveness a bit less aggressively
Currently we check whether a window is alive everytime it's focused.
This means that an application that doesn't respond to the check-alive
event during startup always showing the "application froze" dialog,
without the user ever trying to interact with it.

An example where this tends to to happen is with games, and for this
particular scenario, it's purely an annoyance, as I never tried to
interact with the game window in the first place, so I don't care that
it's not responding - it's loading.

To avoid these unnecessary particular "app-is-frozen" popups, remove the
alive check from the focus function, and instead move it back to the
"meta_window_activate_full()" call. To also trigger it slightly more
often, also add it to the path that triggers the window focus when a
user actively clicks on the window.

This means that we currently check whether a window is alive on:

  * Any time the window is activated. This means e.g. alt-tab or
    selecting the window in the overview.
  * The user clicks on the window.

Note that the second only works for an already focused window on
Wayland, as on X11, we don't refocus it. This particular case isn't
changed with this commit, as we didn't call meta_window_focus() to begin
with here.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1182


(cherry picked from commit 8df3b21a51)
2020-04-07 13:23:21 +00:00
Christian Rauch
7baabc7ed0 x11: fix compilation if 'libwacom=false'
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1168


(cherry picked from commit a8f6cada88)
2020-04-06 14:57:57 +00:00
Dušan Kazik
b0709504ea Update Slovak translation 2020-04-05 20:22:08 +00:00
Jonas Ådahl
7e94311e2e window-actor: Set viewport when blitting to screencast fb
This fixes an issue where a non-maximized screen casted window would be
stretched to fill the whole screen cast stream, instead of just the crop
that corresponds to the current window size.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1174


(cherry picked from commit a6f94696e2)
2020-04-03 16:30:26 +00:00
Simon McVittie
e339a57ddf cogl: Defend against empty or unallocated framebuffers
It isn't immediately obvious that this is impossible, because there's some
"action at a distance" going on with framebuffers that have their size
set lazily, after their textures get allocated; so let's make this a
critical warning rather than crashing.

In particular, this works around a crash when gnome-shell tries to blur a
background that hasn't yet had any space allocated for it - which it seems
is really an actor layout bug, but more robustness seems good to have.

Workaround for <https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538>.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1172

Signed-off-by: Simon McVittie <smcv@debian.org>

(cherry picked from commit c389aadff9)
2020-04-03 13:49:34 +02:00
Simon McVittie
e3b2b90c72 cogl: Don't allow creating sized textures with 0 pixels
A texture with no pixels isn't a useful thing to have, and breaks
assumptions elsewhere. For example, CoglFramebuffer assumes that after
a texture has been allocated, it will have width and height both greater
than 0.

In particular, this works around a crash when gnome-shell tries to blur a
background that hasn't yet had any space allocated for it - which it seems
is really an actor layout bug, but more robustness seems good to have.

Workaround for <https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538>.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1172

Signed-off-by: Simon McVittie <smcv@debian.org>

(cherry picked from commit 37eda498f2)
2020-04-03 13:48:46 +02:00
Daniel van Vugt
6f094bd399 clutter/master-clock-default: Sync timelines to hardware vsync
Previously clutter timelines advanced according to `g_source_get_time`.
But that meant the spatial stepping of animations was visibly sensitive to
any irregularities in the main loop. It also represented a time older [1]
than the intended presentation time of each frame.

Now we instead use `master_clock_get_next_presentation_time`. This ensures
we get the smoothness of hardware vsync as well as being closer to the
actual presentation time.

This means, for example, backends like Xorg that move the hardware cursor
independently of repaints will have their animations more closely matching
the hardware cursor position. So the cursor appears to stick more closely
when dragging windows or on the lock screen etc.

[1] "older" = (refresh_interval - sync_delay) = ~14ms for 60Hz

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/25

https://gitlab.gnome.org/GNOME/mutter/merge_requests/724
2020-04-03 10:59:36 +00:00
Daniel van Vugt
2c805524b4 clutter/stage: Add API to get_next_presentation_time
https://gitlab.gnome.org/GNOME/mutter/merge_requests/724
2020-04-03 10:59:36 +00:00
Andre Moreira Magalhaes
95c1baf3d1 clutter/click-action: Do not process captured event if action is disabled
Disabling a click action after a button-press but before a
button-release is captured makes ClutterClickAction connect to
captured-event and never disconnect.

This change fixes it by making sure the captured-event is only
processed if the action is still enabled, otherwise releasing
the action (reset state) and propagating the event.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1170


(cherry picked from commit 5f5ce08ba4)
2020-04-02 17:09:24 +00:00
Georges Basile Stavracas Neto
6f9b5edd4d tests/actor-pick: Allocate actor before picking
Picking now only happens on allocated actors, but the
callback in the actor-pick test is not waiting for the
stage to run an allocation cycle. Ideally, we'd wait
for this cycle, but for now, forcing an allocation works
as well.

Allocate the overlay actor in the actor-pick test.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169


(cherry picked from commit 7f488e3e1d)
2020-03-31 23:13:42 +00:00
Georges Basile Stavracas Neto
31809e1214 tests/actor-pick: Remove tabs
They're evil.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169


(cherry picked from commit 059d2144b2)
2020-03-31 23:13:15 +00:00
Andre Moreira Magalhaes
82f3bdd14e clutter/actor: Fix pick when actor is not allocated
When selecting the pick regions for an actor we were not considering
whether the actor was allocated and that was causing issues where the
preferred width/height of the actor was used when deciding whether
the actor should be considered as a pick target.

Check if the actor has a valid allocation, in addition to being mapped
and being in pick mode, in clutter_actor_should_pick_paint().

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169


(cherry picked from commit 902302a174)
2020-03-31 23:12:44 +00:00
Florian Müllner
52e5d6fc94 Bump version to 3.36.1
Update NEWS.
2020-03-30 21:29:03 +02:00
Robert Mader
09a6031c69 window-actor: Force full actor geometry sync when mapping
Normally we bail out in `sync_actor_geometry()`. The comment there
states:
```
Normally we want freezing a window to also freeze its position; this allows
windows to atomically move and resize together, either under app control,
or because the user is resizing from the left/top. But on initial placement
we need to assign a position, since immediately after the window
is shown, the map effect will go into effect and prevent further geometry
updates.
```

The signal for the initial sync originates in `MetaWindow` though and predates
`xdg_toplevel_set_maximized`, which again calls `meta_window_force_placement`,
triggering the signal too early. As a result, Wayland clients that start up
maximized have a wrong map animation, starting in the top-left corner.

In order to fix this without changing big parts of the geometry logic and risking
regressions, force the initial sync again before mapping.

Solution suggested by Jonas Ådahl.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1164
2020-03-30 15:59:48 +00:00
Robert Mader
dbe919ef92 wayland/surface: Check for surface role in meta_wayland_surface_get_window()
The function can get called without valid surface role, e.g. from
`zwp_xwayland_keyboard_grab_manager_grab()`.

Debugged by @piegamesde

Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1147
2020-03-30 16:08:13 +02:00
Christian Rauch
2907ee93cc wayland/pointer-constraints: Fix typo
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1163
2020-03-29 19:48:33 +01:00
Carlos Garnacho
aa136f4515 cogl-pango: Special case alpha of 0 for color glyphs
Like ed10aea44d, but for color glyphs. Since they do use the alpha
component from the given color.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1161
2020-03-29 12:53:39 +00:00
Florian Müllner
8748841094 cogl: Export two more functions
cogl_object_[get|set]_value_object() are annotated as [get|set]-value-func
for objects and primitives, so they must be visible for any derived types
to be usable from introspection.

https://gitlab.gnome.org/GNOME/mutter/-/issues/1146
2020-03-29 12:17:11 +00:00
Florian Müllner
86f2885e98 cogl: Remove obsolete .map file
Obsolete since commit 6885c37784.

https://gitlab.gnome.org/GNOME/mutter/-/issues/1146
2020-03-29 12:17:11 +00:00
Carlos Garnacho
bb5ea0580f wayland: Translate delete-surrounding properly to protocols
IBusInputContext/ClutterInputFocus/GtkIMContext all go for offset+len
for their ::delete-surrounding signals, with offset being a signed int
(neg. to delete towards left of selection, pos. to delete towards right
of selection) and len being an unsigned int from the offset (and
presumably, skipping the current selection).

The text-input protocols however pass in this event two unsigned integers,
one being the length of text to delete towards the left of the selection,
and another the length of text to delete towards the right of the selection.

To translate properly these semantics, positive offsets shouldn't account
for before_length, and negative offset+len shouldn't account for after_length.
The offset/length approach may of course represent deletions that are
detached from the current cursor/selection, we simply delete the whole range
from the cursor/selection positions then.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/517
2020-03-29 11:37:27 +00:00
Takao Fujiwara
2cfdbbd730 clutter: Enable negative offsets in delete surrounding text
The input method can assign a negative value to
clutter_input_method_delete_surrounding() to move the cursor to the left.
But Wayland protocol accepts positive values in delete_surrounding() and
GTK converts the values to the negative ones in
text_input_delete_surrounding_text_apply().

https://gitlab.gnome.org/GNOME/mutter/issues/539
2020-03-29 11:37:27 +00:00
Jonas Dreßler
9f31e7252c backends/native: Release virtual buttons on dispose instead of finalize
GObject recommends to break references to other objects on dispose
instead of finalize, also we want to release the pressed virtual buttons
as early as possible if we know the object is getting destroyed.

So release the pressed buttons and unref our virtual
MetaInputDeviceNative when the dispose vfunc is called, which also
allows us to release the buttons immediately from javascript instead of
waiting for the garbage collector by calling run_dispose() on the
object.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1157
2020-03-28 16:55:59 +00:00
Carlos Garnacho
e8ea5ecd8a cogl-pango: Factor in default color alpha again
In commit d846fabda we moved to using the override color alpha, however
it was missed that the actor opacity is transferred to the PangoRenderer
through the default color alpha, and the reason it was used there.

We actually want to factor in both alpha values, in order to respect
both foreground color alpha and actor opacity. This is done on the
unpremultiplied color, so we just need to change the alpha value.

Fixes effects on text actors that involve actor opacity.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1158
2020-03-28 12:48:11 +01:00
Florian Müllner
ed10aea44d cogl-pango: Special case alpha of 0
pango_renderer_get_alpha() returns 0 to indicate that the alpha value
should be inherited from the environment, but we are passing it on
(and therefore making the text fully translucent).

Instead, make the text fully opaque as expected.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1156
2020-03-28 01:04:17 +01:00
Georges Basile Stavracas Neto
fed5f4d9aa window-actor: Inhibit culling when blitting to screencast
This allows us to screencast any window continuously, even
without it being visible. Because it's still being painted,
clients continue to receive frame callbacks, and people
are happy again.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
2020-03-27 23:29:58 +00:00
Georges Basile Stavracas Neto
73250b8f4c clutter/actor: Add culling inhibiting API
This will allow us to continue painting actors that are
outside the visible boundaries of the stage view.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
2020-03-27 23:29:58 +00:00
Georges Basile Stavracas Neto
f6700f19a7 window-stream-src: Finish framebuffer after blitting
Just like what's done for monitor screencasting. Unfortunately, there's
no mechanism to share fences with PipeWire clients yet, which forces
us to guarantee that a frame is completed after blitting.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
2020-03-27 23:29:58 +00:00
Georges Basile Stavracas Neto
ea34915df3 window-stream-src: Implement cursor blitting
A regression compared to the old code, we're not drawing the cursor
when on EMBEDDED mode.

Blit the cursor to the screencast framebuffer when on EMBEDDED mode.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
2020-03-27 23:29:58 +00:00
Georges Basile Stavracas Neto
37742c5cde window-stream-src: Ensure initial frame is recorded
MetaScreenCastWindowStreamSrc connects to the "damaged" signal of
MetaWindowActor. This signal is not exactly tied to the paint cycle
of the stage, and a damage may take quite a while to arrive when
a client doesn't want to draw anything. For that reason, the window
screencast can start empty, waiting for a damage to arrive.

Ensure at least one frame is recorded when enabling the window stream.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1097

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
2020-03-27 23:29:57 +00:00
Georges Basile Stavracas Neto
cdd27d0e53 window-actor: Clip before translate when blitting
cogl_framebuffer_push_rectangle_clip() acts on the current modelview
matrix. That means the result of clipping then translating will be
different of the result of translating then clipping.

What we want for window screencasting is the former, not the latter.
Move the translation code (and associated) to after clipping.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1097

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
2020-03-27 23:29:57 +00:00
Georges Basile Stavracas Neto
82778f72a4 window-actor: Shuffle some lines around
Move the CoglColor assignment right above the cogl_framebuffer_clear() call,
and let these wonderful partners together to delight us with an easier to
read code.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
2020-03-27 23:29:57 +00:00
Carlos Garnacho
d846fabda2 cogl-pango: Forward alpha from correct color
Use the override color alpha, if set.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1155
2020-03-27 23:33:38 +01:00
Carlos Garnacho
2d94a34a14 cogl-pango: Honor foreground alpha PangoAttribute
Instead of hardcoding 0xff as alpha, forward this attribute.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1155
2020-03-27 23:33:35 +01:00
Jonas Dreßler
92710d8f89 clutter/stage-cogl: Check for buffer age early
Fix a regression that got introduced with
c483b52d24 where we started passing the
redraw_clip to paint_stage() instead of creating a temporary view_region
for unclipped redraws: In case we detect an invalid buffer age, we fall
back to doing an unclipped redraw after we passed the first check
setting up may_use_clipped_redraw. That means we didn't reset the
redraw_clip to the view_rect, and we're now going to redraw the stage
using the original redraw clip even though we're swapping the full
framebuffer without damage.

To fix that, check for the buffer age before setting up the
fb_clip_region and the redraw_clip and set may_use_clipped_redraw to
FALSE if the buffer age is invalid, too. This ensures the redraw_clip is
always going to be correctly set to the view rect when we want to force
a full redraw.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/1128
2020-03-27 16:37:45 +00:00
Hans de Goede
da600b8400 cursor-renderer-native: Take panel-orientation into account for sprite transform
When calculating the transform we should apply to the cursor sprite
before uploading it to the cursor plane, we must also take into
account non upright mounted LCD panels.

Otherwise the cursor ends up 90 degrees rotated on devices where the
LCD panel is mounted 90 degrees rotated in its enclosure.

This commit fixes this by calling meta_monitor_logical_to_crtc_transform
in get_common_crtc_sprite_transform_for_logical_monitors to adjust the
transform for each Monitor in the LogicalMonitor.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1123

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1153
2020-03-27 15:10:35 +00:00
Robert Mader
6aa546145f core: Demote tiff and bmp image formats in the clipboard manager
Support for them appears to be way less common than e.g. png, which is
currently the preferred format from Firefox, Chromium, Libreoffice and others.
Adopt to that fact.

As a side effect, this works around a bug observed when copying images in
Firefox on Wayland.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1141
2020-03-27 14:37:29 +00:00
Georges Basile Stavracas Neto
3956ffd5e8 cogl/driver: Remove GError from context_init
It is not used by anyone, let's just remove it.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1152
2020-03-27 09:01:43 -03:00
Georges Basile Stavracas Neto
05341221d4 cogl/renderer: Remove documentation of nonexistent enum
We don't want to delve into the philosohical study of the not-being,
so let's just not document an enum value that doesn't exist anymore.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1151
2020-03-26 18:44:13 -03:00
Georges Basile Stavracas Neto
95642d05a6 cogl/gl: Move shared functions to shared file
Cogl shares some GL functions between the GLES and the big
GL drivers. Namely, it shares _cogl_driver_gl_context_init
and _cogl_driver_gl_context_deinit between these two drivers.

The plot twist is: even though these functions are shared and
their prototypes are in cogl-util-gl-private.h, they're actually
implemented inside cogl-driver-gl.c, which is strictly only
about the big GL driver.

This is problematic when building Mutter on ARM v7, where we
need to disable OpenGL, but keep GLES enabled.

Fix this by moving the shared GL functions to a shared GL file.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1151
2020-03-26 18:43:32 -03:00
Georges Basile Stavracas Neto
51cd8aed96 ci: Add a new 'build-without-opengl-and-glx' step
To make sure we don't regress with this specific set of flags.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1151
2020-03-26 18:24:54 -03:00
Jonas Ådahl
ac01e69a67 window-wayland: Don't use grab op for some other window when resizing
When resizing a window interactively, we'll set a grab operation and a
grab window, among other things. If we're resizing (including setting
initial size, i.e. mapping) another window, that didn't change position,
don't use the gravity of the grab operation when resizing our own
window.

This fixes an issue with jumpy popup position when moving a previously
mapped gtk popover.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/999
2020-03-26 17:44:09 +01:00
Jonas Ådahl
a68e6972a2 cursor-renderer-native: Set cursor hotspot metadata on plane assignment
This triggers the paths in the legacy KMS backend to use
drmModeSetCursor2(), making virtual machines using "seamless mouse mode"
behave correctly again.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1094

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1136
2020-03-26 16:18:28 +00:00
Jonas Ådahl
55cf1c1496 kms/plane-assignment: Add API to set cursor hotspot metadata
The transactional KMS API has been modelled after atomic KMS. Atomic KMS
currently doesn't support forwarding cursor hotspot metadata, thus it
was left out of the transactional KMS API having the user set the simply
create a plane assigment with the cursor sprite assigned to a cursor
plane using regular coordinates.

This, however, proved to be inadequate for virtual machines using
"seamless mouse mode" where they rely on the cursor position to
correspond to the actual cursor position of the virtual machine, not the
cursor plane. In effect, this caused cursor positions to look "shifted".

Fix this by adding back the hotspot metadata, right now as a optional
field to the plane assignment. In the legacy KMS implementation, this is
translated into drmModeSetCursor2() just as before, while still falling
back to drmModeSetCursor() with the plane coordinates, if either there
was no hotspot set, or if drmModeSetCursor2() failed.

Eventually, the atomic KMS API will learn about hotspots, but when
adding our own atomic KMS backend to the transacitonal KMS API, we must
until then still fall back to legacy KMS for virtual machines.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1136
2020-03-26 16:18:28 +00:00
Jonas Ådahl
343de21af5 monitor-transform: Add API to transform point
Transforms a point in a rectangle with the origin (0, 0). To be used to
transform cursor hotspots within a cursor sprite.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1136
2020-03-26 16:18:28 +00:00
Jonas Ådahl
3c157242fa cursor-sprite: Add API to get dimension
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1136
2020-03-26 16:18:28 +00:00
Jonas Ådahl
32c99513c8 clutter/actor: Inherit cloned painting when calculating resource scale
When calculating the resource scale of a clone source, we might end up
in situations where we fail to do so, even though we're in a paint. A
real world example when this may happen if this happens:

 * A client creates a toplevel window
 * A client creates a modal dialog for said toplevel window
 * Said client commits a buffer to the modal before the toplevel

If GNOME Shell is in overview mode, the window group is hidden, and the
toplevel window actor is hidden. When the clone tries to paint, it fails
to calculate the resource scale, as the parent of the parent (window
group) is not currently mapped. It would have succeeded if only the
clone source was unmapped, as it deals with the unmapped actor painting
by setting intermediate state while painting, but this does not work
when the *parent* of the source is unmapped as well.

Fix this by inheriting the unmapped clone paint even when calculating
the resource scale.

This also adds a test case that mimics the sequence of events otherwise
triggered by a client. We can't add a Wayland client to test this, where
we actually crash is in the offscreen redirect effect used by the window
dimming feature in GNOME Shell.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/808

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1147
2020-03-26 11:42:23 +01:00
Jonas Ådahl
40c345d6f3 cursor-sprite-xcursor: Emulate Wayland hotspot limitations
For HiDPI pointer cursors backed by Wayland surfaces, the hotspot must
be placed using integers on the logical pixel grid. In practice what
this means is that if the client loads a cursor sprite with the buffer
scale 2, and it's hotspot is not dividable by 2, it will be rounded
down to an integer that can. E.g. a wl_surface with buffer scale 2 and a
cursor image with hotspot coordinate (7, 7) will have the coordinate
(3.5, 3.5) in surface coordinate space, and will in practice be rounded
down to (3, 3) as the hotspot position in wl_pointer only takes
integers.

To not potentially shift by 1 pixel on HiDPI monitors when switching
between wl_surface backend cursor sprites and built-in ones, make the
built in one emulate the restrictions put up by the Wayland protocol.

This also initializes the theme scale of the xcursor sprite instances to
1, as they may not have been set prior to being used, it'll only happen
in response to "prepare-at" signals being emitted prior to rendering.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1092

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1107
2020-03-26 08:47:37 +00:00
Jonas Ådahl
8beef8ccd0 shaped-texture: Fix use-nearest check when viewports are scaled
We checked that the content size was appropriately painted in the stage,
but didn't take into account that the size of the sampled texture
region, meaning that when stage views were scaled, we'd think that we
would draw a texture scaled, as e.g. a 200x200 sized texture with buffer
scale 2 would have the size 100x100. When stage views were not scaled,
we'd apply a geometry scale meaning it'd end up as 200x200 anyway, thus
pass the check, but when stage views are scaled, it'd still be painted
as a 100x100 shaped texture on the stage, thus failing the
are-we-unscaled test.

Fix this by comparing the transformed paint size with the sampled size,
instead of the paint size again, when checking whether we are being
painted scaled or not. For example, when stage views are scaled, our
200x200 buffer with buffer scale 2, thus content size 100x100 will
transform to a 200x200 paint command, thus passing the test. For
non-scaled stage views, our 200x200 buffer with buffer scale 2 thus
content size 100x100 will also transform into a 200x200 paint command,
and will also pass the check, as the texture sample region is still
200x200.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/804

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1124
2020-03-26 08:32:46 +00:00
Jonas Ådahl
62d0dd907b clutter-utils: Fix a couple of coding style issues
Multiple assignments on the same line were split up, so was a super long
line.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1124
2020-03-26 08:32:46 +00:00
Jonas Ådahl
0462208d4e crtc-xrandr: Respect configured RANDR panning
A user may have configured an output to be panning, e.g. using xrandr
--output <output> --mode <mode> --panning <size>. Respect this by making
the logical monitor use the panning size, instead of the mode. This
makes e.g. makes the background cover the whole panning size, and panels
etc will cover the whole top of the panned area, instead of just the top
left part covering the monitor if having panned to (0, 0).

No support is added to configuring panning, i.e. a panned monitor
configuration cannot be stored in monitors.xml.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1085
2020-03-26 09:24:25 +01:00
Jonas Ådahl
6885c37784 cogl: Mark exported cogl symbols using COGL_EXPORT
Just like libmutter-clutter, and libmutter, mark exported symbols with
an COGL_EXPORT macro. This removes the .map and .map.in files previously
used, containing a list of semi private symbols. This symbol was out of
date, i.e. pointed to non-existing symbols, and was also replaced with
COGL_EXPORT macros.

unit_test_* symbols are exported by the help of the unit test defining
macro. test_* symbols are no longer supported as it proved unnecessary.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1059
2020-03-26 09:05:38 +01:00
Jonas Ådahl
238e41d493 cogl: Install cogl-trace.h and include from cogl.h
This is so that cogl-trace.h can start using things from cogl-macros.h,
and so that it doesn't leak cogl-config.h into the world, while exposing
it to e.g. gnome-shell so that it can make use of it as well. There is
no practical reason why we shouldn't just include cogl-trace.h via
cogl.h as we do with everything else.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1059
2020-03-26 09:05:38 +01:00
Carlos Garnacho
8699482475 backends: Check both input settings and mapper for tablet monitors
The upper layers (OSDs basically) want to know the monitor that a
tablet is currently assigned to, not the monitor just as configured
through settings.

This broke proper OSD positioning for display-attached tablets since
commit 87858a4e01, as the MetaInputMapper kicks in precisely when
there is no configured monitor for the given device.

Consulting both about the assigned output will make OSDs pop up
again in the right place.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/971
2020-03-25 19:09:32 +00:00
Carlos Garnacho
dcaa45fc0c backends/x11: Implement is_grouped for X11
If the devices have a wacom description, compare those. Otherwise,
look up the devices' VID:PID, if they match they should also be
grouped.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/971
2020-03-25 19:09:32 +00:00
Carlos Garnacho
3c4f5ddcb4 core: Let pad mode switch events always go through MetaInputSettings
We used to inhibit all pad actions while the OSD is shown, but one we
would actually want to handle are mode switches while the OSD is open.
So it has an opportunity to catch up to the mode switch.

This lets MetaInputSettings reflect the mode switch (eg. when querying
action labels), so the OSD has an opportunity to update the current
actions.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/975
2020-03-25 19:56:09 +01:00
Carlos Garnacho
3aece84499 cogl-pango: Make color glyphs unaffected by foreground color
Making color glyphs affected by the foreground color makes them become
"tinted" on any other color than white. Make it sure we always paint
those white by checking the cached glyph value, the foreground color
will be reset on the next iteration through glyphs.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/850

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1148
2020-03-25 11:14:33 +00:00
Carlos Garnacho
40fb06ca17 cogl-pango: Cache whether glyphs are backed up by a color font
This will be necessary later on.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1148
2020-03-25 11:14:33 +00:00
Florian Müllner
d4c070da88 window: Really propagate effective on-all-workspaces setting to transients
Commit cda9579034 fixed a corner case when setting the initial workspace
state of transient windows, but it still missed a case:

should_be_on_all_workspaces() returns whether the window should be on all
workspaces according to its properties/placement, but it doesn't take
transient relations into account.

That means in case of nested transients, we can still fail the assert:

 1. on-all-workspaces toplevel
 2. should_be_on_all_workspaces() is TRUE for the first transient's parent,
    as the window from (1) has on_all_workspaces_requested == TRUE
 3. should_be_on_all_workspaces() is FALSE for the second transient's
    parent, as the window from (2) is only on-all-workspace because
    of its parent

We can fix this by either using the state from the root ancestor
instead of the direct transient parent, or by using the parent's
on_all_workspaces_state.

The latter is simpler, so go with that.

https://gitlab.gnome.org/GNOME/mutter/issues/1083
2020-03-24 18:15:33 +00:00
Carlos Garnacho
d052f9c070 backends: Drop internal WacomDevice in MetaInputSettings
Use the one from MetaInputDevice instead. Since we no longer try
to ask for WacomDevices that weren't first retrieved:

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1086

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1109
2020-03-24 18:07:31 +00:00
Carlos Garnacho
3b88af94e3 backends/x11: Drop internal WacomDevice lookups
Just use the ones from MetaInputDevice.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1109
2020-03-24 18:07:31 +00:00
Carlos Garnacho
1f00aba92c backends: Add MetaInputDevice derivable class
This class sits between ClutterInputDevice and the backend implementations,
it will be the despositary of features we need across both backends, but
don't need to offer through Clutter's API.

As a first thing to have there, add a getter for a WacomDevice. This is
something scattered across and somewhat inconsistent (eg. different places
of the code create wacom devices for different device types). Just make it
here for all devices, so users can pick.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1109
2020-03-24 18:07:31 +00:00
Carlos Garnacho
ec1195e3ff backends: Fix configuration changes to tap[-and-drag]
Most people just see a harmless warning when applying this setting to
all touchpads (which this patch fixes). But tap[-and-drag] is supposed
to remain enabled for display-less Wacom tablets, despite configuration
changes.

Fix this by using the mapping function, so the setting is forced on for
wacom devices. This happens on a per-device basis, so the warning is
gone too.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1145
2020-03-24 17:05:12 +00:00
Carlos Garnacho
18b661cc93 backends: Add mapping function arg to settings_set_bool_setting()
This will be useful to actually determine on a per-device basis the
setting being applied, while still doing changes on a per-device-type
basis.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1145
2020-03-24 17:05:12 +00:00
Carlos Garnacho
8592a8591b wayland: Handle NULL preedit text
The preedit text may be NULL (eg. when unsetting it). This started
causing crashes since commit db9b60cc63, duh.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1132
2020-03-24 16:07:44 +00:00
Peter Hutterer
7fa7c2aeb7 backends: use the enum name instead of a literal 0
No functional change.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1144
2020-03-24 15:46:43 +10:00
Robert Mader
41130b08eb surface-actor: Add culling offset for geometry scale
This fixes a case that was overlooked in
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1036 - when we
have a geometry scale > 1 and Wayland subsurfaces that have an offset
to their parent surface (which is often the case when the toplevel surface
includes decoration/shadows etc.), we have to add extra offset to their
opaque regions so they match their 'visible' location.

This is necessary as `meta_cullable_cull_out_children` moves the coordinate
system during culling, but does not know about geometry scale.

Also, remove the redundant check for `window_actor` - we only hit this code
path if a `window_actor` culls out its children.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1108
2020-03-23 20:28:59 +01:00
Robert Mader
1d20045247 surface-actor: Fix memory leak
When we create a new region for an opaque texture we need to free it.
While on it, simplify the check slightly.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1108
2020-03-23 18:10:28 +00:00
Carlos Garnacho
c131a9b7fa backends/x11: Observe multiple pad mode switch buttons in a group
Some tablets like the Cintiq 24HDT have several mode switch buttons
per group. Those are meant to jump straight to a given mode, however
we just handle cycling across modes (as most other tablets have a
single mode switch button per group).

So spice up the mode switch handling so we handle multiple mode
switch buttons, assigning each of them a mode. If the device only
has one mode switch button, we do the old-fashioned cycling.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/970
2020-03-20 21:30:30 +01:00
Carlos Garnacho
2ecbf6d746 x11: Handle windowing errors while writing selection INCR data
This error was just logged but not raised. Do as the code comment said
and raise a pipe error at that moment, and for subsequent operations
on the output stream (although none besides close() should be expected
after propagating the error properly).

Related: https://gitlab.gnome.org/GNOME/mutter/issues/1065
2020-03-20 16:14:07 +01:00
Daniel Șerbănescu
a13d60aae5 Update Romanian translation 2020-03-19 10:59:57 +00:00
Robert Mader
ed4b80cee5 clutter/stage: Rename parameters to match documentation
To silence warnings during GIR generation.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1133
2020-03-18 02:45:43 +01:00
Jonas Ådahl
0a6034ef3a monitor-manager: Remove 'mirror' capability
With per-CRTC views, there is nothing stopping NVIDA EGLStream based
rendering to not support monitor mirroring, so lets remove that
restriction.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1098
2020-03-18 00:46:20 +00:00
Jonas Ådahl
c9a5b2b22f kms-impl-simple: Handle lack of cached mode set in flip fallback
When a page flip fails with a certain error code, we've treated this as
a hint that page flipping is broken and we should try to use mode
setting instead.

On some drivers, it seems that this error is also reported when there
was no mode set, which means we'll have no cached mode set to use in the
fallback. The lack of prior mode set tends to happen when we hit a race
when the DRM objects change before we have the time to process a hotplug
event.

Handle the lack a missing mode set in the flip fallback path, with the
assumption that we'll get a hotplug event that'll fix things up for us
eventually.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/917
2020-03-18 00:33:03 +00:00
Carlos Garnacho
db9b60cc63 wayland: Represent preedit string cursor offset in bytes
Both IBus and ClutterInputFocus work in character offsets for the cursor
position in the preedit string. However the zwp_text_input protocol does
define the preedit string cursor offset to be in bytes.

Fixes client bugs in representing the caret within the preedit string,
as we were clearly giving the wrong offset.

Fixes: https://gitlab.gnome.org/GNOME/gtk/issues/2517

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1132
2020-03-17 22:15:52 +00:00
Jonas Ådahl
fa74da0039 wayland/window: Ignore state changes for popups
We send configure events for state changes e.g. for `appears-focused`,
etc. What we don't want to do is to do this for popup windows, as in
Wayland don't care about this state.

When the focus mode was configured to "sloppy focus" we'd get
`appears-focused` state changes for the popup window only by moving the
mouse cursor around, and while a popup may care about focus, it does not
care about related appearance, as there is no such state in xdg_popup.

What these state changes instead resulted in was absolute window
configuration events, intended for toplevel (xdg_toplevel) windows. In
the end this caused the popup to be positioned aginst at (0, 0) of the
parent window, as the assumptions when the configuration of the popup
was acknowledged is that it had received a relative position window
configuration.

Fix this by simply ignoring any state changes of the window if it is a
popup, meaning we won't send any configuration events intended for
toplevels for state changes. Currently we don't have any way to know
this other than checking whether it has a placement rule. Cleaning up
MetaWindow creation is left to be dealt with another day.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1103

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1122
2020-03-17 21:59:02 +00:00
Corentin Noël
b310e1d9d7 clutter-stage: Add annotations to clutter_stage_capture
Especially document that out_captures is an array that is given as output.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1131
2020-03-17 15:14:57 +01:00
Corentin Noël
0053ef2e16 cogl-texture: Add some missing array annotations
This allows bindings to correctly understand that it is an array

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1130
2020-03-17 13:30:31 +01:00
Robert Mader
4133b73632 cursor-renderer/native: Skip hw cursor upload if we can't use it
If the CRTCs the cursor is visible on do not share a common scale
and transform, we can't use the cursor hardware plane as we only have one.
We therefore fall back to software / gl cursor.

The check for that currently happens after we tried to upload the cursor image
to the hardware plane though.
This is made worse by the fact that in the scaling step, where we scale the
cursor image to the desired size, until now we expected a valid common scale -
otherwise scaling the image by an uninitialized float.

Make sure we bail out early during the scale/upload step if we don't have common
scales and transforms - to avoid that bug and save some unnecessary work.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1125
2020-03-16 21:51:30 +01:00
Daniel van Vugt
074f4974dd input-settings: Specify middle-click-emulation key
Which exists, unlike `emulate-middle`.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1124
2020-03-16 15:09:00 +08:00
Andrew Gaul
0700f3749f input-settings/x11: Fix typo in has_udev_property
https://gitlab.gnome.org/GNOME/mutter/merge_requests/256
2020-03-15 13:04:32 +09:00
Andrew Gaul
0487e6f11f input-settings: Wire up middle-emulation
This allows emulating middle click via simultaneous left and right
click.  Fixes #238.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/256
2020-03-15 13:04:32 +09:00
Carlos Garnacho
23da6c2426 keybindings: Check the special modifiers specifically
Make sure it is only the special modifier (hardcoded to 1 currently)
which is being pressed (not counting locked modifiers) before notifying
that the special modifier is pressed, as we are interested in it being
pressed alone and not in combination with other modifier keys.

This helps in two ways:
- Pressing alt, then ctrl, then releasing both won't trigger the locate
  pointer action.
- Pressing alt, then ctrl, then down/up to switch workspace won't interpret
  the last up/down keypress as an additional key on top of the special ctrl
  modifier, thus won't be forwarded down to the focused client in the last
  second.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/812

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1014
2020-03-13 21:37:32 +01:00
Carlos Garnacho
67dd0b4fec keybindings: Avoid double calls to process_event() on the same event
If you first press a key that triggers the "special modifier key" paths
(ctrl, super), and then press another key that doesn't match (yet?) any
keybindings (eg. ctrl+alt, super+x), the second key press goes twice
through process_event(), once in the processing of this so far special
combination and another while we let the event through.

In order to keep things consistent, handle it differently depending on
whether we are a wayland compositor or not. For X11, consider the event
handled after the call to process_event() in process_special_modifier_key().
For Wayland, as XIAllowEvents is not the mechanism that allows clients see
the key event, we can just fall through the regular paths, without this
special handling.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1014
2020-03-13 21:22:28 +01:00
Andre Moreira Magalhaes
6989fea767 cogl: Fix build error when GL_ARB_sync is not defined
Commit 41992757e0 introduced a change to use CoglContext.glFenceSync
but this method is only available when GL_ARB_sync is defined (as
defined on gl-prototypes/cogl-all-functions.h).

This change fixes that.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1123
2020-03-12 18:05:10 -03:00
Corentin Noël
df33255162 cogl: Add main header for Cogl
This allows bindings linking to the C header to actually have the right one.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1101
2020-03-12 13:35:25 +00:00
Jonas Ådahl
5319949a45 kms-impl-device: Clean up state if drm resources disappear
It may happen that drmModeGetResources() starts returning NULL. Handle
this gracefully by removing all connectors, CRTCs and planes making the
device in practice defunct.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1121
2020-03-12 13:08:46 +00:00
Alynx Zhou
aba0b9ef64 keybindings: Move common window grab code out of X-only if statement
`3c8d4171` moved some common codes into X11-only code blocks by mistake,
and it prevents keyboard window resize/move mode under Wayland because
those variables are unset. This commit fixed it via moving such common
codes out of X11-only code blocks.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/949

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/997
2020-03-12 08:42:04 +00:00
Jonas Ådahl
512bb7d1cd wayland: Don't crash when trying to fullscreen on inert wl_output
There is a race where an output can be used as a fullscreen target, but
it has already been removed due to a hotplug. Handle this gracefully by
ignoring said output in such situations.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1120
2020-03-11 14:37:09 +00:00
Jonas Ådahl
d2a12ee0fa crtc-xrandr: Compare right coordinate when checking assignment
Compare x with x, and y with y, not y with x.

Fixes an issue where only changing the scale doesn't actually apply the
new scale.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1119
2020-03-11 13:02:50 +00:00
Jonas Ådahl
531a195cf1 monitor-config-manager: Respect layout mode when calculating CRTC layout
The scale used when calculating the CRTC layout should only come from
the logical monitor scale if the layout mode of the corresponding
configuration is 'logical'.

This fixes an issue where the X11 screen size accidentally got set to a
size scaled down by the configured global UI scale.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1107
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1109

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1118
2020-03-11 12:55:03 +00:00
Sebastian Keller
509e9ca5a0 xwayland: Fix mime type atom list leak on DnD with more than 3 types
Found using the clang static analyzer

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1117
2020-03-11 03:21:36 +01:00
Olivier Fourdan
0743381573 window/x11: Rename meta_window_x11_buffer_rect_to_frame_rect
To keep consistent and avoid confusion, rename the function:
    `meta_window_x11_buffer_rect_to_frame_rect()`
to:
    `meta_window_x11_surface_rect_to_frame_rect()`

As this function doesn't deal with the `window->buffer_rect` at all.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
2020-03-10 14:52:26 +01:00
Olivier Fourdan
267f712068 window-actor/x11: Use the new MetaShapedTexture API
The code in `build_and_scan_frame_mask` predates the introduction of the
`MetaShapedTexture` API to get the texture width hand height.

Use the new `meta_shaped_texture_get_width/height` API instead of using
the CoGL paint texture.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
2020-03-10 14:52:26 +01:00
Olivier Fourdan
0b102afb53 xwayland: Update regions on texture updates
For X11 clients running on Wayland, the actual texture is set by
Xwayland.

The shape, input and opaque regions, however are driven by X11
properties meaning that those may come at a different time than the
actual update of the content.

This results in black areas being visible at times on resize with
Xwayland clients.

To make sure we update all the regions at the same time the buffer is
updated, update the shape, input and opaque regions when the texture is
committed from when the Xwayland surface state is synchronized.

That fixes the remaining black areas being sometimes visible when
resizing client-side decorations windows on Xwayland.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1007
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
2020-03-10 14:52:26 +01:00
Olivier Fourdan
304a103659 window-actor: Add API to update regions
For X11 clients running on Xwayland, the opaque, input and shape regions
are processed from different properties and may occur at a different
time, before the actual buffer is eventually committed by Xwayland.

Add a new API `update_regions` to window actor to trigger the update of
those regions when needed.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
2020-03-10 14:52:26 +01:00
Olivier Fourdan
2d09e95934 window-actor/x11: Compute client area from surface size
Commit 7dbb4bc3 cached the client area when the client was frozen.

This is not sufficient though, because the buffer size might still be
lagging waiting for the buffer from Xwayland to be committed.

So instead of caching the client size from the expected size, deduce the
client area rectangle from the surface size, like we did for the frame
bounds in commit 1ce933e2.

This partly reverts commit 7dbb4bc3 - "window-actor/x11: Cache the
client area"

https://gitlab.gnome.org/GNOME/mutter/issues/1007
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
2020-03-10 14:52:26 +01:00
Olivier Fourdan
be11525b28 window/x11: Add function to convert the surface to client area
Add a convenient function to get the client area rectangle from a given
surface rectangle.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
2020-03-10 14:52:26 +01:00
Robert Mader
adc38f902a window-actor/X11: Update shape, input and opaque region in order
As they depend on each other to be correct, we should set all of them
in the correct order. As we do already have a function for that, use it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1091
2020-03-10 14:52:26 +01:00
Pekka Paalanen
8abdf16a39 cursor-renderer/native: Handle GPU hotplug
Listen for GPU hotplug events to initialize their cursor support.

This fixes one reason for why DisplayLink devices may not be using a hardware
cursor. Particularly, when a DisplayLink device is hotplugged for the first
time such that EVDI creates a new DRM device node after gnome-shell has already
started, we used to forget to initialize the cursor support.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1097
2020-03-10 08:26:17 +00:00
Pekka Paalanen
4cc29cfb61 cursor-renderer/native: Refactor init to per-gpu
Extract the code to initialize a single GPU cursor support into its own
function. The new function will be used by GPU hotplug in the future.

This is a pure refactoring without any behavioral changes.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1097
2020-03-10 08:26:17 +00:00
Mart Raudsepp
121c5d2a92 meson: Expand on xwayland_initfd option description
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1104
2020-03-09 17:59:25 +00:00
Olivier Fourdan
50ff30bf2b xwayland: Log actual error message if available
If X11 initialization fails, print the actual error message if the error
is set, to help with debugging.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1102
2020-03-09 17:49:51 +00:00
Jonas Ådahl
26e1e495a0 screen-cast-stream-src: Don't leak GSource
For every stream src, we created and attached a GSource. Upon stream
src destruction, we g_source_destroy():ed the GSource. What
g_source_destroy() does, hawever, is not really "destroy" it but only
detaches it from the main context removing the reference the context had
added for it via g_source_attach(). This caused the GSource to leak,
although in a detached state, as the reference taken on creation was
still held.

Fix this by also removing our own reference to it when finalizing.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1106
2020-03-09 17:31:23 +00:00
Jonas Ådahl
480e7d44be screen-cast-stream-src: Don't complain when we can't dequeue buffer
PipeWire will be unable to dequeue a buffer if all are already busy.
This can happen for valid reasons, e.g. the stream consumer not being
fast enough, so don't complain in the journal if it happens.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1115
2020-03-09 17:46:54 +01:00
Марко Костић
1c1adb0036 Update Serbian translation 2020-03-08 20:20:38 +00:00
Florian Müllner
6b852e6cb3 Bump version to 3.36.0
Update NEWS.
2020-03-07 22:51:06 +01:00
Jonas Ådahl
6e966e47f2 cursor-renderer-native: Handle lack of cursor planes gracefully
While we will always have cursor planes, as we'll currently create fake
ones when real ones are missing (See #1058), eventually we will run into
situations where we can't create fake ones, for example for atomic KMS
drivers that don't advertise any cursor planes.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1079
2020-03-07 21:40:50 +00:00
Jonas Ådahl
227eea1e31 kms-impl-simple: Add fake cursor planes if no real ones
Non-atomic drivers may support drmModeSetCursor() even if no cursor
plane is advertised. To deal with this, add a fake cursor plane for
every CRTC when using MetaKmsImplSimple. This will eventually be
translated to drmModeSetCursor() calls without any explicit cursor plane
usage.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1058

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1079
2020-03-07 21:40:50 +00:00
Nathan Follens
79920d66d4 Update Dutch translation 2020-03-07 21:11:51 +00:00
Jonas Ådahl
6cd0aa429f window: Force placement for first placement rule
If we don't force the placement, we enter the constrain machinery with
the position (0, 0), meaning we always get the "current work area" setup
to correspond to whatever logical monitor was at that position.

Avoid this by doing the same as "meta_window_force_placement()" and set
"window->calc_placement" to TRUE while move-resizing, causing the
move-resize to first calculate the initial position.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1098

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1110
2020-03-06 17:28:09 +01:00
Aman Alam
15d3de0099 Update Punjabi translation 2020-03-05 03:53:57 +00:00
Andre Klapper
38fb59a6a6 Fix broken markup in Welsh UI translation 2020-03-05 00:43:05 +01:00
Daniel Korostil
748f5bb3e6 Update Ukrainian translation 2020-03-04 16:47:45 +00:00
Milo Casagrande
3c55475391 Update Italian translation 2020-03-03 10:43:50 +00:00
Guillaume Bernard
dd6e371bac Update French translation 2020-03-03 08:31:16 +00:00
Anders Jonsson
00d900e46d Update Swedish translation 2020-03-02 18:50:50 +00:00
Goran Vidović
a4f11bef47 Update Croatian translation 2020-03-01 15:55:04 +00:00
Aurimas Černius
c4f76622a6 Updated Lithuanian translation 2020-03-01 14:48:05 +02:00
Florian Müllner
f80e5dd8e4 Bump version to 3.35.92
Update NEWS.
2020-03-01 02:25:34 +01:00
Matej Urbančič
f484efaac1 Updated Slovenian translation 2020-02-29 22:48:56 +01:00
Jonas Ådahl
f97804f4f4 wayland/xdg-shell: Add support for explicit popup repositioning
This commit completes the implementation of `xdg_wm_base` version 3,
which introduces support for synchronized implicit and explicit popup
repositioning.

Explicit repositioning works by the client providing a new
`xdg_positioner` object via a new request `xdg_popup.reposition`. If the
repositioning is done in combination with the parent itself being
reconfigured, the to be committed state of the parent is provided by the
client via the `xdg_positioner` object, using
`xdg_positioner.set__parent_configure`.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
5c37f5104e wayland/xdg-shell: Add support implicit popup moving
This sets the `is_reactive` flag on the window placement rules, causing
the popups to be reconfigured as they are affected by environmental
changes, such as the parent moving in a way making the popup partially
offscreen.

As with synchronization, the implementation is dormant, as the
version of the advertised global isn't bumped yet, as the new protocol
version is not yet fully implemented.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
d08a8de265 window: Implement asynchronous popup moving
This commits adds support on the MetaWindow and constraints engine side
for asynchronously repositioning a window with a placement rule, either
due to environmental changes (e.g. parent moved) or explicitly done so
via `meta_window_update_placement_rule()`.

This is so far unused, as placement rules where this functionality is
triggered are not yet constructed by the xdg-shell implementation, and
no users of `meta_window_update_placement_rule()` exists yet.

To summarize, it works by making it possible to produce placement rules
with the parent rectangle a window should be placed against, while
creating a pending configuration that is not applied until acknowledged
by the client using the xdg-shell configure/ack_configure mechanisms.

An "temporary" constrain result is added to deal with situations
where the client window *must* move immediately even though it has not yet
acknowledged a new configuration that was sent. This happens for example
when the parent window is moved, causing the popup window to change its
relative position e.g. because it ended up partially off-screen. In this
situation, the temporary position corresponds to the result of the
movement of the parent, while the pending (asynchronously configured)
position is the relative one given the new constraining result.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
6c82feb1b8 wayland/window-configuration: Track resize flags and gravity too
Will later be used to determine in what way a pending configuration will
resize.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
0dac91cffc Add MetaGravity and replace X11 equivalent with it
MetaGravity is an enum, where the values match the X11 macros used for
gravity, with the exception that `ForgetGravity` was renamed
`META_GRAVITY_NONE` to have less of a obscure name.

The motivation for this is to rely less on libX11 data types and macros
in generic code.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
ff381d1d52 constraints: Pass constrained relative coordinates to window impl
A placement rule placed window positions itself relative to its parent,
thus converting between relative coordinates to absolute coordinates,
then back to relative coordinates implies unwanted restrictions for
example when the absolute coordinate should not be calculated againts
the current parent window position.

Deal with this by keeping track of the relative position all the way
from the constraining engine to the move-resize window implementation.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
05e9d6ab9e window: Put placement related fields in a anynomous struct
To organize things a bit better, put the fields related to the placement
rule state in its own anonymous struct inside MetaWindow. While at it,
rename the somewhat oddly named variable that in practice means the
current relative window position.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
d22f947bf5 wayland/window: Pass popup configuration using relative coordinates
After popup placement rules have gone through the constraints engine has
ended up resulting in an actual move, pass the window configuration down
the path using relative coordinates, as that is what the next layer
(xdg-shell implementation) actually cares about.

In the future, this will also be helpful when the configured position is
not against the current state of the parent.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
9b97e5ed58 place: Make placement rule processing provide relative coordinates
A placement rule is always about placing a window relative to its
parent. In order to eventually place it against predicted future parent
positions, make the placement rule processing output relative
coordinates, having the caller deal with turning them into absolute.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Jonas Ådahl
7f9fac2ba2 window/wayland: Don't inhibit finishing moves if any window is resized
meta_window_wayland_finish_move_resize() inhibited window moves to be
finished if there was a resize grab active at the time, in order to
handle window resizing. Change this to only affect the grabbed window
itself, so that e.g. a popup can be positioned according to a pending
configuration while there is an active resize grab.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/705
2020-02-29 21:01:50 +00:00
Carlos Garnacho
64eaf70279 xwayland: Allow setting up maintenance processes
This is made a signal, so the upper layers (read: gnome-shell) may
decide what services to spawn. The signal argument contains a task
that will resume MetaX11Display startup after it is returned upon.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/945
2020-02-29 20:41:26 +00:00
Carlos Garnacho
e3149e6021 wayland: Pass private X connection on GNOME_SETUP_DISPLAY
This envvar will be picked up by the services spawned together with Xwayland
startup, and used instead of the regular DISPLAY meant for regular clients.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/945
2020-02-29 20:41:26 +00:00
Carlos Garnacho
166a464515 wayland: Set up initialization X11 socket
This is used by GDK and the X11 bits, but may also be used for
other initialization services we might need to run along with
Xwayland initialization.

However, as the -initfd argument in Xwayland is a fairly new
feature, add some meson build-time checks so that the feature
is handled transparently while allowing to explicitly set/unset
it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/945
2020-02-29 20:41:26 +00:00
Carlos Garnacho
38e58b837b core: Use DISPLAY envvar to forward in the launch context
The meta_x11_get_display_name() will return our private connection, which
is not what we want to transfer to clients being launched.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/945
2020-02-29 20:41:26 +00:00
Robert Mader
39a8c047d1 background-actor: Do not copy empty clip/unobscured regions
Clip and unobscured regions stricly shrink during culling. If they
are already empty, simply reference the empty region to reduce allocations.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1082
2020-02-29 19:44:01 +00:00
Robert Mader
c979cd95aa surface-actor: Do not copy empty clip/unobscured regions
Clip and unobscured regions stricly shrink during culling. If they
are already empty, simply reference the empty region to reduce allocations.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1082
2020-02-29 19:44:01 +00:00
Robert Mader
6831f2edb4 window-actor/x11: Disable culling on window actor level
This shape region culling was wrongly implemented in f5a28aa9, as it
does not take frame offsets into account, and is also redundant, as
we already set the opaque region of the underlying surface accordingly.

The other parts were implemented in ac7aa114, the reason given in
the commit message:
```
Wayland clients do this through the opaque region in the surface
actor. However X11 clients were considered fully transparent for
culling purposes, which may result in mutter painting other bits
of the background or other windows that will be painted over in
reality.
```

is wrong though - culling on X11 actors works just fine and did only
not work in Wayland sessions because of a bug that got fixed in
19814497.

In conclusion the whole part appears to be redundand and some testing
done suggests the same. Drop it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1082
2020-02-29 19:44:01 +00:00
Robert Mader
372d73e275 surface-actor: Cull out surfaces without alpha channel
If a opaque region is explicitly set we should not consider the surface
opaque, as that implies e.g. a shape region is set.

If no opque region is set but the texture does not have an alpha channel,
we can savely cull it out.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1082
2020-02-29 19:44:01 +00:00
Robert Mader
0ada90024f wayland/actor-surface: Check for MetaXwaylandSurface instead of window type
The previous check would not ignore subsurfaces. Use the chance to directly
check for the surface role instead - it's much cleaner.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1082
2020-02-29 19:44:01 +00:00
Jonas Dreßler
46e38ff61a cogl/clip-stack: Set color and depth mask when drawing rectangle clips
Just like with the other functions drawing to the stencil buffer, we
should make sure the depth and color masks are set to FALSE during
drawing.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1096
2020-02-29 19:29:31 +00:00
Jonas Dreßler
1e0b015ce8 cogl/clip-stack: Explicitely initialize the stencil mask
We need the stencil buffer to consist of binary values of 0 and 1
because we're doing additions and subtractions on the buffer, so even
though this is the default, explicitely set the stencil mask to 0x1.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1096
2020-02-29 19:29:31 +00:00
Jonas Dreßler
72054332c5 cogl/clip-stack: Restore old matrices after drawing to stencil buffer
When using a region clip and something has a rectangle clip pushed, a
special drawing method for ClutterTexts (emit_vertex_buffer_geometry()
in cogl-pango-display-list.c) starts to fail and clipping issues with
long texts (because emit_vertex_buffer_geometry() is only used for texts
longer than 25 characters) start to appear. This specifically happened
in Looking Glass, where the StViewport of the ScrollView sets a
rectangle clips and the texts are usually longer than 25 characters.

This is caused by the changing of the perspective and modelview matrix
when drawing to the stencil buffer and started happening when
region-clipping was introduced with commit 8598b654. Even though the
changing of the matrices was done before that, too, the issue probably
didn't happen because `rect->can_be_scissor` was TRUE and no stencil
buffer clipping was used at all.

To fix this, temporarily save the old matrices, then set the new ones
and restore the old ones when we're done drawing to the stencil buffer.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2246

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1096
2020-02-29 19:29:31 +00:00
Jonas Dreßler
d30ef0dd3b cogl/clip-stack: Use "merge" parameter for rectangle clips
Just like for the other sorts of clips, use a "merge" parameter instead
of a "first" parameter.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1096
2020-02-29 19:29:31 +00:00
sicklylife
84275688f3 Update Japanese translation 2020-02-29 16:06:38 +00:00
sicklylife
90a1eb4275 Update Japanese translation 2020-02-29 15:54:35 +00:00
Daniel van Vugt
73e3207a85 clutter-actor: Add detail to captured-event
So that subscribers can choose the class of events they're interested in
and not be woken by everything else.

Needed by: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/925

Related to: https://gitlab.gnome.org/GNOME/mutter/issues/283

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1000
2020-02-29 13:34:00 +00:00
worldofpeace
8a6673bb55 build: ensure absolute path to sysprof dbus interface dir
We want sysprof's exact datadir for compatability with
platforms where software is installed into their own
individual immutable prefix's. Such that, mutter's prefix will
never equate to sysprof's. This depends on a MR in sysprof [0]
which adds datadir to its pkgconfig files, as these files will always
have the proper path we want.

This adds version a constraint on sysprof_dep, as datadir was added to
the .pc in this version.

[0]: https://gitlab.gnome.org/GNOME/sysprof/merge_requests/19

https://gitlab.gnome.org/GNOME/mutter/merge_requests/957
2020-02-29 13:17:40 +01:00
Piotr Drąg
35c16a9f4b Update Polish translation 2020-02-29 13:17:07 +01:00
Jonas Ådahl
390fd7ddcf cursor-renderer-native: Fix hw cursor for non-square sprites
wl_shm_buffer_get_width() was used where wl_shm_buffer_get_height()
should have used, resulting in only square cursors working. Make
rectangular cursors work again.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1099
2020-02-28 21:49:58 +00:00
Carlos Garnacho
4b513a31ae compositor: Shuffle x11 compositing bits in MetaCompositor
Given that on Wayland we are pretty much guaranteed to finish MetaX11Display
setup after the MetaCompositor is enabled, we may drop the
meta_compositor_manage() x11 initialization bits, and move them into the
MetaX11Compositor subclass where it's actually needed.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/944
2020-02-28 20:20:35 +00:00
Carlos Garnacho
25c9e66c73 xwayland: Do not block on Xwayland initialization
We artificially made Xwayland initialization synchronous, as we used
to rely on MetaX11Display and other bits during meta_display_open().
With support for Xwayland on demand and --no-x11, this is certainly
not the case.

So drop the main loop surrounding Xwayland initialization, and turn
it into an async operation called from meta_display_init_x11(). This
function is turned then into the high-level entry point that will
get you from no X server to having a MetaX11Display.

The role of meta_init() in Xwayland initialization is thus reduced
to setting up the sockets. Notably no processes are spawned from here,
deferring that till there is a MetaDisplay to poke.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/944
2020-02-28 20:20:35 +00:00
Carlos Garnacho
649911b6b3 core: Make meta_display_init_x11() an async function
This ATM completes the task right away, but we will want to do
further things here that are asynchronous in nature, so prepare
for this operation being async.

Since the X11 backend doesn't really need this, make it go on
the fast lane and open the MetaX11Display right away, the case
of mandatory Xwayland on a wayland session is now handled
separately.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/944
2020-02-28 20:20:35 +00:00
Carlos Garnacho
8c332a4704 tests: Set fatal log handler on clutter tests
With Xwayland initialization going async, these errors will seep
into the parts controlled by g_test*(), resulting in the harmless
errors about DBus names not acquired turned fatal.

Set an error log handler, and specifically ignore those.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/944
2020-02-28 20:20:35 +00:00
Carlos Garnacho
21994bb00d tests: Ensure MetaX11Display is initialized before running tests
It might not be available right on initialization time if X11 is started
asynchronously. As this is a requirement for our tests, ensure it is there
before proceeding with the test.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/944
2020-02-28 20:20:35 +00:00
Carlos Garnacho
87a06c63ad x11: Set up the compositing manager selection on meta_display_init_x11()
This used to be set on meta_compositor_manage(), but only if there is a
MetaX11Display. Given meta_display_init_x11() is Wayland only, and we can
always assume compositing to be enabled, just have it invariably set after
the X server is up.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/944
2020-02-28 20:20:35 +00:00
Georges Basile Stavracas Neto
09026e5f0e monitor-stream-src: Use cogl_framebuffer_finish()
Even though cogl_framebuffer_flush() was supposed to be enough,
it ends up creating streams with odd visual glitches that look
very much like unfinished frames.

Switch back to cogl_framebuffer_finish(), which is admittedly
an overkill, but it's what works for now. There is anedoctal
evidence showing it doesn't incur in worse performance.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 15:52:19 -03:00
Georges Basile Stavracas Neto
1f190a7cfe screen-cast-stream-src: Remove unused parameter
The 'data' parameter is not used in maybe_record_cursor(), so remove
it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 15:52:19 -03:00
Georges Basile Stavracas Neto
86168b945c window-stream-source: Draw into DMA buffer image
Much like monitor streaming, implement window streaming by
making the window actor draw itself with a paint context
that used the passed framebuffer.

Now that all MetaScreenCastStreamSrc subclasses implement
blit_to_framebuffer, remove the conditional check from
meta_screen_cast_stream_src_blit_to_framebuffer().

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 15:52:19 -03:00
Georges Basile Stavracas Neto
680a54aff6 monitor-stream-src: Implement blitting view framebuffers
Add the vfunc override that actually consume the new Cogl API. Every
view that fits into the logical monitor is rendered.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/639

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 15:52:03 -03:00
Georges Basile Stavracas Neto
548073ec27 screen-cast-stream-src: Support DMA buffer sharing
Implement PipeWire's add_buffer and remove buffer, try and export
a DMA buffer first and, on failure, fallback to memfd.

When DMA buffers are successfully created and shared, blit the
framebuffer contents when drawing instead of downloading the pixels.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 15:29:03 -03:00
Georges Basile Stavracas Neto
d366fb335d renderer-native: Implement DMA buffer creation
Create a new gbm_bo using the same given geometry, and export the new
bo's DMA buffer fd. The new bo lives as long as necessary to be used,
and reused, by PipeWire.

Unfortunately, PipeWire doesn't support modifiers properly, so use the
linear format for now. For now, a hardcoded format of DRM_FORMAT_XRGB8888
is set, so we don't need to negotiate the format with PipeWire early.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 15:29:02 -03:00
Georges Basile Stavracas Neto
7fbb47b2bb renderer-native: Move DMA buffer creation to an auxiliary function
This will be reused by the DMA buffer exporting function.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 15:28:22 -03:00
Georges Basile Stavracas Neto
3881c1f952 cogl/context: Add cogl_renderer_create_dma_buf() and family
This is a winsys-specific API that allows exporting a DMA buffer fd.
The CoglDmaBufHandle structure allows passing the ownership of the
DMA buffer to whoever is using it, so the winsys doesn't need to
manually track it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 14:54:48 -03:00
Georges Basile Stavracas Neto
038a3170bf cogl/framebuffer: Add cogl_framebuffer_flush
In future patches, we'll create additional CoglFramebuffers that
will be shared via DMA-Buf with PipeWire. When recording frames,
we'll blit the current onscreen framebuffer into the shared one.

However, that presents a problem: cogl_framebuffer_blit() mimics
glBlitFramebuffer() semantics, and doesn't do an implicit flush
of the GPU command stream. As a consequence, clients may receive
unblitted or incomplete framebuffers.

We could use cogl_framebuffer_finish() to ensure the commands were
submitted to the GPU, but it is too harsh -- it blocks the CPU
completely until the commands are finished!

Add cogl_framebuffer_flush(), which ensures the command stream is
submitted to the GPU without blocking the CPU. Even though we don't
use the framebuffer specifically, it may be useful in the future
for e.g. a potential Vulkan backend to have access to the framebuffer.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
2020-02-28 10:52:34 -03:00
Alan Mortensen
f27de9620a Updated Danish translation 2020-02-28 14:01:26 +01:00
Robert Mader
969ad54feb cursor-renderer/native: Remove unnecessary endian check
Both cases have the same content.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/526
2020-02-28 10:22:11 +00:00
Robert Mader
987ce5bec0 cursor-renderer/native: Implement scaled/transformed hardware cursors
If the cursor sprite does not match the scale factor or transformation
of the monintor, we currently fall back to a software cursor, causing
redraws of the shell. This commit implements scaling and transforming
of the cursor sprite, so we can use it with hardware planes, too.

This commit does the following steps:

1. Make sure we reupload the cursor image if the cursor is over
a logical monitor not matching the scale or transform from the previous
update.
2. Before upload to the hardware plane, scale and transform the cursor
image if possible and necessary.
3. Make sure we always use the hardware cursor if possible (only fall
back to software/OGL cursor if it is visible on multiple logical monitors
with differet scales/transforms).
4. Transform or scale the cursor coordinates if necessary.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/526
2020-02-28 10:22:11 +00:00
Robert Mader
d600cd9aee monitor-transform: Add generic function to get relative transform
It takes transforms A and B and returns the transform to get from
A to B.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/526
2020-02-28 10:22:11 +00:00
Robert Mader
1fc7935858 backends/cursor: Add API to set and get the texture buffer transform
In Wayland clients can commit transformed surfaces, so the compositor
can directly use them on hardware planes. We already support that
for other surfaces, this is the first step to also support it on
cursor sprites.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/526
2020-02-28 10:22:11 +00:00
Kukuh Syafaat
b5354fb3cd Update Indonesian translation 2020-02-28 02:13:12 +00:00
Jonas Ådahl
01aaced129 crtc: Don't leak MetaCrtcConfig
We never freed it except when CRTC disabled during runtime.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1095
2020-02-27 20:35:07 +00:00
Jonas Ådahl
ff59b5d041 monitor: Move logical <-> CRTC transform helpers to MetaOutput
So that we avoid leaking the internal guts of MetaOutput into
MetaMonitor, while also making it possible to use it without a
MetaMonitor at hand.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1064
2020-02-27 09:47:22 +01:00
Jonas Ådahl
92f0eb9d14 monitor: Use transform helper when dealing with panel orientation
Replace the open coded monitor transform math with the new helper.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1064
2020-02-27 09:47:08 +01:00
Jonas Ådahl
e6913d1471 monitor-transform: Add meta_monitor_transform_transform() helper
Intended to replace various manual monitor transform enum math here and
there. Tests added as well, to test some hand picked transforms.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1064
2020-02-27 09:07:25 +01:00
Fran Dieguez
d495dc6c63 Update Galician translation 2020-02-26 20:57:31 +00:00
Carlos Garnacho
88bb24f66e backends/native: Shuffle udev client initialization in MetaSeatNative
This may be used indirectly before creation as we dispatch libinput events
right after creation (to let input devices be known), so those device
additions would trigger the touch-mode checks.

Creating it in advance results in checks being correctly performed, although
redundantly.

Spotted by Bastien Nocera.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1067
2020-02-26 18:32:05 +00:00
Arun Raghavan
6e7316ef11 build: Use dbus interface dir from pkg-config
Using 'datadir' breaks prefixed builds (as we look for interface files
in the prefix we are going to install to).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1094
2020-02-26 15:37:00 +00:00
Jonas Ådahl
9fa56176fd monitor-manager-xrandr: Don't try to disable disabled CRTC
When applying a configuration to XRANDR, we first disable CRTCs that
happen to extend outside of the to-be X11 screen size. While doing so,
we fail to actually check whether the CRTC is active or not, meaning
we'll try to query the content of the CRTC configuration even though it
has none, leading to a NULL pointer dereference.

Fix this by simply ignoring non-configured CRTCs.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1093
2020-02-26 16:14:04 +01:00
Marek Černocký
fb81199dec Updated Czech translation 2020-02-26 14:13:21 +01:00
Christian Hergert
b7f47ea17f clutter: add tracing for frameclock cycle
This adds a new frameclock tracing mark for a single cycle of the frame
clock. Doing so allows Sysprof to potentially do more with the information
that happens during the frameclock. For example, we can now find
allocations that happen while the frame clock is advancing.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1088
2020-02-26 12:33:00 +00:00
Sebastian Keller
71101cab82 clutter/cogl/stage: Remove duplicate region union
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1089
2020-02-26 07:26:10 +00:00
Sebastian Keller
c4b28b0939 clutter/cogl/stage: Don't leak FB damage region on redraw
offset_scale_and_clamp_region() creates a new region resulting in
view_damage which at this point is the only thing left pointing to what
originally was fb_damage getting overwritten and being leaked.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1089
2020-02-26 07:26:10 +00:00
Florian Müllner
38954de11c ci: Adjust URL check
While the old merge request URLs still work, gitlab recently started
including an additional /- for merge requests.

Adjust the regex to account for that, so that simply copying the URL
from gitlab works again.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1090
2020-02-26 06:28:46 +00:00
Gwan-gyeong Mun
964ea60090 Update Korean translation 2020-02-26 03:00:37 +00:00
Jonas Ådahl
159c83b914 clutter: Move redraw clip management to views
The stage window handled the redraw clip in a global manner; this would
interfere if we want to paint views individually as it'd mean
intersecting views (i.e. mirrored monitors) would loose the redraw clip
once the first view was painted. It also is awkward to have a global
state for something that is built up before redrawing, and only really
valid during paint, due to buffer damage history.

This commits removes all redraw clip management from the stage window,
moving it all into the stage views. When a redraw clip is added to the
stage, every affected view will get the same redraw clip added to it,
and eventually when painted, the stage window (ClutterStageCogl) will
retrieve the redraw clip for each view as it repaints them.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 19:18:54 +01:00
Jonas Ådahl
b68c630329 clutter/cogl/stage: Use g_clear_pointer() to clean up regions
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 19:18:54 +01:00
Jonas Ådahl
fe1ccea1e1 clutter: Pass redraw clip via paint context
Instead of users fetching it via `clutter_stage_get_redraw_clip()`, pass
it via the paint context. This is helpful as it is only valid during a
paint, making it more obvious that it needs to be handled differently
when there is no redraw clip (i.e. we're painting off-screen).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 19:18:54 +01:00
Jonas Ådahl
c483b52d24 clutter/stage: Pass redraw clip instead of extents when painting view
That's the struct we have ready, the callee can just call
cairo_region_get_extents() if it only cares about the extents rectangle.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 19:18:54 +01:00
Jonas Ådahl
f3dcba27f5 clutter/cogl/stage: Simplify region transform code
Add a helper that scales and clamps a region, aimed to be used when
transforming between framebuffer coordinate space and view coordinate
spaces.

This helps readability by moving out the verbose for loops that deals
with the individual rects of a region to the helper, making the logic
where it's used much simpler.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 19:18:54 +01:00
Jonas Ådahl
86ccc28413 clutter/cogl/stage: Rename have_clip to is_full_redraw
The 'have_clip' variable has repeatedly confused me to meaning that
there is a clip. What it actually means is that the effective clip
covers the whole view; the 'redraw_clip == NULL' meaning full redraw is
an important implementation detail for the context, and makes the
intention of the variable unclear; especially since we will after a
couple of blocks will *always* have a clip, just that it covers the
whole view.

Rename the variable to 'is_full_redraw' and negate the meaning, aiming
to make things a lot more clear.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
0d039c3ba3 clutter/view: Don't take paint rect after paint
It was unused, and will be become unused by the primary paint function
as well, so go ahead and remove it here first.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
adcbc2aa5f clutter/cogl/stage: Use fb size for for fallback fb clip region
When calculating the fallback framebuffer clip region, which should be
the region in framebuffer coordinates, we didn't scale the view layout
with the view framebuffer scale, meaning for any other scale than 1,
we'd draw a too small region of the view. Fix this by just using the
size of the framebuffer directly, avoiding any scale dependent
calculation all together.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
860906246e clutter/cogl/stage: Simplify swap_event boolean logic
We'll expect a swap event if any of the view paints resulted in a swap;
make the logic dealing with this clearer by making changing the less
vilible '|| swap_event' postfix with a up front '|=' operator.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
37d7df612b clutter/stage/cogl: Name variable to make coordinate space obvious
The ambiguous "clip" was renamed to "fb_clip_region", as it was called
at the call site. This should make it more clear that the clip is in
buffer coordinate space.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
0baf4578c8 clutter/stage/cogl: Remove some leftover whitespace
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
2d6665950c crtc: Move logical monitor pointer to MetaMonitor
Since the last code fetching the logical monitor state directly from the
CRTC has been removed, we can move the logical monitor pointer to a more
natural place.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
1c98f01a65 renderer-native: Draw stage separately per CRTC
Prior to this commit the stage was drawn separately for each logical
monitor. This allowed to draw different parts of the stage with
different transformations, e.g. with a different viewport to implement
HiDPI support.

Go even further and have one view per CRTC. This causes the stage to
e.g. draw two mirrored monitors twice, instead of using the same
framebuffer on both. This enables us to do two things: one is to support
tiled monitors and monitor mirroring using the EGLStreams backend; the
other is that it'll enable us to tie rendering directly to the CRTC it
will render for. It is also a requirement for rendering being affected
by CRTC state, such as gamma.

It'll be possible to still inhibit re-drawing of the same content
twice, but it should be implemented differently, so that it will still
be possible to implement features requiring the CRTC split.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
e3f30371aa renderer-native: Fix a couple of style misses
Removed stray newline, and fixed an incorrect indentation.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
1a14c4d3c9 renderer-x11-nested: Remove stray newline
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
292d2754ae clutter/stage: Remove stray newline
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
fe42d56db3 crtc: Move configured state to separate struct
To make it more reliable to distinguish between values that are read
from the backend implementation (which is likely to be irrelevant for
anything but the backend implementation), split out those values (e.g.
layout).

This changes the meaning of what was MetaCrtc::rect, to a
MetaCrtcConfig::layout which is the layout the CRTC has in the global
coordinate space.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
a11f9bd513 boxes: Add 'round' rounding strategy
It just calls roundf(), and is intended to be used when the graphene
rectangle is approximately integer aligned.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
7f6cafa847 logical-monitor: Pass monitor in the for each CRTC helper callback
Will be used in later commits.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Jonas Ådahl
1b67f49f7f monitor: Move logical to CRTC transform helper to MetaOutput
So that it can be used on a per output basis in the future.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
2020-02-25 18:39:51 +01:00
Balázs Úr
c447d76cd4 Update Hungarian translation 2020-02-25 06:32:01 +00:00
Christian Hergert
d327cedb83 clutter: avoid redundant _clutter_paint_node_init_types()
This only needs to be initialized once but is in the hot path of creating
new paint nodes (for which we create many). Instead, do this as part of
the clutter_init() workflow to keep it out of the hot path.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1087
2020-02-25 01:14:09 +00:00
Christian Hergert
0c55e87d8f cogl: reduce temporary allocations calculating redraw regions
When calculating regions, a lot of temporary allocations are created. For
the array of rects (which is often a short number of them) we can use
stack allocations up to 1 page (256 cairo_rectangle_int_t). For building
a region of rectangles, cairo and pixman are much faster if you have all
of the rectangles up front or else it mallocs quite a bit of temporary
memory.

If we re-use the cairo_rectangle_int_t array we've already allocated (and
preferably on the stack), we can delay the creation of regions until after
the tight loop.

Additionally, it requires fewer allocations to union two cairo_region_t
than to incrementally union the rectangles into the region.

Before (percentages are of total number of allocations)

     TOTAL    FUNCTION
[ 100.00%]    [Everything]
[ 100.00%]      [gnome-shell --wayland --display-server]
[  99.67%]        _start
[  99.67%]          __libc_start_main
[  99.67%]            main
[  98.60%]              meta_run
[  96.90%]                g_main_loop_run
[  96.90%]                  g_main_context_iterate.isra.0
[  96.90%]                    g_main_context_dispatch
[  90.27%]                      clutter_clock_dispatch
[  86.54%]                        _clutter_stage_do_update
[  85.00%]                          clutter_stage_cogl_redraw
[  84.98%]                            clutter_stage_cogl_redraw_view
[  81.09%]                              cairo_region_union_rectangle

After (overhead has much dropped)

     TOTAL    FUNCTION
[ 100.00%]    [Everything]
[  99.80%]      [gnome-shell --wayland --display-server]
[  99.48%]        _start
[  99.48%]          __libc_start_main
[  99.48%]            main
[  92.37%]              meta_run
[  81.49%]                g_main_loop_run
[  81.49%]                  g_main_context_iterate.isra.0
[  81.43%]                    g_main_context_dispatch
[  39.40%]                      clutter_clock_dispatch
[  26.93%]                        _clutter_stage_do_update
[  25.80%]                          clutter_stage_cogl_redraw
[  25.60%]                            clutter_stage_cogl_redraw_view

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1071
2020-02-24 22:44:35 +00:00
Christian Hergert
81d11ac0a8 clutter: avoid g_signal_emit_by_name() from ClutterActor
g_signal_emit_by_name() is used to emit signals on ClutterContainer when
actors are removed or added. It happens to do various interface lookups
which are a bit unneccessary and can allocate memory.

Simply using emission wrappers makes all of that go away.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1083
2020-02-24 22:36:27 +00:00
Asier Sarasua Garmendia
84261d1db3 Update Basque translation 2020-02-24 16:41:35 +00:00
Daniel Mustieles
a0441ad666 Updated Spanish translation 2020-02-24 16:48:17 +01:00
Emin Tufan Çetin
67152916e1 Update Turkish translation 2020-02-24 15:06:58 +00:00
Jonas Dreßler
b98ebe60b2 clutter/x11: Stop tracking stage changes on crossing events
On x11 we emulate pointer events from touch events as long as there's
only one touchpoint on screen, this obviously leads to x11 sending us
crossing events triggered by the emulated pointer. Now if we get a leave
event and set the stage of the ClutterInputDevice to NULL, new touch
events will be discarded by clutters backend because the core pointer
doesn't have a stage associated. This means Mutter completely loses
state of a touchpoint as soon as it crosses a shell actor.

An easy reproducer for this issue is to start the four-finger-workspace
gesture above a window and to move the pointer emulating touch outside
of the window, this will freeze the gesture as the gesture no longer
receives touch events.

To fix this, stop tracking stage changes on crossing events and simply
leave the ClutterInputDevice stage as-is. In our case there is only one
stage anyway and that won't change in the future.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/423
2020-02-24 10:54:56 +00:00
Jonas Dreßler
ad8ba69423 wayland/pointer: Use g_signal_connect_swapped for one signal
Remove the rather useless callback function that's currently used for
handling the "visibility-changed" signal and instead connect to the
signal using `g_signal_connect_swapped()`.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1077
2020-02-24 09:52:06 +00:00
Jonas Dreßler
bf24b816c2 wayland/pointer: Add support for the new ClutterSeat inhibit-unfocus API
The last commit added a new API to ClutterSeat to inhibit setting the
focus-surface of the MetaWaylandPointer to NULL, let's do that.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1077
2020-02-24 09:52:06 +00:00
Jonas Dreßler
a9b1134dfb clutter/seat: Add API to inhibit unfocus of the cursor surface/actor
Add API to ClutterSeat that allows inhibiting the unsetting of the
pointer focus surface. This can be useful for drawing custom cursor
textures like the magnifier of gnome-shell does.

In the future this API should also control unsetting of Clutters
focus-actor, not just the focus surface, that's not really needed right
now since we never unset the focus-actor anyway.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1077
2020-02-24 09:52:06 +00:00
Rafael Fontenelle
6fb6a23389 Update Brazilian Portuguese translation 2020-02-24 09:40:26 +00:00
Jonas Ådahl
2da27720ca display: Make check-alive timeout configureable
The check-alive feature is there for the user to be able to terminate
frozen applications more easily. However, sometimes applications are
implemented in a way where they fail to be reply to ping requests in a
timely manner, resulting in that, to the compositor, they are
indistinguishable from clients that have frozen indefinitely.

When using an application that has these issues, the GUI showed in
response to the failure to respond to ping requests can become annoying,
as it disrupts the visual presentation of the application.

To allow users to work-around these issues, add a setting allowing them
to configure the timeout waited until an application is considered
frozen, or disabling the check completely.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1080
2020-02-23 17:28:57 +00:00
Olivier Fourdan
f9326cfa3d wayland/data-device: Fix crash with offer from X11 client
If a data offer comes from an X11 client, the Wayland resource would be
NULL, causing a crash in `data_offer_choose_action()` trying to get the
resource version.

So instead of doing the version check in `data_offer_choose_action()`,
do it early when creating the data source.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1057
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1073
2020-02-23 16:36:16 +00:00
Olivier Fourdan
963108a9a6 wayland/data-device: Check resource version on cancel
For clarity, check the resource version needs the "cancelled" message in
the actual vmethod rather than from the caller function.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1073
2020-02-23 16:36:15 +00:00
Olivier Fourdan
b8355a6686 xwayland: Not all xwayland surface have a window
`meta_xwayland_surface_get_relative_coordinates()` may cause a crash if
the Xwayland surface has no window associated.

That can be observed when using drag and drop from an X11 window to a
Wayland native window:

```
    at src/core/window.c:4503
    at src/wayland/meta-xwayland-surface.c:200
    at src/wayland/meta-wayland-surface.c:1517
    at src/wayland/meta-wayland-pointer.c:1048
    at src/wayland/meta-wayland-pointer.c:840
    at src/wayland/meta-wayland-pointer.c:865
    at src/wayland/meta-wayland-pointer.c:954
    at src/wayland/meta-wayland-pointer.c:456
    at src/wayland/meta-wayland-pointer.c:993
    at src/wayland/meta-wayland-data-device.c:1004
    at src/wayland/meta-wayland-data-device.c:1278
    at src/wayland/meta-xwayland-dnd.c:326
```

Check if the xwayland surface has an associated MetaWindow prior to get
its buffer rect.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1073
2020-02-23 16:36:15 +00:00
Christian Hergert
4c421959dc clutter: fix hole in ClutterPaintNode
Fixing the missalignment takes the structure from 80 bytes down to 72.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1081
2020-02-21 22:36:31 +00:00
Sebastian Keller
aedcfcd010 sound-player: Fix invalid write after playback is cancelled early
The cancellable of a request might already be cancelled by the time
the cancelled_cb is connected resulting in finish_cb being called via
ca_context_cancel before g_cancellable_connect returns. In this case
the request that is written to has already been freed.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/1060
2020-02-21 16:06:18 +00:00
Jonas Dreßler
d7c7311ceb clutter/seat: Add gtkDoc comments for touch-mode property
It's not that easy to find out when the touch-mode is enabled without
reading the code, so document that.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1075
2020-02-21 15:24:58 +00:00
Jonas Dreßler
41d72e86e0 backends/native: Also check touch-mode on object initialization
On a Surface Pro 2017, touch-mode is currently only detected correctly
after detaching and attaching the Type Cover (detachable keyboard) once,
it seems that `has_external_keyboard` is only set to the correct value
after MetaSeatNative is initialized.

So fix that and call `update_touch_mode()` once again when the object is
initialized and the `has_external_keyboard` and `has_touchscreen`
properties have been finally updated.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1075
2020-02-21 15:24:58 +00:00
Daniel van Vugt
282b09c17e clutter/actor: Add CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE
Which offscreens actor rendering only in cases where it hasn't changed for
2 frames or more. This avoids the performance penalty of offscreening an
actor whose content is trying to animate at full frame rate. It will
switch automatically.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1069
2020-02-21 18:07:46 +08:00
Wim Taymans
c5d2fc856a screen-cast: Update to PipeWire 0.3 API
Update to 0.3 API

[jadahl: update Dockerfile to include new enough pipewire]

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1051

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1062
2020-02-20 18:45:31 +01:00
Robert Mader
f5a28aa9e4 window-actor: Make culling of opaque windows X11 only
It is only useful for clients that do not set an opaque region but
still can be detected as being opaque. This is helpful for X11 clients
as opaque regions only got introduced around 2012 and only as part of EWMH
and are thus not used in many cases.
On Wayland however opaque regions have been part of the core protocol from the
beginnig and we can assume they are used more commonly.

As the current implementation in `MetaWindowActor` does not handle Wayland
subsurfaces well, instead of adding more complexity just move it to
`MetaWindowActorX11`.

While on it, take the shape region into account that is set when clients
use the X Nonrectangular Window Shape Extension Protocol, so we have exact
culling with those clients.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1058
2020-02-20 15:57:51 +00:00
Asier Sarasua Garmendia
6206511846 Update Basque translation 2020-02-20 15:42:44 +00:00
Jonas Ådahl
a209a14898 renderer-native: Use hardware acceleration check in generic layer
No need to duplicate it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/838
2020-02-20 10:40:42 +00:00
Jonas Ådahl
3e6a55aff0 renderer: Add API to check whether renderer is hardware accelerated
Also expose an introspected variant via the MetaBackend.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/838
2020-02-20 10:40:42 +00:00
Jonas Ådahl
704fea6323 renderer-native: Move 'backend' field to MetaRenderer
So that it can be used by the generic MetaRenderer class, as well as
other sub types, as well.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/838
2020-02-20 10:40:42 +00:00
Jonas Ådahl
8c1e6ebde0 remote-access-handle: Expose disable-animations property
Set to TRUE if a screen cast session asked for animations to be
disabled.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/838
2020-02-20 10:40:42 +00:00
Jonas Ådahl
81512ad0dc screen-cast-session: Add 'disable-animations' property
Allow screen casters (e.g. VNC remote desktop services) to ask for
animations to be inhibited, in order to lower the number of frames sent
over the network.

Currently only sets a field on the screen cast session object. Later
it'll be exposed via the remote access handle and via D-Bus by
gnome-shell.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/838
2020-02-20 10:40:42 +00:00
Christian Hergert
d122b66abc clutter/actor: avoid transform node for identity matrix
If the transform matrix is an identity, then positioning wont change and
we can avoid creating the transform node altogether. This is based on
a similar find in GTK today while reducing temporary allocations.

This cuts the number of transforms created in clutter_actor_paint() by
about half under light testing of GNOME Shell from 6.8% to 2.4% of
allocations.

Before:

    ALLOCATED      TOTAL    FUNCTION
[   20.4 MiB] [  21.20%]    clutter_actor_paint
[   11.0 MiB] [  11.45%]      clutter_paint_node_paint
[    6.6 MiB] [   6.84%]      clutter_transform_node_new
[    2.5 MiB] [   2.61%]      clutter_actor_node_new

After:

    ALLOCATED      TOTAL    FUNCTION
[   33.4 MiB] [  24.12%]    clutter_actor_paint
[   26.2 MiB] [  18.91%]      clutter_paint_node_paint
[    3.4 MiB] [   2.43%]      clutter_actor_node_new
[    3.3 MiB] [   2.41%]      clutter_transform_node_new

Allocation amounts will have differed due to different amounts of running
time, but the % of allocations has now dropped below
clutter_actor_node_new() which should be expected.

https://gitlab.gnome.org/GNOME/mutter/issues/1056
2020-02-20 06:41:34 +00:00
Jonas Ådahl
44ae38599f wayland: Move MetaWindow ownership to window owning roles
There are two surface roles owning a MetaWindow: MetaWaylandShellSurface
(basis of MetaWaylandXdgToplevel, MetaWaylandXdgPopup,
MetaWaylandWlShellSurface, etc), and MetaXwaylandSurface.

With these two role types, the MetaWindow has two different types of
life times. With MetaWaylandShellSurface, the window is owned and
managed by the role itself, while with MetaXwaylandSurface, the
MetaWindow is tied to the X11 window, while the Wayland surface and its
role plays more the role of the backing rendering surface.

Before, for historical reasons, MetaWindow was part of
MetaWaylandSurface, even though just some roles used it, and before
'wayland: Untie MetaWindowXwayland lifetime from the wl_surface' had
equivalent life times as well. But since that commit, the management
changed. To not have the same fied in MetaWaylandSurface being managed
in such drastically different ways, rearrange it so that the roles that
has a MetaWindow themself manages it in the way it is meant to; meaning
MetaWaylandShellSurface practically owns it, while with Xwayland, the
existance of a MetaWindow is tracked via X11.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/835
2020-02-19 22:34:28 +00:00
Jonas Ådahl
df642eb150 wayland: Move calc-showing window logic to roles having windows
https://gitlab.gnome.org/GNOME/mutter/merge_requests/835
2020-02-19 22:34:28 +00:00
Jonas Ådahl
722ae2b77a wayland/surface: Let roles set DND functions
The DND functions are role specific, with Xwayland surface being the
special one. Let the roles set it instead of having per role like logic
in MetaWaylandSurface.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/835
2020-02-19 22:34:28 +00:00
Jonas Ådahl
54194e67e3 wayland/surface: Move relative coordinate calculating to roles
The role determines how a relative coordinate is calculated. More
specifically, using clutters API to transform coordinates is only
accurate right after a clutter layout pass but this function is used
e.g. to deliver pointer motion events which can happen at any time. This
isn't a problem for Wayland clients since they don't control their
position, but X clients do and we'd be sending outdated coordinates if a
client is moving a window in response to motion events.

This was already done already, but now move the Xwayland specific logic
to the Xwayland surface role, keeping the generic transformation logic
in the generic actor surface role.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/835
2020-02-19 22:34:28 +00:00
Jonas Ådahl
c0c74484bc wayland: Don't access MetaWaylandSurface::window directly
It'll be moved to the role owning it, accessed via a helper function
implemented by the role. Currently it still just fetches the field in
MetaWaylandSurface.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/835
2020-02-19 22:34:28 +00:00
Jonas Ådahl
5149e1e43a wayland: Move tree updating to the shell surface role
The shell surface role is the one where subsurfaces may exist, and it
has direct relation to the MetaWindowActorWayland which currently has
the subsurface stacking logic.

Instead of directly finding the window actor when dealing with
subsurfaces, notify the parent surface that the subsurface state
changed, so that it can outsource the application of this information to
the role. For subsurface roles, this simply means forward upward to the
parent; for shell surface roles, this means regenerate the surface actor
layering.

This allows us to move away from accessing the window directly from the
surface, which in turn allows us to change the ownership structure of
windows.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/835
2020-02-19 22:34:28 +00:00
Jonas Ådahl
ac2c870177 surface-actor: Remove get_window() API and vfunc
It was unused.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/835
2020-02-19 22:34:28 +00:00
Jonas Ådahl
f21595687f xwayland: Move out surface role related logic
Does some needed naming cleanup while at it, to be more similar to other
role types.

In short, MetaWaylandSurfaceRoleXwayland was changed to
MetaXwaylandSurface.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/835
2020-02-19 22:34:28 +00:00
Jonas Dreßler
e51279dcf0 display: Only send one ping to a window at a time
If a window already is being pinged, it doesn't make sense to send more
pings to the window, instead we should just wait for that answer or
timeout until we send a new one.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/891
2020-02-19 21:20:29 +00:00
Jonas Dreßler
9b58033375 display: Make sure ping serials are never reused
Using a timestamp twice in a row (e.g. when activating two windows in
response to the same event or due to other bugs) will break the window
detection and show a close dialog on the wrong window. This is a grave
error that should never happen, so check every timestamp before sending
the ping for uniqueness and if the timestamp was already used and its
ping is still pending, log a warning message and don't send the ping.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/891
2020-02-19 21:20:29 +00:00
Jonas Dreßler
0bf9727a31 display: Fix intendation of an argument and add details to a warning
https://gitlab.gnome.org/GNOME/mutter/merge_requests/891
2020-02-19 21:20:29 +00:00
Jonas Dreßler
d053ccfb18 window: Check window responsiveness on every window focus
Increase the number of checks whether a window is still responsive and
ping windows on every call to `meta_window_focus()` instead of
`meta_window_activate_full()`. This ensures the window is also pinged in
case normal interaction like clicks on the window happen and a close
dialog will eventually get shown.

Related https://gitlab.gnome.org/GNOME/mutter/issues/395

https://gitlab.gnome.org/GNOME/mutter/merge_requests/891
2020-02-19 21:20:29 +00:00
Jonas Dreßler
7cc02cf24e backends/native: Replace tabs with spaces
Replace the few remaining places where tabs are used for indentation
with spaces.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1065
2020-02-19 18:28:29 +00:00
Jonas Dreßler
e07478f8bc virtual-input-device/native: Fix warning message
We want to log the evdev keycode here, not the Clutter one.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1065
2020-02-19 18:28:29 +00:00
Jonas Dreßler
efe1bc2e59 util: Add INPUT debug topic
Allow debugging input issues more easily by adding an INPUT debug topic.
Currently there are only debug messages for the native backend.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1065
2020-02-19 18:28:29 +00:00
Adam Jackson
41992757e0 cogl: GLES3 has sync objects
https://gitlab.gnome.org/GNOME/mutter/merge_requests/882
2020-02-19 17:55:46 +00:00
Adam Jackson
445af61a68 cogl: GLES3 has vertex array objects
https://gitlab.gnome.org/GNOME/mutter/merge_requests/882
2020-02-19 17:55:46 +00:00
Adam Jackson
03ef335a70 cogl: GLES3 has sampler objects
https://gitlab.gnome.org/GNOME/mutter/merge_requests/882
2020-02-19 17:55:46 +00:00
Adam Jackson
b4226daadb cogl: GLES3 has glGetStringi
https://gitlab.gnome.org/GNOME/mutter/merge_requests/882
2020-02-19 17:55:46 +00:00
Daniel van Vugt
b70611e3cf clutter/enums: Correct docs about ClutterOffscreenRedirect
The default value is zero, not the flag the docs say.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1068
2020-02-19 17:36:29 +00:00
Florian Müllner
35fe6a40ed clutter: Make clutter_contraint_update_preferred_size() public
This is necessary for gobject-introspection to correctly pick up
the annotations for the corresponding vfunc.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1067
2020-02-19 11:57:05 +00:00
Emmanuele Bassi
4f8e518d42 bind-constraint: Update the preferred size
Bind the preferred size of an actor using a BindConstraint to the
preferred size of the source of the constraint, depending on the
coordinate of the constraint.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1070
2020-02-19 08:26:28 -03:00
Yi-Jyun Pan
d2953e0d33 Update Chinese (Taiwan) translation
(cherry picked from commit 053bb5901a)
2020-02-19 03:09:27 +00:00
Sebastian Keller
b45b03b063 surface-actor-x11: Avoid flicker when (un)redirecting windows
Currently when a window is requested to be unredirected, the
corresponding pixmap and texture can get cleared before the window has
been unredirected by the X server. This can result in the windows behind
showing through which causes a short flicker after showing an OSD or
notification when a fullscreen application is running.
Fix this by ensuring the texture is only cleared after the window has
been unredirected by the server.

Similarly when the window is being redirected again, the pixmap of the
window can only be requested after the redirection has been completed by
the server. This currently can happen in a different frame than the next
redraw of the actor resulting in an empty texture until the next redraw.
Fix this by queuing a redraw immediately after redirecting.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/997
2020-02-18 22:49:01 +00:00
Jonas Ådahl
c06fae4741 window-actor: Don't show actor until meta_window_actor_show()
By default clutter will show an actor as it is added to a parent. This
means that after we create the window actor, when it's added to the
window group, we implicitly show it. What we really want is to not show
it until the window is supposed to be shown, which happens when
meta_window_actor_show() is called, as showing prior to that, could
cause issues.

Avoid the implicit show by setting the "show-on-set-parent" property on
the window actor to `FALSE` on window actor construction.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1066
2020-02-18 23:04:49 +01:00
Olivier Fourdan
76e0d7293d window-actor/x11: Update opaque region
Now that the opaque region is not reset by the Wayland actor surface, we
need to update the opaque region just like we do for input region.

That fixes a regression with client-side decoration X11 windows running
in Xwayland.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1060
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1043
2020-02-17 23:37:18 +00:00
Jonas Ådahl
0e0afa240e settings: Improve logging of enabled experimental features
We didn't log what we enabled, just g_info():ed what failed to be
enabled. Change this to g_warning() what failed to be enabled, and
g_message() on what was enabled, so that both will be visible in the
logs.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1061
2020-02-17 17:08:21 +00:00
Florian Müllner
560055fc97 Bump version to 3.35.91
Update NEWS.
2020-02-17 13:05:40 +01:00
Björn Daase
3e1db33967 gitlab: Add missing < in markdown comment tag
This adds a missing < to the comment tag at beginning of the Bug.md
issue template, to fix that the comment content (and the rest of the
tag) is not shown.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1051
2020-02-14 03:10:28 +00:00
Robert Mader
aceadfe305 cullable: Check if effects are disabled
Currently we skip culling actors if they have any effects set. But
effects can be disabled, in which case we don't need to do that.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1052
2020-02-14 01:17:42 +01:00
sicklylife
ae344a606d Update Japanese translation 2020-02-13 15:52:40 +00:00
sicklylife
8b70232d25 Update Japanese translation 2020-02-13 15:47:26 +00:00
Carlos Garnacho
1ecfdb1748 backends: Drop meta_idle_monitor_get_for_device()
As far as public API is concerned, there's only one idletime monitor
from now on.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1039
2020-02-12 22:07:55 +00:00
Carlos Garnacho
f7646af810 core: Do not update idle times for slave devices
Those go nowhere, so just avoid doing this.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1039
2020-02-12 22:07:55 +00:00
Carlos Garnacho
586723eb44 backends: Drop per-device idle monitors
We preserve the core one, which represents the union of all input
devices. It might make sense to make this per-seat in the future,
but certainly the per-device granularity is unused (at last!) and
useless.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1039
2020-02-12 22:07:55 +00:00
Adam Jackson
5c704e3f81 cogl: Remove no-op cogl_shader_compile and cogl_shader_get_info_log
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1024
2020-02-12 21:55:44 +00:00
Robert Mader
1981449776 wayland/actor-surface: Do not set opaque region for XWayland clients
XWayland clients get their opaque region set from their window, not the
surface. Doing both resulted in the surface constantly overwriting the
opaque region - effectively disabling culling of XWayland clients.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1049
2020-02-12 01:52:38 +01:00
Olivier Fourdan
98d7a542b0 wayland: Advertise MetaMonitor as wl_output
With the logical size of outputs being handled by xdg-output, we don't
need to "lie" to Wayland clients anymore about the output size, so
advertise the real mode size as wl_output regardless of the scale, as it
should be (and like other Wayland compositors do).

https://bugzilla.gnome.org/show_bug.cgi?id=787363
https://gitlab.gnome.org/GNOME/mutter/merge_requests/994
2020-02-11 18:56:13 +00:00
Jonas Ådahl
438f75e6b3 cursor-renderer-native: Get cursor size from MetaKmsDevice
It now provides this information, so don't get it ourself.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
f3cdc9906c kms/device: Handle tracking capabilities
Devices have capabilities that other parts need to know about. Instead
of having them probe using drmMode* API, outsource this to
MetaKmsDevice. Currently the only capability tracked is HW cursor size.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
ae00f5653e cursor-renderer-native: Port to transactional KMS api
Turns the cursor setting and movement into cursor plane assignment
primitives. In the current simple implementation, this in turn
translates into legacy drmModeSetCursor() and drmModeMoveCursor() calls.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
7c3172a0af kms/impl-simple: Add cursor plane processing
A cursor plane can now be assigned, and for the simple KMS
implementation, it'll translate into drmModeSetCursor() and
drmModeMoveCursor() calls.

When assignments failed, the cursor planes that failed to be assigned
are communicated via the feedback object.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
73dcb9fa22 kms: Make update processing return direct feedback
The current API as all synchronous, so they can be made to return
feedback immediately. This will be needed for the cursor renderer which
needs to know whether it should fall back to OpenGL cursor rendering.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
3ace2b9a28 kms/update: Move auto-cleanup declaration to the bottom
It relies on visible function declarations, so move it to the bottom so
we can add more auto-cleanup declarations same without them being spread
out.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
01bab81727 kms/update: Add flags to plane assignment
Currently unused, but will used to let the implementation know when it
can avoid setting the plane content (i.e. not call drmModeSetCursor()).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
c1fc46e3db kms/device: Fix indentation mistake
https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
4abec2f8e7 kms: Assert that callbacks are outside of the impl context
https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
ee854ed7ab kms: Fix function name
meta_kms_update_process_..() makes it sound like it's a MetaKmsUpdate
function called update_..() but in fact it's a MetaKms function that
calls the corresponding process-update impl function. Clear up this
naming confusion.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
ec9d7145c8 kms: Return gpointer from impl tasks
Currently only used to return either TRUE or FALSE to communicate
success or failure. Will be used to return feedback objects.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
3a8c545b32 kms/device: Add getter for finding cursor planes
Works the same as the getter for the primary planes.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:32:07 +01:00
Jonas Ådahl
6c1e9b51f9 kms-impl-simple: Add helper to process update entries
This avoids some loop iteration boiler plate.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:27:46 +01:00
Jonas Ådahl
851024f730 kms/update: Add unassign_plane() API
Meant to disable a plane.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:27:46 +01:00
Jonas Ådahl
b23fc99655 kms/plane: Move _new() function to private header
Code outside of the MetaKms namespace is not expected to create plane
objects, so move it to a private header. More things will be added to
this header later.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
2020-02-11 18:27:46 +01:00
Olivier Fourdan
0f58c98386 screen-cast-window: Use buffer bounds in place of frame bounds
The frame bounds as returned by `meta_window_actor_get_frame_bounds()`
would be used as cropping values when streaming a window content.

But, as its name implies, it returns the actual frame bounds, whereas we
may want to include the whole buffer, to include client side shadows for
example.

Rename the `get_frame_bounds()` API to `get_buffer_bounds()` (which was
previously partly removed with commit 11bd84789) and return the actual
buffer bounds to use as the cropping area when streaming a window.

Fixes: 931934511 - "Implement MetaScreenCastWindow interface"
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1022
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1018
2020-02-11 12:59:57 +00:00
Olivier Fourdan
ebc07871eb shaped-texture: Add get_width()/get_height() API
Add an API to retrieve the content size of a shaped texture.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1022
2020-02-11 12:59:57 +00:00
Olivier Fourdan
840c50b00d window-actor: Ensure clipping in capture_into()
The clip bounds passed in `meta_window_actor_capture_into()` represent
the actual allocated buffer size where the window actor image will be
eventually copied.

As such, it is completely agnostic to the scaling factors that might
affect the different surface actors which compose the window actor.

So instead of trying to compute the scale factor by which the given
clipping bounds need to be adjusted, simply clip the resulting image
based on the given bounds to make sure we never overflow the destination
buffer.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1022
2020-02-11 12:59:57 +00:00
Carlos Garnacho
e76ff8530b backends/native: Override the right property name
Fixup to https://gitlab.gnome.org/GNOME/mutter/merge_requests/1044,
clearly it's not enough to compile check after "just a minor rename".
2020-02-11 12:02:04 +01:00
Carlos Garnacho
c273f74025 backends: Implement ClutterSeat::touch-mode on MetaSeatNative
This taps on:
1) Touchscreen availability
2) Availability of external keyboards
3) Tablet mode switch, if existent

So we get this property enabled whenever it makes sense to show touch
focused features (eg. the OSK).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1044
2020-02-10 22:04:53 +00:00
Carlos Garnacho
9ff4f29bac build: Depend on libinput 1.7
We will want it for switch events. This release is from 2017, so
presumably old enough by now.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1044
2020-02-10 22:04:53 +00:00
Carlos Garnacho
dcba7c5044 clutter: Add ClutterSeat::touch-mode boolean property
And the corresponding getter. This property returns FALSE by default
and must be overridden by subclasses. This will allow gnome-shell to
hook up specific behavior that should not happen on mouse+keyboard
setups.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1044
2020-02-10 22:04:53 +00:00
Sergio Costas
5b1620475e Fix incorrect 'is' in gen_default_modes
During compilation, gen_default_modes.py shows two warnings that
say that a comparison is using 'is' instead of '=='.

This patch fixes this bug.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/985
2020-02-10 20:35:05 +01:00
Olivier Fourdan
934a829a57 wayland/subsurface: Keep subsurface actors reactive
The actors of Wayland subsurfaces are set to be reactive on creation,
when receiving the `wl_subcompositor.get_subsurface` request.

However, if a client creates several subsurfaces and then creates the
xdg_toplevel object after, the previous subsurface actors are reset.

As a result, Clutter picking will skip and ignore those actors in
`clutter_actor_should_pick_paint()` because they aren't marked as
reactive anymore.

An example of such a client being affected by this issue is SCTK, the
Rust library implementing client side decorations for Wayland used
internally by winit and alacritty.

Move the `set_reactive()` call from `get_subsurface()` to the subsurface
`sync_actor_subsurface_state()` vfunc to make sure those remain reactive
even after `xdg_surface.get_toplevel` is invoked.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1024
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1040
2020-02-10 08:51:41 +00:00
Robert Mader
264f68858a surface-actor: Implement meta_cullable_is_untransformed interface
Its `cull_out()` method was already implemented with geometry scale
in mind. Add a corresponding `is_untransformed()` method so culling
succeeds with geometry scale > 1.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1036
2020-02-08 19:20:41 +01:00
Robert Mader
56ce25360c cullable: Factor out untransformed check into a vfunc
Some cullable implementation may have extra information about their
expected size. The main example here are surface actors which can be scaled
by geometry scale.

Add an API to overwrite the default size / untransformed check for such cases.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1036
2020-02-08 19:20:41 +01:00
Robert Mader
d8b7905662 surface-actor: Scale unobscured and clip region by geometry scale
The local copy of the clip- and unobscured region are used to optimize
painting. To get correct results when the actor is scaled, thus "grows",
the corresponding regions have to "shrink", i.e. get scaled down.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1036
2020-02-07 19:22:15 +01:00
Robert Mader
ae1768bf4f wayland/actor-surface: Do not use geometry scale to constrain regions
The regions and the surface size are all in surface coordinates, thus
don't use the geometry scale, otherwise we might not clip scaled actors
enough.

See also https://gitlab.gnome.org/GNOME/mutter/merge_requests/148

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1036
2020-02-07 18:05:49 +01:00
Robert Mader
cbef49fd74 shaped-texture: Remove unused meta-cullable header
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1036
2020-02-07 18:05:49 +01:00
Hans de Goede
bcbb44fdea monitor-config-manager: honor accelerometer value changes when there is more than 1 monitor
Modify create_for_builtin_display_rotation to lookup the
MetaLogicalMonitorConfig for the panel in the logical_monitor_configs
list instead of only working when there is only 1 monitor.

The goal of this change is to honor accelerometer value changes when there is
more than 1 monitor.

Note, since create_for_builtin_display_rotation is also used for handling the
"rotate-monitor" hotkey and this commit modifies the common path of
create_for_builtin_display_rotation this means that we will now also honor
"rotate-monitor" hotkey keypresses when there is more than 1 monitor and
update the builtin display rotation instead of ignoring "rotate-monitor"
hotkey keypresses when there is more than 1 monitor. If this is deemed
undesirable this is easy to fix, but I believe that doing things this way
is more consistent.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/959
2020-02-07 13:55:39 +01:00
Hans de Goede
0d185b21fd monitor-config-manager: Add clone_logical_monitor_config_list helper
Add a clone_logical_monitor_config_list helper function for making a deep
copy of MetaLogicalMonitorConfig lists.

This is a preparation patch for honoring accelerometer value changes when
there is more than 1 monitor.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/959
2020-02-07 13:50:51 +01:00
Hans de Goede
e4d5cb72ee monitor-config-manager: Take device orientation into account for new configs
When creating a new config because of a monitor being (un)plugged or
because of super+p being pressed, honor the orientation reported by
the accelerometer for the internal panel.

Before this commit we would always configure the internal panel with
a normal / upright transform when e.g. an external monitor gets plugged
in even if another transform was in use before plugging in the external
monitor. This is inconsistent and causes problems for several use-cases.
This commit fixes this by querying the accelerometer when creating a new
config for an internal panel.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/707
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/924

https://gitlab.gnome.org/GNOME/mutter/merge_requests/959
2020-02-07 13:46:45 +01:00
Hans de Goede
c37e2523ac orientation-manager: Do not change current orientation when locked
Bail out of sync_state() immediately if the orientation is locked, before
calling read_iio_prox() which updates the curr_orientation value.

There are 2 reasons for this change:

1. Currently meta-monitor-config-manager.c always assumes normal / upright
orientation when generating a new config. This means that e.g. when an
external monitor gets plugged in the builtin panel's transform will be reset
to normal / upright even if the device is not in an upright orientation.

To fix this meta-monitor-config-manager.c needs to call
meta_orientation_manager_get_orientation() to get the current orientation
when generating a new config. Without this change locking the orientation
would stop the emitting of "orientation-changed" signals but we would
still update the curr_orientation value. So when a new config needs to
be generated the latest orientation would be used, effectively ignoring
the "orientation-lock" setting, not updating curr_orientation when
locked fixes this.

2. This ensures we properly emit an an "orientation-changed" signal when
the orientation has changed between when it was locked and it was
unlocked. Before this change if the user locked the orientation, changed it
and then unlocked it, no signal would be raised as we would already have
updated the curr_orientation value turning the sync_state() call in
orientation_lock_changed() into a no-op.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/959
2020-02-07 13:46:45 +01:00
Florian Müllner
c4f8b93357 Bump version to 3.35.90
Update NEWS.
2020-02-06 18:02:21 +01:00
Daniel van Vugt
06dae3a8cc wayland-pointer: Bail unconditionally if without native backend
Using `-Dnative_backend=false` caused build failure due to a missing
(implicit) definition of `META_IS_BACKEND_X11`. But if we define it
properly then that just leaves some of the function's locals uninitialized
and it will never work anyway. Just return unconditionally if there's no
native backend to initialize the variables.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1025
2020-02-05 18:09:34 +08:00
Daniel van Vugt
76240e24f7 background: Scale monitor_area after texture creation
Scaling the `monitor_area` before texture creation was just wasting
megabytes of memory on resolution that the monitor can't display. This
was also hurting runtime performance.

Example:

  Monitor is natively 1920x1080 and scale set to 3.

  Before: The monitor texture allocated was 5760x3250x4 = 74.6 MB
  After:  The monitor texture allocated is  1920x1080x4 =  8.3 MB

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/2118

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1004
2020-02-04 19:48:01 +00:00
Olivier Fourdan
9b0392e988 backends/native: Emit signals for virtual devices
When creating a virtual device for the native backend, no "device-added"
is emitted.

Similarly, no "device-removed" signal is emitted either when the virtual
device is disposed.

However, the backend plugs into the "device-added" signal to set the
monitor device. Without the "device-added" signal being emitted, the
monitor associated with a virtual device remains NULL.

That later will cause a crash in `meta_idle_monitor_reset_idlettime()`
called from `handle_idletime_for_event()` when processing events from a
virtual device because the device monitor is NULL.

Make sure to emit the "device-added" signal when creating a virtual
device, and the "device-removed" when the virtual device is disposed.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1037
2020-02-04 18:26:52 +01:00
Florian Müllner
aa0aa89a1e window: Ignore requests to be placed on non-existent workspaces
When an X11 window requests an initial workspace, we currently trust
it that the workspace actually exists. However dynamic workspaces
make this easy to get wrong for applications: They make it likely
for the number of workspaces to change between application starts,
and if the app blindly applies its saved state on startup, it will
trigger an assertion.

Make sure that we pass valid parameters to set_workspace_state(),
and simply let the workspace assignment fall through to the default
handling otherwise.

https://gitlab.gnome.org/GNOME/mutter/issues/1029
2020-02-04 00:07:54 +00:00
Robert Mader
b91d66bf98 core: Extend list of image formats to be stored in the clipboard manager
These types are probably common enough to support.

See also:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1034
2020-02-03 16:51:15 +01:00
Carlos Garnacho
832c0fb0ea core: Define specific image formats to be stored in the clipboard manager
And order those preferences in order of lossiness (jpeg < png < bmp). This
avoids us from prefering other formats that are not useful or widely
recognized.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/939
2020-02-03 13:19:00 +00:00
Carlos Garnacho
2fbbf657d5 core: Demote image formats' priority from preservation in clipboard manager
Most usually, applications either expose clipboard content either as text
or as images, so the prioritization here is pointless. However there's some
outliers like LibreOffice Calc which exports content as both image and text
formats (besides other internal ones).

In that mixed case, we probably prefer to keep text formats, rather than
image based ones.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/919
2020-02-03 13:19:00 +00:00
Sebastian Keller
81de2c2913 backends/x11: Fix use after free on device removal
The devices_by_id hash table is responsible for managing the reference
to the devices. In remove_device however, for non-core devices there are
additional calls to dispose/unref, after the last reference has
already been dropped by the hash table.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1032
2020-02-01 15:35:49 +00:00
Carlos Garnacho
ffad55c66f wayland: Handle dragging from/dropping to v1 data device users
Interoperation between wl_data_device_manager v1 and v3 got broken
at some point. Ensure that we resort to the "copy" action if either
the drop site or the drag source are from a client that requested v1.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/965
2020-02-01 15:14:52 +00:00
Sebastian Keller
2212a44cc2 clutter/actor: Fix GValue leak when overwriting transition values
When the 'initial'/'final' values of an existing transition were being
overwritten, the GValues used in _clutter_actor_create_transition()
were not being unset.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1033
2020-02-01 15:00:15 +00:00
Sebastian Keller
98040e67a2 core: Fix task leak in meta_selection_source_memory_read_async
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Sebastian Keller
e7928ce6ee selection: Fix task leak in error case of source_read_cb
Fixes the last part of https://gitlab.gnome.org/GNOME/mutter/issues/1006
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Sebastian Keller
b41094ef5f x11-selection: Unref owners and cancellables on shutdown
Selection owners are set using g_set_object in source_new_cb, but that
reference is never removed on shutdown.

Similarly the cancellables created in handle_xfixes_selection_notify are
never freed on shutdown.

Fixes parts of https://gitlab.gnome.org/GNOME/mutter/issues/1006
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Sebastian Keller
d699c80ac2 display: Unref selection on shutdown
Otherwise it will be leaked and the dispose method added in the previous
commit would never be run.

Fixes parts of https://gitlab.gnome.org/GNOME/mutter/issues/1006
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Sebastian Keller
35316a034f selection: Unref selection owners on dispose
Selection owners are set using g_set_object, which adds a reference to
the owner, which then never was removed on shutdown.

Fixes parts of https://gitlab.gnome.org/GNOME/mutter/issues/1006
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Sebastian Keller
c05019e232 x11-selection: Don't store copies of strings that are not being used
MetaX11SelectionOutputStream was storing copies of strings only to use
them in init and then free them in finalize. This was also causing a
small leak, because one of these strings was not freed. Instead of doing
that just don't create these unnecessary copies in the first place.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Sebastian Keller
861e5caf8c x11-selection: Plug potential GInputStream leak
The stream was not freed in the error case. I have never observed this
one in practice though.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Sebastian Keller
8e6821bc65 x11-selection: Plug MetaSelectionSourceX11 leak
meta_selection_source_x11_new_finish() transfers the ownership of the
selection source, but source_new_cb() was not freeing it.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/998
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Sebastian Keller
05301d280c clipboard-manager: Plug mimetypes list leak
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/1005
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1001
2020-02-01 14:02:19 +00:00
Adam Jackson
c1bdaba5ac cogl: Inline cogl_use_program into its one caller
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
640ad4718e cogl: Inline _cogl_framebuffer_remove_all_dependencies into its one caller
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
985b3b32ce cogl: Remove unused _cogl_pipeline_get_layers
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
795491c80a cogl: Remove unused cogl_program_use and friends
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
f5e2310dc7 cogl: Remove unused _cogl_framebuffer_set_clip_stack
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
c5a936e0e8 cogl: Remove unused _cogl_framebuffer_{push,pop}_projection
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
600dd155ce cogl: Remove unused p-axis texture wrap mode
Unused since removing 3D textures.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
99043e2af2 cogl: Mark _cogl_buffer_access_to_gl_enum static
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
e0d2e1096d cogl: Remove unused _cogl_framebuffer_try_creating_gl_fbo
Unused since the cogl-gles2 removal in 7e8a8649.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Adam Jackson
136c09585d cogl: Remove unused cogl.symbols
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1015
2020-01-31 17:26:25 +00:00
Robert Mader
15b46a6f88 wayland/data-device: Small style fixes
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1031
2020-01-31 12:13:02 +01:00
Robert Mader
c27fc3537b wayland/data-device: Guard against a potential crash
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1031
2020-01-31 12:13:02 +01:00
Robert Mader
6cc748cce9 wayland/data-device: Cancel drag source when the drag finished unsuccessfully
When a drag was performed but did not finish successfully, e.g. because no
mimetype was accepted, we need to send the source cancel event so clients
know they can destroy the drag source (since version 3).

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/740

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1031
2020-01-31 12:13:02 +01:00
Sebastian Keller
afd645193a backends/native: Use proper method for getting core idle monitor
e9fbbd5853 changed meta_backend_get_idle_monitor() to use
ClutterInputDevice pointers instead of device IDs, but did not adjust
the call in meta_backend_native_resume() which was still using 0 to get
the core idle monitor resulting in a NULL pointer dereference.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1029
2020-01-30 22:19:49 +00:00
Sebastian Keller
09af21cd0b clutter: Fix input device node path leak
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1030
2020-01-30 22:28:56 +01:00
Daniel van Vugt
2731be6929 clutter/actor: Use the new shallow relayout API
If an actor sets flag `CLUTTER_ACTOR_NO_LAYOUT` then that means it
is (or should be) unaffected by `queue_relayout` calls in its children.
So we can avoid propagating `queue_relayout` all the way up to the stage
and avoid a full stage relayout each time.

But those children whose parent has `CLUTTER_ACTOR_NO_LAYOUT` still need
to be allocated at some point. So we do it at the same point where it
happened before. Only we now queue a *shallow* relayout so the `allocate`
run on the next frame doesn't need to descend the whole actor tree anymore.
Only a subtree and hopefully very small.

For free-floating and top-level actors this provides a measurable
performance benefit. According to Google Profiler, calls to
`_clutter_stage_maybe_relayout` are now so cheap that they no longer show
up in performance profiles.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/575
2020-01-30 18:31:24 +00:00
Daniel van Vugt
5257c6ecc2 clutter/stage: Add an API for shallow relayouts
Where "shallow" means you can specify any actor instead of every relayout
having to start from the stage.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/575
2020-01-30 18:31:24 +00:00
Carlos Garnacho
5723bd8ec7 backends: Use latest pointer position if no pointer constrain exists
The meta_seat_native_constrain_pointer() function receives the current
pointer position, and the new pointer position as in/out parameters.
We were however calculating the new coordinates based on the last pointer
position if there was no pointer constrain in place.

Fortunately to us, this didn't use to happen often/ever, as a pointer
constrain function is set on MetaBackend initialization. This behavior
did also exist previously in MetaDeviceManagerNative.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1028
2020-01-30 18:57:18 +01:00
Carlos Garnacho
1e9682b417 backends: Move warp_pointer() to ClutterSeat
The onscreen pointer sprite is a per-seat element, so it makes sense
to move pointer warping over there too.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:12:58 +01:00
Carlos Garnacho
9da275cf73 backends: Set pointer constrain/relative motion hooks before backend init
The backend being initialized triggers a pointer warp (and motion event)
where we want to observe the callbacks put in place. So ensure we set
up the hooks before that could happen.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:12:58 +01:00
Carlos Garnacho
f1d4d687f3 backends: Drop get_relative_motion_deltas() vfunc
Just go ATM through backend checks, and looking up directly the
native event data, pretty much like the rest of the places do that...
Eventually would be nice to have this information in ClutterEvent,
but let's not have it clutter the MetaBackend class.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:11:37 +01:00
Carlos Garnacho
e9fbbd5853 backends: Do not use device IDs on idle monitors
Device IDs are somewhat x11 specific, seems better to avoid those
on public API. We can rely everywhere on ClutterInputDevice, so use
it instead.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:11:23 +01:00
Carlos Garnacho
d3160d095d clutter: Drop ClutterDeviceManager
This is mostly replaced by ClutterSeat, which offers a per-seat instead
of a global device abstraction.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:11:23 +01:00
Carlos Garnacho
873449d0f9 tests: Replace ClutterDeviceManager usage in favor of ClutterSeat
https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:11:23 +01:00
Carlos Garnacho
4413b86a30 backends: Replace ClutterDeviceManager usage in favor of ClutterSeat
https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:11:23 +01:00
Carlos Garnacho
f8fa86f9db clutter: Replace ClutterDeviceManager usage in favor of ClutterSeat
https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:11:23 +01:00
Carlos Garnacho
f55d4f33af backends: Make meta_backend_update_last_device() take a clutter device
Instead of a pretty x11 specific device ID. This also updates the argument
of the ::last-device-changed signal to be a ClutterInputDevice.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:02:34 +01:00
Carlos Garnacho
4761c4ee1c backends: Move native keymap manipulation functions to MetaSeatNative
Since the ClutterKeymap is obtained through the ClutterSeat, it makes
sense to have these manipulation functions in the ClutterSeat impl.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:02:34 +01:00
Carlos Garnacho
7644ddeddc core: Replace ClutterDeviceManager usage in favor of ClutterSeat
https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:02:34 +01:00
Carlos Garnacho
6dfd2ffcef wayland: Replace ClutterDeviceManager usage in favor of ClutterSeat
https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:02:34 +01:00
Carlos Garnacho
835f12043e clutter: Drop select_stage_events() device manager vfunc
This is specific to X11, so handle it within the X11 backend.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:02:34 +01:00
Carlos Garnacho
7afbc01fe8 clutter: Move motion compression handling to ClutterSeat
Another responsibility taken away from ClutterDeviceManager

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:02:31 +01:00
Carlos Garnacho
1c689b83f9 clutter: Move virtual device management to ClutterSeat
A11y in general may be considered a per-seat feature.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:02:14 +01:00
Carlos Garnacho
8d0527f674 clutter: Move pointer a11y from ClutterDeviceManager to ClutterSeat
A11y in general may be considered a per-seat feature.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:01:53 +01:00
Carlos Garnacho
bc7ba8c875 clutter: Move keyboard a11y from ClutterDeviceManager to ClutterSeat
A11y in general may be considered a per-seat feature.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 18:01:50 +01:00
Carlos Garnacho
34ce39f8dc clutter: Move platform event data management to ClutterSeat
https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 17:59:47 +01:00
Carlos Garnacho
9be4f98c73 clutter: Move keymap from ClutterBackend to ClutterSeat
Keymaps are a per-seat feature, so move it there.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 17:59:47 +01:00
Carlos Garnacho
1fc021c3c6 clutter: Move bell_notify() from ClutterBackend to ClutterSeat
Bells can be considered to be a per-seat feature, so move it there.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 17:59:46 +01:00
Carlos Garnacho
9aba37f70f clutter: Move keymap direction from ClutterBackend to ClutterKeymap
This makes more sense to have in the ClutterKeymap, since we have it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 17:59:46 +01:00
Carlos Garnacho
5bb3d86884 native: Implement ClutterSeat
We had the MetaSeatNative struct around, so use it as the base of
this Clutter object. A few responsibilities were drawn from
ClutterDeviceManager.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 17:59:41 +01:00
Carlos Garnacho
1611979fa8 x11: Implement ClutterSeat
The ClutterDeviceManager signaling becomes implemented on top of this.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 16:28:51 +01:00
Carlos Garnacho
467e94f858 clutter: Add ClutterSeat object
This object will take most responsibilities away from ClutterDeviceManager,
with the peculiarity that it'll express the per-seat device tree.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 16:28:51 +01:00
Carlos Garnacho
88fb003cdc x11: Drop subscription for input event from floating devices
This is unlikely to happen, and unlikely to be right (eg. we don't translate
input event coordinates, since those are not in display coordinate space, we
don't offer any feedback for those either).

This can simply be dropped, we listen to XIAllMasterDevices, which suffices
for what we want to do.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
2020-01-30 16:28:51 +01:00
Olivier Fourdan
a382698acc wayland: Update input device before repick
When a Wayland window is mapped or unmapped, the Wayland compositor is
expected to send the coorespoindign `wl_pointer` enter/leave events to
the affected clients.

To do so, mutter calls `meta_wayland_compositor_repick()` which
eventually calls `meta_wayland_pointer_repick()` and
`repick_for_event()`.

If pointer input device has not been updated yet, the old clutter actor
is picked and no enter/leave event is emitted.

Make sure we update the pointer input device prior to do the repick to
get the actual `ClutterActor` under the pointer.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1016
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1026
2020-01-30 09:37:58 +01:00
Olivier Fourdan
8b3bc1f97d clutter: Export clutter_input_device_update()
The private function `_clutter_input_device_update()` is not currently
exported.

This function calls `_clutter_input_device_set_actor()` which updates
the `ClutterActor` under the pointer, so making that function available
outside of Clutter will allow to make sure the pointer device actor is
updated prior to do picking.

Also, now that the functions is exported to the upper layers, drop the
underscore suffix from the function name.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1026
2020-01-30 09:37:58 +01:00
Olivier Fourdan
5618e41cea window: Remove Wayland code from meta_window_show()
As we now call `meta_wayland_compositor_repick()` when the effects are
complete for Wayland surfaces, we can safely remove the Wayland specific
code to do the same from `meta_window_show()`.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1026
2020-01-30 09:37:58 +01:00
Olivier Fourdan
f97930eaf5 wayland/surface: Repick when effects are complete
When mapping/unmapping windows, an animation may be played which can
change the actual actor size and location, hence defeating picking if
done too early.

Make sure we repick when the affects are completed, once the actor is
sized and placed.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1026
2020-01-30 09:37:58 +01:00
Alberts Muktupāvels
5e07478843 x11-display: add support for _GTK_WORKAREAS_Dn
In addition to existing _NET_WORKAREA property set also new
_GTK_WORKAREAS_Dn property where n is desktop number (between 0
and _NET_NUMBER_OF_DESKTOPS - 1).

https://mail.gnome.org/archives/wm-spec-list/2018-December/msg00000.html
https://gitlab.freedesktop.org/xdg/xdg-specs/merge_requests/22

https://gitlab.gnome.org/GNOME/mutter/merge_requests/370
2020-01-29 11:08:21 +00:00
Olivier Fourdan
1ce933e281 window-actor/x11: Get frame rect from the buffer size
When building the frame mask, the current reported frame size may not
match when is actually on screen if the buffer has not been updated
yet.

So instead of getting the frame size from the meta window, deduce it
from the texture size.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1009
2020-01-29 10:44:50 +00:00
Olivier Fourdan
1000ebe203 window/x11: Add function to convert the buffer to frame rect
Add a convenient function to get the frame rectangle from a given
buffer.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1009
2020-01-29 10:44:50 +00:00
Olivier Fourdan
c0321c7b21 frame: Pass the frame area for get_mask()
Currently, `meta_frame_get_mask()` and `meta_ui_frame_get_mask()` will
return the frame mask applied to the current frame size, by querying the
frame themselves.

To be able to get the frame mask at an arbitrary size, change the API to
take a rectangle representing the size at which the frame mask should be
rendered.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1009
2020-01-29 10:44:50 +00:00
Olivier Fourdan
7dbb4bc3f5 window-actor/x11: Cache the client area
With Xwayland, the shape region is recomputed and reapplied even when
the actor is frozen to prevent the black shadows effect.

However, while recomputing the shape region, the current client size is
taken into account, rather than the size when the client was frozen,
which is ahead of the actual client size using the NET_WM_SYNC protocol.

Keep the current client area and to reuse them when the X11 window actor
is frozen for rebuilding the client mask texture.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1009
2020-01-29 10:44:50 +00:00
Corentin Noël
9d390ee49f meta: Add missing display.h to meta-workspace-manager.h
This is required because MetaDisplayCorner is only defined in display.h

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1025
2020-01-29 11:30:24 +01:00
Carlos Garnacho
403466c0db wayland: Implement dnd cancel on pressing Esc key
When this key is pressed the DnD operation should be cancelled,
and the "pop DnD icon back" animation to happen.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1020
2020-01-28 14:05:35 +00:00
Jonas Dreßler
f2f89d9b46 clutter/actor: Respect CONTENT_SIZE request mode in get_preferred_* APIs
Right now the CONTENT_SIZE request mode for a ClutterActor is only
respected by `clutter_actor_get_preferred_size()`, but not by
`get_preferred_width()` and `get_preferred_height()`. Those simply try
to ask the layout manager and will return [0, 0] for actors without
children. So be consistent and also return the content size in those two
functions.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1019
2020-01-27 14:57:13 +00:00
Carlos Garnacho
30bf588a38 wayland: Do not check current offer on DnD button release
This check was added on commit 48639ac5 as a means to disregard
DnD drops where the offer would disappear beforehand. However since
that commit was all about wl_data_device_manager version < 3,
forgetting about the selected mimetype seems a behavior more inline
with those versions.

Since no current drop is something expected on X11 drop sites, fixes
DnD over those, while keeping the original bug fixed.

Found by Robert Mader (https://gitlab.gnome.org/GNOME/mutter/issues/974#note_688144)

https://gitlab.gnome.org/GNOME/mutter/issues/974
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1005
2020-01-27 14:07:47 +00:00
Carlos Garnacho
090a6ad409 xwayland: Set XDND source-side actions as per XDND
In XDND, we just get a hint on XdndPosition about what's the action
chosen by the user. Make the data source actions the full set on
XdndEnter (as we can't know better), and pass the hint in XdndPosition
as the user chosen action as it should be.

Makes Wayland drop sites aware of the user action as per XDND with X11
drag sources, and still makes modifiers during DnD work.

https://gitlab.gnome.org/GNOME/mutter/issues/974
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1005
2020-01-27 14:07:47 +00:00
Carlos Garnacho
a6c195b05c x11: Map x11 (UTF8_)STRING requests to text/plain mimetypes
Make the x11 selection proxy map UTF8_STRING and STRING to proper
mimetypes, as the selection source (wayland or memory) might not
offer those for backwards compatibility.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1355
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1005
2020-01-27 14:07:47 +00:00
Carlos Garnacho
c1df48befd wayland: Preserve XdndTypeList for future callers
This Xdnd property is owned by the drag source, we shouldn't delete
it when reading/proxying it to Wayland clients.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/2347
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1005
2020-01-27 14:07:47 +00:00
Umarzuki Bin Mochlis Moktar
102c07d5e5 Update Malay translation 2020-01-27 12:28:08 +00:00
Sebastian Keller
abc58f7b9d kms: Fix drmModeEncoder leak
The result of drmModeGetEncoder() needs to be free'd by the caller.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1020
2020-01-24 21:10:11 +00:00
Sebastian Keller
66fe6d85d0 backends/crtc: Fix leak of MetaCrtcMode name string
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1020
2020-01-24 21:10:11 +00:00
Sebastian Keller
a63e80ec64 wayland: Avoid GVariant leak in set_gnome_env
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1020
2020-01-24 21:10:11 +00:00
Sebastian Keller
9feda1c58b kms/crtc: Fix gamma state leak
The gamma value pointers of the current_state are overwritten by the
calls to memdup causing a small leak. while the leak itself is small, it
can be triggered quite often from things like night light.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1020
2020-01-24 21:10:11 +00:00
Sebastian Keller
51733ca499 window/wayland: Plug window configuration leak
The acked configuration is removed from the pending configuration list
by acquire_acked_configuration(), but finish_move_resize() does not free
the data after applying the configuration.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1020
2020-01-24 21:10:11 +00:00
Sebastian Keller
f0c92646eb wayland/surface: Plug leak in meta_wayland_surface_assign_role
The underlying data of the names array is not used anymore after this,
so it should be freed as well.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1020
2020-01-24 21:10:11 +00:00
Daniel van Vugt
d28a640960 backend-eglnative: Search for the xsettings schema recursively
As recommended by the docs for `g_settings_schema_source_get_default`:

> The returned source may actually consist of multiple schema sources
> from different directories, depending on which directories were given
> in XDG_DATA_DIRS and GSETTINGS_SCHEMA_DIR. For this reason, all lookups
> performed against the default source should probably be done recursively.

Now it's actually found and works again, including subpixel font smoothing.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1447

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1017
2020-01-24 17:38:06 +00:00
Jonas Dreßler
b3fbc26340 clutter/actor: Allow setting width and height properties to -1.0
ClutterActors width and height can be reset to automatically use the
preferred (calculated) value by setting the width or height to -1, so
far this only works by setting it using `clutter_actor_set_width()` or
`clutter_actor_set_height()`, make sure it can also be done using the
"width" and "height" GObject properties.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1018
2020-01-24 17:27:31 +00:00
sicklylife
612b622689 Update Japanese translation 2020-01-24 16:31:54 +00:00
sicklylife
ccd33ce17f Update Japanese translation 2020-01-24 16:29:17 +00:00
Sebastian Keller
f447a053bb renderer: Chain up parent class finalize
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1016
2020-01-22 20:56:34 +01:00
Adam Jackson
545fcb3dbf renderer-native: Fix memory leak in secondary GPU update
Leaking a texture object and a framebuffer object every time you update
the secondary GPU is perhaps not the best plan.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1011
2020-01-21 14:39:01 +00:00
Sebastian Keller
65401ed3f9 clutter/cogl: Plug region leak in clutter_stage_cogl_redraw_view
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/1000
2020-01-16 20:57:20 +00:00
Sebastian Keller
b30a29f830 shaped-texture: Plug region leak
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1002
2020-01-16 20:57:20 +00:00
Pekka Paalanen
b6c824dd16 renderer/native: Import primary buffer to 2nd GPU
Where possible, try to export the buffer rendered by the primary GPU as a
dmabuf and import it to the secondary GPU and turn it into a DRM FB for
scanout. If this works, we get a zero-copy path to secondary GPU outputs.

This is especially useful on virtual drivers like EVDI (used for DisplayLink
devices) which are not picky at all about what kind of FBs they can handle.

The zero-copy path is prioritised after the secondary GPU copy path, which
should avoid regressions for existing working systems. Attempting zero-copy
would have the risk of being less performant than doing the copy on the
secondary GPU. This does not affect the DisplayLink use case, because there is
no GPU in a DisplayLink device.

The zero-copy path is prioritised before the primary GPU and CPU copy paths. It
will be tried on the first frame of an output and the copy path is executed
too. If zero-copy fails, the result from the copy path will take over on that
frame. Furthermore, zero-copy will not be attemped again on that output. If
zero-copy succeeds, the copy path is de-initialized.

Zero-copy is assumed to be always preferable over the primary GPU and CPU copy
paths. Whether this is universally true remains to be seen.

This patch has one unhandled failure mode: if zero-copy path first succeeds and
then fails later, there is no fallback and the output is left frozen or black.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
2020-01-16 20:19:29 +00:00
Pekka Paalanen
03ac7b1821 backend/native: Share drmModeAddFB code
With all the three paths this is quite a handful of code, and it was mostly
duplicated in two places. A follow-up patch would need to introduce a third
copy of it. Therefore move the code into a helper function.

There are two behavioral changes:

- The format error now prints the string code as well, because it is easy to
  read.

- The g_debug() in init_dumb_fb() is removed. Did not seem useful.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
2020-01-16 20:19:29 +00:00
Pekka Paalanen
f409dddb54 renderer/native: Extract secondary_gpu_release_dumb
There will be another place where I need to release the dumb buffers but not
destroy the whole secondary_gpu_state, so extract this bit of code into a
helper.

The checks of fb_id are dropped as redundant with the check already in in
release_dumb_fb ().

https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
2020-01-16 20:19:29 +00:00
Pekka Paalanen
fe76e6a228 renderer/native: Reset all fields of MetaDumbBuffer
release_dumb_fb () checks 'map' to see if anything needs freeing. Other places
are checking fb_id instead. The checks maybe redundant, but let's reset all
fields here while at it, so that all the checks work as expected.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
2020-01-16 20:19:29 +00:00
Pekka Paalanen
40408150f0 renderer/native: Absorb free_next_secondary_bo
The function is trivial and only used once, so fold it into the caller.

Makes the code more readable by removing a little bit of boilerplate.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
2020-01-16 20:19:29 +00:00
Pekka Paalanen
fea6abb4f0 renderer/native: Copy mode irrelevant for bo freeing
Simplify the bo freeing functions by not checking what the copy mode is. This
matches what swap_secondary_drm_fb () already does. g_clear_object () is safe
to call even if the value is already NULL.

The copy mode does not change mid-operation. If it did, this change would
ensure we still clean up everything. So this is more future-proof too.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
2020-01-16 20:19:29 +00:00
Pekka Paalanen
94992ffff6 renderer/native: META_DRM_BUFFER is not NULL-safe
I could not find this in GObject documentation, but I hear the cast macro is
not safe to call with NULL.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
2020-01-16 20:19:29 +00:00
Pekka Paalanen
d7c9042c78 renderer/native: state consistency in copy_shared_framebuffer_gpu
To mirror what happens in meta_onscreen_native_swap_buffers_with_damage(), warn
here too if next_fb is not NULL. This makes it clear to the reader of what the
expectations are inside this function.

Ensuring next_fb is NULL as the first thing in the function will make all error
paths equal: no longer some failures reset next_fb while others don't. Removing
such special cases should reduce surprises.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
2020-01-16 20:19:29 +00:00
Adam Jackson
5b1ff5935e cogl: Clean up private feature flags and GLSL builtin handling of same
https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Adam Jackson
347619a85f cogl: Remove unused GL imports from the CoglContext vtable
Notably this deletes cogl-fixed-functions.h since we are no longer using
any of the GL1-style fixed-function pipeline API.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Adam Jackson
282eab45f7 cogl: Stop using glPointSize in big-GL
Just pass it in to the vertex shader like in GLES, it's one less thing
to vary between drivers. mutter is, shall we say, not a heavy user of
point primitives, so any performance impact (it might be measurable, who
knows) is not an issue. Again, the feature flag remains to be cleaned up
in a future commit.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Adam Jackson
35f21c5bc0 cogl: Stop using glAlphaFunc in big-GL
We're always running through the GLSL pipeline so the fixed-function
alpha test is never invoked. This change does not yet remove the
alpha-test feture bit from the context because this bit of uniform
handling is going to be simplified in a future commit.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Adam Jackson
9f2662c7f8 cogl: Remove fixed-function handling for layer color
This can't matter anymore, glColor* doesn't get used when drawing
through a shader.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Adam Jackson
71a2ba7a98 cogl: Remove fixed-function workaround for point sprite coordinates
https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Adam Jackson
3f2ad5a50a cogl: Remove builtin/texcoord attribute tracking bitmasks from CoglContext
These were only being set from the fixed-function pipeline.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Adam Jackson
abd094d135 cogl: Remove stray references to gl*Pointer, which we're never calling
https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Adam Jackson
737763112e cogl: Remove unused CoglMatrixMode
https://gitlab.gnome.org/GNOME/mutter/merge_requests/995
2020-01-16 18:38:20 +00:00
Jonas Ådahl
ce3409b2b7 kms-impl-simple: Handle mode set race conditions gracefully
If we end up trying to do a mode set on a DRM state that has already
changed behind our back without us yet having seen the hotplug event we
may fail with `EINVAL`. Since the renderer layer doesn't handle mode set
failure, it'll still try to page flip later on, which will then also
fail. When failing, it'll try to look up the cached mode set in order to
retry the mode set later on, as is needed to handle other error
conditions. However, if the mode set prior to the page flip failed, we
won't cache the mode set, and the page flip error handling code will get
confused.

Instead of asserting that a page flip always has a valid cached mode set
ready to look up, handle it being missing more gracefully by failing to
mode set. It is expected that things will correct themself as there
should be a hotplug event waiting around the the corner, to reconfigure
the monitor configuration setting new modes.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/917

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1007
2020-01-16 14:50:34 +00:00
Jonas Ådahl
7733f88168 kms-impl-simple: Include mode name in error message
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1007
2020-01-16 14:50:34 +00:00
Olivier Fourdan
c0038f6dac window-actor/x11: Update shape even when frozen
On Xwayland, freezing actor updates on sync requests means the
server-side frame and shadows repaint will be frozen as well, which
causes the shadow to show black at times when resizing X11 clients
which support NET_WM_SYNC.

Using freeze/thaw commits prevents the content from changing, yet the
shape window still needs to be updated when frozen otherwise the
difference in shape induced by the on-going resize operation will show
as well, even if the toplevel window has its commits frozen.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
Closes: https://bugzilla.gnome.org/show_bug.cgi?id=767212
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/858
2020-01-16 09:22:25 +01:00
Olivier Fourdan
4d5a86327a window/x11: Add always_update_shape() vfunc
To address the black shadows that sometimes show during resize with
Xwayland, we need to update the window shape regardless of the frozen
status of the window actor.

However, plain Xorg does not need this, as resized windows do not clear
to black, so add a new vfunc to window/x11 to indicate whether or not
the backing windowing system (either plain X11 or Xwayland) would
require the shape to be always updated.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Olivier Fourdan
d7a7af1ff2 window-actor/x11: Freeze/thaw commits on actor freeze/thaw
When using Xwayland, if the damage get posted before the X11 window
manager/compositor has finished repainting the actors, the intermediate
state will show.

Make sure to hint Xwayland as to when it can post pending damages and
commit the Wayland buffer using the `freeze_commits()/thaw_commits()`
API, based on window actor freeze/thaw.

See-also: https://gitlab.gnome.org/GNOME/mutter/merge_requests/855
See-also: https://gitlab.freedesktop.org/xorg/xserver/merge_requests/316

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Olivier Fourdan
aa017383ac window-actor: Add set_frozen vfunc
Currently, the window actor freeze/thaw implementation sets the frozen
state of the surface actor using `meta_surface_actor_set_frozen()`.

If we want to expand that behavior to also freeze/thaw commits for X11
windows running on Xwayland, we need to have a specific vfunc to abstract
that in the window actor specific implementation.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Olivier Fourdan
c3c54e8ce6 surface-actor: Add meta_surface_actor_is_frozen()
Change the internal `is_frozen()` API to be available publicly.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Olivier Fourdan
53fce8e988 frames: Freeze Xwayland commits until repainted
To make sure the frame is painted before the commits are thawed, freeze
the commits when invalidating the GDK window, only to thaw to it after
the actual frame draw is performed or the frame is destroyed.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Olivier Fourdan
4ae9953607 window/x11: Freeze commits on resize
Make sure we freeze commits before resizing the window as this will
clear the frame to black.

Set the "thaw on paint" flag so that the post paint for window actor X11
can then thaw the freeze initiated prior to the resize and keep the
freeze/thaw balanced.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Olivier Fourdan
10796e6726 window/x11: Add flag to thaw commits after resize
To be able to thaw commits following a resize that might have frozen
commits, to keep freezes and thaws even, we need a way to tell whether
a repaint should also thaw commits.

Add a flag to `MetaWindowX11` and the appropriate functions to set and
query it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Olivier Fourdan
845157c111 window/x11: Add freeze_commits()/thaw_commits()
Xwayland may post damages for an X11 window as soon as the frame
callback is triggered, while the X11 window manager/compositor has not
yet finished updating the windows.

If Xwayland becomes compliant enough to not permit updates after the
buffer has been committed (see [1]), then the partial redraw of the X11
window at the time it was posted will show on screen.

To avoid that issue, the X11 window manager can use the X11 property
`_XWAYLAND_ALLOW_COMMITS` to control when Xwayland should be allowed to
post the pending damages.

Add `freeze_commits()` and `thaw_commits()` methods to `MetaWindowX11`
which are a no-op on plain X11, but sets `_XWAYLAND_ALLOW_COMMITS` on
the toplevel X11 windows running on Xwayland.

[1] https://gitlab.freedesktop.org/xorg/xserver/merge_requests/316
See-also: https://gitlab.gnome.org/GNOME/mutter/merge_requests/855

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Ray Strode
bac188b568 window: Always disarm XSYNC watchdog when X client responds
At the moment we only disarm the watchdog timer set up for SYNC counter
requests if we're in the middle of a resize operation.

It's possible that the resize operation finished prematurely by the user
letting go of the mouse before the client responded.  If that happens, when the
client finally updates mutter will erroneously still have the watchdog timer
engaged from before until it times out, leading to resizes for the next second
or so to not get processed, and the client to get blacklisted from future sync
requests.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/942
2020-01-16 09:22:25 +01:00
Jonas Ådahl
6d15231f10 wayland/actor-surface: Always consider unmapped actors not on output
This avoids using bogus geometric values from an unmapped actor to
determine whether an actor is on a logical monitor or not. This would
happen when committing to a subsurface of a yet to be mapped toplevel.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/961
2020-01-10 16:01:22 +00:00
Jonas Ådahl
3e90070b88 tests/wayland: Test subsurface commits after parent was reset
Without 'wayland/surface-actor: Reset and sync subsurface state when
resetting' this test would fail.

This also adds a simple framework for testing lower level Wayland
semantics.

In contrast to the test-client and test-driver framework, which uses
gtk and tests mostly window management related things, this framework is
aimed to run Wayland clients made to test a particular protocol flow,
thus will likely consist of manual lower level Wayland mechanics.

A private protocol is added in order to help out clients do things they
cannot do by themself. The protocol currently only consists of a request
meant to be used for getting a callback when the actor of a given
surface is eventually destroyed. This is different from the wl_surface
being destroyed due to window destroy animations taking an arbitrary
amount of time. It'll be used by the first test added in the next
commit.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/961
2020-01-10 16:01:22 +00:00
Jonas Ådahl
f0df07cba3 wayland/surface: Move shaped-texture synchronization to actor surface
As with most other state that ends up being pushed to the actor and the
associated shaped texture, also push the texture and the corresponding
metadata from the actor surface. This fixes an issue when a toplevel
surface was reset, where before the subsurface content was not properly
re-initialized, as content state synchronization only happened on
commit, not when asked to synchronize.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/961
2020-01-10 16:01:22 +00:00
Jonas Ådahl
fe7bece31e wayland/surface-actor: Reset and sync subsurface state when resetting
A actor surface may be reset by an xdg_toplevel if a NULL buffer is
attached. This should reset the actor state of the toplevel to an empty
state, while unmapping the previous actor. Subsurfaces, however, should
stay intact, including their relationship to the toplevel. They should
also not be yanked away from the actor of the actor surface prior to it
resetting, so that a window-destroy animation can include the subsurface
actor.

This fixes a potential crash when a subsurface tries to commit to its
wl_surface after the destroy animation of the toplevel has finished, as
the actor would at that point have been destroyed and cleared from the
actor surface struct, causing a segmentation fault.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/961
2020-01-10 16:01:22 +00:00
Jonas Ådahl
3969285e5c shaped-texture: Make setting the same texture a no-op
Will be helpful when pushing state to the shaped texture, letting the
one pushing not have to care about checking if anything changed.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/961
2020-01-10 16:01:22 +00:00
Jonas Ådahl
60ebf19c9e shaped-texture: Minor clean up
Use cogl_clear_object(), add reference to texture when setting, and
remove redundant runtime type check.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/961
2020-01-10 16:01:22 +00:00
Jonas Ådahl
fcfe90aa9f wayland: Replace manual GNode subsurface iteration with macro
Similar to wl_list_foreach(), add
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE() that iterates over all the
subsurfaces of a surface, without the caller needing to care about
implementation details, such as leaf nodes vs non-leaf nodes.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/961
2020-01-10 16:01:21 +00:00
Jonas Ådahl
76ee026caa wayland/egl-stream: Cache texture snippet
While it's not very relevant now, as we would rarely create it anyway
since the buffer nor texture never changes for a surface, it will be in
the future, as the actor state (including its content,
MetaShapedTexture) will be synchronized by the MetaWaylandActorSurface
at a later point in time, and not by MetaWaylandSurface, at state
application time.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/961
2020-01-10 16:01:21 +00:00
Jonas Ådahl
6e5ac0b585 Use G_GNUC_FALLTHROUGH instead of comments
Get the same task done in a bit more C:y way.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/998
2020-01-09 17:58:29 +01:00
Björn Daase
17e20619ec gitlab: Add issue templates
This adds two GitLab issue templates for:
* Bugs
* Features

It is the equivalent to dd2e560255.

https://gitlab.gnome.org/GNOME/mutter/issues/385
2020-01-08 19:34:19 +00:00
Jonas Dreßler
c4fa30ac7d backends/native: Fix relative motion calculation if monitor isn't found
The method `relative_motion_across_outputs` is used to adjust the
distance/delta of a mouse movement across multiple monitors to take the
different scale factors of those monitors into account. This works by
getting the adjacent monitors that the movement-line/vector intersects
with and adjusting the final position (or end point of the
movement-line) by multiplying the parts of the line spanning across
different monitors with the scale factors of those monitors.

In the end of this calculation, we always want to set the new end
coordinates of the relative motion to the new end coordinates of the
adjusted movement-line. We currently only do that if all adjacent
monitors the line is crossing actually exist, because only then we end
up inside the "We reached the dest logical monitor" else-block and set
`x` and `y` to the correct values. Fix that and make sure the returned
values are also correct in case an adjacent monitor doesn't exist by
adding separate `target_x` and `target_y` variables which we update during
each pass of the while loop so we're always prepared for the while loop
exiting before the destination monitor was found.

Thanks to Axel Kittenberger for reporting the initial bug and tracking
the issue down to `relative_motion_across_outputs`.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/774
2020-01-07 20:18:46 +00:00
Georges Basile Stavracas Neto
84ea4ad990 clutter/brightness-contrast-effect: Compare float with G_APPROX_VALUE
Nobody should ever compare float for equality. Use G_APPROX_VALUE to
check that.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/992
2020-01-07 14:20:21 -03:00
Georges Basile Stavracas Neto
64685f4b20 clutter/offscreen-effect: Clear offscreen when pre-paint fails
Some ClutterOffscreenEffect subclasses, such as ClutterBrightnessContrastEffect,
early-return FALSE in pre-paint before chaining up. It's an important optimization
that avoids creating or updating the offscreen framebuffer.

However, if an offscreen framebuffer already exists by the time pre-paint fails,
it will be used *without* repaint the actor over it. That causes an old picture
of the actor to be displayed.

Fix that by always clearing the offscreen framebuffer when pre-paint fails.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/810

https://gitlab.gnome.org/GNOME/mutter/merge_requests/992
2020-01-07 14:20:21 -03:00
Georges Basile Stavracas Neto
bf594e9fb6 clutter/offscreen-effect: Clear offscreen framebuffer when disabling
When changing the 'enabled' property and disabling the offscreen effect,
it doesn't make sense to preserve the offscreen framebuffer. It's not
drawing, after all.

Furthermore, because ClutterOffscreenEffect only checks if the offscreen
framebuffer exists to decide whether or not to redraw, keeping the fbo
alive is a waste of resources.

Clear the offscreen framebuffer when the effect is disabled or enabled.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/810

https://gitlab.gnome.org/GNOME/mutter/merge_requests/992
2020-01-07 14:19:33 -03:00
Georges Basile Stavracas Neto
3958e75ed2 clutter/offscreen-effect: Use g_clear_pointer for cleanup
It does the exact same checks, and saves us a few lines of code.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/992
2020-01-07 14:02:25 -03:00
Sebastian Keller
802309caf9 x11-selection: Plug MetaX11SelectionOutputStream leak
https://gitlab.gnome.org/GNOME/mutter/merge_requests/991
2020-01-06 19:54:00 +00:00
Sebastian Keller
468b09c01e theme: Plug GdkPixbuf leak
https://gitlab.gnome.org/GNOME/mutter/merge_requests/991
2020-01-06 19:54:00 +00:00
Sebastian Keller
c13ea4f48d theme: Plug GtkIconInfo leak
https://gitlab.gnome.org/GNOME/mutter/merge_requests/991
2020-01-06 19:54:00 +00:00
Carlos Garnacho
1e7285b2bb backends: Always enable tap-to-click/drag on opaque Wacom tablets
Touch-wise, those are essentially giant touchpads, but have no buttons
associated to the "touchpad" device (There may be pad buttons, but
those are not mouse buttons).

Without tap-to-click/drag, touch in those devices is somewhat useless
out of the box. Have them always enable these features, despite the
setting.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/968
2020-01-06 13:52:55 +00:00
Robert Mader
a8cb84c711 window-actor: Also cull out clip_region
From `meta_cullable_cull_out`:
```
Actors that may have fully opaque parts should also subtract out a region
that is fully opaque from @unobscured_region and @clip_region.
```

As we do no check for the intersection of these two elsewhere in the code,
let's substract from the clip region, too.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/985
2020-01-06 13:38:23 +00:00
541 changed files with 24742 additions and 21597 deletions

View File

@@ -28,6 +28,20 @@ build-mutter:
- merge_requests
- /^.*$/
build-without-opengl-and-glx:
stage: build
script:
- meson . build -Dbuildtype=debugoptimized -Dopengl=false -Dglx=false -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
- ninja -C build
- ninja -C build install
artifacts:
expire_in: 1 day
paths:
- build
only:
- merge_requests
- /^.*$/
build-without-native-backend-and-wayland:
stage: build
script:

View File

@@ -11,6 +11,7 @@ RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(builddep)' && \
dnf install -y 'dnf-command(copr)' && \
dnf copr enable -y fmuellner/gnome-shell-ci && \
dnf copr enable -y jadahl/mutter-ci && \
dnf -y update && dnf -y upgrade && \
dnf builddep -y mutter && \
@@ -26,4 +27,6 @@ RUN dnf -y update && dnf -y upgrade && \
dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \
dnf remove -y --noautoremove mutter mutter-devel && \
dnf upgrade -y 'pkgconfig(libpipewire-0.3)' && \
dnf clean all

View File

@@ -19,7 +19,7 @@ fi
function commit_message_has_url() {
commit=$1
commit_message=$(git show -s --format='format:%b' $commit)
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(-/\)\?\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
return $?
}

View File

@@ -0,0 +1,55 @@
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Affected version
<!--
Provide at least the following information:
* Your OS and version
* Affected Mutter version
* Does this issue appear in XOrg and/or Wayland
-->
### Bug summary
<!--
Provide a short summary of the bug you encountered.
-->
### Steps to reproduce
<!--
1. Step one
2. Step two
3. ...
-->
### What happened
<!--
What did Mutter do that was unexpected?
-->
### What did you expect to happen
<!--
What did you expect Mutter to do?
-->
### Relevant logs, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation, logs,
screenshots or screencasts related, please provide them here.
If the bug is a crash, please obtain a stack trace with installed debug
symbols (at least for GNOME Shell and Mutter) and attach it to
this issue following the instructions on
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces.
-->
<!-- Do not remove the following line. -->
/label ~"1. Bug"

View File

@@ -0,0 +1,30 @@
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Feature summary
<!--
Describe what you would like to be able to do with Mutter
that you currently cannot do.
-->
### How would you like it to work
<!--
If you can think of a way Mutter might be able to do this,
let us know here.
-->
### Relevant links, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation,
code, mockups or a similar feature in another window managers,
please provide them here.
-->
<!-- Do not remove the following line. -->
/label ~"1. Feature"

208
NEWS
View File

@@ -1,3 +1,211 @@
3.36.4
======
* Fix crash on area screenshots with fractional scaling [Sebastian; !1320]
* Do not paint textures of fully obscured windows [Robert; !1326]
* Turn off CRTCs as well when enabling DPMS [Michel; !1240]
* Improve selection support
[Robert, Carlos, Sebastian; !1330, !1193, !1253, !1255, !1293, !1350]
* Use a more appropriate combine function on opaque areas [Daniel; !1331]
* Fix remote desktop being broken without screencast session [Olivier; #1307]
* Fix popovers disappearing on wayland and HiDPI [Robert; #1312]
* Fixed crashes [Jonas Å.; !1317]
* Plugged memory leaks [Jonas Å.; !1283]
* Misc. bug fixes and cleanups
[Corentin, Sebastian, Jonas Å., Jonas D.; !1314, !1321, !1295, !1333]
Contributors:
Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho,
Sebastian Keller, Robert Mader, Corentin Noël, Daniel van Vugt, Jonas Ådahl
3.36.3
======
* Broadcast clipboard/primary offers [Carlos; !1262]
* Fix monitor screen cast on X11 [Jonas Å.; !1251]
* Implement touch-mode detecation for the X11 backend [Carlos; !1278]
* Drop external keyboard detection from touch-mode heuristics [Carlos; !1277]
* Fix leaked DMA buffers in screencasts [Jonas; !1283]
* Fixed crashes [Daniel, Carlos, Jonas D.; !1256, !1258, !1280]
Contributors:
Carlos Garnacho, Daniel van Vugt, Jonas Ådahl
3.36.2
======
* Sync timelines to hardware vsync [Daniel; !724]
* Fix screencasting non-maximized windows [Jonas; !1174]
* Make window-aliveness checks less aggressive [Jonas; !1182]
* Fix stylus coordinates when using screen rotation [Jonas T.; #1118]
* Preserve keyboard state on VT switch [Olivier; !1185]
* Fix trackball button scrolling [Phillip; #1120]
* Fix tiled monitor support [Jonas Å.; !1199]
* Fix various clipboard issues [Carlos; !1198, !1203, !1204, !1186, !1206]
* Synchronize shadows to server-side decorations [Olivier; !1214]
* Fix overview key on X11 when using multiple keyboard layouts [Olivier; !1219]
* Fix capturing with multiple stage views [Jonas Å.; !1222]
* Fixed crashes [Jonas D., Carlos; !1173, !1183]
* Misc. bug fixes and cleanups [Andre, Georges, Simon, Christian, Carlos, Marco,
Pekka, Laurent, Jonas D.; !1169, !1170, !1172, !1168, !1184, !1200, !1209,
#1074, !1208]
Contributors:
Marco Trevisan (Treviño), Laurent Bigonville, Jonas Dreßler, Olivier Fourdan,
Carlos Garnacho, Andre Moreira Magalhaes, Simon McVittie,
Georges Basile Stavracas Neto, Pekka Paalanen, Christian Rauch, Jonas Troeger,
Daniel van Vugt, Phillip Wood, Jonas Ådahl
Translators:
Dušan Kazik [sk], Christian Kirbach [de]
3.36.1
======
* Fix hardware cursor on GPU hotplpug [Pekka; !1097]
* Fix black areas around XWayland windows when resizing [Robert, Olivier; !1091]
* Fix applying wrong scale to monitors on X11 [Jonas; !1118]
* Fix moving/resizing windows via keyboard on wayland [Alynx; !997]
* Fix locate-pointer feature interfering with keybindings [Carlos; !1014]
* Add support for middle-click emulation [Andrew; !256]
* Fix freeze when moving cursor between scaled monitors [Robert; !1125]
* Fix popup misplacement with focus-follows-mouse [Jonas Å.; !1122]
* Fix misplaced cursor in preedit strings [Carlos; !1132]
* Support mirroring with proprietary Nvidia driver [Jonas Å.; !1098]
* Support tablets with multiple mode switch buttons in a group [Carlos; !970]
* Ignore foreground color for color glyphs (emojis) [Carlos; !1148]
* Allow pad mode switches while showing OSD [Carlos; !975]
* Fix positioning of OSD for display-attached tablets [Carlos; !971]
* Respect configured RANDR panning on X11 [Jonas Å.; !1085]
* Use correct texture filtering with scaled displays [Jonas; !1124]
* Fix cursor hotspots in virtual machines [Jonas Å.; !1136]
* Fix build with GLES and no GL [Georges; !1151]
* Work around Firefox bug when copying images on wayland [Robert; !1141]
* Fix wrong cursor rotation on rotated displays [Hans; !1153]
* Fix glitches in window screencasts [Georges; !1129]
* Fix IM support for deleting surrounding text [Takao, Carlos; #539]
* Fix map animation of maximized windows [Robert; !1164]
* Fixed crashes [Jonas Å., Carlos, Florian, Robert; !1120, !1121,
#917, #1132, #1083, !1147, #1147]
* Misc. bug fixes and cleanups [Jonas Å., Olivier, Mart, Sebastian, Corentin,
Andre, Daniel, Robert, Carlos, Peter, Georges, Jonas D., Florian, Christian;
!1115, !1102, !1104, !1106, !1117, !1119, !1101, !1123, #1124, !1130, !1131,
!1133, #1065, !1108, !1144, !1145, !1109, !1059, !1107, !999, !1152, #1128,
!1155, !1156, !1158, !1157, #1146, !1161, !1163]
Contributors:
Jonas Dreßler, Olivier Fourdan, Takao Fujiwara, Carlos Garnacho, Andrew Gaul,
Hans de Goede, Peter Hutterer, Sebastian Keller, Robert Mader,
Andre Moreira Magalhaes, Florian Müllner, Georges Basile Stavracas Neto,
Corentin Noël, Pekka Paalanen, Christian Rauch, Mart Raudsepp,
Daniel van Vugt, Alynx Zhou, Jonas Ådahl
Translators:
Марко Костић [sr], Daniel Șerbănescu [ro]
3.36.0
======
* Fix placement of popup windows in multi-monitor setups [Jonas; !1110]
* Fix invisible mouse cursor on some hardware [Jonas; !1079]
Contributors:
Jonas Ådahl
Translators:
Aurimas Černius [lt], Goran Vidović [hr], Anders Jonsson [sv],
Guillaume Bernard [fr], Milo Casagrande [it], Daniel Korostil [uk],
Andre Klapper [cy], Aman Alam [pa], Nathan Follens [nl]
3.35.92
=======
* Fix visibility of initially hidden windows [Jonas Å.; !1066]
* Avoid flicker when (un)redirecting windows [Sebastian; #997]
* Let BindConstraints update the preferred size [Emmanuele; !1070]
* Learn about GLES3 [Adam; !882]
* Ping windows on every window focus [Jonas D.; !891]
* Remove overhead from hot code paths [Christian;
#1056, !1081, !1083, !1071, !1087]
* Allow remote desktop services to inhibit animations [Jonas Å.; !838]
* Update screen-cast code to PipeWire 0.3 API [Wim; !1062]
* Make check-alive timeouts configurable [Jonas Å.; !1080]
* Make each stage view correspond to a single CRTC [Jonas Å.; !1042]
* Implement scaled/transformed hardware cursors [Robert; !526]
* Use DMA buffers for screencasting if possible [Georges; !1086]
* Make Xwayland startup asynchronous [Carlos; !944]
* Fix clipping glitches in long text entries [Jonas D.; !1096]
* Add side channel for starting required X11 services [Carlos; !945]
* Support synchronized wayland popup moving [Jonas Å.; !705]
* Fixed crashes [Olivier, Jonas Å.; !1073, !1093]
* Plugged memory leaks [Sebastian, Jonas Å.; !1089, !1095]
* Misc. bug fixes and cleanups [Jonas Å, Olivier, Florian, Daniel, Jonas D.,
Robert, Sebastian, Christian, Arun, Carlos, worldofpeace; !1061, #1043,
!1067, !1068, !1065, !835, !1058, !1069, !1075, #1060, !1077, !423, !1090,
!1088, !1094, #1067, !1064, !1099, !957, !1000, !1082]
Contributors:
Emmanuele Bassi, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho,
Christian Hergert, Adam Jackson, Sebastian Keller, Robert Mader,
Florian Müllner, Georges Basile Stavracas Neto, Arun Raghavan, Wim Taymans,
Daniel van Vugt, worldofpeace, Jonas Ådahl
Translators:
Yi-Jyun Pan [zh_TW], Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR],
Emin Tufan Çetin [tr], Daniel Mustieles [es], Balázs Úr [hu],
Gwan-gyeong Mun [ko], Marek Černocký [cs], Fran Dieguez [gl],
Kukuh Syafaat [id], Alan Mortensen [da], Piotr Drąg [pl], sicklylife [ja],
Matej Urbančič [sl]
3.35.91
=======
* Honor accelerometer orientation on monitor config changes [Hans; !959]
* Enable culling for integer-scaled actors [Robert; !1036]
* Add ClutterSeat::touch-mode property [Carlos; !1044]
* Fix mis-scaling when streaming windows [Olivier; !1022]
* Make the cursor renderer use the transactional KMS API [Jonas; !930]
* Advertise MetaMonitor as wl_output [Olivier; !994]
* Fix culling of XWayland windows [Robert; !1049]
* Only consider enabled effects when disabling culling [Robert; !1052]
* Misc. bug fixes and cleanups [Olivier, Sergio, Adam, Carlos, Björn; !1040,
#985, !1024, !1039, !1051]
Contributors:
Sergio Costas, Björn Daase, Olivier Fourdan, Carlos Garnacho, Hans de Goede,
Adam Jackson, Robert Mader, Jonas Ådahl
Translators:
sicklylife [ja]
3.35.90
=======
* Cull out clip region [Robert; !985]
* Always enable tap-to-click/drag on opaque Wacom tablets [Carlos; !968]
* Fix visual glitches with offscreen effects applied [Georges; !992]
* Fix "sticky corner" in multi-head setups [Jonas D.; #774]
* Fix black shadows around XWayland windows during resizes [Ray, Olivier; #858]
* Zero-copy path for GPU-less secondary GPUs [Pekka; !810]
* Cancel DND on Esc [Carlos; #1020]
* Sync XWayland window shadows to frame during resizes [Olivier; !1009]
* Add support for per-monitor workareas [Alberts; !370]
* Ensure newly mapped wayland windows receive ENTER event [Olivier; !1026]
* Add ClutterSeat object [Carlos; !852]
* Honour CLUTTER_ACTOR_NO_LAYOUT flag more efficiently [Daniel; !575]
* Fix interoperation with wl_data_device_manager v1 [Carlos; #965]
* Favor text over images in clipboard manager [Carlos; #919]
* Apply monitor scale after background texture creation [Daniel; !1004]
* Plugged memory leaks [Sebastian, Adam; !991, #1000, !1011, !1020, !1030,
!1001, !1033]
* Fixed crashes [Jonas Å., Florian, Olivier; !961, #1029, !1037]
* Misc. bug fixes and cleanups [Björn, Jonas Å., Adam, Sebastian, Jonas D.,
Daniel, Carlos, Corentin, Sebastian, Robert, Daniel; #385, !998, !1007, !995,
!1016, !1018, !1017, !1005, !1019, !1025, !1028, !1029, !1031, !1015, !1032,
!1034, #1025]
Contributors:
Björn Daase, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, Adam Jackson,
Sebastian Keller, Robert Mader, Alberts Muktupāvels, Florian Müllner,
Georges Basile Stavracas Neto, Corentin Noël, Pekka Paalanen, Ray Strode,
Daniel van Vugt, Jonas Ådahl
Translators:
sicklylife [ja], Umarzuki Bin Mochlis Moktar [ms]
3.35.3
======
* backends/native: Correct dy value in pinch gesture event [Yariv; !974]

View File

@@ -600,10 +600,11 @@ cally_actor_real_remove_actor (ClutterActor *container,
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
atk_parent = ATK_OBJECT (data);
atk_child = clutter_actor_get_accessible (actor);
if (atk_child)
if (clutter_actor_has_accessible (actor))
{
atk_child = clutter_actor_get_accessible (actor);
g_value_init (&values.old_value, G_TYPE_POINTER);
g_value_set_pointer (&values.old_value, atk_parent);

View File

@@ -631,7 +631,7 @@
#include "clutter-color-static.h"
#include "clutter-color.h"
#include "clutter-constraint-private.h"
#include "clutter-container.h"
#include "clutter-container-private.h"
#include "clutter-content-private.h"
#include "clutter-debug.h"
#include "clutter-easing.h"
@@ -710,6 +710,7 @@ struct _ClutterActorPrivate
guint8 opacity;
gint opacity_override;
unsigned int inhibit_culling_counter;
ClutterOffscreenRedirect offscreen_redirect;
@@ -1124,6 +1125,20 @@ static GQuark quark_actor_layout_info = 0;
static GQuark quark_actor_transform_info = 0;
static GQuark quark_actor_animation_info = 0;
static GQuark quark_key = 0;
static GQuark quark_motion = 0;
static GQuark quark_pointer_focus = 0;
static GQuark quark_button = 0;
static GQuark quark_scroll = 0;
static GQuark quark_stage = 0;
static GQuark quark_destroy = 0;
static GQuark quark_client = 0;
static GQuark quark_delete = 0;
static GQuark quark_touch = 0;
static GQuark quark_touchpad = 0;
static GQuark quark_proximity = 0;
static GQuark quark_pad = 0;
G_DEFINE_TYPE_WITH_CODE (ClutterActor,
clutter_actor,
G_TYPE_INITIALLY_UNOWNED,
@@ -1778,6 +1793,15 @@ clutter_actor_unmap (ClutterActor *self)
clutter_actor_update_map_state (self, MAP_STATE_MAKE_UNMAPPED);
}
static void
clutter_actor_queue_shallow_relayout (ClutterActor *self)
{
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
if (stage != NULL)
clutter_stage_queue_actor_relayout (CLUTTER_STAGE (stage), self);
}
static void
clutter_actor_real_show (ClutterActor *self)
{
@@ -1811,6 +1835,11 @@ clutter_actor_real_show (ClutterActor *self)
clutter_actor_queue_relayout (self);
}
else /* but still don't leave the actor un-allocated before showing it */
{
clutter_actor_queue_shallow_relayout (self);
clutter_actor_queue_redraw (self);
}
}
static inline void
@@ -2381,6 +2410,7 @@ clutter_actor_should_pick_paint (ClutterActor *self)
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
if (CLUTTER_ACTOR_IS_MAPPED (self) &&
clutter_actor_has_allocation (self) &&
(_clutter_context_get_pick_mode () == CLUTTER_PICK_ALL ||
CLUTTER_ACTOR_IS_REACTIVE (self)))
return TRUE;
@@ -2574,6 +2604,9 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
gboolean retval;
ClutterActorBox old_alloc = { 0, };
g_return_val_if_fail (!isnan (box->x1) && !isnan (box->x2) &&
!isnan (box->y1) && !isnan (box->y2), FALSE);
obj = G_OBJECT (self);
g_object_freeze_notify (obj);
@@ -2864,9 +2897,23 @@ clutter_actor_real_queue_relayout (ClutterActor *self)
memset (priv->height_requests, 0,
N_CACHED_SIZE_REQUESTS * sizeof (SizeRequest));
/* We need to go all the way up the hierarchy */
/* We may need to go all the way up the hierarchy */
if (priv->parent != NULL)
_clutter_actor_queue_only_relayout (priv->parent);
{
if (priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT)
{
clutter_actor_queue_shallow_relayout (self);
/* The above might have invalidated the parent's paint volume if self
* has moved or resized. DnD seems to require this...
*/
priv->parent->priv->needs_paint_volume_update = TRUE;
}
else
{
_clutter_actor_queue_only_relayout (priv->parent);
}
}
}
/**
@@ -3446,8 +3493,8 @@ _clutter_actor_draw_paint_volume_full (ClutterActor *self,
cogl_pipeline_set_color (outline, &cogl_color);
pipeline_node = clutter_pipeline_node_new (outline);
clutter_paint_node_set_name (pipeline_node,
"ClutterActor (paint volume outline)");
clutter_paint_node_set_static_name (pipeline_node,
"ClutterActor (paint volume outline)");
clutter_paint_node_add_primitive (pipeline_node, prim);
clutter_paint_node_add_child (node, pipeline_node);
cogl_object_unref (prim);
@@ -3461,8 +3508,8 @@ _clutter_actor_draw_paint_volume_full (ClutterActor *self,
pango_layout_set_text (layout, label, -1);
text_node = clutter_text_node_new (layout, color);
clutter_paint_node_set_name (text_node,
"ClutterActor (paint volume label)");
clutter_paint_node_set_static_name (text_node,
"ClutterActor (paint volume label)");
clutter_paint_node_add_rectangle (text_node,
&(ClutterActorBox) {
.x1 = pv->vertices[0].x,
@@ -3558,8 +3605,8 @@ _clutter_actor_paint_cull_result (ClutterActor *self,
pango_layout_set_text (layout, label, -1);
text_node = clutter_text_node_new (layout, &color);
clutter_paint_node_set_name (text_node,
"ClutterActor (paint volume text)");
clutter_paint_node_set_static_name (text_node,
"ClutterActor (paint volume text)");
clutter_paint_node_add_rectangle (text_node,
&(ClutterActorBox) {
.x1 = 0.f,
@@ -3715,7 +3762,13 @@ needs_flatten_effect (ClutterActor *self)
CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT))
return FALSE;
if (priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ALWAYS)
/* We need to enable the effect immediately even in ON_IDLE because that can
* only be implemented efficiently within the effect itself.
* If it was implemented here using just priv->is_dirty then we would lose
* the ability to animate opacity without repaints.
*/
if ((priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ALWAYS) ||
(priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE))
return TRUE;
else if (priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY)
{
@@ -3834,7 +3887,7 @@ clutter_actor_paint_node (ClutterActor *actor,
clear_flags = COGL_BUFFER_BIT_DEPTH;
node = clutter_root_node_new (fb, &bg_color, clear_flags);
clutter_paint_node_set_name (node, "stageClear");
clutter_paint_node_set_static_name (node, "stageClear");
clutter_paint_node_add_rectangle (node, &box);
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
@@ -3849,7 +3902,7 @@ clutter_actor_paint_node (ClutterActor *actor,
/ 255;
node = clutter_color_node_new (&bg_color);
clutter_paint_node_set_name (node, "backgroundColor");
clutter_paint_node_set_static_name (node, "backgroundColor");
clutter_paint_node_add_rectangle (node, &box);
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
@@ -3903,6 +3956,7 @@ clutter_actor_paint (ClutterActor *self,
g_autoptr (ClutterPaintNode) root_node = NULL;
ClutterActorPrivate *priv;
ClutterActorBox clip;
gboolean culling_inhibited;
gboolean clip_set = FALSE;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
@@ -3969,11 +4023,14 @@ clutter_actor_paint (ClutterActor *self,
clutter_actor_get_transform (self, &transform);
transform_node = clutter_transform_node_new (&transform);
clutter_paint_node_add_child (transform_node, root_node);
clutter_paint_node_unref (root_node);
if (!cogl_matrix_is_identity (&transform))
{
transform_node = clutter_transform_node_new (&transform);
clutter_paint_node_add_child (transform_node, root_node);
clutter_paint_node_unref (root_node);
root_node = g_steal_pointer (&transform_node);
root_node = g_steal_pointer (&transform_node);
}
#ifdef CLUTTER_ENABLE_DEBUG
/* Catch when out-of-band transforms have been made by actors not as part
@@ -4048,7 +4105,8 @@ clutter_actor_paint (ClutterActor *self,
* paint then the last-paint-volume would likely represent the new
* actor position not the old.
*/
if (!in_clone_paint ())
culling_inhibited = priv->inhibit_culling_counter > 0;
if (!culling_inhibited && !in_clone_paint ())
{
gboolean success;
/* annoyingly gcc warns if uninitialized even though
@@ -4130,7 +4188,7 @@ clutter_actor_continue_paint (ClutterActor *self,
*/
framebuffer = clutter_paint_context_get_base_framebuffer (paint_context);
dummy = _clutter_dummy_node_new (self, framebuffer);
clutter_paint_node_set_name (dummy, "Root");
clutter_paint_node_set_static_name (dummy, "Root");
/* XXX - for 1.12, we use the return value of paint_node() to
* decide whether we should emit the ::paint signal.
@@ -4139,7 +4197,9 @@ clutter_actor_continue_paint (ClutterActor *self,
clutter_paint_node_unref (dummy);
/* XXX:2.0 - Call the paint() virtual directly */
if (g_signal_has_handler_pending (self, actor_signals[PAINT],
if (!(clutter_paint_context_get_paint_flags (paint_context) &
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL) &&
g_signal_has_handler_pending (self, actor_signals[PAINT],
0, TRUE))
g_signal_emit (self, actor_signals[PAINT], 0, paint_context);
else
@@ -4170,6 +4230,11 @@ clutter_actor_continue_paint (ClutterActor *self,
run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY;
}
if (priv->current_effect == priv->flatten_effect &&
priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE &&
run_flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY)
run_flags |= CLUTTER_EFFECT_PAINT_BYPASS_EFFECT;
_clutter_effect_paint (priv->current_effect, paint_context, run_flags);
priv->current_effect = old_current_effect;
@@ -4540,7 +4605,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
/* we need to emit the signal before dropping the reference */
if (emit_actor_removed)
g_signal_emit_by_name (self, "actor-removed", child);
_clutter_container_emit_actor_removed (CLUTTER_CONTAINER (self), child);
if (notify_first_last)
{
@@ -6503,6 +6568,20 @@ clutter_actor_class_init (ClutterActorClass *klass)
quark_actor_transform_info = g_quark_from_static_string ("-clutter-actor-transform-info");
quark_actor_animation_info = g_quark_from_static_string ("-clutter-actor-animation-info");
quark_key = g_quark_from_static_string ("key");
quark_motion = g_quark_from_static_string ("motion");
quark_pointer_focus = g_quark_from_static_string ("pointer-focus");
quark_button = g_quark_from_static_string ("button");
quark_scroll = g_quark_from_static_string ("scroll");
quark_stage = g_quark_from_static_string ("stage");
quark_destroy = g_quark_from_static_string ("destroy");
quark_client = g_quark_from_static_string ("client");
quark_delete = g_quark_from_static_string ("delete");
quark_touch = g_quark_from_static_string ("touch");
quark_touchpad = g_quark_from_static_string ("touchpad");
quark_proximity = g_quark_from_static_string ("proximity");
quark_pad = g_quark_from_static_string ("pad");
object_class->constructor = clutter_actor_constructor;
object_class->set_property = clutter_actor_set_property;
object_class->get_property = clutter_actor_get_property;
@@ -6602,7 +6681,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
g_param_spec_float ("width",
P_("Width"),
P_("Width of the actor"),
0.0, G_MAXFLOAT,
-1.0f, G_MAXFLOAT,
0.0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
@@ -6621,7 +6700,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
g_param_spec_float ("height",
P_("Height"),
P_("Height of the actor"),
0.0, G_MAXFLOAT,
-1.0f, G_MAXFLOAT,
0.0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
@@ -8538,7 +8617,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
actor_signals[CAPTURED_EVENT] =
g_signal_new (I_("captured-event"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
G_STRUCT_OFFSET (ClutterActorClass, captured_event),
_clutter_boolean_handled_accumulator, NULL,
_clutter_marshal_BOOLEAN__BOXED,
@@ -9725,6 +9804,23 @@ clutter_actor_get_preferred_width (ClutterActor *self,
return;
}
/* if the request mode is CONTENT_SIZE we simply return the content width */
if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE)
{
float content_width = 0.f;
if (priv->content != NULL)
clutter_content_get_preferred_size (priv->content, &content_width, NULL);
if (min_width_p != NULL)
*min_width_p = content_width;
if (natural_width_p != NULL)
*natural_width_p = content_width;
return;
}
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_WIDTH);
/* the remaining cases are:
@@ -9873,6 +9969,23 @@ clutter_actor_get_preferred_height (ClutterActor *self,
return;
}
/* if the request mode is CONTENT_SIZE we simply return the content height */
if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE)
{
float content_height = 0.f;
if (priv->content != NULL)
clutter_content_get_preferred_size (priv->content, NULL, &content_height);
if (min_height_p != NULL)
*min_height_p = content_height;
if (natural_height_p != NULL)
*natural_height_p = content_height;
return;
}
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_HEIGHT);
/* the remaining cases are:
@@ -10256,6 +10369,11 @@ clutter_actor_allocate (ClutterActor *self,
old_allocation = priv->allocation;
real_allocation = *box;
g_return_if_fail (!isnan (real_allocation.x1) &&
!isnan (real_allocation.x2) &&
!isnan (real_allocation.y1) &&
!isnan (real_allocation.y2));
/* constraints are allowed to modify the allocation only here; we do
* this prior to all the other checks so that we can bail out if the
* allocation did not change
@@ -13150,7 +13268,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
}
if (emit_actor_added)
g_signal_emit_by_name (self, "actor-added", child);
_clutter_container_emit_actor_added (CLUTTER_CONTAINER (self), child);
if (notify_first_last)
{
@@ -13814,8 +13932,70 @@ clutter_actor_event (ClutterActor *actor,
if (capture)
{
g_signal_emit (actor, actor_signals[CAPTURED_EVENT], 0,
event,
GQuark detail = 0;
switch (event->type)
{
case CLUTTER_NOTHING:
break;
case CLUTTER_KEY_PRESS:
case CLUTTER_KEY_RELEASE:
detail = quark_key;
break;
case CLUTTER_MOTION:
detail = quark_motion;
break;
case CLUTTER_ENTER:
case CLUTTER_LEAVE:
detail = quark_pointer_focus;
break;
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
detail = quark_button;
break;
case CLUTTER_SCROLL:
detail = quark_scroll;
break;
case CLUTTER_STAGE_STATE:
detail = quark_stage;
break;
case CLUTTER_DESTROY_NOTIFY:
detail = quark_destroy;
break;
case CLUTTER_CLIENT_MESSAGE:
detail = quark_client;
break;
case CLUTTER_DELETE:
detail = quark_delete;
break;
case CLUTTER_TOUCH_BEGIN:
case CLUTTER_TOUCH_UPDATE:
case CLUTTER_TOUCH_END:
case CLUTTER_TOUCH_CANCEL:
detail = quark_touch;
break;
case CLUTTER_TOUCHPAD_PINCH:
case CLUTTER_TOUCHPAD_SWIPE:
detail = quark_touchpad;
break;
case CLUTTER_PROXIMITY_IN:
case CLUTTER_PROXIMITY_OUT:
detail = quark_proximity;
break;
case CLUTTER_PAD_BUTTON_PRESS:
case CLUTTER_PAD_BUTTON_RELEASE:
case CLUTTER_PAD_STRIP:
case CLUTTER_PAD_RING:
detail = quark_pad;
break;
case CLUTTER_EVENT_LAST: /* Just keep compiler warnings quiet */
break;
}
g_signal_emit (actor,
actor_signals[CAPTURED_EVENT],
detail,
event,
&retval);
goto out;
}
@@ -15836,6 +16016,63 @@ clutter_actor_get_opacity_override (ClutterActor *self)
return self->priv->opacity_override;
}
/**
* clutter_actor_inhibit_culling:
* @actor: a #ClutterActor
*
* Increases the culling inhibitor counter. Inhibiting culling
* forces the actor to be painted even when outside the visible
* bounds of the stage view.
*
* This is usually necessary when an actor is being painted on
* another paint context.
*
* Pair with clutter_actor_uninhibit_culling() when the actor doesn't
* need to be painted anymore.
*/
void
clutter_actor_inhibit_culling (ClutterActor *actor)
{
ClutterActorPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
priv = actor->priv;
priv->inhibit_culling_counter++;
_clutter_actor_set_enable_paint_unmapped (actor, TRUE);
}
/**
* clutter_actor_uninhibit_culling:
* @actor: a #ClutterActor
*
* Decreases the culling inhibitor counter. See clutter_actor_inhibit_culling()
* for when inhibit culling is necessary.
*
* Calling this function without a matching call to
* clutter_actor_inhibit_culling() is a programming error.
*/
void
clutter_actor_uninhibit_culling (ClutterActor *actor)
{
ClutterActorPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
priv = actor->priv;
if (priv->inhibit_culling_counter == 0)
{
g_critical ("Unpaired call to clutter_actor_uninhibit_culling");
return;
}
priv->inhibit_culling_counter--;
if (priv->inhibit_culling_counter == 0)
_clutter_actor_set_enable_paint_unmapped (actor, FALSE);
}
/* Allows you to disable applying the actors model view transform during
* a paint. Used by ClutterClone. */
void
@@ -17549,10 +17786,42 @@ _clutter_actor_compute_resource_scale (ClutterActor *self,
resource_scale))
{
if (priv->parent)
return _clutter_actor_compute_resource_scale (priv->parent,
resource_scale);
{
gboolean in_clone_paint;
gboolean was_parent_in_clone_paint;
gboolean was_parent_unmapped;
gboolean was_parent_paint_unmapped;
gboolean ret;
in_clone_paint = clutter_actor_is_in_clone_paint (self);
was_parent_unmapped = !clutter_actor_is_mapped (priv->parent);
was_parent_in_clone_paint =
clutter_actor_is_in_clone_paint (priv->parent);
was_parent_paint_unmapped = priv->parent->priv->enable_paint_unmapped;
if (in_clone_paint && was_parent_unmapped)
{
_clutter_actor_set_in_clone_paint (priv->parent, TRUE);
_clutter_actor_set_enable_paint_unmapped (priv->parent, TRUE);
}
ret = _clutter_actor_compute_resource_scale (priv->parent,
resource_scale);
if (in_clone_paint && was_parent_unmapped)
{
_clutter_actor_set_in_clone_paint (priv->parent,
was_parent_in_clone_paint);
_clutter_actor_set_enable_paint_unmapped (priv->parent,
was_parent_paint_unmapped);
}
return ret;
}
else
return FALSE;
{
return FALSE;
}
}
return TRUE;
@@ -19203,8 +19472,8 @@ _clutter_actor_create_transition (ClutterActor *actor,
gboolean call_restore = FALSE;
TransitionClosure *clos;
va_list var_args;
GValue initial = G_VALUE_INIT;
GValue final = G_VALUE_INIT;
g_auto (GValue) initial = G_VALUE_INIT;
g_auto (GValue) final = G_VALUE_INIT;
GType ptype;
char *error;
@@ -19253,7 +19522,6 @@ _clutter_actor_create_transition (ClutterActor *actor,
if (error != NULL)
{
g_critical ("%s: %s", G_STRLOC, error);
g_value_unset (&initial);
g_free (error);
goto out;
}
@@ -19275,9 +19543,6 @@ _clutter_actor_create_transition (ClutterActor *actor,
&final,
pspec);
g_value_unset (&initial);
g_value_unset (&final);
goto out;
}
@@ -19325,9 +19590,6 @@ _clutter_actor_create_transition (ClutterActor *actor,
/* the actor now owns the transition */
g_object_unref (res);
g_value_unset (&initial);
g_value_unset (&final);
}
else
{
@@ -21102,7 +21364,7 @@ clutter_actor_create_texture_paint_node (ClutterActor *self,
color.alpha = clutter_actor_get_paint_opacity_internal (self);
node = clutter_texture_node_new (texture, &color, priv->min_filter, priv->mag_filter);
clutter_paint_node_set_name (node, "Texture");
clutter_paint_node_set_static_name (node, "Texture");
if (priv->content_repeat == CLUTTER_REPEAT_NONE)
clutter_paint_node_add_rectangle (node, &box);
@@ -21123,3 +21385,14 @@ clutter_actor_create_texture_paint_node (ClutterActor *self,
return node;
}
gboolean
clutter_actor_has_accessible (ClutterActor *actor)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE);
if (CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible)
return CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible (actor);
return TRUE;
}

View File

@@ -299,10 +299,11 @@ struct _ClutterActorClass
gboolean (* touch_event) (ClutterActor *self,
ClutterTouchEvent *event);
gboolean (* has_accessible) (ClutterActor *self);
/*< private >*/
/* padding for future expansion */
gpointer _padding_dummy[26];
gpointer _padding_dummy[25];
};
/**
@@ -380,6 +381,8 @@ CLUTTER_EXPORT
const gchar * clutter_actor_get_name (ClutterActor *self);
CLUTTER_EXPORT
AtkObject * clutter_actor_get_accessible (ClutterActor *self);
CLUTTER_EXPORT
gboolean clutter_actor_has_accessible (ClutterActor *self);
CLUTTER_EXPORT
gboolean clutter_actor_is_visible (ClutterActor *self);
@@ -881,6 +884,11 @@ void clutter_actor_set_opacity_override
CLUTTER_EXPORT
gint clutter_actor_get_opacity_override (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_inhibit_culling (ClutterActor *actor);
CLUTTER_EXPORT
void clutter_actor_uninhibit_culling (ClutterActor *actor);
/**
* ClutterActorCreateChildFunc:
* @item: (type GObject): the item in the model

View File

@@ -23,8 +23,7 @@
#define __CLUTTER_BACKEND_PRIVATE_H__
#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
#include <clutter/clutter-keymap.h>
#include <clutter/clutter-seat.h>
#include <clutter/clutter-stage-window.h>
#define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
@@ -47,8 +46,6 @@ struct _ClutterBackend
CoglOnscreen *dummy_onscreen;
ClutterDeviceManager *device_manager;
cairo_font_options_t *font_options;
gchar *font_name;
@@ -59,8 +56,6 @@ struct _ClutterBackend
ClutterStageWindow *stage_window;
ClutterInputMethod *input_method;
ClutterKeymap *keymap;
};
struct _ClutterBackendClass
@@ -89,17 +84,12 @@ struct _ClutterBackendClass
GError **error);
gboolean (* create_context) (ClutterBackend *backend,
GError **error);
ClutterDeviceManager *(* get_device_manager) (ClutterBackend *backend);
gboolean (* translate_event) (ClutterBackend *backend,
gpointer native,
ClutterEvent *event);
PangoDirection (* get_keymap_direction) (ClutterBackend *backend);
void (* bell_notify) (ClutterBackend *backend);
ClutterKeymap * (* get_keymap) (ClutterBackend *backend);
ClutterSeat * (* get_default_seat) (ClutterBackend *backend);
/* signals */
void (* resolution_changed) (ClutterBackend *backend);
@@ -139,8 +129,6 @@ gfloat _clutter_backend_get_units_per_em (Clutter
PangoFontDescription *font_desc);
gint32 _clutter_backend_get_units_serial (ClutterBackend *backend);
PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend);
void clutter_set_allowed_drivers (const char *drivers);
CLUTTER_EXPORT

View File

@@ -51,7 +51,6 @@
#include "clutter-stage-manager-private.h"
#include "clutter-stage-private.h"
#include "clutter-stage-window.h"
#include "clutter-device-manager-private.h"
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
#include "wayland/clutter-wayland-compositor.h"
@@ -528,30 +527,6 @@ clutter_backend_real_init_events (ClutterBackend *backend)
g_error ("Unknown input backend");
}
static ClutterDeviceManager *
clutter_backend_real_get_device_manager (ClutterBackend *backend)
{
if (G_UNLIKELY (backend->device_manager == NULL))
{
g_critical ("No device manager available, expect broken input");
return NULL;
}
return backend->device_manager;
}
static ClutterKeymap *
clutter_backend_real_get_keymap (ClutterBackend *backend)
{
if (G_UNLIKELY (backend->keymap == NULL))
{
g_critical ("No keymap available, expect broken keyboard input");
return NULL;
}
return backend->keymap;
}
static void
clutter_backend_class_init (ClutterBackendClass *klass)
{
@@ -615,10 +590,8 @@ clutter_backend_class_init (ClutterBackendClass *klass)
klass->font_changed = clutter_backend_real_font_changed;
klass->init_events = clutter_backend_real_init_events;
klass->get_device_manager = clutter_backend_real_get_device_manager;
klass->create_context = clutter_backend_real_create_context;
klass->get_features = clutter_backend_real_get_features;
klass->get_keymap = clutter_backend_real_get_keymap;
}
static void
@@ -783,24 +756,24 @@ _clutter_backend_copy_event_data (ClutterBackend *backend,
const ClutterEvent *src,
ClutterEvent *dest)
{
ClutterDeviceManagerClass *device_manager_class;
ClutterDeviceManager *device_manager;
ClutterSeatClass *seat_class;
ClutterSeat *seat;
device_manager = clutter_device_manager_get_default ();
device_manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
device_manager_class->copy_event_data (device_manager, src, dest);
seat = clutter_backend_get_default_seat (backend);
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
seat_class->copy_event_data (seat, src, dest);
}
void
_clutter_backend_free_event_data (ClutterBackend *backend,
ClutterEvent *event)
{
ClutterDeviceManagerClass *device_manager_class;
ClutterDeviceManager *device_manager;
ClutterSeatClass *seat_class;
ClutterSeat *seat;
device_manager = clutter_device_manager_get_default ();
device_manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
device_manager_class->free_event_data (device_manager, event);
seat = clutter_backend_get_default_seat (backend);
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
seat_class->free_event_data (seat, event);
}
/**
@@ -997,18 +970,6 @@ clutter_wayland_set_compositor_display (void *display)
}
#endif
PangoDirection
_clutter_backend_get_keymap_direction (ClutterBackend *backend)
{
ClutterBackendClass *klass;
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->get_keymap_direction != NULL)
return klass->get_keymap_direction (backend);
return PANGO_DIRECTION_NEUTRAL;
}
void
clutter_set_allowed_drivers (const char *drivers)
{
@@ -1021,16 +982,6 @@ clutter_set_allowed_drivers (const char *drivers)
allowed_drivers = g_strdup (drivers);
}
void
clutter_backend_bell_notify (ClutterBackend *backend)
{
ClutterBackendClass *klass;
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->bell_notify)
klass->bell_notify (backend);
}
/**
* clutter_backend_get_input_method:
* @backend: the #CLutterBackend
@@ -1059,22 +1010,24 @@ clutter_backend_set_input_method (ClutterBackend *backend,
g_set_object (&backend->input_method, method);
}
/**
* clutter_backend_get_keymap:
* @backend: the #ClutterBackend
*
* Gets the keymap used by Clutter
*
* Returns: (transfer none): the keymap
**/
ClutterKeymap *
clutter_backend_get_keymap (ClutterBackend *backend)
{
return CLUTTER_BACKEND_GET_CLASS (backend)->get_keymap (backend);
}
ClutterStageWindow *
clutter_backend_get_stage_window (ClutterBackend *backend)
{
return backend->stage_window;
}
/**
* clutter_backend_get_default_seat:
* @backend: the #ClutterBackend
*
* Returns the default seat
*
* Returns: (transfer none): the default seat
**/
ClutterSeat *
clutter_backend_get_default_seat (ClutterBackend *backend)
{
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL);
return CLUTTER_BACKEND_GET_CLASS (backend)->get_default_seat (backend);
}

View File

@@ -36,6 +36,7 @@
#include <clutter/clutter-config.h>
#include <clutter/clutter-keymap.h>
#include <clutter/clutter-types.h>
#include <clutter/clutter-seat.h>
G_BEGIN_DECLS
@@ -72,9 +73,6 @@ const cairo_font_options_t * clutter_backend_get_font_options (Clutter
CLUTTER_EXPORT
CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend);
CLUTTER_EXPORT
void clutter_backend_bell_notify (ClutterBackend *backend);
CLUTTER_EXPORT
ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend);
@@ -82,7 +80,7 @@ CLUTTER_EXPORT
void clutter_backend_set_input_method (ClutterBackend *backend,
ClutterInputMethod *method);
CLUTTER_EXPORT
ClutterKeymap * clutter_backend_get_keymap (ClutterBackend *backend);
ClutterSeat * clutter_backend_get_default_seat (ClutterBackend *backend);
G_END_DECLS

View File

@@ -144,6 +144,55 @@ source_destroyed (ClutterActor *actor,
bind->source = NULL;
}
static void
clutter_bind_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterOrientation direction,
float for_size,
float *minimum_size,
float *natural_size)
{
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
float source_min, source_nat;
if (bind->source == NULL)
return;
/* only these bindings affect the preferred size */
if (!(bind->coordinate == CLUTTER_BIND_WIDTH ||
bind->coordinate == CLUTTER_BIND_HEIGHT ||
bind->coordinate == CLUTTER_BIND_SIZE ||
bind->coordinate == CLUTTER_BIND_ALL))
return;
switch (direction)
{
case CLUTTER_ORIENTATION_HORIZONTAL:
if (bind->coordinate != CLUTTER_BIND_HEIGHT)
{
clutter_actor_get_preferred_width (bind->source, for_size,
&source_min,
&source_nat);
*minimum_size = source_min;
*natural_size = source_nat;
}
break;
case CLUTTER_ORIENTATION_VERTICAL:
if (bind->coordinate != CLUTTER_BIND_WIDTH)
{
clutter_actor_get_preferred_height (bind->source, for_size,
&source_min,
&source_nat);
*minimum_size = source_min;
*natural_size = source_nat;
}
break;
}
}
static void
clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
ClutterActor *actor,
@@ -328,6 +377,8 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
meta_class->set_actor = clutter_bind_constraint_set_actor;
constraint_class->update_allocation = clutter_bind_constraint_update_allocation;
constraint_class->update_preferred_size = clutter_bind_constraint_update_preferred_size;
/**
* ClutterBindConstraint:source:
*

View File

@@ -475,8 +475,10 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
ClutterActor *child;
gint n_children = 0;
gfloat minimum, natural;
float largest_min_size, largest_nat_size;
minimum = natural = 0;
largest_min_size = largest_nat_size = 0;
clutter_actor_iter_init (&iter, container);
while (clutter_actor_iter_next (&iter, &child))
@@ -491,8 +493,22 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
get_child_size (child, priv->orientation,
for_size, &child_min, &child_nat);
minimum += child_min;
natural += child_nat;
if (priv->is_homogeneous)
{
largest_min_size = MAX (largest_min_size, child_min);
largest_nat_size = MAX (largest_nat_size, child_nat);
}
else
{
minimum += child_min;
natural += child_nat;
}
}
if (priv->is_homogeneous)
{
minimum = largest_min_size * n_children;
natural = largest_nat_size * n_children;
}
if (n_children > 1)
@@ -623,6 +639,8 @@ get_preferred_size_for_opposite_orientation (ClutterBoxLayout *self,
}
else
{
size -= (nvis_children - 1) * priv->spacing;
/* Bring children up to size first */
if (isnormal (size) || size == 0)
{

View File

@@ -121,12 +121,12 @@ G_DEFINE_TYPE (ClutterBrightnessContrastEffect,
static gboolean
will_have_no_effect (ClutterBrightnessContrastEffect *self)
{
return (self->brightness_red == no_change &&
self->brightness_green == no_change &&
self->brightness_blue == no_change &&
self->contrast_red == no_change &&
self->contrast_green == no_change &&
self->contrast_blue == no_change);
return (G_APPROX_VALUE (self->brightness_red, no_change, FLT_EPSILON) &&
G_APPROX_VALUE (self->brightness_green, no_change, FLT_EPSILON) &&
G_APPROX_VALUE (self->brightness_blue, no_change, FLT_EPSILON) &&
G_APPROX_VALUE (self->contrast_red, no_change, FLT_EPSILON) &&
G_APPROX_VALUE (self->contrast_green, no_change, FLT_EPSILON) &&
G_APPROX_VALUE (self->contrast_blue, no_change, FLT_EPSILON));
}
static gboolean
@@ -497,9 +497,9 @@ clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContras
{
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (red == effect->brightness_red &&
green == effect->brightness_green &&
blue == effect->brightness_blue)
if (G_APPROX_VALUE (red, effect->brightness_red, FLT_EPSILON) &&
G_APPROX_VALUE (green, effect->brightness_green, FLT_EPSILON) &&
G_APPROX_VALUE (blue, effect->brightness_blue, FLT_EPSILON))
return;
effect->brightness_red = red;
@@ -587,9 +587,9 @@ clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastE
{
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (red == effect->contrast_red &&
green == effect->contrast_green &&
blue == effect->contrast_blue)
if (G_APPROX_VALUE (red, effect->contrast_red, FLT_EPSILON) &&
G_APPROX_VALUE (green, effect->contrast_green, FLT_EPSILON) &&
G_APPROX_VALUE (blue, effect->contrast_blue, FLT_EPSILON))
return;
effect->contrast_red = red;

View File

@@ -352,7 +352,7 @@ clutter_canvas_paint_content (ClutterContent *content,
return;
node = clutter_actor_create_texture_paint_node (actor, priv->texture);
clutter_paint_node_set_name (node, "Canvas Content");
clutter_paint_node_set_static_name (node, "Canvas Content");
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);

View File

@@ -346,6 +346,12 @@ on_captured_event (ClutterActor *stage,
ClutterModifierType modifier_state;
gboolean has_button = TRUE;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
{
clutter_click_action_release (action);
return CLUTTER_EVENT_PROPAGATE;
}
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
switch (clutter_event_type (event))

View File

@@ -30,13 +30,6 @@ gboolean clutter_constraint_update_allocation (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterActorBox *allocation);
void clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterOrientation direction,
float for_size,
float *minimum_size,
float *natural_size);
G_END_DECLS
#endif /* __CLUTTER_CONSTRAINT_PRIVATE_H__ */

View File

@@ -222,6 +222,17 @@ clutter_constraint_update_allocation (ClutterConstraint *constraint,
return !clutter_actor_box_equal (allocation, &old_alloc);
}
/**
* clutter_constraint_update_preferred_size:
* @constraint: a #ClutterConstraint
* @actor: a #ClutterActor
* @direction: a #ClutterOrientation
* @for_size: the size in the opposite direction
* @minimum_size: (inout): the minimum size to modify
* @natural_size: (inout): the natural size to modify
*
* Asks the @constraint to update the size request of a #ClutterActor.
*/
void
clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor,

View File

@@ -99,6 +99,14 @@ struct _ClutterConstraintClass
CLUTTER_EXPORT
GType clutter_constraint_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
void clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterOrientation direction,
float for_size,
float *minimum_size,
float *natural_size);
/* ClutterActor API */
CLUTTER_EXPORT
void clutter_actor_add_constraint (ClutterActor *self,

View File

@@ -0,0 +1,36 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* 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 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLUTTER_CONTAINER_PRIVATE_H__
#define __CLUTTER_CONTAINER_PRIVATE_H__
#include <clutter/clutter-container.h>
G_BEGIN_DECLS
void _clutter_container_emit_actor_added (ClutterContainer *container,
ClutterActor *actor);
void _clutter_container_emit_actor_removed (ClutterContainer *container,
ClutterActor *actor);
G_END_DECLS
#endif /* __CLUTTER_CONTAINER_PRIVATE_H__ */

View File

@@ -37,6 +37,7 @@
#include "clutter-actor-private.h"
#include "clutter-child-meta.h"
#include "clutter-container-private.h"
#include "clutter-debug.h"
#include "clutter-main.h"
#include "clutter-marshal.h"
@@ -1250,3 +1251,23 @@ clutter_container_child_notify (ClutterContainer *container,
child,
pspec);
}
void
_clutter_container_emit_actor_added (ClutterContainer *container,
ClutterActor *actor)
{
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_signal_emit (container, container_signals[ACTOR_ADDED], 0, actor);
}
void
_clutter_container_emit_actor_removed (ClutterContainer *container,
ClutterActor *actor)
{
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_signal_emit (container, container_signals[ACTOR_REMOVED], 0, actor);
}

View File

@@ -1,306 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_DEVICE_MANAGER_PRIVATE_H__
#define __CLUTTER_DEVICE_MANAGER_PRIVATE_H__
#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
#include <clutter/clutter-event.h>
G_BEGIN_DECLS
typedef struct _ClutterAxisInfo
{
ClutterInputAxis axis;
gdouble min_axis;
gdouble max_axis;
gdouble min_value;
gdouble max_value;
gdouble resolution;
} ClutterAxisInfo;
typedef struct _ClutterKeyInfo
{
guint keyval;
ClutterModifierType modifiers;
} ClutterKeyInfo;
typedef struct _ClutterScrollInfo
{
guint axis_id;
ClutterScrollDirection direction;
gdouble increment;
gdouble last_value;
guint last_value_valid : 1;
} ClutterScrollInfo;
typedef struct _ClutterTouchInfo
{
ClutterEventSequence *sequence;
ClutterActor *actor;
gfloat current_x;
gfloat current_y;
} ClutterTouchInfo;
typedef struct _ClutterPtrA11yData
{
int n_btn_pressed;
float current_x;
float current_y;
float dwell_x;
float dwell_y;
gboolean dwell_drag_started;
gboolean dwell_gesture_started;
guint dwell_timer;
guint dwell_position_timer;
guint secondary_click_timer;
gboolean secondary_click_triggered;
} ClutterPtrA11yData;
struct _ClutterInputDevice
{
GObject parent_instance;
gint id;
ClutterInputDeviceType device_type;
ClutterInputMode device_mode;
gchar *device_name;
ClutterDeviceManager *device_manager;
ClutterBackend *backend;
/* the associated device */
ClutterInputDevice *associated;
GList *slaves;
/* the actor underneath the pointer */
ClutterActor *cursor_actor;
GHashTable *inv_touch_sequence_actors;
/* the actor that has a grab in place for the device */
ClutterActor *pointer_grab_actor;
ClutterActor *keyboard_grab_actor;
GHashTable *sequence_grab_actors;
GHashTable *inv_sequence_grab_actors;
/* the current click count */
gint click_count;
/* the stage the device is on */
ClutterStage *stage;
/* the current state */
gfloat current_x;
gfloat current_y;
guint32 current_time;
gint current_button_number;
ClutterModifierType current_state;
/* the current touch points states */
GHashTable *touch_sequences_info;
/* the previous state, used for click count generation */
gint previous_x;
gint previous_y;
guint32 previous_time;
gint previous_button_number;
ClutterModifierType previous_state;
GArray *axes;
guint n_keys;
GArray *keys;
GArray *scroll_info;
gchar *vendor_id;
gchar *product_id;
gchar *node_path;
GPtrArray *tools;
gint n_rings;
gint n_strips;
gint n_mode_groups;
ClutterInputDeviceMapping mapping_mode;
guint has_cursor : 1;
guint is_enabled : 1;
/* Accessiblity */
ClutterVirtualInputDevice *accessibility_virtual_device;
ClutterPtrA11yData *ptr_a11y_data;
};
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
ClutterInputDevice *device);
struct _ClutterInputDeviceClass
{
GObjectClass parent_class;
gboolean (* keycode_to_evdev) (ClutterInputDevice *device,
guint hardware_keycode,
guint *evdev_keycode);
void (* update_from_tool) (ClutterInputDevice *device,
ClutterInputDeviceTool *tool);
gboolean (* is_mode_switch_button) (ClutterInputDevice *device,
guint group,
guint button);
gint (* get_group_n_modes) (ClutterInputDevice *device,
gint group);
gboolean (* is_grouped) (ClutterInputDevice *device,
ClutterInputDevice *other_device);
/* Keyboard accessbility */
void (* process_kbd_a11y_event) (ClutterEvent *event,
ClutterInputDevice *device,
ClutterEmitInputDeviceEvent emit_event_func);
};
/* device manager */
CLUTTER_EXPORT
void _clutter_device_manager_add_device (ClutterDeviceManager *device_manager,
ClutterInputDevice *device);
CLUTTER_EXPORT
void _clutter_device_manager_remove_device (ClutterDeviceManager *device_manager,
ClutterInputDevice *device);
void _clutter_device_manager_update_devices (ClutterDeviceManager *device_manager);
CLUTTER_EXPORT
void _clutter_device_manager_select_stage_events (ClutterDeviceManager *device_manager,
ClutterStage *stage);
ClutterBackend *_clutter_device_manager_get_backend (ClutterDeviceManager *device_manager);
void _clutter_device_manager_compress_motion (ClutterDeviceManager *device_manger,
ClutterEvent *event,
const ClutterEvent *to_discard);
CLUTTER_EXPORT
void clutter_device_manager_ensure_a11y_state (ClutterDeviceManager *device_manager);
/* input device */
CLUTTER_EXPORT
gboolean _clutter_input_device_has_sequence (ClutterInputDevice *device,
ClutterEventSequence *sequence);
CLUTTER_EXPORT
void _clutter_input_device_add_event_sequence (ClutterInputDevice *device,
ClutterEvent *event);
CLUTTER_EXPORT
void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
ClutterEvent *event);
CLUTTER_EXPORT
void _clutter_input_device_set_coords (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gfloat x,
gfloat y,
ClutterStage *stage);
CLUTTER_EXPORT
void _clutter_input_device_set_state (ClutterInputDevice *device,
ClutterModifierType state);
CLUTTER_EXPORT
void _clutter_input_device_set_time (ClutterInputDevice *device,
guint32 time_);
CLUTTER_EXPORT
void _clutter_input_device_set_stage (ClutterInputDevice *device,
ClutterStage *stage);
CLUTTER_EXPORT
ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device);
void _clutter_input_device_set_actor (ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterActor *actor,
gboolean emit_crossing);
ClutterActor * _clutter_input_device_update (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gboolean emit_crossing);
CLUTTER_EXPORT
void _clutter_input_device_set_n_keys (ClutterInputDevice *device,
guint n_keys);
CLUTTER_EXPORT
guint _clutter_input_device_add_axis (ClutterInputDevice *device,
ClutterInputAxis axis,
gdouble min_value,
gdouble max_value,
gdouble resolution);
CLUTTER_EXPORT
void _clutter_input_device_reset_axes (ClutterInputDevice *device);
CLUTTER_EXPORT
void _clutter_input_device_set_associated_device (ClutterInputDevice *device,
ClutterInputDevice *associated);
CLUTTER_EXPORT
void _clutter_input_device_add_slave (ClutterInputDevice *master,
ClutterInputDevice *slave);
CLUTTER_EXPORT
void _clutter_input_device_remove_slave (ClutterInputDevice *master,
ClutterInputDevice *slave);
CLUTTER_EXPORT
gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device,
guint index_,
gdouble value,
gdouble *axis_value);
CLUTTER_EXPORT
void _clutter_input_device_add_scroll_info (ClutterInputDevice *device,
guint index_,
ClutterScrollDirection direction,
gdouble increment);
CLUTTER_EXPORT
void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device);
CLUTTER_EXPORT
gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice *device,
guint index_,
gdouble value,
ClutterScrollDirection *direction_p,
gdouble *delta_p);
CLUTTER_EXPORT
ClutterInputDeviceTool * clutter_input_device_lookup_tool (ClutterInputDevice *device,
guint64 serial,
ClutterInputDeviceToolType type);
CLUTTER_EXPORT
void clutter_input_device_add_tool (ClutterInputDevice *device,
ClutterInputDeviceTool *tool);
CLUTTER_EXPORT
void clutter_input_device_update_from_tool (ClutterInputDevice *device,
ClutterInputDeviceTool *tool);
G_END_DECLS
#endif /* __CLUTTER_DEVICE_MANAGER_PRIVATE_H__ */

View File

@@ -1,753 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2009 Intel Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
*/
/**
* SECTION:clutter-device-manager
* @short_description: Maintains the list of input devices
*
* #ClutterDeviceManager is a singleton object, owned by Clutter, which
* maintains the list of #ClutterInputDevice<!-- -->s.
*
* Depending on the backend used by Clutter it is possible to use the
* #ClutterDeviceManager::device-added and
* #ClutterDeviceManager::device-removed to monitor addition and removal
* of devices.
*
* #ClutterDeviceManager is available since Clutter 1.2
*/
#include "clutter-build-config.h"
#include "clutter-backend-private.h"
#include "clutter-debug.h"
#include "clutter-device-manager-private.h"
#include "clutter-enum-types.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-stage-private.h"
#include "clutter-virtual-input-device.h"
#include "clutter-input-device-tool.h"
#include "clutter-input-pointer-a11y-private.h"
struct _ClutterDeviceManagerPrivate
{
/* back-pointer to the backend */
ClutterBackend *backend;
/* Keyboard a11y */
ClutterKbdA11ySettings kbd_a11y_settings;
/* Pointer a11y */
ClutterPointerA11ySettings pointer_a11y_settings;
};
enum
{
PROP_0,
PROP_BACKEND,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
enum
{
DEVICE_ADDED,
DEVICE_REMOVED,
TOOL_CHANGED,
KBD_A11Y_MASK_CHANGED,
KBD_A11Y_FLAGS_CHANGED,
PTR_A11Y_DWELL_CLICK_TYPE_CHANGED,
PTR_A11Y_TIMEOUT_STARTED,
PTR_A11Y_TIMEOUT_STOPPED,
LAST_SIGNAL
};
static guint manager_signals[LAST_SIGNAL] = { 0, };
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterDeviceManager,
clutter_device_manager,
G_TYPE_OBJECT)
static void
clutter_device_manager_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterDeviceManager *self = CLUTTER_DEVICE_MANAGER (gobject);
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (self);
switch (prop_id)
{
case PROP_BACKEND:
priv->backend = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
}
static void
clutter_device_manager_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterDeviceManager *self = CLUTTER_DEVICE_MANAGER (gobject);
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (self);
switch (prop_id)
{
case PROP_BACKEND:
g_value_set_object (value, priv->backend);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
}
static void
clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
obj_props[PROP_BACKEND] =
g_param_spec_object ("backend",
P_("Backend"),
P_("The ClutterBackend of the device manager"),
CLUTTER_TYPE_BACKEND,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
gobject_class->set_property = clutter_device_manager_set_property;
gobject_class->get_property = clutter_device_manager_get_property;
g_object_class_install_properties (gobject_class,
PROP_LAST,
obj_props);
/**
* ClutterDeviceManager::device-added:
* @manager: the #ClutterDeviceManager that emitted the signal
* @device: the newly added #ClutterInputDevice
*
* The ::device-added signal is emitted each time a device has been
* added to the #ClutterDeviceManager
*
* Since: 1.2
*/
manager_signals[DEVICE_ADDED] =
g_signal_new (I_("device-added"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1,
CLUTTER_TYPE_INPUT_DEVICE);
/**
* ClutterDeviceManager::device-removed:
* @manager: the #ClutterDeviceManager that emitted the signal
* @device: the removed #ClutterInputDevice
*
* The ::device-removed signal is emitted each time a device has been
* removed from the #ClutterDeviceManager
*
* Since: 1.2
*/
manager_signals[DEVICE_REMOVED] =
g_signal_new (I_("device-removed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1,
CLUTTER_TYPE_INPUT_DEVICE);
manager_signals[TOOL_CHANGED] =
g_signal_new (I_("tool-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE, 2,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_INPUT_DEVICE_TOOL);
/**
* ClutterDeviceManager::kbd-a11y-mods-state-changed:
* @manager: the #ClutterDeviceManager that emitted the signal
* @latched_mask: the latched modifier mask from stickykeys
* @locked_mask: the locked modifier mask from stickykeys
*
* The ::kbd-a11y-mods-state-changed signal is emitted each time either the
* latched modifiers mask or locked modifiers mask are changed as the
* result of keyboard accessibilty's sticky keys operations.
*/
manager_signals[KBD_A11Y_MASK_CHANGED] =
g_signal_new (I_("kbd-a11y-mods-state-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__UINT_UINT,
G_TYPE_NONE, 2,
G_TYPE_UINT,
G_TYPE_UINT);
/**
* ClutterDeviceManager::kbd-a11y-flags-changed:
* @manager: the #ClutterDeviceManager that emitted the signal
* @settings_flags: the new ClutterKeyboardA11yFlags configuration
* @changed_mask: the ClutterKeyboardA11yFlags changed
*
* The ::kbd-a11y-flags-changed signal is emitted each time the
* ClutterKeyboardA11yFlags configuration is changed as the result of
* keyboard accessibilty operations.
*/
manager_signals[KBD_A11Y_FLAGS_CHANGED] =
g_signal_new (I_("kbd-a11y-flags-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__UINT_UINT,
G_TYPE_NONE, 2,
G_TYPE_UINT,
G_TYPE_UINT);
/**
* ClutterDeviceManager::ptr-a11y-dwell-click-type-changed:
* @manager: the #ClutterDeviceManager that emitted the signal
* @click_type: the new #ClutterPointerA11yDwellClickType mode
*
* The ::ptr-a11y-dwell-click-type-changed signal is emitted each time
* the ClutterPointerA11yDwellClickType mode is changed as the result
* of pointer accessibility operations.
*/
manager_signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] =
g_signal_new (I_("ptr-a11y-dwell-click-type-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__FLAGS,
G_TYPE_NONE, 1,
CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE);
/**
* ClutterDeviceManager::ptr-a11y-timeout-started:
* @manager: the #ClutterDeviceManager that emitted the signal
* @device: the core pointer #ClutterInputDevice
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
* @delay: the delay in ms before secondary-click is triggered.
*
* The ::ptr-a11y-timeout-started signal is emitted when a
* pointer accessibility timeout delay is started, so that upper
* layers can notify the user with some visual feedback.
*/
manager_signals[PTR_A11Y_TIMEOUT_STARTED] =
g_signal_new (I_("ptr-a11y-timeout-started"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_FLAGS_UINT,
G_TYPE_NONE, 3,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
G_TYPE_UINT);
/**
* ClutterDeviceManager::ptr-a11y-timeout-stopped:
* @manager: the #ClutterDeviceManager that emitted the signal
* @device: the core pointer #ClutterInputDevice
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
* @clicked: %TRUE if the timeout finished and triggered a click
*
* The ::ptr-a11y-timeout-stopped signal is emitted when a running
* pointer accessibility timeout delay is stopped, either because
* it's triggered at the end of the delay or cancelled, so that
* upper layers can notify the user with some visual feedback.
*/
manager_signals[PTR_A11Y_TIMEOUT_STOPPED] =
g_signal_new (I_("ptr-a11y-timeout-stopped"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_FLAGS_BOOLEAN,
G_TYPE_NONE, 3,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
G_TYPE_BOOLEAN);
}
static void
clutter_device_manager_init (ClutterDeviceManager *self)
{
}
/**
* clutter_device_manager_get_default:
*
* Retrieves the device manager singleton
*
* Return value: (transfer none): the #ClutterDeviceManager singleton.
* The returned instance is owned by Clutter and it should not be
* modified or freed
*
* Since: 1.2
*/
ClutterDeviceManager *
clutter_device_manager_get_default (void)
{
ClutterBackend *backend = clutter_get_default_backend ();
return CLUTTER_BACKEND_GET_CLASS (backend)->get_device_manager (backend);
}
/**
* clutter_device_manager_list_devices:
* @device_manager: a #ClutterDeviceManager
*
* Lists all currently registered input devices
*
* Return value: (transfer container) (element-type Clutter.InputDevice):
* a newly allocated list of #ClutterInputDevice objects. Use
* g_slist_free() to deallocate it when done
*
* Since: 1.2
*/
GSList *
clutter_device_manager_list_devices (ClutterDeviceManager *device_manager)
{
const GSList *devices;
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL);
devices = clutter_device_manager_peek_devices (device_manager);
return g_slist_copy ((GSList *) devices);
}
/**
* clutter_device_manager_peek_devices:
* @device_manager: a #ClutterDeviceManager
*
* Lists all currently registered input devices
*
* Return value: (transfer none) (element-type Clutter.InputDevice):
* a pointer to the internal list of #ClutterInputDevice objects. The
* returned list is owned by the #ClutterDeviceManager and should never
* be modified or freed
*
* Since: 1.2
*/
const GSList *
clutter_device_manager_peek_devices (ClutterDeviceManager *device_manager)
{
ClutterDeviceManagerClass *manager_class;
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL);
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
return manager_class->get_devices (device_manager);
}
/**
* clutter_device_manager_get_device:
* @device_manager: a #ClutterDeviceManager
* @device_id: the integer id of a device
*
* Retrieves the #ClutterInputDevice with the given @device_id
*
* Return value: (transfer none): a #ClutterInputDevice or %NULL. The
* returned device is owned by the #ClutterDeviceManager and should
* never be modified or freed
*
* Since: 1.2
*/
ClutterInputDevice *
clutter_device_manager_get_device (ClutterDeviceManager *device_manager,
gint device_id)
{
ClutterDeviceManagerClass *manager_class;
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL);
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
return manager_class->get_device (device_manager, device_id);
}
/**
* clutter_device_manager_get_core_device:
* @device_manager: a #ClutterDeviceManager
* @device_type: the type of the core device
*
* Retrieves the core #ClutterInputDevice of type @device_type
*
* Core devices are devices created automatically by the default
* Clutter backend
*
* Return value: (transfer none): a #ClutterInputDevice or %NULL. The
* returned device is owned by the #ClutterDeviceManager and should
* not be modified or freed
*
* Since: 1.2
*/
ClutterInputDevice *
clutter_device_manager_get_core_device (ClutterDeviceManager *device_manager,
ClutterInputDeviceType device_type)
{
ClutterDeviceManagerClass *manager_class;
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL);
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
return manager_class->get_core_device (device_manager, device_type);
}
void
_clutter_device_manager_select_stage_events (ClutterDeviceManager *device_manager,
ClutterStage *stage)
{
ClutterDeviceManagerClass *manager_class;
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
if (manager_class->select_stage_events)
manager_class->select_stage_events (device_manager, stage);
}
/*
* _clutter_device_manager_add_device:
* @device_manager: a #ClutterDeviceManager
* @device: a #ClutterInputDevice
*
* Adds @device to the list of #ClutterInputDevice<!-- -->s maintained
* by @device_manager
*
* The reference count of @device is not increased
*
* The #ClutterDeviceManager::device-added signal is emitted after
* adding @device to the list
*/
void
_clutter_device_manager_add_device (ClutterDeviceManager *device_manager,
ClutterInputDevice *device)
{
ClutterDeviceManagerClass *manager_class;
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
g_assert (manager_class->add_device != NULL);
manager_class->add_device (device_manager, device);
g_signal_emit (device_manager, manager_signals[DEVICE_ADDED], 0, device);
}
/*
* _clutter_device_manager_remove_device:
* @device_manager: a #ClutterDeviceManager
* @device: a #ClutterInputDevice
*
* Removes @device from the list of #ClutterInputDevice<!-- -->s
* maintained by @device_manager
*
* The reference count of @device is not decreased
*
* The #ClutterDeviceManager::device-removed signal is emitted after
* removing @device from the list
*/
void
_clutter_device_manager_remove_device (ClutterDeviceManager *device_manager,
ClutterInputDevice *device)
{
ClutterDeviceManagerClass *manager_class;
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
g_assert (manager_class->remove_device != NULL);
/* The subclass remove_device() method will likely unref it but we
have to keep it alive during the signal emission. */
g_object_ref (device);
manager_class->remove_device (device_manager, device);
g_signal_emit (device_manager, manager_signals[DEVICE_REMOVED], 0, device);
g_object_unref (device);
}
/*
* _clutter_device_manager_update_devices:
* @device_manager: a #ClutterDeviceManager
*
* Updates every #ClutterInputDevice handled by @device_manager
* by performing a pick paint at the coordinates of each pointer
* device
*/
void
_clutter_device_manager_update_devices (ClutterDeviceManager *device_manager)
{
const GSList *d;
for (d = clutter_device_manager_peek_devices (device_manager);
d != NULL;
d = d->next)
{
ClutterInputDevice *device = d->data;
ClutterInputDeviceType device_type;
/* we only care about pointer devices */
device_type = clutter_input_device_get_device_type (device);
if (device_type != CLUTTER_POINTER_DEVICE)
continue;
/* out of stage */
if (device->stage == NULL)
continue;
/* the user disabled motion events delivery on actors for
* the stage the device is on; we don't perform any picking
* since the source of the events will always be set to be
* the stage
*/
if (!clutter_stage_get_motion_events_enabled (device->stage))
continue;
_clutter_input_device_update (device, NULL, TRUE);
}
}
ClutterBackend *
_clutter_device_manager_get_backend (ClutterDeviceManager *manager)
{
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (manager);
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (manager), NULL);
return priv->backend;
}
/**
* clutter_device_manager_create_virtual_device:
* @device_manager: a #ClutterDeviceManager
* @device_type: the type of the virtual device
*
* Creates a virtual input device.
*
* Returns: (transfer full): a newly created virtual device
**/
ClutterVirtualInputDevice *
clutter_device_manager_create_virtual_device (ClutterDeviceManager *device_manager,
ClutterInputDeviceType device_type)
{
ClutterDeviceManagerClass *manager_class;
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL);
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
return manager_class->create_virtual_device (device_manager,
device_type);
}
/**
* clutter_device_manager_supported_virtua_device_types: (skip)
*/
ClutterVirtualDeviceType
clutter_device_manager_get_supported_virtual_device_types (ClutterDeviceManager *device_manager)
{
ClutterDeviceManagerClass *manager_class;
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager),
CLUTTER_VIRTUAL_DEVICE_TYPE_NONE);
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
return manager_class->get_supported_virtual_device_types (device_manager);
}
void
_clutter_device_manager_compress_motion (ClutterDeviceManager *device_manager,
ClutterEvent *event,
const ClutterEvent *to_discard)
{
ClutterDeviceManagerClass *manager_class;
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
if (!manager_class->compress_motion)
return;
manager_class->compress_motion (device_manager, event, to_discard);
}
void
clutter_device_manager_ensure_a11y_state (ClutterDeviceManager *device_manager)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device_manager,
CLUTTER_POINTER_DEVICE);
if (core_pointer)
{
if (_clutter_is_input_pointer_a11y_enabled (core_pointer))
_clutter_input_pointer_a11y_add_device (core_pointer);
}
}
static gboolean
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
ClutterKbdA11ySettings *b)
{
return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0);
}
void
clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings)
{
ClutterDeviceManagerClass *manager_class;
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (device_manager);
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
if (are_kbd_a11y_settings_equal (&priv->kbd_a11y_settings, settings))
return;
priv->kbd_a11y_settings = *settings;
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
if (manager_class->apply_kbd_a11y_settings)
manager_class->apply_kbd_a11y_settings (device_manager, settings);
}
void
clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings)
{
ClutterDeviceManagerPrivate *priv = clutter_device_manager_get_instance_private (device_manager);
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
*settings = priv->kbd_a11y_settings;
}
static gboolean
are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a,
ClutterPointerA11ySettings *b)
{
return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0);
}
static void
clutter_device_manager_enable_pointer_a11y (ClutterDeviceManager *device_manager)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_add_device (core_pointer);
}
static void
clutter_device_manager_disable_pointer_a11y (ClutterDeviceManager *device_manager)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_remove_device (core_pointer);
}
/**
* clutter_device_manager_set_pointer_a11y_settings:
* @device_manager: a #ClutterDeviceManager
* @settings: a pointer to a #ClutterPointerA11ySettings
*
* Sets the pointer accessibility settings
**/
void
clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings)
{
ClutterDeviceManagerPrivate *priv =
clutter_device_manager_get_instance_private (device_manager);
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
if (are_pointer_a11y_settings_equal (&priv->pointer_a11y_settings, settings))
return;
if (priv->pointer_a11y_settings.controls == 0 && settings->controls != 0)
clutter_device_manager_enable_pointer_a11y (device_manager);
else if (priv->pointer_a11y_settings.controls != 0 && settings->controls == 0)
clutter_device_manager_disable_pointer_a11y (device_manager);
priv->pointer_a11y_settings = *settings;
}
/**
* clutter_device_manager_get_pointer_a11y_settings:
* @device_manager: a #ClutterDeviceManager
* @settings: a pointer to a #ClutterPointerA11ySettings
*
* Gets the current pointer accessibility settings
**/
void
clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings)
{
ClutterDeviceManagerPrivate *priv =
clutter_device_manager_get_instance_private (device_manager);
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
*settings = priv->pointer_a11y_settings;
}
/**
* clutter_device_manager_set_pointer_a11y_dwell_click_type:
* @device_manager: a #ClutterDeviceManager
* @click_type: type of click as #ClutterPointerA11yDwellClickType
*
* Sets the dwell click type
**/
void
clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
ClutterPointerA11yDwellClickType click_type)
{
ClutterDeviceManagerPrivate *priv =
clutter_device_manager_get_instance_private (device_manager);
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
priv->pointer_a11y_settings.dwell_click_type = click_type;
}

View File

@@ -1,181 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2009 Intel Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef __CLUTTER_DEVICE_MANAGER_H__
#define __CLUTTER_DEVICE_MANAGER_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-input-device.h>
#include <clutter/clutter-stage.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_DEVICE_MANAGER (clutter_device_manager_get_type ())
CLUTTER_EXPORT
G_DECLARE_DERIVABLE_TYPE (ClutterDeviceManager, clutter_device_manager,
CLUTTER, DEVICE_MANAGER, GObject)
typedef struct _ClutterDeviceManagerPrivate ClutterDeviceManagerPrivate;
/**
* ClutterVirtualDeviceType:
*/
typedef enum _ClutterVirtualDeviceType
{
CLUTTER_VIRTUAL_DEVICE_TYPE_NONE = 0,
CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD = 1 << 0,
CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER = 1 << 1,
CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN = 1 << 2,
} ClutterVirtualDeviceType;
/**
* ClutterKbdA11ySettings:
*
* The #ClutterKbdA11ySettings structure contains keyboard accessibility
* settings
*
*/
typedef struct _ClutterKbdA11ySettings
{
ClutterKeyboardA11yFlags controls;
gint slowkeys_delay;
gint debounce_delay;
gint timeout_delay;
gint mousekeys_init_delay;
gint mousekeys_max_speed;
gint mousekeys_accel_time;
} ClutterKbdA11ySettings;
/**
* ClutterPointerA11ySettings:
*
* The #ClutterPointerA11ySettings structure contains pointer accessibility
* settings
*
*/
typedef struct _ClutterPointerA11ySettings
{
ClutterPointerA11yFlags controls;
ClutterPointerA11yDwellClickType dwell_click_type;
ClutterPointerA11yDwellMode dwell_mode;
ClutterPointerA11yDwellDirection dwell_gesture_single;
ClutterPointerA11yDwellDirection dwell_gesture_double;
ClutterPointerA11yDwellDirection dwell_gesture_drag;
ClutterPointerA11yDwellDirection dwell_gesture_secondary;
gint secondary_click_delay;
gint dwell_delay;
gint dwell_threshold;
} ClutterPointerA11ySettings;
/**
* ClutterDeviceManagerClass:
*
* The #ClutterDeviceManagerClass structure contains only private data
*
* Since: 1.2
*/
struct _ClutterDeviceManagerClass
{
/*< private >*/
GObjectClass parent_class;
const GSList * (* get_devices) (ClutterDeviceManager *device_manager);
ClutterInputDevice *(* get_core_device) (ClutterDeviceManager *device_manager,
ClutterInputDeviceType device_type);
ClutterInputDevice *(* get_device) (ClutterDeviceManager *device_manager,
gint device_id);
void (* add_device) (ClutterDeviceManager *manager,
ClutterInputDevice *device);
void (* remove_device) (ClutterDeviceManager *manager,
ClutterInputDevice *device);
void (* select_stage_events) (ClutterDeviceManager *manager,
ClutterStage *stage);
ClutterVirtualInputDevice *(* create_virtual_device) (ClutterDeviceManager *device_manager,
ClutterInputDeviceType device_type);
ClutterVirtualDeviceType (* get_supported_virtual_device_types) (ClutterDeviceManager *device_manager);
void (* compress_motion) (ClutterDeviceManager *device_manger,
ClutterEvent *event,
const ClutterEvent *to_discard);
/* Keyboard accessbility */
void (* apply_kbd_a11y_settings) (ClutterDeviceManager *device_manger,
ClutterKbdA11ySettings *settings);
/* Event platform data */
void (* copy_event_data) (ClutterDeviceManager *device_manager,
const ClutterEvent *src,
ClutterEvent *dest);
void (* free_event_data) (ClutterDeviceManager *device_manager,
ClutterEvent *event);
/* padding */
gpointer _padding[4];
};
CLUTTER_EXPORT
ClutterDeviceManager *clutter_device_manager_get_default (void);
CLUTTER_EXPORT
GSList * clutter_device_manager_list_devices (ClutterDeviceManager *device_manager);
CLUTTER_EXPORT
const GSList * clutter_device_manager_peek_devices (ClutterDeviceManager *device_manager);
CLUTTER_EXPORT
ClutterInputDevice * clutter_device_manager_get_device (ClutterDeviceManager *device_manager,
gint device_id);
CLUTTER_EXPORT
ClutterInputDevice * clutter_device_manager_get_core_device (ClutterDeviceManager *device_manager,
ClutterInputDeviceType device_type);
CLUTTER_EXPORT
ClutterVirtualInputDevice *clutter_device_manager_create_virtual_device (ClutterDeviceManager *device_manager,
ClutterInputDeviceType device_type);
CLUTTER_EXPORT
ClutterVirtualDeviceType clutter_device_manager_get_supported_virtual_device_types (ClutterDeviceManager *device_manager);
CLUTTER_EXPORT
void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
ClutterPointerA11ySettings *settings);
CLUTTER_EXPORT
void clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
ClutterPointerA11yDwellClickType click_type);
G_END_DECLS
#endif /* __CLUTTER_DEVICE_MANAGER_H__ */

View File

@@ -535,9 +535,13 @@ typedef enum /*< prefix=CLUTTER_ACTOR >*/
* ClutterOffscreenRedirect:
* @CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY: Only redirect
* the actor if it is semi-transparent and its has_overlaps()
* virtual returns %TRUE. This is the default.
* virtual returns %TRUE.
* @CLUTTER_OFFSCREEN_REDIRECT_ALWAYS: Always redirect the actor to an
* offscreen buffer even if it is fully opaque.
* @CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE: Only redirect the actor if it is the
* most efficient thing to do based on its recent repaint behaviour. That
* means when its contents are changing less frequently than it's being used
* on stage.
*
* Possible flags to pass to clutter_actor_set_offscreen_redirect().
*
@@ -545,8 +549,9 @@ typedef enum /*< prefix=CLUTTER_ACTOR >*/
*/
typedef enum /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/
{
CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY = 1<<0,
CLUTTER_OFFSCREEN_REDIRECT_ALWAYS = 1<<1
CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY = 1 << 0,
CLUTTER_OFFSCREEN_REDIRECT_ALWAYS = 1 << 1,
CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE = 1 << 2
} ClutterOffscreenRedirect;
/**
@@ -673,12 +678,15 @@ typedef enum /*< prefix=CLUTTER_BIND >*/
* has queued a redraw before this paint. This implies that the effect
* should call clutter_actor_continue_paint() to chain to the next
* effect and can not cache any results from a previous paint.
* @CLUTTER_EFFECT_PAINT_BYPASS_EFFECT: The effect should not be used
* on this frame, but it will be asked to paint the actor still.
*
* Flags passed to the paint or pick method of #ClutterEffect.
*/
typedef enum /*< prefix=CLUTTER_EFFECT_PAINT >*/
{
CLUTTER_EFFECT_PAINT_ACTOR_DIRTY = (1 << 0)
CLUTTER_EFFECT_PAINT_ACTOR_DIRTY = (1 << 0),
CLUTTER_EFFECT_PAINT_BYPASS_EFFECT = (1 << 1)
} ClutterEffectPaintFlags;
/**

View File

@@ -130,7 +130,7 @@ clutter_image_paint_content (ClutterContent *content,
return;
node = clutter_actor_create_texture_paint_node (actor, priv->texture);
clutter_paint_node_set_name (node, "Image Content");
clutter_paint_node_set_static_name (node, "Image Content");
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
}

View File

@@ -0,0 +1,255 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright © 2009, 2010, 2011 Intel Corp.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef CLUTTER_INPUT_DEVICE_PRIVATE_H
#define CLUTTER_INPUT_DEVICE_PRIVATE_H
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-input-device.h>
G_BEGIN_DECLS
typedef struct _ClutterAxisInfo
{
ClutterInputAxis axis;
double min_axis;
double max_axis;
double min_value;
double max_value;
double resolution;
} ClutterAxisInfo;
typedef struct _ClutterKeyInfo
{
guint keyval;
ClutterModifierType modifiers;
} ClutterKeyInfo;
typedef struct _ClutterScrollInfo
{
guint axis_id;
ClutterScrollDirection direction;
double increment;
double last_value;
guint last_value_valid : 1;
} ClutterScrollInfo;
typedef struct _ClutterTouchInfo
{
ClutterEventSequence *sequence;
ClutterActor *actor;
float current_x;
float current_y;
} ClutterTouchInfo;
typedef struct _ClutterPtrA11yData
{
int n_btn_pressed;
float current_x;
float current_y;
float dwell_x;
float dwell_y;
gboolean dwell_drag_started;
gboolean dwell_gesture_started;
guint dwell_timer;
guint dwell_position_timer;
guint secondary_click_timer;
gboolean secondary_click_triggered;
} ClutterPtrA11yData;
struct _ClutterInputDevice
{
GObject parent_instance;
int id;
ClutterInputDeviceType device_type;
ClutterInputMode device_mode;
char *device_name;
ClutterSeat *seat;
ClutterBackend *backend;
/* the associated device */
ClutterInputDevice *associated;
GList *slaves;
/* the actor underneath the pointer */
ClutterActor *cursor_actor;
GHashTable *inv_touch_sequence_actors;
/* the actor that has a grab in place for the device */
ClutterActor *pointer_grab_actor;
ClutterActor *keyboard_grab_actor;
GHashTable *sequence_grab_actors;
GHashTable *inv_sequence_grab_actors;
/* the current click count */
int click_count;
/* the stage the device is on */
ClutterStage *stage;
/* the current state */
float current_x;
float current_y;
uint32_t current_time;
int current_button_number;
ClutterModifierType current_state;
/* the current touch points states */
GHashTable *touch_sequences_info;
/* the previous state, used for click count generation */
int previous_x;
int previous_y;
uint32_t previous_time;
int previous_button_number;
ClutterModifierType previous_state;
GArray *axes;
guint n_keys;
GArray *keys;
GArray *scroll_info;
char *vendor_id;
char *product_id;
char *node_path;
GPtrArray *tools;
int n_rings;
int n_strips;
int n_mode_groups;
ClutterInputDeviceMapping mapping_mode;
guint has_cursor : 1;
guint is_enabled : 1;
/* Accessiblity */
ClutterVirtualInputDevice *accessibility_virtual_device;
ClutterPtrA11yData *ptr_a11y_data;
};
CLUTTER_EXPORT
void _clutter_input_device_set_associated_device (ClutterInputDevice *device,
ClutterInputDevice *associated);
CLUTTER_EXPORT
void _clutter_input_device_add_slave (ClutterInputDevice *master,
ClutterInputDevice *slave);
CLUTTER_EXPORT
void _clutter_input_device_remove_slave (ClutterInputDevice *master,
ClutterInputDevice *slave);
CLUTTER_EXPORT
void clutter_input_device_update_from_tool (ClutterInputDevice *device,
ClutterInputDeviceTool *tool);
CLUTTER_EXPORT
ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device);
CLUTTER_EXPORT
void _clutter_input_device_set_stage (ClutterInputDevice *device,
ClutterStage *stage);
CLUTTER_EXPORT
void _clutter_input_device_set_coords (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gfloat x,
gfloat y,
ClutterStage *stage);
CLUTTER_EXPORT
void _clutter_input_device_set_state (ClutterInputDevice *device,
ClutterModifierType state);
CLUTTER_EXPORT
void _clutter_input_device_set_time (ClutterInputDevice *device,
guint32 time_);
void _clutter_input_device_set_actor (ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterActor *actor,
gboolean emit_crossing);
CLUTTER_EXPORT
ClutterActor * clutter_input_device_update (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gboolean emit_crossing);
CLUTTER_EXPORT
void _clutter_input_device_add_event_sequence (ClutterInputDevice *device,
ClutterEvent *event);
CLUTTER_EXPORT
void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
ClutterEvent *event);
CLUTTER_EXPORT
void _clutter_input_device_set_n_keys (ClutterInputDevice *device,
guint n_keys);
CLUTTER_EXPORT
gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device,
guint index_,
gdouble value,
gdouble *axis_value);
CLUTTER_EXPORT
guint _clutter_input_device_add_axis (ClutterInputDevice *device,
ClutterInputAxis axis,
gdouble minimum,
gdouble maximum,
gdouble resolution);
CLUTTER_EXPORT
void _clutter_input_device_reset_axes (ClutterInputDevice *device);
CLUTTER_EXPORT
void _clutter_input_device_add_scroll_info (ClutterInputDevice *device,
guint index_,
ClutterScrollDirection direction,
gdouble increment);
CLUTTER_EXPORT
gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice *device,
guint index_,
gdouble value,
ClutterScrollDirection *direction_p,
gdouble *delta_p);
CLUTTER_EXPORT
void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device);
CLUTTER_EXPORT
void clutter_input_device_add_tool (ClutterInputDevice *device,
ClutterInputDeviceTool *tool);
CLUTTER_EXPORT
ClutterInputDeviceTool *
clutter_input_device_lookup_tool (ClutterInputDevice *device,
guint64 serial,
ClutterInputDeviceToolType type);
#endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */

View File

@@ -37,12 +37,12 @@
#include "clutter-actor-private.h"
#include "clutter-debug.h"
#include "clutter-device-manager-private.h"
#include "clutter-enum-types.h"
#include "clutter-event-private.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-stage-private.h"
#include "clutter-input-device-private.h"
#include "clutter-input-device-tool.h"
#include <math.h>
@@ -57,7 +57,7 @@ enum
PROP_NAME,
PROP_DEVICE_TYPE,
PROP_DEVICE_MANAGER,
PROP_SEAT,
PROP_DEVICE_MODE,
PROP_HAS_CURSOR,
@@ -96,6 +96,7 @@ clutter_input_device_dispose (GObject *gobject)
g_clear_pointer (&device->device_name, g_free);
g_clear_pointer (&device->vendor_id, g_free);
g_clear_pointer (&device->product_id, g_free);
g_clear_pointer (&device->node_path, g_free);
if (device->associated != NULL)
{
@@ -170,8 +171,8 @@ clutter_input_device_set_property (GObject *gobject,
self->device_type = g_value_get_enum (value);
break;
case PROP_DEVICE_MANAGER:
self->device_manager = g_value_get_object (value);
case PROP_SEAT:
self->seat = g_value_get_object (value);
break;
case PROP_DEVICE_MODE:
@@ -246,8 +247,8 @@ clutter_input_device_get_property (GObject *gobject,
g_value_set_enum (value, self->device_type);
break;
case PROP_DEVICE_MANAGER:
g_value_set_object (value, self->device_manager);
case PROP_SEAT:
g_value_set_object (value, self->seat);
break;
case PROP_DEVICE_MODE:
@@ -361,17 +362,15 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass)
G_PARAM_CONSTRUCT_ONLY);
/**
* ClutterInputDevice:device-manager:
* ClutterInputDevice:seat:
*
* The #ClutterDeviceManager instance which owns the device
*
* Since: 1.6
* The #ClutterSeat instance which owns the device
*/
obj_props[PROP_DEVICE_MANAGER] =
g_param_spec_object ("device-manager",
P_("Device Manager"),
P_("The device manager instance"),
CLUTTER_TYPE_DEVICE_MANAGER,
obj_props[PROP_SEAT] =
g_param_spec_object ("seat",
P_("Seat"),
P_("Seat"),
CLUTTER_TYPE_SEAT,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
/**
@@ -799,7 +798,7 @@ on_cursor_actor_reactive_changed (ClutterActor *actor,
*
* Sets the actor under the pointer coordinates of @device
*
* This function is called by _clutter_input_device_update()
* This function is called by clutter_input_device_update()
* and it will:
*
* - queue a %CLUTTER_LEAVE event on the previous pointer actor
@@ -1017,7 +1016,7 @@ clutter_input_device_get_coords (ClutterInputDevice *device,
}
/*
* _clutter_input_device_update:
* clutter_input_device_update:
* @device: a #ClutterInputDevice
*
* Updates the input @device by determining the #ClutterActor underneath the
@@ -1031,9 +1030,9 @@ clutter_input_device_get_coords (ClutterInputDevice *device,
* Since: 1.2
*/
ClutterActor *
_clutter_input_device_update (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gboolean emit_crossing)
clutter_input_device_update (ClutterInputDevice *device,
ClutterEventSequence *sequence,
gboolean emit_crossing)
{
ClutterStage *stage;
ClutterActor *new_cursor_actor;
@@ -1224,11 +1223,11 @@ clutter_input_device_get_device_mode (ClutterInputDevice *device)
*
* translate_native_event_to_clutter (native_event, &c_event);
*
* // get the device manager
* manager = clutter_device_manager_get_default ();
* // get the seat
* seat = clutter_backend_get_deafult_seat (clutter_get_default_backend ());
*
* // use the default Core Pointer that Clutter backends register by default
* device = clutter_device_manager_get_core_device (manager, %CLUTTER_POINTER_DEVICE);
* device = clutter_seat_get_pointer (seat);
*
* // update the state of the input device
* clutter_input_device_update_from_event (device, &c_event, FALSE);
@@ -2441,3 +2440,19 @@ clutter_input_device_is_grouped (ClutterInputDevice *device,
return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->is_grouped (device, other_device);
}
/**
* clutter_input_device_get_seat:
* @device: a #ClutterInputDevice
*
* Returns the seat the device belongs to
*
* Returns: (transfer none): the device seat
**/
ClutterSeat *
clutter_input_device_get_seat (ClutterInputDevice *device)
{
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
return device->seat;
}

View File

@@ -28,10 +28,40 @@
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include <clutter/clutter-backend.h>
#include <clutter/clutter-types.h>
#include <clutter/clutter-seat.h>
G_BEGIN_DECLS
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
ClutterInputDevice *device);
struct _ClutterInputDeviceClass
{
GObjectClass parent_class;
gboolean (* keycode_to_evdev) (ClutterInputDevice *device,
guint hardware_keycode,
guint *evdev_keycode);
void (* update_from_tool) (ClutterInputDevice *device,
ClutterInputDeviceTool *tool);
gboolean (* is_mode_switch_button) (ClutterInputDevice *device,
guint group,
guint button);
gint (* get_group_n_modes) (ClutterInputDevice *device,
gint group);
gboolean (* is_grouped) (ClutterInputDevice *device,
ClutterInputDevice *other_device);
/* Keyboard accessbility */
void (* process_kbd_a11y_event) (ClutterEvent *event,
ClutterInputDevice *device,
ClutterEmitInputDeviceEvent emit_event_func);
};
#define CLUTTER_TYPE_INPUT_DEVICE (clutter_input_device_get_type ())
#define CLUTTER_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INPUT_DEVICE, ClutterInputDevice))
#define CLUTTER_IS_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INPUT_DEVICE))
@@ -171,6 +201,8 @@ void clutter_input_device_set_mapping_mode (ClutterInputDev
CLUTTER_EXPORT
gboolean clutter_input_device_is_grouped (ClutterInputDevice *device,
ClutterInputDevice *other_device);
CLUTTER_EXPORT
ClutterSeat * clutter_input_device_get_seat (ClutterInputDevice *device);
G_END_DECLS

View File

@@ -29,7 +29,7 @@ void clutter_input_focus_focus_out (ClutterInputFocus *focus);
void clutter_input_focus_commit (ClutterInputFocus *focus,
const gchar *text);
void clutter_input_focus_delete_surrounding (ClutterInputFocus *focus,
guint offset,
int offset,
guint len);
void clutter_input_focus_request_surrounding (ClutterInputFocus *focus);

View File

@@ -217,7 +217,7 @@ clutter_input_focus_commit (ClutterInputFocus *focus,
void
clutter_input_focus_delete_surrounding (ClutterInputFocus *focus,
guint offset,
int offset,
guint len)
{
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));

View File

@@ -41,7 +41,7 @@ struct _ClutterInputFocusClass
void (* request_surrounding) (ClutterInputFocus *focus);
void (* delete_surrounding) (ClutterInputFocus *focus,
guint offset,
int offset,
guint len);
void (* commit_text) (ClutterInputFocus *focus,
const gchar *text);

View File

@@ -22,10 +22,10 @@
#include "clutter-build-config.h"
#include "clutter-private.h"
#include "clutter/clutter-input-device-private.h"
#include "clutter/clutter-input-method.h"
#include "clutter/clutter-input-method-private.h"
#include "clutter/clutter-input-focus-private.h"
#include "clutter/clutter-device-manager-private.h"
typedef struct _ClutterInputMethodPrivate ClutterInputMethodPrivate;
@@ -168,7 +168,7 @@ clutter_input_method_class_init (ClutterInputMethodClass *klass)
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT);
signals[REQUEST_SURROUNDING] =
g_signal_new ("request-surrounding",
G_TYPE_FROM_CLASS (object_class),
@@ -292,7 +292,7 @@ clutter_input_method_commit (ClutterInputMethod *im,
void
clutter_input_method_delete_surrounding (ClutterInputMethod *im,
guint offset,
int offset,
guint len)
{
ClutterInputMethodPrivate *priv;
@@ -452,8 +452,8 @@ clutter_input_method_forward_key (ClutterInputMethod *im,
gboolean press)
{
ClutterInputMethodPrivate *priv;
ClutterDeviceManager *device_manager;
ClutterInputDevice *keyboard;
ClutterSeat *seat;
ClutterStage *stage;
ClutterEvent *event;
@@ -463,9 +463,8 @@ clutter_input_method_forward_key (ClutterInputMethod *im,
if (!priv->focus)
return;
device_manager = clutter_device_manager_get_default ();
keyboard = clutter_device_manager_get_core_device (device_manager,
CLUTTER_KEYBOARD_DEVICE);
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
keyboard = clutter_seat_get_keyboard (seat);
stage = _clutter_input_device_get_stage (keyboard);
if (stage == NULL)
return;

View File

@@ -68,7 +68,7 @@ void clutter_input_method_commit (ClutterInputMethod *im,
const gchar *text);
CLUTTER_EXPORT
void clutter_input_method_delete_surrounding (ClutterInputMethod *im,
guint offset,
int offset,
guint len);
CLUTTER_EXPORT
void clutter_input_method_request_surrounding (ClutterInputMethod *im);

View File

@@ -25,10 +25,9 @@
#include "clutter-build-config.h"
#include "clutter-device-manager.h"
#include "clutter-device-manager-private.h"
#include "clutter-enum-types.h"
#include "clutter-input-device.h"
#include "clutter-input-device-private.h"
#include "clutter-input-pointer-a11y-private.h"
#include "clutter-main.h"
#include "clutter-virtual-input-device.h"
@@ -38,7 +37,7 @@ is_secondary_click_enabled (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED);
}
@@ -48,7 +47,7 @@ is_dwell_click_enabled (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED);
}
@@ -58,7 +57,7 @@ get_secondary_click_delay (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
return settings.secondary_click_delay;
}
@@ -68,7 +67,7 @@ get_dwell_delay (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
return settings.dwell_delay;
}
@@ -78,7 +77,7 @@ get_dwell_threshold (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
return settings.dwell_threshold;
}
@@ -88,7 +87,7 @@ get_dwell_mode (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
return settings.dwell_mode;
}
@@ -98,7 +97,7 @@ get_dwell_click_type (ClutterInputDevice *device)
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
return settings.dwell_click_type;
}
@@ -109,7 +108,7 @@ get_dwell_click_type_for_direction (ClutterInputDevice *device,
{
ClutterPointerA11ySettings settings;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
if (direction == settings.dwell_gesture_single)
return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
@@ -168,7 +167,7 @@ trigger_secondary_click (gpointer data)
device->ptr_a11y_data->secondary_click_triggered = TRUE;
device->ptr_a11y_data->secondary_click_timer = 0;
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
@@ -185,7 +184,7 @@ start_secondary_click_timeout (ClutterInputDevice *device)
device->ptr_a11y_data->secondary_click_timer =
clutter_threads_add_timeout (delay, trigger_secondary_click, device);
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-timeout-started",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
@@ -200,7 +199,7 @@ stop_secondary_click_timeout (ClutterInputDevice *device)
g_clear_handle_id (&device->ptr_a11y_data->secondary_click_timer,
g_source_remove);
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
@@ -304,7 +303,7 @@ update_dwell_click_type (ClutterInputDevice *device)
ClutterPointerA11ySettings settings;
ClutterPointerA11yDwellClickType dwell_click_type;
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
dwell_click_type = settings.dwell_click_type;
switch (dwell_click_type)
@@ -329,10 +328,9 @@ update_dwell_click_type (ClutterInputDevice *device)
if (dwell_click_type != settings.dwell_click_type)
{
settings.dwell_click_type = dwell_click_type;
clutter_device_manager_set_pointer_a11y_settings (device->device_manager,
&settings);
clutter_seat_set_pointer_a11y_settings (device->seat, &settings);
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-dwell-click-type-changed",
dwell_click_type);
}
@@ -437,7 +435,7 @@ trigger_dwell_gesture (gpointer data)
device->ptr_a11y_data->dwell_timer =
clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device);
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
@@ -455,7 +453,7 @@ start_dwell_gesture_timeout (ClutterInputDevice *device)
clutter_threads_add_timeout (delay, trigger_dwell_gesture, device);
device->ptr_a11y_data->dwell_gesture_started = TRUE;
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-timeout-started",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
@@ -469,7 +467,7 @@ trigger_dwell_click (gpointer data)
device->ptr_a11y_data->dwell_timer = 0;
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
@@ -499,7 +497,7 @@ start_dwell_timeout (ClutterInputDevice *device)
device->ptr_a11y_data->dwell_timer =
clutter_threads_add_timeout (delay, trigger_dwell_click, device);
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-timeout-started",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
@@ -514,7 +512,7 @@ stop_dwell_timeout (ClutterInputDevice *device)
g_clear_handle_id (&device->ptr_a11y_data->dwell_timer, g_source_remove);
device->ptr_a11y_data->dwell_gesture_started = FALSE;
g_signal_emit_by_name (device->device_manager,
g_signal_emit_by_name (device->seat,
"ptr-a11y-timeout-stopped",
device,
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
@@ -573,8 +571,7 @@ is_device_core_pointer (ClutterInputDevice *device)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
CLUTTER_POINTER_DEVICE);
core_pointer = clutter_seat_get_pointer (device->seat);
if (core_pointer == NULL)
return FALSE;
@@ -588,8 +585,8 @@ _clutter_input_pointer_a11y_add_device (ClutterInputDevice *device)
return;
device->accessibility_virtual_device =
clutter_device_manager_create_virtual_device (device->device_manager,
CLUTTER_POINTER_DEVICE);
clutter_seat_create_virtual_device (device->seat,
CLUTTER_POINTER_DEVICE);
device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1);
}

View File

@@ -62,3 +62,9 @@ clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap)
{
return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_caps_lock_state (keymap);
}
PangoDirection
clutter_keymap_get_direction (ClutterKeymap *keymap)
{
return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_direction (keymap);
}

View File

@@ -29,6 +29,7 @@
#include <clutter/clutter-macros.h>
#include <glib-object.h>
#include <pango/pango.h>
typedef struct _ClutterKeymap ClutterKeymap;
typedef struct _ClutterKeymapClass ClutterKeymapClass;
@@ -39,6 +40,7 @@ struct _ClutterKeymapClass
gboolean (* get_num_lock_state) (ClutterKeymap *keymap);
gboolean (* get_caps_lock_state) (ClutterKeymap *keymap);
PangoDirection (* get_direction) (ClutterKeymap *keymap);
};
#define CLUTTER_TYPE_KEYMAP (clutter_keymap_get_type ())
@@ -53,4 +55,6 @@ gboolean clutter_keymap_get_num_lock_state (ClutterKeymap *keymap);
CLUTTER_EXPORT
gboolean clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap);
PangoDirection clutter_keymap_get_direction (ClutterKeymap *keymap);
#endif /* CLUTTER_KEYMAP_H */

View File

@@ -55,14 +55,15 @@
#include "clutter-backend-private.h"
#include "clutter-config.h"
#include "clutter-debug.h"
#include "clutter-device-manager-private.h"
#include "clutter-event-private.h"
#include "clutter-feature.h"
#include "clutter-input-device-private.h"
#include "clutter-input-pointer-a11y-private.h"
#include "clutter-graphene.h"
#include "clutter-main.h"
#include "clutter-master-clock.h"
#include "clutter-mutter.h"
#include "clutter-paint-node-private.h"
#include "clutter-private.h"
#include "clutter-settings-private.h"
#include "clutter-stage-manager.h"
@@ -970,6 +971,9 @@ clutter_init_real (GError **error)
if (clutter_enable_accessibility)
cally_accessibility_init ();
/* Initialize types required for paint nodes */
_clutter_paint_node_init_types ();
return CLUTTER_INIT_SUCCESS;
}
@@ -1523,7 +1527,7 @@ event_click_count_generate (ClutterEvent *event)
previous_y = event->button.y;
previous_time = event->button.time;
/* fallthrough */
G_GNUC_FALLTHROUGH;
case CLUTTER_BUTTON_RELEASE:
event->button.click_count = click_count;
break;
@@ -1776,7 +1780,7 @@ _clutter_process_event_details (ClutterActor *stage,
emit_crossing_event (event, device);
actor = _clutter_input_device_update (device, NULL, FALSE);
actor = clutter_input_device_update (device, NULL, FALSE);
if (actor != stage)
{
ClutterEvent *crossing;
@@ -1834,13 +1838,10 @@ _clutter_process_event_details (ClutterActor *stage,
{
if (_clutter_is_input_pointer_a11y_enabled (device))
{
ClutterInputDevice *core_pointer;
gfloat x, y;
clutter_event_get_coords (event, &x, &y);
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_on_motion_event (core_pointer, x, y);
_clutter_input_pointer_a11y_on_motion_event (device, x, y);
}
}
#endif /* CLUTTER_WINDOWING_X11 */
@@ -1871,7 +1872,7 @@ _clutter_process_event_details (ClutterActor *stage,
break;
}
/* fallthrough from motion */
G_GNUC_FALLTHROUGH;
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
#ifdef CLUTTER_WINDOWING_X11
@@ -1879,12 +1880,7 @@ _clutter_process_event_details (ClutterActor *stage,
{
if (_clutter_is_input_pointer_a11y_enabled (device) && (event->type != CLUTTER_MOTION))
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
CLUTTER_POINTER_DEVICE);
_clutter_input_pointer_a11y_on_button_event (core_pointer,
_clutter_input_pointer_a11y_on_button_event (device,
event->button.button,
event->type == CLUTTER_BUTTON_PRESS);
}
@@ -1943,7 +1939,7 @@ _clutter_process_event_details (ClutterActor *stage,
* get the actor underneath
*/
if (device != NULL)
actor = _clutter_input_device_update (device, NULL, TRUE);
actor = clutter_input_device_update (device, NULL, TRUE);
else
{
CLUTTER_NOTE (EVENT, "No device found: picking");
@@ -2016,7 +2012,7 @@ _clutter_process_event_details (ClutterActor *stage,
break;
}
/* fallthrough from motion */
G_GNUC_FALLTHROUGH;
case CLUTTER_TOUCH_BEGIN:
case CLUTTER_TOUCH_CANCEL:
case CLUTTER_TOUCH_END:
@@ -2060,7 +2056,7 @@ _clutter_process_event_details (ClutterActor *stage,
}
if (device != NULL)
actor = _clutter_input_device_update (device, sequence, TRUE);
actor = clutter_input_device_update (device, sequence, TRUE);
else
{
CLUTTER_NOTE (EVENT, "No device found: picking");

View File

@@ -31,6 +31,8 @@
#include "clutter-build-config.h"
#include <cogl/cogl.h>
#include "clutter-master-clock.h"
#include "clutter-master-clock-default.h"
#include "clutter-debug.h"
@@ -188,6 +190,26 @@ master_clock_get_swap_wait_time (ClutterMasterClockDefault *master_clock)
}
}
static int64_t
master_clock_get_next_presentation_time (ClutterMasterClockDefault *master_clock)
{
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
const GSList *stages, *l;
int64_t earliest = -1;
stages = clutter_stage_manager_peek_stages (stage_manager);
for (l = stages; l != NULL; l = l->next)
{
gint64 t = _clutter_stage_get_next_presentation_time (l->data);
if (earliest == -1 || (t != -1 && t < earliest))
earliest = t;
}
return earliest;
}
static void
master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock)
{
@@ -461,8 +483,14 @@ clutter_clock_dispatch (GSource *source,
_clutter_threads_acquire_lock ();
COGL_TRACE_BEGIN (ClutterMasterClockTick, "Master Clock (tick)");
/* Get the time to use for this frame */
master_clock->cur_tick = g_source_get_time (source);
master_clock->cur_tick = master_clock_get_next_presentation_time (master_clock);
/* On the first frame the backend might not have an answer */
if (master_clock->cur_tick <= 0)
master_clock->cur_tick = g_source_get_time (source);
#ifdef CLUTTER_ENABLE_DEBUG
master_clock->remaining_budget = master_clock->frame_budget;
@@ -492,6 +520,8 @@ clutter_clock_dispatch (GSource *source,
g_slist_free_full (stages, g_object_unref);
COGL_TRACE_END (ClutterMasterClockTick);
_clutter_threads_release_lock ();
return TRUE;

View File

@@ -26,10 +26,11 @@
#define __CLUTTER_H_INSIDE__
#include "clutter-backend.h"
#include "clutter-device-manager-private.h"
#include "clutter-event-private.h"
#include "clutter-input-device-private.h"
#include "clutter-input-pointer-a11y-private.h"
#include "clutter-macros.h"
#include "clutter-paint-context-private.h"
#include "clutter-private.h"
#include "clutter-stage-private.h"
#include "clutter-stage-view.h"
@@ -48,6 +49,23 @@ void clutter_stage_capture_into (ClutterStage *stage,
cairo_rectangle_int_t *rect,
uint8_t *data);
CLUTTER_EXPORT
void clutter_stage_paint_to_framebuffer (ClutterStage *stage,
CoglFramebuffer *framebuffer,
const cairo_rectangle_int_t *rect,
float scale,
ClutterPaintFlag paint_flags);
CLUTTER_EXPORT
gboolean clutter_stage_paint_to_buffer (ClutterStage *stage,
const cairo_rectangle_int_t *rect,
float scale,
uint8_t *data,
int stride,
CoglPixelFormat format,
ClutterPaintFlag paint_flags,
GError **error);
CLUTTER_EXPORT
void clutter_stage_freeze_updates (ClutterStage *stage);

View File

@@ -118,11 +118,7 @@ clutter_offscreen_effect_set_actor (ClutterActorMeta *meta,
meta_class->set_actor (meta, actor);
/* clear out the previous state */
if (priv->offscreen != NULL)
{
cogl_object_unref (priv->offscreen);
priv->offscreen = NULL;
}
g_clear_pointer (&priv->offscreen, cogl_object_unref);
/* we keep a back pointer here, to avoid going through the ActorMeta */
priv->actor = clutter_actor_meta_get_actor (meta);
@@ -198,17 +194,8 @@ update_fbo (ClutterEffect *effect,
ensure_pipeline_filter_for_scale (self, resource_scale);
}
if (priv->texture != NULL)
{
cogl_object_unref (priv->texture);
priv->texture = NULL;
}
if (priv->offscreen != NULL)
{
cogl_object_unref (priv->offscreen);
priv->offscreen = NULL;
}
g_clear_pointer (&priv->texture, cogl_object_unref);
g_clear_pointer (&priv->offscreen, cogl_object_unref);
priv->texture =
clutter_offscreen_effect_create_texture (self, target_width, target_height);
@@ -482,34 +469,56 @@ clutter_offscreen_effect_paint (ClutterEffect *effect,
ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
ClutterOffscreenEffectPrivate *priv = self->priv;
if (flags & CLUTTER_EFFECT_PAINT_BYPASS_EFFECT)
{
clutter_actor_continue_paint (priv->actor, paint_context);
cogl_clear_object (&priv->offscreen);
return;
}
/* If we've already got a cached image and the actor hasn't been redrawn
* then we can just use the cached image in the FBO.
*/
if (priv->offscreen == NULL || (flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY))
{
/* Chain up to the parent paint method which will call the pre and
post paint functions to update the image */
CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class)->
paint (effect, paint_context, flags);
ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect);
gboolean pre_paint_succeeded;
pre_paint_succeeded = effect_class->pre_paint (effect, paint_context);
clutter_actor_continue_paint (priv->actor, paint_context);
if (pre_paint_succeeded)
effect_class->post_paint (effect, paint_context);
else
g_clear_pointer (&priv->offscreen, cogl_object_unref);
}
else
clutter_offscreen_effect_paint_texture (self, paint_context);
}
static void
clutter_offscreen_effect_notify (GObject *gobject,
GParamSpec *pspec)
{
ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (gobject);
ClutterOffscreenEffectPrivate *priv = offscreen_effect->priv;
if (strcmp (pspec->name, "enabled") == 0)
g_clear_pointer (&priv->offscreen, cogl_object_unref);
G_OBJECT_CLASS (clutter_offscreen_effect_parent_class)->notify (gobject, pspec);
}
static void
clutter_offscreen_effect_finalize (GObject *gobject)
{
ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (gobject);
ClutterOffscreenEffectPrivate *priv = self->priv;
if (priv->offscreen)
cogl_object_unref (priv->offscreen);
if (priv->target)
cogl_object_unref (priv->target);
if (priv->texture)
cogl_object_unref (priv->texture);
g_clear_pointer (&priv->offscreen, cogl_object_unref);
g_clear_pointer (&priv->texture, cogl_object_unref);
g_clear_pointer (&priv->target, cogl_object_unref);
G_OBJECT_CLASS (clutter_offscreen_effect_parent_class)->finalize (gobject);
}
@@ -531,6 +540,7 @@ clutter_offscreen_effect_class_init (ClutterOffscreenEffectClass *klass)
effect_class->paint = clutter_offscreen_effect_paint;
gobject_class->finalize = clutter_offscreen_effect_finalize;
gobject_class->notify = clutter_offscreen_effect_notify;
}
static void

View File

@@ -20,10 +20,22 @@
#include "clutter-paint-context.h"
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view);
typedef enum _ClutterPaintFlag
{
CLUTTER_PAINT_FLAG_NONE = 0,
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 1,
} ClutterPaintFlag;
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
const cairo_region_t *redraw_clip,
ClutterPaintFlag paint_flags);
gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context);
CoglFramebuffer * clutter_paint_context_get_base_framebuffer (ClutterPaintContext *paint_context);
CLUTTER_EXPORT
ClutterPaintFlag clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context);
#endif /* CLUTTER_PAINT_CONTEXT_PRIVATE_H */

View File

@@ -23,9 +23,13 @@ struct _ClutterPaintContext
{
grefcount ref_count;
ClutterPaintFlag paint_flags;
GList *framebuffers;
ClutterStageView *view;
cairo_region_t *redraw_clip;
};
G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
@@ -33,7 +37,9 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
clutter_paint_context_unref)
ClutterPaintContext *
clutter_paint_context_new_for_view (ClutterStageView *view)
clutter_paint_context_new_for_view (ClutterStageView *view,
const cairo_region_t *redraw_clip,
ClutterPaintFlag paint_flags)
{
ClutterPaintContext *paint_context;
CoglFramebuffer *framebuffer;
@@ -41,6 +47,8 @@ clutter_paint_context_new_for_view (ClutterStageView *view)
paint_context = g_new0 (ClutterPaintContext, 1);
g_ref_count_init (&paint_context->ref_count);
paint_context->view = view;
paint_context->redraw_clip = cairo_region_copy (redraw_clip);
paint_context->paint_flags = paint_flags;
framebuffer = clutter_stage_view_get_framebuffer (view);
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
@@ -58,6 +66,8 @@ clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer)
paint_context = g_new0 (ClutterPaintContext, 1);
g_ref_count_init (&paint_context->ref_count);
paint_context->paint_flags = (CLUTTER_PAINT_FLAG_NO_CURSORS |
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL);
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
@@ -77,6 +87,7 @@ clutter_paint_context_dispose (ClutterPaintContext *paint_context)
g_list_free_full (paint_context->framebuffers,
cogl_object_unref);
paint_context->framebuffers = NULL;
g_clear_pointer (&paint_context->redraw_clip, cairo_region_destroy);
}
void
@@ -115,6 +126,12 @@ clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context)
paint_context->framebuffers);
}
const cairo_region_t *
clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context)
{
return paint_context->redraw_clip;
}
/**
* clutter_paint_context_get_framebuffer:
* @paint_context: The #ClutterPaintContext
@@ -159,3 +176,12 @@ clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context)
return !paint_context->view;
}
/**
* clutter_paint_context_get_paint_flags: (skip)
*/
ClutterPaintFlag
clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context)
{
return paint_context->paint_flags;
}

View File

@@ -59,4 +59,7 @@ void clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context,
CLUTTER_EXPORT
void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context);
CLUTTER_EXPORT
const cairo_region_t * clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context);
#endif /* CLUTTER_PAINT_CONTEXT_H */

View File

@@ -49,11 +49,11 @@ struct _ClutterPaintNode
ClutterPaintNode *next_sibling;
ClutterPaintNode *last_child;
guint n_children;
GArray *operations;
gchar *name;
const gchar *name;
guint n_children;
volatile int ref_count;
};

View File

@@ -171,8 +171,6 @@ clutter_paint_node_real_finalize (ClutterPaintNode *node)
{
ClutterPaintNode *iter;
g_free (node->name);
if (node->operations != NULL)
{
guint i;
@@ -297,7 +295,8 @@ clutter_paint_node_get_type (void)
*
* The @name will be used for debugging purposes.
*
* The @node will copy the passed string.
* The @node will intern @name using g_intern_string(). If you have access to a
* static string, use clutter_paint_node_set_static_name() instead.
*
* Since: 1.10
*/
@@ -307,8 +306,22 @@ clutter_paint_node_set_name (ClutterPaintNode *node,
{
g_return_if_fail (CLUTTER_IS_PAINT_NODE (node));
g_free (node->name);
node->name = g_strdup (name);
node->name = g_intern_string (name);
}
/**
* clutter_paint_node_set_static_name: (skip)
*
* Like clutter_paint_node_set_name() but uses a static or interned string
* containing the name.
*/
void
clutter_paint_node_set_static_name (ClutterPaintNode *node,
const char *name)
{
g_return_if_fail (CLUTTER_IS_PAINT_NODE (node));
node->name = name;
}
/**
@@ -1181,8 +1194,6 @@ _clutter_paint_node_create (GType gtype)
{
g_return_val_if_fail (g_type_is_a (gtype, CLUTTER_TYPE_PAINT_NODE), NULL);
_clutter_paint_node_init_types ();
return (gpointer) g_type_create_instance (gtype);
}

View File

@@ -56,6 +56,9 @@ void clutter_paint_node_paint (Clutter
CLUTTER_EXPORT
void clutter_paint_node_set_name (ClutterPaintNode *node,
const char *name);
CLUTTER_EXPORT
void clutter_paint_node_set_static_name (ClutterPaintNode *node,
const char *name);
CLUTTER_EXPORT
CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node);

View File

@@ -248,6 +248,9 @@ gboolean _clutter_util_rectangle_intersection (const cairo_rectangle_int_t *src1
const cairo_rectangle_int_t *src2,
cairo_rectangle_int_t *dest);
gboolean clutter_util_rectangle_equal (const cairo_rectangle_int_t *src1,
const cairo_rectangle_int_t *src2);
struct _ClutterVertex4
{

View File

@@ -0,0 +1,700 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2019 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#include "clutter-build-config.h"
#include "clutter-backend-private.h"
#include "clutter-input-device-tool.h"
#include "clutter-input-pointer-a11y-private.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-seat.h"
#include "clutter-virtual-input-device.h"
enum
{
DEVICE_ADDED,
DEVICE_REMOVED,
TOOL_CHANGED,
KBD_A11Y_MASK_CHANGED,
KBD_A11Y_FLAGS_CHANGED,
PTR_A11Y_DWELL_CLICK_TYPE_CHANGED,
PTR_A11Y_TIMEOUT_STARTED,
PTR_A11Y_TIMEOUT_STOPPED,
IS_UNFOCUS_INHIBITED_CHANGED,
N_SIGNALS,
};
static guint signals[N_SIGNALS] = { 0 };
enum
{
PROP_0,
PROP_BACKEND,
PROP_TOUCH_MODE,
N_PROPS
};
static GParamSpec *props[N_PROPS];
typedef struct _ClutterSeatPrivate ClutterSeatPrivate;
struct _ClutterSeatPrivate
{
ClutterBackend *backend;
unsigned int inhibit_unfocus_count;
/* Keyboard a11y */
ClutterKbdA11ySettings kbd_a11y_settings;
/* Pointer a11y */
ClutterPointerA11ySettings pointer_a11y_settings;
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterSeat, clutter_seat, G_TYPE_OBJECT)
static void
clutter_seat_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterSeat *seat = CLUTTER_SEAT (object);
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
switch (prop_id)
{
case PROP_BACKEND:
priv->backend = g_value_get_object (value);
break;
case PROP_TOUCH_MODE:
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
clutter_seat_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterSeat *seat = CLUTTER_SEAT (object);
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
switch (prop_id)
{
case PROP_BACKEND:
g_value_set_object (value, priv->backend);
break;
case PROP_TOUCH_MODE:
g_value_set_boolean (value, FALSE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
clutter_seat_finalize (GObject *object)
{
ClutterSeat *seat = CLUTTER_SEAT (object);
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
g_clear_object (&priv->backend);
G_OBJECT_CLASS (clutter_seat_parent_class)->finalize (object);
}
static void
clutter_seat_class_init (ClutterSeatClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = clutter_seat_set_property;
object_class->get_property = clutter_seat_get_property;
object_class->finalize = clutter_seat_finalize;
signals[DEVICE_ADDED] =
g_signal_new (I_("device-added"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1,
CLUTTER_TYPE_INPUT_DEVICE);
signals[DEVICE_REMOVED] =
g_signal_new (I_("device-removed"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1,
CLUTTER_TYPE_INPUT_DEVICE);
signals[TOOL_CHANGED] =
g_signal_new (I_("tool-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE, 2,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_INPUT_DEVICE_TOOL);
g_signal_set_va_marshaller (signals[TOOL_CHANGED],
G_TYPE_FROM_CLASS (object_class),
_clutter_marshal_VOID__OBJECT_OBJECTv);
/**
* ClutterSeat::kbd-a11y-mods-state-changed:
* @seat: the #ClutterSeat that emitted the signal
* @latched_mask: the latched modifier mask from stickykeys
* @locked_mask: the locked modifier mask from stickykeys
*
* The ::kbd-a11y-mods-state-changed signal is emitted each time either the
* latched modifiers mask or locked modifiers mask are changed as the
* result of keyboard accessibilty's sticky keys operations.
*/
signals[KBD_A11Y_MASK_CHANGED] =
g_signal_new (I_("kbd-a11y-mods-state-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__UINT_UINT,
G_TYPE_NONE, 2,
G_TYPE_UINT,
G_TYPE_UINT);
g_signal_set_va_marshaller (signals[KBD_A11Y_MASK_CHANGED],
G_TYPE_FROM_CLASS (object_class),
_clutter_marshal_VOID__UINT_UINTv);
/**
* ClutterSeat::kbd-a11y-flags-changed:
* @seat: the #ClutterSeat that emitted the signal
* @settings_flags: the new ClutterKeyboardA11yFlags configuration
* @changed_mask: the ClutterKeyboardA11yFlags changed
*
* The ::kbd-a11y-flags-changed signal is emitted each time the
* ClutterKeyboardA11yFlags configuration is changed as the result of
* keyboard accessibility operations.
*/
signals[KBD_A11Y_FLAGS_CHANGED] =
g_signal_new (I_("kbd-a11y-flags-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__UINT_UINT,
G_TYPE_NONE, 2,
G_TYPE_UINT,
G_TYPE_UINT);
g_signal_set_va_marshaller (signals[KBD_A11Y_FLAGS_CHANGED],
G_TYPE_FROM_CLASS (object_class),
_clutter_marshal_VOID__UINT_UINTv);
/**
* ClutterSeat::ptr-a11y-dwell-click-type-changed:
* @seat: the #ClutterSeat that emitted the signal
* @click_type: the new #ClutterPointerA11yDwellClickType mode
*
* The ::ptr-a11y-dwell-click-type-changed signal is emitted each time
* the ClutterPointerA11yDwellClickType mode is changed as the result
* of pointer accessibility operations.
*/
signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] =
g_signal_new (I_("ptr-a11y-dwell-click-type-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1,
CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE);
/**
* ClutterSeat::ptr-a11y-timeout-started:
* @seat: the #ClutterSeat that emitted the signal
* @device: the core pointer #ClutterInputDevice
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
* @delay: the delay in ms before secondary-click is triggered.
*
* The ::ptr-a11y-timeout-started signal is emitted when a
* pointer accessibility timeout delay is started, so that upper
* layers can notify the user with some visual feedback.
*/
signals[PTR_A11Y_TIMEOUT_STARTED] =
g_signal_new (I_("ptr-a11y-timeout-started"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_FLAGS_UINT,
G_TYPE_NONE, 3,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
G_TYPE_UINT);
g_signal_set_va_marshaller (signals[PTR_A11Y_TIMEOUT_STARTED],
G_TYPE_FROM_CLASS (object_class),
_clutter_marshal_VOID__OBJECT_FLAGS_UINTv);
/**
* ClutterSeat::ptr-a11y-timeout-stopped:
* @seat: the #ClutterSeat that emitted the signal
* @device: the core pointer #ClutterInputDevice
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
* @clicked: %TRUE if the timeout finished and triggered a click
*
* The ::ptr-a11y-timeout-stopped signal is emitted when a running
* pointer accessibility timeout delay is stopped, either because
* it's triggered at the end of the delay or cancelled, so that
* upper layers can notify the user with some visual feedback.
*/
signals[PTR_A11Y_TIMEOUT_STOPPED] =
g_signal_new (I_("ptr-a11y-timeout-stopped"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_clutter_marshal_VOID__OBJECT_FLAGS_BOOLEAN,
G_TYPE_NONE, 3,
CLUTTER_TYPE_INPUT_DEVICE,
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
G_TYPE_BOOLEAN);
g_signal_set_va_marshaller (signals[PTR_A11Y_TIMEOUT_STOPPED],
G_TYPE_FROM_CLASS (object_class),
_clutter_marshal_VOID__OBJECT_FLAGS_BOOLEANv);
/**
* ClutterSeat::is-unfocus-inhibited-changed:
* @seat: the #ClutterSeat that emitted the signal
*
* The ::is-unfocus-inhibited-changed signal is emitted when the
* property to inhibit the unsetting of the focus-surface of the
* #ClutterSeat changed. To get the current state of this property,
* use clutter_seat_is_unfocus_inhibited().
*/
signals[IS_UNFOCUS_INHIBITED_CHANGED] =
g_signal_new (I_("is-unfocus-inhibited-changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
props[PROP_BACKEND] =
g_param_spec_object ("backend",
P_("Backend"),
P_("Backend"),
CLUTTER_TYPE_BACKEND,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
/**
* ClutterSeat:touch-mode:
*
* The current touch-mode of the #ClutterSeat, it is set to %TRUE if the
* requirements documented in clutter_seat_get_touch_mode() are fulfilled.
**/
props[PROP_TOUCH_MODE] =
g_param_spec_boolean ("touch-mode",
P_("Touch mode"),
P_("Touch mode"),
FALSE,
CLUTTER_PARAM_READABLE);
g_object_class_install_properties (object_class, N_PROPS, props);
}
static void
clutter_seat_init (ClutterSeat *seat)
{
}
/**
* clutter_seat_get_pointer:
* @seat: a #ClutterSeat
*
* Returns the master pointer
*
* Returns: (transfer none): the master pointer
**/
ClutterInputDevice *
clutter_seat_get_pointer (ClutterSeat *seat)
{
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL);
return CLUTTER_SEAT_GET_CLASS (seat)->get_pointer (seat);
}
/**
* clutter_seat_get_keyboard:
* @seat: a #ClutterSeat
*
* Returns the master keyboard
*
* Returns: (transfer none): the master keyboard
**/
ClutterInputDevice *
clutter_seat_get_keyboard (ClutterSeat *seat)
{
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL);
return CLUTTER_SEAT_GET_CLASS (seat)->get_keyboard (seat);
}
/**
* clutter_seat_list_devices:
* @seat: a #ClutterSeat
*
* Returns the list of HW devices
*
* Returns: (transfer container) (element-type Clutter.InputDevice): A list
* of #ClutterInputDevice. The elements of the returned list are owned by
* Clutter and may not be freed, the returned list should be freed using
* g_list_free() when done.
**/
GList *
clutter_seat_list_devices (ClutterSeat *seat)
{
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL);
return CLUTTER_SEAT_GET_CLASS (seat)->list_devices (seat);
}
void
clutter_seat_bell_notify (ClutterSeat *seat)
{
CLUTTER_SEAT_GET_CLASS (seat)->bell_notify (seat);
}
/**
* clutter_seat_get_keymap:
* @seat: a #ClutterSeat
*
* Returns the seat keymap
*
* Returns: (transfer none): the seat keymap
**/
ClutterKeymap *
clutter_seat_get_keymap (ClutterSeat *seat)
{
return CLUTTER_SEAT_GET_CLASS (seat)->get_keymap (seat);
}
static gboolean
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
ClutterKbdA11ySettings *b)
{
return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0);
}
void
clutter_seat_set_kbd_a11y_settings (ClutterSeat *seat,
ClutterKbdA11ySettings *settings)
{
ClutterSeatClass *seat_class;
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
g_return_if_fail (CLUTTER_IS_SEAT (seat));
if (are_kbd_a11y_settings_equal (&priv->kbd_a11y_settings, settings))
return;
priv->kbd_a11y_settings = *settings;
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
if (seat_class->apply_kbd_a11y_settings)
seat_class->apply_kbd_a11y_settings (seat, settings);
}
void
clutter_seat_get_kbd_a11y_settings (ClutterSeat *seat,
ClutterKbdA11ySettings *settings)
{
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
g_return_if_fail (CLUTTER_IS_SEAT (seat));
*settings = priv->kbd_a11y_settings;
}
void
clutter_seat_ensure_a11y_state (ClutterSeat *seat)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_seat_get_pointer (seat);
if (core_pointer)
{
if (_clutter_is_input_pointer_a11y_enabled (core_pointer))
_clutter_input_pointer_a11y_add_device (core_pointer);
}
}
static gboolean
are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a,
ClutterPointerA11ySettings *b)
{
return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0);
}
static void
clutter_seat_enable_pointer_a11y (ClutterSeat *seat)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_seat_get_pointer (seat);
_clutter_input_pointer_a11y_add_device (core_pointer);
}
static void
clutter_seat_disable_pointer_a11y (ClutterSeat *seat)
{
ClutterInputDevice *core_pointer;
core_pointer = clutter_seat_get_pointer (seat);
_clutter_input_pointer_a11y_remove_device (core_pointer);
}
/**
* clutter_seat_set_pointer_a11y_settings:
* @seat: a #ClutterSeat
* @settings: a pointer to a #ClutterPointerA11ySettings
*
* Sets the pointer accessibility settings
**/
void
clutter_seat_set_pointer_a11y_settings (ClutterSeat *seat,
ClutterPointerA11ySettings *settings)
{
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
g_return_if_fail (CLUTTER_IS_SEAT (seat));
if (are_pointer_a11y_settings_equal (&priv->pointer_a11y_settings, settings))
return;
if (priv->pointer_a11y_settings.controls == 0 && settings->controls != 0)
clutter_seat_enable_pointer_a11y (seat);
else if (priv->pointer_a11y_settings.controls != 0 && settings->controls == 0)
clutter_seat_disable_pointer_a11y (seat);
priv->pointer_a11y_settings = *settings;
}
/**
* clutter_seat_get_pointer_a11y_settings:
* @seat: a #ClutterSeat
* @settings: a pointer to a #ClutterPointerA11ySettings
*
* Gets the current pointer accessibility settings
**/
void
clutter_seat_get_pointer_a11y_settings (ClutterSeat *seat,
ClutterPointerA11ySettings *settings)
{
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
g_return_if_fail (CLUTTER_IS_SEAT (seat));
*settings = priv->pointer_a11y_settings;
}
/**
* clutter_seat_set_pointer_a11y_dwell_click_type:
* @seat: a #ClutterSeat
* @click_type: type of click as #ClutterPointerA11yDwellClickType
*
* Sets the dwell click type
**/
void
clutter_seat_set_pointer_a11y_dwell_click_type (ClutterSeat *seat,
ClutterPointerA11yDwellClickType click_type)
{
ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat);
g_return_if_fail (CLUTTER_IS_SEAT (seat));
priv->pointer_a11y_settings.dwell_click_type = click_type;
}
/**
* clutter_seat_inhibit_unfocus:
* @seat: a #ClutterSeat
*
* Inhibits unsetting of the pointer focus-surface for the #ClutterSeat @seat,
* this allows to keep using the pointer even when it's hidden.
*
* This property is refcounted, so clutter_seat_uninhibit_unfocus() must be
* called the exact same number of times as clutter_seat_inhibit_unfocus()
* was called before.
**/
void
clutter_seat_inhibit_unfocus (ClutterSeat *seat)
{
ClutterSeatPrivate *priv;
g_return_if_fail (CLUTTER_IS_SEAT (seat));
priv = clutter_seat_get_instance_private (seat);
priv->inhibit_unfocus_count++;
if (priv->inhibit_unfocus_count == 1)
g_signal_emit (G_OBJECT (seat), signals[IS_UNFOCUS_INHIBITED_CHANGED], 0);
}
/**
* clutter_seat_uninhibit_unfocus:
* @seat: a #ClutterSeat
*
* Disables the inhibiting of unsetting of the pointer focus-surface
* previously enabled by calling clutter_seat_inhibit_unfocus().
*
* This property is refcounted, so clutter_seat_uninhibit_unfocus() must be
* called the exact same number of times as clutter_seat_inhibit_unfocus()
* was called before.
**/
void
clutter_seat_uninhibit_unfocus (ClutterSeat *seat)
{
ClutterSeatPrivate *priv;
g_return_if_fail (CLUTTER_IS_SEAT (seat));
priv = clutter_seat_get_instance_private (seat);
if (priv->inhibit_unfocus_count == 0)
{
g_warning ("Called clutter_seat_uninhibit_unfocus without inhibiting before");
return;
}
priv->inhibit_unfocus_count--;
if (priv->inhibit_unfocus_count == 0)
g_signal_emit (G_OBJECT (seat), signals[IS_UNFOCUS_INHIBITED_CHANGED], 0);
}
/**
* clutter_seat_is_unfocus_inhibited:
* @seat: a #ClutterSeat
*
* Gets whether unsetting of the pointer focus-surface is inhibited
* for the #ClutterSeat @seat.
*
* Returns: %TRUE if unsetting is inhibited, %FALSE otherwise
**/
gboolean
clutter_seat_is_unfocus_inhibited (ClutterSeat *seat)
{
ClutterSeatPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE);
priv = clutter_seat_get_instance_private (seat);
return priv->inhibit_unfocus_count > 0;
}
/**
* clutter_seat_create_virtual_device:
* @seat: a #ClutterSeat
* @device_type: the type of the virtual device
*
* Creates a virtual input device.
*
* Returns: (transfer full): a newly created virtual device
**/
ClutterVirtualInputDevice *
clutter_seat_create_virtual_device (ClutterSeat *seat,
ClutterInputDeviceType device_type)
{
ClutterSeatClass *seat_class;
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL);
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
return seat_class->create_virtual_device (seat, device_type);
}
/**
* clutter_seat_supported_virtual_device_types: (skip)
*/
ClutterVirtualDeviceType
clutter_seat_get_supported_virtual_device_types (ClutterSeat *seat)
{
ClutterSeatClass *seat_class;
g_return_val_if_fail (CLUTTER_IS_SEAT (seat),
CLUTTER_VIRTUAL_DEVICE_TYPE_NONE);
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
return seat_class->get_supported_virtual_device_types (seat);
}
void
clutter_seat_compress_motion (ClutterSeat *seat,
ClutterEvent *event,
const ClutterEvent *to_discard)
{
ClutterSeatClass *seat_class;
g_return_if_fail (CLUTTER_IS_SEAT (seat));
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
if (seat_class->compress_motion)
seat_class->compress_motion (seat, event, to_discard);
}
void
clutter_seat_warp_pointer (ClutterSeat *seat,
int x,
int y)
{
g_return_if_fail (CLUTTER_IS_SEAT (seat));
CLUTTER_SEAT_GET_CLASS (seat)->warp_pointer (seat, x, y);
}
/**
* clutter_seat_get_touch_mode:
* @seat: a #ClutterSeat
*
* Gets the current touch-mode state of the #ClutterSeat @seat.
* The #ClutterSeat:touch-mode property is set to %TRUE if the following
* requirements are fulfilled:
*
* - A touchscreen is available
* - A tablet mode switch, if present, is enabled
*
* Returns: %TRUE if the device is a tablet that doesn't have an external
* keyboard attached, %FALSE otherwise.
**/
gboolean
clutter_seat_get_touch_mode (ClutterSeat *seat)
{
gboolean touch_mode;
g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE);
g_object_get (G_OBJECT (seat), "touch-mode", &touch_mode, NULL);
return touch_mode;
}

View File

@@ -0,0 +1,190 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2019 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#ifndef CLUTTER_SEAT_H
#define CLUTTER_SEAT_H
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#include "clutter/clutter-types.h"
#include "clutter/clutter-keymap.h"
#include "clutter/clutter-virtual-input-device.h"
#define CLUTTER_TYPE_SEAT (clutter_seat_get_type ())
CLUTTER_EXPORT
G_DECLARE_DERIVABLE_TYPE (ClutterSeat, clutter_seat,
CLUTTER, SEAT, GObject)
/**
* ClutterKbdA11ySettings:
*
* The #ClutterKbdA11ySettings structure contains keyboard accessibility
* settings
*
*/
typedef struct _ClutterKbdA11ySettings
{
ClutterKeyboardA11yFlags controls;
gint slowkeys_delay;
gint debounce_delay;
gint timeout_delay;
gint mousekeys_init_delay;
gint mousekeys_max_speed;
gint mousekeys_accel_time;
} ClutterKbdA11ySettings;
/**
* ClutterPointerA11ySettings:
*
* The #ClutterPointerA11ySettings structure contains pointer accessibility
* settings
*
*/
typedef struct _ClutterPointerA11ySettings
{
ClutterPointerA11yFlags controls;
ClutterPointerA11yDwellClickType dwell_click_type;
ClutterPointerA11yDwellMode dwell_mode;
ClutterPointerA11yDwellDirection dwell_gesture_single;
ClutterPointerA11yDwellDirection dwell_gesture_double;
ClutterPointerA11yDwellDirection dwell_gesture_drag;
ClutterPointerA11yDwellDirection dwell_gesture_secondary;
gint secondary_click_delay;
gint dwell_delay;
gint dwell_threshold;
} ClutterPointerA11ySettings;
/**
* ClutterVirtualDeviceType:
*/
typedef enum
{
CLUTTER_VIRTUAL_DEVICE_TYPE_NONE = 0,
CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD = 1 << 0,
CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER = 1 << 1,
CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN = 1 << 2,
} ClutterVirtualDeviceType;
typedef struct _ClutterSeatClass ClutterSeatClass;
struct _ClutterSeatClass
{
GObjectClass parent_class;
ClutterInputDevice * (* get_pointer) (ClutterSeat *seat);
ClutterInputDevice * (* get_keyboard) (ClutterSeat *seat);
GList * (* list_devices) (ClutterSeat *seat);
void (* bell_notify) (ClutterSeat *seat);
ClutterKeymap * (* get_keymap) (ClutterSeat *seat);
void (* compress_motion) (ClutterSeat *seat,
ClutterEvent *event,
const ClutterEvent *to_discard);
void (* warp_pointer) (ClutterSeat *seat,
int x,
int y);
/* Event platform data */
void (* copy_event_data) (ClutterSeat *seat,
const ClutterEvent *src,
ClutterEvent *dest);
void (* free_event_data) (ClutterSeat *seat,
ClutterEvent *event);
/* Keyboard accessibility */
void (* apply_kbd_a11y_settings) (ClutterSeat *seat,
ClutterKbdA11ySettings *settings);
/* Virtual devices */
ClutterVirtualInputDevice * (* create_virtual_device) (ClutterSeat *seat,
ClutterInputDeviceType device_type);
ClutterVirtualDeviceType (* get_supported_virtual_device_types) (ClutterSeat *seat);
};
CLUTTER_EXPORT
ClutterInputDevice * clutter_seat_get_pointer (ClutterSeat *seat);
CLUTTER_EXPORT
ClutterInputDevice * clutter_seat_get_keyboard (ClutterSeat *seat);
CLUTTER_EXPORT
GList * clutter_seat_list_devices (ClutterSeat *seat);
CLUTTER_EXPORT
void clutter_seat_bell_notify (ClutterSeat *seat);
CLUTTER_EXPORT
ClutterKeymap * clutter_seat_get_keymap (ClutterSeat *seat);
CLUTTER_EXPORT
void clutter_seat_set_kbd_a11y_settings (ClutterSeat *seat,
ClutterKbdA11ySettings *settings);
CLUTTER_EXPORT
void clutter_seat_get_kbd_a11y_settings (ClutterSeat *seat,
ClutterKbdA11ySettings *settings);
CLUTTER_EXPORT
void clutter_seat_ensure_a11y_state (ClutterSeat *seat);
CLUTTER_EXPORT
void clutter_seat_set_pointer_a11y_settings (ClutterSeat *seat,
ClutterPointerA11ySettings *settings);
CLUTTER_EXPORT
void clutter_seat_get_pointer_a11y_settings (ClutterSeat *seat,
ClutterPointerA11ySettings *settings);
CLUTTER_EXPORT
void clutter_seat_set_pointer_a11y_dwell_click_type (ClutterSeat *seat,
ClutterPointerA11yDwellClickType click_type);
CLUTTER_EXPORT
void clutter_seat_inhibit_unfocus (ClutterSeat *seat);
CLUTTER_EXPORT
void clutter_seat_uninhibit_unfocus (ClutterSeat *seat);
CLUTTER_EXPORT
gboolean clutter_seat_is_unfocus_inhibited (ClutterSeat *seat);
CLUTTER_EXPORT
ClutterVirtualInputDevice *clutter_seat_create_virtual_device (ClutterSeat *seat,
ClutterInputDeviceType device_type);
CLUTTER_EXPORT
ClutterVirtualDeviceType clutter_seat_get_supported_virtual_device_types (ClutterSeat *seat);
void clutter_seat_compress_motion (ClutterSeat *seat,
ClutterEvent *event,
const ClutterEvent *to_discard);
CLUTTER_EXPORT
void clutter_seat_warp_pointer (ClutterSeat *seat,
int x,
int y);
CLUTTER_EXPORT
gboolean clutter_seat_get_touch_mode (ClutterSeat *seat);
#endif /* CLUTTER_SEAT_H */

View File

@@ -367,24 +367,12 @@ clutter_shader_effect_try_static_source (ClutterShaderEffect *self)
CLUTTER_NOTE (SHADER, "Compiling shader effect");
cogl_shader_compile (class_priv->shader);
class_priv->program = cogl_create_program ();
if (cogl_shader_is_compiled (class_priv->shader))
{
class_priv->program = cogl_create_program ();
cogl_program_attach_shader (class_priv->program,
class_priv->shader);
cogl_program_attach_shader (class_priv->program,
class_priv->shader);
cogl_program_link (class_priv->program);
}
else
{
gchar *log_buf = cogl_shader_get_info_log (class_priv->shader);
g_warning (G_STRLOC ": Unable to compile the GLSL shader: %s", log_buf);
g_free (log_buf);
}
cogl_program_link (class_priv->program);
}
priv->shader = cogl_object_ref (class_priv->shader);
@@ -902,23 +890,11 @@ clutter_shader_effect_set_shader_source (ClutterShaderEffect *effect,
CLUTTER_NOTE (SHADER, "Compiling shader effect");
cogl_shader_compile (priv->shader);
priv->program = cogl_create_program ();
if (cogl_shader_is_compiled (priv->shader))
{
priv->program = cogl_create_program ();
cogl_program_attach_shader (priv->program, priv->shader);
cogl_program_attach_shader (priv->program, priv->shader);
cogl_program_link (priv->program);
}
else
{
gchar *log_buf = cogl_shader_get_info_log (priv->shader);
g_warning (G_STRLOC ": Unable to compile the GLSL shader: %s", log_buf);
g_free (log_buf);
}
cogl_program_link (priv->program);
return TRUE;
}

View File

@@ -36,9 +36,9 @@ typedef struct _ClutterStageQueueRedrawEntry ClutterStageQueueRedrawEntry;
/* stage */
ClutterStageWindow *_clutter_stage_get_default_window (void);
void _clutter_stage_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_rectangle_int_t *clip);
void clutter_stage_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_region_t *redraw_clip);
void _clutter_stage_emit_after_paint (ClutterStage *stage);
@@ -78,6 +78,7 @@ void _clutter_stage_schedule_update (ClutterStage *stage);
gint64 _clutter_stage_get_update_time (ClutterStage *stage);
void _clutter_stage_clear_update_time (ClutterStage *stage);
gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage);
int64_t _clutter_stage_get_next_presentation_time (ClutterStage *stage);
void clutter_stage_log_pick (ClutterStage *stage,
const graphene_point_t *vertices,
@@ -141,6 +142,9 @@ void _clutter_stage_presented (ClutterStage *stag
GList * _clutter_stage_peek_stage_views (ClutterStage *stage);
void clutter_stage_queue_actor_relayout (ClutterStage *stage,
ClutterActor *actor);
G_END_DECLS
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */

View File

@@ -20,8 +20,7 @@
#include "clutter/clutter-stage-view.h"
void clutter_stage_view_after_paint (ClutterStageView *view,
const cairo_rectangle_int_t *clip);
void clutter_stage_view_after_paint (ClutterStageView *view);
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
@@ -33,7 +32,15 @@ gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
gboolean dirty);
void clutter_stage_view_add_redraw_clip (ClutterStageView *view,
cairo_rectangle_int_t *clip);
void clutter_stage_view_add_redraw_clip (ClutterStageView *view,
const cairo_rectangle_int_t *clip);
gboolean clutter_stage_view_has_full_redraw_clip (ClutterStageView *view);
gboolean clutter_stage_view_has_redraw_clip (ClutterStageView *view);
const cairo_region_t * clutter_stage_view_peek_redraw_clip (ClutterStageView *view);
cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view);
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */

View File

@@ -23,6 +23,8 @@
#include <cairo-gobject.h>
#include <math.h>
#include "clutter/clutter-private.h"
enum
{
PROP_0,
@@ -50,6 +52,9 @@ typedef struct _ClutterStageViewPrivate
CoglOffscreen *shadowfb;
CoglPipeline *shadowfb_pipeline;
gboolean has_redraw_clip;
cairo_region_t *redraw_clip;
guint dirty_viewport : 1;
guint dirty_projection : 1;
} ClutterStageViewPrivate;
@@ -166,12 +171,11 @@ clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view)
}
static void
clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
const cairo_rectangle_int_t *rect,
CoglPipeline *pipeline,
CoglFramebuffer *src_framebuffer,
CoglFramebuffer *dst_framebuffer,
gboolean can_blit)
clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
CoglPipeline *pipeline,
CoglFramebuffer *src_framebuffer,
CoglFramebuffer *dst_framebuffer,
gboolean can_blit)
{
CoglMatrix matrix;
@@ -204,8 +208,7 @@ clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
}
void
clutter_stage_view_after_paint (ClutterStageView *view,
const cairo_rectangle_int_t *rect)
clutter_stage_view_after_paint (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
@@ -222,7 +225,6 @@ clutter_stage_view_after_paint (ClutterStageView *view,
if (priv->shadowfb)
{
clutter_stage_view_copy_to_framebuffer (view,
rect,
priv->offscreen_pipeline,
priv->offscreen,
priv->shadowfb,
@@ -231,7 +233,6 @@ clutter_stage_view_after_paint (ClutterStageView *view,
else
{
clutter_stage_view_copy_to_framebuffer (view,
rect,
priv->offscreen_pipeline,
priv->offscreen,
priv->framebuffer,
@@ -243,7 +244,6 @@ clutter_stage_view_after_paint (ClutterStageView *view,
{
clutter_stage_view_ensure_shadowfb_blit_pipeline (view);
clutter_stage_view_copy_to_framebuffer (view,
rect,
priv->shadowfb_pipeline,
priv->shadowfb,
priv->framebuffer,
@@ -307,6 +307,86 @@ clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view,
view_class->get_offscreen_transformation_matrix (view, matrix);
}
void
clutter_stage_view_add_redraw_clip (ClutterStageView *view,
const cairo_rectangle_int_t *clip)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
if (priv->has_redraw_clip && !priv->redraw_clip)
return;
if (!clip)
{
g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
priv->has_redraw_clip = TRUE;
return;
}
if (clip->width == 0 || clip->height == 0)
return;
if (!priv->redraw_clip)
{
if (!clutter_util_rectangle_equal (&priv->layout, clip))
priv->redraw_clip = cairo_region_create_rectangle (clip);
}
else
{
cairo_region_union_rectangle (priv->redraw_clip, clip);
if (cairo_region_num_rectangles (priv->redraw_clip) == 1)
{
cairo_rectangle_int_t redraw_clip_extents;
cairo_region_get_extents (priv->redraw_clip, &redraw_clip_extents);
if (clutter_util_rectangle_equal (&priv->layout, &redraw_clip_extents))
g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
}
}
priv->has_redraw_clip = TRUE;
}
gboolean
clutter_stage_view_has_redraw_clip (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return priv->has_redraw_clip;
}
gboolean
clutter_stage_view_has_full_redraw_clip (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return priv->has_redraw_clip && !priv->redraw_clip;
}
const cairo_region_t *
clutter_stage_view_peek_redraw_clip (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return priv->redraw_clip;
}
cairo_region_t *
clutter_stage_view_take_redraw_clip (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
priv->has_redraw_clip = FALSE;
return g_steal_pointer (&priv->redraw_clip);
}
void
clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
gfloat *x,
@@ -419,6 +499,7 @@ clutter_stage_view_dispose (GObject *object)
g_clear_pointer (&priv->offscreen, cogl_object_unref);
g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
g_clear_pointer (&priv->shadowfb_pipeline, cogl_object_unref);
g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object);
}

View File

@@ -178,75 +178,20 @@ _clutter_stage_window_clear_update_time (ClutterStageWindow *window)
iface->clear_update_time (window);
}
void
_clutter_stage_window_add_redraw_clip (ClutterStageWindow *window,
cairo_rectangle_int_t *stage_clip)
int64_t
_clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window)
{
ClutterStageWindowInterface *iface;
g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 0);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->add_redraw_clip != NULL)
iface->add_redraw_clip (window, stage_clip);
}
/* Determines if the backend will clip the rendering of the next
* frame.
*
* Note: at the start of each new frame there is an implied clip that
* clips everything (i.e. nothing would be drawn) so this function
* will return True at the start of a new frame if the backend
* supports clipped redraws.
*/
gboolean
_clutter_stage_window_has_redraw_clips (ClutterStageWindow *window)
{
ClutterStageWindowInterface *iface;
/* If not implemented then just revert to the old behaviour... */
if (iface->get_next_presentation_time == NULL)
return _clutter_stage_window_get_update_time (window);
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->has_redraw_clips != NULL)
return iface->has_redraw_clips (window);
return FALSE;
}
/* Determines if the backend will discard any additional redraw clips
* and instead promote them to a full stage redraw.
*
* The ideas is that backend may have some heuristics that cause it to
* give up tracking redraw clips so this can be used to avoid the cost
* of calculating a redraw clip when we know it's going to be ignored
* anyway.
*/
gboolean
_clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window)
{
ClutterStageWindowInterface *iface;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->ignoring_redraw_clips != NULL)
return iface->ignoring_redraw_clips (window);
return TRUE;
}
cairo_region_t *
_clutter_stage_window_get_redraw_clip (ClutterStageWindow *window)
{
ClutterStageWindowInterface *iface;
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->get_redraw_clip != NULL)
return iface->get_redraw_clip (window);
return NULL;
return iface->get_next_presentation_time (window);
}
void

View File

@@ -51,12 +51,6 @@ struct _ClutterStageWindowInterface
gint64 (* get_update_time) (ClutterStageWindow *stage_window);
void (* clear_update_time) (ClutterStageWindow *stage_window);
void (* add_redraw_clip) (ClutterStageWindow *stage_window,
cairo_rectangle_int_t *stage_rectangle);
gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window);
gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window);
cairo_region_t * (* get_redraw_clip) (ClutterStageWindow *stage_window);
void (* set_accept_focus) (ClutterStageWindow *stage_window,
gboolean accept_focus);
@@ -67,6 +61,8 @@ struct _ClutterStageWindowInterface
GList *(* get_views) (ClutterStageWindow *stage_window);
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
void (* finish_frame) (ClutterStageWindow *stage_window);
int64_t (* get_next_presentation_time) (ClutterStageWindow *stage_window);
};
ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *window);
@@ -94,12 +90,6 @@ void _clutter_stage_window_schedule_update (ClutterStageWin
gint64 _clutter_stage_window_get_update_time (ClutterStageWindow *window);
void _clutter_stage_window_clear_update_time (ClutterStageWindow *window);
void _clutter_stage_window_add_redraw_clip (ClutterStageWindow *window,
cairo_rectangle_int_t *stage_clip);
gboolean _clutter_stage_window_has_redraw_clips (ClutterStageWindow *window);
gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window);
cairo_region_t * _clutter_stage_window_get_redraw_clip (ClutterStageWindow *window);
void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
gboolean accept_focus);
@@ -113,6 +103,8 @@ void _clutter_stage_window_finish_frame (ClutterStageWin
int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window);
int64_t _clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window);
G_END_DECLS
#endif /* __CLUTTER_STAGE_WINDOW_H__ */

View File

@@ -60,10 +60,10 @@
#include "clutter-color.h"
#include "clutter-container.h"
#include "clutter-debug.h"
#include "clutter-device-manager-private.h"
#include "clutter-enum-types.h"
#include "clutter-event-private.h"
#include "clutter-id-pool.h"
#include "clutter-input-device-private.h"
#include "clutter-main.h"
#include "clutter-marshal.h"
#include "clutter-master-clock.h"
@@ -78,7 +78,6 @@
#include "clutter-private.h"
#include "cogl/cogl.h"
#include "cogl/cogl-trace.h"
struct _ClutterStageQueueRedrawEntry
{
@@ -120,6 +119,8 @@ struct _ClutterStagePrivate
ClutterPlane current_clip_planes[4];
GHashTable *pending_relayouts;
unsigned int pending_relayouts_version;
GList *pending_queue_redraws;
gint sync_delay;
@@ -142,11 +143,8 @@ struct _ClutterStagePrivate
gpointer paint_data;
GDestroyNotify paint_notify;
cairo_rectangle_int_t view_clip;
int update_freeze_count;
guint relayout_pending : 1;
guint redraw_pending : 1;
guint is_cursor_visible : 1;
guint throttle_motion_events : 1;
@@ -558,6 +556,33 @@ pick_record_contains_point (ClutterStage *stage,
return TRUE;
}
static void
clutter_stage_add_redraw_clip (ClutterStage *stage,
cairo_rectangle_int_t *clip)
{
GList *l;
for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
{
ClutterStageView *view = l->data;
if (!clip)
{
clutter_stage_view_add_redraw_clip (view, NULL);
}
else
{
cairo_rectangle_int_t view_layout;
cairo_rectangle_int_t intersection;
clutter_stage_view_get_layout (view, &view_layout);
if (_clutter_util_rectangle_intersection (&view_layout, clip,
&intersection))
clutter_stage_view_add_redraw_clip (view, &intersection);
}
}
}
static inline void
queue_full_redraw (ClutterStage *stage)
{
@@ -576,7 +601,7 @@ queue_full_redraw (ClutterStage *stage)
if (stage_window == NULL)
return;
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
clutter_stage_add_redraw_clip (stage, NULL);
}
static gboolean
@@ -902,15 +927,19 @@ setup_view_for_pick_or_paint (ClutterStage *stage,
}
static void
clutter_stage_do_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_rectangle_int_t *clip)
clutter_stage_do_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_region_t *redraw_clip)
{
ClutterPaintContext *paint_context;
cairo_rectangle_int_t clip_rect;
paint_context = clutter_paint_context_new_for_view (view);
paint_context = clutter_paint_context_new_for_view (view, redraw_clip,
CLUTTER_PAINT_FLAG_NONE);
cairo_region_get_extents (redraw_clip, &clip_rect);
setup_view_for_pick_or_paint (stage, view, &clip_rect);
setup_view_for_pick_or_paint (stage, view, clip);
clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
clutter_paint_context_destroy (paint_context);
}
@@ -919,9 +948,9 @@ clutter_stage_do_paint_view (ClutterStage *stage,
* for picking or painting...
*/
void
_clutter_stage_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_rectangle_int_t *clip)
clutter_stage_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_region_t *redraw_clip)
{
ClutterStagePrivate *priv = stage->priv;
@@ -930,15 +959,11 @@ _clutter_stage_paint_view (ClutterStage *stage,
COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Paint (view)");
priv->view_clip = *clip;
if (g_signal_has_handler_pending (stage, stage_signals[PAINT_VIEW],
0, TRUE))
g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view);
g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view, redraw_clip);
else
CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view);
priv->view_clip = (cairo_rectangle_int_t) { 0 };
CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view, redraw_clip);
}
void
@@ -1239,11 +1264,9 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
if (next_event->type == CLUTTER_MOTION)
{
ClutterDeviceManager *device_manager =
clutter_device_manager_get_default ();
ClutterSeat *seat = clutter_input_device_get_seat (device);
_clutter_device_manager_compress_motion (device_manager,
next_event, event);
clutter_seat_compress_motion (seat, next_event, event);
}
goto next_event;
@@ -1289,7 +1312,20 @@ _clutter_stage_needs_update (ClutterStage *stage)
priv = stage->priv;
return priv->relayout_pending || priv->redraw_pending;
return priv->redraw_pending || g_hash_table_size (priv->pending_relayouts) > 0;
}
void
clutter_stage_queue_actor_relayout (ClutterStage *stage,
ClutterActor *actor)
{
ClutterStagePrivate *priv = stage->priv;
if (g_hash_table_size (priv->pending_relayouts) == 0)
_clutter_stage_schedule_update (stage);
g_hash_table_add (priv->pending_relayouts, g_object_ref (actor));
priv->pending_relayouts_version++;
}
void
@@ -1297,41 +1333,58 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
{
ClutterStage *stage = CLUTTER_STAGE (actor);
ClutterStagePrivate *priv = stage->priv;
gfloat natural_width, natural_height;
ClutterActorBox box = { 0, };
GHashTableIter iter;
gpointer key;
int count = 0;
if (!priv->relayout_pending)
/* No work to do? Avoid the extraneous debug log messages too. */
if (g_hash_table_size (priv->pending_relayouts) == 0)
return;
/* avoid reentrancy */
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
CLUTTER_NOTE (ACTOR, ">>> Recomputing layout");
g_hash_table_iter_init (&iter, priv->pending_relayouts);
while (g_hash_table_iter_next (&iter, &key, NULL))
{
priv->relayout_pending = FALSE;
priv->stage_was_relayout = TRUE;
g_autoptr (ClutterActor) queued_actor = key;
unsigned int old_version;
CLUTTER_NOTE (ACTOR, "Recomputing layout");
g_hash_table_iter_steal (&iter);
priv->pending_relayouts_version++;
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
if (CLUTTER_ACTOR_IN_RELAYOUT (queued_actor)) /* avoid reentrancy */
continue;
natural_width = natural_height = 0;
clutter_actor_get_preferred_size (CLUTTER_ACTOR (stage),
NULL, NULL,
&natural_width, &natural_height);
/* An actor may have been destroyed or hidden between queuing and now */
if (clutter_actor_get_stage (queued_actor) != actor)
continue;
box.x1 = 0;
box.y1 = 0;
box.x2 = natural_width;
box.y2 = natural_height;
if (queued_actor == actor)
CLUTTER_NOTE (ACTOR, " Deep relayout of stage %s",
_clutter_actor_get_debug_name (queued_actor));
else
CLUTTER_NOTE (ACTOR, " Shallow relayout of actor %s",
_clutter_actor_get_debug_name (queued_actor));
CLUTTER_NOTE (ACTOR, "Allocating (0, 0 - %d, %d) for the stage",
(int) natural_width,
(int) natural_height);
CLUTTER_SET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
clutter_actor_allocate (CLUTTER_ACTOR (stage),
&box, CLUTTER_ALLOCATION_NONE);
old_version = priv->pending_relayouts_version;
clutter_actor_allocate_preferred_size (queued_actor,
CLUTTER_ALLOCATION_NONE);
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
CLUTTER_UNSET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
count++;
/* Prevent using an iterator that's been invalidated */
if (old_version != priv->pending_relayouts_version)
g_hash_table_iter_init (&iter, priv->pending_relayouts);
}
CLUTTER_NOTE (ACTOR, "<<< Completed recomputing layout of %d subtrees", count);
if (count)
priv->stage_was_relayout = TRUE;
}
static void
@@ -1381,21 +1434,21 @@ clutter_stage_do_redraw (ClutterStage *stage)
static GSList *
_clutter_stage_check_updated_pointers (ClutterStage *stage)
{
ClutterStagePrivate *priv = stage->priv;
ClutterDeviceManager *device_manager;
ClutterBackend *backend;
ClutterSeat *seat;
GSList *updating = NULL;
const GSList *devices;
cairo_region_t *clip;
GList *l, *devices;
graphene_point_t point;
clip = _clutter_stage_window_get_redraw_clip (priv->impl);
backend = clutter_get_default_backend ();
seat = clutter_backend_get_default_seat (backend);
devices = clutter_seat_list_devices (seat);
device_manager = clutter_device_manager_get_default ();
devices = clutter_device_manager_peek_devices (device_manager);
for (; devices != NULL; devices = devices->next)
for (l = devices; l; l = l->next)
{
ClutterInputDevice *dev = devices->data;
ClutterInputDevice *dev = l->data;
ClutterStageView *view;
const cairo_region_t *clip;
if (clutter_input_device_get_device_mode (dev) !=
CLUTTER_INPUT_MODE_MASTER)
@@ -1411,6 +1464,11 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage)
if (!clutter_input_device_get_coords (dev, NULL, &point))
continue;
view = clutter_stage_get_view_at (stage, point.x, point.y);
if (!view)
continue;
clip = clutter_stage_view_peek_redraw_clip (view);
if (!clip || cairo_region_contains_point (clip, point.x, point.y))
updating = g_slist_prepend (updating, dev);
break;
@@ -1424,6 +1482,8 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage)
}
}
g_list_free (devices);
return updating;
}
@@ -1496,7 +1556,7 @@ _clutter_stage_do_update (ClutterStage *stage)
while (pointers)
{
_clutter_input_device_update (pointers->data, NULL, TRUE);
clutter_input_device_update (pointers->data, NULL, TRUE);
pointers = g_slist_delete_link (pointers, pointers);
}
@@ -1509,20 +1569,31 @@ static void
clutter_stage_real_queue_relayout (ClutterActor *self)
{
ClutterStage *stage = CLUTTER_STAGE (self);
ClutterStagePrivate *priv = stage->priv;
ClutterActorClass *parent_class;
if (!priv->relayout_pending)
{
_clutter_stage_schedule_update (stage);
priv->relayout_pending = TRUE;
}
clutter_stage_queue_actor_relayout (stage, self);
/* chain up */
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_parent_class);
parent_class->queue_relayout (self);
}
static gboolean
is_full_stage_redraw_queued (ClutterStage *stage)
{
GList *l;
for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
{
ClutterStageView *view = l->data;
if (!clutter_stage_view_has_full_redraw_clip (view))
return FALSE;
}
return TRUE;
}
static gboolean
clutter_stage_real_queue_redraw (ClutterActor *actor,
ClutterActor *leaf,
@@ -1544,12 +1615,12 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
if (stage_window == NULL)
return TRUE;
if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
if (is_full_stage_redraw_queued (stage))
return FALSE;
if (redraw_clip == NULL)
{
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
clutter_stage_add_redraw_clip (stage, NULL);
return FALSE;
}
@@ -1581,43 +1652,20 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
stage_clip.width = intersection_box.x2 - stage_clip.x;
stage_clip.height = intersection_box.y2 - stage_clip.y;
_clutter_stage_window_add_redraw_clip (stage_window, &stage_clip);
clutter_stage_add_redraw_clip (stage, &stage_clip);
return FALSE;
}
gboolean
_clutter_stage_has_full_redraw_queued (ClutterStage *stage)
{
ClutterStageWindow *stage_window = _clutter_stage_get_window (stage);
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage) || stage_window == NULL)
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return FALSE;
if (stage->priv->redraw_pending &&
!_clutter_stage_window_has_redraw_clips (stage_window))
return TRUE;
else
if (!stage->priv->redraw_pending)
return FALSE;
}
cairo_region_t *
clutter_stage_get_redraw_clip (ClutterStage *stage)
{
ClutterStagePrivate *priv;
cairo_rectangle_int_t clip;
cairo_region_t *region;
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
priv = stage->priv;
region = _clutter_stage_window_get_redraw_clip (priv->impl);
if (region)
return region;
/* Set clip to the full extents of the stage */
_clutter_stage_window_get_geometry (priv->impl, &clip);
return cairo_region_create_rectangle (&clip);
return is_full_stage_redraw_queued (stage);
}
static ClutterActor *
@@ -1910,6 +1958,8 @@ clutter_stage_dispose (GObject *object)
(GDestroyNotify) free_queue_redraw_entry);
priv->pending_queue_redraws = NULL;
g_clear_pointer (&priv->pending_relayouts, g_hash_table_destroy);
/* this will release the reference on the stage */
stage_manager = clutter_stage_manager_get_default ();
_clutter_stage_manager_remove_stage (stage_manager, stage);
@@ -1944,13 +1994,11 @@ clutter_stage_finalize (GObject *object)
}
static void
clutter_stage_real_paint_view (ClutterStage *stage,
ClutterStageView *view)
clutter_stage_real_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_region_t *redraw_clip)
{
ClutterStagePrivate *priv = stage->priv;
const cairo_rectangle_int_t *clip = &priv->view_clip;
clutter_stage_do_paint_view (stage, view, clip);
clutter_stage_do_paint_view (stage, view, redraw_clip);
}
static void
@@ -2176,6 +2224,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
* ClutterStage::paint-view:
* @stage: the stage that received the event
* @view: a #ClutterStageView
* @redraw_clip: a #cairo_region_t with the redraw clip
*
* The ::paint-view signal is emitted before a #ClutterStageView is being
* painted.
@@ -2190,8 +2239,9 @@ clutter_stage_class_init (ClutterStageClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, paint_view),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
CLUTTER_TYPE_STAGE_VIEW);
G_TYPE_NONE, 2,
CLUTTER_TYPE_STAGE_VIEW,
G_TYPE_POINTER);
/**
* ClutterStage::presented: (skip)
@@ -2269,7 +2319,11 @@ clutter_stage_init (ClutterStage *self)
clutter_actor_set_background_color (CLUTTER_ACTOR (self),
&default_stage_color);
priv->relayout_pending = TRUE;
priv->pending_relayouts = g_hash_table_new_full (NULL,
NULL,
g_object_unref,
NULL);
clutter_stage_queue_actor_relayout (self, CLUTTER_ACTOR (self));
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
clutter_stage_set_title (self, g_get_prgname ());
@@ -2763,13 +2817,17 @@ clutter_stage_read_pixels (ClutterStage *stage,
.height = height,
});
cairo_region_get_extents (clip, &clip_rect);
cairo_region_destroy (clip);
if (clip_rect.width == 0 || clip_rect.height == 0)
return NULL;
{
cairo_region_destroy (clip);
return NULL;
}
framebuffer = clutter_stage_view_get_framebuffer (view);
clutter_stage_do_paint_view (stage, view, &clip_rect);
clutter_stage_do_paint_view (stage, view, clip);
cairo_region_destroy (clip);
view_scale = clutter_stage_view_get_scale (view);
pixel_width = roundf (clip_rect.width * view_scale);
@@ -3344,10 +3402,9 @@ clutter_stage_ensure_redraw (ClutterStage *stage)
priv = stage->priv;
if (!priv->relayout_pending && !priv->redraw_pending)
if (!_clutter_stage_needs_update (stage))
_clutter_stage_schedule_update (stage);
priv->relayout_pending = TRUE;
priv->redraw_pending = TRUE;
master_clock = _clutter_master_clock_get_default ();
@@ -3689,6 +3746,21 @@ _clutter_stage_clear_update_time (ClutterStage *stage)
_clutter_stage_window_clear_update_time (stage_window);
}
int64_t
_clutter_stage_get_next_presentation_time (ClutterStage *stage)
{
ClutterStageWindow *stage_window;
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return 0;
stage_window = _clutter_stage_get_window (stage);
if (stage_window == NULL)
return 0;
return _clutter_stage_window_get_next_presentation_time (stage_window);
}
ClutterPaintVolume *
_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage)
{
@@ -4277,7 +4349,6 @@ capture_view (ClutterStage *stage,
texture_width, texture_height);
cairo_surface_set_device_scale (image, view_scale, view_scale);
data = cairo_image_surface_get_data (image);
stride = cairo_image_surface_get_stride (image);
@@ -4287,6 +4358,20 @@ capture_view (ClutterStage *stage,
cairo_surface_mark_dirty (capture->image);
}
/**
* clutter_stage_capture:
* @stage: a #ClutterStage
* @paint: whether to pain the frame
* @rect: a #cairo_rectangle_int_t in stage coordinates
* @out_captures: (out) (array length=out_n_captures): an array of
* #ClutterCapture
* @out_n_captures: (out): the number of captures in @out_captures
*
* Captures the stage pixels of @rect into @captures. @rect is in stage
* coordinates.
*
* Returns: %TRUE if a #ClutterCapture has been created, %FALSE otherwise
*/
gboolean
clutter_stage_capture (ClutterStage *stage,
gboolean paint,
@@ -4388,6 +4473,100 @@ clutter_stage_get_capture_final_size (ClutterStage *stage,
return TRUE;
}
/**
* clutter_stage_paint_to_framebuffer: (skip)
*/
void
clutter_stage_paint_to_framebuffer (ClutterStage *stage,
CoglFramebuffer *framebuffer,
const cairo_rectangle_int_t *rect,
float scale,
ClutterPaintFlag paint_flags)
{
ClutterStagePrivate *priv = stage->priv;
ClutterPaintContext *paint_context;
cairo_region_t *redraw_clip;
redraw_clip = cairo_region_create_rectangle (rect);
paint_context = clutter_paint_context_new_for_framebuffer (framebuffer);
cairo_region_destroy (redraw_clip);
cogl_framebuffer_push_matrix (framebuffer);
cogl_framebuffer_set_projection_matrix (framebuffer, &priv->projection);
cogl_framebuffer_set_viewport (framebuffer,
-(rect->x * scale),
-(rect->y * scale),
priv->viewport[2] * scale,
priv->viewport[3] * scale);
clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
cogl_framebuffer_pop_matrix (framebuffer);
clutter_paint_context_destroy (paint_context);
}
/**
* clutter_stage_paint_to_buffer: (skip)
*/
gboolean
clutter_stage_paint_to_buffer (ClutterStage *stage,
const cairo_rectangle_int_t *rect,
float scale,
uint8_t *data,
int stride,
CoglPixelFormat format,
ClutterPaintFlag paint_flags,
GError **error)
{
ClutterBackend *clutter_backend = clutter_get_default_backend ();
CoglContext *cogl_context =
clutter_backend_get_cogl_context (clutter_backend);
int texture_width, texture_height;
CoglTexture2D *texture;
CoglOffscreen *offscreen;
CoglFramebuffer *framebuffer;
CoglBitmap *bitmap;
texture_width = (int) roundf (rect->width * scale);
texture_height = (int) roundf (rect->height * scale);
texture = cogl_texture_2d_new_with_size (cogl_context,
texture_width,
texture_height);
if (!texture)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to create %dx%d texture",
texture_width, texture_height);
return FALSE;
}
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
framebuffer = COGL_FRAMEBUFFER (offscreen);
cogl_object_unref (texture);
if (!cogl_framebuffer_allocate (framebuffer, error))
return FALSE;
clutter_stage_paint_to_framebuffer (stage, framebuffer,
rect, scale, paint_flags);
bitmap = cogl_bitmap_new_for_data (cogl_context,
texture_width, texture_height,
format,
stride,
data);
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
0, 0,
COGL_READ_PIXELS_COLOR_BUFFER,
bitmap);
cogl_object_unref (bitmap);
cogl_object_unref (framebuffer);
return TRUE;
}
static void
capture_view_into (ClutterStage *stage,
gboolean paint,
@@ -4396,78 +4575,17 @@ capture_view_into (ClutterStage *stage,
uint8_t *data,
int stride)
{
CoglFramebuffer *framebuffer;
ClutterBackend *backend;
CoglContext *context;
CoglBitmap *bitmap;
cairo_rectangle_int_t view_layout;
g_autoptr (GError) error = NULL;
float view_scale;
float texture_width;
float texture_height;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
framebuffer = clutter_stage_view_get_framebuffer (view);
if (paint)
{
_clutter_stage_maybe_setup_viewport (stage, view);
clutter_stage_do_paint_view (stage, view, rect);
}
view_scale = clutter_stage_view_get_scale (view);
texture_width = roundf (rect->width * view_scale);
texture_height = roundf (rect->height * view_scale);
backend = clutter_get_default_backend ();
context = clutter_backend_get_cogl_context (backend);
bitmap = cogl_bitmap_new_for_data (context,
texture_width, texture_height,
CLUTTER_CAIRO_FORMAT_ARGB32,
stride,
data);
clutter_stage_view_get_layout (view, &view_layout);
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
roundf ((rect->x - view_layout.x) * view_scale),
roundf ((rect->y - view_layout.y) * view_scale),
COGL_READ_PIXELS_COLOR_BUFFER,
bitmap);
cogl_object_unref (bitmap);
}
static ClutterStageView *
get_view_at_rect (ClutterStage *stage,
cairo_rectangle_int_t *rect)
{
ClutterStagePrivate *priv = stage->priv;
GList *views = _clutter_stage_window_get_views (priv->impl);
GList *l;
for (l = views; l; l = l->next)
{
ClutterStageView *view = l->data;
cairo_rectangle_int_t view_layout;
cairo_region_t *region;
cairo_rectangle_int_t view_capture_rect;
clutter_stage_view_get_layout (view, &view_layout);
region = cairo_region_create_rectangle (&view_layout);
cairo_region_intersect_rectangle (region, rect);
cairo_region_get_extents (region, &view_capture_rect);
cairo_region_destroy (region);
if (view_capture_rect.width == 0 || view_capture_rect.height == 0)
continue;
g_assert (view_capture_rect.width == rect->width &&
view_capture_rect.height == rect->height);
return view;
}
return NULL;
if (!clutter_stage_paint_to_buffer (stage, rect, view_scale, data, stride,
CLUTTER_CAIRO_FORMAT_ARGB32,
CLUTTER_PAINT_FLAG_NO_CURSORS,
&error))
g_warning ("Failed to capture stage: %s", error->message);
}
void
@@ -4476,11 +4594,36 @@ clutter_stage_capture_into (ClutterStage *stage,
cairo_rectangle_int_t *rect,
uint8_t *data)
{
ClutterStageView *view;
ClutterStagePrivate *priv = stage->priv;
GList *l;
int bpp = 4;
int stride;
view = get_view_at_rect (stage, rect);
capture_view_into (stage, paint, view, rect, data, rect->width * bpp);
stride = rect->width * 4;
for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next)
{
ClutterStageView *view = l->data;
cairo_rectangle_int_t view_layout;
cairo_region_t *region;
cairo_rectangle_int_t capture_rect;
int x_offset, y_offset;
clutter_stage_view_get_layout (view, &view_layout);
region = cairo_region_create_rectangle (&view_layout);
cairo_region_intersect_rectangle (region, rect);
cairo_region_get_extents (region, &capture_rect);
cairo_region_destroy (region);
x_offset = capture_rect.x - rect->x;
y_offset = capture_rect.y - rect->y;
capture_view_into (stage, paint, view,
&capture_rect,
data + (x_offset * bpp) + (y_offset * stride),
stride);
}
}
/**

View File

@@ -84,8 +84,9 @@ struct _ClutterStageClass
gboolean (* delete_event) (ClutterStage *stage,
ClutterEvent *event);
void (* paint_view) (ClutterStage *stage,
ClutterStageView *view);
void (* paint_view) (ClutterStage *stage,
ClutterStageView *view,
const cairo_region_t *redraw_clip);
/*< private >*/
/* padding for future expansion */
@@ -205,8 +206,6 @@ guchar * clutter_stage_read_pixels (ClutterStage
gint width,
gint height);
CLUTTER_EXPORT
cairo_region_t * clutter_stage_get_redraw_clip (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_ensure_viewport (ClutterStage *stage);
CLUTTER_EXPORT
@@ -234,8 +233,8 @@ CLUTTER_EXPORT
gboolean clutter_stage_capture (ClutterStage *stage,
gboolean paint,
cairo_rectangle_int_t *rect,
ClutterCapture **captures,
int *n_captures);
ClutterCapture **out_captures,
int *out_n_captures);
CLUTTER_EXPORT
ClutterStageView * clutter_stage_get_view_at (ClutterStage *stage,
float x,

View File

@@ -348,13 +348,23 @@ clutter_text_input_focus_request_surrounding (ClutterInputFocus *focus)
static void
clutter_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
guint offset,
int offset,
guint len)
{
ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text;
int cursor;
int start;
cursor = clutter_text_get_cursor_position (clutter_text);
start = cursor + offset;
if (start < 0)
{
g_warning ("The offset '%d' of deleting surrounding is larger than the cursor pos '%d'",
offset, cursor);
return;
}
if (clutter_text_get_editable (clutter_text))
clutter_text_delete_text (clutter_text, offset, len);
clutter_text_delete_text (clutter_text, start, len);
}
static void
@@ -759,7 +769,14 @@ clutter_text_create_layout_no_cache (ClutterText *text,
ClutterTextDirection text_dir;
if (clutter_actor_has_key_focus (CLUTTER_ACTOR (text)))
pango_dir = _clutter_backend_get_keymap_direction (backend);
{
ClutterSeat *seat;
ClutterKeymap *keymap;
seat = clutter_backend_get_default_seat (backend);
keymap = clutter_seat_get_keymap (seat);
pango_dir = clutter_keymap_get_direction (keymap);
}
else
{
text_dir = clutter_actor_get_text_direction (CLUTTER_ACTOR (text));

View File

@@ -214,6 +214,16 @@ _clutter_util_rectangle_intersection (const cairo_rectangle_int_t *src1,
}
}
gboolean
clutter_util_rectangle_equal (const cairo_rectangle_int_t *src1,
const cairo_rectangle_int_t *src2)
{
return ((src1->x == src2->x) &&
(src1->y == src2->y) &&
(src1->width == src2->width) &&
(src1->height == src2->height));
}
float
_clutter_util_matrix_determinant (const ClutterMatrix *matrix)
{

View File

@@ -27,15 +27,15 @@
#include "clutter-virtual-input-device.h"
#include "clutter-device-manager.h"
#include "clutter-private.h"
#include "clutter-enum-types.h"
#include "clutter-private.h"
#include "clutter-seat.h"
enum
{
PROP_0,
PROP_DEVICE_MANAGER,
PROP_SEAT,
PROP_DEVICE_TYPE,
PROP_LAST
@@ -45,7 +45,7 @@ static GParamSpec *obj_props[PROP_LAST];
typedef struct _ClutterVirtualInputDevicePrivate
{
ClutterDeviceManager *manager;
ClutterSeat *seat;
ClutterInputDeviceType device_type;
} ClutterVirtualInputDevicePrivate;
@@ -181,23 +181,6 @@ clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *virtual
slot);
}
/**
* clutter_virtual_input_device_get_manager:
* @virtual_device: a virtual device
*
* Gets the device manager of this virtual device.
*
* Returns: (transfer none): The #ClutterDeviceManager of this virtual device
**/
ClutterDeviceManager *
clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device)
{
ClutterVirtualInputDevicePrivate *priv =
clutter_virtual_input_device_get_instance_private (virtual_device);
return priv->manager;
}
int
clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device)
{
@@ -220,8 +203,8 @@ clutter_virtual_input_device_get_property (GObject *object,
switch (prop_id)
{
case PROP_DEVICE_MANAGER:
g_value_set_object (value, priv->manager);
case PROP_SEAT:
g_value_set_object (value, priv->seat);
break;
case PROP_DEVICE_TYPE:
g_value_set_enum (value, priv->device_type);
@@ -245,8 +228,8 @@ clutter_virtual_input_device_set_property (GObject *object,
switch (prop_id)
{
case PROP_DEVICE_MANAGER:
priv->manager = g_value_get_object (value);
case PROP_SEAT:
priv->seat = g_value_get_object (value);
break;
case PROP_DEVICE_TYPE:
priv->device_type = g_value_get_enum (value);
@@ -270,11 +253,11 @@ clutter_virtual_input_device_class_init (ClutterVirtualInputDeviceClass *klass)
object_class->get_property = clutter_virtual_input_device_get_property;
object_class->set_property = clutter_virtual_input_device_set_property;
obj_props[PROP_DEVICE_MANAGER] =
g_param_spec_object ("device-manager",
P_("Device Manager"),
P_("The device manager instance"),
CLUTTER_TYPE_DEVICE_MANAGER,
obj_props[PROP_SEAT] =
g_param_spec_object ("seat",
P_("Seat"),
P_("Seat"),
CLUTTER_TYPE_SEAT,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
obj_props[PROP_DEVICE_TYPE] =
g_param_spec_enum ("device-type",

View File

@@ -27,7 +27,7 @@
#include <glib-object.h>
#include <stdint.h>
#include "clutter-device-manager.h"
#include "clutter-seat.h"
#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE (clutter_virtual_input_device_get_type ())
@@ -169,9 +169,6 @@ void clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *vi
uint64_t time_us,
int slot);
CLUTTER_EXPORT
ClutterDeviceManager * clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device);
CLUTTER_EXPORT
int clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device);

View File

@@ -56,7 +56,6 @@
#include "clutter-content.h"
#include "clutter-deform-effect.h"
#include "clutter-desaturate-effect.h"
#include "clutter-device-manager.h"
#include "clutter-drag-action.h"
#include "clutter-drop-action.h"
#include "clutter-effect.h"

View File

@@ -47,7 +47,7 @@
#include "clutter-stage-private.h"
#include "clutter-stage-view-private.h"
#include "cogl/cogl-trace.h"
#define MAX_STACK_RECTS 256
typedef struct _ClutterStageViewCoglPrivate
{
@@ -235,7 +235,12 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
if (stage_cogl->update_time == stage_cogl->last_update_time)
stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval;
{
stage_cogl->update_time += refresh_interval;
next_presentation_time += refresh_interval;
}
stage_cogl->next_presentation_time = next_presentation_time;
}
static gint64
@@ -256,6 +261,29 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window)
stage_cogl->last_update_time = stage_cogl->update_time;
stage_cogl->update_time = -1;
stage_cogl->next_presentation_time = -1;
}
static int64_t
clutter_stage_cogl_get_next_presentation_time (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
int64_t now = g_get_monotonic_time ();
if (stage_cogl->next_presentation_time > 0 &&
stage_cogl->next_presentation_time <= now)
{
CLUTTER_NOTE (BACKEND,
"Missed some frames. Something blocked for over "
"%" G_GINT64_FORMAT "ms.",
(now - stage_cogl->next_presentation_time) / 1000);
stage_cogl->update_time = -1;
clutter_stage_cogl_schedule_update (stage_window,
stage_cogl->last_sync_delay);
}
return stage_cogl->next_presentation_time;
}
static ClutterActor *
@@ -288,97 +316,6 @@ clutter_stage_cogl_resize (ClutterStageWindow *stage_window,
{
}
static gboolean
clutter_stage_cogl_has_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
/* NB: at the start of each new frame there is an implied clip that
* clips everything (i.e. nothing would be drawn) so we need to make
* sure we return True in the un-initialized case here.
*/
if (!stage_cogl->initialized_redraw_clip ||
(stage_cogl->initialized_redraw_clip &&
stage_cogl->redraw_clip))
return TRUE;
else
return FALSE;
}
static gboolean
clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
/* NB: a NULL clip means a full stage redraw is required */
if (stage_cogl->initialized_redraw_clip &&
!stage_cogl->redraw_clip)
return TRUE;
else
return FALSE;
}
/* A redraw clip represents (in stage coordinates) the bounding box of
* something that needs to be redrawn. Typically they are added to the
* StageWindow as a result of clutter_actor_queue_clipped_redraw() by
* actors such as ClutterGLXTexturePixmap. All redraw clips are
* discarded after the next paint.
*
* A NULL stage_clip means the whole stage needs to be redrawn.
*
* What we do with this information:
* - we keep track of the bounding box for all redraw clips
* - when we come to redraw; we scissor the redraw to that box and use
* glBlitFramebuffer to present the redraw to the front
* buffer.
*/
static void
clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window,
cairo_rectangle_int_t *stage_clip)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
/* If we are already forced to do a full stage redraw then bail early */
if (clutter_stage_cogl_ignoring_redraw_clips (stage_window))
return;
/* A NULL stage clip means a full stage redraw has been queued and
* we keep track of this by setting a NULL redraw_clip.
*/
if (stage_clip == NULL)
{
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
stage_cogl->initialized_redraw_clip = TRUE;
return;
}
/* Ignore requests to add degenerate/empty clip rectangles */
if (stage_clip->width == 0 || stage_clip->height == 0)
return;
if (!stage_cogl->redraw_clip)
{
stage_cogl->redraw_clip = cairo_region_create_rectangle (stage_clip);
}
else
{
cairo_region_union_rectangle (stage_cogl->redraw_clip, stage_clip);
}
stage_cogl->initialized_redraw_clip = TRUE;
}
static cairo_region_t *
clutter_stage_cogl_get_redraw_clip (ClutterStageWindow *stage_window)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
if (stage_cogl->using_clipped_redraw && stage_cogl->redraw_clip)
return cairo_region_copy (stage_cogl->redraw_clip);
return NULL;
}
static inline gboolean
valid_buffer_age (ClutterStageViewCogl *view_cogl,
int age)
@@ -395,7 +332,8 @@ valid_buffer_age (ClutterStageViewCogl *view_cogl,
static void
paint_damage_region (ClutterStageWindow *stage_window,
ClutterStageView *view,
cairo_region_t *swap_region)
cairo_region_t *swap_region,
cairo_region_t *queued_redraw_clip)
{
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
@@ -432,8 +370,7 @@ paint_damage_region (ClutterStageWindow *stage_window,
}
/* Red for the clip */
if (stage_cogl->initialized_redraw_clip &&
stage_cogl->redraw_clip)
if (queued_redraw_clip)
{
static CoglPipeline *overlay_red = NULL;
@@ -443,13 +380,13 @@ paint_damage_region (ClutterStageWindow *stage_window,
cogl_pipeline_set_color4ub (overlay_red, 0x33, 0x00, 0x00, 0x33);
}
n_rects = cairo_region_num_rectangles (stage_cogl->redraw_clip);
n_rects = cairo_region_num_rectangles (queued_redraw_clip);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
float x_1, x_2, y_1, y_2;
cairo_region_get_rectangle (stage_cogl->redraw_clip, i, &rect);
cairo_region_get_rectangle (queued_redraw_clip, i, &rect);
x_1 = rect.x;
x_2 = rect.x + rect.width;
y_1 = rect.y;
@@ -471,9 +408,6 @@ swap_framebuffer (ClutterStageWindow *stage_window,
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
int *damage, n_rects, i;
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
paint_damage_region (stage_window, view, swap_region);
n_rects = cairo_region_num_rectangles (swap_region);
damage = g_newa (int, n_rects * 4);
for (i = 0; i < n_rects; i++)
@@ -536,34 +470,52 @@ scale_and_clamp_rect (const graphene_rect_t *rect,
_clutter_util_rectangle_int_extents (&tmp, dest);
}
static cairo_region_t *
offset_scale_and_clamp_region (const cairo_region_t *region,
int offset_x,
int offset_y,
float scale)
{
int n_rects, i;
cairo_rectangle_int_t *rects;
g_autofree cairo_rectangle_int_t *freeme = NULL;
n_rects = cairo_region_num_rectangles (region);
if (n_rects == 0)
return cairo_region_create ();
if (n_rects < MAX_STACK_RECTS)
rects = g_newa (cairo_rectangle_int_t, n_rects);
else
rects = freeme = g_new (cairo_rectangle_int_t, n_rects);
for (i = 0; i < n_rects; i++)
cairo_region_get_rectangle (region, i, &rects[i]);
for (i = 0; i < n_rects; i++)
{
graphene_rect_t tmp;
_clutter_util_rect_from_rectangle (&rects[i], &tmp);
graphene_rect_offset (&tmp, offset_x, offset_y);
scale_and_clamp_rect (&tmp, scale, &rects[i]);
}
return cairo_region_create_rectangles (rects, n_rects);
}
static void
paint_stage (ClutterStageCogl *stage_cogl,
ClutterStageView *view,
cairo_region_t *clip)
paint_stage (ClutterStageCogl *stage_cogl,
ClutterStageView *view,
cairo_region_t *redraw_clip)
{
ClutterStage *stage = stage_cogl->wrapper;
cairo_rectangle_int_t clip_rect;
cairo_rectangle_int_t paint_rect;
cairo_rectangle_int_t view_rect;
graphene_rect_t rect;
float fb_scale;
clutter_stage_view_get_layout (view, &view_rect);
fb_scale = clutter_stage_view_get_scale (view);
cairo_region_get_extents (clip, &clip_rect);
_clutter_util_rect_from_rectangle (&clip_rect, &rect);
scale_and_clamp_rect (&rect, 1.0f / fb_scale, &paint_rect);
_clutter_util_rectangle_offset (&paint_rect,
view_rect.x,
view_rect.y,
&paint_rect);
_clutter_stage_maybe_setup_viewport (stage, view);
_clutter_stage_paint_view (stage, view, &paint_rect);
clutter_stage_paint_view (stage, view, redraw_clip);
clutter_stage_view_after_paint (view, &paint_rect);
clutter_stage_view_after_paint (view);
}
static void
@@ -683,7 +635,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
clutter_stage_view_cogl_get_instance_private (view_cogl);
CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
cairo_rectangle_int_t view_rect;
gboolean have_clip;
gboolean is_full_redraw;
gboolean may_use_clipped_redraw;
gboolean use_clipped_redraw;
gboolean can_blit_sub_buffer;
@@ -692,6 +644,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
gboolean swap_with_damage;
ClutterActor *wrapper;
cairo_region_t *redraw_clip;
cairo_region_t *queued_redraw_clip = NULL;
cairo_region_t *fb_clip_region;
cairo_region_t *swap_region;
cairo_rectangle_int_t redraw_rect;
@@ -699,6 +652,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
float fb_scale;
int subpixel_compensation = 0;
int fb_width, fb_height;
int buffer_age;
wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
@@ -713,55 +667,46 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled ();
redraw_clip = clutter_stage_view_take_redraw_clip (view);
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
queued_redraw_clip = cairo_region_copy (redraw_clip);
/* NB: a NULL redraw clip == full stage redraw */
if (!stage_cogl->redraw_clip)
have_clip = FALSE;
if (!redraw_clip)
is_full_redraw = TRUE;
else
is_full_redraw = FALSE;
may_use_clipped_redraw =
_clutter_stage_window_can_clip_redraws (stage_window) &&
(can_blit_sub_buffer || has_buffer_age) &&
!is_full_redraw &&
/* some drivers struggle to get going and produce some junk
* frames when starting up... */
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3;
if (has_buffer_age)
{
cairo_region_t *view_region;
redraw_clip = cairo_region_copy (stage_cogl->redraw_clip);
view_region = cairo_region_create_rectangle (&view_rect);
cairo_region_intersect (redraw_clip, view_region);
have_clip = !cairo_region_equal (redraw_clip, view_region);
cairo_region_destroy (view_region);
buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
if (!valid_buffer_age (view_cogl, buffer_age))
{
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", buffer_age);
may_use_clipped_redraw = FALSE;
}
}
may_use_clipped_redraw = FALSE;
if (_clutter_stage_window_can_clip_redraws (stage_window) &&
(can_blit_sub_buffer || has_buffer_age) &&
have_clip &&
/* some drivers struggle to get going and produce some junk
* frames when starting up... */
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
if (may_use_clipped_redraw)
{
graphene_rect_t rect;
cairo_rectangle_int_t *rects;
int n_rects, i;
may_use_clipped_redraw = TRUE;
fb_clip_region = cairo_region_create ();
n_rects = cairo_region_num_rectangles (redraw_clip);
rects = g_new (cairo_rectangle_int_t, n_rects);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t new_fb_clip_rect;
cairo_region_get_rectangle (redraw_clip, i, &rects[i]);
_clutter_util_rect_from_rectangle (&rects[i], &rect);
graphene_rect_offset (&rect, -view_rect.x, -view_rect.y);
scale_and_clamp_rect (&rect, fb_scale, &new_fb_clip_rect);
cairo_region_union_rectangle (fb_clip_region, &new_fb_clip_rect);
}
g_free (rects);
fb_clip_region = offset_scale_and_clamp_region (redraw_clip,
-view_rect.x,
-view_rect.y,
fb_scale);
if (fb_scale != floorf (fb_scale))
{
int n_rects, i;
cairo_rectangle_int_t *rects;
subpixel_compensation = ceilf (fb_scale);
n_rects = cairo_region_num_rectangles (fb_clip_region);
@@ -780,9 +725,16 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
}
else
{
cairo_rectangle_int_t rect = { 0, 0, view_rect.width, view_rect.height };
fb_clip_region = cairo_region_create_rectangle (&rect);
redraw_clip = cairo_region_copy (fb_clip_region);
cairo_rectangle_int_t fb_rect;
fb_rect = (cairo_rectangle_int_t) {
.width = fb_width,
.height = fb_height,
};
fb_clip_region = cairo_region_create_rectangle (&fb_rect);
g_clear_pointer (&redraw_clip, cairo_region_destroy);
redraw_clip = cairo_region_create_rectangle (&view_rect);
}
if (may_use_clipped_redraw &&
@@ -798,62 +750,43 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
{
if (use_clipped_redraw && !clip_region_empty)
{
int age;
cairo_region_t *fb_damage;
cairo_region_t *view_damage;
int i;
age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
fill_current_damage_history (view, fb_clip_region);
if (valid_buffer_age (view_cogl, age))
fb_damage = cairo_region_create ();
for (i = 1; i <= buffer_age; i++)
{
graphene_rect_t rect;
cairo_rectangle_int_t damage_region;
cairo_rectangle_int_t *rects;
int n_rects, i;
int damage_index;
fill_current_damage_history (view, fb_clip_region);
for (i = 1; i <= age; i++)
{
cairo_region_t *fb_damage =
view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
cairo_region_union (fb_clip_region, fb_damage);
}
/* Update the redraw clip state with the extra damage. */
n_rects = cairo_region_num_rectangles (fb_clip_region);
rects = g_newa (cairo_rectangle_int_t, n_rects);
for (i = 0; i < n_rects; i++)
{
cairo_region_get_rectangle (fb_clip_region, i, &rects[i]);
_clutter_util_rect_from_rectangle (&rects[i], &rect);
scale_and_clamp_rect (&rect, 1.0f / fb_scale, &damage_region);
_clutter_util_rectangle_offset (&damage_region,
view_rect.x,
view_rect.y,
&damage_region);
cairo_region_union_rectangle (stage_cogl->redraw_clip,
&damage_region);
}
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
age,
cairo_region_num_rectangles (fb_clip_region));
swap_with_damage = TRUE;
damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1);
cairo_region_union (fb_damage,
view_priv->damage_history[damage_index]);
}
else
{
cairo_rectangle_int_t fb_damage;
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
use_clipped_redraw = FALSE;
fb_damage = (cairo_rectangle_int_t) {
.x = 0,
.y = 0,
.width = ceilf (view_rect.width * fb_scale),
.height = ceilf (view_rect.height * fb_scale)
};
fill_current_damage_history_rectangle (view, &fb_damage);
}
/* Update the fb clip region with the extra damage. */
cairo_region_union (fb_clip_region, fb_damage);
view_damage = offset_scale_and_clamp_region (fb_damage,
0, 0,
1.0f / fb_scale);
cairo_region_translate (view_damage, view_rect.x, view_rect.y);
cairo_region_intersect_rectangle (view_damage, &view_rect);
/* Update the redraw clip region with the extra damage. */
cairo_region_union (redraw_clip, view_damage);
cairo_region_destroy (view_damage);
cairo_region_destroy (fb_damage);
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
buffer_age,
cairo_region_num_rectangles (fb_clip_region));
swap_with_damage = TRUE;
}
else if (!use_clipped_redraw)
{
@@ -878,8 +811,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
cairo_rectangle_int_t clip_rect;
cairo_rectangle_int_t scissor_rect;
stage_cogl->using_clipped_redraw = TRUE;
if (cairo_region_num_rectangles (fb_clip_region) == 1)
{
cairo_region_get_extents (fb_clip_region, &clip_rect);
@@ -907,11 +838,9 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
cogl_framebuffer_push_region_clip (fb, fb_clip_region);
}
paint_stage (stage_cogl, view, fb_clip_region);
paint_stage (stage_cogl, view, redraw_clip);
cogl_framebuffer_pop_clip (fb);
stage_cogl->using_clipped_redraw = FALSE;
}
else
{
@@ -939,24 +868,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
scissor_rect.width,
scissor_rect.height);
paint_stage (stage_cogl, view, fb_clip_region);
paint_stage (stage_cogl, view, redraw_clip);
cogl_framebuffer_pop_clip (fb);
}
else
{
cairo_rectangle_int_t clip;
cairo_region_t *view_region;
clip = (cairo_rectangle_int_t) {
.x = 0,
.y = 0,
.width = ceilf (view_rect.width * fb_scale),
.height = ceilf (view_rect.height * fb_scale)
};
view_region = cairo_region_create_rectangle (&clip);
paint_stage (stage_cogl, view, view_region);
cairo_region_destroy (view_region);
paint_stage (stage_cogl, view, redraw_clip);
}
}
@@ -1027,10 +945,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
do_swap_buffer = TRUE;
}
if (redraw_clip)
cairo_region_destroy (redraw_clip);
if (fb_clip_region)
cairo_region_destroy (fb_clip_region);
g_clear_pointer (&redraw_clip, cairo_region_destroy);
g_clear_pointer (&fb_clip_region, cairo_region_destroy);
if (do_swap_buffer)
{
@@ -1050,6 +966,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
swap_region = transformed_swap_region;
}
if (queued_redraw_clip)
{
paint_damage_region (stage_window, view,
swap_region, queued_redraw_clip);
cairo_region_destroy (queued_redraw_clip);
}
res = swap_framebuffer (stage_window,
view,
swap_region,
@@ -1061,6 +984,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
}
else
{
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
return FALSE;
}
}
@@ -1078,8 +1002,10 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
{
ClutterStageView *view = l->data;
swap_event =
clutter_stage_cogl_redraw_view (stage_window, view) || swap_event;
if (!clutter_stage_view_has_redraw_clip (view))
continue;
swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
}
_clutter_stage_emit_after_paint (stage_cogl->wrapper);
@@ -1095,10 +1021,6 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
stage_cogl->pending_swaps++;
}
/* reset the redraw clipping for the next paint... */
stage_cogl->initialized_redraw_clip = FALSE;
g_clear_pointer (&stage_cogl->redraw_clip, cairo_region_destroy);
stage_cogl->frame_count++;
COGL_TRACE_END (ClutterStageCoglRedraw);
@@ -1116,10 +1038,7 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
iface->schedule_update = clutter_stage_cogl_schedule_update;
iface->get_update_time = clutter_stage_cogl_get_update_time;
iface->clear_update_time = clutter_stage_cogl_clear_update_time;
iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip;
iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips;
iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
iface->get_redraw_clip = clutter_stage_cogl_get_redraw_clip;
iface->get_next_presentation_time = clutter_stage_cogl_get_next_presentation_time;
iface->redraw = clutter_stage_cogl_redraw;
}
@@ -1165,6 +1084,7 @@ _clutter_stage_cogl_init (ClutterStageCogl *stage)
stage->refresh_rate = 0.0;
stage->update_time = -1;
stage->next_presentation_time = -1;
}
static void

View File

@@ -48,6 +48,7 @@ struct _ClutterStageCogl
gint64 last_presentation_time;
gint64 update_time;
int64_t last_update_time;
int64_t next_presentation_time;
/* We only enable clipped redraws after 2 frames, since we've seen
* a lot of drivers can struggle to get going and may output some
@@ -55,14 +56,6 @@ struct _ClutterStageCogl
unsigned int frame_count;
gint last_sync_delay;
cairo_region_t *redraw_clip;
guint initialized_redraw_clip : 1;
/* TRUE if the current paint cycle has a clipped redraw. In that
case bounding_redraw_clip specifies the the bounds. */
guint using_clipped_redraw : 1;
};
struct _ClutterStageCoglClass

View File

@@ -233,7 +233,7 @@ clutter_backend_egl_native_init (ClutterBackendEglNative *backend_egl_native)
GSettingsSchemaSource *source = g_settings_schema_source_get_default ();
GSettingsSchema *schema = g_settings_schema_source_lookup (source,
xsettings_path,
FALSE);
TRUE);
if (!schema)
{

View File

@@ -27,11 +27,11 @@
#define __CLUTTER_BACKEND_EGL_NATIVE_H__
#include <glib-object.h>
#include <gio/gio.h>
#include <cogl/cogl.h>
#include <cogl/cogl-egl.h>
#include <clutter/clutter-event.h>
#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
#include "clutter-backend-private.h"
@@ -53,9 +53,6 @@ struct _ClutterBackendEglNative
{
ClutterBackend parent_instance;
/* device manager (ie evdev) */
ClutterDeviceManager *device_manager;
/* event source */
GSource *event_source;

View File

@@ -30,7 +30,6 @@ clutter_headers = [
'clutter-deform-effect.h',
'clutter-deprecated.h',
'clutter-desaturate-effect.h',
'clutter-device-manager.h',
'clutter-drag-action.h',
'clutter-drop-action.h',
'clutter-effect.h',
@@ -70,6 +69,7 @@ clutter_headers = [
'clutter-script.h',
'clutter-scriptable.h',
'clutter-scroll-actor.h',
'clutter-seat.h',
'clutter-settings.h',
'clutter-shader-effect.h',
'clutter-shader-types.h',
@@ -118,7 +118,6 @@ clutter_sources = [
'clutter-content.c',
'clutter-deform-effect.c',
'clutter-desaturate-effect.c',
'clutter-device-manager.c',
'clutter-drag-action.c',
'clutter-drop-action.c',
'clutter-effect.c',
@@ -161,6 +160,7 @@ clutter_sources = [
'clutter-script-parser.c',
'clutter-scriptable.c',
'clutter-scroll-actor.c',
'clutter-seat.c',
'clutter-settings.c',
'clutter-shader-effect.c',
'clutter-shader-types.c',
@@ -190,7 +190,6 @@ clutter_private_headers = [
'clutter-constraint-private.h',
'clutter-content-private.h',
'clutter-debug.h',
'clutter-device-manager-private.h',
'clutter-easing.h',
'clutter-effect-private.h',
'clutter-event-private.h',
@@ -198,6 +197,7 @@ clutter_private_headers = [
'clutter-graphene.h',
'clutter-gesture-action-private.h',
'clutter-id-pool.h',
'clutter-input-device-private.h',
'clutter-input-focus-private.h',
'clutter-input-method-private.h',
'clutter-input-pointer-a11y-private.h',

View File

@@ -47,7 +47,6 @@
#include "clutter-backend.h"
#include "clutter-debug.h"
#include "clutter-device-manager-private.h"
#include "clutter-event-private.h"
#include "clutter-main.h"
#include "clutter-private.h"

View File

@@ -86,8 +86,6 @@ struct _ClutterBackendX11
Time last_event_time;
ClutterDeviceManager *device_manager;
XSettingsClient *xsettings;
Window xsettings_xwin;
};

View File

@@ -81,6 +81,7 @@ struct _CoglPangoDisplayListNode
GArray *rectangles;
/* A primitive representing those vertices */
CoglPrimitive *primitive;
guint has_color : 1;
} texture;
struct
@@ -420,7 +421,9 @@ _cogl_pango_display_list_render (CoglFramebuffer *fb,
cogl_color_get_red_byte (&node->color),
cogl_color_get_green_byte (&node->color),
cogl_color_get_blue_byte (&node->color),
cogl_color_get_alpha_byte (color));
(cogl_color_get_alpha_byte (&node->color) *
cogl_color_get_alpha_byte (color) /
255));
else
draw_color = *color;
cogl_color_premultiply (&draw_color);

View File

@@ -58,27 +58,29 @@ struct _CoglPangoGlyphCacheValue
/* This will be set to TRUE when the glyph atlas is reorganized
which means the glyph will need to be redrawn */
gboolean dirty;
guint dirty : 1;
/* Set to TRUE if the glyph has colors (eg. emoji) */
guint has_color : 1;
};
typedef void (* CoglPangoGlyphCacheDirtyFunc) (PangoFont *font,
PangoGlyph glyph,
CoglPangoGlyphCacheValue *value);
CoglPangoGlyphCache *
COGL_EXPORT CoglPangoGlyphCache *
cogl_pango_glyph_cache_new (CoglContext *ctx,
gboolean use_mipmapping);
void
COGL_EXPORT void
cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache);
CoglPangoGlyphCacheValue *
COGL_EXPORT CoglPangoGlyphCacheValue *
cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache,
gboolean create,
PangoFont *font,
PangoGlyph glyph);
void
COGL_EXPORT void
cogl_pango_glyph_cache_clear (CoglPangoGlyphCache *cache);
void

View File

@@ -50,6 +50,7 @@
#include <pango/pangocairo.h>
#include <pango/pango-renderer.h>
#include <cairo.h>
#include <cairo-ft.h>
#include "cogl/cogl-debug.h"
#include "cogl/cogl-context-private.h"
@@ -526,6 +527,24 @@ cogl_pango_renderer_get_cached_glyph (PangoRenderer *renderer,
create, font, glyph);
}
static gboolean
font_has_color_glyphs (const PangoFont *font)
{
cairo_scaled_font_t *scaled_font;
gboolean has_color = FALSE;
scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *) font);
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_FT)
{
FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
has_color = (FT_HAS_COLOR (ft_face) != 0);
cairo_ft_scaled_font_unlock_face (scaled_font);
}
return has_color;
}
static void
cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
PangoGlyph glyph,
@@ -600,6 +619,8 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
cairo_image_surface_get_data (surface));
cairo_surface_destroy (surface);
value->has_color = font_has_color_glyphs (font);
}
static void
@@ -698,6 +719,7 @@ cogl_pango_renderer_set_color_for_part (PangoRenderer *renderer,
PangoRenderPart part)
{
PangoColor *pango_color = pango_renderer_get_color (renderer, part);
uint16_t alpha = pango_renderer_get_alpha (renderer, part);
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
if (pango_color)
@@ -708,7 +730,7 @@ cogl_pango_renderer_set_color_for_part (PangoRenderer *renderer,
pango_color->red >> 8,
pango_color->green >> 8,
pango_color->blue >> 8,
0xff);
alpha ? alpha >> 8 : 0xff);
_cogl_pango_display_list_set_color_override (priv->display_list, &color);
}
@@ -820,14 +842,13 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
CoglPangoGlyphCacheValue *cache_value;
int i;
cogl_pango_renderer_set_color_for_part (renderer,
PANGO_RENDER_PART_FOREGROUND);
for (i = 0; i < glyphs->num_glyphs; i++)
{
PangoGlyphInfo *gi = glyphs->glyphs + i;
float x, y;
cogl_pango_renderer_set_color_for_part (renderer,
PANGO_RENDER_PART_FOREGROUND);
cogl_pango_renderer_get_device_units (renderer,
xi + gi->geometry.x_offset,
yi + gi->geometry.y_offset,
@@ -884,6 +905,19 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
x += (float)(cache_value->draw_x);
y += (float)(cache_value->draw_y);
/* Do not override color if the glyph/font provide its own */
if (cache_value->has_color)
{
CoglColor color;
uint16_t alpha;
alpha = pango_renderer_get_alpha (renderer,
PANGO_RENDER_PART_FOREGROUND);
cogl_color_init_from_4ub (&color, 0xff, 0xff, 0xff,
alpha ? alpha >> 8 : 0xff);
_cogl_pango_display_list_set_color_override (priv->display_list, &color);
}
cogl_pango_renderer_draw_glyph (priv, cache_value, x, y);
}
}

View File

@@ -75,7 +75,7 @@ typedef PangoCairoFontMap CoglPangoFontMap;
*
* Since: 1.14
*/
PangoFontMap *
COGL_EXPORT PangoFontMap *
cogl_pango_font_map_new (void);
/**
@@ -86,7 +86,7 @@ cogl_pango_font_map_new (void);
*
* Returns: (transfer full): the newly created context: free with g_object_unref().
*/
PangoContext *
COGL_EXPORT PangoContext *
cogl_pango_font_map_create_context (CoglPangoFontMap *font_map);
/**
@@ -102,7 +102,7 @@ cogl_pango_font_map_create_context (CoglPangoFontMap *font_map);
*
* Since: 1.14
*/
void
COGL_EXPORT void
cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map,
double dpi);
@@ -114,7 +114,7 @@ cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map,
*
* Since: 1.0
*/
void
COGL_EXPORT void
cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *font_map);
/**
@@ -129,7 +129,7 @@ cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *font_map);
*
* Since: 1.0
*/
void
COGL_EXPORT void
cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout);
/**
@@ -142,7 +142,7 @@ cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout);
*
* Since: 1.0
*/
void
COGL_EXPORT void
cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *font_map,
gboolean value);
@@ -157,7 +157,7 @@ cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *font_map,
*
* Since: 1.0
*/
gboolean
COGL_EXPORT gboolean
cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *font_map);
/**
@@ -170,7 +170,7 @@ cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *font_map);
*
* Since: 1.0
*/
PangoRenderer *
COGL_EXPORT PangoRenderer *
cogl_pango_font_map_get_renderer (CoglPangoFontMap *font_map);
/**
@@ -187,7 +187,7 @@ cogl_pango_font_map_get_renderer (CoglPangoFontMap *font_map);
*
* Since: 1.14
*/
void
COGL_EXPORT void
cogl_pango_show_layout (CoglFramebuffer *framebuffer,
PangoLayout *layout,
float x,
@@ -208,7 +208,7 @@ cogl_pango_show_layout (CoglFramebuffer *framebuffer,
*
* Since: 1.14
*/
void
COGL_EXPORT void
cogl_pango_show_layout_line (CoglFramebuffer *framebuffer,
PangoLayoutLine *line,
float x,
@@ -227,7 +227,7 @@ cogl_pango_show_layout_line (CoglFramebuffer *framebuffer,
typedef struct _CoglPangoRenderer CoglPangoRenderer;
typedef struct _CoglPangoRendererClass CoglPangoRendererClass;
GType cogl_pango_renderer_get_type (void) G_GNUC_CONST;
COGL_EXPORT GType cogl_pango_renderer_get_type (void) G_GNUC_CONST;
G_END_DECLS

View File

@@ -1,6 +0,0 @@
{
global:
cogl_pango_*;
local:
*;
};

View File

@@ -20,19 +20,13 @@ cogl_pango_deps = [
libmutter_cogl_dep,
]
libmutter_cogl_pango_map = 'libmutter-cogl-pango.map'
libmutter_cogl_pango_link_args = [
'-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(),
libmutter_cogl_pango_map),
]
libmutter_cogl_pango = shared_library('mutter-cogl-pango-' + libmutter_api_version,
sources: [cogl_pango_sources, cogl_pango_public_headers],
version: '0.0.0',
soversion: 0,
c_args: cogl_c_args,
include_directories: [cogl_includepath, cogl_path_includepath],
link_depends: libmutter_cogl_pango_map,
link_args: libmutter_cogl_pango_link_args,
gnu_symbol_visibility: 'hidden',
dependencies: [cogl_pango_deps],
install_rpath: pkglibdir,
install_dir: pkglibdir,

View File

@@ -50,6 +50,7 @@ G_BEGIN_DECLS
*
* Returns: a #GType that can be used with the GLib type system.
*/
COGL_EXPORT
GType cogl_path_get_gtype (void);
#define cogl_path_new cogl2_path_new
@@ -64,7 +65,7 @@ GType cogl_path_get_gtype (void);
*
* Since: 2.0
*/
CoglPath *
COGL_EXPORT CoglPath *
cogl_path_new (void);
/**
@@ -82,7 +83,7 @@ cogl_path_new (void);
*
* Since: 2.0
*/
CoglPath *
COGL_EXPORT CoglPath *
cogl_path_copy (CoglPath *path);
/**
@@ -96,7 +97,7 @@ cogl_path_copy (CoglPath *path);
*
* Since: 2.0
*/
gboolean
COGL_EXPORT gboolean
cogl_is_path (void *object);
#define cogl_path_move_to cogl2_path_move_to
@@ -110,7 +111,7 @@ cogl_is_path (void *object);
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_move_to (CoglPath *path,
float x,
float y);
@@ -127,7 +128,7 @@ cogl_path_move_to (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_rel_move_to (CoglPath *path,
float x,
float y);
@@ -143,7 +144,7 @@ cogl_path_rel_move_to (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_line_to (CoglPath *path,
float x,
float y);
@@ -159,7 +160,7 @@ cogl_path_line_to (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_rel_line_to (CoglPath *path,
float x,
float y);
@@ -187,7 +188,7 @@ cogl_path_rel_line_to (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_arc (CoglPath *path,
float center_x,
float center_y,
@@ -212,7 +213,7 @@ cogl_path_arc (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_curve_to (CoglPath *path,
float x_1,
float y_1,
@@ -238,7 +239,7 @@ cogl_path_curve_to (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_rel_curve_to (CoglPath *path,
float x_1,
float y_1,
@@ -256,7 +257,7 @@ cogl_path_rel_curve_to (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_close (CoglPath *path);
#define cogl_path_line cogl2_path_line
@@ -273,7 +274,7 @@ cogl_path_close (CoglPath *path);
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_line (CoglPath *path,
float x_1,
float y_1,
@@ -301,7 +302,7 @@ cogl_path_line (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_polyline (CoglPath *path,
const float *coords,
int num_points);
@@ -323,7 +324,7 @@ cogl_path_polyline (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_polygon (CoglPath *path,
const float *coords,
int num_points);
@@ -341,7 +342,7 @@ cogl_path_polygon (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_rectangle (CoglPath *path,
float x_1,
float y_1,
@@ -361,7 +362,7 @@ cogl_path_rectangle (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_ellipse (CoglPath *path,
float center_x,
float center_y,
@@ -384,7 +385,7 @@ cogl_path_ellipse (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_round_rectangle (CoglPath *path,
float x_1,
float y_1,
@@ -406,7 +407,7 @@ cogl_path_round_rectangle (CoglPath *path,
*
* Since: 2.0
*/
void
COGL_EXPORT void
cogl_path_set_fill_rule (CoglPath *path, CoglPathFillRule fill_rule);
#define cogl_path_get_fill_rule cogl2_path_get_fill_rule
@@ -419,7 +420,7 @@ cogl_path_set_fill_rule (CoglPath *path, CoglPathFillRule fill_rule);
*
* Since: 2.0
*/
CoglPathFillRule
COGL_EXPORT CoglPathFillRule
cogl_path_get_fill_rule (CoglPath *path);
/**
@@ -441,7 +442,7 @@ cogl_path_get_fill_rule (CoglPath *path);
*
* Stability: unstable
*/
void
COGL_EXPORT void
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglPath *path);
@@ -458,7 +459,7 @@ cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
*
* Stability: unstable
*/
void
COGL_EXPORT void
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglPath *path);
@@ -476,7 +477,7 @@ cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
* Since: 1.0
* Stability: unstable
*/
void
COGL_EXPORT void
cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
CoglPath *path);

View File

@@ -1,17 +0,0 @@
{
global:
cogl_framebuffer_*;
cogl_path_*;
cogl_is_*;
cogl_clip_*;
cogl_get_*;
cogl_set_*;
cogl2_framebuffer_*;
cogl2_path_*;
cogl2_is_*;
cogl2_clip_*;
cogl2_get_*;
cogl2_set_*;
local:
*;
};

View File

@@ -53,19 +53,13 @@ cogl_path_c_args = [
cogl_c_args,
]
libmutter_cogl_path_map = 'libmutter-cogl-path.map'
libmutter_cogl_path_link_args = [
'-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(),
libmutter_cogl_path_map),
]
libmutter_cogl_path = shared_library('mutter-cogl-path-' + libmutter_api_version,
sources: [cogl_path_sources, cogl_path_public_headers],
version: '0.0.0',
soversion: 0,
c_args: cogl_path_c_args,
include_directories: [cogl_includepath, cogl_path_includepath],
link_depends: libmutter_cogl_path_map,
link_args: libmutter_cogl_path_link_args,
gnu_symbol_visibility: 'hidden',
dependencies: libmutter_cogl_dep,
install_rpath: pkglibdir,
install_dir: pkglibdir,

View File

@@ -65,12 +65,12 @@ CoglAtlasTexture *
_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp,
gboolean can_convert_in_place);
void
COGL_EXPORT void
_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx,
GHookFunc callback,
void *user_data);
void
COGL_EXPORT void
_cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx,
GHookFunc callback,
void *user_data);

View File

@@ -252,16 +252,14 @@ _cogl_atlas_texture_foreach_sub_texture_in_region (
static void
_cogl_atlas_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex,
GLenum wrap_mode_s,
GLenum wrap_mode_t,
GLenum wrap_mode_p)
GLenum wrap_mode_t)
{
CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex);
/* Forward on to the sub texture */
_cogl_texture_gl_flush_legacy_texobj_wrap_modes (atlas_tex->sub_texture,
wrap_mode_s,
wrap_mode_t,
wrap_mode_p);
wrap_mode_t);
}
static void

View File

@@ -74,6 +74,7 @@ typedef struct _CoglAtlasTexture CoglAtlasTexture;
*
* Returns: a #GType that can be used with the GLib type system.
*/
COGL_EXPORT
GType cogl_atlas_texture_get_gtype (void);
/**
@@ -108,7 +109,7 @@ GType cogl_atlas_texture_get_gtype (void);
* Since: 1.16
* Stability: unstable
*/
CoglAtlasTexture *
COGL_EXPORT CoglAtlasTexture *
cogl_atlas_texture_new_with_size (CoglContext *ctx,
int width,
int height);
@@ -146,7 +147,7 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx,
* Since: 1.16
* Stability: unstable
*/
CoglAtlasTexture *
COGL_EXPORT CoglAtlasTexture *
cogl_atlas_texture_new_from_file (CoglContext *ctx,
const char *filename,
GError **error);
@@ -191,7 +192,7 @@ cogl_atlas_texture_new_from_file (CoglContext *ctx,
* Since: 1.16
* Stability: unstable
*/
CoglAtlasTexture *
COGL_EXPORT CoglAtlasTexture *
cogl_atlas_texture_new_from_data (CoglContext *ctx,
int width,
int height,
@@ -231,7 +232,7 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx,
* Since: 1.16
* Stability: unstable
*/
CoglAtlasTexture *
COGL_EXPORT CoglAtlasTexture *
cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp);
/**
@@ -246,7 +247,7 @@ cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp);
* Since: 1.16
* Stability: Unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_is_atlas_texture (void *object);
G_END_DECLS

View File

@@ -64,12 +64,12 @@ struct _CoglAtlas
GHookList post_reorganize_callbacks;
};
CoglAtlas *
COGL_EXPORT CoglAtlas *
_cogl_atlas_new (CoglPixelFormat texture_format,
CoglAtlasFlags flags,
CoglAtlasUpdatePositionCallback update_position_cb);
gboolean
COGL_EXPORT gboolean
_cogl_atlas_reserve_space (CoglAtlas *atlas,
unsigned int width,
unsigned int height,
@@ -87,7 +87,7 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas,
int height,
CoglPixelFormat format);
void
COGL_EXPORT void
_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas,
GHookFunc pre_callback,
GHookFunc post_callback,

View File

@@ -64,6 +64,7 @@ G_BEGIN_DECLS
*
* Returns: a #GType that can be used with the GLib type system.
*/
COGL_EXPORT
GType cogl_attribute_buffer_get_gtype (void);
/**
@@ -89,7 +90,7 @@ GType cogl_attribute_buffer_get_gtype (void);
*
* Stability: Unstable
*/
CoglAttributeBuffer *
COGL_EXPORT CoglAttributeBuffer *
cogl_attribute_buffer_new_with_size (CoglContext *context,
size_t bytes);
@@ -122,7 +123,7 @@ cogl_attribute_buffer_new_with_size (CoglContext *context,
* Since: 1.4
* Stability: Unstable
*/
CoglAttributeBuffer *
COGL_EXPORT CoglAttributeBuffer *
cogl_attribute_buffer_new (CoglContext *context,
size_t bytes,
const void *data);
@@ -139,7 +140,7 @@ cogl_attribute_buffer_new (CoglContext *context,
* Since: 1.4
* Stability: Unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_is_attribute_buffer (void *object);
G_END_DECLS

View File

@@ -168,35 +168,6 @@ validate_n_components (const CoglAttributeNameState *name_state,
{
switch (name_state->name_id)
{
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
if (G_UNLIKELY (n_components == 1))
{
g_critical ("glVertexPointer doesn't allow 1 component vertex "
"positions so we currently only support \"cogl_vertex\" "
"attributes where n_components == 2, 3 or 4");
return FALSE;
}
break;
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
if (G_UNLIKELY (n_components != 3 && n_components != 4))
{
g_critical ("glColorPointer expects 3 or 4 component colors so we "
"currently only support \"cogl_color\" attributes where "
"n_components == 3 or 4");
return FALSE;
}
break;
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
break;
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
if (G_UNLIKELY (n_components != 3))
{
g_critical ("glNormalPointer expects 3 component normals so we "
"currently only support \"cogl_normal\" attributes "
"where n_components == 3");
return FALSE;
}
break;
case COGL_ATTRIBUTE_NAME_ID_POINT_SIZE_ARRAY:
if (G_UNLIKELY (n_components != 1))
{
@@ -205,6 +176,10 @@ validate_n_components (const CoglAttributeNameState *name_state,
return FALSE;
}
break;
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
return TRUE;
}

View File

@@ -63,6 +63,7 @@ G_BEGIN_DECLS
*
* Returns: a #GType that can be used with the GLib type system.
*/
COGL_EXPORT
GType cogl_attribute_get_gtype (void);
/**
@@ -155,7 +156,7 @@ GType cogl_attribute_get_gtype (void);
*/
/* XXX: look for a precedent to see if the stride/offset args should
* have a different order. */
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
const char *name,
size_t stride,
@@ -183,7 +184,7 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant @value.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_1f (CoglContext *context,
const char *name,
float value);
@@ -210,7 +211,7 @@ cogl_attribute_new_const_1f (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant vector.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_2f (CoglContext *context,
const char *name,
float component0,
@@ -242,7 +243,7 @@ cogl_attribute_new_const_2f (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant vector.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_3f (CoglContext *context,
const char *name,
float component0,
@@ -277,7 +278,7 @@ cogl_attribute_new_const_3f (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant vector.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_4f (CoglContext *context,
const char *name,
float component0,
@@ -306,7 +307,7 @@ cogl_attribute_new_const_4f (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant vector.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_2fv (CoglContext *context,
const char *name,
const float *value);
@@ -335,7 +336,7 @@ cogl_attribute_new_const_2fv (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant vector.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_3fv (CoglContext *context,
const char *name,
const float *value);
@@ -365,7 +366,7 @@ cogl_attribute_new_const_3fv (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant vector.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_4fv (CoglContext *context,
const char *name,
const float *value);
@@ -398,7 +399,7 @@ cogl_attribute_new_const_4fv (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant matrix.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_2x2fv (CoglContext *context,
const char *name,
const float *matrix2x2,
@@ -433,7 +434,7 @@ cogl_attribute_new_const_2x2fv (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant matrix.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_3x3fv (CoglContext *context,
const char *name,
const float *matrix3x3,
@@ -468,7 +469,7 @@ cogl_attribute_new_const_3x3fv (CoglContext *context,
* Return value: (transfer full): A newly allocated #CoglAttribute
* representing the given constant matrix.
*/
CoglAttribute *
COGL_EXPORT CoglAttribute *
cogl_attribute_new_const_4x4fv (CoglContext *context,
const char *name,
const float *matrix4x4,
@@ -492,7 +493,7 @@ cogl_attribute_new_const_4x4fv (CoglContext *context,
* Stability: unstable
* Since: 1.10
*/
void
COGL_EXPORT void
cogl_attribute_set_normalized (CoglAttribute *attribute,
gboolean normalized);
@@ -506,7 +507,7 @@ cogl_attribute_set_normalized (CoglAttribute *attribute,
* Stability: unstable
* Since: 1.10
*/
gboolean
COGL_EXPORT gboolean
cogl_attribute_get_normalized (CoglAttribute *attribute);
/**
@@ -519,7 +520,7 @@ cogl_attribute_get_normalized (CoglAttribute *attribute);
* Stability: unstable
* Since: 1.10
*/
CoglAttributeBuffer *
COGL_EXPORT CoglAttributeBuffer *
cogl_attribute_get_buffer (CoglAttribute *attribute);
/**
@@ -532,7 +533,7 @@ cogl_attribute_get_buffer (CoglAttribute *attribute);
* Stability: unstable
* Since: 1.10
*/
void
COGL_EXPORT void
cogl_attribute_set_buffer (CoglAttribute *attribute,
CoglAttributeBuffer *attribute_buffer);
@@ -545,7 +546,7 @@ cogl_attribute_set_buffer (CoglAttribute *attribute,
* Return value: %TRUE if the @object references a #CoglAttribute,
* %FALSE otherwise
*/
gboolean
COGL_EXPORT gboolean
cogl_is_attribute (void *object);
G_END_DECLS

View File

@@ -54,6 +54,7 @@ G_BEGIN_DECLS
*
* Returns: a #GType that can be used with the GLib type system.
*/
COGL_EXPORT
GType cogl_bitmap_get_gtype (void);
/**
@@ -80,7 +81,7 @@ GType cogl_bitmap_get_gtype (void);
*
* Since: 1.0
*/
CoglBitmap *
COGL_EXPORT CoglBitmap *
cogl_bitmap_new_from_file (const char *filename,
GError **error);
@@ -103,7 +104,7 @@ cogl_bitmap_new_from_file (const char *filename,
* Since: 1.8
* Stability: unstable
*/
CoglBitmap *
COGL_EXPORT CoglBitmap *
cogl_bitmap_new_from_buffer (CoglBuffer *buffer,
CoglPixelFormat format,
int width,
@@ -140,7 +141,7 @@ cogl_bitmap_new_from_buffer (CoglBuffer *buffer,
* Since: 1.10
* Stability: Unstable
*/
CoglBitmap *
COGL_EXPORT CoglBitmap *
cogl_bitmap_new_with_size (CoglContext *context,
unsigned int width,
unsigned int height,
@@ -166,7 +167,7 @@ cogl_bitmap_new_with_size (CoglContext *context,
* Since: 1.10
* Stability: unstable
*/
CoglBitmap *
COGL_EXPORT CoglBitmap *
cogl_bitmap_new_for_data (CoglContext *context,
int width,
int height,
@@ -182,7 +183,7 @@ cogl_bitmap_new_for_data (CoglContext *context,
* Since: 1.10
* Stability: unstable
*/
CoglPixelFormat
COGL_EXPORT CoglPixelFormat
cogl_bitmap_get_format (CoglBitmap *bitmap);
/**
@@ -193,7 +194,7 @@ cogl_bitmap_get_format (CoglBitmap *bitmap);
* Since: 1.10
* Stability: unstable
*/
int
COGL_EXPORT int
cogl_bitmap_get_width (CoglBitmap *bitmap);
/**
@@ -204,7 +205,7 @@ cogl_bitmap_get_width (CoglBitmap *bitmap);
* Since: 1.10
* Stability: unstable
*/
int
COGL_EXPORT int
cogl_bitmap_get_height (CoglBitmap *bitmap);
/**
@@ -217,7 +218,7 @@ cogl_bitmap_get_height (CoglBitmap *bitmap);
* Since: 1.10
* Stability: unstable
*/
int
COGL_EXPORT int
cogl_bitmap_get_rowstride (CoglBitmap *bitmap);
/**
@@ -231,7 +232,7 @@ cogl_bitmap_get_rowstride (CoglBitmap *bitmap);
* Stability: unstable
* Since: 1.10
*/
CoglPixelBuffer *
COGL_EXPORT CoglPixelBuffer *
cogl_bitmap_get_buffer (CoglBitmap *bitmap);
/**
@@ -247,7 +248,7 @@ cogl_bitmap_get_buffer (CoglBitmap *bitmap);
*
* Since: 1.0
*/
gboolean
COGL_EXPORT gboolean
cogl_bitmap_get_size_from_file (const char *filename,
int *width,
int *height);
@@ -263,7 +264,7 @@ cogl_bitmap_get_size_from_file (const char *filename,
*
* Since: 1.0
*/
gboolean
COGL_EXPORT gboolean
cogl_is_bitmap (void *object);
/**
@@ -297,6 +298,7 @@ typedef enum
COGL_BITMAP_ERROR_CORRUPT_IMAGE
} CoglBitmapError;
COGL_EXPORT
uint32_t cogl_bitmap_error_quark (void);
G_END_DECLS

View File

@@ -509,7 +509,7 @@ parse_argument (const char *string, /* original user string */
if (parsing_factor)
arg->factor.is_color = TRUE;
/* fall through */
G_GNUC_FALLTHROUGH;
case PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME:
if (!is_symbol_char (*p))
{
@@ -540,7 +540,7 @@ parse_argument (const char *string, /* original user string */
else
continue;
/* fall through */
G_GNUC_FALLTHROUGH;
case PARSER_ARG_STATE_MAYBE_COLOR_MASK:
if (*p != '[')
{
@@ -554,7 +554,7 @@ parse_argument (const char *string, /* original user string */
state = PARSER_ARG_STATE_SCRAPING_MASK;
mark = p;
/* fall through */
G_GNUC_FALLTHROUGH;
case PARSER_ARG_STATE_SCRAPING_MASK:
if (*p == ']')
{
@@ -687,7 +687,7 @@ parse_argument (const char *string, /* original user string */
arg->factor.is_one = TRUE;
state = PARSER_ARG_STATE_EXPECT_END;
/* fall through */
G_GNUC_FALLTHROUGH;
case PARSER_ARG_STATE_EXPECT_END:
if (*p != ',' && *p != ')')
{
@@ -787,7 +787,7 @@ _cogl_blend_string_compile (const char *string,
mark = p;
state = PARSER_STATE_SCRAPING_DEST_CHANNELS;
/* fall through */
G_GNUC_FALLTHROUGH;
case PARSER_STATE_SCRAPING_DEST_CHANNELS:
if (*p != '=')
continue;
@@ -810,7 +810,7 @@ _cogl_blend_string_compile (const char *string,
mark = p;
state = PARSER_STATE_SCRAPING_FUNCTION_NAME;
/* fall through */
G_GNUC_FALLTHROUGH;
case PARSER_STATE_SCRAPING_FUNCTION_NAME:
if (*p != '(')
{
@@ -832,7 +832,7 @@ _cogl_blend_string_compile (const char *string,
current_arg = 0;
state = PARSER_STATE_EXPECT_ARG_START;
/* fall through */
G_GNUC_FALLTHROUGH;
case PARSER_STATE_EXPECT_ARG_START:
if (*p != '(' && *p != ',')
continue;

View File

@@ -139,9 +139,6 @@ _cogl_buffer_fini (CoglBuffer *buffer);
CoglBufferUsageHint
_cogl_buffer_get_usage_hint (CoglBuffer *buffer);
GLenum
_cogl_buffer_access_to_gl_enum (CoglBufferAccess access);
CoglBuffer *
_cogl_buffer_immutable_ref (CoglBuffer *buffer);
@@ -171,10 +168,10 @@ void *
_cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer,
size_t offset,
size_t size);
void *
COGL_EXPORT void *
_cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer);
void
COGL_EXPORT void
_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer);
G_END_DECLS

View File

@@ -107,7 +107,7 @@ _cogl_buffer_error_domain (void);
* Since: 1.2
* Stability: unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_is_buffer (void *object);
/**
@@ -121,7 +121,7 @@ cogl_is_buffer (void *object);
* Since: 1.2
* Stability: unstable
*/
unsigned int
COGL_EXPORT unsigned int
cogl_buffer_get_size (CoglBuffer *buffer);
/**
@@ -155,7 +155,7 @@ typedef enum /*< prefix=COGL_BUFFER_UPDATE_HINT >*/
* Since: 1.2
* Stability: unstable
*/
void
COGL_EXPORT void
cogl_buffer_set_update_hint (CoglBuffer *buffer,
CoglBufferUpdateHint hint);
@@ -170,7 +170,7 @@ cogl_buffer_set_update_hint (CoglBuffer *buffer,
* Since: 1.2
* Stability: unstable
*/
CoglBufferUpdateHint
COGL_EXPORT CoglBufferUpdateHint
cogl_buffer_get_update_hint (CoglBuffer *buffer);
/**
@@ -244,7 +244,7 @@ typedef enum /*< prefix=COGL_BUFFER_MAP_HINT >*/
* Since: 1.2
* Stability: unstable
*/
void *
COGL_EXPORT void *
cogl_buffer_map (CoglBuffer *buffer,
CoglBufferAccess access,
CoglBufferMapHint hints);
@@ -281,7 +281,7 @@ cogl_buffer_map (CoglBuffer *buffer,
* Since: 2.0
* Stability: unstable
*/
void *
COGL_EXPORT void *
cogl_buffer_map_range (CoglBuffer *buffer,
size_t offset,
size_t size,
@@ -298,7 +298,7 @@ cogl_buffer_map_range (CoglBuffer *buffer,
* Since: 1.2
* Stability: unstable
*/
void
COGL_EXPORT void
cogl_buffer_unmap (CoglBuffer *buffer);
/**
@@ -317,7 +317,7 @@ cogl_buffer_unmap (CoglBuffer *buffer);
* Since: 1.2
* Stability: unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_buffer_set_data (CoglBuffer *buffer,
size_t offset,
const void *data,

View File

@@ -178,7 +178,7 @@ _cogl_clip_stack_push_window_rectangle (CoglClipStack *stack,
int width,
int height);
CoglClipStack *
COGL_EXPORT CoglClipStack *
_cogl_clip_stack_push_rectangle (CoglClipStack *stack,
float x_1,
float y_1,
@@ -188,7 +188,7 @@ _cogl_clip_stack_push_rectangle (CoglClipStack *stack,
CoglMatrixEntry *projection_entry,
const float *viewport);
CoglClipStack *
COGL_EXPORT CoglClipStack *
_cogl_clip_stack_push_primitive (CoglClipStack *stack,
CoglPrimitive *primitive,
float bounds_x1,

View File

@@ -65,7 +65,7 @@ typedef struct _CoglClosure
* Removes the given closure from the callback list it is connected to
* and destroys it. If the closure was created with a destroy function
* then it will be invoked. */
void
COGL_EXPORT void
_cogl_closure_disconnect (CoglClosure *closure);
void

View File

@@ -57,6 +57,7 @@ G_BEGIN_DECLS
*
* Returns: a #GType that can be used with the GLib type system.
*/
COGL_EXPORT
GType cogl_color_get_gtype (void);
/**
@@ -69,7 +70,7 @@ GType cogl_color_get_gtype (void);
*
* Since: 1.0
*/
CoglColor *
COGL_EXPORT CoglColor *
cogl_color_new (void);
/**
@@ -83,7 +84,7 @@ cogl_color_new (void);
*
* Since: 1.0
*/
CoglColor *
COGL_EXPORT CoglColor *
cogl_color_copy (const CoglColor *color);
/**
@@ -94,7 +95,7 @@ cogl_color_copy (const CoglColor *color);
*
* Since: 1.0
*/
void
COGL_EXPORT void
cogl_color_free (CoglColor *color);
/**
@@ -109,7 +110,7 @@ cogl_color_free (CoglColor *color);
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_init_from_4ub (CoglColor *color,
uint8_t red,
uint8_t green,
@@ -128,7 +129,7 @@ cogl_color_init_from_4ub (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_init_from_4f (CoglColor *color,
float red,
float green,
@@ -144,7 +145,7 @@ cogl_color_init_from_4f (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_init_from_4fv (CoglColor *color,
const float *color_array);
@@ -159,7 +160,7 @@ cogl_color_init_from_4fv (CoglColor *color,
*
* Since: 1.0
*/
unsigned char
COGL_EXPORT unsigned char
cogl_color_get_red_byte (const CoglColor *color);
/**
@@ -173,7 +174,7 @@ cogl_color_get_red_byte (const CoglColor *color);
*
* Since: 1.0
*/
unsigned char
COGL_EXPORT unsigned char
cogl_color_get_green_byte (const CoglColor *color);
/**
@@ -187,7 +188,7 @@ cogl_color_get_green_byte (const CoglColor *color);
*
* Since: 1.0
*/
unsigned char
COGL_EXPORT unsigned char
cogl_color_get_blue_byte (const CoglColor *color);
/**
@@ -201,7 +202,7 @@ cogl_color_get_blue_byte (const CoglColor *color);
*
* Since: 1.0
*/
unsigned char
COGL_EXPORT unsigned char
cogl_color_get_alpha_byte (const CoglColor *color);
/**
@@ -215,7 +216,7 @@ cogl_color_get_alpha_byte (const CoglColor *color);
*
* Since: 1.0
*/
float
COGL_EXPORT float
cogl_color_get_red_float (const CoglColor *color);
/**
@@ -229,7 +230,7 @@ cogl_color_get_red_float (const CoglColor *color);
*
* Since: 1.0
*/
float
COGL_EXPORT float
cogl_color_get_green_float (const CoglColor *color);
/**
@@ -243,7 +244,7 @@ cogl_color_get_green_float (const CoglColor *color);
*
* Since: 1.0
*/
float
COGL_EXPORT float
cogl_color_get_blue_float (const CoglColor *color);
/**
@@ -257,7 +258,7 @@ cogl_color_get_blue_float (const CoglColor *color);
*
* Since: 1.0
*/
float
COGL_EXPORT float
cogl_color_get_alpha_float (const CoglColor *color);
/**
@@ -271,7 +272,7 @@ cogl_color_get_alpha_float (const CoglColor *color);
*
* Since: 1.0
*/
float
COGL_EXPORT float
cogl_color_get_red (const CoglColor *color);
/**
@@ -285,7 +286,7 @@ cogl_color_get_red (const CoglColor *color);
*
* Since: 1.0
*/
float
COGL_EXPORT float
cogl_color_get_green (const CoglColor *color);
/**
@@ -299,7 +300,7 @@ cogl_color_get_green (const CoglColor *color);
*
* Since: 1.0
*/
float
COGL_EXPORT float
cogl_color_get_blue (const CoglColor *color);
/**
@@ -313,7 +314,7 @@ cogl_color_get_blue (const CoglColor *color);
*
* Since: 1.0
*/
float
COGL_EXPORT float
cogl_color_get_alpha (const CoglColor *color);
/**
@@ -325,7 +326,7 @@ cogl_color_get_alpha (const CoglColor *color);
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_red_byte (CoglColor *color,
unsigned char red);
@@ -338,7 +339,7 @@ cogl_color_set_red_byte (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_green_byte (CoglColor *color,
unsigned char green);
@@ -351,7 +352,7 @@ cogl_color_set_green_byte (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_blue_byte (CoglColor *color,
unsigned char blue);
@@ -364,7 +365,7 @@ cogl_color_set_blue_byte (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_alpha_byte (CoglColor *color,
unsigned char alpha);
@@ -377,7 +378,7 @@ cogl_color_set_alpha_byte (CoglColor *color,
*
* since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_red_float (CoglColor *color,
float red);
@@ -390,7 +391,7 @@ cogl_color_set_red_float (CoglColor *color,
*
* since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_green_float (CoglColor *color,
float green);
@@ -403,7 +404,7 @@ cogl_color_set_green_float (CoglColor *color,
*
* since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_blue_float (CoglColor *color,
float blue);
@@ -416,7 +417,7 @@ cogl_color_set_blue_float (CoglColor *color,
*
* since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_alpha_float (CoglColor *color,
float alpha);
@@ -429,7 +430,7 @@ cogl_color_set_alpha_float (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_red (CoglColor *color,
float red);
@@ -442,7 +443,7 @@ cogl_color_set_red (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_green (CoglColor *color,
float green);
@@ -455,7 +456,7 @@ cogl_color_set_green (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_blue (CoglColor *color,
float blue);
@@ -468,7 +469,7 @@ cogl_color_set_blue (CoglColor *color,
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_set_alpha (CoglColor *color,
float alpha);
@@ -482,7 +483,7 @@ cogl_color_set_alpha (CoglColor *color,
*
* Since: 1.0
*/
void
COGL_EXPORT void
cogl_color_premultiply (CoglColor *color);
/**
@@ -495,7 +496,7 @@ cogl_color_premultiply (CoglColor *color);
*
* Since: 1.4
*/
void
COGL_EXPORT void
cogl_color_unpremultiply (CoglColor *color);
/**
@@ -512,7 +513,7 @@ cogl_color_unpremultiply (CoglColor *color);
*
* Since: 1.0
*/
gboolean
COGL_EXPORT gboolean
cogl_color_equal (const void *v1, const void *v2);
/**
@@ -529,7 +530,7 @@ cogl_color_equal (const void *v1, const void *v2);
*
* Since: 1.16
*/
void
COGL_EXPORT void
cogl_color_to_hsl (const CoglColor *color,
float *hue,
float *saturation,
@@ -547,7 +548,7 @@ cogl_color_to_hsl (const CoglColor *color,
*
* Since: 1.16
*/
void
COGL_EXPORT void
cogl_color_init_from_hsl (CoglColor *color,
float hue,
float saturation,

View File

@@ -104,15 +104,11 @@ struct _CoglContext
GArray *attribute_name_index_map;
int n_attribute_names;
CoglBitmask enabled_builtin_attributes;
CoglBitmask enabled_texcoord_attributes;
CoglBitmask enabled_custom_attributes;
/* These are temporary bitmasks that are used when disabling
* builtin,texcoord and custom attribute arrays. They are here just
* builtin and custom attribute arrays. They are here just
* to avoid allocating new ones each time */
CoglBitmask enable_builtin_attributes_tmp;
CoglBitmask enable_texcoord_attributes_tmp;
CoglBitmask enable_custom_attributes_tmp;
CoglBitmask changed_bits_tmp;
@@ -122,10 +118,6 @@ struct _CoglContext
CoglMatrix identity_matrix;
CoglMatrix y_flip_matrix;
/* Value that was last used when calling glMatrixMode to avoid
calling it multiple times */
CoglMatrixMode flushed_matrix_mode;
/* The matrix stack entries that should be flushed during the next
* pipeline state flush */
CoglMatrixEntry *current_projection_entry;
@@ -236,8 +228,6 @@ struct _CoglContext
GLint max_activateable_texture_units;
/* Fragment processing programs */
CoglHandle current_program;
GLuint current_gl_program;
gboolean current_gl_dither_enabled;
@@ -310,7 +300,7 @@ struct _CoglContext
#undef COGL_EXT_END
};
CoglContext *
COGL_EXPORT CoglContext *
_cogl_context_get_default (void);
const CoglWinsysVtable *

View File

@@ -211,7 +211,7 @@ cogl_context_new (CoglDisplay *display,
return NULL;
}
if (!context->driver_vtable->context_init (context, error))
if (!context->driver_vtable->context_init (context))
{
cogl_object_unref (display);
g_free (context);
@@ -252,8 +252,6 @@ cogl_context_new (CoglDisplay *display,
cogl_matrix_init_identity (&context->y_flip_matrix);
cogl_matrix_scale (&context->y_flip_matrix, 1, -1, 1);
context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW;
context->opaque_color_pipeline = cogl_pipeline_new (context);
context->codegen_header_buffer = g_string_new ("");
@@ -284,10 +282,6 @@ cogl_context_new (CoglDisplay *display,
context->current_pipeline_changes_since_flush = 0;
context->current_pipeline_with_color_attrib = FALSE;
_cogl_bitmask_init (&context->enabled_builtin_attributes);
_cogl_bitmask_init (&context->enable_builtin_attributes_tmp);
_cogl_bitmask_init (&context->enabled_texcoord_attributes);
_cogl_bitmask_init (&context->enable_texcoord_attributes_tmp);
_cogl_bitmask_init (&context->enabled_custom_attributes);
_cogl_bitmask_init (&context->enable_custom_attributes_tmp);
_cogl_bitmask_init (&context->changed_bits_tmp);
@@ -411,10 +405,6 @@ _cogl_context_free (CoglContext *context)
g_slist_free (context->atlases);
g_hook_list_clear (&context->atlas_reorganize_callbacks);
_cogl_bitmask_destroy (&context->enabled_builtin_attributes);
_cogl_bitmask_destroy (&context->enable_builtin_attributes_tmp);
_cogl_bitmask_destroy (&context->enabled_texcoord_attributes);
_cogl_bitmask_destroy (&context->enable_texcoord_attributes_tmp);
_cogl_bitmask_destroy (&context->enabled_custom_attributes);
_cogl_bitmask_destroy (&context->enable_custom_attributes_tmp);
_cogl_bitmask_destroy (&context->changed_bits_tmp);

View File

@@ -99,6 +99,7 @@ G_BEGIN_DECLS
*
* Returns: a #GType that can be used with the GLib type system.
*/
COGL_EXPORT
GType cogl_context_get_gtype (void);
/**
@@ -113,7 +114,7 @@ GType cogl_context_get_gtype (void);
* Since: 1.8
* Stability: unstable
*/
CoglContext *
COGL_EXPORT CoglContext *
cogl_context_new (CoglDisplay *display,
GError **error);
@@ -132,7 +133,7 @@ cogl_context_new (CoglDisplay *display,
* Since: 1.8
* Stability: unstable
*/
CoglDisplay *
COGL_EXPORT CoglDisplay *
cogl_context_get_display (CoglContext *context);
/**
@@ -151,7 +152,7 @@ cogl_context_get_display (CoglContext *context);
* Since: 1.16
* Stability: unstable
*/
CoglRenderer *
COGL_EXPORT CoglRenderer *
cogl_context_get_renderer (CoglContext *context);
/**
@@ -166,7 +167,7 @@ cogl_context_get_renderer (CoglContext *context);
* Since: 1.10
* Stability: Unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_is_context (void *object);
/* XXX: not guarded by the EXPERIMENTAL_API defines to avoid
@@ -234,7 +235,7 @@ typedef enum _CoglFeatureID
* Since: 1.10
* Stability: unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_has_feature (CoglContext *context, CoglFeatureID feature);
/**
@@ -254,7 +255,7 @@ cogl_has_feature (CoglContext *context, CoglFeatureID feature);
* Since: 1.10
* Stability: unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_has_features (CoglContext *context, ...);
/**
@@ -283,7 +284,7 @@ typedef void (*CoglFeatureCallback) (CoglFeatureID feature, void *user_data);
* Since: 1.10
* Stability: unstable
*/
void
COGL_EXPORT void
cogl_foreach_feature (CoglContext *context,
CoglFeatureCallback callback,
void *user_data);
@@ -308,7 +309,7 @@ cogl_foreach_feature (CoglContext *context,
* Since: 1.14
* Stability: unstable
*/
int64_t
COGL_EXPORT int64_t
cogl_get_clock_time (CoglContext *context);
/**
@@ -350,7 +351,7 @@ typedef enum _CoglGraphicsResetStatus
*
* Return value: a #CoglGraphicsResetStatus
*/
CoglGraphicsResetStatus
COGL_EXPORT CoglGraphicsResetStatus
cogl_get_graphics_reset_status (CoglContext *context);
G_END_DECLS

View File

@@ -75,10 +75,12 @@ typedef enum
COGL_DEBUG_N_FLAGS
} CoglDebugFlags;
extern GHashTable *_cogl_debug_instances;
COGL_EXPORT
GHashTable *_cogl_debug_instances;
#define COGL_DEBUG_N_LONGS COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_DEBUG_N_FLAGS)
extern unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS];
COGL_EXPORT
unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS];
#define COGL_DEBUG_ENABLED(flag) \
COGL_FLAGS_GET (_cogl_debug_flags, flag)

View File

@@ -46,3 +46,5 @@
#mesondefine COGL_HAS_X11_SUPPORT
#mesondefine COGL_HAS_XLIB
#mesondefine COGL_HAS_XLIB_SUPPORT
#mesondefine COGL_HAS_TRACING

View File

@@ -84,7 +84,7 @@ typedef struct {
* Since: 2.0
* Stability: Unstable
*/
void
COGL_EXPORT void
cogl_depth_state_init (CoglDepthState *state);
/**
@@ -112,7 +112,7 @@ cogl_depth_state_init (CoglDepthState *state);
* Since: 2.0
* Stability: Unstable
*/
void
COGL_EXPORT void
cogl_depth_state_set_test_enabled (CoglDepthState *state,
gboolean enable);
@@ -127,7 +127,7 @@ cogl_depth_state_set_test_enabled (CoglDepthState *state,
* Since: 2.0
* Stability: Unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_depth_state_get_test_enabled (CoglDepthState *state);
/**
@@ -150,7 +150,7 @@ cogl_depth_state_get_test_enabled (CoglDepthState *state);
* Since: 2.0
* Stability: Unstable
*/
void
COGL_EXPORT void
cogl_depth_state_set_write_enabled (CoglDepthState *state,
gboolean enable);
@@ -165,7 +165,7 @@ cogl_depth_state_set_write_enabled (CoglDepthState *state,
* Since: 2.0
* Stability: Unstable
*/
gboolean
COGL_EXPORT gboolean
cogl_depth_state_get_write_enabled (CoglDepthState *state);
/**
@@ -186,7 +186,7 @@ cogl_depth_state_get_write_enabled (CoglDepthState *state);
* Since: 2.0
* Stability: Unstable
*/
void
COGL_EXPORT void
cogl_depth_state_set_test_function (CoglDepthState *state,
CoglDepthTestFunction function);
@@ -201,7 +201,7 @@ cogl_depth_state_set_test_function (CoglDepthState *state,
* Since: 2.0
* Stability: Unstable
*/
CoglDepthTestFunction
COGL_EXPORT CoglDepthTestFunction
cogl_depth_state_get_test_function (CoglDepthState *state);
/**
@@ -235,7 +235,7 @@ cogl_depth_state_get_test_function (CoglDepthState *state);
* Since: 2.0
* Stability: Unstable
*/
void
COGL_EXPORT void
cogl_depth_state_set_range (CoglDepthState *state,
float near_val,
float far_val);
@@ -253,7 +253,7 @@ cogl_depth_state_set_range (CoglDepthState *state,
* Since: 2.0
* Stability: Unstable
*/
void
COGL_EXPORT void
cogl_depth_state_get_range (CoglDepthState *state,
float *near_val,
float *far_val);

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