This introduces seat_get_focus_inactive_tiling and updates
`focus mode_toggle` to use it instead, because the previous method
wasn't guaranteed to return a tiling view.
It would focus the split container rather than the child.
This commit makes it track the child and the split container separately
and send the surface click to the child.
Things worth noting:
* When a fullscreen view unmaps, the check to unset fullscreen on the
workspace has been moved out of view_unmap and into container_destroy,
because containers can be fullscreen too
* The calls to `container_reap_empty_recursive(workspace)` have been
removed from `container_set_floating`. That function reaps upwards so it
wouldn't do anything. I'm probably the one who originally added it...
* My fix (b14bd1b0b1) for the tabbed child
crash has a side effect where when you close a floating container, focus
is not given to the tiled container again. I've removed my fix and
removed the call to `send_cursor_motion` from `seat_set_focus_warp`. We
should consider calling it from somewhere earlier in the call stack.
After setting the keymap, try to enable NumLock and disable CapsLock.
This only works if sway has the xkb master state and controls the keyboard.
Prepare configuration settings for later use as well.
The crash only occurs if the mouse cursor is above the tabbed container
when the last child is closed.
Introduced in 03d49490cc, over a week ago
and unnoticed until now :O
The above commit changes the behaviour of a focus change. When you
change focus, it sends pointer motion which makes the client set a new
cursor image. We already had this behaviour for workspace switching, but
this commit adds it for view switching too, such as in a tabbed
container or when closing a view.
The sequence of events that leads to the crash is:
* The last child of a tabbed container unmaps, which triggers a
`destroy` event before we've cleaned up the child or reaped the tabbed
container.
* The seat code listens to the `destroy` event and removes the seat
container from the focus stack. As part of this, it decides to set focus
to the parent (my fix alters this decision).
* When setting focus to the new parent, the container motion is sent as
per the previously mentioned commit.
* The motion code uses `container_at`, which encounters the tabbed
container and its child in a half destroyed state, and everything blows
up from there.
`con->parent` is needed because scratchpad containers don't have parents
if they're hidden, so this probably fixes a crash when a hidden
scratchpad container closes too.
The `con->parent->children->length > 1` check should catch any cases
where the parent is about to be reaped.
This makes it so if you hold mod and right click on a surface to resize
it, the resize direction is chosen based on which quarter of the surface
you've clicked. The previous implementation only resized towards the
bottom right.
The mouse binding logic is inspired/copied from the
keyboard binding logic; we store a sorted list of the
currently pressed buttons, and trigger a binding when
the currently pressed (or just recently pressed, in
the case of a release binding) buttons, as well as
modifiers/container region, match those of a given
binding.
As the code to execute a binding is not very keyboard
specific, keyboard_execute_command is renamed to
seat_execute_command and moved to where the other
binding handling functions are. The call to
transaction_commit_dirty has been lifted out.
First, the existing sway_binding structure is given an
enumerated type code. As all flags to bindsym/bindcode
are boolean, a single uint32 is used to hold all flags.
The _BORDER, _CONTENTS, _TITLEBAR flags, when active,
indicate in which part of a container the binding can
trigger; to localize complexity, they do not overlap
with the command line arguments, which center around
_TITLEBAR being set by default.
The keyboard handling code is adjusted for this change,
as is binding_key_compare; note that BINDING_LOCKED
is *not* part of the key portion of the binding.
Next, list of mouse bindings is introduced and cleaned up.
Finally, the binding command parsing code is extended
to handle the case where bindsym is used to describe
a mouse binding rather than a keysym binding; the
difference between the two may be detected as late as
when the first key/button is parsed, or as early as
the first flag. As bindings can have multiple
keycodes/keysyms/buttons, mixed keysym/button sequences
are prohibited.
cursor_set_image only uploads the named image if it doesn't match the
previous named image. This means when setting the cursor image to a
surface as given by a client, we have to clear the currently stored
image.
Also does a few other related things:
* Now uses enum wlr_edges instead of our own enum resize_edge
* Now uses wlr_xcursor_get_resize_name and removes our own
find_resize_edge_name
* Renames drag to move for consistency
This implements the following:
* `floating_modifier` configuration directive
* Drag a floating window by its title bar
* Hold mod + drag a floating window from anywhere
* Resize a floating view by dragging the border
* Resize a floating view by holding mod and right clicking anywhere on
the view
* Resize a floating view and keep aspect ratio by holding shift while
resizing using either method
* Mouse cursor turns into resize when hovering floating border or corner
The directive sets the timeout before an urgent view becomes normal
again after switching to it from another workspace.
Also:
* When an xwayland surface removes the urgent hint while the timer is
active, we now ignore the request. This happens as soon as the view
receives focus, so it was effectively making the timer pointless.
* The timeout is now only applied when switching to it from another
workspace.
Fixes#2303, as well as a crash.
To replicate the crash:
* Have multiple outputs
* In config: for_window [<criteria>] workspace foo
* Also in config: workspace foo output <left-output-name>
* Focus the right output, and ensure workspace foo doesn't exist
* Launch the app that triggers the criteria
When the view maps, it calls workspace_switch which calls
send_set_focus which calls cursor_send_pointer_motion which calls
transaction_commit_dirty. This call to transaction_commit_dirty is not
meant to happen at this time because the tree isn't guaranteed to be in
a consistent state, but I'm not sure how exactly this leads to the crash
or render issues.
In this case the transaction is already committed by the view
implementation's handle_map function. So the solution is to remove it
from cursor_send_pointer_motion and add it to the other functions in
cursor.c which call cursor_send_pointer_motion.
This allows to send wl_pointer.enter when switching between views
in a split/tabbed layout for instance. This (1) updates the cursor
image accordingly (2) makes it unnecessary to move the mouse before
scrolling. It's harmless to always call cursor_send_pointer_motion
because in case the focused surface hasn't changed this is a no-op.
The `last_focus != NULL` condition is required otherwise
cursor_send_pointer_motion will crash when sway starts up (the
sway_output doesn't yet have a workspace).
Introduces a command to manually set urgency, as well as rendering of
urgent views, sending the IPC event, removing urgency after focused for
one second, and matching urgent views via criteria.
Rather than maintain copies of the entire focus stack, this PR
transactionises the focus by introducing two new properties to the
container state and using those when rendering.
* `bool focused` means this container has actual focus. Only one
container should have this equalling true in its current state.
* `struct sway_container *focus_inactive_child` points to the immediate
child that was most recently focused (eg. for tabbed and stacked
containers).
This commit introduces a scroll_button option, which is intended to be
used with scroll_method. Now user can edit his sway config and add an
scroll_button option to device section.
When you have an unfocused container (so one view is focused_inactive),
and you focus any other view in that container, the view with
focused_inactive was not damaged. This is because we damaged the
previous focus and new focus, but needed to damage the parent of the new
focus.
Fixes#2192.
seat_get_active_current_child is intended to return a child of the given
container which has finished its mapping transaction and is able to be
rendered on screen. The previous implementation was capable of returning
a pending child, which caused a child of a tabbed or stacked view to be
rendered prematurely while it was mapping.
* Ensure that modifier keys are identified even when the next key does
not produce a keysym. This requires that modifier change tracking
be done for each sway_shortcut_state.
* Permit regular and --release shortcuts on the same key combination.
Distinct bindings are identified for press and release cases; note
that the release binding needs to be identified for both key press
and key release events.
* Maintain ascending sort order for the shortcut state list, and keep
track of the number of pressed key ids, for simpler (and hence
faster) searching of the list of key bindings.
* Move binding duplicate detection into get_active_binding to avoid
duplicating error messages.
seat_get_active_child is used for tabbed and stacked containers to get
the active child. The previous implementation used seat_get_focus_inactive
then ascended the tree to the child of the tabbed/stacked container, but
this fails when the workspace itself is stacked or tabbed and the most
recently active child is floating.
The new implementation takes a more simple approach, where it directly
scans the focus stack for the first immediate child which isn't the
floating container.
Fixes#2098.
The same shortcut algorithm is now used for keycodes,
raw keysyms, and translated keysyms. Pressed keysyms
are now stored in association with the keycodes that
generated them. Modifier keycodes (and associated
keysyms) are identified retroactively by the subsequent
change to the modifier flags.
Adds the --locked flag to bindsym and bindcode commands.
When a keyboard's associated seat has an exclusive client
(i.e, a screenlocker), then bindings are only executed if
they have the locked flag. When there is no such client,
this restriction is lifted.