mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	alt-tab preview: restore functionality after move to scene-graph
This commit is contained in:
		
							parent
							
								
									296e58079f
								
							
						
					
					
						commit
						15a5b710db
					
				
					 7 changed files with 98 additions and 4 deletions
				
			
		| 
						 | 
					@ -1,7 +1,17 @@
 | 
				
			||||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
					/* SPDX-License-Identifier: GPL-2.0-only */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <wlr/types/wlr_scene.h>
 | 
					struct wlr_scene_node;
 | 
				
			||||||
 | 
					struct wlr_scene_rect;
 | 
				
			||||||
 | 
					struct wlr_scene_tree;
 | 
				
			||||||
 | 
					struct wlr_surface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_scene_rect *lab_wlr_scene_get_rect(struct wlr_scene_node *node);
 | 
					struct wlr_scene_rect *lab_wlr_scene_get_rect(struct wlr_scene_node *node);
 | 
				
			||||||
struct wlr_scene_tree *lab_scene_tree_from_node(struct wlr_scene_node *node);
 | 
					struct wlr_scene_tree *lab_scene_tree_from_node(struct wlr_scene_node *node);
 | 
				
			||||||
struct wlr_surface *lab_wlr_surface_from_node(struct wlr_scene_node *node);
 | 
					struct wlr_surface *lab_wlr_surface_from_node(struct wlr_scene_node *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * lab_get_prev_node - return previous (sibling) node
 | 
				
			||||||
 | 
					 * @node: node to find the previous node from
 | 
				
			||||||
 | 
					 * Return NULL if previous link is list-head which means node is bottom-most
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct wlr_scene_node *lab_wlr_scene_get_prev_node(struct wlr_scene_node *node);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -233,6 +233,7 @@ struct server {
 | 
				
			||||||
	/* Set when in cycle (alt-tab) mode */
 | 
						/* Set when in cycle (alt-tab) mode */
 | 
				
			||||||
	struct osd_state {
 | 
						struct osd_state {
 | 
				
			||||||
		struct view *cycle_view;
 | 
							struct view *cycle_view;
 | 
				
			||||||
 | 
							bool preview_was_enabled;
 | 
				
			||||||
		struct wlr_scene_node *preview_node;
 | 
							struct wlr_scene_node *preview_node;
 | 
				
			||||||
		struct wlr_scene_node *preview_anchor;
 | 
							struct wlr_scene_node *preview_anchor;
 | 
				
			||||||
	} osd_state;
 | 
						} osd_state;
 | 
				
			||||||
| 
						 | 
					@ -577,9 +578,12 @@ void server_init(struct server *server);
 | 
				
			||||||
void server_start(struct server *server);
 | 
					void server_start(struct server *server);
 | 
				
			||||||
void server_finish(struct server *server);
 | 
					void server_finish(struct server *server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* update onscreen display 'alt-tab' buffer */
 | 
					/* Updates onscreen display 'alt-tab' buffer */
 | 
				
			||||||
void osd_finish(struct server *server);
 | 
					 | 
				
			||||||
void osd_update(struct server *server);
 | 
					void osd_update(struct server *server);
 | 
				
			||||||
 | 
					/* Closes the OSD */
 | 
				
			||||||
 | 
					void osd_finish(struct server *server);
 | 
				
			||||||
 | 
					/* Moves preview views back into their original stacking order and state */
 | 
				
			||||||
 | 
					void osd_preview_restore(struct server *server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * wlroots "input inhibitor" extension (required for swaylock) blocks
 | 
					 * wlroots "input inhibitor" extension (required for swaylock) blocks
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,3 +32,15 @@ lab_wlr_surface_from_node(struct wlr_scene_node *node)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_scene_node *
 | 
				
			||||||
 | 
					lab_wlr_scene_get_prev_node(struct wlr_scene_node *node)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						assert(node);
 | 
				
			||||||
 | 
						struct wlr_scene_node *prev;
 | 
				
			||||||
 | 
						prev = wl_container_of(node->link.prev, node, link);
 | 
				
			||||||
 | 
						if (&prev->link == &node->parent->children) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return prev;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,6 +203,9 @@ desktop_cycle_view(struct server *server, struct view *start_view,
 | 
				
			||||||
	/* Scene nodes are ordered like last node == displayed topmost */
 | 
						/* Scene nodes are ordered like last node == displayed topmost */
 | 
				
			||||||
	iter = dir == LAB_CYCLE_DIR_FORWARD ? get_prev_item : get_next_item;
 | 
						iter = dir == LAB_CYCLE_DIR_FORWARD ? get_prev_item : get_next_item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make sure to have all nodes in their actual ordering */
 | 
				
			||||||
 | 
						osd_preview_restore(server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		list_item = iter(list_item);
 | 
							list_item = iter(list_item);
 | 
				
			||||||
		if (list_item == list_head) {
 | 
							if (list_item == list_head) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,7 @@ handle_compositor_keybindings(struct wl_listener *listener,
 | 
				
			||||||
			for (int i = 0; i < nsyms; i++) {
 | 
								for (int i = 0; i < nsyms; i++) {
 | 
				
			||||||
				if (syms[i] == XKB_KEY_Escape) {
 | 
									if (syms[i] == XKB_KEY_Escape) {
 | 
				
			||||||
					/* cancel */
 | 
										/* cancel */
 | 
				
			||||||
 | 
										osd_preview_restore(server);
 | 
				
			||||||
					/* osd_finish() additionally resets cycle_view to NULL */
 | 
										/* osd_finish() additionally resets cycle_view to NULL */
 | 
				
			||||||
					osd_finish(server);
 | 
										osd_finish(server);
 | 
				
			||||||
					return true;
 | 
										return true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										55
									
								
								src/osd.c
									
										
									
									
									
								
							
							
						
						
									
										55
									
								
								src/osd.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
// SPDX-License-Identifier: GPL-2.0-only
 | 
					// SPDX-License-Identifier: GPL-2.0-only
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
#include <cairo.h>
 | 
					#include <cairo.h>
 | 
				
			||||||
#include <drm_fourcc.h>
 | 
					#include <drm_fourcc.h>
 | 
				
			||||||
#include <pango/pangocairo.h>
 | 
					#include <pango/pangocairo.h>
 | 
				
			||||||
| 
						 | 
					@ -8,6 +9,7 @@
 | 
				
			||||||
#include "common/buf.h"
 | 
					#include "common/buf.h"
 | 
				
			||||||
#include "common/font.h"
 | 
					#include "common/font.h"
 | 
				
			||||||
#include "common/graphic-helpers.h"
 | 
					#include "common/graphic-helpers.h"
 | 
				
			||||||
 | 
					#include "common/scene-helpers.h"
 | 
				
			||||||
#include "config/rcxml.h"
 | 
					#include "config/rcxml.h"
 | 
				
			||||||
#include "labwc.h"
 | 
					#include "labwc.h"
 | 
				
			||||||
#include "theme.h"
 | 
					#include "theme.h"
 | 
				
			||||||
| 
						 | 
					@ -110,6 +112,8 @@ void
 | 
				
			||||||
osd_finish(struct server *server)
 | 
					osd_finish(struct server *server)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	server->osd_state.cycle_view = NULL;
 | 
						server->osd_state.cycle_view = NULL;
 | 
				
			||||||
 | 
						server->osd_state.preview_node = NULL;
 | 
				
			||||||
 | 
						server->osd_state.preview_anchor = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct output *output;
 | 
						struct output *output;
 | 
				
			||||||
	wl_list_for_each(output, &server->outputs, link) {
 | 
						wl_list_for_each(output, &server->outputs, link) {
 | 
				
			||||||
| 
						 | 
					@ -123,6 +127,53 @@ osd_finish(struct server *server)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					osd_preview_restore(struct server *server)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct osd_state *osd_state = &server->osd_state;
 | 
				
			||||||
 | 
						if (osd_state->preview_node) {
 | 
				
			||||||
 | 
							if (osd_state->preview_anchor) {
 | 
				
			||||||
 | 
								wlr_scene_node_place_above(osd_state->preview_node,
 | 
				
			||||||
 | 
									osd_state->preview_anchor);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/* Selected view was the first node */
 | 
				
			||||||
 | 
								wlr_scene_node_lower_to_bottom(osd_state->preview_node);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Node was disabled / minimized before, disable again */
 | 
				
			||||||
 | 
							if (!osd_state->preview_was_enabled) {
 | 
				
			||||||
 | 
								wlr_scene_node_set_enabled(osd_state->preview_node, false);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							osd_state->preview_node = NULL;
 | 
				
			||||||
 | 
							osd_state->preview_anchor = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					preview_cycled_view(struct view *view)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						assert(view);
 | 
				
			||||||
 | 
						assert(view->scene_tree);
 | 
				
			||||||
 | 
						struct osd_state *osd_state = &view->server->osd_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Move previous selected node back to its original place */
 | 
				
			||||||
 | 
						osd_preview_restore(view->server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Remember the sibling right before the selected node */
 | 
				
			||||||
 | 
						osd_state->preview_node = &view->scene_tree->node;
 | 
				
			||||||
 | 
						osd_state->preview_anchor = lab_wlr_scene_get_prev_node(
 | 
				
			||||||
 | 
							osd_state->preview_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Store node enabled / minimized state and force-enable if disabled */
 | 
				
			||||||
 | 
						osd_state->preview_was_enabled = osd_state->preview_node->enabled;
 | 
				
			||||||
 | 
						if (!osd_state->preview_was_enabled) {
 | 
				
			||||||
 | 
							wlr_scene_node_set_enabled(osd_state->preview_node, true);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Finally raise selected node to the top */
 | 
				
			||||||
 | 
						wlr_scene_node_raise_to_top(osd_state->preview_node);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
osd_update(struct server *server)
 | 
					osd_update(struct server *server)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -294,4 +345,8 @@ osd_update(struct server *server)
 | 
				
			||||||
		wlr_scene_node_set_enabled(&output->osd_tree->node, true);
 | 
							wlr_scene_node_set_enabled(&output->osd_tree->node, true);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(buf.buf);
 | 
						free(buf.buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rc.cycle_preview_contents) {
 | 
				
			||||||
 | 
							preview_cycled_view(server->osd_state.cycle_view);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								src/view.c
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								src/view.c
									
										
									
									
									
								
							| 
						 | 
					@ -3,6 +3,7 @@
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <strings.h>
 | 
					#include <strings.h>
 | 
				
			||||||
#include <xcb/xcb_icccm.h>
 | 
					#include <xcb/xcb_icccm.h>
 | 
				
			||||||
 | 
					#include "common/scene-helpers.h"
 | 
				
			||||||
#include "labwc.h"
 | 
					#include "labwc.h"
 | 
				
			||||||
#include "ssd.h"
 | 
					#include "ssd.h"
 | 
				
			||||||
#include "menu/menu.h"
 | 
					#include "menu/menu.h"
 | 
				
			||||||
| 
						 | 
					@ -833,8 +834,16 @@ view_destroy(struct view *view)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (view->scene_tree) {
 | 
						if (view->scene_tree) {
 | 
				
			||||||
 | 
							struct wlr_scene_node *node = &view->scene_tree->node;
 | 
				
			||||||
 | 
							if (osd_state->preview_anchor == node) {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * If we are the anchor for the current OSD selected view,
 | 
				
			||||||
 | 
								 * replace the anchor with the node before us.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								osd_state->preview_anchor = lab_wlr_scene_get_prev_node(node);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ssd_destroy(view);
 | 
							ssd_destroy(view);
 | 
				
			||||||
		wlr_scene_node_destroy(&view->scene_tree->node);
 | 
							wlr_scene_node_destroy(node);
 | 
				
			||||||
		view->scene_tree = NULL;
 | 
							view->scene_tree = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue