Example config that produces the crash (with a single output):
workspace 1
workspace 2
Prior to this commit, container_workspace_free would manually mark the
L_FLOATING container as destroying and free it. This assumed the
L_FLOATING container would never be involved in a transaction. This was
a safe assumption when it was implemented, but became an incorrect
assumption once parent/child relationships became transactionised.
This commit removes the L_FLOATING free from container_workspace_free.
When the workspace is destroyed, it starts the normal destroy process on
the L_FLOATING container so it can be freed via transactions.
The solution used in 073ac425d5 doesn't
work in all cases because the freed instruction might be ahead in the
list, not necessarily behind.
The new solution delays running the queue until after the loop has
finished iterating, thus avoiding the problem completely.
In set_instructions_ready, calling set_instruction_ready may cause any
number of transactions to get applied, which removes them from the list
being iterated. The iteration variables need to be adjusted
accordingly.
* Move workspace selection into separate function
* Instead of keeping a `prev_focus` variable, do the check in
`should_focus` (ie. views can only take focus if they're mapped into the
active workspace)
* Fix assign-to-output - it previously set `prev_focus` but should be
`target_sibling`
* Remove call to `workspace_switch` as we'll only ever focus the view if
it's in the active workspace
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.
when using 2 display, if scaling is different
`container_update_textures_recursive` is called when moving workspace on
different display.
We need to call `container_update_title_textures` only for container of type
"CONTAINER" or "VIEW" in order to be consistent with the assert in
`update_title_texture`.
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.
The rendering code doesn't use the exclusive input surface at all
anymore to decide to skip rendering of shell surfaces. This fixes
a weird situation in which a client requests exclusive input but
isn't an overlay layer surface.
The renderer also renders all overlay surfaces in this situation,
not just one. This simplifies the code and fixes rendering when
there are more than one overlay surfaces (e.g. for a virtual
keyboard to type the lockscreen password).
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.