commit 8187fc81d9efc0c1062a07d8554ac517468e9cd3
parent 8a03536703bb4c1c7373258b46f6b6e2f087380d
Author: Michael Forney <mforney@mforney.org>
Date: Mon, 24 Feb 2014 14:27:51 -0800
input_focus: Keep track of view instead of surface
If we ever want to have a surface visible in multiple views, it is the
focused view that matters, not the surface (so we can correctly
calculate coordinates for wl_pointer motion events).
Diffstat:
13 files changed, 81 insertions(+), 82 deletions(-)
diff --git a/libswc/compositor.c b/libswc/compositor.c
@@ -486,6 +486,7 @@ struct compositor_view * swc_compositor_create_view
view_initialize(&view->base, &view_impl);
view->surface = surface;
view->buffer = NULL;
+ view->window = NULL;
view->parent = NULL;
view->visible = false;
view->extents.x1 = 0;
@@ -497,6 +498,7 @@ struct compositor_view * swc_compositor_create_view
view->border.damaged = false;
pixman_region32_init(&view->clip);
wl_list_init(&view->children);
+ wl_signal_init(&view->destroy_signal);
swc_surface_set_view(surface, &view->base);
return view;
@@ -504,6 +506,7 @@ struct compositor_view * swc_compositor_create_view
void compositor_view_destroy(struct compositor_view * view)
{
+ wl_signal_emit(&view->destroy_signal, NULL);
compositor_view_hide(view);
swc_surface_set_view(view->surface, NULL);
view_finalize(&view->base);
@@ -732,7 +735,7 @@ bool handle_motion(struct pointer_handler * handler, uint32_t time,
wl_fixed_t fx, wl_fixed_t fy)
{
struct compositor_view * view;
- struct swc_surface * surface = NULL;
+ bool found = false;
int32_t x, y;
wl_list_for_each(view, &compositor.views, link)
@@ -745,12 +748,12 @@ bool handle_motion(struct pointer_handler * handler, uint32_t time,
x - view->base.geometry.x,
y - view->base.geometry.y, NULL))
{
- surface = view->surface;
+ found = true;
break;
}
}
- pointer_set_focus(swc.seat->pointer, surface);
+ pointer_set_focus(swc.seat->pointer, found ? view : NULL);
return false;
}
diff --git a/libswc/compositor.h b/libswc/compositor.h
@@ -42,6 +42,7 @@ struct compositor_view
struct view base;
struct swc_surface * surface;
struct wld_buffer * buffer;
+ struct window * window;
struct compositor_view * parent;
/* Whether or not the view is visible (mapped). */
@@ -62,6 +63,7 @@ struct compositor_view
} border;
struct wl_list link, children, child_link;
+ struct wl_signal destroy_signal;
};
struct compositor_view * swc_compositor_create_view
diff --git a/libswc/input_focus.c b/libswc/input_focus.c
@@ -22,56 +22,62 @@
*/
#include "input_focus.h"
+#include "compositor.h"
#include "event.h"
#include "surface.h"
#include "util.h"
static inline void focus(struct input_focus * input_focus,
- struct swc_surface * surface,
- struct wl_resource * resource)
+ struct compositor_view * view)
{
- if (surface)
+ struct wl_resource * resource = NULL;
+
+ if (view)
{
- wl_resource_add_destroy_listener
- (surface->resource, &input_focus->surface_destroy_listener);
- }
+ struct wl_client * client;
+
+ client = wl_resource_get_client(view->surface->resource);
+ resource = wl_resource_find_for_client(&input_focus->resources, client);
- if (resource)
- input_focus->handler->enter(input_focus->handler, resource, surface);
+ wl_signal_add(&view->destroy_signal,
+ &input_focus->view_destroy_listener);
- input_focus->surface = surface;
+ if (resource)
+ input_focus->handler->enter(input_focus->handler, resource, view);
+ }
+
+ input_focus->view = view;
input_focus->resource = resource;
}
static inline void unfocus(struct input_focus * input_focus)
{
- if (input_focus->surface)
- wl_list_remove(&input_focus->surface_destroy_listener.link);
+ if (input_focus->view)
+ wl_list_remove(&input_focus->view_destroy_listener.link);
if (input_focus->resource)
{
input_focus->handler->leave(input_focus->handler, input_focus->resource,
- input_focus->surface);
+ input_focus->view);
}
}
-static void handle_focus_surface_destroy(struct wl_listener * listener,
- void * data)
+static void handle_focus_view_destroy(struct wl_listener * listener,
+ void * data)
{
- struct input_focus * input_focus = CONTAINER_OF
- (listener, typeof(*input_focus), surface_destroy_listener);
+ struct input_focus * input_focus
+ = CONTAINER_OF(listener, typeof(*input_focus), view_destroy_listener);
- input_focus->surface = NULL;
input_focus->resource = NULL;
+ input_focus->view = NULL;
}
bool input_focus_initialize(struct input_focus * input_focus,
struct input_focus_handler * handler)
{
input_focus->resource = NULL;
- input_focus->surface = NULL;
- input_focus->surface_destroy_listener.notify
- = &handle_focus_surface_destroy;
+ input_focus->view = NULL;
+ input_focus->view_destroy_listener.notify = &handle_focus_view_destroy;
input_focus->handler = handler;
wl_list_init(&input_focus->resources);
@@ -90,17 +96,19 @@ void input_focus_add_resource(struct input_focus * input_focus,
{
/* If this new input resource corresponds to our focus, set it as our
* focus. */
- if (input_focus->surface)
+ if (input_focus->view)
{
struct wl_client * client, * surface_client;
client = wl_resource_get_client(resource);
- surface_client = wl_resource_get_client(input_focus->surface->resource);
+ surface_client = wl_resource_get_client
+ (input_focus->view->surface->resource);
if (client == surface_client)
{
- unfocus(input_focus);
- focus(input_focus, input_focus->surface, resource);
+ input_focus->handler->enter(input_focus->handler, resource,
+ input_focus->view);
+ input_focus->resource = resource;
}
}
@@ -117,35 +125,21 @@ void input_focus_remove_resource(struct input_focus * input_focus,
}
void input_focus_set(struct input_focus * input_focus,
- struct swc_surface * surface)
+ struct compositor_view * view)
{
- struct wl_client * client;
- struct wl_resource * resource;
struct input_focus_event_data data;
- if (surface == input_focus->surface)
+ if (view == input_focus->view)
return;
- data.old = input_focus->surface;
+ data.old = input_focus->view;
+ data.new = view;
- /* Unfocus previously focused surface. */
+ /* Unfocus previously focused view. */
unfocus(input_focus);
- /* Focus new surface, if given. */
- if (surface)
- {
- client = wl_resource_get_client(surface->resource);
- resource = wl_resource_find_for_client(&input_focus->resources, client);
-
- focus(input_focus, surface, resource);
- }
- else
- {
- input_focus->surface = NULL;
- input_focus->resource = NULL;
- }
-
- data.new = input_focus->surface;
+ /* Focus new view, if given. */
+ focus(input_focus, view);
swc_send_event(&input_focus->event_signal, INPUT_FOCUS_EVENT_CHANGED,
&data);
diff --git a/libswc/input_focus.h b/libswc/input_focus.h
@@ -34,24 +34,24 @@ enum
struct input_focus_event_data
{
- struct swc_surface * old, * new;
+ struct compositor_view * old, * new;
};
struct input_focus_handler
{
void (* enter)(struct input_focus_handler * handler,
struct wl_resource * resource,
- struct swc_surface * surface);
+ struct compositor_view * view);
void (* leave)(struct input_focus_handler * handler,
struct wl_resource * resource,
- struct swc_surface * surface);
+ struct compositor_view * view);
};
struct input_focus
{
struct wl_resource * resource;
- struct swc_surface * surface;
- struct wl_listener surface_destroy_listener;
+ struct compositor_view * view;
+ struct wl_listener view_destroy_listener;
struct input_focus_handler * handler;
struct wl_list resources;
@@ -71,7 +71,7 @@ void input_focus_remove_resource(struct input_focus * input_focus,
struct wl_resource * resource);
void input_focus_set(struct input_focus * input_focus,
- struct swc_surface * surface);
+ struct compositor_view * view);
#endif
diff --git a/libswc/keyboard.c b/libswc/keyboard.c
@@ -26,6 +26,7 @@
*/
#include "swc.h"
+#include "compositor.h"
#include "keyboard.h"
#include "util.h"
@@ -33,7 +34,7 @@
#include <string.h>
static void enter(struct input_focus_handler * handler,
- struct wl_resource * resource, struct swc_surface * surface)
+ struct wl_resource * resource, struct compositor_view * view)
{
struct keyboard * keyboard;
struct wl_client * client;
@@ -45,12 +46,12 @@ static void enter(struct input_focus_handler * handler,
display = wl_client_get_display(client);
serial = wl_display_next_serial(display);
- wl_keyboard_send_enter(resource, serial, surface->resource,
+ wl_keyboard_send_enter(resource, serial, view->surface->resource,
&keyboard->client_handler.keys);
}
static void leave(struct input_focus_handler * handler,
- struct wl_resource * resource, struct swc_surface * surface)
+ struct wl_resource * resource, struct compositor_view * view)
{
struct wl_client * client;
struct wl_display * display;
@@ -60,7 +61,7 @@ static void leave(struct input_focus_handler * handler,
display = wl_client_get_display(client);
serial = wl_display_next_serial(display);
- wl_keyboard_send_leave(resource, serial, surface->resource);
+ wl_keyboard_send_leave(resource, serial, view->surface->resource);
}
static bool client_handle_key(struct keyboard * keyboard, uint32_t time,
@@ -141,9 +142,9 @@ void keyboard_finalize(struct keyboard * keyboard)
* Sets the focus of the keyboard to the specified surface.
*/
void keyboard_set_focus(struct keyboard * keyboard,
- struct swc_surface * surface)
+ struct compositor_view * view)
{
- input_focus_set(&keyboard->focus, surface);
+ input_focus_set(&keyboard->focus, view);
}
static void unbind(struct wl_resource * resource)
diff --git a/libswc/keyboard.h b/libswc/keyboard.h
@@ -68,7 +68,7 @@ struct keyboard
bool keyboard_initialize(struct keyboard * keyboard);
void keyboard_finalize(struct keyboard * keyboard);
void keyboard_set_focus(struct keyboard * keyboard,
- struct swc_surface * surface);
+ struct compositor_view * view);
struct wl_resource * keyboard_bind(struct keyboard * keyboard,
struct wl_client * client, uint32_t id);
void keyboard_handle_key(struct keyboard * keyboard, uint32_t time,
diff --git a/libswc/panel.c b/libswc/panel.c
@@ -132,7 +132,7 @@ static void dock(struct wl_client * client, struct wl_resource * resource,
wl_list_insert(&screen->modifiers, &panel->modifier.link);
if (focus)
- keyboard_set_focus(swc.seat->keyboard, panel->surface);
+ keyboard_set_focus(swc.seat->keyboard, panel->view);
swc_panel_send_docked(resource, length);
}
diff --git a/libswc/pointer.c b/libswc/pointer.c
@@ -22,6 +22,7 @@
*/
#include "pointer.h"
+#include "compositor.h"
#include "event.h"
#include "internal.h"
#include "screen.h"
@@ -34,7 +35,7 @@
#include <wld/wld.h>
static void enter(struct input_focus_handler * handler,
- struct wl_resource * resource, struct swc_surface * surface)
+ struct wl_resource * resource, struct compositor_view * view)
{
struct pointer * pointer;
struct wl_client * client;
@@ -47,15 +48,15 @@ static void enter(struct input_focus_handler * handler,
display = wl_client_get_display(client);
serial = wl_display_next_serial(display);
- surface_x = pointer->x - wl_fixed_from_int(surface->view->geometry.x);
- surface_y = pointer->y - wl_fixed_from_int(surface->view->geometry.y);
+ surface_x = pointer->x - wl_fixed_from_int(view->base.geometry.x);
+ surface_y = pointer->y - wl_fixed_from_int(view->base.geometry.y);
- wl_pointer_send_enter(resource, serial, surface->resource,
+ wl_pointer_send_enter(resource, serial, view->surface->resource,
surface_x, surface_y);
}
static void leave(struct input_focus_handler * handler,
- struct wl_resource * resource, struct swc_surface * surface)
+ struct wl_resource * resource, struct compositor_view * view)
{
struct wl_client * client;
struct wl_display * display;
@@ -65,7 +66,7 @@ static void leave(struct input_focus_handler * handler,
display = wl_client_get_display(client);
serial = wl_display_next_serial(display);
- wl_pointer_send_leave(resource, serial, surface->resource);
+ wl_pointer_send_leave(resource, serial, view->surface->resource);
}
static void handle_cursor_surface_destroy(struct wl_listener * listener,
@@ -203,8 +204,8 @@ static bool client_handle_motion(struct pointer_handler * handler,
wl_pointer_send_motion
(pointer->focus.resource, time,
- x - wl_fixed_from_int(pointer->focus.surface->view->geometry.x),
- y - wl_fixed_from_int(pointer->focus.surface->view->geometry.y));
+ x - wl_fixed_from_int(pointer->focus.view->base.geometry.x),
+ y - wl_fixed_from_int(pointer->focus.view->base.geometry.y));
return true;
}
@@ -256,9 +257,9 @@ void pointer_finalize(struct pointer * pointer)
pixman_region32_fini(&pointer->region);
}
-void pointer_set_focus(struct pointer * pointer, struct swc_surface * surface)
+void pointer_set_focus(struct pointer * pointer, struct compositor_view * view)
{
- input_focus_set(&pointer->focus, surface);
+ input_focus_set(&pointer->focus, view);
}
static void clip_position(struct pointer * pointer,
diff --git a/libswc/pointer.h b/libswc/pointer.h
@@ -81,7 +81,7 @@ struct pointer
bool pointer_initialize(struct pointer * pointer);
void pointer_finalize(struct pointer * pointer);
-void pointer_set_focus(struct pointer * pointer, struct swc_surface * surface);
+void pointer_set_focus(struct pointer * pointer, struct compositor_view * view);
void pointer_set_region(struct pointer * pointer, pixman_region32_t * region);
void pointer_set_cursor(struct pointer * pointer, uint32_t id);
diff --git a/libswc/seat.c b/libswc/seat.c
@@ -22,6 +22,7 @@
*/
#include "seat.h"
+#include "compositor.h"
#include "data_device.h"
#include "evdev_device.h"
#include "event.h"
@@ -103,8 +104,8 @@ static void handle_keyboard_focus_event(struct wl_listener * listener,
case INPUT_FOCUS_EVENT_CHANGED:
if (event_data->new)
{
- struct wl_client * client
- = wl_resource_get_client(event_data->new->resource);
+ struct wl_client * client = wl_resource_get_client
+ (event_data->new->surface->resource);
/* Offer the selection to the new focus. */
swc_data_device_offer_selection(&seat.data_device, client);
diff --git a/libswc/surface.c b/libswc/surface.c
@@ -373,7 +373,6 @@ struct swc_surface * swc_surface_new(struct wl_client * client,
/* Initialize the surface. */
surface->pending.commit = 0;
- surface->window = NULL;
surface->view = NULL;
surface->view_listener.notify = &handle_view_event;
diff --git a/libswc/surface.h b/libswc/surface.h
@@ -68,7 +68,6 @@ struct swc_surface
int32_t x, y;
} pending;
- struct window * window;
struct view * view;
struct wl_listener view_listener;
};
diff --git a/libswc/window.c b/libswc/window.c
@@ -71,8 +71,8 @@ EXPORT
void swc_window_focus(struct swc_window * base)
{
struct window * window = INTERNAL(base);
- struct swc_surface * new_focus = window ? window->surface : NULL,
- * old_focus = swc.seat->keyboard->focus.surface;
+ struct compositor_view * new_focus = window ? window->view : NULL,
+ * old_focus = swc.seat->keyboard->focus.view;
/* If the keyboard already has a focused window, and we are changing the
* focus to either NULL, or a window with a different implementation, set
@@ -239,6 +239,7 @@ bool window_initialize(struct window * window, const struct window_impl * impl,
window->surface = surface;
window->impl = impl;
+ window->view->window = window;
window->move.interaction.handler = (struct pointer_handler) {
.motion = &move_motion,
.button = &handle_button
@@ -248,8 +249,6 @@ bool window_initialize(struct window * window, const struct window_impl * impl,
.button = &handle_button
};
- surface->window = window;
-
swc.manager->new_window(&window->base);
return true;
@@ -261,7 +260,7 @@ void window_finalize(struct window * window)
swc_send_event(&window->base.event_signal, SWC_WINDOW_DESTROYED, NULL);
compositor_view_destroy(window->view);
- window->surface->window = NULL;
+ window->view->window = NULL;
free(window->base.title);
free(window->base.class);
}