`i3 4.16` allows users to list multiple outputs for a workspace and the
first available will be used. The syntax is as follows:
`workspace <workspace> output <outputs...>`
Additionally when the workspace is created, the outputs get added to the
output priority list in the order specified. This ensures that if a higher
output gets connected, the workspace will move to the higher output. This
works the same way as if the user had a workspace on an output, disconnected
the output, and then later reconnected the output.
Currently, variables cannot contain commands and cannot span more than
one argument. This is due to variable replacement happening after
determining the handler and after splitting the config line into
arguments.
This changes the process to:
0. Check for empty lines and block boundaries
1. Split the arguments as before
2. Verify that the first argument is not a variable. If needed the
following occurs
a. Perform variable replacement on just the first argument
b. Join the arguments back together then split the arguments again. This is needed when the variable
contains the command and arguments for the command.
3. Determine the handler
4. If the handler is cmd_set, escape the variable name so that it does
not get replaced
5. Join the arguments back together, do variable replacement on the full
command, and split the arguments again
6. Perform any needed quote stripping or unescaping on arguments
7. Run the command handler
This allows for config snippets such as:
```
set $super bindsym Mod4
$super+a exec some-command
```
and
```
set $bg bg #ffffff solid_color
output * $bg
```
This implements the following syntaxes from `i3 4.16`:
* `resize set [width] <width> [px|ppt]`
* `resize set height <height> [px|ppt]`
* `resize set [width] <width> [px|ppt] [height] <height> [px|ppt]`
Additionally, a bug was fixed that caused setting the height of a tiled
container to change the width instead due to a typo.
This introduces the following command extensions from `i3-gaps`:
* `gaps horizontal|vertical|top|right|bottom|left <amount>`
* `gaps horizontal|vertical|top|right|bottom|left all|current
set|plus|minus <amount>`
* `workspace <ws> gaps horizontal|vertical|top|right|bottom|left
<amount>`
`inner` and `outer` are also still available as options for all three
of the above commands. `outer` now acts as a shorthand to set/alter
all sides.
Additionally, this fixes two bugs with the prevention of invalid gap
configurations for workspace configs:
1. If outer gaps were not set and inner gaps were, the outer gaps
would be snapped to the negation of the inner gaps due to `INT_MIN`
being less than the negation. This took precedence over the default
outer gaps.
2. Similarly, if inner gaps were not set and outer gaps were, inner
gaps would be set to zero, which would take precedence over the
default inner gaps.
Fixing both of the above items also requires checking the gaps again
when creating a workspace since the default outer gaps can be smaller
than the negation of the workspace specific inner gaps.
This commit enhances the output transform
command with options for a relative transform,
i.e. the provided transform will be applied as
an offset to the current transform. Append
`clockwise` to rotate clockwise from the current
rotation, or `anticlockwise` to rotate in the
opposite direction.
For example, if the output LVDS-1 is rotated
90 degrees clockwise, the command
`output LVDS-1 transform 90 clockwise`
will rotate the display to 180 degrees.
All transform options are supported,
including flipped transforms.
Relative transforms can only be applied to
a single output and cannot be used with
a wildcard (*) output specifier.
The exec_always command was executed twice, since it was not checking for the
config->validating variable.
Fix this by defering the command if the configuration is validating.
Fixes#3072
It appears that the focus code that handles `focus_wrapping yes` was
removed during the conversion to type safety. This re-implements the
focus code for when `focus_wrapping` is set to `yes` (default). Neither
the `no` or `force` options appear to be effected and should be working.
There's no point having both movement_direction and wlr_direction. This
replaces the former with the latter.
As movement_direction also contained MOVE_PARENT and MOVE_CHILD items,
these are now checked specifically in the focus command and handled in
separate functions, just like the other focus variants.
The previous pull request #2993 tried to fix this by moving the function which
used the layers after the initilization.
Since this initialization is done unconditionally only depending on the struct
definition, move the layer initialization to the beginning of the function.
Also move the signal initialization of the destroy event.
Fixes#2992
input_manager_set_focus is used to set the focus after mapping the view in
view_map. This needs to consider to warp the cursor as well, since for
WARP_CONTAINER, the cursor should warp to the newly created view.
i3 seems to make all window properties, with the exception of
transient_for, optional[1].
[1]: 315ff17563/src/ipc.c (L435-L450)
Signed-off-by: Franklin "Snaipe" Mathieu <snaipe@diacritic.io>
It turns out that i3 does not have a `class` key in the json description
of a view, but provides it through `window_properties.class`. Since
`window_properties` has been added by 8fc9328, we can remove `class`
altogether.
Signed-off-by: Franklin "Snaipe" Mathieu <snaipe@diacritic.io>
In i3, when a child of a tabbed or stacked container has no siblings,
its border settings are respected.
This patch achieves the same effect by rendering a lone tabbed/stacked
child as if it's a linear container. This makes the border settings be
respected.
Over in view_autoconfigure, we compensate for this by only adjusting
`y_offset` if there's multiple children.
The code being changed is responsible for updating the focus stack when
a container is destroyed in a different part of the tree to where the
real focus is. It's attempting to set focus_inactive to a sibling (or
parent if no siblings) of the container that is being destroyed, then
put our real focus back on the end of the focus stack.
The problem occurs when the container being destroyed is in a different
workspace. For example:
* Have a focused view on workspace 1
* Have workspace 2 not visible with a single view that is unmapping
* The first call to seat_set_raw_focus sets focus to workspace 2 because
it's the parent
* Prior to this patch, the second call to seat_set_raw_focus would set
focus to the view on workspace 1
* Later, when using output_get_active_workspace, this function would
return workspace 2 because it's the first workspace it finds in the
focus stack.
To fix this, workspace 1 must be placed on the focus stack between
workspace 2 and the focused view. That's what this patch does.
Lastly, it also uses seat_get_focus_inactive to choose the focus. This
fixes a crash when a view unmaps while a non-container is focused (eg.
swaylock), because focus is NULL.
When a floating container is tiled (e.g.: 'floating toggle' or
'floating disable'), it should be placed after/below the inactive
focused container from the tiling layout.
This approaches cursor rebasing from a different angle. Rather than
littering the codebase with cursor_rebase calls and using transaction
callbacks, this just runs cursor_rebase after applying every transaction
- but only if there's outputs connected, because otherwise it causes a
crash during shutdown.
There is one known case where we still need to call cursor_rebase
directly, and that's when running `seat seat0 cursor move ...`. This
command doesn't set anything as dirty so no transaction occurs.
This fixes a regression introduced by
662466e8db. When adding a container to the
scratchpad, setting container->scratchpad = true before
container_set_floating made container_set_floating believe that the
container was already floating. This fixes it by setting the property
afterwards instead.
For example, create layout H[view T[view view view]], focus the view in
the hsplit and scroll the mouse wheel over the tab title bars. Prior to
this patch, focus would be given to a descendant of the tabbed
container. This patch keeps the focus on the hsplit view.
This also renames some of the variables used in this part of the code to
make it be easier to follow.
I originally put the rebase at the end of view_map, but at this point
the view is still at its native size and will ignore the motion event if
it falls outside of its native size. The only way to do this properly is
to rebase the cursor later - either after sending the configure, after
the view commits with the new size, or after applying the transaction. I
chose to do it after applying the transaction for simplicity.
I then attempted to just call cursor_rebase after applying every
transaction, but this causes crashes when exiting sway (and possibly
other places) because cursor_rebase assumes the tree is in a valid
state.
So my chosen solution introduces transaction_commit_dirty_with_callback
which allows handle_map to register a callback which will run when the
transaction is applied.
Prior to this patch, creating a tabbed container with two views,
switching tab and then scrolling without motion would cause the scroll
events to be sent to the old focus. To fix this, rebasing the cursor is
needed after changing focus.
window_properties is documented to contain a subset of the X11 properties
of a window (its title, class, instance, role, and transient ID). This
commit adds the missing json object from the get_tree output for
xwayland windows only.
This is a follow-up of #2911.
Signed-off-by: Franklin "Snaipe" Mathieu <me@snai.pe>
The cursor's image would be removed or set when the seat's capabilities
were updated, but there was nothing to prevent the image from being set
at other times.
The peeked and expanded line log entries were useful during the switch
to generic code blocks and subcommands. However, it has been a while
since those were introduced and the log entries are no longer helpful
for any remaining issues with config parsing. Instead of keeping them
as clutter in the log, they can just be removed.
Firstly, the container was wrongly identifying as a tiling container
because it had no workspace.
Secondly, when calculating the maximum possible size we can't use the
workspace if it's not there, so we'll allow unlimited size in this case.
QT unmaps the view before destroying the popup. We destroyed the popup
in response to the view unmapping, but then we'd attempt to destroy it a
second time which caused a crash.
The patch removes the listener.
I tested it with GTK as well, and can confirm the popup is still being
destroyed.
Setting normal focus to the fullscreen view causes the old workspace to
start destroying. We then set focus to the old workspace which is no
longer attached in the tree.
As we are only setting focus_inactive on the fullscreen container, the
fix uses seat_set_raw_focus to avoid all the additional behaviour that
comes with it such as destroying the old workspace.
When the config gets reloaded, the font height and baseline get reset to
0. If the config does not have a font command in it, the variables will
remain at 0 causing a transparent area where the title would be
rendered.
This makes it so the font height and baseline are recalculated. Additionally,
since the font height and baseline may have changed due to the reload, the
title and marks textures are rebuilt.
* When using multiple seats, each seat has its own prev_workspace_name
for the purpose of workspace back_and_forth.
* Removes prev_workspace_name global variable.
* Removes unused next_name_map function in tree/workspace.c.
* Fixes memory leak in seat_destroy (seat was not freed).
The idea here is we don't want users to be blissfully unaware that they
are running unsupported drivers. So we abort on startup, and force the
user to add a specific argument to bypass the check.