mirror of
https://github.com/labwc/labwc.git
synced 2026-02-04 04:06:25 -05:00
cycle: clarify the lifecycle of window switcher
This commit clarifies the lifecycle of the window switcher (cycle) by: - init_cycle(): initializes the window switcher (e.g. OSD). - update_cycle(): updates the window switcher states including OSD, preview and outlines. - destroy_cycle(): clears all the window switcher states. This commit temporarily regresses by not trying to preserve the selected view when a view is destroyed. This will be addressed in the next commit.
This commit is contained in:
parent
1783b805e1
commit
b6c1a9ea59
3 changed files with 65 additions and 64 deletions
|
|
@ -56,8 +56,8 @@ void cycle_step(struct server *server, enum lab_cycle_dir direction);
|
|||
/* Closes the OSD */
|
||||
void cycle_finish(struct server *server, bool switch_focus);
|
||||
|
||||
/* Notify OSD about a destroying view */
|
||||
void cycle_on_view_destroy(struct view *view);
|
||||
/* Re-initialize the window switcher */
|
||||
void cycle_reinitialize(struct server *server);
|
||||
|
||||
/* Focus the clicked window and close OSD */
|
||||
void cycle_on_cursor_release(struct server *server, struct wlr_scene_node *node);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "theme.h"
|
||||
#include "view.h"
|
||||
|
||||
static bool init_cycle(struct server *server);
|
||||
static void update_cycle(struct server *server);
|
||||
static void destroy_cycle(struct server *server);
|
||||
|
||||
|
|
@ -80,10 +81,8 @@ get_next_selected_view(struct server *server, struct view *start_view,
|
|||
}
|
||||
|
||||
void
|
||||
cycle_on_view_destroy(struct view *view)
|
||||
cycle_reinitialize(struct server *server)
|
||||
{
|
||||
assert(view);
|
||||
struct server *server = view->server;
|
||||
struct cycle_state *cycle = &server->cycle;
|
||||
|
||||
if (server->input_mode != LAB_INPUT_STATE_CYCLE) {
|
||||
|
|
@ -91,31 +90,15 @@ cycle_on_view_destroy(struct view *view)
|
|||
return;
|
||||
}
|
||||
|
||||
if (cycle->selected_view == view) {
|
||||
/*
|
||||
* If we are the current OSD selected view, cycle
|
||||
* to the next because we are dying.
|
||||
*/
|
||||
|
||||
/* Also resets preview node */
|
||||
cycle->selected_view = get_next_selected_view(server,
|
||||
cycle->selected_view, LAB_CYCLE_DIR_BACKWARD);
|
||||
|
||||
/*
|
||||
* If we cycled back to ourselves, then we have no more windows.
|
||||
* Just close the OSD for good.
|
||||
*/
|
||||
if (cycle->selected_view == view
|
||||
|| !cycle->selected_view) {
|
||||
/* cycle_finish() additionally resets selected_view to NULL */
|
||||
cycle_finish(server, /*switch_focus*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
if (cycle->selected_view) {
|
||||
/* Recreate the OSD to reflect the view has now gone. */
|
||||
destroy_cycle(server);
|
||||
destroy_cycle(server);
|
||||
if (init_cycle(server)) {
|
||||
/* TODO: try to select the same view */
|
||||
cycle->selected_view = get_next_selected_view(server, NULL,
|
||||
LAB_CYCLE_DIR_FORWARD);
|
||||
update_cycle(server);
|
||||
} else {
|
||||
/* Failed to re-init window switcher, exit */
|
||||
cycle_finish(server, /*switch_focus*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,6 +132,7 @@ restore_preview_node(struct server *server)
|
|||
}
|
||||
server->cycle.preview_node = NULL;
|
||||
server->cycle.preview_dummy = NULL;
|
||||
server->cycle.preview_was_enabled = false;
|
||||
server->cycle.preview_was_shaded = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -160,6 +144,10 @@ cycle_begin(struct server *server, enum lab_cycle_dir direction)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!init_cycle(server)) {
|
||||
return;
|
||||
}
|
||||
|
||||
server->cycle.selected_view = get_next_selected_view(server,
|
||||
server->cycle.selected_view, direction);
|
||||
|
||||
|
|
@ -188,23 +176,11 @@ cycle_finish(struct server *server, bool switch_focus)
|
|||
return;
|
||||
}
|
||||
|
||||
restore_preview_node(server);
|
||||
/* FIXME: this sets focus to the old surface even with switch_focus=true */
|
||||
seat_focus_override_end(&server->seat);
|
||||
|
||||
struct view *selected_view = server->cycle.selected_view;
|
||||
server->cycle.preview_node = NULL;
|
||||
server->cycle.preview_dummy = NULL;
|
||||
server->cycle.selected_view = NULL;
|
||||
server->cycle.preview_was_shaded = false;
|
||||
|
||||
destroy_cycle(server);
|
||||
|
||||
if (server->cycle.preview_outline) {
|
||||
/* Destroy the whole multi_rect so we can easily react to new themes */
|
||||
wlr_scene_node_destroy(&server->cycle.preview_outline->tree->node);
|
||||
server->cycle.preview_outline = NULL;
|
||||
}
|
||||
/* FIXME: this sets focus to the old surface even with switch_focus=true */
|
||||
seat_focus_override_end(&server->seat);
|
||||
|
||||
/* Hiding OSD may need a cursor change */
|
||||
cursor_update_focus(server);
|
||||
|
|
@ -270,42 +246,40 @@ get_osd_impl(void)
|
|||
}
|
||||
|
||||
static void
|
||||
update_osd_on_output(struct output *output, struct wl_array *views)
|
||||
create_osd_on_output(struct output *output, struct wl_array *views)
|
||||
{
|
||||
if (!output_is_usable(output)) {
|
||||
return;
|
||||
}
|
||||
if (!output->cycle_osd.tree) {
|
||||
get_osd_impl()->create(output, views);
|
||||
assert(output->cycle_osd.tree);
|
||||
}
|
||||
get_osd_impl()->update(output);
|
||||
get_osd_impl()->create(output, views);
|
||||
assert(output->cycle_osd.tree);
|
||||
}
|
||||
|
||||
static void
|
||||
update_cycle(struct server *server)
|
||||
/* Return false on failure */
|
||||
static bool
|
||||
init_cycle(struct server *server)
|
||||
{
|
||||
struct wl_array views;
|
||||
wl_array_init(&views);
|
||||
view_array_append(server, &views, rc.window_switcher.criteria);
|
||||
|
||||
if (!wl_array_len(&views) || !server->cycle.selected_view) {
|
||||
cycle_finish(server, /*switch_focus*/ false);
|
||||
goto out;
|
||||
if (wl_array_len(&views) <= 0) {
|
||||
wlr_log(WLR_DEBUG, "no views to switch between");
|
||||
wl_array_release(&views);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rc.window_switcher.show) {
|
||||
/* Display the actual OSD */
|
||||
/* Create OSD */
|
||||
switch (rc.window_switcher.output_criteria) {
|
||||
case CYCLE_OSD_OUTPUT_ALL: {
|
||||
struct output *output;
|
||||
wl_list_for_each(output, &server->outputs, link) {
|
||||
update_osd_on_output(output, &views);
|
||||
create_osd_on_output(output, &views);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CYCLE_OSD_OUTPUT_POINTER:
|
||||
update_osd_on_output(output_nearest_to_cursor(server), &views);
|
||||
create_osd_on_output(output_nearest_to_cursor(server), &views);
|
||||
break;
|
||||
case CYCLE_OSD_OUTPUT_KEYBOARD: {
|
||||
struct output *output;
|
||||
|
|
@ -315,14 +289,32 @@ update_cycle(struct server *server)
|
|||
/* Fallback to pointer, if there is no active_view */
|
||||
output = output_nearest_to_cursor(server);
|
||||
}
|
||||
update_osd_on_output(output, &views);
|
||||
create_osd_on_output(output, &views);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wl_array_release(&views);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
update_cycle(struct server *server)
|
||||
{
|
||||
struct cycle_state *cycle = &server->cycle;
|
||||
|
||||
if (rc.window_switcher.show) {
|
||||
struct output *output;
|
||||
wl_list_for_each(output, &server->outputs, link) {
|
||||
if (output->cycle_osd.tree) {
|
||||
get_osd_impl()->update(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rc.window_switcher.preview) {
|
||||
preview_selected_view(server->cycle.selected_view);
|
||||
preview_selected_view(cycle->selected_view);
|
||||
}
|
||||
|
||||
/* Outline current window */
|
||||
|
|
@ -331,11 +323,9 @@ update_cycle(struct server *server)
|
|||
update_preview_outlines(server->cycle.selected_view);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
wl_array_release(&views);
|
||||
}
|
||||
|
||||
/* Resets all the states in server->cycle */
|
||||
static void
|
||||
destroy_cycle(struct server *server)
|
||||
{
|
||||
|
|
@ -351,4 +341,13 @@ destroy_cycle(struct server *server)
|
|||
output->cycle_osd.tree = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
restore_preview_node(server);
|
||||
|
||||
if (server->cycle.preview_outline) {
|
||||
wlr_scene_node_destroy(&server->cycle.preview_outline->tree->node);
|
||||
server->cycle.preview_outline = NULL;
|
||||
}
|
||||
|
||||
server->cycle.selected_view = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2616,7 +2616,9 @@ view_destroy(struct view *view)
|
|||
zfree(view->tiled_region_evacuate);
|
||||
}
|
||||
|
||||
cycle_on_view_destroy(view);
|
||||
/* TODO: call this on map/unmap instead */
|
||||
cycle_reinitialize(server);
|
||||
|
||||
undecorate(view);
|
||||
|
||||
view_set_icon(view, NULL, NULL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue