/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef LABWC_H #define LABWC_H #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cursor.h" #include "config/keybind.h" #include "config/rcxml.h" #include "regions.h" #include "session-lock.h" #if HAVE_NLS #include #include #define _ gettext #else #define _(s) (s) #endif #define XCURSOR_DEFAULT "left_ptr" #define XCURSOR_SIZE 24 #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif enum input_mode { LAB_INPUT_STATE_PASSTHROUGH = 0, LAB_INPUT_STATE_MOVE, LAB_INPUT_STATE_RESIZE, LAB_INPUT_STATE_MENU, }; struct input { struct wlr_input_device *wlr_input_device; struct seat *seat; struct wl_listener destroy; struct wl_list link; /* seat::inputs */ }; /* * Virtual keyboards should not belong to seat->keyboard_group. As a result we * need to be able to ascertain which wlr_keyboard key/modifer events come from * and we achieve that by using `struct keyboard` which inherits `struct input` * and adds keybord specific listeners and a wlr_keyboard pointer. */ struct keyboard { struct input base; struct wlr_keyboard *wlr_keyboard; bool is_virtual; struct wl_listener modifier; struct wl_listener key; /* key repeat for compositor keybinds */ uint32_t keybind_repeat_keycode; int32_t keybind_repeat_rate; struct wl_event_source *keybind_repeat; }; struct seat { struct wlr_seat *seat; struct server *server; struct wlr_keyboard_group *keyboard_group; /* * 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; struct wlr_cursor *cursor; struct wlr_xcursor_manager *xcursor_manager; struct { double x, y; } smooth_scroll_offset; struct wlr_pointer_constraint_v1 *current_constraint; struct wlr_idle *wlr_idle; struct wlr_idle_inhibit_manager_v1 *wlr_idle_inhibit_manager; /* In support for ToggleKeybinds */ bool inhibit_keybinds; /* 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; /** * pressed view/surface/node will usually be NULL and is only set on * button press while the mouse is over a view or surface, and reset * to NULL 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. * * Both (view && !surface) and (surface && !view) are possible. */ struct { struct view *view; struct wlr_scene_node *node; struct wlr_surface *surface; struct wlr_surface *toplevel; uint32_t resize_edges; } pressed; struct { bool active; struct { struct wl_listener request; struct wl_listener start; struct wl_listener destroy; } events; struct wlr_scene_tree *icons; } drag; /* Private use by regions.c */ struct region *region_active; struct region_overlay region_overlay; /* Used to prevent region snapping when starting a move with A-Left */ bool region_prevent_snap; struct wl_client *active_client_while_inhibited; struct wl_list inputs; struct wl_listener new_input; struct wl_listener cursor_motion; struct wl_listener cursor_motion_absolute; struct wl_listener cursor_button; struct wl_listener cursor_axis; struct wl_listener cursor_frame; 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 request_cursor; 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 constraint_commit; struct wl_listener idle_inhibitor_create; 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 virtual_keyboard_new; }; struct lab_data_buffer; struct workspace; 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 wlr_xdg_shell *xdg_shell; struct wlr_layer_shell_v1 *layer_shell; struct wl_listener new_xdg_surface; 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_ready; struct wl_listener xwayland_new_surface; #endif struct wlr_input_inhibit_manager *input_inhibit; struct wl_listener input_inhibit_activate; struct wl_listener input_inhibit_deactivate; struct wlr_xdg_activation_v1 *xdg_activation; struct wl_listener xdg_activation_request; struct wl_list views; struct wl_list unmanaged_surfaces; struct seat seat; struct wlr_scene *scene; /* cursor interactive */ enum input_mode input_mode; struct view *grabbed_view; double grab_x, grab_y; struct wlr_box grab_box; uint32_t resize_edges; /* SSD state */ struct view *focused_view; struct ssd_hover_state *ssd_hover_state; /* 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; #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 wl_list workspaces; /* struct workspace.link */ struct workspace *workspace_current; struct workspace *workspace_last; 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_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 session_lock *session_lock; struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; 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; /* 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; struct multi_rect *preview_outline; } osd_state; struct theme *theme; struct menu *menu_current; }; #define LAB_NR_LAYERS (4) struct output { struct wl_list link; /* server::outputs */ struct server *server; struct wlr_output *wlr_output; struct wlr_scene_output *scene_output; struct wlr_scene_tree *layer_tree[LAB_NR_LAYERS]; struct wlr_scene_tree *layer_popup_tree; struct wlr_scene_tree *osd_tree; struct wlr_scene_tree *session_lock_tree; struct wlr_scene_buffer *workspace_osd; struct wlr_box usable_area; struct wl_list regions; /* struct region.link */ struct lab_data_buffer *osd_buffer; struct wl_listener destroy; struct wl_listener frame; bool leased; }; #undef LAB_NR_LAYERS struct constraint { struct seat *seat; struct wlr_pointer_constraint_v1 *constraint; struct wl_listener destroy; }; struct idle_inhibitor { struct seat *seat; struct wlr_idle_inhibitor_v1 *wlr_inhibitor; struct wl_listener destroy; }; void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup); void xdg_activation_handle_request(struct wl_listener *listener, void *data); void xdg_surface_new(struct wl_listener *listener, void *data); void foreign_toplevel_handle_create(struct view *view); void foreign_toplevel_update_outputs(struct view *view); /* * 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. */ void desktop_focus_and_activate_view(struct seat *seat, struct view *view); void desktop_arrange_all_views(struct server *server); void desktop_focus_output(struct output *output); struct view *desktop_topmost_mapped_view(struct server *server); enum lab_cycle_dir { LAB_CYCLE_DIR_NONE, LAB_CYCLE_DIR_FORWARD, LAB_CYCLE_DIR_BACKWARD, }; /** * desktop_cycle_view - return view to 'cycle' to * @start_view: reference point for finding next view to cycle to * Note: If !start_view, the second focusable view is returned */ struct view *desktop_cycle_view(struct server *server, struct view *start_view, enum lab_cycle_dir dir); struct view *desktop_focused_view(struct server *server); void desktop_focus_topmost_mapped_view(struct server *server); bool isfocusable(struct view *view); void keyboard_cancel_keybind_repeat(struct keyboard *keyboard); void keyboard_key_notify(struct wl_listener *listener, void *data); void keyboard_modifiers_notify(struct wl_listener *listener, void *data); void keyboard_init(struct seat *seat); bool keyboard_any_modifiers_pressed(struct wlr_keyboard *keyboard); void keyboard_finish(struct seat *seat); void touch_init(struct seat *seat); void touch_finish(struct seat *seat); 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_set_focus_layer(struct seat *seat, struct wlr_layer_surface_v1 *layer); void seat_set_pressed(struct seat *seat, struct view *view, struct wlr_scene_node *node, struct wlr_surface *surface, struct wlr_surface *toplevel, uint32_t resize_edges); void seat_reset_pressed(struct seat *seat); void interactive_begin(struct view *view, enum input_mode mode, uint32_t edges); void interactive_finish(struct view *view); void interactive_cancel(struct view *view); void output_init(struct server *server); void output_manager_init(struct server *server); struct output *output_from_wlr_output(struct server *server, struct wlr_output *wlr_output); struct output *output_from_name(struct server *server, const char *name); struct output *output_nearest_to(struct server *server, int lx, int ly); struct output *output_nearest_to_cursor(struct server *server); bool output_is_usable(struct output *output); void output_update_usable_area(struct output *output); void output_update_all_usable_areas(struct server *server, bool layout_changed); struct wlr_box output_usable_area_in_layout_coords(struct output *output); void handle_output_power_manager_set_mode(struct wl_listener *listener, void *data); void server_init(struct server *server); void server_start(struct server *server); void server_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); /* Notify OSD about a destroying view */ void osd_on_view_destroy(struct view *view); /* * wlroots "input inhibitor" extension (required for swaylock) blocks * any client other than the requesting client from receiving events */ bool input_inhibit_blocks_surface(struct seat *seat, struct wl_resource *resource); void create_constraint(struct wl_listener *listener, void *data); void constrain_cursor(struct server *server, struct wlr_pointer_constraint_v1 *constraint); #endif /* LABWC_H */