This introduces seat_set_raw_focus: a function that manipulates the
focus stack without doing any other behaviour whatsoever. There are a
few places where this is useful, such as where we set focus_inactive
followed by another call to set the real focus again. With this change,
the notify argument to seat_set_focus_warp is also removed as these
cases now use the raw function instead.
A bonus of this is we are no longer emitting window::focus IPC events
when setting focus_inactive, nor are we sending focus/unfocus events to
the surface.
This also fixes the following:
* When running `move workspace to output <name>` and moving the last
workspace from the source output, the workspace::focus IPC event is no
longer emitted for the newly created workspace.
* When splitting the currently focused container, unfocus/focus events
will not be sent to the surface when giving focus_inactive to the newly
created parent, and window::focus events will not be emitted.
* The loop functions are now prefixed with `loop_`.
* It is now easy to add timers to the loop.
* Timers are implemented using pollfd and timerfd, rather than manually
checking them when any other event happens to arrive.
Since wayland does not currently allow swaybar to create global
keybinds, this is handled within sway and sent to the bar using a custom
event, so as not to pollute existing events, called bar_state_update.
As well as adding the hidden_state property to the bar config struct,
this commit handles barconfig_update events when the mode or
hidden_state changes, and uses a new function determine_bar_visibility
to hide or show the bar as required, using, respectively,
destroy_layer_surface, which is also newly added, and add_layer_surface,
which has been changed to allow dynamically adding the surface.
This distinguishes the binding mode from the distinct config mode, as
well as removing mode_pango_markup from the config struct where it
should not be present.
While allowing negative values for the outer gaps it is still prevented that negative values move windows out of the container. This replaces the non-i3 option for edge_gaps.
Returning a boolean from container_resize_tiled and resize_tiled doesn't
work in all cases. This patch changes it back to void and does a
before/after check to see if the container was resized.
This introduces a new view_impl function: is_transient_for. Similar to
container_has_ancestor but works using the surface parents rather than
the tree.
This patch modifies view_is_visible, container_at and so on to allow
transient views to function normally when they're in front of a
fullscreen view.
This patch makes it so when you run reload, the actual reloading is
deferred to the next time the event loop becomes idle. This avoids
several use-after-frees and removes the workarounds we have to avoid
them.
When you run reload, we validate the config before creating the idle
event. This is so the reload command will still return an error if there
are validation errors. To allow this, load_main_config has been adjusted
so it doesn't apply the config if validating is true rather than
applying it unconditionally.
This also fixes a memory leak in the reload command where if the config
failed to load, the bar_ids list would not be freed.
The previous behaviour was to damage the entire view, which would
recurse into each popup. This patch makes it damage only the popup's
surface, and respect the surface damage given by the client.
This adds listeners to the popup's map and unmap events rather than
doing the damage in the create and destroy functions. To get the popup's
position relative to the view, a new child_impl function get_root_coords
has been introduced, which traverses up the parents.
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.
Fixes `hide_edge_borders smart` when gaps are in use.
Implements `hide_edge_borders smart_no_gaps` and `smart_borders
on|no_gaps|off`.
Since `smart_borders on` is equivalent to `hide_edge_borders smart`
and `smart_borders no_gaps` is equivalent to `hide_edge_borders
smart_no_gaps`, I opted to just save the last value set for
`hide_edge_borders` and restore that on `smart_borders off`. This
simplifies the conditions for setting the border.
This changes our gaps implementation to behave like i3-gaps.
Our previous implementation allowed you to set gaps on a per container
basis. This isn't supported by i3-gaps and doesn't seem to have a
practical use case. The gaps_outer and gaps_inner properties on
containers are now removed as they just read the gaps_inner from the
workspace.
`gaps inner|outer <px>` no longer changes the gaps for all workspaces.
It only sets defaults for new workspaces.
`gaps inner|outer current|workspace|all set|plus|minus <px>` is now
runtime only, and the workspace option is now removed. `current` now
sets gaps for the current workspace as opposed to the current container.
`workspace <ws> gaps inner|outer <px>` is now implemented. This sets
defaults for a workspace.
This also fixes a bug where changing the layout of a split container
from linear to tabbed would cause gaps to not be applied to it until you
switch to another workspace and back.
When we eventually implement `workspace <ws> gaps inner|outer <px>`,
we'll need to store the gaps settings for workspaces before they're
created. Rather than create a workspace_gaps struct, the approach I'm
taking is to rename workspace_outputs to workspace_configs and then add
gaps settings to that.
I've added a lookup function workspace_find_config. Note that we have a
similar thing for outputs (output_config struct and output_find_config).
Lastly, when freeing config it would create a memory leak by freeing the
list items but not the workspace or output names inside them. This has
been rectified using a free_workspace_config function.
This involves setuid'ing swaylock, which then forks and drops perms on
the parent process. The child process remains root and listens on a pipe
for requests to validate passwords against /etc/shadow.
This does the following:
* Removes the xdg-decoration surface_commit listener. I was under the
impression the client could ignore the server's preference and set
whatever decoration they like using this protocol, but I don't think
that's right.
* Adds a listener for the xdg-decoration request_mode signal. The
protocol states that the server should respond to this with its
preference. We'll always respond with SSD here.
* Makes it so tiled views which use CSD will still have sway decorations
rendered. To do this, using_csd had to be added back to the view struct,
and the border is changed when floating or unfloating a view.
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.
This adds a `con` argument to `execute_command` which allows you to
specify the container to execute the command on. In most cases it leaves
it as `NULL` which makes it use the focused node. We only set it when
executing `for_window` criteria such as when a view maps. This means we
don't send unnecessary IPC focus events, and fixes a crash when the
criteria command is `move scratchpad` (because we can't give focus to a
hidden scratchpad container).
Each of the shell map handlers now check to see if the view has a
workspace. It won't have a workspace if criteria has moved it to the
scratchpad.
Fixes#2674.
The cause of the issue was in get_pango_layout. When we call
pango_parse_markup, `text` is the escaped string, and the unescaped
string is then computed and written to `buf`. We were then passing the
unescaped string to pango_layout_set_markup, but this function needs the
escaped string. `buf` is not needed and has been removed.
The other part of this PR refactors escape_markup_text to remove the
dest_length argument and removes the -1 return value on error. It now
assumes that you've allocated dest to the correct length.
This now correctly handles an incoming json infinite array by shifting
most of the heavy listing to the json-c parser, as well as sending
multiple statuses at once. It also removes the struct
i3bar_protocol_state and moves its members into the status_line struct,
allowing the same buffer to be used for both protocols.
This now uses getline to correctly handle multiple or long statuses. It
also removes the struct text_protocol_state and moves its members into
the status_line struct.
This prevents blocks from being destroyed before their hotspots are destroyed,
in case it is used for a pending click event that fires between the bar
receiving a new status, which destroys the block, and the bar rendering the new
status, which destroys the hotspot; this problem can be easily produced by
scrolling on a block that immediately causes a new status to be sent, with
multiple outputs
* 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
This does the following:
* Adds a baseline argument to get_text_size (the baseline is the
distance from the top of the texture to the baseline).
* Stores the baseline in the container when calculating the title
height.
* Takes the baseline into account when calculating the config's max font
height.
* When rendering, pads the textures according to the baseline so they
line up.
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.
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.
This commit changes the arrange code in a way that will support type
safe arguments.
The arrange_output et al functions are now public, however I opted not
to use them directly yet. I've kept the generic arrange_windows there
for convenience until type safety is fully implemented. This means this
patch has much less risk of breaking things as it would otherwise.
To be type safe, arrange_children_of cannot exist in its previous form
because the thing passed to it could be either a workspace or a
container. So it's now renamed to arrange_children and accepts a list_t,
as well as the parent layout and parent's box.
There was some code which checked the grandparent's layout to see if it
was tabbed or stacked and adjusted the Y offset of the grandchild
accordingly. Accessing the grandparent layout isn't easy when using type
safe arguments, and it seemed odd to even need to do this. I determined
that this was needed because a child of a tabbed container would have a
swayc Y matching the top of the tab bar. I've changed this so a child of
a tabbed container will have a swayc Y matching the bottom of the tab
bar, which means we don't need to access the grandparent layout. Some
tweaks to the rendering and autoconfigure code have been made to
implement this, and the container_at code appears to work without
needing any changes.
arrange_children_of (now arrange_children) would check if the parent had
gaps and would copy them to the child, effectively making the
workspace's gaps recurse into all children. We can't do this any more
without passing has_gaps, gaps_inner and gaps_outer as arguments to
arrange_children, so I've changed the add_gaps function to retrieve it
from the workspace directly.
apply_tabbed_or_stacked_layout has been split into two functions, as it
had different logic depending on the layout.
Lastly, arrange.h had an unnecessary include of transaction.h. I've
removed it, which means I've had to add it to several other files.
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.
This list includes disabled outputs.
When sway_container is demoted, we'll need to store the root's children
(ie. enabled outputs) in the sway_root. It makes sense to put these in a
list called `outputs`, so I'm renaming the existing list in advance.
* 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 makes all debug options stored in a single struct rather than in
various places, changes/fixes the behaviour of existing options, and
introduces some new options.
* Fixes damage issues with `-Drender-tree` texture (by removing scissor)
* Offsets the render tree overlay's `y` position for those who have
swaybar at the top
* Replaces `-Ddamage=rerender` with `-Dnodamage`
* Replaces `-Ddamage=highlight` with `-Dhighlight-damage`
* Replaces `-Dtxn-debug` with `-Dtxn-wait`
* Introduces `-Dnoatomic`
* Removes the `create_time` and `ms_arranging` figures from transactions
and the log message. Transactions are created after arranging and the
create time is of no significance.
* Fixes `-Dtxn-debug` (now `-Dtxn-wait`) not working.
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.
This fixes a race condition flicker when unfloating a view which uses
client side decorations.
When the view is floated it has using_csd = true, so the decorations are
not drawn. When unfloating it it changes to false, but this change
wasn't part of transactions so it could potentially render the
decorations around the view while it's waiting for the transaction to
apply.
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 original purpose of this commit is to replace some for loops with
list_find. But while doing this I found the workspace_prev_next_impl
functions to be difficult to read and also contained a bug, so I
refactored them and fixed the bug.
To reproduce the bug:
* Have two outputs, where the left output has workspaces 1, 2, 3 and the
right output has workspaces 4, 5, 6. Make workspace 2 focused_inactive
and workspace 4 focused.
* Run `workspace prev`.
* Previously it would visit the left output, then apply `workspace prev`
to workspace 2, which focuses workspace 1.
* Now it will focus the rightmost workspace on the left output
(workspace 3).
The refactoring I made to the workspace functions are:
* Added the static keyword.
* They now accept an int dir rather than bool, to avoid an unnecessary
conversion.
* Rather than preparing start and end variables for the purpose of
iterating, just iterate everything.
* Replace for loops with list_find.
* Don't call workspace_output_prev_next_impl (this fixes the bug).
Commit 4b8e3a885b makes it so only one
transaction is committed (ie. configures sent) at a time. This commit
removes the now-unnecessary code which was used to support concurrent
committed transactions.
* Instead of containers storing a list of instructions which they've
been sent, it now stores a single instruction.
* Containers now have an ntxnrefs property. Previously we knew how many
references there were by the length of the instruction list.
* Instructions no longer need a ready property. It was used to avoid
marking an instruction ready twice when they were in a list, but this is
now avoided because there is only one instruction and we nullify the
container->instruction pointer when it's ready.
* When a transaction applies, we no longer need to consider releasing
and resaving the surface, as we know there are no other committed
transactions.
* transaction_notify_view_ready has been renamed to
view_notify_view_ready_by_serial to make it consistent with
transaction_notify_view_ready_by_size.
* Out-of-memory checks have been added when creating transactions and
instructions.
* 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.
* Removes container_floating_move_to_container, instead opting to put
that logic in container_move_to
* In the seat code, focusing a floating view now updates the pending
state only and lets the next transaction carry it over to the current
state. This is required, otherwise it would crash.
* When unfullscreening a floating container, an output check is now done
to see if it should center it.
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
Calling container_at_view fails an assertion if the container isn't a
view. Calling tiling_container_at works correctly, as that function
checks if the container is a view and calls container_at_view if so.
Fixes segfauls for any case where swaynag->outputs was not inititalized
including -h/--help, -v/--version, and invalid arguments.
Sets sane defaults for colors not given. Any color not given will
fallback to the default color values for type error.
Adds support for a hidpi cursor
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.
Fixes#2364.
Suppose a view is 600px wide, and we tell it to resize to 601px during a
resize operation. We create a transaction, save the 600px buffer and
send the configure. This buffer is saved into the associated
instruction, and is rendered while we wait for the view to commit a
601px buffer.
Before the view commits the 601px buffer, suppose we tell it to resize
to 602px. The new transaction will also save the buffer, but it's still
the 600px buffer because we haven't received a new one yet.
Then suppose the view commits its original 601px buffer. This completes
the first transaction, so we apply the 601px width to the container.
There's still the second (now only) transaction remaining, so we render
the saved buffer from that. But this is still the 600px buffer, and we
believe it's 601px. Whoops.
The problem here is we can't stack buffers like this. So this commit
removes the saved buffer from the instructions, places it in the view
instead, and re-saves the latest buffer every time the view completes a
transaction and still has further pending transactions.
As saved buffers are now specific to views rather than instructions, the
functions for saving and removing the saved buffer have been moved to
view.c.
The calls to save and restore the buffer have been relocated to more
appropriate functions too, favouring transaction_commit and
transaction_apply rather than transaction_add_container and
transaction_destroy.
Fixes the render and container_at order for popups.
Fixes#2210
For rendering:
* render_view_surfaces has been renamed to render_view_toplevels
* render_view_toplevels now uses output_surface_for_each_surface (which
is now public), as that function uses wlr_surface_for_each_surface which
doesn't descend into popups
* Views now have a for_each_popup iterator, which is used by the
renderer to render the focused view's popups
* When rendering a popup, toplevels (xdg subsurfaces) of that popup are
also rendered
For sending frame done, the logic has been updated to match the
rendering logic:
* send_frame_done_container no longer descends into popups
* for_each_popup is used to send frame done to the focused view's popups
and their child toplevels
For container_at:
* floating_container_at is now static, which means it had to be moved
higher in the file.
* container_at now considers popups for the focused view before checking
containers.
* tiling_container_at has been introduced, so that it doesn't call
container_at recursively (it would check popups recursively if it did)
Now 'repeat_delay' and 'repeat_rate' control the initial delay
and rate (per second) of repeated binding invocations.
If the repeat delay is zero, binding repetition is disabled.
When the repeat rate is zero, the binding is repeated exactly
once, assuming no other key events intervene.
Each sway_keyboard is provided with a wayland timer event source.
When a valid keypress binding has been found, a callback to
handle_keyboard_repeat is set. Any key event will either clear
the callback or (if the new key event is a valid keypress binding)
delay the callback again.
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.
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 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).
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 allows to update the title even if the view doesn't commit.
This is useful e.g. when a terminal sets its toplevel title to
the currently running command and when the view isn't visible.
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.
As well as ignoring scroll events on status elements when click_events
is enabled.
Previously, using the scroll wheel on a workspace button would switch to
that workspace instead of scrolling through them. Clicks and scrolling
on status elements would always be processed by swaybar, too. So in case
you were using scrolling as volume control on a status item, swaybar
would additionally scroll through your workspaces.
This removes the urgency stuff from the commit handler and puts it in a
new set_hints handler instead. This allows the xwayland surface to
become urgent without having to commit (which doesn't happen if it's on
an non-visible 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).
We currently have several ways of setting debug flags, including command
line arguments, environment variables, and compile-time macros. This
replaces the lot with command line flags.
This PR changes the way we handle transactions to a more simple method.
The new method is to mark containers as dirty from low level code
(eg. arranging, or container_destroy, and eventually seat_set_focus),
then call transaction_commit_dirty which picks up those containers and
runs them through a transaction. The old methods of using transactions
(arrange_and_commit, or creating one manually) are now no longer
possible.
The highest-level code (execute_command and view implementation
handlers) will call transaction_commit_dirty, so most other code just
needs to set containers as dirty. This is done by arranging, but can
also be done by calling container_set_dirty.
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.
The only user of this function would copy the string right away
to get rid of the const flag anyway, and freeing a const string
afterwards might work but is not meant to be done according to the
json-c API.
wl_event_source_remove() is illegal after display has been destroyed,
so just destroy everything when we still can.
==20392==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000001240 at pc 0x00000048e86e bp 0x7ffe4b557e00 sp 0x7ffe4b557df0
READ of size 8 at 0x607000001240 thread T0
#0 0x48e86d in wl_list_insert ../common/list.c:149
#1 0x7fdf673d4d7d in wl_event_source_remove src/event-loop.c:487
#2 0x41b742 in ipc_terminate ../sway/ipc-server.c:94
#3 0x40b1ad in main ../sway/main.c:440
#4 0x7fdf6664c18a in __libc_start_main ../csu/libc-start.c:308
#5 0x409359 in _start (/opt/wayland/bin/sway+0x409359)
0x607000001240 is located 48 bytes inside of 72-byte region [0x607000001210,0x607000001258)
freed by thread T0 here:
#0 0x7fdf692c4880 in __interceptor_free (/lib64/libasan.so.5+0xee880)
#1 0x7fdf673d371a in wl_display_destroy src/wayland-server.c:1097
previously allocated by thread T0 here:
#0 0x7fdf692c4c48 in malloc (/lib64/libasan.so.5+0xeec48)
#1 0x7fdf673d4d9e in wl_event_loop_create src/event-loop.c:522
#2 0x40acb2 in main ../sway/main.c:363
#3 0x7fdf6664c18a in __libc_start_main ../csu/libc-start.c:308
When you spawn a process with the exec command, sway now notes the
workspace you had focused and the pid of the child process, then assigns
that workspace to the child when its window appears.
Some of this is carried over from sway 0.15, but with some major
refactoring and centralization of state.
Rather than allocate a structure and expect callers to free it, take a
pointer to an existing struct as an argument.
This function is no longer called anywhere though.
Both sway_output and sway_layer_shell listen to wlr's output destroy event,
but sway_layer_shell needs to access into sway_output's data strucure and needs
to be destroyed first.
Resolve this by making sway_layer_shell listen to a new event that happens at
start of sway_output's destroy handler
Some operations during backend creation (e.g. becoming DRM master)
require CAP_SYS_ADMIN privileges. At this point, sway has dropped them
already, though. This patch splits the privileged part of server_init
into its own function and calls it before dropping its privileges.
This fixes the bug with minimal security implications.
* 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.
Sort the list comprising the set of keys for the binding in ascending
order. (Keyboard shortcuts depend only on the set of simultaneously
pressed keys, not their order, so this change should have no external
effect.) This simplifies comparisons between bindings.
* The arrange_foo functions are now replaced with arrange_and_commit, or
with manually created transactions and arrange_windows x2.
* The arrange functions are now only called from the highest level
functions rather than from both high level and low level functions.
* Due to the previous point, view_set_fullscreen_raw and
view_set_fullscreen are both merged into one function again.
* Floating and fullscreen are now working with transactions.
The whole state->xcb.modifiers thing didn't work at all (always 0)
The xkb doc says "[xkb_state_serialize_mods] should not be used in
regular clients; please use the xkb_state_mod_*_is_active API instead"
so here it is
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.
* Add and use lenient_strcat and lenient_strncat functions
* Rename `concatenate_child_titles` function as that's no longer what it
does
* Rename `container_notify_child_title_changed` because we only need to
notify that the tree structure has changed, not titles
* Don't notify parents when a child changes its title
* Update ancestor titles when changing a container's layout
* Eg. create nested tabs and change the inner container to stacking
* No need to store tree presentation in both container->name and
formatted_title
Swayidle handles idle events and allows
for dpms and lockscreen handling. It also
handles systemd sleep events, and can
raise a lockscreen on sleep
Fixes#541
The criteria struct now uses properties for each token type rather than
the list_t list of tokens. The reason for this is that different token
types have different data types: pcre, string and number to name a few.
This solution should be more flexible moving forward. A bonus of this is
that criteria is now easier to understand when looking at the struct
definition.
The criteria parser has been rewritten because the previous one didn't
support valueless pairs (eg. [class="foo" floating]).
Criteria now has types. Types at the moment are CT_COMMAND,
CT_ASSIGN_WORKSPACE and CT_ASSIGN_OUTPUT. i3 uses types as well.
Previously the assign command was creating a criteria with 'move to
workspace <name>' as its command, but this caused the window to appear
briefly on the focused workspace before being moved to the assigned
workspace. It now creates the view directly in the assigned workspace.
Each view will only execute a given criteria once. This is achieved by
storing a list of executed criteria in the view. This is the same
strategy used by i3.
Escaping now works properly. Previously you could do things like
[class="Fire\"fox"] and the stored value would be 'Fire\"fox', but it
should be (and now is) 'Fire"fox'.
The public functions in criteria.c are now all prefixed with criteria_.
Xwayland views now listen to the set_title, set_class and
set_window_type events and criteria will be run when these happen. XDG
shell has none of these events so it continues to update the title in
handle_commit.
Each view type's get_prop function has been split into get_string_prop
and get_int_prop because some properties like the X11 window ID and
window type are numeric.
The following new criteria tokens are now supported:
* id (X11 window ID)
* instance
* tiling
* workspace
This implements the title_format command, with a new placeholder %shell
which gets substituted with the view type (xwayland, xdg_shell_v6 or
wl_shell).
Example config:
for_window [title=".*"] title_format %title (class=%class instance=%instance shell=%shell)
Implements rendering of borders. Title text is still to do.
Implements the following configuration directives:
* client.focused
* client.focused_inactive
* client.unfocused
* client.urgent
* border
* default_border
Replaces arrange_windows() with arrange_root(), arrange_output(),
arrange_workspace() and arrange_children_of().
Also makes fullscreen views save and restore their dimensions, which
allows it to preserve any custom resize and is also a requirement for
floating views once they are implemented.
- Replace char* with static array. Any chars > 1024 will be discarded.
- mlock() password buffer so it can't be written to swap.
- Clear password buffer after auth succeeds or fails.
This is basically the same treatment I gave the 0.15 branch in https://github.com/swaywm/sway/pull/1519
The exact semantics of this command are complicated. I'll describe each
test scenario as s-expressions. Everything assumes L_HORIZ if not
specified, but if you rotate everything 90 degrees the same test cases
hold.
```
(container (view a) (view b focus) (view c))
-> move left
(container (view b focus) (view a) (view c))
(container (view a) (view b focus) (view c))
-> move right
(container (view a) (view c) (view b focus))
(container L_VERT (view a))
(container L_HORIZ
(view b) (view c focus))
-> move up
(container L_VERT
(view a) (view c focus))
(container L_HORIZ (view b))
(workspace
(view a) (view b focus) (view c))
-> move up
(workspace [split direction flipped]
(view b focus)
(container (view a) (view c)))
(workspace
(view a) (view b focus) (view c))
-> move down
(workspace [split direction flipped]
(container (view a) (view c))
(view b focus)))
Note: outputs use wlr_output_layout instead of assuming that i+/-1 is
the next output in the move direction.
(root
(output X11-1
(workspace 1))
(output X11-2
(workspace 1 (view a focus) (view b)))))
-> move left
(root
(output X11-1
(workspace 1 (view a focus)))
(output X11-2
(workspace 1 (view b)))))
(root
(output X11-1
(workspace 1
(container (view a) (view b)))
(output X11-2
(workspace 1 (view c focus)))))
-> move left
(root
(output X11-1
(workspace 1
(container (view a) (view b))
(view c focus)))
(output X11-2
(workspace 1)))
```