From 3b6e68e2c1e3b80173f29b9930f966ce84fd5c77 Mon Sep 17 00:00:00 2001 From: Emilio Pozuelo Monfort Date: Mon, 10 Feb 2014 13:22:32 +0100 Subject: [PATCH] exposay: arrange views per-output https://bugs.freedesktop.org/show_bug.cgi?id=73173 --- desktop-shell/exposay.c | 108 +++++++++++++++++++++++----------------- desktop-shell/shell.c | 7 --- desktop-shell/shell.h | 74 ++++++++++++++++----------- 3 files changed, 107 insertions(+), 82 deletions(-) diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c index fe7a3a71..b7e32c9a 100644 --- a/desktop-shell/exposay.c +++ b/desktop-shell/exposay.c @@ -30,6 +30,7 @@ struct exposay_surface { struct desktop_shell *shell; + struct exposay_output *eoutput; struct weston_surface *surface; struct weston_view *view; struct wl_list link; @@ -140,6 +141,7 @@ exposay_highlight_surface(struct desktop_shell *shell, shell->exposay.row_current = esurface->row; shell->exposay.column_current = esurface->column; + shell->exposay.cur_output = esurface->eoutput; activate(shell, view->surface, shell->exposay.seat); shell->exposay.focus_current = view; @@ -178,32 +180,32 @@ exposay_pick(struct desktop_shell *shell, int x, int y) * aspect ratio into account really. Also needs to be notified of surface * addition and removal and adjust layout/animate accordingly. */ static enum exposay_layout_state -exposay_layout(struct desktop_shell *shell) +exposay_layout(struct desktop_shell *shell, struct shell_output *shell_output) { struct workspace *workspace = shell->exposay.workspace; - struct weston_compositor *compositor = shell->compositor; - struct weston_output *output = get_default_output(compositor); + struct weston_output *output = shell_output->output; + struct exposay_output *eoutput = &shell_output->eoutput; struct weston_view *view; struct exposay_surface *esurface, *highlight = NULL; int w, h; int i; int last_row_removed = 0; - wl_list_init(&shell->exposay.surface_list); - - shell->exposay.num_surfaces = 0; + eoutput->num_surfaces = 0; wl_list_for_each(view, &workspace->layer.view_list, layer_link) { if (!get_shell_surface(view->surface)) continue; - shell->exposay.num_surfaces++; + if (view->output != output) + continue; + eoutput->num_surfaces++; } - if (shell->exposay.num_surfaces == 0) { - shell->exposay.grid_size = 0; - shell->exposay.hpadding_outer = 0; - shell->exposay.vpadding_outer = 0; - shell->exposay.padding_inner = 0; - shell->exposay.surface_size = 0; + if (eoutput->num_surfaces == 0) { + eoutput->grid_size = 0; + eoutput->hpadding_outer = 0; + eoutput->vpadding_outer = 0; + eoutput->padding_inner = 0; + eoutput->surface_size = 0; return EXPOSAY_LAYOUT_OVERVIEW; } @@ -219,37 +221,39 @@ exposay_layout(struct desktop_shell *shell) * XXX: Surely there has to be a better way to express this maths, * right?! */ - shell->exposay.grid_size = floor(sqrtf(shell->exposay.num_surfaces)); - if (pow(shell->exposay.grid_size, 2) != shell->exposay.num_surfaces) - shell->exposay.grid_size++; - last_row_removed = pow(shell->exposay.grid_size, 2) - shell->exposay.num_surfaces; + eoutput->grid_size = floor(sqrtf(eoutput->num_surfaces)); + if (pow(eoutput->grid_size, 2) != eoutput->num_surfaces) + eoutput->grid_size++; + last_row_removed = pow(eoutput->grid_size, 2) - eoutput->num_surfaces; - shell->exposay.hpadding_outer = (output->width / 10); - shell->exposay.vpadding_outer = (output->height / 10); - shell->exposay.padding_inner = 80; + eoutput->hpadding_outer = (output->width / 10); + eoutput->vpadding_outer = (output->height / 10); + eoutput->padding_inner = 80; - w = output->width - (shell->exposay.hpadding_outer * 2); - w -= shell->exposay.padding_inner * (shell->exposay.grid_size - 1); - w /= shell->exposay.grid_size; + w = output->width - (eoutput->hpadding_outer * 2); + w -= eoutput->padding_inner * (eoutput->grid_size - 1); + w /= eoutput->grid_size; - h = output->height - (shell->exposay.vpadding_outer * 2); - h -= shell->exposay.padding_inner * (shell->exposay.grid_size - 1); - h /= shell->exposay.grid_size; + h = output->height - (eoutput->vpadding_outer * 2); + h -= eoutput->padding_inner * (eoutput->grid_size - 1); + h /= eoutput->grid_size; - shell->exposay.surface_size = (w < h) ? w : h; - if (shell->exposay.surface_size > (output->width / 2)) - shell->exposay.surface_size = output->width / 2; - if (shell->exposay.surface_size > (output->height / 2)) - shell->exposay.surface_size = output->height / 2; + eoutput->surface_size = (w < h) ? w : h; + if (eoutput->surface_size > (output->width / 2)) + eoutput->surface_size = output->width / 2; + if (eoutput->surface_size > (output->height / 2)) + eoutput->surface_size = output->height / 2; i = 0; wl_list_for_each(view, &workspace->layer.view_list, layer_link) { int pad; - pad = shell->exposay.surface_size + shell->exposay.padding_inner; + pad = eoutput->surface_size + eoutput->padding_inner; if (!get_shell_surface(view->surface)) continue; + if (view->output != output) + continue; esurface = malloc(sizeof(*esurface)); if (!esurface) { @@ -260,23 +264,24 @@ exposay_layout(struct desktop_shell *shell) wl_list_insert(&shell->exposay.surface_list, &esurface->link); esurface->shell = shell; + esurface->eoutput = eoutput; esurface->view = view; - esurface->row = i / shell->exposay.grid_size; - esurface->column = i % shell->exposay.grid_size; + esurface->row = i / eoutput->grid_size; + esurface->column = i % eoutput->grid_size; - esurface->x = shell->exposay.hpadding_outer; + esurface->x = output->x + eoutput->hpadding_outer; esurface->x += pad * esurface->column; - esurface->y = shell->exposay.vpadding_outer; + esurface->y = output->y + eoutput->vpadding_outer; esurface->y += pad * esurface->row; - if (esurface->row == shell->exposay.grid_size - 1) - esurface->x += (shell->exposay.surface_size + shell->exposay.padding_inner) * last_row_removed / 2; + if (esurface->row == eoutput->grid_size - 1) + esurface->x += (eoutput->surface_size + eoutput->padding_inner) * last_row_removed / 2; if (view->surface->width > view->surface->height) - esurface->scale = shell->exposay.surface_size / (float) view->surface->width; + esurface->scale = eoutput->surface_size / (float) view->surface->width; else - esurface->scale = shell->exposay.surface_size / (float) view->surface->height; + esurface->scale = eoutput->surface_size / (float) view->surface->height; esurface->width = view->surface->width * esurface->scale; esurface->height = view->surface->height * esurface->scale; @@ -364,7 +369,8 @@ exposay_maybe_move(struct desktop_shell *shell, int row, int column) struct exposay_surface *esurface; wl_list_for_each(esurface, &shell->exposay.surface_list, link) { - if (esurface->row != row || esurface->column != column) + if (esurface->eoutput != shell->exposay.cur_output || + esurface->row != row || esurface->column != column) continue; exposay_highlight_surface(shell, esurface); @@ -402,10 +408,10 @@ exposay_key(struct weston_keyboard_grab *grab, uint32_t time, uint32_t key, * has fewer items than all the others. */ if (!exposay_maybe_move(shell, shell->exposay.row_current + 1, shell->exposay.column_current) && - shell->exposay.row_current < (shell->exposay.grid_size - 1)) { + shell->exposay.row_current < (shell->exposay.cur_output->grid_size - 1)) { exposay_maybe_move(shell, shell->exposay.row_current + 1, - (shell->exposay.num_surfaces % - shell->exposay.grid_size) - 1); + (shell->exposay.cur_output->num_surfaces % + shell->exposay.cur_output->grid_size) - 1); } break; case KEY_LEFT: @@ -518,6 +524,8 @@ static enum exposay_layout_state exposay_transition_active(struct desktop_shell *shell) { struct weston_seat *seat = shell->exposay.seat; + struct shell_output *shell_output; + bool animate = false; shell->exposay.workspace = get_current_workspace(shell); shell->exposay.focus_prev = get_default_view (seat->keyboard->focus); @@ -537,7 +545,17 @@ exposay_transition_active(struct desktop_shell *shell) weston_pointer_set_focus(seat->pointer, NULL, seat->pointer->x, seat->pointer->y); - return exposay_layout(shell); + wl_list_for_each(shell_output, &shell->output_list, link) { + enum exposay_layout_state state; + + state = exposay_layout(shell, shell_output); + + if (state == EXPOSAY_LAYOUT_ANIMATE_TO_OVERVIEW) + animate = true; + } + + return animate ? EXPOSAY_LAYOUT_ANIMATE_TO_OVERVIEW + : EXPOSAY_LAYOUT_OVERVIEW; } static void diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 1b57bfc5..e8abeb59 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -56,13 +56,6 @@ struct focus_state { struct wl_listener surface_destroy_listener; }; -struct shell_output { - struct desktop_shell *shell; - struct weston_output *output; - struct wl_listener destroy_listener; - struct wl_list link; -}; - enum shell_surface_type { SHELL_SURFACE_NONE, SHELL_SURFACE_TOPLEVEL, diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h index 4d4f00ab..48ac250e 100644 --- a/desktop-shell/shell.h +++ b/desktop-shell/shell.h @@ -52,6 +52,41 @@ enum exposay_layout_state { EXPOSAY_LAYOUT_ANIMATE_TO_OVERVIEW, /* in transition to all windows */ }; +struct exposay_output { + int num_surfaces; + int grid_size; + int surface_size; + + int hpadding_outer; + int vpadding_outer; + int padding_inner; +}; + +struct exposay { + /* XXX: Make these exposay_surfaces. */ + struct weston_view *focus_prev; + struct weston_view *focus_current; + struct weston_view *clicked; + struct workspace *workspace; + struct weston_seat *seat; + + struct wl_list surface_list; + + struct weston_keyboard_grab grab_kbd; + struct weston_pointer_grab grab_ptr; + + enum exposay_target_state state_target; + enum exposay_layout_state state_cur; + int in_flight; /* number of animations still running */ + + int row_current; + int column_current; + struct exposay_output *cur_output; + + bool mod_pressed; + bool mod_invalid; +}; + struct focus_surface { struct weston_surface *surface; struct weston_view *view; @@ -69,6 +104,14 @@ struct workspace { struct weston_view_animation *focus_animation; }; +struct shell_output { + struct desktop_shell *shell; + struct weston_output *output; + struct exposay_output eoutput; + struct wl_listener destroy_listener; + struct wl_list link; +}; + struct desktop_shell { struct weston_compositor *compositor; @@ -146,36 +189,7 @@ struct desktop_shell { struct wl_event_source *startup_timer; } fade; - struct exposay { - /* XXX: Make these exposay_surfaces. */ - struct weston_view *focus_prev; - struct weston_view *focus_current; - struct weston_view *clicked; - struct workspace *workspace; - struct weston_seat *seat; - struct wl_list surface_list; - - struct weston_keyboard_grab grab_kbd; - struct weston_pointer_grab grab_ptr; - - enum exposay_target_state state_target; - enum exposay_layout_state state_cur; - int in_flight; /* number of animations still running */ - - int num_surfaces; - int grid_size; - int surface_size; - - int hpadding_outer; - int vpadding_outer; - int padding_inner; - - int row_current; - int column_current; - - bool mod_pressed; - bool mod_invalid; - } exposay; + struct exposay exposay; uint32_t binding_modifier; uint32_t exposay_modifier;