We're going to enforce some invariants a bit stricter and will only
allow allocating if an actor is mapped, not only visible.
Since actors are only mapped if their parent is mapped and stages are
hidden by default, we need to show the stage to ensure the actors are
mapped before we allocate them. So do that and call clutter_actor_show()
on the stage before fake-allocating the test actors.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1366
Add new private API to ClutterActor, returning TRUE in case the actor is
being painted while unmapped. This is useful for implementations of the
paint() vfunc or for signal handlers of the "notify::mapped" signal.
Use this API in CallyActor to properly detect "notify::mapped" emissions
while painting unmapped, this fixes detecting the case where
painting-unmapped is used for screencasting.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1366
Just like the existing in_cloned_branch counter, add a property which
tracks whether the actor is part of a subtree that's being painted while
unmapped. This is going to be useful for a few things, for example
changing the clutter_actor_is_in_clone_paint() API to use
enable_paint_unmapped instead of in_clone_paint.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1366
clutter_actor_queue_relayout() detects whether a parent has the
NO_LAYOUT flag set by itself and then queues a shallow relayout for us.
There's no need to duplicate that logic when showing actors, so simply
call clutter_actor_queue_relayout() and let that handle it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1366
Apparently clutter_paint_volume_union() has problems building the union
of two paint volumes in eye coordinates, that's probably because of the
negative coordinates that come into play there.
Circumvent that by making even more use of Graphene and letting it take
care of computing the union. We do that by creating two graphene_box_t's
from the axis-aligned paint volumes and intersecting those boxes, then
setting our vertices to the new min and max points of the resulting box.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1507
Bug 448183 fixed an issue with _NET_WM_MOVERESIZE_WINDOW not moving a
window by basing the resize on the current (new) rectangle instead of
the original rectangle.
While this fixes the issue with _NET_WM_MOVERESIZE_WINDOW, this also
causes windows with a size increment to move when the resize also
implies a move, such windows might drift while resizing.
Make sure to use the current rectangle for non-interactive resizes only.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/543
The XSizeHints set by X11 clients give a hint to the window manager
about size increment, aspect ratio, base, minimum and maximum size, etc.
When an X11 client changes those values, there is a good chance that it
will affect the actual window size in some way, and mutter rightfully
queue a window resize in that case.
However, mutter does not check if any of the hints have actually changed
and unconditionally queue a window resize whenever a client changes its
WM_NORMAL_HINTS property.
That can be a problem when a zealous client such as xterm decides to
update its WM_NORMAL_HINTS property on resize, because in return mutter
will queue a non-user driven resize in the middle of user-driven events,
hence defeating the purpose of the META_MOVE_RESIZE_USER_ACTION flag.
To avoid that issue, make mutter a bit smarter and avoid queuing a
window resize if the XSizeHints haven't actually changed.
https://gitlab.gnome.org/GNOME/mutter/-/issues/543
On interactive resize, mutter calculates the difference in size based on
the pointer location and relies on window constraints to ensure the
minimum size is honored.
Wayland however does asynchronous window configuration, meaning that not
checking for size hints early enough may lead to the window moving as
the locations was initially computed on a size which will be invalidate
by the client eventually.
Make sure to respect the client size hint on update_resize() so that we
don't end up with a window moving unexpectedly when the client
eventually acked the configuration.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1495
Many tablets have a native portrait mode panel, yet come with a keyboard dock,
where the device gets docked in landscape mode. To avoid the display being
on its side when mutter starts while the tablet is docked, we need to take
the accelerometer reported orientation into account even if there is a
tablet-mode-switch which indicates that the device is NOT in tablet-mode
(because it is docked).
Add special handling for the first time the "orientation-changed"
signal gets signalled by the orientation-manager, which happens after it
has successfully claimed the accelerometer with iio-sensor-proxy.
The added special handling of the initial "orientation-changed" signal
does a number of checks:
1. panel_orientation_managed is false because of the tablet-mode-switch and not
because of other reasons.
2. The device has a native portrait mode panel (and thus likely needs rotation
to display the image the right way up when docked).
If all these checks succeed then it continues with creating a new
monitors-config based on the orientation ignoring the panel_orientation_managed
value (for the initial/first "orientation-changed" signal only).
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
The orientation reported by the orientation_manager may have changed while
panel_orientation_managed was false. So when panel_orientation_managed
changes to true we should re-check the orientation.
This fixes the orientation not being correct when e.g. taking a 360 degree
hinges 2-in-1 in clamshell mode (so landscape orientation) and then folding
it into tablet mode while holding it in portrait orientation.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Add support for the (mostly theoretical) case of an input-device
offering tablet-mode-switch functionality being unplugged.
This makes the has_tablet_switch handling identical to the has_touchscreen
handling, leading to more consistent code.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Detect if a tablet-mode-switch device is already present when mutter
starts by checking for this from meta_seat_native_constructed. This
mirrors how we also set has_touchscreen from meta_seat_native_constructed.
This fixes tablet-mode-switches only being recognized when they are added
at runtime.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Unconditionally setting has_touchscreen to check_touch_mode
when a new device gets added leads to has_touchscreen becoming
false when during runtime e.g. an USB keyboard gets plugged in.
Fix this by setting has_touchscreen to TRUE when check_touch_mode
is TRUE and leaving it alone otherwise.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Add a helper function to determine if a seat has a (physical)
touchscreen associated with it.
Currently src/backends/meta-backend.c has a private version of this
(check_has_physical_touchscreen) and further patches in this patch-set
need the same functionality. So add a generic helper for this to
avoid code duplication.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
_cogl_util_get_eye_planes_for_screen_poly() is quite a complicated beast. Ever
since Clutter became a compositor toolkit, and specially after we switched to
graphene_frustum_t on paint volumes, we can brutally simplify this function.
The new code assumes camera is at (0, 0, 0) at world coordinates (i.e. before
applying the projection). We also consider that the redraw clip are at stage
coordinates. That means that converting the clip rectangle to world rectangle
is simply a matter of projecting the corresponding vertices using the "view"
matrix. Furthermore, we only need to project the top-left, and bottom-right
vertices, since top-right and bottom-left can be derived from those two.
The frustum setup still uses triplets of vertices to setup the planes, except
now the first vertex is always the camera (hardcoded to 0, 0, 0), and the other
two vertices are the projected clip rectangle vertices.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
The redraw clip region may contain multiple clip rectangles. We currently
only use the extents of this region, but having multiple frusta for each
rectangle is a better alternative, and will allow us to remove the extra
projection we currently do.
Make the clip frustum an array, with multiple frusta.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
The clip planes / frustum are contextual to painting. In the past, for
the lack of a better place, it was added to ClutterStage, but now we
have an appropriate home for such data: ClutterPaintContext.
Move the frustum to the paint context.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
While refactoring the clipping planes / frustum code, it became more and
more evident that we do not need to update them while picking. Picking
nowadays goes through a completely different code path, that does not
rely on paint volume culling.
While it might be interesting to eventually also cull out based on paint
volumes, it certainly won't go through the painting code anymore.
Remove setting up the view when picking, and rename functions appropriatedly.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
Culling paint volumes don't give this level of detail anymore, and in
fact knowing whether it was partially or fully in was only being used
in a debug path. For the purposes of culling, it doesn't matter if a
given actor is partially or completely inside the frustum; either way,
it must be painted.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
Instead of 4 planes, use a graphene_frustum_t to store the clipping
planes.
The cautious reviewer might noticed that we are now setting up 6
planes: the 4 planes we were doing before, plus 2 extra planes in
the Z axis. These extra planes simulate an "infinite" Z far, and
an "on-camera" Z near.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
ClutterStage defines the 8 vertices of a frustum:
4 ----------------------------- 5
| \ / |
| \ / |
| 0 --------------------- 1 |
| | | |
| | | |
| 3 --------------------- 2 |
| / \ |
| / \ |
7 ----------------------------- 6
Then, it uses triplets of vertices to create each clipping plane.
It only sets up 4 planes (it doesn't clip based on depth), defined
by the following vertices:
* 0 - 4 - 5
* 1 - 5 - 6
* 2 - 6 - 7
* 0 - 7 - 4
The first 3 triplets are selected using the for-loop. However, the
last triplet is different, and is done out of the loop. It could
have been made simpler by using the "3 - 7 - 4" triplet.
Simplify the current code by using the suggested triplet, calculated
inside the for-loop.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
Instead of our own implementation that upscales, then downscales back,
use graphene_matrix_inverse() directly. This is possible after switching
to a z-near value that doesn't have problems with float precision.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
Picking is specially sensitive for float precision, and tests can
easily fail when something changes, even if ever so slightly. A
simple way to workaround this is by adjusting the projected points
using the same procedure described at 67cc60cbda.
Round projected points for picking to 256ths.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
A first step towards abandoning the CoglObject type system: convert
CoglFramebuffer, CoglOffscreen and CoglOnscreen into GObjects.
CoglFramebuffer is turned into an abstract GObject, while the two others
are currently final. The "winsys" and "platform" are still sprinkled
'void *' in the the non-abstract type instances however.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1496