container_flatten removes the container from the tree (via
container_replace) before destroying it. When destroying, the recent
changes to handle_seat_node_destroy incorrectly assumes that the
container has a parent.
This adds a check for destroying a container which is no longer in the
tree. If this is the case, focus does not need to be changed.
* Click and hold a scrollbar
* Drag the cursor onto another surface
* While still holding the original button, press and release another
cursor button
* Things get weird
There's two ways to fix this. Either cancel the seat operation and do
the other click, or continue the seat operation and ignore the other
click. I opted for the latter (ignoring the click) because it's easier
to implement, and I suspect a second click during a seat operation is
probably unintentional anyway.
* Have multiple outputs
* Launch swaylock
* Unplug an output (possibly has to be the last "connected" one)
* The swaylock surface on the remaining output would not respond to key
events
This was happening because when the output destroys, focus was not given
to the other swaylock surface.
This patch makes focus be transferred to another surface owned by the
same Wayland client, but only if input was inhibited by the surface
being destroyed, and only if it's in the overlay layer. I figure it's
best to be overly specific and relax the requirements later if needed.
This patch removes a check in seat_set_focus_surface which was
preventing focus from being passed from a layer surface to any other
surface. I don't know of a use case for this check, but it's possible
that this change could produce issues.
Re-focus on the container on which the cursor hovers over. A
special case is, if there are menus or other subsurfaces open
in the focused container. It will prefer the focused container
as long as there are subsurfaces.
This commit starts caching the previous node as well as the
previous x/y cursor position. Re-calculating the previous
focused node by looking at the current state of the cursor
position does not work, if the environment changes.
* New configuration option: raise_floating
(From the discussion on https://github.com/i3/i3/issues/2990)
* By default, it still raises the window on focus, otherwise it
will raise the window on click.
To reproduce the problem, create layout
H[view V[view view view-focused]], then switch to another workspace and
have the previously focused view in the vsplit close (eg. using
criteria, or an mpv video finishing). Return to the workspace using
`$mod+<num>` and the entire vsplit would be focused. This happens
because handle_seat_node_destroy would only set a new focus if the
currently focused view or a parent was being destroyed. To fix it, it
needs to set a sibling of the destroying container to focus_inactive
regardless of the current focus, then restore current focus if needed.
This patch changes the function accordingly. Additionally:
* The function now makes an early return if the node being destroyed is
a workspace.
* set_focus has been renamed to needs_new_focus. This variable is true
if the head focus needs to be changed.
This replaces view.using_csd with a new border mode: B_CSD. This also
removes sway_xdg_shell{_v6}_view.deco_mode and
view->has_client_side_decorations as we can now get these from the
border.
You can use `border toggle` to cycle through the modes including CSD, or
use `border csd` to set it directly. The client must support the
xdg-decoration protocol, and the only client I know of that does is the
example in wlroots.
If the client switches from SSD to CSD without us expecting it (via the
server-decoration protocol), we stash the previous border type into
view.saved_border so we can restore it if the client returns to SSD. I
haven't found a way to test this though.
Firstly, a change had to be made to the container_at functions. If you
create layout `T[view H[view view]]` and hover the second tab, the
container_at functions would return the focus_inactive child. They now
return the split container itself. To compensate for this,
dispatch_cursor_button has been adjusted to find the focus_inactive
child before focusing it.
The actual implementation of wheel scrolling is pretty straightforward.
This uses handle_cursor_axis, so I took a similar approach to
handle_cursor_button (ie. creating a dispatch_cursor_axis function).
seat_get_active_child is used to get the active tiling child in a few
places, such as outputs getting their active workspace and
tabbed/stacked containers getting their visible child. When a workspace
uses a tabbed or stacked layout and contains a focused floating view,
calling seat_get_active_child on the workspace would incorrectly return
the floating view. This changes it so it will return the tiling child.
This fixes the following bug:
* Create layout T[view view] then float one of the views
* Attempt to click the tiling view to give it focus - it wouldn't work
because seat_get_active_child would return the floating view
* Make container_add_sibling's `after` argument a boolean.
* Use a constant for drop layout border
* Make thickness an int
* Add button state check
* Move comments in seat_end_move_tiling
These are the same as seat_set_focus, but accept a specific type rather
than using nodes. Doing this adds more typesafety and lets us avoid
using &con->node which looks a little ugly.
This fixes a crash that pretty much nobody would ever come across. If
you have a bindsym for "focus" with no arguments and run it from an
empty workspace, sway would crash because it assumes `container` is not
NULL.
seat_execute_command needs to check the flags on `binding_copy`, as
`binding` will be a dangling pointer after a reload command.
handle_keyboard_key needs to set the next_repeat_binding for
non-reloads prior to executing the command in case the binding is
freed by the reload command.
* Was crashing when a view was moved to the scratchpad (prev focus had
no parent).
* Was crashing when a hidden scratchpad view unmaps because it has no
workspace.
When changing focus from a view in one workspace to an empty workspace
using `focus <direction>`, the view in the previous workspace would keep
focused styling. This is because the check to unfocus it was only done
in the container case and not workspace case, so it's been moved out of
both.
This commit changes the meaning of sway_container so that it only refers
to layout containers and view containers. Workspaces, outputs and the
root are no longer known as containers. Instead, root, outputs,
workspaces and containers are all a type of node, and containers come in
two types: layout containers and view containers.
In addition to the above, this implements type safe variables. This
means we use specific types such as sway_output and sway_workspace
instead of generic containers or nodes. However, it's worth noting that
in a few places places (eg. seat focus and transactions) referring to
them in a generic way is unavoidable which is why we still use nodes in
some places.
If you want a TL;DR, look at node.h, as well as the struct definitions
for root, output, workspace and container. Note that sway_output now
contains a workspaces list, and workspaces now contain a tiling and
floating list, and containers now contain a pointer back to the
workspace.
There are now functions for seat_get_focused_workspace and
seat_get_focused_container. The latter will return NULL if a workspace
itself is focused. Most other seat functions like seat_get_focus and
seat_set_focus now accept and return nodes.
In the config->handler_context struct, current_container has been
replaced with three pointers: node, container and workspace. node is the
same as what current_container was, while workspace is the workspace
that the node resides on and container is the actual container, which
may be NULL if a workspace itself is focused.
The global root_container variable has been replaced with one simply
called root, which is a pointer to the sway_root instance.
The way outputs are created, enabled, disabled and destroyed has
changed. Previously we'd wrap the sway_output in a container when it is
enabled, but as we don't have containers any more it needs a different
approach. The output_create and output_destroy functions previously
created/destroyed the container, but now they create/destroy the
sway_output. There is a new function output_disable to disable an output
without destroying it.
Containers have a new view property. If this is populated then the
container is a view container, otherwise it's a layout container. Like
before, this property is immutable for the life of the container.
Containers have both a `sway_container *parent` and
`sway_workspace *workspace`. As we use specific types now, parent cannot
point to a workspace so it'll be NULL for containers which are direct
children of the workspace. The workspace property is set for all
containers, except those which are hidden in the scratchpad as they have
no workspace.
In some cases we need to refer to workspaces in a container-like way.
For example, workspaces have layout and children, but when using
specific types this makes it difficult. Likewise, it's difficult for a
container to get its parent's layout when the parent could be another
container or a workspace. To make it easier, some helper functions have
been created: container_parent_layout and container_get_siblings.
container_remove_child has been renamed to container_detach and
container_replace_child has been renamed to container_replace.
`container_handle_fullscreen_reparent(con, old_parent)` has had the
old_parent removed. We now unfullscreen the workspace when detaching the
container, so this function is simplified and only needs one argument
now.
container_notify_subtree_changed has been renamed to
container_update_representation. This is more descriptive of its
purpose. I also wanted to be able to call it with whatever container was
changed rather than the container's parent, which makes bubbling up to
the workspace easier.
There are now state structs per node thing. ie. sway_output_state,
sway_workspace_state and sway_container_state.
The focus, move and layout commands have been completely refactored to
work with the specific types. I considered making these a separate PR,
but I'd be backporting my changes only to replace them again, and it's
easier just to test everything at once.
Fixes#2568
The binding that gets stored in the keyboard's `repeat_binding` would
get freed on reload, leaving a dangling pointer.
Rather than attempt to unset the keyboard's `repeat_binding` along with
the other bindings, I opted to just not set it for the reload command
because there's no point in reloading repeatedly by holding the binding.
This disables repeat bindings for the reload command.
As we now need to detect whether it's a reload command in two places,
I've added a binding flag to track whether it's a reload or not.