May as well make it as easy as possible for users who are coming from
i3.
This also changes the `border` command to accept a thickness when
setting the border to normal. This makes it work the same way as the
`default_border` command. Eg. `border normal 5`
If sway is reloaded using a bindsym which has multiple commands, it
failed to detect the reload command, didn't create a duplicate of the
binding and would crash because the reload command frees the bindings.
For example:
mode system {
bindsym r reload, mode default
}
In this example, the binding->command is "reload, mode default".
Fixes#2545
When moving a container to an inactive workspace on a different output, this will change the focus on the destination output back to its last active workspace
* In layout command, arrange parent of parent - not sure why this is
needed but it is
* Remove gap adjustment when rendering
* Workspace should use outer gaps, not inner
* Add exceptions for tabbed and stacked containers
* Don't mess with gap state when splitting a container
When we have type safety we'll need to have functions for
workspace_add_tiling and so on. This means the existing container
functions will be just for containers, so they are being moved to
container.c. At this point layout.c doesn't contain much else, so I've
relocated everything and removed the file.
* container_swap and its static functions have been moved to the swap
command and made static.
* container_recursive_resize has been moved to the resize command and
made static.
* The following have been moved to container.c:
* container_handle_fullscreen_reparent
* container_insert_child
* container_add_sibling
* container_add_child
* container_remove_child
* container_replace_child
* container_split
* enum movement_direction and sway_dir_to_wlr have been moved to util.c.
Side note: Several commands included layout.h which then included
root.h. With layout.h gone, root.h has to be included by those commands.
* container_move is only called from the move command
* container_move_to was called from both the move command and the sticky
command, but the sticky command can easily not call it
* container_get_in_direction is only called from the focus command
Moving these functions to their respective commands gives better
separation of code and removes bloat from layout.c. These functions will
need to be refactored to take advantage of type safety, so separating
them will make this easier to refactor.
The following static functions have also been moved:
* is_parellel
* invert_movement
* move_offs
* container_limit
* workspace_rejigger
* move_out_of_tabs_stacks
* get_swayc_in_output_direction
They were all used by the move functions, except for the last one which
is used by focus.
Other changes:
* index_child has been renamed to container_sibling_index, moved to
container.c and made public
* sway_output_from_wlr has been renamed to output_from_wlr_output, moved
to output.c and made public
* container_handle_fullscreen_reparent has been made public
* sway_dir_to_wlr has been made public
No changes have been made to any of the moved functions, other than
updating calls to functions that have been renamed.
This changes the destroy functions to the following:
* output_begin_destroy
* output_destroy
* workspace_begin_destroy
* workspace_destroy
* container_begin_destroy
* container_destroy
* view_begin_destroy
* view_destroy
The terminology was `destroy` and `free`, and it has been changed to
`begin_destroy` and `destroy` respectively.
When the last output is disconnected, its workspaces will now be stashed
in the root. Upon connection of a new output they will be restored.
There is a new function `workspace_consider_destroy` which decides
whether the given workspace should be destroyed or not (ie. empty and
not visible).
Calling container_begin_destroy will no longer automatically reap the
parents. In some places we want to reap the parents and in some we
don't, so this is left to the caller.
container_reap_empty_recursive and container_reap_empty have been
combined into one function and it will recurse up the tree.
Previously we used a reparent event to detect when a view changes
parent, then sent an output enter/leave to the surfaces if needed. This
worked for tiling views but not floating views, as floating views can
intersect another output without changing parent.
The solution implemented for floating views also applies cleanly to
tiling views, so the previous method has been completely replaced and
the reparent event has been removed.
This introduces a new function container_discover_outputs. This function
compares the container's `current` position to the outputs, sends enter
and leave events as needed, and keeps track of which outputs it's
intersecting in a new `container->outputs` list. If it has entered a new
output with a different scale then the title and marks textures will
also be recreated at the new scale.
The function is called when a transaction applies. This is convenient as
it means we don't have to call it from various places.
There is imperfect rendering when a floating view overlaps two outputs
with different scales. It renders correctly for the most recently
entered output, but there is only one title texture so it renders
incorrectly on the old output.
Fixes#2482
Workspaces previously had a magical `workspace->floating` container,
which had a layout of L_FLOATING and whose children were actual floating
views. This allowed some conveniences, but was a hacky solution because
the container has to be exempt from focus, coordinate transactions with
the workspace, and omit emitting IPC events (which we didn't do).
This commit changes it to be a list directly in the sway_workspace. The
L_FLOATING layout is no longer used so this has been removed as well.
* Fixes incorrect check in the swap command (it checked if the
containers had the L_FLOATING layout, but this layout applied to the
magical container).
* Introduces workspace_add_floating
This introduces the following `for_each` functions:
* root_for_each_workspace
* root_for_each_container
* output_for_each_workspace
* output_for_each_container
* workspace_for_each_container
And introduces the following `find` functions:
* root_find_output
* root_find_workspace
* root_find_container
* output_find_workspace
* output_find_container
* workspace_find_container
* container_find_child
And removes the following functions:
* container_descendants
* container_for_each_descendant
* container_find
This change is preparing the way for demoting sway_container. Eventually
these functions will accept and return sway_outputs, sway_workspaces and
sway_containers (meaning a C_CONTAINER or C_VIEW).
This change also makes it easy to handle abnormalities like the
workspace floating list, root's scratchpad list and (once implemented)
root's saved workspaces list for when there's no connected outputs.
This commit renames container_sort_workspaces to output_sort_workspaces
and moves it to output.c.
This also renames container_wrap_children to workspace_wrap_children and
moves it to workspace.c. This function is only called with workspaces.
Fixes#2467.
This commit introduces seat_get_focus_inactive_floating to supplement
seat_get_focus_inactive_tiling, and uses it during `focus mode_toggle`
which fixes a focus bug.
This also refactors the seat_get_focus_inactive functions so that they
do their selection logic themselves rather than offloading it to
seat_get_focus_by_type which was getting bloated. seat_get_focus_by_type
is now removed.
Lastly, this commit changes seat_get_focus to just return the first
container in the focus stack rather than looping and calling
seat_get_focus_by_type.
* The OP_RESIZE seat operation has been renamed to OP_RESIZE_FLOATING,
and OP_RESIZE_TILING has been introduced.
* Similar to the above, seat_begin_resize and handle_resize_motion have
been renamed and tiling variants introduced.
* resize.c's resize_tiled has to be used, so container_resize_tiled has
been introduced in resize.c to allow external code to call it.
This allows for a color to be set when the wallpaper does not fill the
entire output. If specified, the fallback color is also used when the
image path is inaccessible.
Rationale: Sticky containers are always assigned to the visible
workspace.
The basic idea here is to check the destination's output (move.c:190).
But if the command was `move container to workspace x` then a workspace
might have been created for it. We could destroy the workspace in this
case, but that results in unnecessary IPC events.
To avoid this, the logic for `move container to workspace x` has been
adjusted. It now delays creating the workspace until the end, and uses
`workspace_get_initial_output` to determine and check the output before
creating it.
The back_and_forth condition is intended to be handled in the else-if
block, but this was never reached because it remained in the first
block's conditions.
container_move_to handled moving containers to new parents, as well as
moving workspaces to new outputs.
This commit removes the workspace-moving code from this function and
introduces workspace_move_to_output. Moving workspaces using
container_move_to only happened from the move command, so it's been
implemented as a static function in that file.
Simplifying container_move_to makes it easier for me to fix some issues
in #2420.
This creates a root.c and moves bits and pieces from elsewhere into it.
* layout_init has been renamed to root_create and moved into root.c
* root_destroy has been created and is called on shutdown
* scratchpad code has been moved into root.c, because hidden scratchpad
containers are stored in the root struct
wlroots uses wl_event_loop_add_signal to handle SIGUSR1 from Xwayland.
wl_event_loop_add_signal works by masking the signal and receiving it from a
signalfd. The signal mask is preserved across fork and exec, so subprocesses
spawned by Sway start with SIGUSR1 masked. Most subprocesses do not expect this
and never unmask the signal, resulting in missing functionality or unexpected
behavior for processes that use SIGUSR1 (such as i3status).
Fix this by unmasking all signals between fork and exec.
When a container is moved from, say, workspace 1 to workspace 2, workspace 2 is focused in order to arrange the windows before focus is moved back to workspace 1, which caused a workspace:focus event from workspace 2 to workspace 1 to be emitted. This commit inhibits that event.
Also fixes a crash when unfloating a window. It needs to add it back to
the tiling tree as a sibling rather than a child, because the reference
container might be a view.
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.
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.
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.
Implements the following commands:
* move scratchpad
* scratchpad show
* [criteria] scratchpad show
Also fixes these:
* Fix memory leak when executing command with criteria
(use `list_free(views)` instead of `free(views)`)
* Fix crash when running `move to` with no further arguments
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.
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.