mirror of
https://github.com/labwc/labwc.git
synced 2026-03-14 05:33:52 -04: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 */
|
/* Closes the OSD */
|
||||||
void cycle_finish(struct server *server, bool switch_focus);
|
void cycle_finish(struct server *server, bool switch_focus);
|
||||||
|
|
||||||
/* Notify OSD about a destroying view */
|
/* Re-initialize the window switcher */
|
||||||
void cycle_on_view_destroy(struct view *view);
|
void cycle_reinitialize(struct server *server);
|
||||||
|
|
||||||
/* Focus the clicked window and close OSD */
|
/* Focus the clicked window and close OSD */
|
||||||
void cycle_on_cursor_release(struct server *server, struct wlr_scene_node *node);
|
void cycle_on_cursor_release(struct server *server, struct wlr_scene_node *node);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
|
||||||
|
static bool init_cycle(struct server *server);
|
||||||
static void update_cycle(struct server *server);
|
static void update_cycle(struct server *server);
|
||||||
static void destroy_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
|
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;
|
struct cycle_state *cycle = &server->cycle;
|
||||||
|
|
||||||
if (server->input_mode != LAB_INPUT_STATE_CYCLE) {
|
if (server->input_mode != LAB_INPUT_STATE_CYCLE) {
|
||||||
|
|
@ -91,31 +90,15 @@ cycle_on_view_destroy(struct view *view)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycle->selected_view == view) {
|
destroy_cycle(server);
|
||||||
/*
|
if (init_cycle(server)) {
|
||||||
* If we are the current OSD selected view, cycle
|
/* TODO: try to select the same view */
|
||||||
* to the next because we are dying.
|
cycle->selected_view = get_next_selected_view(server, NULL,
|
||||||
*/
|
LAB_CYCLE_DIR_FORWARD);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
update_cycle(server);
|
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_node = NULL;
|
||||||
server->cycle.preview_dummy = NULL;
|
server->cycle.preview_dummy = NULL;
|
||||||
|
server->cycle.preview_was_enabled = false;
|
||||||
server->cycle.preview_was_shaded = false;
|
server->cycle.preview_was_shaded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,6 +144,10 @@ cycle_begin(struct server *server, enum lab_cycle_dir direction)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!init_cycle(server)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
server->cycle.selected_view = get_next_selected_view(server,
|
server->cycle.selected_view = get_next_selected_view(server,
|
||||||
server->cycle.selected_view, direction);
|
server->cycle.selected_view, direction);
|
||||||
|
|
||||||
|
|
@ -188,23 +176,11 @@ cycle_finish(struct server *server, bool switch_focus)
|
||||||
return;
|
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;
|
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);
|
destroy_cycle(server);
|
||||||
|
|
||||||
if (server->cycle.preview_outline) {
|
/* FIXME: this sets focus to the old surface even with switch_focus=true */
|
||||||
/* Destroy the whole multi_rect so we can easily react to new themes */
|
seat_focus_override_end(&server->seat);
|
||||||
wlr_scene_node_destroy(&server->cycle.preview_outline->tree->node);
|
|
||||||
server->cycle.preview_outline = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hiding OSD may need a cursor change */
|
/* Hiding OSD may need a cursor change */
|
||||||
cursor_update_focus(server);
|
cursor_update_focus(server);
|
||||||
|
|
@ -270,42 +246,40 @@ get_osd_impl(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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)) {
|
if (!output_is_usable(output)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!output->cycle_osd.tree) {
|
get_osd_impl()->create(output, views);
|
||||||
get_osd_impl()->create(output, views);
|
assert(output->cycle_osd.tree);
|
||||||
assert(output->cycle_osd.tree);
|
|
||||||
}
|
|
||||||
get_osd_impl()->update(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* Return false on failure */
|
||||||
update_cycle(struct server *server)
|
static bool
|
||||||
|
init_cycle(struct server *server)
|
||||||
{
|
{
|
||||||
struct wl_array views;
|
struct wl_array views;
|
||||||
wl_array_init(&views);
|
wl_array_init(&views);
|
||||||
view_array_append(server, &views, rc.window_switcher.criteria);
|
view_array_append(server, &views, rc.window_switcher.criteria);
|
||||||
|
if (wl_array_len(&views) <= 0) {
|
||||||
if (!wl_array_len(&views) || !server->cycle.selected_view) {
|
wlr_log(WLR_DEBUG, "no views to switch between");
|
||||||
cycle_finish(server, /*switch_focus*/ false);
|
wl_array_release(&views);
|
||||||
goto out;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc.window_switcher.show) {
|
if (rc.window_switcher.show) {
|
||||||
/* Display the actual OSD */
|
/* Create OSD */
|
||||||
switch (rc.window_switcher.output_criteria) {
|
switch (rc.window_switcher.output_criteria) {
|
||||||
case CYCLE_OSD_OUTPUT_ALL: {
|
case CYCLE_OSD_OUTPUT_ALL: {
|
||||||
struct output *output;
|
struct output *output;
|
||||||
wl_list_for_each(output, &server->outputs, link) {
|
wl_list_for_each(output, &server->outputs, link) {
|
||||||
update_osd_on_output(output, &views);
|
create_osd_on_output(output, &views);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CYCLE_OSD_OUTPUT_POINTER:
|
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;
|
break;
|
||||||
case CYCLE_OSD_OUTPUT_KEYBOARD: {
|
case CYCLE_OSD_OUTPUT_KEYBOARD: {
|
||||||
struct output *output;
|
struct output *output;
|
||||||
|
|
@ -315,14 +289,32 @@ update_cycle(struct server *server)
|
||||||
/* Fallback to pointer, if there is no active_view */
|
/* Fallback to pointer, if there is no active_view */
|
||||||
output = output_nearest_to_cursor(server);
|
output = output_nearest_to_cursor(server);
|
||||||
}
|
}
|
||||||
update_osd_on_output(output, &views);
|
create_osd_on_output(output, &views);
|
||||||
break;
|
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) {
|
if (rc.window_switcher.preview) {
|
||||||
preview_selected_view(server->cycle.selected_view);
|
preview_selected_view(cycle->selected_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Outline current window */
|
/* Outline current window */
|
||||||
|
|
@ -331,11 +323,9 @@ update_cycle(struct server *server)
|
||||||
update_preview_outlines(server->cycle.selected_view);
|
update_preview_outlines(server->cycle.selected_view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
wl_array_release(&views);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Resets all the states in server->cycle */
|
||||||
static void
|
static void
|
||||||
destroy_cycle(struct server *server)
|
destroy_cycle(struct server *server)
|
||||||
{
|
{
|
||||||
|
|
@ -351,4 +341,13 @@ destroy_cycle(struct server *server)
|
||||||
output->cycle_osd.tree = NULL;
|
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);
|
zfree(view->tiled_region_evacuate);
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle_on_view_destroy(view);
|
/* TODO: call this on map/unmap instead */
|
||||||
|
cycle_reinitialize(server);
|
||||||
|
|
||||||
undecorate(view);
|
undecorate(view);
|
||||||
|
|
||||||
view_set_icon(view, NULL, NULL);
|
view_set_icon(view, NULL, NULL);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue