Add interactive move and rudamentary resize

This commit is contained in:
buffet 2020-01-17 19:51:56 +00:00
parent 598731af12
commit b909262f5a
7 changed files with 165 additions and 5 deletions

View file

@ -36,6 +36,8 @@ struct kiwmi_view {
struct wl_listener map; struct wl_listener map;
struct wl_listener unmap; struct wl_listener unmap;
struct wl_listener destroy; struct wl_listener destroy;
struct wl_listener request_move;
struct wl_listener request_resize;
double x; double x;
double y; double y;
@ -91,6 +93,8 @@ struct kiwmi_view *view_at(
struct wlr_surface **surface, struct wlr_surface **surface,
double *sx, double *sx,
double *sy); double *sy);
void view_move(struct kiwmi_view *view);
void view_resize(struct kiwmi_view *view, uint32_t edges);
struct kiwmi_view *view_create( struct kiwmi_view *view_create(
struct kiwmi_desktop *desktop, struct kiwmi_desktop *desktop,
enum kiwmi_view_type type, enum kiwmi_view_type type,

View file

@ -11,11 +11,29 @@
#include <wayland-server.h> #include <wayland-server.h>
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include "desktop/view.h"
enum kiwmi_cursor_mode {
KIWMI_CURSOR_PASSTHROUGH,
KIWMI_CURSOR_MOVE,
KIWMI_CURSOR_RESIZE,
};
struct kiwmi_cursor { struct kiwmi_cursor {
struct kiwmi_server *server; struct kiwmi_server *server;
struct wlr_cursor *cursor; struct wlr_cursor *cursor;
struct wlr_xcursor_manager *xcursor_manager; struct wlr_xcursor_manager *xcursor_manager;
enum kiwmi_cursor_mode cursor_mode;
struct {
struct kiwmi_view *view;
int orig_x;
int orig_y;
struct wlr_box orig_geom;
uint32_t resize_edges;
} grabbed;
struct wl_listener cursor_motion; struct wl_listener cursor_motion;
struct wl_listener cursor_motion_absolute; struct wl_listener cursor_motion_absolute;
struct wl_listener cursor_button; struct wl_listener cursor_button;

View file

@ -7,9 +7,11 @@
#include "desktop/view.h" #include "desktop/view.h"
#include <wlr/types/wlr_cursor.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "desktop/output.h" #include "desktop/output.h"
#include "input/cursor.h"
#include "server.h" #include "server.h"
void void
@ -74,6 +76,7 @@ view_surface_at(
if (view->impl->surface_at) { if (view->impl->surface_at) {
return view->impl->surface_at(view, sx, sy, sub_x, sub_y); return view->impl->surface_at(view, sx, sy, sub_x, sub_y);
} }
return NULL; return NULL;
} }
@ -161,6 +164,57 @@ view_at(
return NULL; return NULL;
} }
static void
view_begin_interactive(
struct kiwmi_view *view,
enum kiwmi_cursor_mode mode,
uint32_t edges)
{
struct kiwmi_desktop *desktop = view->desktop;
struct kiwmi_server *server = wl_container_of(desktop, server, desktop);
struct kiwmi_cursor *cursor = server->input.cursor;
struct wlr_surface *focused_surface =
server->input.seat->pointer_state.focused_surface;
struct wlr_surface *wlr_surface = view->wlr_surface;
if (wlr_surface != focused_surface) {
return;
}
uint32_t width;
uint32_t height;
view_get_size(view, &width, &height);
cursor->cursor_mode = mode;
cursor->grabbed.view = view;
if (mode == KIWMI_CURSOR_MOVE) {
cursor->grabbed.orig_x = cursor->cursor->x - view->x;
cursor->grabbed.orig_y = cursor->cursor->y - view->y;
} else {
cursor->grabbed.orig_x = cursor->cursor->x;
cursor->grabbed.orig_y = cursor->cursor->y;
cursor->grabbed.resize_edges = edges;
}
cursor->grabbed.orig_geom.x = view->x;
cursor->grabbed.orig_geom.y = view->y;
cursor->grabbed.orig_geom.width = width;
cursor->grabbed.orig_geom.height = height;
}
void
view_move(struct kiwmi_view *view)
{
view_begin_interactive(view, KIWMI_CURSOR_MOVE, 0);
}
void
view_resize(struct kiwmi_view *view, uint32_t edges)
{
view_begin_interactive(view, KIWMI_CURSOR_RESIZE, edges);
}
struct kiwmi_view * struct kiwmi_view *
view_create( view_create(
struct kiwmi_desktop *desktop, struct kiwmi_desktop *desktop,

View file

@ -47,10 +47,31 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
wl_list_remove(&view->map.link); wl_list_remove(&view->map.link);
wl_list_remove(&view->unmap.link); wl_list_remove(&view->unmap.link);
wl_list_remove(&view->destroy.link); wl_list_remove(&view->destroy.link);
wl_list_remove(&view->request_move.link);
wl_list_remove(&view->request_resize.link);
free(view); free(view);
} }
static void
xdg_toplevel_request_move_notify(
struct wl_listener *listener,
void *UNUSED(data))
{
struct kiwmi_view *view = wl_container_of(listener, view, request_move);
view_move(view);
}
static void
xdg_toplevel_request_resize_notify(struct wl_listener *listener, void *data)
{
struct kiwmi_view *view = wl_container_of(listener, view, request_resize);
struct wlr_xdg_toplevel_resize_event *event = data;
view_resize(view, event->edges);
}
static void static void
xdg_shell_view_close(struct kiwmi_view *view) xdg_shell_view_close(struct kiwmi_view *view)
{ {
@ -162,5 +183,13 @@ xdg_shell_new_surface_notify(struct wl_listener *listener, void *data)
view->destroy.notify = xdg_surface_destroy_notify; view->destroy.notify = xdg_surface_destroy_notify;
wl_signal_add(&xdg_surface->events.destroy, &view->destroy); wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
view->request_move.notify = xdg_toplevel_request_move_notify;
wl_signal_add(
&xdg_surface->toplevel->events.request_move, &view->request_move);
view->request_resize.notify = xdg_toplevel_request_resize_notify;
wl_signal_add(
&xdg_surface->toplevel->events.request_resize, &view->request_resize);
wl_list_insert(&desktop->views, &view->link); wl_list_insert(&desktop->views, &view->link);
} }

View file

@ -20,6 +20,7 @@
#include "desktop/desktop.h" #include "desktop/desktop.h"
#include "desktop/view.h" #include "desktop/view.h"
#include "server.h" #include "server.h"
#include "wlr/util/edges.h"
static void static void
process_cursor_motion(struct kiwmi_server *server, uint32_t time) process_cursor_motion(struct kiwmi_server *server, uint32_t time)
@ -29,6 +30,56 @@ process_cursor_motion(struct kiwmi_server *server, uint32_t time)
struct kiwmi_cursor *cursor = input->cursor; struct kiwmi_cursor *cursor = input->cursor;
struct wlr_seat *seat = input->seat; struct wlr_seat *seat = input->seat;
switch (cursor->cursor_mode) {
case KIWMI_CURSOR_MOVE: {
struct kiwmi_view *view = cursor->grabbed.view;
view->x = cursor->cursor->x - cursor->grabbed.orig_x;
view->y = cursor->cursor->y - cursor->grabbed.orig_y;
return;
}
case KIWMI_CURSOR_RESIZE: {
struct kiwmi_view *view = cursor->grabbed.view;
double dx = cursor->cursor->x - cursor->grabbed.orig_x;
double dy = cursor->cursor->y - cursor->grabbed.orig_y;
struct wlr_box new_geom = {
.x = view->x,
.y = view->y,
.width = cursor->grabbed.orig_geom.width,
.height = cursor->grabbed.orig_geom.height,
};
if (cursor->grabbed.resize_edges & WLR_EDGE_TOP) {
new_geom.y = cursor->grabbed.orig_y + dy;
new_geom.height -= dy;
if (new_geom.height < 1) {
new_geom.y += new_geom.height;
}
} else if (cursor->grabbed.resize_edges & WLR_EDGE_BOTTOM) {
new_geom.height += dy;
}
if (cursor->grabbed.resize_edges & WLR_EDGE_LEFT) {
new_geom.x = cursor->grabbed.orig_geom.x + dx;
new_geom.width -= dx;
if (new_geom.width < 1) {
new_geom.x += new_geom.width;
}
} else if (cursor->grabbed.resize_edges & WLR_EDGE_RIGHT) {
new_geom.width += dx;
}
view->x = new_geom.x;
view->y = new_geom.y;
view_set_size(view, new_geom.width, new_geom.height);
return;
}
default:
// EMPTY
break;
}
struct wlr_surface *surface = NULL; struct wlr_surface *surface = NULL;
double sx; double sx;
double sy; double sy;
@ -125,6 +176,8 @@ cursor_button_notify(struct wl_listener *listener, void *data)
wlr_seat_pointer_notify_button( wlr_seat_pointer_notify_button(
input->seat, event->time_msec, event->button, event->state); input->seat, event->time_msec, event->button, event->state);
} }
cursor->cursor_mode = KIWMI_CURSOR_PASSTHROUGH;
} }
static void static void
@ -194,7 +247,8 @@ cursor_create(
return NULL; return NULL;
} }
cursor->server = server; cursor->server = server;
cursor->cursor_mode = KIWMI_CURSOR_PASSTHROUGH;
cursor->cursor = wlr_cursor_create(); cursor->cursor = wlr_cursor_create();
if (!cursor->cursor) { if (!cursor->cursor) {

View file

@ -96,7 +96,8 @@ keyboard_key_notify(struct wl_listener *listener, void *data)
static void static void
keyboard_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) keyboard_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
{ {
struct kiwmi_keyboard *keyboard = wl_container_of(listener, keyboard, device_destroy); struct kiwmi_keyboard *keyboard =
wl_container_of(listener, keyboard, device_destroy);
wl_list_remove(&keyboard->link); wl_list_remove(&keyboard->link);
wl_list_remove(&keyboard->modifiers.link); wl_list_remove(&keyboard->modifiers.link);

View file

@ -62,9 +62,9 @@ static const luaL_Reg kiwmi_keyboard_methods[] = {
static void static void
kiwmi_keyboard_on_destroy_notify(struct wl_listener *listener, void *data) kiwmi_keyboard_on_destroy_notify(struct wl_listener *listener, void *data)
{ {
struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener); struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener);
struct kiwmi_server *server = lc->server; struct kiwmi_server *server = lc->server;
lua_State *L = server->lua->L; lua_State *L = server->lua->L;
struct kiwmi_keyboard *keyboard = data; struct kiwmi_keyboard *keyboard = data;
lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref);