mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	seat: use focus_change event to update focused/active view
- Connect to wlr_seat_keyboard_state's focus_change event. - Add view_from_wlr_surface(), which does what the name says. - Use focus_change event along with view_from_wlr_surface() to update server->focused_view and set SSD states via view_set_activated(). - Eliminate desktop_focused_view() since server->focused_view should be reliably up-to-date now. - Eliminate view_focus/defocus() since we can now just call seat_focus_surface() directly.
This commit is contained in:
		
							parent
							
								
									bb5d272dc9
								
							
						
					
					
						commit
						4028a9482f
					
				
					 9 changed files with 77 additions and 100 deletions
				
			
		| 
						 | 
					@ -167,6 +167,7 @@ struct seat {
 | 
				
			||||||
	struct wl_client *active_client_while_inhibited;
 | 
						struct wl_client *active_client_while_inhibited;
 | 
				
			||||||
	struct wl_list inputs;
 | 
						struct wl_list inputs;
 | 
				
			||||||
	struct wl_listener new_input;
 | 
						struct wl_listener new_input;
 | 
				
			||||||
 | 
						struct wl_listener focus_change;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener cursor_motion;
 | 
						struct wl_listener cursor_motion;
 | 
				
			||||||
	struct wl_listener cursor_motion_absolute;
 | 
						struct wl_listener cursor_motion_absolute;
 | 
				
			||||||
| 
						 | 
					@ -247,11 +248,8 @@ struct server {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* SSD state */
 | 
						/* SSD state */
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Currently focused view (cached value). This pointer is used
 | 
						 * Currently focused view. Updated with each "focus change"
 | 
				
			||||||
	 * primarily to track which view is being drawn with "active"
 | 
						 * event. This view is drawn with "active" SSD coloring.
 | 
				
			||||||
	 * SSD coloring. We consider it a bug if this gets out of sync
 | 
					 | 
				
			||||||
	 * with the actual keyboard focus (according to wlroots). See
 | 
					 | 
				
			||||||
	 * also desktop_focused_view().
 | 
					 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	struct view *focused_view;
 | 
						struct view *focused_view;
 | 
				
			||||||
	struct ssd_hover_state *ssd_hover_state;
 | 
						struct ssd_hover_state *ssd_hover_state;
 | 
				
			||||||
| 
						 | 
					@ -395,14 +393,6 @@ enum lab_cycle_dir {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct view *desktop_cycle_view(struct server *server, struct view *start_view,
 | 
					struct view *desktop_cycle_view(struct server *server, struct view *start_view,
 | 
				
			||||||
	enum lab_cycle_dir dir);
 | 
						enum lab_cycle_dir dir);
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * desktop_focused_view - return the view that is currently focused
 | 
					 | 
				
			||||||
 * (determined on-the-fly from the wlroots keyboard focus). The return
 | 
					 | 
				
			||||||
 * value should ideally match server->focused_view (we consider it a
 | 
					 | 
				
			||||||
 * bug otherwise) but is guaranteed to be up-to-date even if
 | 
					 | 
				
			||||||
 * server->focused_view gets out of sync.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct view *desktop_focused_view(struct server *server);
 | 
					 | 
				
			||||||
void desktop_focus_topmost_mapped_view(struct server *server);
 | 
					void desktop_focus_topmost_mapped_view(struct server *server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void keyboard_cancel_keybind_repeat(struct keyboard *keyboard);
 | 
					void keyboard_cancel_keybind_repeat(struct keyboard *keyboard);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,6 +186,12 @@ enum lab_view_criteria {
 | 
				
			||||||
	LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 2,
 | 
						LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 2,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * view_from_wlr_surface() - returns the view associated with a
 | 
				
			||||||
 | 
					 * wlr_surface, or NULL if the surface has no associated view.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct view *view_from_wlr_surface(struct wlr_surface *surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * for_each_view() - iterate over all views which match criteria
 | 
					 * for_each_view() - iterate over all views which match criteria
 | 
				
			||||||
 * @view: Iterator.
 | 
					 * @view: Iterator.
 | 
				
			||||||
| 
						 | 
					@ -257,8 +263,7 @@ bool view_isfocusable(struct view *view);
 | 
				
			||||||
bool view_inhibits_keybinds(struct view *view);
 | 
					bool view_inhibits_keybinds(struct view *view);
 | 
				
			||||||
void view_toggle_keybinds(struct view *view);
 | 
					void view_toggle_keybinds(struct view *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void view_focus(struct view *view);
 | 
					void view_set_activated(struct view *view, bool activated);
 | 
				
			||||||
void view_defocus(struct view *view);
 | 
					 | 
				
			||||||
void view_set_output(struct view *view, struct output *output);
 | 
					void view_set_output(struct view *view, struct output *output);
 | 
				
			||||||
void view_close(struct view *view);
 | 
					void view_close(struct view *view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -503,7 +503,7 @@ view_for_action(struct view *activator, struct server *server,
 | 
				
			||||||
		return ctx.view;
 | 
							return ctx.view;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return desktop_focused_view(server);
 | 
							return server->focused_view;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -602,7 +602,7 @@ create_constraint(struct wl_listener *listener, void *data)
 | 
				
			||||||
	constraint->destroy.notify = destroy_constraint;
 | 
						constraint->destroy.notify = destroy_constraint;
 | 
				
			||||||
	wl_signal_add(&wlr_constraint->events.destroy, &constraint->destroy);
 | 
						wl_signal_add(&wlr_constraint->events.destroy, &constraint->destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct view *view = desktop_focused_view(server);
 | 
						struct view *view = server->focused_view;
 | 
				
			||||||
	if (view && view->surface == wlr_constraint->surface) {
 | 
						if (view && view->surface == wlr_constraint->surface) {
 | 
				
			||||||
		constrain_cursor(server, wlr_constraint);
 | 
							constrain_cursor(server, wlr_constraint);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,10 @@ desktop_focus_view(struct view *view, bool raise)
 | 
				
			||||||
		workspaces_switch_to(view->workspace, /*update_focus*/ false);
 | 
							workspaces_switch_to(view->workspace, /*update_focus*/ false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	view_focus(view);
 | 
						struct seat *seat = &server->seat;
 | 
				
			||||||
 | 
						if (view->surface != seat->seat->keyboard_state.focused_surface) {
 | 
				
			||||||
 | 
							seat_focus_surface(seat, view->surface);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (raise) {
 | 
						if (raise) {
 | 
				
			||||||
		view_move_to_front(view);
 | 
							view_move_to_front(view);
 | 
				
			||||||
| 
						 | 
					@ -147,7 +150,7 @@ desktop_cycle_view(struct server *server, struct view *start_view,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!start_view) {
 | 
						if (!start_view) {
 | 
				
			||||||
		start_view = first_view(server);
 | 
							start_view = first_view(server);
 | 
				
			||||||
		if (!start_view || start_view != desktop_focused_view(server)) {
 | 
							if (!start_view || start_view != server->focused_view) {
 | 
				
			||||||
			return start_view;  /* may be NULL */
 | 
								return start_view;  /* may be NULL */
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -206,32 +209,6 @@ desktop_topmost_mapped_view(struct server *server)
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct view *
 | 
					 | 
				
			||||||
desktop_focused_view(struct server *server)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct seat *seat = &server->seat;
 | 
					 | 
				
			||||||
	struct wlr_surface *focused_surface =
 | 
					 | 
				
			||||||
		seat->seat->keyboard_state.focused_surface;
 | 
					 | 
				
			||||||
	struct view *focused_view = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (focused_surface) {
 | 
					 | 
				
			||||||
		struct view *view;
 | 
					 | 
				
			||||||
		wl_list_for_each(view, &server->views, link) {
 | 
					 | 
				
			||||||
			if (view->surface == focused_surface) {
 | 
					 | 
				
			||||||
				focused_view = view;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* warn so we can identify cases where this occurs */
 | 
					 | 
				
			||||||
	if (focused_view != server->focused_view) {
 | 
					 | 
				
			||||||
		wlr_log(WLR_ERROR, "server->focused_view is out of sync");
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return focused_view;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
desktop_focus_topmost_mapped_view(struct server *server)
 | 
					desktop_focus_topmost_mapped_view(struct server *server)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -242,12 +219,8 @@ desktop_focus_topmost_mapped_view(struct server *server)
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Defocus previous focused surface/view if no longer
 | 
							 * Defocus previous focused surface/view if no longer
 | 
				
			||||||
		 * focusable (e.g. unmapped or on a different workspace).
 | 
							 * focusable (e.g. unmapped or on a different workspace).
 | 
				
			||||||
		 * Note than a non-view surface may have been focused.
 | 
					 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		seat_focus_surface(&server->seat, NULL);
 | 
							seat_focus_surface(&server->seat, NULL);
 | 
				
			||||||
		if (server->focused_view) {
 | 
					 | 
				
			||||||
			view_defocus(server->focused_view);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ handle_keybinding(struct server *server, uint32_t modifiers, xkb_keysym_t sym, x
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (server->seat.nr_inhibited_keybind_views
 | 
							if (server->seat.nr_inhibited_keybind_views
 | 
				
			||||||
				&& view_inhibits_keybinds(desktop_focused_view(server))
 | 
									&& view_inhibits_keybinds(server->focused_view)
 | 
				
			||||||
				&& !actions_contain_toggle_keybinds(&keybind->actions)) {
 | 
									&& !actions_contain_toggle_keybinds(&keybind->actions)) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								src/seat.c
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								src/seat.c
									
										
									
									
									
								
							| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
#include "common/mem.h"
 | 
					#include "common/mem.h"
 | 
				
			||||||
#include "key-state.h"
 | 
					#include "key-state.h"
 | 
				
			||||||
#include "labwc.h"
 | 
					#include "labwc.h"
 | 
				
			||||||
 | 
					#include "view.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
input_device_destroy(struct wl_listener *listener, void *data)
 | 
					input_device_destroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
| 
						 | 
					@ -335,6 +336,26 @@ new_virtual_keyboard(struct wl_listener *listener, void *data)
 | 
				
			||||||
	seat_add_device(seat, input);
 | 
						seat_add_device(seat, input);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					focus_change_notify(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct seat *seat = wl_container_of(listener, seat, focus_change);
 | 
				
			||||||
 | 
						struct wlr_seat_keyboard_focus_change_event *event = data;
 | 
				
			||||||
 | 
						struct server *server = seat->server;
 | 
				
			||||||
 | 
						struct view *view = event->new_surface ?
 | 
				
			||||||
 | 
							view_from_wlr_surface(event->new_surface) : NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (view != server->focused_view) {
 | 
				
			||||||
 | 
							if (server->focused_view) {
 | 
				
			||||||
 | 
								view_set_activated(server->focused_view, false);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (view) {
 | 
				
			||||||
 | 
								view_set_activated(view, true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							server->focused_view = view;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
seat_init(struct server *server)
 | 
					seat_init(struct server *server)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -353,6 +374,10 @@ seat_init(struct server *server)
 | 
				
			||||||
	seat->new_input.notify = new_input_notify;
 | 
						seat->new_input.notify = new_input_notify;
 | 
				
			||||||
	wl_signal_add(&server->backend->events.new_input, &seat->new_input);
 | 
						wl_signal_add(&server->backend->events.new_input, &seat->new_input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						seat->focus_change.notify = focus_change_notify;
 | 
				
			||||||
 | 
						wl_signal_add(&seat->seat->keyboard_state.events.focus_change,
 | 
				
			||||||
 | 
							&seat->focus_change);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	seat->virtual_pointer = wlr_virtual_pointer_manager_v1_create(
 | 
						seat->virtual_pointer = wlr_virtual_pointer_manager_v1_create(
 | 
				
			||||||
		server->wl_display);
 | 
							server->wl_display);
 | 
				
			||||||
	wl_signal_add(&seat->virtual_pointer->events.new_virtual_pointer,
 | 
						wl_signal_add(&seat->virtual_pointer->events.new_virtual_pointer,
 | 
				
			||||||
| 
						 | 
					@ -382,6 +407,7 @@ seat_finish(struct server *server)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct seat *seat = &server->seat;
 | 
						struct seat *seat = &server->seat;
 | 
				
			||||||
	wl_list_remove(&seat->new_input.link);
 | 
						wl_list_remove(&seat->new_input.link);
 | 
				
			||||||
 | 
						wl_list_remove(&seat->focus_change.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct input *input, *next;
 | 
						struct input *input, *next;
 | 
				
			||||||
	wl_list_for_each_safe(input, next, &seat->inputs, link) {
 | 
						wl_list_for_each_safe(input, next, &seat->inputs, link) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										81
									
								
								src/view.c
									
										
									
									
									
								
							
							
						
						
									
										81
									
								
								src/view.c
									
										
									
									
									
								
							| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <strings.h>
 | 
					#include <strings.h>
 | 
				
			||||||
 | 
					#include <wlr/xwayland.h>
 | 
				
			||||||
#include "common/mem.h"
 | 
					#include "common/mem.h"
 | 
				
			||||||
#include "common/scene-helpers.h"
 | 
					#include "common/scene-helpers.h"
 | 
				
			||||||
#include "labwc.h"
 | 
					#include "labwc.h"
 | 
				
			||||||
| 
						 | 
					@ -19,6 +20,34 @@
 | 
				
			||||||
#define LAB_FALLBACK_WIDTH  640
 | 
					#define LAB_FALLBACK_WIDTH  640
 | 
				
			||||||
#define LAB_FALLBACK_HEIGHT 480
 | 
					#define LAB_FALLBACK_HEIGHT 480
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct view *
 | 
				
			||||||
 | 
					view_from_wlr_surface(struct wlr_surface *surface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						assert(surface);
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * TODO:
 | 
				
			||||||
 | 
						 * - find a way to get rid of xdg/xwayland-specific stuff
 | 
				
			||||||
 | 
						 * - look up root/toplevel surface if passed a subsurface?
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (wlr_surface_is_xdg_surface(surface)) {
 | 
				
			||||||
 | 
							struct wlr_xdg_surface *xdg_surface =
 | 
				
			||||||
 | 
								wlr_xdg_surface_from_wlr_surface(surface);
 | 
				
			||||||
 | 
							if (xdg_surface) {
 | 
				
			||||||
 | 
								return xdg_surface->data;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#if HAVE_XWAYLAND
 | 
				
			||||||
 | 
						if (wlr_surface_is_xwayland_surface(surface)) {
 | 
				
			||||||
 | 
							struct wlr_xwayland_surface *xsurface =
 | 
				
			||||||
 | 
								wlr_xwayland_surface_from_wlr_surface(surface);
 | 
				
			||||||
 | 
							if (xsurface) {
 | 
				
			||||||
 | 
								return xsurface->data;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool
 | 
					static bool
 | 
				
			||||||
matches_criteria(struct view *view, enum lab_view_criteria criteria)
 | 
					matches_criteria(struct view *view, enum lab_view_criteria criteria)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -174,9 +203,10 @@ view_discover_output(struct view *view)
 | 
				
			||||||
		view->current.y + view->current.height / 2);
 | 
							view->current.y + view->current.height / 2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					void
 | 
				
			||||||
_view_set_activated(struct view *view, bool activated)
 | 
					view_set_activated(struct view *view, bool activated)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						assert(view);
 | 
				
			||||||
	ssd_set_active(view->ssd, activated);
 | 
						ssd_set_active(view->ssd, activated);
 | 
				
			||||||
	if (view->impl->set_activated) {
 | 
						if (view->impl->set_activated) {
 | 
				
			||||||
		view->impl->set_activated(view, activated);
 | 
							view->impl->set_activated(view, activated);
 | 
				
			||||||
| 
						 | 
					@ -187,52 +217,6 @@ _view_set_activated(struct view *view, bool activated)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Give the view keyboard focus and mark it active. This function should
 | 
					 | 
				
			||||||
 * only be called by desktop_focus_view(), which contains additional
 | 
					 | 
				
			||||||
 * checks to make sure it's okay to give focus.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
view_focus(struct view *view)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	assert(view);
 | 
					 | 
				
			||||||
	/* Update seat focus */
 | 
					 | 
				
			||||||
	struct seat *seat = &view->server->seat;
 | 
					 | 
				
			||||||
	if (view->surface != seat->seat->keyboard_state.focused_surface) {
 | 
					 | 
				
			||||||
		seat_focus_surface(seat, view->surface);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	/* Update active view */
 | 
					 | 
				
			||||||
	if (view != view->server->focused_view) {
 | 
					 | 
				
			||||||
		if (view->server->focused_view) {
 | 
					 | 
				
			||||||
			_view_set_activated(view->server->focused_view, false);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_view_set_activated(view, true);
 | 
					 | 
				
			||||||
		view->server->focused_view = view;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Take keyboard focus from the view and mark it inactive. It's rarely
 | 
					 | 
				
			||||||
 * necessary to call this function directly; usually it's better to
 | 
					 | 
				
			||||||
 * focus a different view instead by calling something like
 | 
					 | 
				
			||||||
 * desktop_focus_topmost_mapped_view().
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
view_defocus(struct view *view)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	assert(view);
 | 
					 | 
				
			||||||
	/* Update seat focus */
 | 
					 | 
				
			||||||
	struct seat *seat = &view->server->seat;
 | 
					 | 
				
			||||||
	if (view->surface == seat->seat->keyboard_state.focused_surface) {
 | 
					 | 
				
			||||||
		seat_focus_surface(seat, NULL);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	/* Update active view */
 | 
					 | 
				
			||||||
	if (view == view->server->focused_view) {
 | 
					 | 
				
			||||||
		_view_set_activated(view, false);
 | 
					 | 
				
			||||||
		view->server->focused_view = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
view_set_output(struct view *view, struct output *output)
 | 
					view_set_output(struct view *view, struct output *output)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -408,7 +392,6 @@ _minimize(struct view *view, bool minimized)
 | 
				
			||||||
	view->minimized = minimized;
 | 
						view->minimized = minimized;
 | 
				
			||||||
	if (minimized) {
 | 
						if (minimized) {
 | 
				
			||||||
		view->impl->unmap(view, /* client_request */ false);
 | 
							view->impl->unmap(view, /* client_request */ false);
 | 
				
			||||||
		view_defocus(view);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		view->impl->map(view);
 | 
							view->impl->map(view);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -287,7 +287,7 @@ workspaces_switch_to(struct workspace *target, bool update_focus)
 | 
				
			||||||
	 * Only refocus if the focus is not already on an always-on-top view.
 | 
						 * Only refocus if the focus is not already on an always-on-top view.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (update_focus) {
 | 
						if (update_focus) {
 | 
				
			||||||
		struct view *view = desktop_focused_view(server);
 | 
							struct view *view = server->focused_view;
 | 
				
			||||||
		if (!view || !view_is_always_on_top(view)) {
 | 
							if (!view || !view_is_always_on_top(view)) {
 | 
				
			||||||
			desktop_focus_topmost_mapped_view(server);
 | 
								desktop_focus_topmost_mapped_view(server);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue