2017-12-08 13:22:26 +01:00
|
|
|
#define _XOPEN_SOURCE 700
|
2018-04-27 18:30:45 +02:00
|
|
|
#include <math.h>
|
2017-12-10 17:11:47 +01:00
|
|
|
#ifdef __linux__
|
|
|
|
#include <linux/input-event-codes.h>
|
|
|
|
#elif __FreeBSD__
|
|
|
|
#include <dev/evdev/input-event-codes.h>
|
|
|
|
#endif
|
2018-07-18 08:13:28 +02:00
|
|
|
#include <limits.h>
|
2017-12-08 13:22:26 +01:00
|
|
|
#include <wlr/types/wlr_cursor.h>
|
2017-12-09 20:06:00 +01:00
|
|
|
#include <wlr/types/wlr_xcursor_manager.h>
|
2018-04-17 09:54:02 +02:00
|
|
|
#include <wlr/types/wlr_idle.h>
|
2018-10-15 16:18:46 +02:00
|
|
|
#include <wlr/types/wlr_box.h>
|
2017-12-10 14:48:44 +01:00
|
|
|
#include "list.h"
|
2017-12-08 13:22:26 +01:00
|
|
|
#include "log.h"
|
2018-07-25 13:32:20 +02:00
|
|
|
#include "config.h"
|
2018-08-10 06:10:09 +02:00
|
|
|
#include "sway/commands.h"
|
2018-07-18 08:13:28 +02:00
|
|
|
#include "sway/desktop.h"
|
2018-07-15 07:20:21 +02:00
|
|
|
#include "sway/desktop/transaction.h"
|
2018-03-30 21:33:16 +02:00
|
|
|
#include "sway/input/cursor.h"
|
2018-07-18 08:13:28 +02:00
|
|
|
#include "sway/input/keyboard.h"
|
2018-03-31 03:03:35 +02:00
|
|
|
#include "sway/layers.h"
|
2018-03-30 21:33:16 +02:00
|
|
|
#include "sway/output.h"
|
2018-07-18 08:13:28 +02:00
|
|
|
#include "sway/tree/arrange.h"
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
#include "sway/tree/container.h"
|
2018-08-26 04:05:16 +02:00
|
|
|
#include "sway/tree/root.h"
|
2018-03-30 21:33:16 +02:00
|
|
|
#include "sway/tree/view.h"
|
2018-04-18 00:35:28 +02:00
|
|
|
#include "sway/tree/workspace.h"
|
2018-03-31 03:03:35 +02:00
|
|
|
#include "wlr-layer-shell-unstable-v1-protocol.h"
|
2017-12-08 13:22:26 +01:00
|
|
|
|
2018-09-12 00:46:46 +02:00
|
|
|
// When doing a tiling drag, this is the thickness of the dropzone
|
|
|
|
// when dragging to the edge of a layout container.
|
|
|
|
#define DROP_LAYOUT_BORDER 30
|
|
|
|
|
2018-09-30 12:58:49 +02:00
|
|
|
static uint32_t get_current_time_msec(void) {
|
2018-04-21 15:07:22 +02:00
|
|
|
struct timespec now;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
|
|
return now.tv_nsec / 1000;
|
|
|
|
}
|
|
|
|
|
2018-03-31 03:03:35 +02:00
|
|
|
static struct wlr_surface *layer_surface_at(struct sway_output *output,
|
|
|
|
struct wl_list *layer, double ox, double oy, double *sx, double *sy) {
|
|
|
|
struct sway_layer_surface *sway_layer;
|
|
|
|
wl_list_for_each_reverse(sway_layer, layer, link) {
|
|
|
|
struct wlr_surface *wlr_surface =
|
|
|
|
sway_layer->layer_surface->surface;
|
|
|
|
double _sx = ox - sway_layer->geo.x;
|
|
|
|
double _sy = oy - sway_layer->geo.y;
|
|
|
|
// TODO: Test popups/subsurfaces
|
2018-03-31 05:08:24 +02:00
|
|
|
if (wlr_surface_point_accepts_input(wlr_surface, _sx, _sy)) {
|
2018-03-31 03:03:35 +02:00
|
|
|
*sx = _sx;
|
|
|
|
*sy = _sy;
|
|
|
|
return wlr_surface;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-03-30 22:12:02 +02:00
|
|
|
/**
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
* Returns the node at the cursor's position. If there is a surface at that
|
2018-03-31 03:03:35 +02:00
|
|
|
* location, it is stored in **surface (it may not be a view).
|
2018-03-30 22:12:02 +02:00
|
|
|
*/
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
static struct sway_node *node_at_coords(
|
2018-05-26 08:26:10 +02:00
|
|
|
struct sway_seat *seat, double lx, double ly,
|
2018-03-30 21:33:16 +02:00
|
|
|
struct wlr_surface **surface, double *sx, double *sy) {
|
2018-01-14 19:19:21 +01:00
|
|
|
// check for unmanaged views first
|
2018-07-24 23:37:41 +02:00
|
|
|
#ifdef HAVE_XWAYLAND
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
struct wl_list *unmanaged = &root->xwayland_unmanaged;
|
2018-04-06 00:48:35 +02:00
|
|
|
struct sway_xwayland_unmanaged *unmanaged_surface;
|
|
|
|
wl_list_for_each_reverse(unmanaged_surface, unmanaged, link) {
|
2018-04-02 20:35:43 +02:00
|
|
|
struct wlr_xwayland_surface *xsurface =
|
2018-04-06 00:48:35 +02:00
|
|
|
unmanaged_surface->wlr_xwayland_surface;
|
2018-01-14 19:19:21 +01:00
|
|
|
|
2018-05-26 08:26:10 +02:00
|
|
|
double _sx = lx - unmanaged_surface->lx;
|
|
|
|
double _sy = ly - unmanaged_surface->ly;
|
2018-04-08 17:43:18 +02:00
|
|
|
if (wlr_surface_point_accepts_input(xsurface->surface, _sx, _sy)) {
|
2018-03-31 17:30:15 +02:00
|
|
|
*surface = xsurface->surface;
|
2018-04-08 17:43:18 +02:00
|
|
|
*sx = _sx;
|
|
|
|
*sy = _sy;
|
2018-03-31 17:30:15 +02:00
|
|
|
return NULL;
|
2018-01-14 19:19:21 +01:00
|
|
|
}
|
|
|
|
}
|
2018-07-24 23:37:41 +02:00
|
|
|
#endif
|
2018-03-30 21:33:16 +02:00
|
|
|
// find the output the cursor is on
|
2018-05-02 15:00:26 +02:00
|
|
|
struct wlr_output *wlr_output = wlr_output_layout_output_at(
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
root->output_layout, lx, ly);
|
2018-03-30 21:33:16 +02:00
|
|
|
if (wlr_output == NULL) {
|
|
|
|
return NULL;
|
2018-03-30 16:53:18 +02:00
|
|
|
}
|
2018-03-30 21:33:16 +02:00
|
|
|
struct sway_output *output = wlr_output->data;
|
2018-05-26 08:26:10 +02:00
|
|
|
double ox = lx, oy = ly;
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy);
|
2018-03-30 21:33:16 +02:00
|
|
|
|
|
|
|
// find the focused workspace on the output for this seat
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
struct sway_workspace *ws = output_get_active_workspace(output);
|
2018-03-30 21:33:16 +02:00
|
|
|
|
2018-03-31 03:03:35 +02:00
|
|
|
if ((*surface = layer_surface_at(output,
|
|
|
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
|
|
|
|
ox, oy, sx, sy))) {
|
2018-09-04 15:21:37 +02:00
|
|
|
return NULL;
|
2018-03-31 03:03:35 +02:00
|
|
|
}
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
if (ws->fullscreen) {
|
2018-10-07 12:40:05 +02:00
|
|
|
// Try transient containers
|
2018-10-08 15:00:36 +02:00
|
|
|
for (int i = 0; i < ws->floating->length; ++i) {
|
|
|
|
struct sway_container *floater = ws->floating->items[i];
|
|
|
|
if (container_is_transient_for(floater, ws->fullscreen)) {
|
|
|
|
struct sway_container *con = tiling_container_at(
|
|
|
|
&floater->node, lx, ly, surface, sx, sy);
|
|
|
|
if (con) {
|
|
|
|
return &con->node;
|
2018-10-07 12:40:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Try fullscreen container
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
struct sway_container *con =
|
|
|
|
tiling_container_at(&ws->fullscreen->node, lx, ly, surface, sx, sy);
|
|
|
|
if (con) {
|
|
|
|
return &con->node;
|
|
|
|
}
|
|
|
|
return NULL;
|
2018-04-18 05:06:10 +02:00
|
|
|
}
|
2018-03-31 03:03:35 +02:00
|
|
|
if ((*surface = layer_surface_at(output,
|
|
|
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
|
|
|
|
ox, oy, sx, sy))) {
|
2018-09-04 15:21:37 +02:00
|
|
|
return NULL;
|
2018-03-31 03:03:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct sway_container *c;
|
2018-05-26 08:26:10 +02:00
|
|
|
if ((c = container_at(ws, lx, ly, surface, sx, sy))) {
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
return &c->node;
|
2018-03-31 03:03:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((*surface = layer_surface_at(output,
|
|
|
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
|
|
|
|
ox, oy, sx, sy))) {
|
2018-09-04 15:21:37 +02:00
|
|
|
return NULL;
|
2018-03-31 03:03:35 +02:00
|
|
|
}
|
|
|
|
if ((*surface = layer_surface_at(output,
|
|
|
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
|
|
|
|
ox, oy, sx, sy))) {
|
2018-09-04 15:21:37 +02:00
|
|
|
return NULL;
|
2018-03-31 03:03:35 +02:00
|
|
|
}
|
|
|
|
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
return &ws->node;
|
|
|
|
}
|
2018-04-06 15:32:38 +02:00
|
|
|
|
2018-08-10 06:10:09 +02:00
|
|
|
/**
|
|
|
|
* Determine if the edge of the given container is on the edge of the
|
|
|
|
* workspace/output.
|
|
|
|
*/
|
|
|
|
static bool edge_is_external(struct sway_container *cont, enum wlr_edges edge) {
|
|
|
|
enum sway_container_layout layout = L_NONE;
|
|
|
|
switch (edge) {
|
|
|
|
case WLR_EDGE_TOP:
|
|
|
|
case WLR_EDGE_BOTTOM:
|
|
|
|
layout = L_VERT;
|
|
|
|
break;
|
|
|
|
case WLR_EDGE_LEFT:
|
|
|
|
case WLR_EDGE_RIGHT:
|
|
|
|
layout = L_HORIZ;
|
|
|
|
break;
|
|
|
|
case WLR_EDGE_NONE:
|
|
|
|
sway_assert(false, "Never reached");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterate the parents until we find one with the layout we want,
|
|
|
|
// then check if the child has siblings between it and the edge.
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
while (cont) {
|
|
|
|
if (container_parent_layout(cont) == layout) {
|
|
|
|
list_t *siblings = container_get_siblings(cont);
|
|
|
|
int index = list_find(siblings, cont);
|
2018-08-10 06:10:09 +02:00
|
|
|
if (index > 0 && (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_TOP)) {
|
|
|
|
return false;
|
|
|
|
}
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
if (index < siblings->length - 1 &&
|
2018-08-10 06:10:09 +02:00
|
|
|
(edge == WLR_EDGE_RIGHT || edge == WLR_EDGE_BOTTOM)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cont = cont->parent;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-08-10 08:51:24 +02:00
|
|
|
static enum wlr_edges find_edge(struct sway_container *cont,
|
2018-07-18 08:13:28 +02:00
|
|
|
struct sway_cursor *cursor) {
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
if (!cont->view) {
|
2018-07-20 01:28:22 +02:00
|
|
|
return WLR_EDGE_NONE;
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
2018-10-31 11:28:36 +01:00
|
|
|
if (cont->border == B_NONE || !cont->border_thickness ||
|
|
|
|
cont->border == B_CSD) {
|
2018-07-20 01:28:22 +02:00
|
|
|
return WLR_EDGE_NONE;
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
|
|
|
|
2018-07-20 01:28:22 +02:00
|
|
|
enum wlr_edges edge = 0;
|
2018-10-31 11:28:36 +01:00
|
|
|
if (cursor->cursor->x < cont->x + cont->border_thickness) {
|
2018-07-20 01:28:22 +02:00
|
|
|
edge |= WLR_EDGE_LEFT;
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
2018-10-31 11:28:36 +01:00
|
|
|
if (cursor->cursor->y < cont->y + cont->border_thickness) {
|
2018-07-20 01:28:22 +02:00
|
|
|
edge |= WLR_EDGE_TOP;
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
2018-10-31 11:28:36 +01:00
|
|
|
if (cursor->cursor->x >= cont->x + cont->width - cont->border_thickness) {
|
2018-07-20 01:28:22 +02:00
|
|
|
edge |= WLR_EDGE_RIGHT;
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
2018-10-31 11:28:36 +01:00
|
|
|
if (cursor->cursor->y >= cont->y + cont->height - cont->border_thickness) {
|
2018-07-20 01:28:22 +02:00
|
|
|
edge |= WLR_EDGE_BOTTOM;
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
2018-08-10 06:10:09 +02:00
|
|
|
|
2018-08-10 08:51:24 +02:00
|
|
|
return edge;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If the cursor is over a _resizable_ edge, return the edge.
|
|
|
|
* Edges that can't be resized are edges of the workspace.
|
|
|
|
*/
|
|
|
|
static enum wlr_edges find_resize_edge(struct sway_container *cont,
|
|
|
|
struct sway_cursor *cursor) {
|
|
|
|
enum wlr_edges edge = find_edge(cont, cursor);
|
2018-08-10 06:10:09 +02:00
|
|
|
if (edge && !container_is_floating(cont) && edge_is_external(cont, edge)) {
|
|
|
|
return WLR_EDGE_NONE;
|
|
|
|
}
|
2018-07-18 08:13:28 +02:00
|
|
|
return edge;
|
|
|
|
}
|
|
|
|
|
2018-08-16 01:12:48 +02:00
|
|
|
static void handle_down_motion(struct sway_seat *seat,
|
2018-08-15 08:47:02 +02:00
|
|
|
struct sway_cursor *cursor, uint32_t time_msec) {
|
|
|
|
struct sway_container *con = seat->op_container;
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
if (seat_is_input_allowed(seat, con->view->surface)) {
|
2018-08-15 08:47:02 +02:00
|
|
|
double moved_x = cursor->cursor->x - seat->op_ref_lx;
|
|
|
|
double moved_y = cursor->cursor->y - seat->op_ref_ly;
|
|
|
|
double sx = seat->op_ref_con_lx + moved_x;
|
|
|
|
double sy = seat->op_ref_con_ly + moved_y;
|
|
|
|
wlr_seat_pointer_notify_motion(seat->wlr_seat, time_msec, sx, sy);
|
|
|
|
}
|
2018-08-18 01:29:18 +02:00
|
|
|
seat->op_moved = true;
|
2018-08-15 08:47:02 +02:00
|
|
|
}
|
|
|
|
|
2018-09-11 08:56:05 +02:00
|
|
|
static void handle_move_floating_motion(struct sway_seat *seat,
|
2018-07-18 08:13:28 +02:00
|
|
|
struct sway_cursor *cursor) {
|
|
|
|
struct sway_container *con = seat->op_container;
|
|
|
|
desktop_damage_whole_container(con);
|
|
|
|
container_floating_translate(con,
|
|
|
|
cursor->cursor->x - cursor->previous.x,
|
|
|
|
cursor->cursor->y - cursor->previous.y);
|
|
|
|
desktop_damage_whole_container(con);
|
|
|
|
}
|
|
|
|
|
2018-09-11 13:34:21 +02:00
|
|
|
static void resize_box(struct wlr_box *box, enum wlr_edges edge,
|
2018-09-12 00:46:46 +02:00
|
|
|
int thickness) {
|
2018-09-11 13:34:21 +02:00
|
|
|
switch (edge) {
|
|
|
|
case WLR_EDGE_TOP:
|
|
|
|
box->height = thickness;
|
|
|
|
break;
|
|
|
|
case WLR_EDGE_LEFT:
|
|
|
|
box->width = thickness;
|
|
|
|
break;
|
|
|
|
case WLR_EDGE_RIGHT:
|
|
|
|
box->x = box->x + box->width - thickness;
|
|
|
|
box->width = thickness;
|
|
|
|
break;
|
|
|
|
case WLR_EDGE_BOTTOM:
|
|
|
|
box->y = box->y + box->height - thickness;
|
|
|
|
box->height = thickness;
|
|
|
|
break;
|
|
|
|
case WLR_EDGE_NONE:
|
|
|
|
box->x += thickness;
|
|
|
|
box->y += thickness;
|
|
|
|
box->width -= thickness * 2;
|
|
|
|
box->height -= thickness * 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_move_tiling_motion(struct sway_seat *seat,
|
|
|
|
struct sway_cursor *cursor) {
|
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
double sx, sy;
|
|
|
|
struct sway_node *node = node_at_coords(seat,
|
|
|
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
|
|
// Damage the old location
|
|
|
|
desktop_damage_box(&seat->op_drop_box);
|
|
|
|
|
|
|
|
if (!node) {
|
|
|
|
// Eg. hovered over a layer surface such as swaybar
|
|
|
|
seat->op_target_node = NULL;
|
|
|
|
seat->op_target_edge = WLR_EDGE_NONE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (node->type == N_WORKSPACE) {
|
|
|
|
// Emtpy workspace
|
|
|
|
seat->op_target_node = node;
|
|
|
|
seat->op_target_edge = WLR_EDGE_NONE;
|
|
|
|
workspace_get_box(node->sway_workspace, &seat->op_drop_box);
|
|
|
|
desktop_damage_box(&seat->op_drop_box);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deny moving within own workspace if this is the only child
|
|
|
|
struct sway_container *con = node->sway_container;
|
|
|
|
if (workspace_num_tiling_views(seat->op_container->workspace) == 1 &&
|
|
|
|
con->workspace == seat->op_container->workspace) {
|
|
|
|
seat->op_target_node = NULL;
|
|
|
|
seat->op_target_edge = WLR_EDGE_NONE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Traverse the ancestors, trying to find a layout container perpendicular
|
|
|
|
// to the edge. Eg. close to the top or bottom of a horiz layout.
|
|
|
|
while (con) {
|
|
|
|
enum wlr_edges edge = WLR_EDGE_NONE;
|
|
|
|
enum sway_container_layout layout = container_parent_layout(con);
|
|
|
|
struct wlr_box parent;
|
|
|
|
con->parent ? container_get_box(con->parent, &parent) :
|
|
|
|
workspace_get_box(con->workspace, &parent);
|
|
|
|
if (layout == L_HORIZ || layout == L_TABBED) {
|
2018-09-12 00:46:46 +02:00
|
|
|
if (cursor->cursor->y < parent.y + DROP_LAYOUT_BORDER) {
|
2018-09-11 13:34:21 +02:00
|
|
|
edge = WLR_EDGE_TOP;
|
2018-09-12 00:46:46 +02:00
|
|
|
} else if (cursor->cursor->y > parent.y + parent.height
|
|
|
|
- DROP_LAYOUT_BORDER) {
|
2018-09-11 13:34:21 +02:00
|
|
|
edge = WLR_EDGE_BOTTOM;
|
|
|
|
}
|
|
|
|
} else if (layout == L_VERT || layout == L_STACKED) {
|
2018-09-12 00:46:46 +02:00
|
|
|
if (cursor->cursor->x < parent.x + DROP_LAYOUT_BORDER) {
|
2018-09-11 13:34:21 +02:00
|
|
|
edge = WLR_EDGE_LEFT;
|
2018-09-12 00:46:46 +02:00
|
|
|
} else if (cursor->cursor->x > parent.x + parent.width
|
|
|
|
- DROP_LAYOUT_BORDER) {
|
2018-09-11 13:34:21 +02:00
|
|
|
edge = WLR_EDGE_RIGHT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (edge) {
|
|
|
|
seat->op_target_node = node_get_parent(&con->node);
|
|
|
|
seat->op_target_edge = edge;
|
|
|
|
node_get_box(seat->op_target_node, &seat->op_drop_box);
|
2018-09-12 00:46:46 +02:00
|
|
|
resize_box(&seat->op_drop_box, edge, DROP_LAYOUT_BORDER);
|
2018-09-11 13:34:21 +02:00
|
|
|
desktop_damage_box(&seat->op_drop_box);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
con = con->parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use the hovered view - but we must be over the actual surface
|
|
|
|
con = node->sway_container;
|
|
|
|
if (!con->view->surface || node == &seat->op_container->node) {
|
|
|
|
seat->op_target_node = NULL;
|
|
|
|
seat->op_target_edge = WLR_EDGE_NONE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the closest edge
|
|
|
|
size_t thickness = fmin(con->view->width, con->view->height) * 0.3;
|
|
|
|
size_t closest_dist = INT_MAX;
|
|
|
|
size_t dist;
|
|
|
|
seat->op_target_edge = WLR_EDGE_NONE;
|
|
|
|
if ((dist = cursor->cursor->y - con->y) < closest_dist) {
|
|
|
|
closest_dist = dist;
|
|
|
|
seat->op_target_edge = WLR_EDGE_TOP;
|
|
|
|
}
|
|
|
|
if ((dist = cursor->cursor->x - con->x) < closest_dist) {
|
|
|
|
closest_dist = dist;
|
|
|
|
seat->op_target_edge = WLR_EDGE_LEFT;
|
|
|
|
}
|
|
|
|
if ((dist = con->x + con->width - cursor->cursor->x) < closest_dist) {
|
|
|
|
closest_dist = dist;
|
|
|
|
seat->op_target_edge = WLR_EDGE_RIGHT;
|
|
|
|
}
|
|
|
|
if ((dist = con->y + con->height - cursor->cursor->y) < closest_dist) {
|
|
|
|
closest_dist = dist;
|
|
|
|
seat->op_target_edge = WLR_EDGE_BOTTOM;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (closest_dist > thickness) {
|
|
|
|
seat->op_target_edge = WLR_EDGE_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
seat->op_target_node = node;
|
|
|
|
seat->op_drop_box.x = con->view->x;
|
|
|
|
seat->op_drop_box.y = con->view->y;
|
|
|
|
seat->op_drop_box.width = con->view->width;
|
|
|
|
seat->op_drop_box.height = con->view->height;
|
|
|
|
resize_box(&seat->op_drop_box, seat->op_target_edge, thickness);
|
|
|
|
desktop_damage_box(&seat->op_drop_box);
|
|
|
|
}
|
|
|
|
|
2018-07-18 08:13:28 +02:00
|
|
|
static void calculate_floating_constraints(struct sway_container *con,
|
|
|
|
int *min_width, int *max_width, int *min_height, int *max_height) {
|
|
|
|
if (config->floating_minimum_width == -1) { // no minimum
|
|
|
|
*min_width = 0;
|
|
|
|
} else if (config->floating_minimum_width == 0) { // automatic
|
|
|
|
*min_width = 75;
|
|
|
|
} else {
|
|
|
|
*min_width = config->floating_minimum_width;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config->floating_minimum_height == -1) { // no minimum
|
|
|
|
*min_height = 0;
|
|
|
|
} else if (config->floating_minimum_height == 0) { // automatic
|
|
|
|
*min_height = 50;
|
|
|
|
} else {
|
|
|
|
*min_height = config->floating_minimum_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config->floating_maximum_width == -1) { // no maximum
|
|
|
|
*max_width = INT_MAX;
|
|
|
|
} else if (config->floating_maximum_width == 0) { // automatic
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
*max_width = con->workspace->width;
|
2018-07-18 08:13:28 +02:00
|
|
|
} else {
|
|
|
|
*max_width = config->floating_maximum_width;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config->floating_maximum_height == -1) { // no maximum
|
|
|
|
*max_height = INT_MAX;
|
|
|
|
} else if (config->floating_maximum_height == 0) { // automatic
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
*max_height = con->workspace->height;
|
2018-07-18 08:13:28 +02:00
|
|
|
} else {
|
|
|
|
*max_height = config->floating_maximum_height;
|
|
|
|
}
|
|
|
|
}
|
2018-07-22 15:10:06 +02:00
|
|
|
|
2018-08-10 06:10:09 +02:00
|
|
|
static void handle_resize_floating_motion(struct sway_seat *seat,
|
2018-07-18 08:13:28 +02:00
|
|
|
struct sway_cursor *cursor) {
|
|
|
|
struct sway_container *con = seat->op_container;
|
2018-07-20 01:28:22 +02:00
|
|
|
enum wlr_edges edge = seat->op_resize_edge;
|
2018-07-18 08:13:28 +02:00
|
|
|
|
|
|
|
// The amount the mouse has moved since the start of the resize operation
|
|
|
|
// Positive is down/right
|
|
|
|
double mouse_move_x = cursor->cursor->x - seat->op_ref_lx;
|
|
|
|
double mouse_move_y = cursor->cursor->y - seat->op_ref_ly;
|
|
|
|
|
2018-07-20 01:28:22 +02:00
|
|
|
if (edge == WLR_EDGE_TOP || edge == WLR_EDGE_BOTTOM) {
|
2018-07-18 08:13:28 +02:00
|
|
|
mouse_move_x = 0;
|
|
|
|
}
|
2018-07-20 01:28:22 +02:00
|
|
|
if (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT) {
|
2018-07-18 08:13:28 +02:00
|
|
|
mouse_move_y = 0;
|
|
|
|
}
|
|
|
|
|
2018-07-20 01:28:22 +02:00
|
|
|
double grow_width = edge & WLR_EDGE_LEFT ? -mouse_move_x : mouse_move_x;
|
|
|
|
double grow_height = edge & WLR_EDGE_TOP ? -mouse_move_y : mouse_move_y;
|
2018-07-18 08:13:28 +02:00
|
|
|
|
|
|
|
if (seat->op_resize_preserve_ratio) {
|
|
|
|
double x_multiplier = grow_width / seat->op_ref_width;
|
|
|
|
double y_multiplier = grow_height / seat->op_ref_height;
|
2018-07-19 05:42:43 +02:00
|
|
|
double max_multiplier = fmax(x_multiplier, y_multiplier);
|
|
|
|
grow_width = seat->op_ref_width * max_multiplier;
|
|
|
|
grow_height = seat->op_ref_height * max_multiplier;
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
|
|
|
|
2018-07-21 04:13:00 +02:00
|
|
|
// Determine new width/height, and accommodate for floating min/max values
|
2018-07-18 08:13:28 +02:00
|
|
|
double width = seat->op_ref_width + grow_width;
|
|
|
|
double height = seat->op_ref_height + grow_height;
|
|
|
|
int min_width, max_width, min_height, max_height;
|
|
|
|
calculate_floating_constraints(con, &min_width, &max_width,
|
|
|
|
&min_height, &max_height);
|
|
|
|
width = fmax(min_width, fmin(width, max_width));
|
|
|
|
height = fmax(min_height, fmin(height, max_height));
|
|
|
|
|
2018-07-21 04:13:00 +02:00
|
|
|
// Apply the view's min/max size
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
if (con->view) {
|
2018-07-21 04:13:00 +02:00
|
|
|
double view_min_width, view_max_width, view_min_height, view_max_height;
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
view_get_constraints(con->view, &view_min_width, &view_max_width,
|
2018-07-21 04:13:00 +02:00
|
|
|
&view_min_height, &view_max_height);
|
|
|
|
width = fmax(view_min_width, fmin(width, view_max_width));
|
|
|
|
height = fmax(view_min_height, fmin(height, view_max_height));
|
|
|
|
}
|
|
|
|
|
2018-07-18 08:13:28 +02:00
|
|
|
// Recalculate these, in case we hit a min/max limit
|
|
|
|
grow_width = width - seat->op_ref_width;
|
|
|
|
grow_height = height - seat->op_ref_height;
|
|
|
|
|
|
|
|
// Determine grow x/y values - these are relative to the container's x/y at
|
|
|
|
// the start of the resize operation.
|
|
|
|
double grow_x = 0, grow_y = 0;
|
2018-07-20 01:28:22 +02:00
|
|
|
if (edge & WLR_EDGE_LEFT) {
|
2018-07-18 08:13:28 +02:00
|
|
|
grow_x = -grow_width;
|
2018-07-20 01:28:22 +02:00
|
|
|
} else if (edge & WLR_EDGE_RIGHT) {
|
2018-07-18 08:13:28 +02:00
|
|
|
grow_x = 0;
|
|
|
|
} else {
|
|
|
|
grow_x = -grow_width / 2;
|
|
|
|
}
|
2018-07-20 01:28:22 +02:00
|
|
|
if (edge & WLR_EDGE_TOP) {
|
2018-07-18 08:13:28 +02:00
|
|
|
grow_y = -grow_height;
|
2018-07-20 01:28:22 +02:00
|
|
|
} else if (edge & WLR_EDGE_BOTTOM) {
|
2018-07-18 08:13:28 +02:00
|
|
|
grow_y = 0;
|
|
|
|
} else {
|
|
|
|
grow_y = -grow_height / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine the amounts we need to bump everything relative to the current
|
|
|
|
// size.
|
|
|
|
int relative_grow_width = width - con->width;
|
|
|
|
int relative_grow_height = height - con->height;
|
|
|
|
int relative_grow_x = (seat->op_ref_con_lx + grow_x) - con->x;
|
|
|
|
int relative_grow_y = (seat->op_ref_con_ly + grow_y) - con->y;
|
|
|
|
|
|
|
|
// Actually resize stuff
|
|
|
|
con->x += relative_grow_x;
|
|
|
|
con->y += relative_grow_y;
|
|
|
|
con->width += relative_grow_width;
|
|
|
|
con->height += relative_grow_height;
|
|
|
|
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
if (con->view) {
|
|
|
|
struct sway_view *view = con->view;
|
2018-07-18 08:13:28 +02:00
|
|
|
view->x += relative_grow_x;
|
|
|
|
view->y += relative_grow_y;
|
|
|
|
view->width += relative_grow_width;
|
|
|
|
view->height += relative_grow_height;
|
|
|
|
}
|
|
|
|
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
arrange_container(con);
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
|
|
|
|
2018-08-10 06:10:09 +02:00
|
|
|
static void handle_resize_tiling_motion(struct sway_seat *seat,
|
|
|
|
struct sway_cursor *cursor) {
|
2018-08-10 09:22:50 +02:00
|
|
|
int amount_x = 0;
|
|
|
|
int amount_y = 0;
|
2018-08-10 06:10:09 +02:00
|
|
|
int moved_x = cursor->cursor->x - seat->op_ref_lx;
|
|
|
|
int moved_y = cursor->cursor->y - seat->op_ref_ly;
|
2018-08-10 09:22:50 +02:00
|
|
|
enum wlr_edges edge_x = WLR_EDGE_NONE;
|
|
|
|
enum wlr_edges edge_y = WLR_EDGE_NONE;
|
2018-08-10 06:10:09 +02:00
|
|
|
struct sway_container *con = seat->op_container;
|
2018-08-10 09:22:50 +02:00
|
|
|
|
|
|
|
if (seat->op_resize_edge & WLR_EDGE_TOP) {
|
|
|
|
amount_y = (seat->op_ref_height - moved_y) - con->height;
|
|
|
|
edge_y = WLR_EDGE_TOP;
|
|
|
|
} else if (seat->op_resize_edge & WLR_EDGE_BOTTOM) {
|
|
|
|
amount_y = (seat->op_ref_height + moved_y) - con->height;
|
|
|
|
edge_y = WLR_EDGE_BOTTOM;
|
|
|
|
}
|
|
|
|
if (seat->op_resize_edge & WLR_EDGE_LEFT) {
|
|
|
|
amount_x = (seat->op_ref_width - moved_x) - con->width;
|
|
|
|
edge_x = WLR_EDGE_LEFT;
|
|
|
|
} else if (seat->op_resize_edge & WLR_EDGE_RIGHT) {
|
|
|
|
amount_x = (seat->op_ref_width + moved_x) - con->width;
|
|
|
|
edge_x = WLR_EDGE_RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (amount_x != 0) {
|
|
|
|
container_resize_tiled(seat->op_container, edge_x, amount_x);
|
|
|
|
}
|
|
|
|
if (amount_y != 0) {
|
|
|
|
container_resize_tiled(seat->op_container, edge_y, amount_y);
|
2018-08-10 06:10:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-18 16:04:21 +02:00
|
|
|
static void cursor_do_rebase(struct sway_cursor *cursor, uint32_t time_msec,
|
|
|
|
struct sway_node *node, struct wlr_surface *surface,
|
|
|
|
double sx, double sy) {
|
|
|
|
// Handle cursor image
|
|
|
|
if (surface) {
|
|
|
|
// Reset cursor if switching between clients
|
|
|
|
struct wl_client *client = wl_resource_get_client(surface->resource);
|
|
|
|
if (client != cursor->image_client) {
|
|
|
|
cursor_set_image(cursor, "left_ptr", client);
|
|
|
|
}
|
|
|
|
} else if (node && node->type == N_CONTAINER) {
|
|
|
|
// Try a node's resize edge
|
|
|
|
enum wlr_edges edge = find_resize_edge(node->sway_container, cursor);
|
|
|
|
if (edge == WLR_EDGE_NONE) {
|
|
|
|
cursor_set_image(cursor, "left_ptr", NULL);
|
|
|
|
} else if (container_is_floating(node->sway_container)) {
|
|
|
|
cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL);
|
|
|
|
} else {
|
|
|
|
if (edge & (WLR_EDGE_LEFT | WLR_EDGE_RIGHT)) {
|
|
|
|
cursor_set_image(cursor, "col-resize", NULL);
|
|
|
|
} else {
|
|
|
|
cursor_set_image(cursor, "row-resize", NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cursor_set_image(cursor, "left_ptr", NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send pointer enter/leave
|
|
|
|
struct wlr_seat *wlr_seat = cursor->seat->wlr_seat;
|
|
|
|
if (surface) {
|
|
|
|
if (seat_is_input_allowed(cursor->seat, surface)) {
|
|
|
|
wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy);
|
|
|
|
wlr_seat_pointer_notify_motion(wlr_seat, time_msec, sx, sy);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
wlr_seat_pointer_clear_focus(wlr_seat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cursor_rebase(struct sway_cursor *cursor) {
|
|
|
|
uint32_t time_msec = get_current_time_msec();
|
2018-10-28 17:33:27 +01:00
|
|
|
struct wlr_surface *surface = NULL;
|
2018-10-18 16:04:21 +02:00
|
|
|
double sx, sy;
|
|
|
|
cursor->previous.node = node_at_coords(cursor->seat,
|
|
|
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
|
|
cursor_do_rebase(cursor, time_msec, cursor->previous.node, surface, sx, sy);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cursor_send_pointer_motion(struct sway_cursor *cursor,
|
|
|
|
uint32_t time_msec) {
|
2018-04-21 15:07:22 +02:00
|
|
|
if (time_msec == 0) {
|
|
|
|
time_msec = get_current_time_msec();
|
|
|
|
}
|
|
|
|
|
2018-06-09 14:26:03 +02:00
|
|
|
struct sway_seat *seat = cursor->seat;
|
2018-09-07 15:43:15 +02:00
|
|
|
struct wlr_seat *wlr_seat = seat->wlr_seat;
|
2018-07-18 08:13:28 +02:00
|
|
|
|
|
|
|
if (seat->operation != OP_NONE) {
|
2018-08-10 06:10:09 +02:00
|
|
|
switch (seat->operation) {
|
2018-08-16 01:12:48 +02:00
|
|
|
case OP_DOWN:
|
|
|
|
handle_down_motion(seat, cursor, time_msec);
|
2018-08-15 08:47:02 +02:00
|
|
|
break;
|
2018-09-11 08:56:05 +02:00
|
|
|
case OP_MOVE_FLOATING:
|
|
|
|
handle_move_floating_motion(seat, cursor);
|
2018-08-10 06:10:09 +02:00
|
|
|
break;
|
2018-09-11 13:34:21 +02:00
|
|
|
case OP_MOVE_TILING:
|
|
|
|
handle_move_tiling_motion(seat, cursor);
|
|
|
|
break;
|
2018-08-10 06:10:09 +02:00
|
|
|
case OP_RESIZE_FLOATING:
|
|
|
|
handle_resize_floating_motion(seat, cursor);
|
|
|
|
break;
|
|
|
|
case OP_RESIZE_TILING:
|
|
|
|
handle_resize_tiling_motion(seat, cursor);
|
|
|
|
break;
|
|
|
|
case OP_NONE:
|
|
|
|
break;
|
2018-07-18 08:13:28 +02:00
|
|
|
}
|
|
|
|
cursor->previous.x = cursor->cursor->x;
|
|
|
|
cursor->previous.y = cursor->cursor->y;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-05-27 14:45:14 +02:00
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
double sx, sy;
|
|
|
|
|
2018-09-27 18:32:55 +02:00
|
|
|
struct sway_node *prev_node = cursor->previous.node;
|
|
|
|
struct sway_node *node = node_at_coords(seat,
|
|
|
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
|
|
|
2018-05-27 14:45:14 +02:00
|
|
|
// Update the stored previous position
|
2018-05-27 18:14:19 +02:00
|
|
|
cursor->previous.x = cursor->cursor->x;
|
|
|
|
cursor->previous.y = cursor->cursor->y;
|
2018-09-27 18:32:55 +02:00
|
|
|
cursor->previous.node = node;
|
2018-05-27 14:45:14 +02:00
|
|
|
|
2018-11-06 21:58:08 +01:00
|
|
|
if (node && (config->focus_follows_mouse == FOLLOWS_YES ||
|
|
|
|
config->focus_follows_mouse == FOLLOWS_ALWAYS)) {
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
struct sway_node *focus = seat_get_focus(seat);
|
|
|
|
if (focus && node->type == N_WORKSPACE) {
|
2018-05-20 01:57:10 +02:00
|
|
|
// Only follow the mouse if it would move to a new output
|
|
|
|
// Otherwise we'll focus the workspace, which is probably wrong
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
struct sway_output *focused_output = node_get_output(focus);
|
|
|
|
struct sway_output *output = node_get_output(node);
|
|
|
|
if (output != focused_output) {
|
2018-10-18 15:08:45 +02:00
|
|
|
seat_set_focus(seat, node);
|
2018-05-20 01:57:10 +02:00
|
|
|
}
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
} else if (node->type == N_CONTAINER && node->sway_container->view) {
|
|
|
|
// Focus node if the following are true:
|
2018-05-27 17:30:19 +02:00
|
|
|
// - cursor is over a new view, i.e. entered a new window; and
|
2018-06-25 02:30:43 +02:00
|
|
|
// - the new view is visible, i.e. not hidden in a stack or tab; and
|
|
|
|
// - the seat does not have a keyboard grab
|
2018-11-06 21:58:08 +01:00
|
|
|
if ((!wlr_seat_keyboard_has_grab(cursor->seat->wlr_seat) &&
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
node != prev_node &&
|
2018-11-06 21:58:08 +01:00
|
|
|
view_is_visible(node->sway_container->view)) ||
|
|
|
|
config->focus_follows_mouse == FOLLOWS_ALWAYS) {
|
2018-10-18 15:08:45 +02:00
|
|
|
seat_set_focus(seat, node);
|
2018-05-27 14:45:14 +02:00
|
|
|
} else {
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
struct sway_node *next_focus =
|
|
|
|
seat_get_focus_inactive(seat, &root->node);
|
|
|
|
if (next_focus && next_focus->type == N_CONTAINER &&
|
2018-08-31 11:16:49 +02:00
|
|
|
next_focus->sway_container->view &&
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
view_is_visible(next_focus->sway_container->view)) {
|
2018-10-18 15:08:45 +02:00
|
|
|
seat_set_focus(seat, next_focus);
|
2018-05-27 14:45:14 +02:00
|
|
|
}
|
2018-05-24 20:02:38 +02:00
|
|
|
}
|
2018-05-20 01:57:10 +02:00
|
|
|
}
|
2018-03-31 16:11:15 +02:00
|
|
|
}
|
2018-03-30 16:53:18 +02:00
|
|
|
|
2018-10-18 16:04:21 +02:00
|
|
|
cursor_do_rebase(cursor, time_msec, node, surface, sx, sy);
|
2018-06-09 14:26:03 +02:00
|
|
|
|
|
|
|
struct wlr_drag_icon *wlr_drag_icon;
|
|
|
|
wl_list_for_each(wlr_drag_icon, &wlr_seat->drag_icons, link) {
|
|
|
|
struct sway_drag_icon *drag_icon = wlr_drag_icon->data;
|
|
|
|
drag_icon_update_position(drag_icon);
|
2017-12-10 14:48:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-08 13:22:26 +01:00
|
|
|
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
2018-03-30 21:33:16 +02:00
|
|
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, motion);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_event_pointer_motion *event = data;
|
2017-12-10 14:48:44 +01:00
|
|
|
wlr_cursor_move(cursor->cursor, event->device,
|
|
|
|
event->delta_x, event->delta_y);
|
2018-10-18 16:04:21 +02:00
|
|
|
cursor_send_pointer_motion(cursor, event->time_msec);
|
2018-07-19 11:49:50 +02:00
|
|
|
transaction_commit_dirty();
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
2018-03-31 16:49:52 +02:00
|
|
|
static void handle_cursor_motion_absolute(
|
|
|
|
struct wl_listener *listener, void *data) {
|
2017-12-08 13:22:26 +01:00
|
|
|
struct sway_cursor *cursor =
|
|
|
|
wl_container_of(listener, cursor, motion_absolute);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_event_pointer_motion_absolute *event = data;
|
2018-03-28 18:22:45 +02:00
|
|
|
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
|
2018-10-18 16:04:21 +02:00
|
|
|
cursor_send_pointer_motion(cursor, event->time_msec);
|
2018-07-19 11:49:50 +02:00
|
|
|
transaction_commit_dirty();
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
2018-07-24 03:38:29 +02:00
|
|
|
/**
|
|
|
|
* Remove a button (and duplicates) to the sorted list of currently pressed buttons
|
|
|
|
*/
|
|
|
|
static void state_erase_button(struct sway_cursor *cursor, uint32_t button) {
|
|
|
|
size_t j = 0;
|
|
|
|
for (size_t i = 0; i < cursor->pressed_button_count; ++i) {
|
|
|
|
if (i > j) {
|
|
|
|
cursor->pressed_buttons[j] = cursor->pressed_buttons[i];
|
|
|
|
}
|
|
|
|
if (cursor->pressed_buttons[i] != button) {
|
|
|
|
++j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (cursor->pressed_button_count > j) {
|
|
|
|
--cursor->pressed_button_count;
|
|
|
|
cursor->pressed_buttons[cursor->pressed_button_count] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a button to the sorted list of currently pressed buttons, if there
|
|
|
|
* is space.
|
|
|
|
*/
|
|
|
|
static void state_add_button(struct sway_cursor *cursor, uint32_t button) {
|
|
|
|
if (cursor->pressed_button_count >= SWAY_CURSOR_PRESSED_BUTTONS_CAP) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
size_t i = 0;
|
|
|
|
while (i < cursor->pressed_button_count && cursor->pressed_buttons[i] < button) {
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
size_t j = cursor->pressed_button_count;
|
|
|
|
while (j > i) {
|
|
|
|
cursor->pressed_buttons[j] = cursor->pressed_buttons[j - 1];
|
|
|
|
--j;
|
|
|
|
}
|
|
|
|
cursor->pressed_buttons[i] = button;
|
|
|
|
cursor->pressed_button_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the mouse binding which matches modifier, click location, release,
|
|
|
|
* and pressed button state, otherwise return null.
|
|
|
|
*/
|
2018-10-18 19:13:40 +02:00
|
|
|
static struct sway_binding* get_active_mouse_binding(
|
|
|
|
const struct sway_cursor *cursor, list_t *bindings, uint32_t modifiers,
|
|
|
|
bool release, bool on_titlebar, bool on_border, bool on_content,
|
|
|
|
const char *identifier) {
|
2018-07-24 03:38:29 +02:00
|
|
|
uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) |
|
|
|
|
(on_border ? BINDING_BORDER : 0) |
|
|
|
|
(on_content ? BINDING_CONTENTS : 0);
|
|
|
|
|
2018-10-18 19:13:40 +02:00
|
|
|
struct sway_binding *current = NULL;
|
2018-07-24 03:38:29 +02:00
|
|
|
for (int i = 0; i < bindings->length; ++i) {
|
|
|
|
struct sway_binding *binding = bindings->items[i];
|
|
|
|
if (modifiers ^ binding->modifiers ||
|
|
|
|
cursor->pressed_button_count != (size_t)binding->keys->length ||
|
|
|
|
release != (binding->flags & BINDING_RELEASE) ||
|
2018-10-18 19:13:40 +02:00
|
|
|
!(click_region & binding->flags) ||
|
|
|
|
(strcmp(binding->input, identifier) != 0 &&
|
|
|
|
strcmp(binding->input, "*") != 0)) {
|
2018-07-24 03:38:29 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool match = true;
|
|
|
|
for (size_t j = 0; j < cursor->pressed_button_count; j++) {
|
|
|
|
uint32_t key = *(uint32_t *)binding->keys->items[j];
|
|
|
|
if (key != cursor->pressed_buttons[j]) {
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!match) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-10-18 19:13:40 +02:00
|
|
|
if (!current || strcmp(current->input, "*") == 0) {
|
|
|
|
current = binding;
|
|
|
|
if (strcmp(current->input, identifier) == 0) {
|
|
|
|
// If a binding is found for the exact input, quit searching
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-07-24 03:38:29 +02:00
|
|
|
}
|
2018-10-18 19:13:40 +02:00
|
|
|
return current;
|
2018-07-24 03:38:29 +02:00
|
|
|
}
|
|
|
|
|
2018-04-10 17:32:37 +02:00
|
|
|
void dispatch_cursor_button(struct sway_cursor *cursor,
|
2018-10-18 19:13:40 +02:00
|
|
|
struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
|
|
|
|
enum wlr_button_state state) {
|
2018-08-10 08:51:24 +02:00
|
|
|
if (time_msec == 0) {
|
|
|
|
time_msec = get_current_time_msec();
|
|
|
|
}
|
|
|
|
struct sway_seat *seat = cursor->seat;
|
|
|
|
|
2018-10-04 12:57:03 +02:00
|
|
|
// Handle existing seat operation
|
|
|
|
if (cursor->seat->operation != OP_NONE) {
|
|
|
|
if (button == cursor->seat->op_button && state == WLR_BUTTON_RELEASED) {
|
|
|
|
seat_end_mouse_operation(seat);
|
|
|
|
seat_pointer_notify_button(seat, time_msec, button, state);
|
|
|
|
}
|
2018-07-18 08:13:28 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-04-21 15:07:22 +02:00
|
|
|
|
2018-08-10 08:51:24 +02:00
|
|
|
// Determine what's under the cursor
|
2018-03-31 16:11:15 +02:00
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
double sx, sy;
|
2018-09-04 03:45:49 +02:00
|
|
|
struct sway_node *node = node_at_coords(seat,
|
2018-05-02 15:00:26 +02:00
|
|
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
2018-09-04 03:45:49 +02:00
|
|
|
struct sway_container *cont = node && node->type == N_CONTAINER ?
|
|
|
|
node->sway_container : NULL;
|
2018-08-10 08:51:24 +02:00
|
|
|
bool is_floating = cont && container_is_floating(cont);
|
|
|
|
bool is_floating_or_child = cont && container_is_floating_or_child(cont);
|
|
|
|
bool is_fullscreen_or_child = cont && container_is_fullscreen_or_child(cont);
|
|
|
|
enum wlr_edges edge = cont ? find_edge(cont, cursor) : WLR_EDGE_NONE;
|
|
|
|
enum wlr_edges resize_edge = edge ?
|
|
|
|
find_resize_edge(cont, cursor) : WLR_EDGE_NONE;
|
|
|
|
bool on_border = edge != WLR_EDGE_NONE;
|
|
|
|
bool on_contents = cont && !on_border && surface;
|
|
|
|
bool on_titlebar = cont && !on_border && !surface;
|
2018-07-24 03:38:29 +02:00
|
|
|
|
|
|
|
// Handle mouse bindings
|
2018-08-10 08:51:24 +02:00
|
|
|
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
|
2018-07-24 03:38:29 +02:00
|
|
|
uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
|
|
|
|
2018-10-18 19:13:40 +02:00
|
|
|
char *device_identifier = device ? input_device_get_identifier(device)
|
|
|
|
: strdup("*");
|
2018-07-24 03:38:29 +02:00
|
|
|
struct sway_binding *binding = NULL;
|
|
|
|
if (state == WLR_BUTTON_PRESSED) {
|
|
|
|
state_add_button(cursor, button);
|
|
|
|
binding = get_active_mouse_binding(cursor,
|
|
|
|
config->current_mode->mouse_bindings, modifiers, false,
|
2018-10-18 19:13:40 +02:00
|
|
|
on_titlebar, on_border, on_contents, device_identifier);
|
2018-07-24 03:38:29 +02:00
|
|
|
} else {
|
|
|
|
binding = get_active_mouse_binding(cursor,
|
|
|
|
config->current_mode->mouse_bindings, modifiers, true,
|
2018-10-18 19:13:40 +02:00
|
|
|
on_titlebar, on_border, on_contents, device_identifier);
|
2018-07-24 03:38:29 +02:00
|
|
|
state_erase_button(cursor, button);
|
|
|
|
}
|
2018-10-18 19:13:40 +02:00
|
|
|
free(device_identifier);
|
2018-07-24 03:38:29 +02:00
|
|
|
if (binding) {
|
2018-08-10 08:51:24 +02:00
|
|
|
seat_execute_command(seat, binding);
|
|
|
|
return;
|
2018-07-24 03:38:29 +02:00
|
|
|
}
|
|
|
|
|
2018-09-04 03:45:49 +02:00
|
|
|
// Handle clicking an empty workspace
|
|
|
|
if (node && node->type == N_WORKSPACE) {
|
|
|
|
seat_set_focus(seat, node);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-10 08:51:24 +02:00
|
|
|
// Handle clicking a layer surface
|
2018-04-03 03:17:16 +02:00
|
|
|
if (surface && wlr_surface_is_layer_surface(surface)) {
|
2018-09-14 19:21:44 +02:00
|
|
|
struct wlr_layer_surface_v1 *layer =
|
|
|
|
wlr_layer_surface_v1_from_wlr_surface(surface);
|
2018-04-03 03:17:16 +02:00
|
|
|
if (layer->current.keyboard_interactive) {
|
2018-08-10 08:51:24 +02:00
|
|
|
seat_set_focus_layer(seat, layer);
|
|
|
|
}
|
|
|
|
seat_pointer_notify_button(seat, time_msec, button, state);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle tiling resize via border
|
2018-08-10 15:43:31 +02:00
|
|
|
if (resize_edge && button == BTN_LEFT && state == WLR_BUTTON_PRESSED &&
|
|
|
|
!is_floating) {
|
2018-09-06 11:26:56 +02:00
|
|
|
seat_set_focus_container(seat, cont);
|
2018-08-10 08:51:24 +02:00
|
|
|
seat_begin_resize_tiling(seat, cont, button, edge);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-10 09:22:50 +02:00
|
|
|
// Handle tiling resize via mod
|
2018-08-10 08:51:24 +02:00
|
|
|
bool mod_pressed = keyboard &&
|
|
|
|
(wlr_keyboard_get_modifiers(keyboard) & config->floating_mod);
|
2018-08-11 02:47:40 +02:00
|
|
|
if (!is_floating_or_child && mod_pressed && state == WLR_BUTTON_PRESSED) {
|
2018-08-10 09:22:50 +02:00
|
|
|
uint32_t btn_resize = config->floating_mod_inverse ?
|
|
|
|
BTN_LEFT : BTN_RIGHT;
|
|
|
|
if (button == btn_resize) {
|
|
|
|
edge = 0;
|
|
|
|
edge |= cursor->cursor->x > cont->x + cont->width / 2 ?
|
|
|
|
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
|
|
|
|
edge |= cursor->cursor->y > cont->y + cont->height / 2 ?
|
|
|
|
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
|
2018-08-10 16:08:18 +02:00
|
|
|
|
|
|
|
const char *image = NULL;
|
|
|
|
if (edge == (WLR_EDGE_LEFT | WLR_EDGE_TOP)) {
|
|
|
|
image = "nw-resize";
|
|
|
|
} else if (edge == (WLR_EDGE_TOP | WLR_EDGE_RIGHT)) {
|
|
|
|
image = "ne-resize";
|
|
|
|
} else if (edge == (WLR_EDGE_RIGHT | WLR_EDGE_BOTTOM)) {
|
|
|
|
image = "se-resize";
|
|
|
|
} else if (edge == (WLR_EDGE_BOTTOM | WLR_EDGE_LEFT)) {
|
|
|
|
image = "sw-resize";
|
|
|
|
}
|
|
|
|
cursor_set_image(seat->cursor, image, NULL);
|
2018-09-06 11:26:56 +02:00
|
|
|
seat_set_focus_container(seat, cont);
|
2018-08-10 09:22:50 +02:00
|
|
|
seat_begin_resize_tiling(seat, cont, button, edge);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2018-08-10 08:51:24 +02:00
|
|
|
|
2018-08-10 09:22:50 +02:00
|
|
|
// Handle beginning floating move
|
2018-08-10 15:43:31 +02:00
|
|
|
if (is_floating_or_child && !is_fullscreen_or_child &&
|
|
|
|
state == WLR_BUTTON_PRESSED) {
|
2018-08-10 08:51:24 +02:00
|
|
|
uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
|
|
|
|
if (button == btn_move && state == WLR_BUTTON_PRESSED &&
|
|
|
|
(mod_pressed || on_titlebar)) {
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
while (cont->parent) {
|
2018-08-10 08:51:24 +02:00
|
|
|
cont = cont->parent;
|
|
|
|
}
|
2018-10-10 08:58:32 +02:00
|
|
|
seat_set_focus_container(seat, cont);
|
2018-09-11 08:56:05 +02:00
|
|
|
seat_begin_move_floating(seat, cont, button);
|
2018-08-10 08:51:24 +02:00
|
|
|
return;
|
2018-04-03 03:17:16 +02:00
|
|
|
}
|
2018-08-10 08:51:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Handle beginning floating resize
|
|
|
|
if (is_floating_or_child && !is_fullscreen_or_child &&
|
|
|
|
state == WLR_BUTTON_PRESSED) {
|
|
|
|
// Via border
|
|
|
|
if (button == BTN_LEFT && resize_edge != WLR_EDGE_NONE) {
|
|
|
|
seat_begin_resize_floating(seat, cont, button, resize_edge);
|
|
|
|
return;
|
2018-03-31 16:11:15 +02:00
|
|
|
}
|
2018-08-10 08:51:24 +02:00
|
|
|
|
|
|
|
// Via mod+click
|
|
|
|
uint32_t btn_resize = config->floating_mod_inverse ?
|
|
|
|
BTN_LEFT : BTN_RIGHT;
|
2018-08-18 09:50:37 +02:00
|
|
|
if (mod_pressed && button == btn_resize) {
|
|
|
|
struct sway_container *floater = cont;
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
while (floater->parent) {
|
2018-08-18 09:50:37 +02:00
|
|
|
floater = floater->parent;
|
|
|
|
}
|
2018-08-10 09:22:50 +02:00
|
|
|
edge = 0;
|
2018-08-10 08:51:24 +02:00
|
|
|
edge |= cursor->cursor->x > floater->x + floater->width / 2 ?
|
|
|
|
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
|
|
|
|
edge |= cursor->cursor->y > floater->y + floater->height / 2 ?
|
|
|
|
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
|
|
|
|
seat_begin_resize_floating(seat, floater, button, edge);
|
|
|
|
return;
|
2018-03-31 15:45:11 +02:00
|
|
|
}
|
2017-12-10 17:11:47 +01:00
|
|
|
}
|
|
|
|
|
2018-09-11 13:34:21 +02:00
|
|
|
// Handle moving a tiling container
|
2018-09-12 00:46:46 +02:00
|
|
|
if (config->tiling_drag && mod_pressed && state == WLR_BUTTON_PRESSED &&
|
2018-09-25 22:19:46 +02:00
|
|
|
!is_floating_or_child && cont && !cont->is_fullscreen) {
|
2018-09-11 13:34:21 +02:00
|
|
|
seat_pointer_notify_button(seat, time_msec, button, state);
|
|
|
|
seat_begin_move_tiling(seat, cont, button);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-15 08:47:02 +02:00
|
|
|
// Handle mousedown on a container surface
|
|
|
|
if (surface && cont && state == WLR_BUTTON_PRESSED) {
|
2018-09-06 11:26:56 +02:00
|
|
|
seat_set_focus_container(seat, cont);
|
2018-08-15 08:47:02 +02:00
|
|
|
seat_pointer_notify_button(seat, time_msec, button, state);
|
2018-08-16 01:12:48 +02:00
|
|
|
seat_begin_down(seat, cont, button, sx, sy);
|
2018-08-15 08:47:02 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-09-22 02:42:59 +02:00
|
|
|
// Handle clicking a container surface or decorations
|
2018-08-10 08:51:24 +02:00
|
|
|
if (cont) {
|
2018-09-22 02:42:59 +02:00
|
|
|
node = seat_get_focus_inactive(seat, &cont->node);
|
|
|
|
seat_set_focus(seat, node);
|
2018-08-10 08:51:24 +02:00
|
|
|
seat_pointer_notify_button(seat, time_msec, button, state);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
seat_pointer_notify_button(seat, time_msec, button, state);
|
2018-04-08 16:48:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_cursor_button(struct wl_listener *listener, void *data) {
|
|
|
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, button);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2018-04-08 16:48:13 +02:00
|
|
|
struct wlr_event_pointer_button *event = data;
|
2018-10-18 19:13:40 +02:00
|
|
|
dispatch_cursor_button(cursor, event->device,
|
2018-04-08 16:48:13 +02:00
|
|
|
event->time_msec, event->button, event->state);
|
2018-08-10 08:51:24 +02:00
|
|
|
transaction_commit_dirty();
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
2018-09-22 02:42:59 +02:00
|
|
|
static void dispatch_cursor_axis(struct sway_cursor *cursor,
|
|
|
|
struct wlr_event_pointer_axis *event) {
|
|
|
|
struct sway_seat *seat = cursor->seat;
|
|
|
|
|
|
|
|
// Determine what's under the cursor
|
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
double sx, sy;
|
|
|
|
struct sway_node *node = node_at_coords(seat,
|
|
|
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
|
|
|
struct sway_container *cont = node && node->type == N_CONTAINER ?
|
|
|
|
node->sway_container : NULL;
|
|
|
|
enum wlr_edges edge = cont ? find_edge(cont, cursor) : WLR_EDGE_NONE;
|
|
|
|
bool on_border = edge != WLR_EDGE_NONE;
|
|
|
|
bool on_titlebar = cont && !on_border && !surface;
|
|
|
|
|
|
|
|
// Scrolling on a tabbed or stacked title bar
|
|
|
|
if (on_titlebar) {
|
|
|
|
enum sway_container_layout layout = container_parent_layout(cont);
|
|
|
|
if (layout == L_TABBED || layout == L_STACKED) {
|
2018-10-24 15:51:11 +02:00
|
|
|
struct sway_node *tabcontainer = node_get_parent(node);
|
2018-09-22 02:42:59 +02:00
|
|
|
struct sway_node *active =
|
2018-10-24 15:51:11 +02:00
|
|
|
seat_get_active_tiling_child(seat, tabcontainer);
|
2018-09-22 02:42:59 +02:00
|
|
|
list_t *siblings = container_get_siblings(cont);
|
|
|
|
int desired = list_find(siblings, active->sway_container) +
|
|
|
|
event->delta_discrete;
|
|
|
|
if (desired < 0) {
|
|
|
|
desired = 0;
|
|
|
|
} else if (desired >= siblings->length) {
|
|
|
|
desired = siblings->length - 1;
|
|
|
|
}
|
2018-10-24 15:51:11 +02:00
|
|
|
struct sway_node *old_focus = seat_get_focus(seat);
|
|
|
|
struct sway_container *new_sibling_con = siblings->items[desired];
|
|
|
|
struct sway_node *new_sibling = &new_sibling_con->node;
|
|
|
|
struct sway_node *new_focus =
|
|
|
|
seat_get_focus_inactive(seat, new_sibling);
|
|
|
|
if (node_has_ancestor(old_focus, tabcontainer)) {
|
|
|
|
seat_set_focus(seat, new_focus);
|
|
|
|
} else {
|
|
|
|
// Scrolling when focus is not in the tabbed container at all
|
|
|
|
seat_set_raw_focus(seat, new_sibling);
|
|
|
|
seat_set_raw_focus(seat, new_focus);
|
|
|
|
seat_set_raw_focus(seat, old_focus);
|
|
|
|
}
|
2018-09-22 02:42:59 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec,
|
|
|
|
event->orientation, event->delta, event->delta_discrete, event->source);
|
|
|
|
}
|
|
|
|
|
2017-12-08 13:22:26 +01:00
|
|
|
static void handle_cursor_axis(struct wl_listener *listener, void *data) {
|
2018-03-30 21:33:16 +02:00
|
|
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, axis);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_event_pointer_axis *event = data;
|
2018-09-22 02:42:59 +02:00
|
|
|
dispatch_cursor_axis(cursor, event);
|
|
|
|
transaction_commit_dirty();
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_touch_down(struct wl_listener *listener, void *data) {
|
2018-03-30 21:33:16 +02:00
|
|
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_event_touch_down *event = data;
|
2018-05-02 15:00:26 +02:00
|
|
|
|
2018-06-09 14:26:03 +02:00
|
|
|
struct sway_seat *seat = cursor->seat;
|
|
|
|
struct wlr_seat *wlr_seat = seat->wlr_seat;
|
2018-05-02 15:00:26 +02:00
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
|
|
|
|
double lx, ly;
|
|
|
|
wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
|
|
|
|
event->x, event->y, &lx, &ly);
|
|
|
|
double sx, sy;
|
2018-09-04 03:45:49 +02:00
|
|
|
node_at_coords(seat, lx, ly, &surface, &sx, &sy);
|
2018-06-09 14:26:03 +02:00
|
|
|
|
|
|
|
seat->touch_id = event->touch_id;
|
|
|
|
seat->touch_x = lx;
|
|
|
|
seat->touch_y = ly;
|
2018-05-02 15:00:26 +02:00
|
|
|
|
|
|
|
if (!surface) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: fall back to cursor simulation if client has not bound to touch
|
2018-06-09 14:26:03 +02:00
|
|
|
if (seat_is_input_allowed(seat, surface)) {
|
|
|
|
wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec,
|
2018-05-02 15:00:26 +02:00
|
|
|
event->touch_id, sx, sy);
|
2018-09-24 13:29:47 +02:00
|
|
|
cursor_set_image(cursor, NULL, NULL);
|
2018-05-02 15:00:26 +02:00
|
|
|
}
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_touch_up(struct wl_listener *listener, void *data) {
|
2018-03-30 21:33:16 +02:00
|
|
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_event_touch_up *event = data;
|
2018-05-02 15:00:26 +02:00
|
|
|
struct wlr_seat *seat = cursor->seat->wlr_seat;
|
|
|
|
// TODO: fall back to cursor simulation if client has not bound to touch
|
|
|
|
wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id);
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
|
|
|
struct sway_cursor *cursor =
|
|
|
|
wl_container_of(listener, cursor, touch_motion);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_event_touch_motion *event = data;
|
2018-05-02 15:00:26 +02:00
|
|
|
|
2018-06-09 14:26:03 +02:00
|
|
|
struct sway_seat *seat = cursor->seat;
|
|
|
|
struct wlr_seat *wlr_seat = seat->wlr_seat;
|
2018-05-02 15:00:26 +02:00
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
|
|
|
|
double lx, ly;
|
|
|
|
wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
|
|
|
|
event->x, event->y, &lx, &ly);
|
|
|
|
double sx, sy;
|
2018-09-04 03:45:49 +02:00
|
|
|
node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy);
|
2018-05-02 15:00:26 +02:00
|
|
|
|
2018-06-09 14:26:03 +02:00
|
|
|
if (seat->touch_id == event->touch_id) {
|
|
|
|
seat->touch_x = lx;
|
|
|
|
seat->touch_y = ly;
|
|
|
|
|
|
|
|
struct wlr_drag_icon *wlr_drag_icon;
|
|
|
|
wl_list_for_each(wlr_drag_icon, &wlr_seat->drag_icons, link) {
|
|
|
|
struct sway_drag_icon *drag_icon = wlr_drag_icon->data;
|
|
|
|
drag_icon_update_position(drag_icon);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-02 15:00:26 +02:00
|
|
|
if (!surface) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: fall back to cursor simulation if client has not bound to touch
|
|
|
|
if (seat_is_input_allowed(cursor->seat, surface)) {
|
2018-06-09 14:26:03 +02:00
|
|
|
wlr_seat_touch_notify_motion(wlr_seat, event->time_msec,
|
|
|
|
event->touch_id, sx, sy);
|
2018-05-02 15:00:26 +02:00
|
|
|
}
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
2018-04-24 20:39:29 +02:00
|
|
|
static double apply_mapping_from_coord(double low, double high, double value) {
|
2018-04-27 18:30:45 +02:00
|
|
|
if (isnan(value)) {
|
2018-04-24 20:39:29 +02:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2018-04-27 18:30:45 +02:00
|
|
|
return (value - low) / (high - low);
|
2018-04-24 20:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void apply_mapping_from_region(struct wlr_input_device *device,
|
|
|
|
struct input_config_mapped_from_region *region, double *x, double *y) {
|
|
|
|
double x1 = region->x1, x2 = region->x2;
|
|
|
|
double y1 = region->y1, y2 = region->y2;
|
|
|
|
|
|
|
|
if (region->mm) {
|
|
|
|
if (device->width_mm == 0 || device->height_mm == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
x1 /= device->width_mm;
|
|
|
|
x2 /= device->width_mm;
|
|
|
|
y1 /= device->height_mm;
|
|
|
|
y2 /= device->height_mm;
|
|
|
|
}
|
|
|
|
|
|
|
|
*x = apply_mapping_from_coord(x1, x2, *x);
|
|
|
|
*y = apply_mapping_from_coord(y1, y2, *y);
|
|
|
|
}
|
|
|
|
|
2017-12-08 13:22:26 +01:00
|
|
|
static void handle_tool_axis(struct wl_listener *listener, void *data) {
|
2018-03-30 21:33:16 +02:00
|
|
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_event_tablet_tool_axis *event = data;
|
2018-04-24 20:39:29 +02:00
|
|
|
struct sway_input_device *input_device = event->device->data;
|
2018-04-08 16:48:13 +02:00
|
|
|
|
2018-04-27 18:30:45 +02:00
|
|
|
double x = NAN, y = NAN;
|
2018-04-24 20:39:29 +02:00
|
|
|
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) {
|
|
|
|
x = event->x;
|
|
|
|
}
|
|
|
|
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) {
|
|
|
|
y = event->y;
|
2018-04-08 16:48:13 +02:00
|
|
|
}
|
2018-04-24 20:39:29 +02:00
|
|
|
|
|
|
|
struct input_config *ic = input_device_get_config(input_device);
|
|
|
|
if (ic != NULL && ic->mapped_from_region != NULL) {
|
|
|
|
apply_mapping_from_region(event->device, ic->mapped_from_region, &x, &y);
|
|
|
|
}
|
|
|
|
|
|
|
|
wlr_cursor_warp_absolute(cursor->cursor, event->device, x, y);
|
2018-10-18 16:04:21 +02:00
|
|
|
cursor_send_pointer_motion(cursor, event->time_msec);
|
2018-07-19 11:49:50 +02:00
|
|
|
transaction_commit_dirty();
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_tool_tip(struct wl_listener *listener, void *data) {
|
2018-03-30 21:33:16 +02:00
|
|
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_event_tablet_tool_tip *event = data;
|
2018-10-18 19:13:40 +02:00
|
|
|
dispatch_cursor_button(cursor, event->device, event->time_msec,
|
2018-04-08 16:48:13 +02:00
|
|
|
BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ?
|
|
|
|
WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED);
|
2018-08-10 08:51:24 +02:00
|
|
|
transaction_commit_dirty();
|
2018-04-08 16:48:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_tool_button(struct wl_listener *listener, void *data) {
|
|
|
|
struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_button);
|
2018-10-18 13:20:00 +02:00
|
|
|
wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat);
|
2018-04-08 16:48:13 +02:00
|
|
|
struct wlr_event_tablet_tool_button *event = data;
|
|
|
|
// TODO: the user may want to configure which tool buttons are mapped to
|
|
|
|
// which simulated pointer buttons
|
|
|
|
switch (event->state) {
|
|
|
|
case WLR_BUTTON_PRESSED:
|
|
|
|
if (cursor->tool_buttons == 0) {
|
2018-10-18 19:13:40 +02:00
|
|
|
dispatch_cursor_button(cursor, event->device,
|
2018-04-08 16:48:13 +02:00
|
|
|
event->time_msec, BTN_RIGHT, event->state);
|
|
|
|
}
|
|
|
|
cursor->tool_buttons++;
|
|
|
|
break;
|
|
|
|
case WLR_BUTTON_RELEASED:
|
|
|
|
if (cursor->tool_buttons == 1) {
|
2018-10-18 19:13:40 +02:00
|
|
|
dispatch_cursor_button(cursor, event->device,
|
2018-04-08 16:48:13 +02:00
|
|
|
event->time_msec, BTN_RIGHT, event->state);
|
|
|
|
}
|
|
|
|
cursor->tool_buttons--;
|
|
|
|
break;
|
|
|
|
}
|
2018-08-10 08:51:24 +02:00
|
|
|
transaction_commit_dirty();
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_request_set_cursor(struct wl_listener *listener,
|
|
|
|
void *data) {
|
|
|
|
struct sway_cursor *cursor =
|
|
|
|
wl_container_of(listener, cursor, request_set_cursor);
|
2018-07-22 15:10:06 +02:00
|
|
|
if (cursor->seat->operation != OP_NONE) {
|
|
|
|
return;
|
|
|
|
}
|
2017-12-08 13:22:26 +01:00
|
|
|
struct wlr_seat_pointer_request_set_cursor_event *event = data;
|
2018-03-30 16:53:18 +02:00
|
|
|
|
|
|
|
struct wl_client *focused_client = NULL;
|
|
|
|
struct wlr_surface *focused_surface =
|
|
|
|
cursor->seat->wlr_seat->pointer_state.focused_surface;
|
|
|
|
if (focused_surface != NULL) {
|
|
|
|
focused_client = wl_resource_get_client(focused_surface->resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: check cursor mode
|
|
|
|
if (focused_client == NULL ||
|
|
|
|
event->seat_client->client != focused_client) {
|
2018-07-09 23:54:30 +02:00
|
|
|
wlr_log(WLR_DEBUG, "denying request to set cursor from unfocused client");
|
2018-03-30 16:53:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x,
|
|
|
|
event->hotspot_y);
|
2018-07-24 01:09:49 +02:00
|
|
|
cursor->image = NULL;
|
2018-03-30 16:53:18 +02:00
|
|
|
cursor->image_client = focused_client;
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|
|
|
|
|
2018-07-21 02:57:14 +02:00
|
|
|
void cursor_set_image(struct sway_cursor *cursor, const char *image,
|
|
|
|
struct wl_client *client) {
|
2018-10-23 13:38:30 +02:00
|
|
|
if (!(cursor->seat->wlr_seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) {
|
|
|
|
return;
|
|
|
|
}
|
2018-09-24 13:29:47 +02:00
|
|
|
if (!image) {
|
|
|
|
wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
|
|
|
|
} else if (!cursor->image || strcmp(cursor->image, image) != 0) {
|
2018-07-21 02:57:14 +02:00
|
|
|
wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image,
|
|
|
|
cursor->cursor);
|
|
|
|
}
|
2018-09-24 13:29:47 +02:00
|
|
|
cursor->image = image;
|
2018-07-21 02:57:14 +02:00
|
|
|
cursor->image_client = client;
|
|
|
|
}
|
|
|
|
|
2018-01-16 21:16:04 +01:00
|
|
|
void sway_cursor_destroy(struct sway_cursor *cursor) {
|
|
|
|
if (!cursor) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wlr_xcursor_manager_destroy(cursor->xcursor_manager);
|
|
|
|
wlr_cursor_destroy(cursor->cursor);
|
|
|
|
free(cursor);
|
|
|
|
}
|
|
|
|
|
2017-12-08 13:22:26 +01:00
|
|
|
struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
|
|
|
|
struct sway_cursor *cursor = calloc(1, sizeof(struct sway_cursor));
|
|
|
|
if (!sway_assert(cursor, "could not allocate sway cursor")) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct wlr_cursor *wlr_cursor = wlr_cursor_create();
|
|
|
|
if (!sway_assert(wlr_cursor, "could not allocate wlr cursor")) {
|
|
|
|
free(cursor);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-06-06 12:45:02 +02:00
|
|
|
cursor->previous.x = wlr_cursor->x;
|
|
|
|
cursor->previous.y = wlr_cursor->y;
|
|
|
|
|
2017-12-10 14:48:44 +01:00
|
|
|
cursor->seat = seat;
|
Implement type safe arguments and demote sway_container
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.
2018-08-30 13:00:10 +02:00
|
|
|
wlr_cursor_attach_output_layout(wlr_cursor, root->output_layout);
|
2017-12-09 20:06:00 +01:00
|
|
|
|
2017-12-08 13:22:26 +01:00
|
|
|
// input events
|
|
|
|
wl_signal_add(&wlr_cursor->events.motion, &cursor->motion);
|
|
|
|
cursor->motion.notify = handle_cursor_motion;
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_cursor->events.motion_absolute,
|
|
|
|
&cursor->motion_absolute);
|
|
|
|
cursor->motion_absolute.notify = handle_cursor_motion_absolute;
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_cursor->events.button, &cursor->button);
|
|
|
|
cursor->button.notify = handle_cursor_button;
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_cursor->events.axis, &cursor->axis);
|
|
|
|
cursor->axis.notify = handle_cursor_axis;
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_cursor->events.touch_down, &cursor->touch_down);
|
|
|
|
cursor->touch_down.notify = handle_touch_down;
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_cursor->events.touch_up, &cursor->touch_up);
|
|
|
|
cursor->touch_up.notify = handle_touch_up;
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_cursor->events.touch_motion,
|
|
|
|
&cursor->touch_motion);
|
|
|
|
cursor->touch_motion.notify = handle_touch_motion;
|
|
|
|
|
2018-04-08 16:48:13 +02:00
|
|
|
// TODO: tablet protocol support
|
|
|
|
// Note: We should emulate pointer events for clients that don't support the
|
|
|
|
// tablet protocol when the time comes
|
2017-12-08 13:22:26 +01:00
|
|
|
wl_signal_add(&wlr_cursor->events.tablet_tool_axis,
|
|
|
|
&cursor->tool_axis);
|
|
|
|
cursor->tool_axis.notify = handle_tool_axis;
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &cursor->tool_tip);
|
|
|
|
cursor->tool_tip.notify = handle_tool_tip;
|
|
|
|
|
2018-04-08 16:48:13 +02:00
|
|
|
wl_signal_add(&wlr_cursor->events.tablet_tool_button, &cursor->tool_button);
|
|
|
|
cursor->tool_button.notify = handle_tool_button;
|
|
|
|
|
2017-12-14 17:11:56 +01:00
|
|
|
wl_signal_add(&seat->wlr_seat->events.request_set_cursor,
|
2017-12-08 13:22:26 +01:00
|
|
|
&cursor->request_set_cursor);
|
|
|
|
cursor->request_set_cursor.notify = handle_request_set_cursor;
|
|
|
|
|
|
|
|
cursor->cursor = wlr_cursor;
|
|
|
|
|
|
|
|
return cursor;
|
2018-10-15 16:18:46 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Warps the cursor to the middle of the container argument.
|
|
|
|
* Does nothing if the cursor is already inside the container.
|
|
|
|
* If container is NULL, returns without doing anything.
|
|
|
|
*/
|
|
|
|
void cursor_warp_to_container(struct sway_cursor *cursor,
|
|
|
|
struct sway_container *container) {
|
|
|
|
if (!container) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct wlr_box box;
|
|
|
|
container_get_box(container, &box);
|
|
|
|
if (wlr_box_contains_point(&box, cursor->cursor->x, cursor->cursor->y)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
double x = container->x + container->width / 2.0;
|
|
|
|
double y = container->y + container->height / 2.0;
|
|
|
|
|
|
|
|
wlr_cursor_warp(cursor->cursor, NULL, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Warps the cursor to the middle of the workspace argument.
|
|
|
|
* If workspace is NULL, returns without doing anything.
|
|
|
|
*/
|
|
|
|
void cursor_warp_to_workspace(struct sway_cursor *cursor,
|
|
|
|
struct sway_workspace *workspace) {
|
|
|
|
if (!workspace) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
double x = workspace->x + workspace->width / 2.0;
|
|
|
|
double y = workspace->y + workspace->height / 2.0;
|
|
|
|
|
|
|
|
wlr_cursor_warp(cursor->cursor, NULL, x, y);
|
2017-12-08 13:22:26 +01:00
|
|
|
}
|