Layer surfaces are attached to edges of the screen starting with the youngest, causing new ones to always displace existing ones. This changes the order to oldest first, keeping the positions more often.
sx, sy used to store the buffer offset of the drag surface which was
then be added (by rootston) to the drag icon position.
Buffer offsets are handled already in surface_intersect_output
(output.c) so they were added twice for dnd surfaces.
A few pedantic changes and unused variables (1-4), and genuine bugs (5,
6).
The reports with the corresponding files and lines numbers are as
follows.
1. backend/libinput/tablet_pad.c@31,44,57
"Allocator sizeof operand mismatch"
"Result of 'calloc' is converted to a pointer of type 'unsigned int',
which is incompatible with sizeof operand type 'int'"
2. types/tablet_v2/wlr_tablet_v2_pad.c@371
"Allocator sizeof operand mismatch"
"Result of 'calloc' is converted to a pointer of type 'uint32_t', which
is incompatible with sizeof operand type 'int'"
3. types/wlr_cursor.c@335
"Dead initialization"
"Value stored to 'dx'/'dy' during its initialization is never read"
4. rootston/xdg_shell.c@510
"Dead initialization"
"Value stored to 'desktop' during its initialization is never read"
5. types/tablet_v2/wlr_tablet_v2_pad.c@475
"Dereference of null pointer"
"Access to field 'strips' results in a dereference of a null pointer
(loaded from field 'current_client')"
The boolean logic was incorrect (c.f. the check in the following
function).
6. examples/idle.c@163,174,182
"Uninitialized argument value"
"1st function call argument is an uninitialized value"
If close_timeout != 0, but simulate_activity_timeout >= close_timeout,
the program would segfault at pthread_cancel(t1).
Layer surfaces are not notified of cursor position changes if the surface moves, only if the cursor moves. This workaround emits a cursor position event every time a cursor ends up over a newly resized layer surface to make sure the following clicks land in the right place.
This change doesn't address sending leave events when a cursor previously present over the surface becomes away.
There are 2 separate mechanisms in play, because a layer surface gets resized in 2 steps:
1. Layer surface resize & rearrange.
2. Underlying surface resize.
The first step may affect all layer surfaces. The cursor events are sent to cursors placed over all layer surfaces which have moved (not been resized). The second step affects any layer surface whose surface changed size. The cursor event is sent only to that surface.
Together, these events cover all surfaces: those which moves, and those which changed size, as long as each layer surface resize is accompanied by an immediate surface resize.
Implement the tablet-v2 tablet tool's implicit grab semantics for
buttons and tip.
This avoids losing focus (to other [sub]surfaces) when a button is held,
or the tip is down.
This should help when the device is used close to a surface's border and
would otherwise have to be very precise.
Whenever a new surface is created, we have to update the cursor focus,
even if there's no input event. So, we generate one motion event, and
reuse the code to update the proper cursor focus. We need to do this
for all surface roles - toplevels, popups, subsurfaces.
Fixes#1162
153f37bdf5 (#1145) removed the
wlr_xwayland_is_unamanged function while fixing OR, because it was
belieived that it's supposed to work around the broken OR handling.
This was a misunderstanding. is_unmanaged is (while sort of a hack)
intended to work around inherent differences between "real" X sessions
and our Xwayland/wayland situation.
The main reason it exists is to support applications like rofi and dzen,
while not handing focus to other OR windows (which should *not* be
required).
Traditionally, these applications just grabbed input from X and didn't
need to be focused by any logic in the WM. Which of course doesn't work
in wayland compositors. So we have to give them focus in some way.
Giving *every* OR window focus, breaks other applications that don't
expect focus to change.
A testcase that was pointed out to me where wlr_xwayland_is_unamanged was
breaking things is https://github.com/swaywm/sway/issues/2128 (syncplay,
gitk, gitgui)
Supposedly it broke using keyboard to navigate the menus.
I can't reproduce this with this patch. The popups can be navigated as
long as the parent has focus.
Just install a SIG_IGN handler, which is defined by POSIX.1-2001 to
reap the child.
To test, spawn any process (e.g. GUI application) with a keybinding,
close that process, verify it doesn't show up as a <defunct> zombie in
ps(1) output.
Implement the basic logic for tablet-v2 tablet_pad's grabs. And plug in
the default grab.
Features like "holding" the focus should be implemented via grabs, like
they are for pointer and keyboard.
The override_redirect flag can change on configure notify and
on map notify. This adds an event to know when it changes.
This removes wlr_xwayland_surface_is_unmanaged which was wrongly
using the window type to decide whether the view should be
unmanaged.
A similar patch was proposed to Weston, but has never been
merged upstream [1].
[1]: https://patchwork.freedesktop.org/patch/211161/
The previous naming was based on the input-device capability names from
libinput.
With code that uses the libinput_tablet_tool and mapping into tablet-v2,
this is confusing, so the name is changed to follow the names used in
the protocol.
It's possible that a non-default keyboard grab exists when we are trying
to change focus. For example, say there is an XDG popup when we click on
a different window. This popup's keyboard grab will swallow any
keyboard_notify_enter(), meaning the newly-clicked window won't receive
keyboard input.
So, we cancel any existing grabs in roots_seat_set_focus(). Before this
fix, a window would have been set as active but not receive keyboard
entry.
Fixes#233.
Signed-off-by: Genki Sky <sky@genki.is>
The user-visible issue is that newly-mapped xdg-shell* windows would
sometimes start with their top-left-corner, rather than their center, in
the center of the screen. This is because get_size() would
conservatively fall back on (width, height) == (0, 0) if both
set_window_geometry() had not been called, and it found
view->wlr_surface to be NULL.
But, view->wlr_surface is only set to non-NULL in view_map(). We call
get_size() before this. Fortunately, the wlr_surface in question is
accessible via view->xdg_shell{,_v6}->surface, so always fall back on
that. We can assert its presence instead of further falling back on
(width, height) == (0, 0).
Signed-off-by: Genki Sky <sky@genki.is>
Compositors now have more control over how the backend creates its
renderer. Currently all backends create an EGL/GLES2 renderer, so
the necessary attributes for creating the context are passed to a
user-provided callback function. It is responsible for initializing
provided wlr_egl and to return a renderer. On fail, return 0.
Fixes#987
Before this change, a view would lose focus after clicking something that's not keyboard-interactive. This would lead to edge cases with layer-shell windows like input methods, which are pointer-only-interactive, but are not intended to change the state of any focus.
After clicking on something non-interactive, the current view was getting deactivated, but still received keyboard events. roots_seat_set_focus now changes both together in this case.
Makes the xwayland startup process two phased.
The first phase just initialises the X11 sockets.
The second phase starts the Xwayland server itself.
When starting xwayland lazily the second phase will be postponed until
a client has connected to the X11 socket.
Changes in behaviour:
The DISPLAY environment is now set immediately after the X11 sockets
are created.
When the Xwayland server is killed or crashes, the sockets will not be
recreated, but reused.
Fixes#849: Start up Xwayland lazily
On the X11 backend the cursor position might be outside the output
window so no output is returned leading to the assert to trigger. Use
sane fallback instead of crashing.
When e.g. running rootston under X11 it would otherwise crash when
closing rootston like:
#0 0x00007f0197da7327 in wl_list_remove () at /usr/lib/x86_64-linux-gnu/libwayland-server.so.0
#1 0x000056306fcee7fb in handle_destroy (listener=0x5630723a2948, data=0x5630723a5d20) at ../rootston/layer_shell.c:273
#2 0x00007f019800a552 in wlr_signal_emit_safe (signal=0x5630723a5e30, data=0x5630723a5d20) at ../util/signal.c:29
#3 0x00007f0197fef808 in layer_surface_destroy (surface=0x5630723a5d20) at ../types/wlr_layer_shell.c:169
#4 0x00007f0197ff0001 in client_handle_destroy (resource=0x56307229c4c0) at ../types/wlr_layer_shell.c:371
#5 0x00007f0197da2f30 in () at /usr/lib/x86_64-linux-gnu/libwayland-server.so.0
#6 0x00007f0197da77f9 in () at /usr/lib/x86_64-linux-gnu/libwayland-server.so.0
#7 0x00007f0197da301d in wl_client_destroy () at /usr/lib/x86_64-linux-gnu/libwayland-server.so.0
#8 0x00007f0197da30d8 in () at /usr/lib/x86_64-linux-gnu/libwayland-server.so.0
#9 0x00007f0197da4c12 in wl_event_loop_dispatch () at /usr/lib/x86_64-linux-gnu/libwayland-server.so.0
#10 0x00007f0197da344a in wl_display_run () at /usr/lib/x86_64-linux-gnu/libwayland-server.so.0
#11 0x000056306fcef069 in main (argc=3, argv=0x7ffd22032528) at ../rootston/main.c:83
since the output_destroy got already removed in handle_output_destroy.
With -O2:
../rootston/desktop.c: In function ‘desktop_surface_at’:
../rootston/desktop.c:714:18: error: ‘roots_output’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
if ((surface = layer_surface_at(roots_output,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
&roots_output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ox, oy, sx, sy))) {
~~~~~~~~~~~~~~~