From 0704539ec4d81256b95b5b89129d8740f86cb8e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Sun, 19 Feb 2012 18:52:44 -0500 Subject: [PATCH] shell: Revive super-tab application switcher We can do this right, now that we have keyboard grabs. --- src/Makefile.am | 1 - src/compositor.h | 5 -- src/shell.c | 119 +++++++++++++++++++++++++++++++++++++++++- src/switcher.c | 131 ----------------------------------------------- 4 files changed, 118 insertions(+), 138 deletions(-) delete mode 100644 src/switcher.c diff --git a/src/Makefile.am b/src/Makefile.am index 2c91abca..5788df30 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,7 +88,6 @@ desktop_shell_la_LIBADD = $(COMPOSITOR_LIBS) \ desktop_shell_la_CFLAGS = $(GCC_CFLAGS) desktop_shell_la_SOURCES = \ shell.c \ - switcher.c \ desktop-shell-protocol.c \ desktop-shell-server-protocol.h endif diff --git a/src/compositor.h b/src/compositor.h index 7dda3113..4c82e79a 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -179,8 +179,6 @@ struct weston_compositor { struct timespec previous_swap; struct wl_array vertices, indices; - struct weston_surface *overlay; - struct weston_switcher *switcher; uint32_t focus; PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC @@ -430,9 +428,6 @@ weston_input_device_init(struct weston_input_device *device, void weston_input_device_release(struct weston_input_device *device); -void -weston_switcher_init(struct weston_compositor *compositor); - enum { TTY_ENTER_VT, TTY_LEAVE_VT diff --git a/src/shell.c b/src/shell.c index dad633f9..fa165e2c 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1,5 +1,5 @@ /* - * Copyright © 2010 Intel Corporation + * Copyright © 2010-2012 Intel Corporation * Copyright © 2011-2012 Collabora, Ltd. * * Permission to use, copy, modify, distribute, and sell this software and @@ -1653,6 +1653,120 @@ bind_screensaver(struct wl_client *client, wl_resource_destroy(resource, 0); } +struct switcher { + struct weston_compositor *compositor; + struct weston_surface *current; + struct wl_listener listener; + struct wl_keyboard_grab grab; +}; + +static void +switcher_next(struct switcher *switcher) +{ + struct weston_compositor *compositor = switcher->compositor; + struct weston_surface *surface; + struct weston_surface *first = NULL, *prev = NULL, *next = NULL; + + wl_list_for_each(surface, &compositor->surface_list, link) { + /* Workaround for cursor surfaces. */ + if (surface->surface.resource.destroy_listener_list.next == NULL) + continue; + + switch (get_shell_surface_type(surface)) { + case SHELL_SURFACE_TOPLEVEL: + case SHELL_SURFACE_FULLSCREEN: + case SHELL_SURFACE_MAXIMIZED: + if (first == NULL) + first = surface; + if (prev == switcher->current) + next = surface; + prev = surface; + surface->alpha = 64; + weston_surface_damage(surface); + break; + default: + break; + } + } + + if (next == NULL) + next = first; + + wl_list_remove(&switcher->listener.link); + wl_list_insert(next->surface.resource.destroy_listener_list.prev, + &switcher->listener.link); + + switcher->current = next; + next->alpha = 255; +} + +static void +switcher_handle_surface_destroy(struct wl_listener *listener, + struct wl_resource *resource, uint32_t time) +{ + struct switcher *switcher = + container_of(listener, struct switcher, listener); + + switcher_next(switcher); +} + +static void +switcher_destroy(struct switcher *switcher, uint32_t time) +{ + struct weston_compositor *compositor = switcher->compositor; + struct weston_surface *surface; + struct weston_input_device *device = + (struct weston_input_device *) switcher->grab.input_device; + + wl_list_for_each(surface, &compositor->surface_list, link) { + surface->alpha = 255; + weston_surface_damage(surface); + } + + activate(compositor->shell, switcher->current, device, time); + wl_list_remove(&switcher->listener.link); + wl_input_device_end_keyboard_grab(&device->input_device, time); + free(switcher); +} + +static void +switcher_key(struct wl_keyboard_grab *grab, + uint32_t time, uint32_t key, int32_t state) +{ + struct switcher *switcher = container_of(grab, struct switcher, grab); + struct weston_input_device *device = + (struct weston_input_device *) grab->input_device; + + if ((device->modifier_state & MODIFIER_SUPER) == 0) { + switcher_destroy(switcher, time); + } else if (key == KEY_TAB && state) { + switcher_next(switcher); + } +}; + +static const struct wl_keyboard_grab_interface switcher_grab = { + switcher_key +}; + +static void +switcher_binding(struct wl_input_device *device, uint32_t time, + uint32_t key, uint32_t button, + uint32_t state, void *data) +{ + struct weston_compositor *compositor = data; + struct switcher *switcher; + + switcher = malloc(sizeof *switcher); + switcher->compositor = compositor; + switcher->current = NULL; + switcher->listener.func = switcher_handle_surface_destroy; + wl_list_init(&switcher->listener.link); + + switcher->grab.interface = &switcher_grab; + wl_input_device_start_keyboard_grab(device, &switcher->grab, time); + switcher_next(switcher); +} + static void shell_destroy(struct weston_shell *base) { @@ -1722,6 +1836,9 @@ shell_init(struct weston_compositor *ec) MODIFIER_SUPER | MODIFIER_ALT, rotate_binding, NULL); + weston_compositor_add_binding(ec, KEY_TAB, 0, MODIFIER_SUPER, + switcher_binding, ec); + ec->shell = &shell->shell; return 0; diff --git a/src/switcher.c b/src/switcher.c deleted file mode 100644 index c4ed79d5..00000000 --- a/src/switcher.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include -#include -#include - -#include "compositor.h" - -struct weston_switcher { - struct weston_compositor *compositor; - struct weston_surface *current; - struct wl_listener listener; -}; - -static void -weston_switcher_next(struct weston_switcher *switcher) -{ - struct wl_list *l; - struct wl_surface *current; - - weston_surface_damage(switcher->current); - l = switcher->current->link.next; - if (l == &switcher->compositor->surface_list) - l = switcher->compositor->surface_list.next; - switcher->current = container_of(l, struct weston_surface, link); - wl_list_remove(&switcher->listener.link); - current = &switcher->current->surface; - wl_list_insert(current->resource.destroy_listener_list.prev, - &switcher->listener.link); - switcher->compositor->overlay = switcher->current; - weston_surface_damage(switcher->current); -} - -static void -switcher_handle_surface_destroy(struct wl_listener *listener, - struct wl_resource *resource, uint32_t time) -{ - struct weston_switcher *switcher = - container_of(listener, struct weston_switcher, listener); - - weston_switcher_next(switcher); -} - -static struct weston_switcher * -weston_switcher_create(struct weston_compositor *compositor) -{ - struct weston_switcher *switcher; - - switcher = malloc(sizeof *switcher); - switcher->compositor = compositor; - switcher->current = container_of(compositor->surface_list.next, - struct weston_surface, link); - switcher->listener.func = switcher_handle_surface_destroy; - wl_list_init(&switcher->listener.link); - - return switcher; -} - -static void -weston_switcher_destroy(struct weston_switcher *switcher) -{ - wl_list_remove(&switcher->listener.link); - free(switcher); -} - -static void -switcher_next_binding(struct wl_input_device *device, uint32_t time, - uint32_t key, uint32_t button, - uint32_t state, void *data) -{ - struct weston_compositor *compositor = data; - - if (!state) - return; - if (wl_list_empty(&compositor->surface_list)) - return; - if (compositor->switcher == NULL) - compositor->switcher = weston_switcher_create(compositor); - - weston_switcher_next(compositor->switcher); -} - -static void -switcher_terminate_binding(struct wl_input_device *device, - uint32_t time, uint32_t key, uint32_t button, - uint32_t state, void *data) -{ - struct weston_compositor *compositor = data; - struct weston_input_device *wd = (struct weston_input_device *) device; - - if (compositor->switcher && !state) { - weston_surface_activate(compositor->switcher->current, wd, time); - weston_switcher_destroy(compositor->switcher); - compositor->switcher = NULL; - compositor->overlay = NULL; - } -} - -void -weston_switcher_init(struct weston_compositor *compositor) -{ - weston_compositor_add_binding(compositor, - KEY_TAB, 0, MODIFIER_SUPER, - switcher_next_binding, compositor); - weston_compositor_add_binding(compositor, - KEY_LEFTMETA, 0, MODIFIER_SUPER, - switcher_terminate_binding, compositor); - weston_compositor_add_binding(compositor, - KEY_RIGHTMETA, 0, MODIFIER_SUPER, - switcher_terminate_binding, compositor); -}