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

Fix mouse warping container #2820

Merged
merged 4 commits into from
Oct 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion include/sway/input/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec,
uint32_t button, enum wlr_button_state state);

void cursor_set_image(struct sway_cursor *cursor, const char *image,
struct wl_client *client);
struct wl_client *client);

void cursor_warp_to_container(struct sway_cursor *cursor,
struct sway_container *container);

void cursor_warp_to_workspace(struct sway_cursor *cursor,
struct sway_workspace *workspace);
#endif
3 changes: 2 additions & 1 deletion include/sway/tree/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ void view_destroy(struct sway_view *view);

void view_begin_destroy(struct sway_view *view);

void view_map(struct sway_view *view, struct wlr_surface *wlr_surface);
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
bool fullscreen, bool decoration);

void view_unmap(struct sway_view *view);

Expand Down
20 changes: 6 additions & 14 deletions sway/desktop/xdg_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,27 +406,19 @@ static void handle_map(struct wl_listener *listener, void *data) {
view->natural_height = view->wlr_xdg_surface->surface->current.height;
}

view_map(view, view->wlr_xdg_surface->surface);
bool csd = false;

if (!view->xdg_decoration) {
struct sway_server_decoration *deco =
decoration_from_surface(xdg_surface->surface);
bool csd = !deco || deco->wlr_server_decoration->mode ==
decoration_from_surface(xdg_surface->surface);
csd = !deco || deco->wlr_server_decoration->mode ==
WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT;
view_update_csd_from_client(view, csd);
}

if (xdg_surface->toplevel->client_pending.fullscreen) {
container_set_fullscreen(view->container, true);
arrange_workspace(view->container->workspace);
} else {
if (view->container->parent) {
arrange_container(view->container->parent);
} else if (view->container->workspace) {
arrange_workspace(view->container->workspace);
}
}

view_map(view, view->wlr_xdg_surface->surface,
xdg_surface->toplevel->client_pending.fullscreen, csd);

transaction_commit_dirty();

xdg_shell_view->commit.notify = handle_commit;
Expand Down
23 changes: 6 additions & 17 deletions sway/desktop/xdg_shell_v6.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,25 +402,14 @@ static void handle_map(struct wl_listener *listener, void *data) {
view->natural_width = view->wlr_xdg_surface_v6->surface->current.width;
view->natural_height = view->wlr_xdg_surface_v6->surface->current.height;
}
struct sway_server_decoration *deco =
decoration_from_surface(xdg_surface->surface);
bool csd = !deco || deco->wlr_server_decoration->mode
== WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT;

view_map(view, view->wlr_xdg_surface_v6->surface);
view_map(view, view->wlr_xdg_surface_v6->surface,
xdg_surface->toplevel->client_pending.fullscreen, csd);

struct sway_server_decoration *deco =
decoration_from_surface(xdg_surface->surface);
bool csd = !deco || deco->wlr_server_decoration->mode ==
WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT;
view_update_csd_from_client(view, csd);

if (xdg_surface->toplevel->client_pending.fullscreen) {
container_set_fullscreen(view->container, true);
arrange_workspace(view->container->workspace);
} else {
if (view->container->parent) {
arrange_container(view->container->parent);
} else if (view->container->workspace) {
arrange_workspace(view->container->workspace);
}
}
transaction_commit_dirty();

xdg_shell_v6_view->commit.notify = handle_commit;
Expand Down
12 changes: 1 addition & 11 deletions sway/desktop/xwayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,18 +405,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
xwayland_view->commit.notify = handle_commit;

// Put it back into the tree
view_map(view, xsurface->surface);
view_map(view, xsurface->surface, xsurface->fullscreen, false);

if (xsurface->fullscreen) {
container_set_fullscreen(view->container, true);
arrange_workspace(view->container->workspace);
} else {
if (view->container->parent) {
arrange_container(view->container->parent);
} else if (view->container->workspace) {
arrange_workspace(view->container->workspace);
}
}
transaction_commit_dirty();
}

Expand Down
41 changes: 41 additions & 0 deletions sway/input/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_box.h>
#include "list.h"
#include "log.h"
#include "config.h"
Expand Down Expand Up @@ -1271,4 +1272,44 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
cursor->cursor = wlr_cursor;

return cursor;

}

/**
* 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);
}
27 changes: 9 additions & 18 deletions sway/input/seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,27 +771,18 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node,
workspace_consider_destroy(last_workspace);
}

if (last_focus) {
if (config->mouse_warping && warp &&
(new_output != last_output ||
config->mouse_warping == WARP_CONTAINER)) {
double x = 0;
double y = 0;
if (last_focus && warp) {
if (container && config->mouse_warping == WARP_CONTAINER) {
cursor_warp_to_container(seat->cursor, container);
cursor_send_pointer_motion(seat->cursor, 0, true);
} else if (new_output != last_output &&
config->mouse_warping >= WARP_OUTPUT) {
if (container) {
x = container->x + container->width / 2.0;
y = container->y + container->height / 2.0;
cursor_warp_to_container(seat->cursor, container);
} else {
x = new_workspace->x + new_workspace->width / 2.0;
y = new_workspace->y + new_workspace->height / 2.0;
}

if (!wlr_output_layout_contains_point(root->output_layout,
new_output->wlr_output, seat->cursor->cursor->x,
seat->cursor->cursor->y)
|| config->mouse_warping == WARP_CONTAINER) {
wlr_cursor_warp(seat->cursor->cursor, NULL, x, y);
cursor_send_pointer_motion(seat->cursor, 0, true);
cursor_warp_to_workspace(seat->cursor, new_workspace);
}
cursor_send_pointer_motion(seat->cursor, 0, true);
}
}

Expand Down
37 changes: 31 additions & 6 deletions sway/tree/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,8 @@ static bool should_focus(struct sway_view *view) {
return len == 0;
}

void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
bool fullscreen, bool decoration) {
if (!sway_assert(view->surface == NULL, "cannot map mapped view")) {
return;
}
Expand Down Expand Up @@ -586,13 +587,28 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
}
}

if (should_focus(view)) {
input_manager_set_focus(input_manager, &view->container->node);
}

view_update_title(view, false);
container_update_representation(view->container);
view_execute_criteria(view);

if (decoration) {
view_update_csd_from_client(view, decoration);
}

if (fullscreen) {
container_set_fullscreen(view->container, true);
arrange_workspace(view->container->workspace);
} else {
if (view->container->parent) {
arrange_container(view->container->parent);
} else if (view->container->workspace) {
arrange_workspace(view->container->workspace);
}
}

if (should_focus(view)) {
input_manager_set_focus(input_manager, &view->container->node);
}
}

void view_unmap(struct sway_view *view) {
Expand Down Expand Up @@ -621,7 +637,16 @@ void view_unmap(struct sway_view *view) {

struct sway_seat *seat;
wl_list_for_each(seat, &input_manager->seats, link) {
cursor_send_pointer_motion(seat->cursor, 0, true);
if (config->mouse_warping == WARP_CONTAINER) {
struct sway_node *node = seat_get_focus(seat);
Emantor marked this conversation as resolved.
Show resolved Hide resolved
if (node && node->type == N_CONTAINER) {
cursor_warp_to_container(seat->cursor, node->sway_container);
} else if (node && node->type == N_WORKSPACE) {
cursor_warp_to_workspace(seat->cursor, node->sway_workspace);
}
} else {
cursor_send_pointer_motion(seat->cursor, 0, true);
}
}

transaction_commit_dirty();
Expand Down