Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify some input logic #8317

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
11 changes: 9 additions & 2 deletions include/sway/input/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,16 @@ struct sway_cursor {

struct sway_node;

struct wlr_scene_node *scene_node_at_coords(
double lx, double ly, double *sx, double *sy);

struct wlr_surface *surface_try_from_scene_node(struct wlr_scene_node *node);

struct sway_node *sway_node_try_from_scene_node(struct wlr_scene_node *node,
double lx, double ly);

struct sway_node *node_at_coords(
struct sway_seat *seat, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy);
double lx, double ly, struct wlr_surface **surface, double *sx, double *sy);

void sway_cursor_destroy(struct sway_cursor *cursor);
struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
Expand Down
3 changes: 0 additions & 3 deletions include/sway/layers.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ struct sway_layer_popup {

struct sway_output;

struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
struct wlr_surface *surface);

void arrange_layers(struct sway_output *output);

#endif
21 changes: 21 additions & 0 deletions include/sway/scene_descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
#define _SWAY_SCENE_DESCRIPTOR_H
#include <wlr/types/wlr_scene.h>

struct sway_view;

// used for SWAY_SCENE_DESC_POPUP
struct sway_popup_desc {
struct wlr_scene_node *relative;
struct sway_view *view;
};

enum sway_scene_descriptor_type {
SWAY_SCENE_DESC_BUFFER_TIMER,
SWAY_SCENE_DESC_NON_INTERACTIVE,
Expand All @@ -24,10 +32,23 @@ enum sway_scene_descriptor_type {
bool scene_descriptor_assign(struct wlr_scene_node *node,
enum sway_scene_descriptor_type type, void *data);

bool scene_descriptor_reassign(struct wlr_scene_node *node,
enum sway_scene_descriptor_type type, void *data);

void *scene_descriptor_try_get(struct wlr_scene_node *node,
enum sway_scene_descriptor_type type);

void scene_descriptor_destroy(struct wlr_scene_node *node,
enum sway_scene_descriptor_type type);

/*
* Searches the scene node and all its parents for this scene descriptor.
*
* Note that while searching, SWAY_SCENE_DESC_POPUP types will start tracking
* its relative node. With popups, they are part of a seperate layer in the scene
* graph, but that's irrelavent to users of this function.
*/
void *scene_descriptor_find(struct wlr_scene_node *node,
enum sway_scene_descriptor_type type);

#endif
6 changes: 1 addition & 5 deletions include/sway/tree/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#endif
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/scene_descriptor.h"

struct sway_container;
struct sway_xdg_decoration;
Expand Down Expand Up @@ -187,11 +188,6 @@ struct sway_xwayland_unmanaged {
};
#endif

struct sway_popup_desc {
struct wlr_scene_node *relative;
struct sway_view *view;
};

struct sway_xdg_popup {
struct sway_view *view;

Expand Down
2 changes: 1 addition & 1 deletion sway/commands/bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding)
|| binding->type == BINDING_MOUSECODE) {
struct wlr_surface *surface = NULL;
double sx, sy;
struct sway_node *node = node_at_coords(seat,
struct sway_node *node = node_at_coords(
seat->cursor->cursor->x, seat->cursor->cursor->y,
&surface, &sx, &sy);
if (node && node->type == N_CONTAINER) {
Expand Down
33 changes: 0 additions & 33 deletions sway/desktop/layer_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,6 @@
#include "sway/tree/arrange.h"
#include "sway/tree/workspace.h"

struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
struct wlr_surface *surface) {
struct wlr_layer_surface_v1 *layer;
do {
if (!surface) {
return NULL;
}
// Topmost layer surface
if ((layer = wlr_layer_surface_v1_try_from_wlr_surface(surface))) {
return layer;
}
// Layer subsurface
if (wlr_subsurface_try_from_wlr_surface(surface)) {
surface = wlr_surface_get_root_surface(surface);
continue;
}

// Layer surface popup
struct wlr_xdg_surface *xdg_surface = NULL;
if ((xdg_surface = wlr_xdg_surface_try_from_wlr_surface(surface)) &&
xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP && xdg_surface->popup != NULL) {
if (!xdg_surface->popup->parent) {
return NULL;
}
surface = wlr_surface_get_root_surface(xdg_surface->popup->parent);
continue;
}

// Return early if the surface is not a layer/xdg_popup/sub surface
return NULL;
} while (true);
}

static void arrange_surface(struct sway_output *output, const struct wlr_box *full_area,
struct wlr_box *usable_area, struct wlr_scene_tree *tree) {
struct wlr_scene_node *node;
Expand Down
17 changes: 3 additions & 14 deletions sway/desktop/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,20 +151,9 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer,
return;
}

struct wlr_scene_node *current = &buffer->node;
while (true) {
struct sway_view *view = scene_descriptor_try_get(current,
SWAY_SCENE_DESC_VIEW);
if (view) {
view_max_render_time = view->max_render_time;
break;
}

if (!current->parent) {
break;
}

current = &current->parent->node;
struct sway_view *view = scene_descriptor_find(&buffer->node, SWAY_SCENE_DESC_VIEW);
if (view) {
view_max_render_time = view->max_render_time;
}

int delay = data->msec_until_refresh - output->max_render_time
Expand Down
121 changes: 56 additions & 65 deletions sway/input/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,8 @@ static uint32_t get_current_time_msec(void) {
return now.tv_sec * 1000 + now.tv_nsec / 1000000;
}

/**
* Returns the node at the cursor's position. If there is a surface at that
* location, it is stored in **surface (it may not be a view).
*/
struct sway_node *node_at_coords(
struct sway_seat *seat, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy) {
struct wlr_scene_node *scene_node = NULL;

struct wlr_scene_node *scene_node_at_coords(
double lx, double ly, double *sx, double *sy) {
struct wlr_scene_node *node;
wl_list_for_each_reverse(node, &root->layer_tree->children, link) {
struct wlr_scene_tree *layer = wlr_scene_tree_from_node(node);
Expand All @@ -57,69 +50,58 @@ struct sway_node *node_at_coords(
continue;
}

scene_node = wlr_scene_node_at(&layer->node, lx, ly, sx, sy);
if (scene_node) {
break;
struct wlr_scene_node *node = wlr_scene_node_at(&layer->node, lx, ly, sx, sy);
if (node) {
return node;
}
}

if (scene_node) {
// determine what wlr_surface we clicked on
if (scene_node->type == WLR_SCENE_NODE_BUFFER) {
struct wlr_scene_buffer *scene_buffer =
wlr_scene_buffer_from_node(scene_node);
struct wlr_scene_surface *scene_surface =
wlr_scene_surface_try_from_buffer(scene_buffer);
return NULL;
}

if (scene_surface) {
*surface = scene_surface->surface;
}
}
struct wlr_surface *surface_try_from_scene_node(struct wlr_scene_node *node) {
if (!node || node->type != WLR_SCENE_NODE_BUFFER) {
return NULL;
}

// determine what container we clicked on
struct wlr_scene_node *current = scene_node;
while (true) {
struct sway_container *con = scene_descriptor_try_get(current,
SWAY_SCENE_DESC_CONTAINER);

if (!con) {
struct sway_view *view = scene_descriptor_try_get(current,
SWAY_SCENE_DESC_VIEW);
if (view) {
con = view->container;
}
}
struct wlr_scene_buffer *scene_buffer =
wlr_scene_buffer_from_node(node);
struct wlr_scene_surface *scene_surface =
wlr_scene_surface_try_from_buffer(scene_buffer);

if (!con) {
struct sway_popup_desc *popup =
scene_descriptor_try_get(current, SWAY_SCENE_DESC_POPUP);
if (popup && popup->view) {
con = popup->view->container;
}
}
if (scene_surface) {
return scene_surface->surface;
}

if (con && (!con->view || con->view->surface)) {
return &con->node;
}
return NULL;
}

if (scene_descriptor_try_get(current, SWAY_SCENE_DESC_LAYER_SHELL)) {
// We don't want to feed through the current workspace on
// layer shells
struct sway_node *sway_node_try_from_scene_node(struct wlr_scene_node *node,
double lx, double ly) {
if (node) {
struct sway_container *con =
scene_descriptor_find(node, SWAY_SCENE_DESC_CONTAINER);
if (con) {
// If this condition succeeds, the container is currently in the
// process of being destroyed. In this case, ignore the container
if (con->view && !con->view->surface) {
return NULL;
}

#if WLR_HAS_XWAYLAND
if (scene_descriptor_try_get(current, SWAY_SCENE_DESC_XWAYLAND_UNMANAGED)) {
return NULL;
}
#endif
return &con->node;
}

if (!current->parent) {
break;
}
// if we clicked on a layer shell or unmanaged xwayland we don't
// want to return the workspace node.
if (scene_descriptor_find(node, SWAY_SCENE_DESC_LAYER_SHELL)) {
return NULL;
}

current = &current->parent->node;
#if WLR_HAS_XWAYLAND
if (scene_descriptor_find(node, SWAY_SCENE_DESC_XWAYLAND_UNMANAGED)) {
return NULL;
}
#endif
}

// if we aren't on a container, determine what workspace we are on
Expand All @@ -143,6 +125,18 @@ struct sway_node *node_at_coords(
return &ws->node;
}

/**
* Returns the node at the cursor's position. If there is a surface at that
* location, it is stored in **surface (it may not be a view).
*/
struct sway_node *node_at_coords(double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy) {
struct wlr_scene_node *scene_node = scene_node_at_coords(lx, ly, sx, sy);
*surface = surface_try_from_scene_node(scene_node);

return sway_node_try_from_scene_node(scene_node, lx, ly);
}

void cursor_rebase(struct sway_cursor *cursor) {
uint32_t time_msec = get_current_time_msec();
seatop_rebase(cursor->seat, time_msec);
Expand Down Expand Up @@ -305,8 +299,7 @@ void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
if (cursor->active_constraint && device->type == WLR_INPUT_DEVICE_POINTER) {
struct wlr_surface *surface = NULL;
double sx, sy;
node_at_coords(cursor->seat,
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
node_at_coords(cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);

if (cursor->active_constraint->surface != surface) {
return;
Expand Down Expand Up @@ -565,7 +558,7 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
double sx, sy;
struct wlr_surface *surface = NULL;
struct sway_seat *seat = cursor->seat;
node_at_coords(seat, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
node_at_coords(cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);

// The logic for whether we should send a tablet event or an emulated pointer
// event is tricky. It comes down to:
Expand Down Expand Up @@ -655,8 +648,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {

double sx, sy;
struct wlr_surface *surface = NULL;
node_at_coords(seat, cursor->cursor->x, cursor->cursor->y,
&surface, &sx, &sy);
node_at_coords(cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);

if (cursor->simulating_pointer_from_tool_tip &&
event->state == WLR_TABLET_TOOL_TIP_UP) {
Expand Down Expand Up @@ -740,8 +732,7 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
double sx, sy;
struct wlr_surface *surface = NULL;

node_at_coords(cursor->seat, cursor->cursor->x, cursor->cursor->y,
&surface, &sx, &sy);
node_at_coords(cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);

// TODO: floating resize should support graphics tablet events
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(cursor->seat->wlr_seat);
Expand Down
Loading