summaryrefslogtreecommitdiff
path: root/libdecor/src
diff options
context:
space:
mode:
Diffstat (limited to 'libdecor/src')
-rw-r--r--libdecor/src/libdecor-plugin.h3
-rw-r--r--libdecor/src/libdecor.c29
-rw-r--r--libdecor/src/libdecor.h18
-rw-r--r--libdecor/src/plugins/cairo/libdecor-cairo.c64
-rw-r--r--libdecor/src/plugins/dummy/libdecor-dummy.c8
-rw-r--r--libdecor/src/plugins/gtk/libdecor-gtk.c40
6 files changed, 136 insertions, 26 deletions
diff --git a/libdecor/src/libdecor-plugin.h b/libdecor/src/libdecor-plugin.h
index ba80ce642..d57430e9c 100644
--- a/libdecor/src/libdecor-plugin.h
+++ b/libdecor/src/libdecor-plugin.h
@@ -92,6 +92,9 @@ struct libdecor_plugin_interface {
int (* dispatch)(struct libdecor_plugin *plugin,
int timeout);
+ void (* set_handle_application_cursor)(struct libdecor_plugin *plugin,
+ bool handle_cursor);
+
struct libdecor_frame * (* frame_new)(struct libdecor_plugin *plugin);
void (* frame_free)(struct libdecor_plugin *plugin,
struct libdecor_frame *frame);
diff --git a/libdecor/src/libdecor.c b/libdecor/src/libdecor.c
index 92d4f46e5..8cef57221 100644
--- a/libdecor/src/libdecor.c
+++ b/libdecor/src/libdecor.c
@@ -451,11 +451,28 @@ xdg_toplevel_close(void *user_data,
#ifdef HAVE_XDG_SHELL_V6
static void
-xdg_toplevel_configure_bounds(void *data,
+xdg_toplevel_configure_bounds(void *user_data,
struct xdg_toplevel *xdg_toplevel,
int32_t width,
int32_t height)
{
+ struct libdecor_frame *frame = user_data;
+ struct libdecor_frame_private *frame_priv = frame->priv;
+ struct libdecor *context = frame_priv->context;
+ struct libdecor_plugin *plugin = context->plugin;
+ int left = 0, top = 0, right = 0, bottom = 0;
+
+ if (frame_has_visible_client_side_decoration(frame) &&
+ plugin->priv->iface->frame_get_border_size) {
+ plugin->priv->iface->frame_get_border_size(plugin, frame, NULL,
+ &left, &right, &top, &bottom);
+ }
+
+ width -= left + right;
+ height -= top + bottom;
+ if (frame_priv->iface->bounds) {
+ frame_priv->iface->bounds(frame, width, height, frame_priv->user_data);
+ }
}
static void
@@ -1261,6 +1278,16 @@ libdecor_frame_get_xdg_toplevel(struct libdecor_frame *frame)
return frame->priv->xdg_toplevel;
}
+LIBDECOR_EXPORT void
+libdecor_set_handle_application_cursor(struct libdecor *context,
+ bool handle_cursor)
+{
+ struct libdecor_plugin *plugin = context->plugin;
+
+ plugin->priv->iface->set_handle_application_cursor(plugin,
+ handle_cursor);
+}
+
LIBDECOR_EXPORT int
libdecor_frame_get_content_width(struct libdecor_frame *frame)
{
diff --git a/libdecor/src/libdecor.h b/libdecor/src/libdecor.h
index e52ced0cd..2158829fd 100644
--- a/libdecor/src/libdecor.h
+++ b/libdecor/src/libdecor.h
@@ -168,6 +168,15 @@ struct libdecor_frame_interface {
const char *seat_name,
void *user_data);
+ /**
+ * The recommended client region bounds for the window.
+ * This will be followed by a configure event.
+ */
+ void (* bounds)(struct libdecor_frame *frame,
+ int width,
+ int height,
+ void *user_data);
+
/* Reserved */
void (* reserved0)(void);
void (* reserved1)(void);
@@ -178,7 +187,6 @@ struct libdecor_frame_interface {
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
- void (* reserved9)(void);
};
/**
@@ -544,6 +552,14 @@ enum libdecor_wm_capabilities
libdecor_frame_get_wm_capabilities(struct libdecor_frame *frame);
/**
+ * Tell libdecor to set the default pointer cursor when the pointer is over an
+ * application surface. The default false.
+ */
+void
+libdecor_set_handle_application_cursor(struct libdecor *context,
+ bool handle_cursor);
+
+/**
* Create a new content surface state.
*/
struct libdecor_state *
diff --git a/libdecor/src/plugins/cairo/libdecor-cairo.c b/libdecor/src/plugins/cairo/libdecor-cairo.c
index 5978d431d..d8854bc8e 100644
--- a/libdecor/src/plugins/cairo/libdecor-cairo.c
+++ b/libdecor/src/plugins/cairo/libdecor-cairo.c
@@ -149,6 +149,7 @@ struct seat {
struct wl_cursor *cursor_left_ptr;
struct wl_surface *pointer_focus;
+ struct libdecor_frame_cairo *pointer_focus_frame;
int pointer_x, pointer_y;
@@ -279,6 +280,8 @@ struct libdecor_plugin_cairo {
int cursor_size;
PangoFontDescription *font;
+
+ bool handle_cursor;
};
static const char *libdecor_cairo_proxy_tag = "libdecor-cairo";
@@ -538,6 +541,16 @@ libdecor_plugin_cairo_dispatch(struct libdecor_plugin *plugin,
}
}
+static void
+libdecor_plugin_cairo_set_handle_application_cursor(struct libdecor_plugin *plugin,
+ bool handle_cursor)
+{
+ struct libdecor_plugin_cairo *plugin_cairo =
+ (struct libdecor_plugin_cairo *) plugin;
+
+ plugin_cairo->handle_cursor = handle_cursor;
+}
+
static struct libdecor_frame *
libdecor_plugin_cairo_frame_new(struct libdecor_plugin *plugin)
{
@@ -685,9 +698,12 @@ libdecor_plugin_cairo_frame_free(struct libdecor_plugin *plugin,
struct seat *seat;
wl_list_for_each(seat, &plugin_cairo->seat_list, link) {
- if (seat->pointer_focus != NULL &&
- wl_surface_get_user_data(seat->pointer_focus) == frame_cairo)
- seat->pointer_focus = NULL;
+ if (seat->pointer_focus) {
+ if (wl_surface_get_user_data(seat->pointer_focus) == frame_cairo)
+ seat->pointer_focus = NULL;
+ if (seat->pointer_focus_frame == frame_cairo)
+ seat->pointer_focus_frame = NULL;
+ }
}
free_border_component(&frame_cairo->title_bar.title);
@@ -812,6 +828,10 @@ update_component_focus(struct libdecor_frame_cairo *frame_cairo,
static struct border_component *focus_component;
border_component = get_component_for_surface(frame_cairo, surface);
+ if (!border_component) {
+ focus_component = NULL;
+ goto out;
+ }
focus_component = border_component;
wl_list_for_each(child_component, &border_component->child_components, link) {
@@ -830,6 +850,7 @@ update_component_focus(struct libdecor_frame_cairo *frame_cairo,
}
}
+out:
if (frame_cairo->grab)
frame_cairo->active = frame_cairo->grab;
else
@@ -1882,6 +1903,8 @@ static struct libdecor_plugin_interface cairo_plugin_iface = {
.get_fd = libdecor_plugin_cairo_get_fd,
.dispatch = libdecor_plugin_cairo_dispatch,
+ .set_handle_application_cursor = libdecor_plugin_cairo_set_handle_application_cursor,
+
.frame_new = libdecor_plugin_cairo_frame_new,
.frame_free = libdecor_plugin_cairo_frame_free,
.frame_commit = libdecor_plugin_cairo_frame_commit,
@@ -2109,8 +2132,14 @@ update_local_cursor(struct seat *seat)
return false;
}
- if (!own_surface(seat->pointer_focus))
- return false;
+ if (!own_surface(seat->pointer_focus)) {
+ if (seat->plugin_cairo->handle_cursor) {
+ seat->current_cursor = seat->cursor_left_ptr;
+ return true;
+ } else {
+ return false;
+ }
+ }
struct libdecor_frame_cairo *frame_cairo =
wl_surface_get_user_data(seat->pointer_focus);
@@ -2195,7 +2224,7 @@ synthesize_pointer_enter(struct seat *seat)
struct libdecor_frame_cairo *frame_cairo;
surface = seat->pointer_focus;
- if (!surface)
+ if (!surface || !own_surface(surface))
return;
frame_cairo = wl_surface_get_user_data(surface);
@@ -2222,7 +2251,7 @@ synthesize_pointer_leave(struct seat *seat)
struct libdecor_frame_cairo *frame_cairo;
surface = seat->pointer_focus;
- if (!surface)
+ if (!surface || !own_surface(surface))
return;
frame_cairo = wl_surface_get_user_data(surface);
@@ -2247,12 +2276,20 @@ pointer_enter(void *data,
wl_fixed_t surface_y)
{
struct seat *seat = data;
+ struct libdecor_frame_cairo *frame_cairo = NULL;
if (!surface)
return;
- if (!own_surface(surface))
- return;
+ if (!own_surface(surface)) {
+ struct seat *seat = wl_pointer_get_user_data(wl_pointer);
+ struct libdecor_plugin_cairo *plugin_cairo = seat->plugin_cairo;
+
+ if (!plugin_cairo->handle_cursor)
+ return;
+ } else {
+ frame_cairo = wl_surface_get_user_data(surface);
+ }
ensure_cursor_surface(seat);
@@ -2260,6 +2297,7 @@ pointer_enter(void *data,
seat->pointer_y = wl_fixed_to_int(surface_y);
seat->serial = serial;
seat->pointer_focus = surface;
+ seat->pointer_focus_frame = frame_cairo;
if (seat->grabbed)
return;
@@ -2283,6 +2321,7 @@ pointer_leave(void *data,
synthesize_pointer_leave(seat);
seat->pointer_focus = NULL;
+ seat->pointer_focus_frame = NULL;
}
static void
@@ -2293,7 +2332,6 @@ pointer_motion(void *data,
wl_fixed_t surface_y)
{
struct seat *seat = data;
- struct libdecor_frame_cairo *frame_cairo;
seat->pointer_x = wl_fixed_to_int(surface_x);
seat->pointer_y = wl_fixed_to_int(surface_y);
@@ -2301,12 +2339,10 @@ pointer_motion(void *data,
if (seat->grabbed)
return;
- if (!seat->pointer_focus)
+ if (!seat->pointer_focus_frame)
return;
- frame_cairo = wl_surface_get_user_data(seat->pointer_focus);
-
- sync_active_component(frame_cairo, seat);
+ sync_active_component(seat->pointer_focus_frame, seat);
}
static void
diff --git a/libdecor/src/plugins/dummy/libdecor-dummy.c b/libdecor/src/plugins/dummy/libdecor-dummy.c
index 7dc2428ca..621dd027f 100644
--- a/libdecor/src/plugins/dummy/libdecor-dummy.c
+++ b/libdecor/src/plugins/dummy/libdecor-dummy.c
@@ -61,6 +61,12 @@ libdecor_plugin_dummy_frame_new(struct libdecor_plugin *plugin)
}
static void
+libdecor_plugin_dummy_set_handle_application_cursor(struct libdecor_plugin *plugin,
+ bool handle_cursor)
+{
+}
+
+static void
libdecor_plugin_dummy_frame_free(struct libdecor_plugin *plugin,
struct libdecor_frame *frame)
{
@@ -97,6 +103,8 @@ libdecor_plugin_dummy_frame_popup_ungrab(struct libdecor_plugin *plugin,
static struct libdecor_plugin_interface dummy_plugin_iface = {
.destroy = libdecor_plugin_dummy_destroy,
+ .set_handle_application_cursor = libdecor_plugin_dummy_set_handle_application_cursor,
+
.frame_new = libdecor_plugin_dummy_frame_new,
.frame_free = libdecor_plugin_dummy_frame_free,
.frame_commit = libdecor_plugin_dummy_frame_commit,
diff --git a/libdecor/src/plugins/gtk/libdecor-gtk.c b/libdecor/src/plugins/gtk/libdecor-gtk.c
index 5f010958a..3f2a54473 100644
--- a/libdecor/src/plugins/gtk/libdecor-gtk.c
+++ b/libdecor/src/plugins/gtk/libdecor-gtk.c
@@ -342,6 +342,8 @@ struct libdecor_plugin_gtk {
int double_click_time_ms;
int drag_threshold;
+
+ bool handle_cursor;
};
static const char *libdecor_gtk_proxy_tag = "libdecor-gtk";
@@ -555,6 +557,16 @@ libdecor_plugin_gtk_dispatch(struct libdecor_plugin *plugin,
}
}
+static void
+libdecor_plugin_gtk_set_handle_application_cursor(struct libdecor_plugin *plugin,
+ bool handle_cursor)
+{
+ struct libdecor_plugin_gtk *plugin_gtk =
+ (struct libdecor_plugin_gtk *) plugin;
+
+ plugin_gtk->handle_cursor = handle_cursor;
+}
+
static struct libdecor_frame *
libdecor_plugin_gtk_frame_new(struct libdecor_plugin *plugin)
{
@@ -1644,7 +1656,7 @@ synthesize_pointer_enter(struct seat *seat)
struct libdecor_frame_gtk *frame_gtk;
surface = seat->pointer_focus;
- if (!surface)
+ if (!surface || !own_surface(surface))
return;
frame_gtk = wl_surface_get_user_data(surface);
@@ -1671,7 +1683,7 @@ synthesize_pointer_leave(struct seat *seat)
struct libdecor_frame_gtk *frame_gtk;
surface = seat->pointer_focus;
- if (!surface)
+ if (!surface || !own_surface(surface))
return;
frame_gtk = wl_surface_get_user_data(surface);
@@ -1788,6 +1800,8 @@ static struct libdecor_plugin_interface gtk_plugin_iface = {
.get_fd = libdecor_plugin_gtk_get_fd,
.dispatch = libdecor_plugin_gtk_dispatch,
+ .set_handle_application_cursor = libdecor_plugin_gtk_set_handle_application_cursor,
+
.frame_new = libdecor_plugin_gtk_frame_new,
.frame_free = libdecor_plugin_gtk_frame_free,
.frame_commit = libdecor_plugin_gtk_frame_commit,
@@ -2089,12 +2103,17 @@ pointer_enter(void *data,
return;
struct seat *seat = data;
- struct libdecor_frame_gtk *frame_gtk;
+ struct libdecor_frame_gtk *frame_gtk = NULL;
- if (!own_surface(surface))
- return;
+ if (!own_surface(surface)) {
+ struct seat *seat = wl_pointer_get_user_data(wl_pointer);
+ struct libdecor_plugin_gtk *plugin_gtk = seat->plugin_gtk;
- frame_gtk = wl_surface_get_user_data(surface);
+ if (!plugin_gtk->handle_cursor)
+ return;
+ } else {
+ frame_gtk = wl_surface_get_user_data(surface);
+ }
ensure_cursor_surface(seat);
@@ -2124,18 +2143,19 @@ pointer_leave(void *data,
uint32_t serial,
struct wl_surface *surface)
{
- if (!surface)
- return;
-
struct seat *seat = data;
struct libdecor_frame_gtk *frame_gtk;
+ seat->pointer_focus = NULL;
+
+ if (!surface)
+ return;
+
if (!own_surface(surface))
return;
frame_gtk = wl_surface_get_user_data(surface);
- seat->pointer_focus = NULL;
if (frame_gtk) {
frame_gtk->titlebar_gesture.state =
TITLEBAR_GESTURE_STATE_INIT;