swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

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:
Mlibswc/compositor.c | 9++++++---
Mlibswc/compositor.h | 2++
Mlibswc/input_focus.c | 84+++++++++++++++++++++++++++++++++++++------------------------------------------
Mlibswc/input_focus.h | 12++++++------
Mlibswc/keyboard.c | 13+++++++------
Mlibswc/keyboard.h | 2+-
Mlibswc/panel.c | 2+-
Mlibswc/pointer.c | 21+++++++++++----------
Mlibswc/pointer.h | 2+-
Mlibswc/seat.c | 5+++--
Mlibswc/surface.c | 1-
Mlibswc/surface.h | 1-
Mlibswc/window.c | 9++++-----
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); }