Avoid some allocations, save some CPU cycles and make the code easier
to read.
Behaviourwise the only expected change is that now, if there are mapped
clones, we unconditionally choose the view with the highest refresh
rate the actor (or one of its clones) is on and don't check the
obscurred region any more.
Thus in some cases a client may receive a higher rate of frame callbacks
when obscured on a faster view while a clone is present on a slower
one. The assumption is that cases like this are relatively rare and
that the reduction of code complexity, the reduction of allocations in
`meta_surface_actor_is_obscured_on_stage_view()` whenever the actor is
not fully obscured and has clones on other views, as well as generally
fewer lookups and less code in most common cases, compensate for that.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2671>
We only support feedback-actors, such as DnD-icons, in the compositing
path at the moment.
The approach is similar to how we handle certain shell elements.
Implementations need to ensure no references to the object keep
around longer that necessary.
Arguably this should be replaced by a more robust and implicit actor
hierachy detection in the direct scanout code at some point.
Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/2470
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2677>
The fields of 'priv->video_format.max_framerate' are all of type
uint32_t. Multiplying by G_USEC_PER_SEC can overflow, and equally,
dividing a large numerical type by uint32_t can err too.
Since the variable holding the result is int64_t, cast all uint32_t
fields to int64_t before doing any maths on it.
Spotted while trying to investigating an issue with framerates on
HDMI screencasts.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2762>
Unused since https://gitlab.gnome.org/GNOME/mutter/merge_requests/932
AFAICT.
As a bonus, gets rid of these compiler warnings:
../cogl/cogl/cogl-pipeline-layer-state.c: In function ‘cogl_pipeline_get_layer_min_filter’:
../cogl/cogl/cogl-pipeline-layer-state.c:1279:10: warning: ‘min_filter’ may be used uninitialized [-Wmaybe-uninitialized]
1279 | return min_filter;
| ^~~~~~~~~~
../cogl/cogl/cogl-pipeline-layer-state.c:1274:22: note: ‘min_filter’ was declared here
1274 | CoglPipelineFilter min_filter;
| ^~~~~~~~~~
../cogl/cogl/cogl-pipeline-layer-state.c: In function ‘cogl_pipeline_get_layer_mag_filter’:
../cogl/cogl/cogl-pipeline-layer-state.c:1291:10: warning: ‘mag_filter’ may be used uninitialized [-Wmaybe-uninitialized]
1291 | return mag_filter;
| ^~~~~~~~~~
../cogl/cogl/cogl-pipeline-layer-state.c:1287:22: note: ‘mag_filter’ was declared here
1287 | CoglPipelineFilter mag_filter;
| ^~~~~~~~~~
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2757>
Add a helper function that ensures any queued virtual input events have
been flushed from the input thread. This works by posting a task to the
input thread, which will itself queue another callback back to the main
thread. Once the main thread callback is invoked, the flush call is
unblocked and the function returns. Upon this, any previously emitted
virtual input event should have already passed through the input thread
back into the main thread, however not necessarily fully processed.
For making sure it has been processed, one also have to make sure the
stage has been updated, e.g. via `meta_wait_for_paint()`.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2727>
After the commit "wayland/subsurface: Implement
meta_wayland_surface_get_window()" subsurfaces are supported. Adjust
some comments and fix a warning that could occur when closing a window.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2717>
The intention here was to check if the subsurface belongs to a window.
Thus it didn't behave as expected for subsurfaces belonging to non-toplevel
windows.
After the previous commit we can use `get_window()` to check for what we
actually want here.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2717>
Subsurfaces are special regarding windows as they don't have a window,
but usually have an ancestor which does. All current users of
`get_window()` are either used for known surface roles, such as xdg-*
ones, or, as is the case for pointer constrains, would actually want to
get the ancestors window.
Thus implement `get_window()` to allow pointer constrains to work.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2223
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2717>
The meta_prop_get_motif_hints() function was only used in the
old MetaUI frames code. The remaining code in mutter accesses
directly the MetaPropValue when loading properties for a window,
and does not use this API call.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2741>
Since we use XCB in the Mutter side, but Xlib in the frames client,
we cannot share the same struct definition since both libraries
will expect different type lengths (respectively, 32-bit ints vs.
longs).
Revert the changes that made both executables share the same
struct, since not both of them can get it right (and retrieve
correctly the struct with the contained flags) in reading the
Motif WM hints.
This reverts commit 2fb3c5a4f5.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2741>
Adding the 'default-decoration' CSS class to MetaFrameHeader after
it is set as the headerbar makes it not account for the minimum size
correctly sometimes. This is a bit racy though - if the window opens
very quickly, it works as expected.
Adding the CSS class before the widget is used guarantees it'll
always report the correct size though, so do that.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2753>
The Python docs recommends using run() for all use-cases it can handle:
https://docs.python.org/3/library/subprocess.html#using-the-subprocess-module
run() waits for the subprocess started to complete, so it's not
necessary to use wait() and communicate() anymore. This simplifies the
script.
Previously running "check-style.py -r" after each commit in an
interactive rebase failed, b/c the script did not wait for the amend
command to complete. Using run() instead of Popen() solves this issue.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2733>
Before this, new files introduced by the range of commits checked were
not considered for formatting b/c uncrustify was always turned off in
the beginning of the files, and never turned back on.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2733>
Add this CSS class both to the header bar itself, since it is what
actually contains the window controls, and to MetaFrameHeader too,
since it's what's directly attached to the window.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2740>
Previous commit added support for setting the GTK4 theme setting
according to the color scheme setting. That's cool. What it didn't
add, though, was initializing the GTK4 theme setting to the proper
value. That means if the desktop starts at dark style, you'd still
get a light titlebar.
Fix that by updating the GTK4 theme setting on init as well.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2740>
These are now referenced on the frames client side (in order to
track deletable state from the client window) and the mutter side
(pretty much everything else, like figuring out if a window wants
WM decorations).
It makes sense to make this a separate header, so that we don't
need to doubly define these flags/structs.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2735>
We use this for tracking the deletable state of the client window,
but forgot to check that the MWM_HINT_FUNCTIONS hint is set in
hints.flags before checking hints.functions.
This resulted in windows that do not specify this flag (and thus
should go with the defaults) in being mistakenly removed the close
button, as the functions flags would be typically 0 in that case.
Fixes issues with Chromium and Electron applications missing the
close button, since Chromium does this on X11.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2735>
Recalculating window features is a busy thing on the Mutter side, the
different properties being (re)set will overwrite the current state
and cause some side work. Between that is the rewriting of the
_MUTTER_NEEDS_FRAME property on the window being recalculated, which
throws the frames client off, by thinking the window does actually
require a new frame.
It is not sufficient to trust that PropertyNewValue means the property
or the value are new, also double check that the window did not have
in fact a frame, and avoid the busy work if it did.
Besides the busywork that can be easily avoided, this also fixes the
window close button state being stuck if the window changed its
deletable state, since the frame being respawn managed to miss the
property change.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2735>
meta_screen_cast_window_stream_src_set_cursor_metadata() relies
entirely on meta_screen_cast_window_transform_cursor_position()
to return the correct relative cursor position.
However, this function actually does not return the expected
values, since it does not apply the resource scale to the
transformed position.
Actually apply the cursor scale when calculating the cursor
position.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2737>
meta_screen_cast_stream_src_set_cursor_sprite_metadata() receives
the cursor sprite, position, and scale, and with that it downloads
the cursor sprite by drawing it into a separate framebuffer, then
calls cogl_framebuffer_read_pixels() in it - this is the offscren
path that is very common when using screen capturing applications
such as OBS Studio.
There's a sneaky issue in this code path though: the 'scale' value
is a float. The cursor size is then determined by multiplying the
sprite width and height - two integer variables - by scale, and
this relies on standard float-to-int conversions. This is problematic
as sometimes the rounded values disagree with what is expected by
cogl_framebuffer_read_pixels(). If the packing of either the cursor
width or height is off by one, glReadPixels() will try to write into
off bounds, which crashes.
This can be reproduced by enabling fractional scaling, setting a 150%
zoom level, on a 4K screen, and opening any commit with an image diff
in gitlab.gnome.org, all while screencasting. When hovering the new
image, the cursor sprite will be such that it triggers this code path,
and reproduces this issue.
Fix this by always ceiling the cursor sprite sizes.
Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/2542
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2736>
The uninitialized fields in this event causes use of uninitialised
data as seen in valgrind:
==71864== Syscall param writev(vector[0]) points to uninitialised byte(s)
==71864== at 0x5026EBD: __writev (writev.c:26)
==71864== by 0x5026EBD: writev (writev.c:24)
==71864== by 0x6482A3B: UnknownInlinedFun (xcb_conn.c:296)
==71864== by 0x6482A3B: _xcb_conn_wait.part.0 (xcb_conn.c:551)
==71864== by 0x6482BAF: UnknownInlinedFun (xcb_out.c:469)
==71864== by 0x6482BAF: _xcb_out_send (xcb_out.c:470)
==71864== by 0x6483DD7: UnknownInlinedFun (xcb_out.c:416)
==71864== by 0x6483DD7: xcb_writev (xcb_out.c:409)
==71864== by 0x53B79B4: _XSend (xcb_io.c:587)
==71864== by 0x53BBF38: _XReply (xcb_io.c:679)
==71864== by 0x53AFFC9: XQueryTree (QuTree.c:47)
==71864== by 0x4982A5F: query_xserver_stack (stack-tracker.c:508)
==71864== by 0x4EA1F5F: g_closure_invoke (gclosure.c:832)
==71864== by 0x4ECFD45: signal_emit_unlocked_R.isra.0 (gsignal.c:3796)
==71864== by 0x4EC0129: g_signal_emit_valist (gsignal.c:3549)
==71864== by 0x4EC03B2: g_signal_emit (gsignal.c:3606)
==71864== Address 0x287d5900 is 32 bytes inside a block of size 16,384 alloc'd
==71864== at 0x4849444: calloc (vg_replace_malloc.c:1340)
==71864== by 0x53A5FE8: XOpenDisplay (OpenDis.c:240)
==71864== by 0x6100E3C: _gdk_x11_display_open (gdkdisplay-x11.c:1565)
==71864== by 0x60CF675: gdk_display_manager_open_display (gdkdisplaymanager.c:462)
==71864== by 0x49D59F1: open_gdk_display (meta-x11-display.c:1041)
==71864== by 0x49D5D64: meta_x11_display_new (meta-x11-display.c:1156)
==71864== by 0x49564AD: meta_display_init_x11_finish (display.c:743)
==71864== by 0x495679D: on_x11_initialized (display.c:818)
==71864== by 0x4D67558: g_task_return_now (gtask.c:1232)
==71864== by 0x4D67782: UnknownInlinedFun (gtask.c:1301)
==71864== by 0x4D67782: g_task_return (gtask.c:1258)
==71864== by 0x495663C: on_xserver_started (display.c:788)
==71864== by 0x4D67558: g_task_return_now (gtask.c:1232)
==71864== Uninitialised value was created by a stack allocation
==71864== at 0x49D4A59: take_manager_selection (meta-x11-display.c:640)
==71864==
To fix this, fully initialize the event struct before sending it.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2535
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2724>
Since the frames are now rendered by a separate process, we no longer
can guarantee at this point that all updates were handled. Engaging
in a new synchronous resize operation will again freeze the actor,
so sometimes we are left with a not-quite-current buffer for the
frame+window surface.
In order to ensure that the right changes made it onscreen, delay
this next synchronous resize step until the moment the surface was
repainted. This avoids those glitches, while still ensuing the
resize operation ends up in sync with the pointer.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
Let the frames client render its own shadow. In order to do that,
avoid double painting a shadow on the compositor side, and extend
the mask area of the frame, so it does unveil the (so far)
hidden frames-client-side shadows.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
There's two meanings of "frame" there! Since SSD frames are now
rendered by an external client, and there are no actual mechanism
that ensures the frame did already get painted when the client did
respond to its NET_WM_FRAME_SYNC_REQUEST request, there may be
artifacts when resizing windows.
In order to get always the best visual result, we should actually
synchronize rendering with both the client window and the window
frame window.
This commit adds these mechanisms, so a sync alarm update is
expected on both windows until further resizes are allowed, this
ensures window and frame stay in sync, even after moving rendering
elsewhere.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>