summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2013-03-07 14:06:11 -0500
committerKristian Høgsberg <krh@bitplanet.net>2013-03-07 14:06:11 -0500
commitef6e0159df6d1baa238ac16a948839a71294e570 (patch)
treef27501a7b4313b412b1ed58b9786f8a9f48e3cdc
parent334e37d75b62320da1b6805bbe61ad05bccbb652 (diff)
Restore previous keyboard focus on close
-rw-r--r--overlay-plugin.c82
1 files changed, 60 insertions, 22 deletions
diff --git a/overlay-plugin.c b/overlay-plugin.c
index 4ecc5b4..8b8353c 100644
--- a/overlay-plugin.c
+++ b/overlay-plugin.c
@@ -43,6 +43,9 @@ struct overlay {
struct wl_seat *seat;
struct wl_pointer_grab grab;
struct weston_output *output;
+
+ struct wl_surface *saved_focus;
+ struct wl_listener saved_focus_destroy_listener;
};
static void
@@ -53,6 +56,12 @@ handle_surface_destroy(struct wl_listener *listener, void *data)
surface_destroy_listener);
overlay->surface = NULL;
+
+ if (overlay->saved_focus) {
+ weston_surface_activate((struct weston_surface *) overlay->saved_focus,
+ (struct weston_seat *) overlay->seat);
+ wl_list_remove(&overlay->saved_focus_destroy_listener.link);
+ }
}
static void
@@ -60,6 +69,7 @@ overlay_close(struct overlay *overlay)
{
overlay_send_done(overlay->resource);
wl_pointer_end_grab(overlay->grab.pointer);
+
}
static void
@@ -137,36 +147,64 @@ get_output_for_pointer(struct overlay *overlay)
}
static void
-overlay_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
+handle_saved_focus_destroy(struct wl_listener *listener, void *data)
{
- struct overlay *overlay = surface->private;
- struct weston_output *output;
- int width, height;
-
- if (wl_list_empty(&surface->layer_link)) {
- wl_list_insert(&overlay->layer.surface_list,
- &surface->layer_link);
+ struct overlay *overlay =container_of(listener, struct overlay,
+ saved_focus_destroy_listener);
- wl_keyboard_set_focus(overlay->seat->keyboard,
- &surface->surface);
-
- overlay->grab.interface = &overlay_grab_interface;
- wl_pointer_start_grab(overlay->seat->pointer, &overlay->grab);
- overlay->output = get_output_for_pointer(overlay);
- }
+ overlay->saved_focus = NULL;
+}
- output = overlay->output;
- width = surface->buffer_ref.buffer->width;
- height = surface->buffer_ref.buffer->height;
+static void
+center_on_output(struct overlay *overlay, int32_t width, int32_t height)
+{
+ struct weston_surface *surface = overlay->surface;
+ struct weston_output *output = overlay->output;
surface->geometry.x = output->x + (output->width - width) / 2;
surface->geometry.y = output->y + (output->height - height) / 2;
- surface->geometry.width = surface->buffer_ref.buffer->width;
- surface->geometry.height = surface->buffer_ref.buffer->height;
+ surface->geometry.width = width;
+ surface->geometry.height = height;
surface->geometry.dirty = 1;
+}
+
+static void
+overlay_map(struct overlay *overlay, int32_t width, int32_t height)
+{
+ struct weston_surface *surface = overlay->surface;
+
+ wl_list_insert(&overlay->layer.surface_list, &surface->layer_link);
+
+ overlay->saved_focus = overlay->seat->keyboard->focus;
+ if (overlay->saved_focus) {
+ overlay->saved_focus_destroy_listener.notify =
+ handle_saved_focus_destroy;
+ wl_signal_add(&overlay->saved_focus->resource.destroy_signal,
+ &overlay->saved_focus_destroy_listener);
+ }
+
+ weston_surface_activate(overlay->surface,
+ (struct weston_seat *) overlay->seat);
+ overlay->grab.interface = &overlay_grab_interface;
+ wl_pointer_start_grab(overlay->seat->pointer, &overlay->grab);
+
+ overlay->output = get_output_for_pointer(overlay);
+ center_on_output(overlay, width, height);
+ weston_surface_update_transform(surface);
+ weston_zoom_run(surface, 0.8, 1.0, NULL, NULL);
+}
+
+static void
+overlay_configure(struct weston_surface *surface,
+ int32_t sx, int32_t sy, int32_t width, int32_t height)
+{
+ struct overlay *overlay = surface->private;
+ struct weston_output *output;
- if (!weston_surface_is_mapped(surface))
- weston_surface_update_transform(surface);
+ if (wl_list_empty(&surface->layer_link))
+ overlay_map(overlay, width, height);
+ else
+ center_on_output(overlay, width, height);
}
static void