aboutsummaryrefslogtreecommitdiff
path: root/rootston/desktop.c
diff options
context:
space:
mode:
Diffstat (limited to 'rootston/desktop.c')
-rw-r--r--rootston/desktop.c99
1 files changed, 95 insertions, 4 deletions
diff --git a/rootston/desktop.c b/rootston/desktop.c
index 3f6d977e..7da64ef8 100644
--- a/rootston/desktop.c
+++ b/rootston/desktop.c
@@ -1,4 +1,4 @@
-#define _POSIX_C_SOURCE 199309L
+#define _POSIX_C_SOURCE 200112L
#include <assert.h>
#include <math.h>
#include <stdlib.h>
@@ -15,6 +15,7 @@
#include <wlr/types/wlr_input_inhibitor.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_output_layout.h>
+#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_wl_shell.h>
@@ -438,6 +439,11 @@ void view_destroy(struct roots_view *view) {
view_unmap(view);
}
+ // Can happen if fullscreened while unmapped, and hasn't been mapped
+ if (view->fullscreen_output != NULL) {
+ view->fullscreen_output->fullscreen_view = NULL;
+ }
+
if (view->destroy) {
view->destroy(view);
}
@@ -575,6 +581,9 @@ static bool view_at(struct roots_view *view, double lx, double ly,
view->wl_shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) {
return false;
}
+ if (view->wlr_surface == NULL) {
+ return false;
+ }
double view_sx = lx - view->x;
double view_sy = ly - view->y;
@@ -776,6 +785,62 @@ static void input_inhibit_deactivate(struct wl_listener *listener, void *data) {
}
}
+static void handle_constraint_destroy(struct wl_listener *listener,
+ void *data) {
+ struct roots_pointer_constraint *constraint =
+ wl_container_of(listener, constraint, destroy);
+ struct wlr_pointer_constraint_v1 *wlr_constraint = data;
+ struct roots_seat *seat = wlr_constraint->seat->data;
+
+ wl_list_remove(&constraint->destroy.link);
+
+ if (seat->cursor->active_constraint == wlr_constraint) {
+ wl_list_remove(&seat->cursor->constraint_commit.link);
+ wl_list_init(&seat->cursor->constraint_commit.link);
+ seat->cursor->active_constraint = NULL;
+
+ if (wlr_constraint->current.committed &
+ WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT &&
+ seat->cursor->pointer_view) {
+ double sx = wlr_constraint->current.cursor_hint.x;
+ double sy = wlr_constraint->current.cursor_hint.y;
+
+ struct roots_view *view = seat->cursor->pointer_view->view;
+ rotate_child_position(&sx, &sy, 0, 0, view->width, view->height,
+ view->rotation);
+ double lx = view->x + sx;
+ double ly = view->y + sy;
+
+ wlr_cursor_warp(seat->cursor->cursor, NULL, lx, ly);
+ }
+ }
+
+ free(constraint);
+}
+
+static void handle_pointer_constraint(struct wl_listener *listener,
+ void *data) {
+ struct wlr_pointer_constraint_v1 *wlr_constraint = data;
+ struct roots_seat *seat = wlr_constraint->seat->data;
+
+ struct roots_pointer_constraint *constraint =
+ calloc(1, sizeof(struct roots_pointer_constraint));
+ constraint->constraint = wlr_constraint;
+
+ constraint->destroy.notify = handle_constraint_destroy;
+ wl_signal_add(&wlr_constraint->events.destroy, &constraint->destroy);
+
+ double sx, sy;
+ struct wlr_surface *surface = desktop_surface_at(
+ seat->input->server->desktop,
+ seat->cursor->cursor->x, seat->cursor->cursor->y, &sx, &sy, NULL);
+
+ if (surface == wlr_constraint->surface) {
+ assert(!seat->cursor->active_constraint);
+ roots_cursor_constrain(seat->cursor, wlr_constraint, sx, sy);
+ }
+}
+
struct roots_desktop *desktop_create(struct roots_server *server,
struct roots_config *config) {
wlr_log(WLR_DEBUG, "Initializing roots desktop");
@@ -824,18 +889,30 @@ struct roots_desktop *desktop_create(struct roots_server *server,
desktop->tablet_v2 = wlr_tablet_v2_create(server->wl_display);
-#ifdef WLR_HAS_XWAYLAND
const char *cursor_theme = NULL;
+#ifdef WLR_HAS_XWAYLAND
const char *cursor_default = ROOTS_XCURSOR_DEFAULT;
+#endif
struct roots_cursor_config *cc =
roots_config_get_cursor(config, ROOTS_CONFIG_DEFAULT_SEAT_NAME);
if (cc != NULL) {
cursor_theme = cc->theme;
+#ifdef WLR_HAS_XWAYLAND
if (cc->default_image != NULL) {
cursor_default = cc->default_image;
}
+#endif
+ }
+
+ char cursor_size_fmt[16];
+ snprintf(cursor_size_fmt, sizeof(cursor_size_fmt),
+ "%d", ROOTS_XCURSOR_SIZE);
+ setenv("XCURSOR_SIZE", cursor_size_fmt, 1);
+ if (cursor_theme != NULL) {
+ setenv("XCURSOR_THEME", cursor_theme, 1);
}
+#ifdef WLR_HAS_XWAYLAND
desktop->xcursor_manager = wlr_xcursor_manager_create(cursor_theme,
ROOTS_XCURSOR_SIZE);
if (desktop->xcursor_manager == NULL) {
@@ -887,10 +964,15 @@ struct roots_desktop *desktop_create(struct roots_server *server,
wlr_input_inhibit_manager_create(server->wl_display);
desktop->input_inhibit_activate.notify = input_inhibit_activate;
wl_signal_add(&desktop->input_inhibit->events.activate,
- &desktop->input_inhibit_activate);
+ &desktop->input_inhibit_activate);
desktop->input_inhibit_deactivate.notify = input_inhibit_deactivate;
wl_signal_add(&desktop->input_inhibit->events.deactivate,
- &desktop->input_inhibit_deactivate);
+ &desktop->input_inhibit_deactivate);
+
+ desktop->input_method =
+ wlr_input_method_manager_v2_create(server->wl_display);
+
+ desktop->text_input = wlr_text_input_manager_v3_create(server->wl_display);
desktop->virtual_keyboard = wlr_virtual_keyboard_manager_v1_create(
server->wl_display);
@@ -906,6 +988,15 @@ struct roots_desktop *desktop_create(struct roots_server *server,
&desktop->xdg_toplevel_decoration);
desktop->xdg_toplevel_decoration.notify = handle_xdg_toplevel_decoration;
+ desktop->pointer_constraints =
+ wlr_pointer_constraints_v1_create(server->wl_display);
+ desktop->pointer_constraint.notify = handle_pointer_constraint;
+ wl_signal_add(&desktop->pointer_constraints->events.new_constraint,
+ &desktop->pointer_constraint);
+
+ desktop->presentation =
+ wlr_presentation_create(server->wl_display, server->backend);
+
return desktop;
}