diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2013-03-07 14:06:11 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-03-07 14:06:11 -0500 |
commit | ef6e0159df6d1baa238ac16a948839a71294e570 (patch) | |
tree | f27501a7b4313b412b1ed58b9786f8a9f48e3cdc | |
parent | 334e37d75b62320da1b6805bbe61ad05bccbb652 (diff) |
Restore previous keyboard focus on close
-rw-r--r-- | overlay-plugin.c | 82 |
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 |