labwc/include/labwc.h

500 lines
15 KiB
C
Raw Normal View History

2021-11-26 19:27:50 +00:00
/* SPDX-License-Identifier: GPL-2.0-only */
2020-08-03 20:56:38 +01:00
#ifndef __LABWC_H
#define __LABWC_H
2020-12-30 10:29:21 +00:00
#include "config.h"
2019-11-19 21:00:26 +00:00
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
2019-11-19 21:00:26 +00:00
#include <time.h>
#include <unistd.h>
#include <wayland-server-core.h>
#include <wlr/backend.h>
#include <wlr/render/allocator.h>
2019-11-19 21:00:26 +00:00
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_cursor.h>
2019-11-19 21:00:26 +00:00
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
2019-11-19 21:00:26 +00:00
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_layer_shell_v1.h>
2019-11-19 21:00:26 +00:00
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_management_v1.h>
2019-11-19 21:00:26 +00:00
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_scene.h>
2021-10-17 16:54:35 -04:00
#include <wlr/types/wlr_relative_pointer_v1.h>
2019-11-19 21:00:26 +00:00
#include <wlr/types/wlr_pointer.h>
2021-10-17 16:54:35 -04:00
#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_pointer_gestures_v1.h>
2019-11-19 21:00:26 +00:00
#include <wlr/types/wlr_seat.h>
2020-05-13 20:51:13 +01:00
#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_xcursor_manager.h>
2020-05-13 20:51:13 +01:00
#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_shell.h>
2019-11-19 21:00:26 +00:00
#include <wlr/util/log.h>
2020-12-30 10:29:21 +00:00
#if HAVE_XWAYLAND
2019-11-19 21:00:26 +00:00
#include <wlr/xwayland.h>
2020-12-30 10:29:21 +00:00
#endif
2019-11-19 21:00:26 +00:00
#include <xkbcommon/xkbcommon.h>
2020-08-03 20:56:38 +01:00
#include "config/keybind.h"
#include "config/rcxml.h"
#include "ssd.h"
2020-06-18 20:18:01 +01:00
2019-11-19 21:00:26 +00:00
#define XCURSOR_DEFAULT "left_ptr"
#define XCURSOR_SIZE 24
#define XCURSOR_MOVE "grabbing"
2020-10-21 20:30:06 +01:00
enum input_mode {
LAB_INPUT_STATE_PASSTHROUGH = 0,
LAB_INPUT_STATE_MOVE,
LAB_INPUT_STATE_RESIZE,
2020-10-19 22:14:17 +01:00
LAB_INPUT_STATE_MENU,
2019-11-19 21:00:26 +00:00
};
struct input {
struct wlr_input_device *wlr_input_device;
struct seat *seat;
struct wl_listener destroy;
struct wl_list link; /* seat::inputs */
};
struct seat {
struct wlr_seat *seat;
struct server *server;
struct wlr_keyboard_group *keyboard_group;
struct wlr_cursor *cursor;
struct wlr_xcursor_manager *xcursor_manager;
2021-10-03 13:33:38 -04:00
struct wlr_drag_icon *drag_icon;
2021-10-17 16:54:35 -04:00
struct wlr_pointer_constraint_v1 *current_constraint;
struct wlr_idle *wlr_idle;
struct wlr_idle_inhibit_manager_v1 *wlr_idle_inhibit_manager;
/* if set, views cannot receive focus */
struct wlr_layer_surface_v1 *focused_layer;
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;
2021-08-18 23:41:07 +01:00
struct wl_listener request_set_primary_selection;
struct wl_listener keyboard_key;
struct wl_listener keyboard_modifiers;
2021-10-03 13:33:38 -04:00
struct wl_listener request_start_drag;
struct wl_listener start_drag;
struct wl_listener destroy_drag;
2021-10-17 16:54:35 -04:00
struct wl_listener constraint_commit;
struct wl_listener idle_inhibitor_create;
};
struct lab_data_buffer;
2019-12-27 20:48:58 +00:00
struct server {
2019-11-19 21:00:26 +00:00
struct wl_display *wl_display;
struct wlr_renderer *renderer;
struct wlr_allocator *allocator;
2020-09-29 19:53:46 +01:00
struct wlr_backend *backend;
2019-11-19 21:00:26 +00:00
struct wlr_xdg_shell *xdg_shell;
struct wlr_layer_shell_v1 *layer_shell;
2019-11-19 21:00:26 +00:00
struct wl_listener new_xdg_surface;
struct wl_listener new_layer_surface;
2020-05-13 20:51:13 +01:00
struct wl_listener xdg_toplevel_decoration;
2020-12-30 10:29:21 +00:00
#if HAVE_XWAYLAND
2019-11-19 21:00:26 +00:00
struct wlr_xwayland *xwayland;
struct wl_listener new_xwayland_surface;
2020-12-30 10:29:21 +00:00
#endif
struct wlr_input_inhibit_manager *input_inhibit;
2021-09-22 20:24:02 +01:00
struct wl_listener input_inhibit_activate;
struct wl_listener input_inhibit_deactivate;
2019-11-19 21:00:26 +00:00
struct wl_list views;
struct wl_list unmanaged_surfaces;
2019-11-19 21:00:26 +00:00
struct seat seat;
struct wlr_scene *scene;
/* Tree for all non-layer xdg/xwayland-shell surfaces */
struct wlr_scene_tree *view_tree;
/* cursor interactive */
2020-10-21 20:30:06 +01:00
enum input_mode input_mode;
2019-12-27 20:48:58 +00:00
struct view *grabbed_view;
2019-11-19 21:00:26 +00:00
double grab_x, grab_y;
struct wlr_box grab_box;
2019-11-19 21:00:26 +00:00
uint32_t resize_edges;
struct wlr_scene_tree *osd_tree;
2019-11-19 21:00:26 +00:00
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;
struct wlr_output_configuration_v1 *pending_output_config;
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
2021-10-17 16:54:35 -04:00
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 view *cycle_view;
2020-10-19 22:14:17 +01:00
2021-02-21 21:54:40 +00:00
struct theme *theme;
2020-10-19 22:14:17 +01:00
struct menu *rootmenu;
2022-01-26 00:07:10 +01:00
struct menu *windowmenu;
2019-11-19 21:00:26 +00:00
};
2019-12-27 20:48:58 +00:00
struct output {
struct wl_list link; /* server::outputs */
2019-12-27 20:48:58 +00:00
struct server *server;
2019-11-19 21:00:26 +00:00
struct wlr_output *wlr_output;
struct wlr_scene_output *scene_output;
struct wl_list layers[4];
struct wlr_scene_tree *layer_tree[4];
struct wlr_box usable_area;
struct lab_data_buffer *osd_buffer;
2020-09-29 19:53:46 +01:00
struct wl_listener destroy;
struct wl_listener frame;
2019-11-19 21:00:26 +00:00
};
2020-12-30 10:29:21 +00:00
enum view_type {
LAB_XDG_SHELL_VIEW,
#if HAVE_XWAYLAND
LAB_XWAYLAND_VIEW,
#endif
};
2019-11-19 21:00:26 +00:00
struct view_impl {
void (*configure)(struct view *view, struct wlr_box geo);
2020-09-02 21:00:28 +01:00
void (*close)(struct view *view);
const char *(*get_string_prop)(struct view *view, const char *prop);
void (*map)(struct view *view);
2020-12-23 18:52:46 +00:00
void (*move)(struct view *view, double x, double y);
void (*set_activated)(struct view *view, bool activated);
void (*set_fullscreen)(struct view *view, bool fullscreen);
void (*unmap)(struct view *view);
void (*maximize)(struct view *view, bool maximize);
};
struct border {
int top;
int right;
int bottom;
int left;
};
2019-12-27 20:48:58 +00:00
struct view {
struct server *server;
2019-11-19 21:00:26 +00:00
enum view_type type;
const struct view_impl *impl;
2019-11-19 21:00:26 +00:00
struct wl_list link;
struct output *output;
union {
struct wlr_xdg_surface *xdg_surface;
2020-12-30 10:29:21 +00:00
#if HAVE_XWAYLAND
struct wlr_xwayland_surface *xwayland_surface;
2020-12-30 10:29:21 +00:00
#endif
};
2019-11-19 21:00:26 +00:00
struct wlr_surface *surface;
struct wlr_scene_tree *scene_tree;
struct wlr_scene_node *scene_node;
bool mapped;
bool been_mapped;
2020-09-07 19:47:11 +01:00
bool minimized;
bool maximized;
2021-08-23 22:05:30 +01:00
struct wlr_output *fullscreen;
/* geometry of the wlr_surface contained within the view */
int x, y, w, h;
2021-02-28 18:12:10 +00:00
/* geometry before maximize */
struct wlr_box unmaximized_geometry;
/*
* margin refers to the space between the extremities of the
* wlr_surface and the max extents of the server-side decorations.
* For xdg-shell views with CSD, this margin is zero.
*/
struct border margin;
/*
* padding refers to the space between the extremities of the
* wlr_surface and the parts of the surface that is considered the
* window.
* This is only used for xdg-shell views with CSD where the padding
* area is typically invisible except for client-side drop-shawdows.
*/
struct border padding;
struct {
bool update_x, update_y;
double x, y;
uint32_t width, height;
uint32_t configure_serial;
} pending_move_resize;
struct {
bool enabled;
struct wl_list parts;
struct wlr_box box; /* remember geo so we know when to update */
} ssd;
/* The title is unique to each view, so we store these here */
struct {
struct wlr_texture *active;
struct wlr_texture *inactive;
} title;
struct wlr_foreign_toplevel_handle_v1 *toplevel_handle;
2021-08-05 12:52:42 +01:00
struct wl_listener toplevel_handle_request_maximize;
2021-08-05 13:00:34 +01:00
struct wl_listener toplevel_handle_request_minimize;
2021-08-23 22:05:30 +01:00
struct wl_listener toplevel_handle_request_fullscreen;
2021-12-02 14:12:32 +00:00
struct wl_listener toplevel_handle_request_activate;
2021-12-23 12:24:24 +01:00
struct wl_listener toplevel_handle_request_close;
2019-11-19 21:00:26 +00:00
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener destroy;
struct wl_listener commit;
2019-11-19 21:00:26 +00:00
struct wl_listener request_move;
struct wl_listener request_resize;
struct wl_listener request_configure; /* xwayland only */
struct wl_listener request_activate;
struct wl_listener request_minimize;
struct wl_listener request_maximize;
2021-08-23 22:05:30 +01:00
struct wl_listener request_fullscreen;
struct wl_listener set_title;
struct wl_listener set_app_id; /* class on xwayland */
struct wl_listener set_decorations; /* xwayland only */
struct wl_listener new_popup; /* xdg-shell only */
2019-11-19 21:00:26 +00:00
};
2020-12-30 10:29:21 +00:00
#if HAVE_XWAYLAND
struct xwayland_unmanaged {
struct server *server;
struct wlr_xwayland_surface *xwayland_surface;
struct wl_list link;
int lx, ly;
struct wl_listener request_configure;
struct wl_listener commit;
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener destroy;
};
2020-12-30 10:29:21 +00:00
#endif
2021-10-17 16:54:35 -04:00
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);
2020-05-13 20:51:13 +01:00
void xdg_toplevel_decoration(struct wl_listener *listener, void *data);
2019-12-26 21:37:31 +00:00
void xdg_surface_new(struct wl_listener *listener, void *data);
2020-12-30 10:29:21 +00:00
#if HAVE_XWAYLAND
2020-09-04 20:32:41 +01:00
void xwayland_surface_new(struct wl_listener *listener, void *data);
void xwayland_unmanaged_create(struct server *server,
struct wlr_xwayland_surface *xsurface);
2020-12-30 10:29:21 +00:00
#endif
2019-12-26 21:37:31 +00:00
void view_set_activated(struct view *view, bool activated);
2021-12-23 12:24:24 +01:00
void view_close(struct view *view);
2021-10-23 22:31:39 -04:00
struct border view_border(struct view *view);
/**
* view_move_resize - resize and move view
* @view: view to be resized and moved
* @geo: the new geometry
* NOTE: Only use this when the view actually changes width and/or height
* otherwise the serials might cause a delay in moving xdg-shell clients.
* For move only, use view_move()
*/
2020-12-22 20:35:06 +00:00
void view_move_resize(struct view *view, struct wlr_box geo);
2020-12-23 18:52:46 +00:00
void view_move(struct view *view, double x, double y);
2021-08-05 13:00:34 +01:00
void view_minimize(struct view *view, bool minimized);
/* view_wlr_output - return the output that a view is mostly on */
struct wlr_output *view_wlr_output(struct view *view);
2021-07-09 21:39:20 +01:00
void view_center(struct view *view);
void view_maximize(struct view *view, bool maximize);
2021-08-23 22:05:30 +01:00
void view_set_fullscreen(struct view *view, bool fullscreen,
struct wlr_output *wlr_output);
2021-08-02 16:49:41 +01:00
void view_toggle_maximize(struct view *view);
void view_toggle_decorations(struct view *view);
void view_set_decorations(struct view *view, bool decorations);
void view_toggle_fullscreen(struct view *view);
Adjust views to account for output layout changes labwc currently doesn't handle output layout changes very well: - Windows can end up "lost" completely offscreen - Maximized/fullscreen windows can end up spanning multiple outputs Currently, new_output_notify() and output_destroy_notify() contain logic to update the cursor and force a repaint when outputs are added or removed. This logic in fact needs to run on any output layout change, so consolidate it into a new function, output_update_for_layout_change(). Then add a second new function, view_adjust_for_layout_change(), which adjusts window placement to account for the new layout. The behavior is roughly as follows: - Normal windows that end up offscreen are centered on the closest output (making use of the existing view_center() logic) - Maximized windows are re-maximized on the closest output. Logic is also added to the unmaximize step to check that the original unmaximized position is still on-screen. - Fullscreen windows are re-fullscreened on the same output if possible; otherwise they are un-fullscreened. Minimized windows don't require any special handling. Their placement is adjusted just the same, but invisible to the user until they are later unminimized. There is some positioning glitch still with un-fullscreening a window whose output has been disconnected/disabled; it can end up in an unexpected position (but at least has the correct size and decoration). I don't think this is due to a bug in my change per se, but perhaps the change has exposed a bug elsewhere. Fixes: #177
2021-12-31 17:30:55 -05:00
void view_adjust_for_layout_change(struct view *view);
void view_discover_output(struct view *view);
2021-07-20 20:24:39 +01:00
void view_move_to_edge(struct view *view, const char *direction);
void view_snap_to_edge(struct view *view, const char *direction);
2021-10-18 20:01:10 +01:00
const char *view_get_string_prop(struct view *view, const char *prop);
void view_update_title(struct view *view);
void view_update_app_id(struct view *view);
void view_impl_map(struct view *view);
void view_min_size(struct view *view, int *w, int *h);
void foreign_toplevel_handle_create(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_move_to_front(struct view *view);
void desktop_move_to_back(struct view *view);
void desktop_focus_and_activate_view(struct seat *seat, struct view *view);
2021-11-26 19:27:50 +00:00
enum lab_cycle_dir {
LAB_CYCLE_DIR_NONE,
LAB_CYCLE_DIR_FORWARD,
LAB_CYCLE_DIR_BACKWARD,
};
/**
2020-10-31 14:46:33 +00:00
* desktop_cycle_view - return view to 'cycle' to
* @current: reference point for finding next view to cycle to
* Note: If !current, the server->views second focusable view is returned
*/
2021-12-26 23:29:01 +00:00
struct view *desktop_cycle_view(struct server *server, struct view *current,
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);
/**
* desktop_node_and_view_at - find view and scene_node at (lx, ly)
* Note: If node points to layer-surface, view_area will be set
* to LAB_SSD_LAYER_SURFACE, if view points to another surface
* view_area will be LAB_SSD_CLIENT
*/
struct view *desktop_node_and_view_at(struct server *server, double lx,
double ly, struct wlr_scene_node **scene_node, double *sx, double *sy,
enum ssd_part_type *view_area);
2019-12-26 21:37:31 +00:00
struct view *desktop_view_at_cursor(struct server *server);
/**
* cursor_rebase - set cursor icon for and send motion-event to surface below it
* @seat - current seat
* @time_msec - time now
*/
void cursor_rebase(struct seat *seat, uint32_t time_msec);
/**
* cursor_set - set cursor icon
* @seat - current seat
* @cursor_name - name of cursor, for example "left_ptr" or "grab"
*/
void cursor_set(struct seat *seat, const char *cursor_name);
void cursor_init(struct seat *seat);
void cursor_finish(struct seat *seat);
2020-10-06 21:31:01 +01:00
void keyboard_init(struct seat *seat);
void keyboard_finish(struct seat *seat);
2020-10-06 21:31:01 +01:00
void arrange_layers(struct output *output);
void seat_init(struct server *server);
void seat_finish(struct server *server);
2021-10-10 12:03:18 -04:00
void seat_reconfigure(struct server *server);
2020-10-08 20:22:52 +01:00
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);
2020-10-21 20:30:06 +01:00
void interactive_begin(struct view *view, enum input_mode mode,
uint32_t edges);
void interactive_end(struct view *view);
2020-05-29 21:27:34 +01:00
void output_init(struct server *server);
2021-01-09 22:51:20 +00:00
void output_damage_surface(struct output *output, struct wlr_surface *surface,
double lx, double ly, bool whole);
2021-03-01 18:15:02 +00:00
void scale_box(struct wlr_box *box, float scale);
void output_manager_init(struct server *server);
2021-09-22 20:24:02 +01:00
struct output *output_from_wlr_output(struct server *server,
struct wlr_output *wlr_output);
struct wlr_box output_usable_area_in_layout_coords(struct output *output);
struct wlr_box output_usable_area_from_cursor_coords(struct server *server);
2021-01-09 22:51:20 +00:00
void damage_all_outputs(struct server *server);
void damage_view_whole(struct view *view);
void damage_view_part(struct view *view);
void server_init(struct server *server);
void server_start(struct server *server);
void server_finish(struct server *server);
2019-12-26 21:37:31 +00:00
/* update onscreen display 'alt-tab' buffer */
void osd_finish(struct server *server);
void osd_update(struct server *server);
2021-09-22 20:24:02 +01:00
/*
2021-08-25 19:59:49 +01:00
* 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,
2021-08-25 19:59:49 +01:00
struct wl_resource *resource);
2021-10-17 16:54:35 -04:00
void create_constraint(struct wl_listener *listener, void *data);
void constrain_cursor(struct server *server, struct wlr_pointer_constraint_v1
*constraint);
2020-08-03 20:56:38 +01:00
#endif /* __LABWC_H */