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 */
 | 
			
		||||
 | 
			
		||||
#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_tree *lab_scene_tree_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 */
 | 
			
		||||
	struct osd_state {
 | 
			
		||||
		struct view *cycle_view;
 | 
			
		||||
		bool preview_was_enabled;
 | 
			
		||||
		struct wlr_scene_node *preview_node;
 | 
			
		||||
		struct wlr_scene_node *preview_anchor;
 | 
			
		||||
	} osd_state;
 | 
			
		||||
| 
						 | 
				
			
			@ -577,9 +578,12 @@ void server_init(struct server *server);
 | 
			
		|||
void server_start(struct server *server);
 | 
			
		||||
void server_finish(struct server *server);
 | 
			
		||||
 | 
			
		||||
/* update onscreen display 'alt-tab' buffer */
 | 
			
		||||
void osd_finish(struct server *server);
 | 
			
		||||
/* Updates onscreen display 'alt-tab' buffer */
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,3 +32,15 @@ lab_wlr_surface_from_node(struct wlr_scene_node *node)
 | 
			
		|||
	}
 | 
			
		||||
	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 */
 | 
			
		||||
	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 {
 | 
			
		||||
		list_item = iter(list_item);
 | 
			
		||||
		if (list_item == list_head) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,6 +150,7 @@ handle_compositor_keybindings(struct wl_listener *listener,
 | 
			
		|||
			for (int i = 0; i < nsyms; i++) {
 | 
			
		||||
				if (syms[i] == XKB_KEY_Escape) {
 | 
			
		||||
					/* cancel */
 | 
			
		||||
					osd_preview_restore(server);
 | 
			
		||||
					/* osd_finish() additionally resets cycle_view to NULL */
 | 
			
		||||
					osd_finish(server);
 | 
			
		||||
					return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										55
									
								
								src/osd.c
									
										
									
									
									
								
							
							
						
						
									
										55
									
								
								src/osd.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
// SPDX-License-Identifier: GPL-2.0-only
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <cairo.h>
 | 
			
		||||
#include <drm_fourcc.h>
 | 
			
		||||
#include <pango/pangocairo.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -8,6 +9,7 @@
 | 
			
		|||
#include "common/buf.h"
 | 
			
		||||
#include "common/font.h"
 | 
			
		||||
#include "common/graphic-helpers.h"
 | 
			
		||||
#include "common/scene-helpers.h"
 | 
			
		||||
#include "config/rcxml.h"
 | 
			
		||||
#include "labwc.h"
 | 
			
		||||
#include "theme.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +112,8 @@ void
 | 
			
		|||
osd_finish(struct server *server)
 | 
			
		||||
{
 | 
			
		||||
	server->osd_state.cycle_view = NULL;
 | 
			
		||||
	server->osd_state.preview_node = NULL;
 | 
			
		||||
	server->osd_state.preview_anchor = NULL;
 | 
			
		||||
 | 
			
		||||
	struct output *output;
 | 
			
		||||
	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
 | 
			
		||||
osd_update(struct server *server)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -294,4 +345,8 @@ osd_update(struct server *server)
 | 
			
		|||
		wlr_scene_node_set_enabled(&output->osd_tree->node, true);
 | 
			
		||||
	}
 | 
			
		||||
	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 <strings.h>
 | 
			
		||||
#include <xcb/xcb_icccm.h>
 | 
			
		||||
#include "common/scene-helpers.h"
 | 
			
		||||
#include "labwc.h"
 | 
			
		||||
#include "ssd.h"
 | 
			
		||||
#include "menu/menu.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -833,8 +834,16 @@ view_destroy(struct view *view)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
		wlr_scene_node_destroy(&view->scene_tree->node);
 | 
			
		||||
		wlr_scene_node_destroy(node);
 | 
			
		||||
		view->scene_tree = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue