mirror of
				https://github.com/labwc/labwc.git
				synced 2025-10-29 05:40:24 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			454 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			454 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* SPDX-License-Identifier: GPL-2.0-only */
 | |
| #ifndef LABWC_H
 | |
| #define LABWC_H
 | |
| #include "config.h"
 | |
| #include <wlr/util/log.h>
 | |
| #include "common/set.h"
 | |
| #include "input/cursor.h"
 | |
| #include "overlay.h"
 | |
| #if HAVE_NLS
 | |
| #include <libintl.h>
 | |
| #include <locale.h>
 | |
| #define _ gettext
 | |
| #else
 | |
| #define _(s) (s)
 | |
| #endif
 | |
| 
 | |
| #define XCURSOR_DEFAULT "left_ptr"
 | |
| #define XCURSOR_SIZE 24
 | |
| 
 | |
| struct wlr_xdg_popup;
 | |
| 
 | |
| enum input_mode {
 | |
| 	LAB_INPUT_STATE_PASSTHROUGH = 0,
 | |
| 	LAB_INPUT_STATE_MOVE,
 | |
| 	LAB_INPUT_STATE_RESIZE,
 | |
| 	LAB_INPUT_STATE_MENU,
 | |
| 	LAB_INPUT_STATE_WINDOW_SWITCHER,
 | |
| };
 | |
| 
 | |
| struct seat {
 | |
| 	struct wlr_seat *seat;
 | |
| 	struct server *server;
 | |
| 	struct wlr_keyboard_group *keyboard_group;
 | |
| 
 | |
| 	struct wl_list touch_points; /* struct touch_point.link */
 | |
| 
 | |
| 	/*
 | |
| 	 * Enum of most recent server-side cursor image.  Set by
 | |
| 	 * cursor_set().  Cleared when a client surface is entered
 | |
| 	 * (in that case the client is expected to set its own cursor image).
 | |
| 	 */
 | |
| 	enum lab_cursors server_cursor;
 | |
| 	bool cursor_visible;
 | |
| 	struct wlr_cursor *cursor;
 | |
| 	struct wlr_xcursor_manager *xcursor_manager;
 | |
| 	struct accumulated_scroll {
 | |
| 		double delta;
 | |
| 		double delta_discrete;
 | |
| 	} accumulated_scrolls[2]; /* indexed by wl_pointer_axis */
 | |
| 	bool cursor_scroll_wheel_emulation;
 | |
| 
 | |
| 	/*
 | |
| 	 * The surface whose keyboard focus is temporarily cleared with
 | |
| 	 * seat_focus_override_begin() and restored with
 | |
| 	 * seat_focus_override_end().
 | |
| 	 */
 | |
| 	struct {
 | |
| 		struct wlr_surface *surface;
 | |
| 		struct wl_listener surface_destroy;
 | |
| 	} focus_override;
 | |
| 
 | |
| 	struct wlr_pointer_constraint_v1 *current_constraint;
 | |
| 
 | |
| 	/* Used to hide the workspace OSD after switching workspaces */
 | |
| 	struct wl_event_source *workspace_osd_timer;
 | |
| 	bool workspace_osd_shown_by_modifier;
 | |
| 
 | |
| 	/* if set, views cannot receive focus */
 | |
| 	struct wlr_layer_surface_v1 *focused_layer;
 | |
| 
 | |
| 	struct input_method_relay *input_method_relay;
 | |
| 
 | |
| 	/**
 | |
| 	 * This is usually zeroed and is only set on button press while the
 | |
| 	 * mouse is over a view or surface, and zeroed on button release.
 | |
| 	 * It is used to send cursor motion events to a surface even though
 | |
| 	 * the cursor has left the surface in the meantime.
 | |
| 	 *
 | |
| 	 * This allows to keep dragging a scrollbar or selecting text even
 | |
| 	 * when moving outside of the window.
 | |
| 	 *
 | |
| 	 * It is also used to:
 | |
| 	 * - determine the target view for action in "Drag" mousebind
 | |
| 	 * - validate view move/resize requests from CSD clients
 | |
| 	 *
 | |
| 	 * Both (view && !surface) and (surface && !view) are possible.
 | |
| 	 */
 | |
| 	struct cursor_context pressed;
 | |
| 
 | |
| 	struct lab_set bound_buttons;
 | |
| 
 | |
| 	struct {
 | |
| 		bool active;
 | |
| 		struct {
 | |
| 			struct wl_listener request;
 | |
| 			struct wl_listener start;
 | |
| 			struct wl_listener destroy;
 | |
| 		} events;
 | |
| 		struct wlr_scene_tree *icons;
 | |
| 	} drag;
 | |
| 
 | |
| 	struct overlay overlay;
 | |
| 	/* Used to prevent region snapping when starting a move with A-Left */
 | |
| 	bool region_prevent_snap;
 | |
| 
 | |
| 	struct wl_list inputs;
 | |
| 	struct wl_listener new_input;
 | |
| 	struct wl_listener focus_change;
 | |
| 
 | |
| 	struct {
 | |
| 		struct wl_listener motion;
 | |
| 		struct wl_listener motion_absolute;
 | |
| 		struct wl_listener button;
 | |
| 		struct wl_listener axis;
 | |
| 		struct wl_listener frame;
 | |
| 	} on_cursor;
 | |
| 
 | |
| 	struct wlr_pointer_gestures_v1 *pointer_gestures;
 | |
| 	struct wl_listener pinch_begin;
 | |
| 	struct wl_listener pinch_update;
 | |
| 	struct wl_listener pinch_end;
 | |
| 	struct wl_listener swipe_begin;
 | |
| 	struct wl_listener swipe_update;
 | |
| 	struct wl_listener swipe_end;
 | |
| 	struct wl_listener hold_begin;
 | |
| 	struct wl_listener hold_end;
 | |
| 
 | |
| 	struct wl_listener request_set_cursor;
 | |
| 	struct wl_listener request_set_shape;
 | |
| 	struct wl_listener request_set_selection;
 | |
| 	struct wl_listener request_set_primary_selection;
 | |
| 
 | |
| 	struct wl_listener touch_down;
 | |
| 	struct wl_listener touch_up;
 | |
| 	struct wl_listener touch_motion;
 | |
| 	struct wl_listener touch_frame;
 | |
| 
 | |
| 	struct wl_listener tablet_tool_proximity;
 | |
| 	struct wl_listener tablet_tool_axis;
 | |
| 	struct wl_listener tablet_tool_tip;
 | |
| 	struct wl_listener tablet_tool_button;
 | |
| 
 | |
| 	struct wl_list tablets;
 | |
| 	struct wl_list tablet_tools;
 | |
| 	struct wl_list tablet_pads;
 | |
| 
 | |
| 	struct wl_listener constraint_commit;
 | |
| 	struct wl_listener pressed_surface_destroy;
 | |
| 
 | |
| 	struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
 | |
| 	struct wl_listener virtual_pointer_new;
 | |
| 
 | |
| 	struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
 | |
| 	struct wl_listener new_virtual_keyboard;
 | |
| };
 | |
| 
 | |
| struct server {
 | |
| 	struct wl_display *wl_display;
 | |
| 	struct wl_event_loop *wl_event_loop;  /* Can be used for timer events */
 | |
| 	struct wlr_renderer *renderer;
 | |
| 	struct wlr_allocator *allocator;
 | |
| 	struct wlr_backend *backend;
 | |
| 	struct headless {
 | |
| 		struct wlr_backend *backend;
 | |
| 	} headless;
 | |
| 	struct wlr_session *session;
 | |
| 	struct wlr_linux_dmabuf_v1 *linux_dmabuf;
 | |
| 	struct wlr_compositor *compositor;
 | |
| 
 | |
| 	struct wl_event_source *sighup_source;
 | |
| 	struct wl_event_source *sigint_source;
 | |
| 	struct wl_event_source *sigterm_source;
 | |
| 	struct wl_event_source *sigchld_source;
 | |
| 
 | |
| 	struct wlr_xdg_shell *xdg_shell;
 | |
| 	struct wlr_layer_shell_v1 *layer_shell;
 | |
| 
 | |
| 	struct wl_listener new_xdg_toplevel;
 | |
| 	struct wl_listener new_layer_surface;
 | |
| 
 | |
| 	struct wl_listener kde_server_decoration;
 | |
| 	struct wl_listener xdg_toplevel_decoration;
 | |
| #if HAVE_XWAYLAND
 | |
| 	struct wlr_xwayland *xwayland;
 | |
| 	struct wl_listener xwayland_server_ready;
 | |
| 	struct wl_listener xwayland_xwm_ready;
 | |
| 	struct wl_listener xwayland_new_surface;
 | |
| #endif
 | |
| 
 | |
| 	struct wlr_xdg_activation_v1 *xdg_activation;
 | |
| 	struct wl_listener xdg_activation_request;
 | |
| 	struct wl_listener xdg_activation_new_token;
 | |
| 
 | |
| 	struct wlr_xdg_toplevel_icon_manager_v1 *xdg_toplevel_icon_manager;
 | |
| 	struct wl_listener xdg_toplevel_icon_set_icon;
 | |
| 
 | |
| 	struct wl_list views;
 | |
| 	struct wl_list unmanaged_surfaces;
 | |
| 
 | |
| 	struct seat seat;
 | |
| 	struct wlr_scene *scene;
 | |
| 	struct wlr_scene_output_layout *scene_layout;
 | |
| 	bool direct_scanout_enabled;
 | |
| 
 | |
| 	/* cursor interactive */
 | |
| 	enum input_mode input_mode;
 | |
| 	struct view *grabbed_view;
 | |
| 	/* Cursor position when interactive move/resize is requested */
 | |
| 	double grab_x, grab_y;
 | |
| 	/* View geometry when interactive move/resize is requested */
 | |
| 	struct wlr_box grab_box;
 | |
| 	enum lab_edge resize_edges;
 | |
| 
 | |
| 	/*
 | |
| 	 * 'active_view' is generally the view with keyboard-focus, updated with
 | |
| 	 * each "focus change". This view is drawn with "active" SSD coloring.
 | |
| 	 *
 | |
| 	 * The exceptions are:
 | |
| 	 * - when a layer-shell client takes keyboard-focus in which case the
 | |
| 	 *   currently active view stays active
 | |
| 	 * - when keyboard focus is temporarily cleared for server-side
 | |
| 	 *   interactions like Move/Resize, window switcher and menus.
 | |
| 	 *
 | |
| 	 * Note that active_view is synced with foreign-toplevel clients.
 | |
| 	 */
 | |
| 	struct view *active_view;
 | |
| 
 | |
| 	struct ssd_part_button *hovered_button;
 | |
| 
 | |
| 	/* Tree for all non-layer xdg/xwayland-shell surfaces */
 | |
| 	struct wlr_scene_tree *view_tree;
 | |
| 
 | |
| 	/*
 | |
| 	 * Popups need to be rendered above always-on-top views, so we reparent
 | |
| 	 * them to this dedicated tree
 | |
| 	 */
 | |
| 	struct wlr_scene_tree *xdg_popup_tree;
 | |
| 
 | |
| 	/* Tree for all non-layer xdg/xwayland-shell surfaces with always-on-top/below */
 | |
| 	struct wlr_scene_tree *view_tree_always_on_top;
 | |
| 	struct wlr_scene_tree *view_tree_always_on_bottom;
 | |
| #if HAVE_XWAYLAND
 | |
| 	/* Tree for unmanaged xsurfaces without initialized view (usually popups) */
 | |
| 	struct wlr_scene_tree *unmanaged_tree;
 | |
| #endif
 | |
| 	/* Tree for built in menu */
 | |
| 	struct wlr_scene_tree *menu_tree;
 | |
| 
 | |
| 	/* Workspaces */
 | |
| 	struct {
 | |
| 		struct wl_list all;  /* struct workspace.link */
 | |
| 		struct workspace *current;
 | |
| 		struct workspace *last;
 | |
| 		struct lab_cosmic_workspace_manager *cosmic_manager;
 | |
| 		struct lab_cosmic_workspace_group *cosmic_group;
 | |
| 		struct lab_ext_workspace_manager *ext_manager;
 | |
| 		struct lab_ext_workspace_group *ext_group;
 | |
| 		struct {
 | |
| 			struct wl_listener layout_output_added;
 | |
| 		} on;
 | |
| 	} workspaces;
 | |
| 
 | |
| 	struct wl_list outputs;
 | |
| 	struct wl_listener new_output;
 | |
| 	struct wlr_output_layout *output_layout;
 | |
| 
 | |
| 	struct wl_listener output_layout_change;
 | |
| 	struct wlr_output_manager_v1 *output_manager;
 | |
| 	struct wl_listener output_manager_test;
 | |
| 	struct wl_listener output_manager_apply;
 | |
| 	/*
 | |
| 	 * While an output layout change is in process, this counter is
 | |
| 	 * non-zero and causes change-events from the wlr_output_layout
 | |
| 	 * to be ignored (to prevent, for example, moving views in a
 | |
| 	 * transitory layout state).  Once the counter reaches zero,
 | |
| 	 * do_output_layout_change() must be called explicitly.
 | |
| 	 */
 | |
| 	int pending_output_layout_change;
 | |
| 
 | |
| 	struct wl_listener renderer_lost;
 | |
| 
 | |
| 	struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1;
 | |
| 	struct wl_listener gamma_control_set_gamma;
 | |
| 
 | |
| 	struct session_lock_manager *session_lock_manager;
 | |
| 
 | |
| 	struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
 | |
| 	struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list;
 | |
| 
 | |
| 	struct wlr_drm_lease_v1_manager *drm_lease_manager;
 | |
| 	struct wl_listener drm_lease_request;
 | |
| 
 | |
| 	struct wlr_output_power_manager_v1 *output_power_manager_v1;
 | |
| 	struct wl_listener output_power_manager_set_mode;
 | |
| 
 | |
| 	struct wlr_relative_pointer_manager_v1 *relative_pointer_manager;
 | |
| 	struct wlr_pointer_constraints_v1 *constraints;
 | |
| 	struct wl_listener new_constraint;
 | |
| 
 | |
| 	struct wlr_tearing_control_manager_v1 *tearing_control;
 | |
| 	struct wl_listener tearing_new_object;
 | |
| 
 | |
| 	struct wlr_input_method_manager_v2 *input_method_manager;
 | |
| 	struct wlr_text_input_manager_v3 *text_input_manager;
 | |
| 
 | |
| 	struct wlr_tablet_manager_v2 *tablet_manager;
 | |
| 	struct wlr_security_context_manager_v1 *security_context_manager_v1;
 | |
| 
 | |
| 	/* 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_tree *preview_parent;
 | |
| 		struct wlr_scene_node *preview_anchor;
 | |
| 		struct lab_scene_rect *preview_outline;
 | |
| 	} osd_state;
 | |
| 
 | |
| 	struct theme *theme;
 | |
| 
 | |
| 	struct menu *menu_current;
 | |
| 	struct wl_list menus;
 | |
| 
 | |
| 	struct sfdo *sfdo;
 | |
| 
 | |
| 	pid_t primary_client_pid;
 | |
| };
 | |
| 
 | |
| void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup);
 | |
| void xdg_shell_init(struct server *server);
 | |
| void xdg_shell_finish(struct server *server);
 | |
| 
 | |
| /*
 | |
|  * desktop.c routines deal with a collection of views
 | |
|  *
 | |
|  * Definition of a few keywords used in desktop.c
 | |
|  *   raise    - Bring view to front.
 | |
|  *   focus    - Give keyboard focus to view.
 | |
|  *   activate - Set view surface as active so that client window decorations
 | |
|  *              are painted to show that the window is active,typically by
 | |
|  *              using a different color. Although xdg-shell protocol says you
 | |
|  *              cannot assume this means that the window actually has keyboard
 | |
|  *              or pointer focus, in this compositor are they called together.
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * desktop_focus_view() - do multiple things to make a view "active" and
 | |
|  * ready to use:
 | |
|  *  - unminimize
 | |
|  *  - switch to the workspace it's on
 | |
|  *  - give input (keyboard) focus
 | |
|  *  - optionally raise above other views
 | |
|  *
 | |
|  * It's okay to call this function even if the view isn't mapped or the
 | |
|  * session is locked; it will simply do nothing.
 | |
|  */
 | |
| void desktop_focus_view(struct view *view, bool raise);
 | |
| 
 | |
| /**
 | |
|  * desktop_focus_view_or_surface() - like desktop_focus_view() but can
 | |
|  * also focus other (e.g. xwayland-unmanaged) surfaces
 | |
|  */
 | |
| void desktop_focus_view_or_surface(struct seat *seat, struct view *view,
 | |
| 	struct wlr_surface *surface, bool raise);
 | |
| 
 | |
| void desktop_arrange_all_views(struct server *server);
 | |
| void desktop_focus_output(struct output *output);
 | |
| struct view *desktop_topmost_focusable_view(struct server *server);
 | |
| 
 | |
| /**
 | |
|  * Toggles the (output local) visibility of the layershell top layer
 | |
|  * based on the existence of a fullscreen window on the current workspace.
 | |
|  */
 | |
| void desktop_update_top_layer_visibility(struct server *server);
 | |
| 
 | |
| /**
 | |
|  * desktop_focus_topmost_view() - focus the topmost view on the current
 | |
|  * workspace, skipping views that claim not to want focus (those can
 | |
|  * still be focused by explicit request, e.g. by clicking in them).
 | |
|  *
 | |
|  * This function is typically called when the focused view is hidden
 | |
|  * (closes, is minimized, etc.) to focus the "next" view underneath.
 | |
|  */
 | |
| void desktop_focus_topmost_view(struct server *server);
 | |
| 
 | |
| void seat_init(struct server *server);
 | |
| void seat_finish(struct server *server);
 | |
| void seat_reconfigure(struct server *server);
 | |
| void seat_focus_surface(struct seat *seat, struct wlr_surface *surface);
 | |
| 
 | |
| void seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface);
 | |
| 
 | |
| /**
 | |
|  * seat_focus_lock_surface() - ONLY to be called from session-lock.c to
 | |
|  * focus lock screen surfaces. Use seat_focus_surface() otherwise.
 | |
|  */
 | |
| void seat_focus_lock_surface(struct seat *seat, struct wlr_surface *surface);
 | |
| 
 | |
| void seat_set_focus_layer(struct seat *seat, struct wlr_layer_surface_v1 *layer);
 | |
| void seat_set_pressed(struct seat *seat, struct cursor_context *ctx);
 | |
| void seat_reset_pressed(struct seat *seat);
 | |
| void seat_output_layout_changed(struct seat *seat);
 | |
| 
 | |
| /*
 | |
|  * Temporarily clear the pointer/keyboard focus from the client at the
 | |
|  * beginning of interactive move/resize, window switcher or menu interactions.
 | |
|  * The focus is kept cleared until seat_focus_override_end() is called or
 | |
|  * layer-shell/session-lock surfaces are mapped.
 | |
|  */
 | |
| void seat_focus_override_begin(struct seat *seat, enum input_mode input_mode,
 | |
| 	enum lab_cursors cursor_shape);
 | |
| /*
 | |
|  * Restore the pointer/keyboard focus which was cleared in
 | |
|  * seat_focus_override_begin().
 | |
|  */
 | |
| void seat_focus_override_end(struct seat *seat);
 | |
| 
 | |
| /**
 | |
|  * interactive_anchor_to_cursor() - repositions the geometry to remain
 | |
|  * underneath the cursor when its size changes during interactive move.
 | |
|  * This function also resizes server->grab_box and repositions it to remain
 | |
|  * underneath server->grab_{x,y}.
 | |
|  *
 | |
|  * geo->{width,height} are provided by the caller.
 | |
|  * geo->{x,y} are computed by this function.
 | |
|  */
 | |
| void interactive_anchor_to_cursor(struct server *server, struct wlr_box *geo);
 | |
| 
 | |
| void interactive_begin(struct view *view, enum input_mode mode,
 | |
| 	enum lab_edge edges);
 | |
| void interactive_finish(struct view *view);
 | |
| void interactive_cancel(struct view *view);
 | |
| 
 | |
| /**
 | |
|  * Returns the edge to snap a window to.
 | |
|  * For example, if the output-relative cursor position (x,y) fulfills
 | |
|  * x <= (<snapping><cornerRange>) and y <= (<snapping><range>),
 | |
|  * then edge1=LAB_EDGE_TOP and edge2=LAB_EDGE_LEFT.
 | |
|  * The value of (edge1|edge2) can be passed to view_snap_to_edge().
 | |
|  */
 | |
| bool edge_from_cursor(struct seat *seat, struct output **dest_output,
 | |
| 	enum lab_edge *edge1, enum lab_edge *edge2);
 | |
| 
 | |
| void handle_tearing_new_object(struct wl_listener *listener, void *data);
 | |
| 
 | |
| void server_init(struct server *server);
 | |
| void server_start(struct server *server);
 | |
| void server_finish(struct server *server);
 | |
| 
 | |
| void create_constraint(struct wl_listener *listener, void *data);
 | |
| void constrain_cursor(struct server *server, struct wlr_pointer_constraint_v1
 | |
| 	*constraint);
 | |
| 
 | |
| #endif /* LABWC_H */
 | 
