mirror of
https://github.com/swaywm/sway.git
synced 2024-11-24 08:51:27 +00:00
Merge branch 'master' into disable_titlebar
This commit is contained in:
commit
f8461bfe6d
|
@ -4,6 +4,7 @@ packages:
|
|||
- eudev-dev
|
||||
- gdk-pixbuf-dev
|
||||
- json-c-dev
|
||||
- lcms2-dev
|
||||
- libdisplay-info-dev
|
||||
- libevdev-dev
|
||||
- libinput-dev
|
||||
|
@ -38,9 +39,14 @@ tasks:
|
|||
cd sway
|
||||
ninja -C build
|
||||
- build-no-xwayland: |
|
||||
cd sway
|
||||
cd wlroots
|
||||
meson configure build -Dxwayland=disabled
|
||||
ninja -C build
|
||||
sudo ninja -C build install
|
||||
|
||||
cd ../sway
|
||||
meson configure build --clearcache
|
||||
ninja -C build
|
||||
- build-static: |
|
||||
cd sway
|
||||
mkdir subprojects
|
||||
|
|
|
@ -3,6 +3,7 @@ packages:
|
|||
- cairo
|
||||
- gdk-pixbuf2
|
||||
- json-c
|
||||
- lcms2
|
||||
- libdisplay-info
|
||||
- libegl
|
||||
- libinput
|
||||
|
|
|
@ -8,6 +8,7 @@ packages:
|
|||
- devel/pkgconf
|
||||
- graphics/cairo
|
||||
- graphics/gdk-pixbuf2
|
||||
- graphics/lcms2
|
||||
- graphics/wayland
|
||||
- graphics/wayland-protocols
|
||||
- textproc/scdoc
|
||||
|
|
|
@ -53,6 +53,8 @@ size_t escape_markup_text(const char *src, char *dest) {
|
|||
PangoLayout *get_pango_layout(cairo_t *cairo, const PangoFontDescription *desc,
|
||||
const char *text, double scale, bool markup) {
|
||||
PangoLayout *layout = pango_cairo_create_layout(cairo);
|
||||
pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false);
|
||||
|
||||
PangoAttrList *attrs;
|
||||
if (markup) {
|
||||
char *buf;
|
||||
|
@ -104,6 +106,7 @@ void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width,
|
|||
void get_text_metrics(const PangoFontDescription *description, int *height, int *baseline) {
|
||||
cairo_t *cairo = cairo_create(NULL);
|
||||
PangoContext *pango = pango_cairo_create_context(cairo);
|
||||
pango_context_set_round_glyph_positions(pango, false);
|
||||
// When passing NULL as a language, pango uses the current locale.
|
||||
PangoFontMetrics *metrics = pango_context_get_metrics(pango, description, NULL);
|
||||
|
||||
|
|
|
@ -250,6 +250,7 @@ sway_cmd input_cmd_seat;
|
|||
sway_cmd input_cmd_accel_profile;
|
||||
sway_cmd input_cmd_calibration_matrix;
|
||||
sway_cmd input_cmd_click_method;
|
||||
sway_cmd input_cmd_clickfinger_button_map;
|
||||
sway_cmd input_cmd_drag;
|
||||
sway_cmd input_cmd_drag_lock;
|
||||
sway_cmd input_cmd_dwt;
|
||||
|
@ -284,6 +285,7 @@ sway_cmd input_cmd_xkb_variant;
|
|||
|
||||
sway_cmd output_cmd_adaptive_sync;
|
||||
sway_cmd output_cmd_background;
|
||||
sway_cmd output_cmd_color_profile;
|
||||
sway_cmd output_cmd_disable;
|
||||
sway_cmd output_cmd_dpms;
|
||||
sway_cmd output_cmd_enable;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <wlr/interfaces/wlr_switch.h>
|
||||
#include <wlr/types/wlr_tablet_tool.h>
|
||||
#include <wlr/util/box.h>
|
||||
#include <wlr/render/color.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include "../include/config.h"
|
||||
|
@ -148,6 +149,7 @@ struct input_config {
|
|||
int accel_profile;
|
||||
struct calibration_matrix calibration_matrix;
|
||||
int click_method;
|
||||
int clickfinger_button_map;
|
||||
int drag;
|
||||
int drag_lock;
|
||||
int dwt;
|
||||
|
@ -285,6 +287,8 @@ struct output_config {
|
|||
int max_render_time; // In milliseconds
|
||||
int adaptive_sync;
|
||||
enum render_bit_depth render_bit_depth;
|
||||
bool set_color_transform;
|
||||
struct wlr_color_transform *color_transform;
|
||||
|
||||
char *background;
|
||||
char *background_option;
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
#include "list.h"
|
||||
#include "tree/view.h"
|
||||
|
||||
#if WLR_HAS_XWAYLAND
|
||||
#include "sway/xwayland.h"
|
||||
#endif
|
||||
|
||||
enum criteria_type {
|
||||
CT_COMMAND = 1 << 0,
|
||||
CT_ASSIGN_OUTPUT = 1 << 1,
|
||||
|
@ -36,7 +40,7 @@ struct criteria {
|
|||
struct pattern *app_id;
|
||||
struct pattern *con_mark;
|
||||
uint32_t con_id; // internal ID
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct pattern *class;
|
||||
uint32_t id; // X11 window ID
|
||||
struct pattern *instance;
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/types/wlr_transient_seat_v1.h>
|
||||
#include "sway/server.h"
|
||||
#include "sway/config.h"
|
||||
#include "list.h"
|
||||
|
||||
struct sway_server;
|
||||
|
||||
struct sway_input_device {
|
||||
char *identifier;
|
||||
struct wlr_input_device *wlr_device;
|
||||
|
|
|
@ -66,6 +66,8 @@ struct sway_output {
|
|||
struct wl_signal disable;
|
||||
} events;
|
||||
|
||||
struct wlr_color_transform *color_transform;
|
||||
|
||||
struct timespec last_presentation;
|
||||
uint32_t refresh_nsec;
|
||||
int max_render_time; // In milliseconds
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "config.h"
|
||||
#include "list.h"
|
||||
#include "sway/desktop/idle_inhibit_v1.h"
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
#include "sway/xwayland.h"
|
||||
#endif
|
||||
|
||||
|
@ -59,7 +59,7 @@ struct sway_server {
|
|||
|
||||
struct wlr_tablet_manager_v2 *tablet_v2;
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct sway_xwayland xwayland;
|
||||
struct wl_listener xwayland_surface;
|
||||
struct wl_listener xwayland_ready;
|
||||
|
@ -81,6 +81,8 @@ struct sway_server {
|
|||
struct wlr_pointer_constraints_v1 *pointer_constraints;
|
||||
struct wl_listener pointer_constraint;
|
||||
|
||||
struct wlr_xdg_output_manager_v1 *xdg_output_manager_v1;
|
||||
|
||||
struct wlr_output_manager_v1 *output_manager_v1;
|
||||
struct wl_listener output_manager_apply;
|
||||
struct wl_listener output_manager_test;
|
||||
|
@ -133,6 +135,8 @@ struct sway_server {
|
|||
// Stores the nodes that have been marked as "dirty" and will be put into
|
||||
// the pending transaction.
|
||||
list_t *dirty_nodes;
|
||||
|
||||
struct wl_event_source *delayed_modeset;
|
||||
};
|
||||
|
||||
extern struct sway_server server;
|
||||
|
@ -165,7 +169,7 @@ void sway_session_lock_add_output(struct sway_session_lock *lock,
|
|||
bool sway_session_lock_has_surface(struct sway_session_lock *lock,
|
||||
struct wlr_surface *surface);
|
||||
void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data);
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
void handle_xwayland_surface(struct wl_listener *listener, void *data);
|
||||
#endif
|
||||
void handle_server_decoration(struct wl_listener *listener, void *data);
|
||||
|
|
|
@ -175,8 +175,6 @@ struct sway_container *container_obstructing_fullscreen_container(struct sway_co
|
|||
bool container_has_ancestor(struct sway_container *container,
|
||||
struct sway_container *ancestor);
|
||||
|
||||
void container_update_textures_recursive(struct sway_container *con);
|
||||
|
||||
void container_reap_empty(struct sway_container *con);
|
||||
|
||||
struct sway_container *container_flatten(struct sway_container *container);
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
#define _SWAY_ROOT_H
|
||||
#include <wayland-server-core.h>
|
||||
#include <wayland-util.h>
|
||||
#include <wlr/config.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/render/wlr_texture.h>
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/node.h"
|
||||
#include "config.h"
|
||||
#include "list.h"
|
||||
|
||||
extern struct sway_root *root;
|
||||
|
@ -47,7 +47,7 @@ struct sway_root {
|
|||
struct wlr_scene_tree *shell_top;
|
||||
struct wlr_scene_tree *fullscreen;
|
||||
struct wlr_scene_tree *fullscreen_global;
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct wlr_scene_tree *unmanaged;
|
||||
#endif
|
||||
struct wlr_scene_tree *shell_overlay;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#ifndef _SWAY_VIEW_H
|
||||
#define _SWAY_VIEW_H
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/config.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include "sway/config.h"
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
#include <wlr/xwayland.h>
|
||||
#endif
|
||||
#include "sway/input/input-manager.h"
|
||||
|
@ -15,7 +16,7 @@ struct sway_xdg_decoration;
|
|||
|
||||
enum sway_view_type {
|
||||
SWAY_VIEW_XDG_SHELL,
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
SWAY_VIEW_XWAYLAND,
|
||||
#endif
|
||||
};
|
||||
|
@ -27,7 +28,7 @@ enum sway_view_prop {
|
|||
VIEW_PROP_INSTANCE,
|
||||
VIEW_PROP_WINDOW_TYPE,
|
||||
VIEW_PROP_WINDOW_ROLE,
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
VIEW_PROP_X11_WINDOW_ID,
|
||||
VIEW_PROP_X11_PARENT_ID,
|
||||
#endif
|
||||
|
@ -98,7 +99,7 @@ struct sway_view {
|
|||
|
||||
union {
|
||||
struct wlr_xdg_toplevel *wlr_xdg_toplevel;
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct wlr_xwayland_surface *wlr_xwayland_surface;
|
||||
#endif
|
||||
};
|
||||
|
@ -127,7 +128,7 @@ struct sway_xdg_shell_view {
|
|||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct sway_xwayland_view {
|
||||
struct sway_view view;
|
||||
|
||||
|
@ -293,7 +294,7 @@ void view_center_and_clip_surface(struct sway_view *view);
|
|||
|
||||
struct sway_view *view_from_wlr_xdg_surface(
|
||||
struct wlr_xdg_surface *xdg_surface);
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct sway_view *view_from_wlr_xwayland_surface(
|
||||
struct wlr_xwayland_surface *xsurface);
|
||||
#endif
|
||||
|
|
18
meson.build
18
meson.build
|
@ -45,7 +45,7 @@ subproject(
|
|||
required: false,
|
||||
version: wlroots_version,
|
||||
)
|
||||
wlroots = dependency('wlroots', version: wlroots_version)
|
||||
wlroots = dependency('wlroots-0.18', version: wlroots_version, fallback: 'wlroots')
|
||||
wlroots_features = {
|
||||
'xwayland': false,
|
||||
'libinput_backend': false,
|
||||
|
@ -57,10 +57,6 @@ foreach name, _ : wlroots_features
|
|||
wlroots_features += { name: have }
|
||||
endforeach
|
||||
|
||||
if get_option('xwayland').enabled() and not wlroots_features['xwayland']
|
||||
error('Cannot enable Xwayland in sway: wlroots has been built without Xwayland support')
|
||||
endif
|
||||
|
||||
null_dep = dependency('', required: false)
|
||||
|
||||
jsonc = dependency('json-c', version: '>=0.13')
|
||||
|
@ -68,7 +64,7 @@ pcre2 = dependency('libpcre2-8')
|
|||
wayland_server = dependency('wayland-server', version: '>=1.21.0')
|
||||
wayland_client = dependency('wayland-client')
|
||||
wayland_cursor = dependency('wayland-cursor')
|
||||
wayland_protos = dependency('wayland-protocols', version: '>=1.24')
|
||||
wayland_protos = dependency('wayland-protocols', version: '>=1.24', default_options: ['tests=false'])
|
||||
xkbcommon = dependency('xkbcommon', version: '>=1.5.0')
|
||||
cairo = dependency('cairo')
|
||||
pango = dependency('pango')
|
||||
|
@ -76,17 +72,15 @@ pangocairo = dependency('pangocairo')
|
|||
gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: get_option('gdk-pixbuf'))
|
||||
pixman = dependency('pixman-1')
|
||||
libevdev = dependency('libevdev')
|
||||
libinput = wlroots_features['libinput_backend'] ? dependency('libinput', version: '>=1.21.0') : null_dep
|
||||
xcb = dependency('xcb', required: get_option('xwayland'))
|
||||
libinput = wlroots_features['libinput_backend'] ? dependency('libinput', version: '>=1.26.0') : null_dep
|
||||
xcb = wlroots_features['xwayland'] ? dependency('xcb') : null_dep
|
||||
drm = dependency('libdrm')
|
||||
libudev = wlroots_features['libinput_backend'] ? dependency('libudev') : null_dep
|
||||
math = cc.find_library('m')
|
||||
rt = cc.find_library('rt')
|
||||
xcb_icccm = dependency('xcb-icccm', required: get_option('xwayland'))
|
||||
xcb_icccm = wlroots_features['xwayland'] ? dependency('xcb-icccm') : null_dep
|
||||
threads = dependency('threads') # for pthread_setschedparam
|
||||
|
||||
have_xwayland = xcb.found() and xcb_icccm.found() and wlroots_features['xwayland']
|
||||
|
||||
if get_option('sd-bus-provider') == 'auto'
|
||||
if not get_option('tray').disabled()
|
||||
assert(get_option('auto_features').auto(), 'sd-bus-provider must not be set to auto since auto_features != auto')
|
||||
|
@ -110,7 +104,6 @@ have_tray = (not get_option('tray').disabled()) and tray_deps_found
|
|||
|
||||
conf_data = configuration_data()
|
||||
|
||||
conf_data.set10('HAVE_XWAYLAND', have_xwayland)
|
||||
conf_data.set10('HAVE_GDK_PIXBUF', gdk_pixbuf.found())
|
||||
conf_data.set10('HAVE_LIBSYSTEMD', sdbus.found() and sdbus.name() == 'libsystemd')
|
||||
conf_data.set10('HAVE_LIBELOGIND', sdbus.found() and sdbus.name() == 'libelogind')
|
||||
|
@ -271,7 +264,6 @@ endif
|
|||
subdir('completions')
|
||||
|
||||
summary({
|
||||
'xwayland': have_xwayland,
|
||||
'gdk-pixbuf': gdk_pixbuf.found(),
|
||||
'tray': have_tray,
|
||||
'man-pages': scdoc.found(),
|
||||
|
|
|
@ -4,7 +4,6 @@ option('bash-completions', type: 'boolean', value: true, description: 'Install b
|
|||
option('fish-completions', type: 'boolean', value: true, description: 'Install fish shell completions.')
|
||||
option('swaybar', type: 'boolean', value: true, description: 'Enable support for swaybar')
|
||||
option('swaynag', type: 'boolean', value: true, description: 'Enable support for swaynag')
|
||||
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
||||
option('tray', type: 'feature', value: 'auto', description: 'Enable support for swaybar tray')
|
||||
option('gdk-pixbuf', type: 'feature', value: 'auto', description: 'Enable support for more image formats in swaybar tray')
|
||||
option('man-pages', type: 'feature', value: 'auto', description: 'Generate and install man pages')
|
||||
|
|
|
@ -7,10 +7,10 @@ wayland_scanner = find_program(
|
|||
)
|
||||
|
||||
protocols = [
|
||||
wl_protocol_dir / 'stable/tablet/tablet-v2.xml',
|
||||
wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
|
||||
wl_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
|
||||
wl_protocol_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
|
||||
wl_protocol_dir / 'unstable/tablet/tablet-unstable-v2.xml',
|
||||
wl_protocol_dir / 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml',
|
||||
wl_protocol_dir / 'staging/content-type/content-type-v1.xml',
|
||||
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||
|
|
|
@ -11,6 +11,7 @@ static const struct cmd_handler input_handlers[] = {
|
|||
{ "accel_profile", input_cmd_accel_profile },
|
||||
{ "calibration_matrix", input_cmd_calibration_matrix },
|
||||
{ "click_method", input_cmd_click_method },
|
||||
{ "clickfinger_button_map", input_cmd_clickfinger_button_map },
|
||||
{ "drag", input_cmd_drag },
|
||||
{ "drag_lock", input_cmd_drag_lock },
|
||||
{ "dwt", input_cmd_dwt },
|
||||
|
|
27
sway/commands/input/clickfinger_button_map.c
Normal file
27
sway/commands/input/clickfinger_button_map.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
|
||||
struct cmd_results *input_cmd_clickfinger_button_map(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "clickfinger_button_map", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct input_config *ic = config->handler_context.input_config;
|
||||
if (!ic) {
|
||||
return cmd_results_new(CMD_FAILURE, "No input device defined.");
|
||||
}
|
||||
|
||||
if (strcasecmp(argv[0], "lrm") == 0) {
|
||||
ic->clickfinger_button_map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM;
|
||||
} else if (strcasecmp(argv[0], "lmr") == 0) {
|
||||
ic->clickfinger_button_map = LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Expected 'clickfinger_button_map <lrm|lmr>'");
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/server.h"
|
||||
#include "log.h"
|
||||
|
||||
#if WLR_HAS_LIBINPUT_BACKEND
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/server.h"
|
||||
#include "log.h"
|
||||
|
||||
struct xkb_switch_layout_action {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "sway/input/seat.h"
|
||||
#include "sway/ipc-server.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/root.h"
|
||||
|
|
|
@ -10,6 +10,7 @@ static const struct cmd_handler output_handlers[] = {
|
|||
{ "adaptive_sync", output_cmd_adaptive_sync },
|
||||
{ "background", output_cmd_background },
|
||||
{ "bg", output_cmd_background },
|
||||
{ "color_profile", output_cmd_color_profile },
|
||||
{ "disable", output_cmd_disable },
|
||||
{ "dpms", output_cmd_dpms },
|
||||
{ "enable", output_cmd_enable },
|
||||
|
|
101
sway/commands/output/color_profile.c
Normal file
101
sway/commands/output/color_profile.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include <fcntl.h>
|
||||
#include <strings.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <wlr/render/color.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
|
||||
static bool read_file_into_buf(const char *path, void **buf, size_t *size) {
|
||||
/* Why not use fopen/fread directly? glibc will succesfully open directories,
|
||||
* not just files, and supports seeking on them. Instead, we directly
|
||||
* work with file descriptors and use the more consistent open/fstat/read. */
|
||||
int fd = open(path, O_RDONLY | O_NOCTTY | O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
char *b = NULL;
|
||||
struct stat info;
|
||||
if (fstat(fd, &info) == -1) {
|
||||
goto fail;
|
||||
}
|
||||
// only regular files, to avoid issues with e.g. opening pipes
|
||||
if (!S_ISREG(info.st_mode)) {
|
||||
goto fail;
|
||||
}
|
||||
off_t s = info.st_size;
|
||||
if (s <= 0) {
|
||||
goto fail;
|
||||
}
|
||||
b = calloc(1, s);
|
||||
if (!b) {
|
||||
goto fail;
|
||||
}
|
||||
size_t nread = 0;
|
||||
while (nread < (size_t)s) {
|
||||
size_t to_read = (size_t)s - nread;
|
||||
ssize_t r = read(fd, b + nread, to_read);
|
||||
if ((r == -1 && errno != EINTR) || r == 0) {
|
||||
goto fail;
|
||||
}
|
||||
nread += (size_t)r;
|
||||
}
|
||||
close(fd);
|
||||
*buf = b;
|
||||
*size = (size_t)s;
|
||||
return true; // success
|
||||
fail:
|
||||
free(b);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct cmd_results *output_cmd_color_profile(int argc, char **argv) {
|
||||
if (!config->handler_context.output_config) {
|
||||
return cmd_results_new(CMD_FAILURE, "Missing output config");
|
||||
}
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_INVALID, "Missing color_profile first argument.");
|
||||
}
|
||||
|
||||
if (strcmp(*argv, "srgb") == 0) {
|
||||
wlr_color_transform_unref(config->handler_context.output_config->color_transform);
|
||||
config->handler_context.output_config->color_transform = NULL;
|
||||
config->handler_context.output_config->set_color_transform = true;
|
||||
|
||||
config->handler_context.leftovers.argc = argc - 1;
|
||||
config->handler_context.leftovers.argv = argv + 1;
|
||||
} else if (strcmp(*argv, "icc") == 0) {
|
||||
if (argc < 2) {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Invalid color profile specification: icc type requires a file");
|
||||
}
|
||||
void *data = NULL;
|
||||
size_t size = 0;
|
||||
if (!read_file_into_buf(argv[1], &data, &size)) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Failed to load color profile: could not read ICC file");
|
||||
}
|
||||
|
||||
struct wlr_color_transform *tmp =
|
||||
wlr_color_transform_init_linear_to_icc(data, size);
|
||||
if (!tmp) {
|
||||
free(data);
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Failed to load color profile: failed to initialize transform from ICC");
|
||||
}
|
||||
free(data);
|
||||
|
||||
wlr_color_transform_unref(config->handler_context.output_config->color_transform);
|
||||
config->handler_context.output_config->color_transform = tmp;
|
||||
config->handler_context.output_config->set_color_transform = true;
|
||||
|
||||
config->handler_context.leftovers.argc = argc - 2;
|
||||
config->handler_context.leftovers.argv = argv + 2;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Invalid color profile specification: first argument should be icc|srgb");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
#include <wlr/types/wlr_pointer.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/server.h"
|
||||
|
||||
static struct cmd_results *press_or_release(struct sway_cursor *cursor,
|
||||
char *action, char *button_str);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "sway/config.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/server.h"
|
||||
|
||||
enum operation {
|
||||
OP_ENABLE,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/server.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct cmd_results *handle_action(struct seat_config *sc,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ static bool test_con_id(struct sway_container *container, void *data) {
|
|||
return container->node.id == *con_id;
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
static bool test_id(struct sway_container *container, void *data) {
|
||||
xcb_window_t *wid = data;
|
||||
return (container->view && container->view->type == SWAY_VIEW_XWAYLAND
|
||||
|
@ -53,7 +53,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
|
|||
|
||||
char *value = join_args(argv + 3, argc - 3);
|
||||
if (strcasecmp(argv[2], "id") == 0) {
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
xcb_window_t id = strtol(value, NULL, 0);
|
||||
other = root_find_container(test_id, &id);
|
||||
#endif
|
||||
|
|
|
@ -10,7 +10,7 @@ struct cmd_results *cmd_xwayland(int argc, char **argv) {
|
|||
return error;
|
||||
}
|
||||
|
||||
#ifdef HAVE_XWAYLAND
|
||||
#ifdef WLR_HAS_XWAYLAND
|
||||
enum xwayland_mode xwayland;
|
||||
if (strcmp(argv[0], "force") == 0) {
|
||||
xwayland = XWAYLAND_MODE_IMMEDIATE;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "sway/config.h"
|
||||
#include "sway/criteria.h"
|
||||
#include "sway/desktop/transaction.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/swaynag.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/root.h"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "sway/config.h"
|
||||
#include "sway/input/keyboard.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/server.h"
|
||||
#include "config.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <float.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/input/keyboard.h"
|
||||
#include "sway/server.h"
|
||||
#include "log.h"
|
||||
|
||||
struct input_config *new_input_config(const char* identifier) {
|
||||
|
@ -27,6 +28,7 @@ struct input_config *new_input_config(const char* identifier) {
|
|||
input->dwtp = INT_MIN;
|
||||
input->send_events = INT_MIN;
|
||||
input->click_method = INT_MIN;
|
||||
input->clickfinger_button_map = INT_MIN;
|
||||
input->middle_emulation = INT_MIN;
|
||||
input->natural_scroll = INT_MIN;
|
||||
input->accel_profile = INT_MIN;
|
||||
|
@ -54,6 +56,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) {
|
|||
if (src->click_method != INT_MIN) {
|
||||
dst->click_method = src->click_method;
|
||||
}
|
||||
if (src->clickfinger_button_map != INT_MIN) {
|
||||
dst->clickfinger_button_map = src->clickfinger_button_map;
|
||||
}
|
||||
if (src->drag != INT_MIN) {
|
||||
dst->drag = src->drag;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "sway/config.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/root.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
|
@ -75,6 +76,8 @@ struct output_config *new_output_config(const char *name) {
|
|||
oc->max_render_time = -1;
|
||||
oc->adaptive_sync = -1;
|
||||
oc->render_bit_depth = RENDER_BIT_DEPTH_DEFAULT;
|
||||
oc->set_color_transform = false;
|
||||
oc->color_transform = NULL;
|
||||
oc->power = -1;
|
||||
return oc;
|
||||
}
|
||||
|
@ -190,6 +193,14 @@ static void merge_output_config(struct output_config *dst, struct output_config
|
|||
if (src->render_bit_depth != RENDER_BIT_DEPTH_DEFAULT) {
|
||||
dst->render_bit_depth = src->render_bit_depth;
|
||||
}
|
||||
if (src->set_color_transform) {
|
||||
if (src->color_transform) {
|
||||
wlr_color_transform_ref(src->color_transform);
|
||||
}
|
||||
wlr_color_transform_unref(dst->color_transform);
|
||||
dst->set_color_transform = true;
|
||||
dst->color_transform = src->color_transform;
|
||||
}
|
||||
if (src->background) {
|
||||
free(dst->background);
|
||||
dst->background = strdup(src->background);
|
||||
|
@ -448,7 +459,7 @@ static void queue_output_config(struct output_config *oc,
|
|||
#endif
|
||||
}
|
||||
if (wlr_output->transform != tr) {
|
||||
sway_log(SWAY_DEBUG, "Set %s transform to %d", oc->name, tr);
|
||||
sway_log(SWAY_DEBUG, "Set %s transform to %d", wlr_output->name, tr);
|
||||
wlr_output_state_set_transform(pending, tr);
|
||||
}
|
||||
|
||||
|
@ -556,6 +567,13 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output
|
|||
output->max_render_time = oc->max_render_time;
|
||||
}
|
||||
|
||||
if (oc && oc->set_color_transform) {
|
||||
if (oc->color_transform) {
|
||||
wlr_color_transform_ref(oc->color_transform);
|
||||
}
|
||||
wlr_color_transform_unref(output->color_transform);
|
||||
output->color_transform = oc->color_transform;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -703,21 +721,18 @@ static bool search_adaptive_sync(struct search_context *ctx, size_t output_idx)
|
|||
struct wlr_backend_output_state *backend_state = &ctx->states[output_idx];
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
|
||||
if (!backend_state->output->adaptive_sync_supported) {
|
||||
return search_finish(ctx, output_idx);
|
||||
}
|
||||
|
||||
if (cfg->config && cfg->config->adaptive_sync == 1) {
|
||||
wlr_output_state_set_adaptive_sync_enabled(state, true);
|
||||
if (search_finish(ctx, output_idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!cfg->config || cfg->config->adaptive_sync != -1) {
|
||||
wlr_output_state_set_adaptive_sync_enabled(state, false);
|
||||
if (search_finish(ctx, output_idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// If adaptive sync has not been set, or fallback in case we are on a
|
||||
// backend that cannot disable adaptive sync such as the wayland backend.
|
||||
state->committed &= ~WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED;
|
||||
|
||||
wlr_output_state_set_adaptive_sync_enabled(state, false);
|
||||
return search_finish(ctx, output_idx);
|
||||
}
|
||||
|
||||
|
@ -909,6 +924,7 @@ bool apply_output_configs(struct matched_output_config *configs,
|
|||
struct wlr_scene_output_state_options opts = {
|
||||
.swapchain = wlr_output_swapchain_manager_get_swapchain(
|
||||
&swapchain_mgr, backend_state->output),
|
||||
.color_transform = cfg->output->color_transform,
|
||||
};
|
||||
struct wlr_scene_output *scene_output = cfg->output->scene_output;
|
||||
struct wlr_output_state *state = &backend_state->base;
|
||||
|
@ -996,6 +1012,7 @@ void free_output_config(struct output_config *oc) {
|
|||
free(oc->name);
|
||||
free(oc->background);
|
||||
free(oc->background_option);
|
||||
wlr_color_transform_unref(oc->color_transform);
|
||||
free(oc);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "sway/criteria.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/root.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
|
@ -22,7 +23,7 @@ bool criteria_is_empty(struct criteria *criteria) {
|
|||
&& !criteria->app_id
|
||||
&& !criteria->con_mark
|
||||
&& !criteria->con_id
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
&& !criteria->class
|
||||
&& !criteria->id
|
||||
&& !criteria->instance
|
||||
|
@ -90,7 +91,7 @@ void criteria_destroy(struct criteria *criteria) {
|
|||
pattern_destroy(criteria->title);
|
||||
pattern_destroy(criteria->shell);
|
||||
pattern_destroy(criteria->app_id);
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
pattern_destroy(criteria->class);
|
||||
pattern_destroy(criteria->instance);
|
||||
pattern_destroy(criteria->window_role);
|
||||
|
@ -110,7 +111,7 @@ static int regex_cmp(const char *item, const pcre2_code *regex) {
|
|||
return result;
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
static bool view_has_window_type(struct sway_view *view, enum atom_name name) {
|
||||
if (view->type != SWAY_VIEW_XWAYLAND) {
|
||||
return false;
|
||||
|
@ -251,7 +252,7 @@ static bool criteria_matches_view(struct criteria *criteria,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
if (criteria->id) { // X11 window ID
|
||||
uint32_t x11_window_id = view_get_x11_window_id(view);
|
||||
if (!x11_window_id || x11_window_id != criteria->id) {
|
||||
|
@ -428,7 +429,7 @@ list_t *criteria_get_containers(struct criteria *criteria) {
|
|||
return matches;
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
static enum atom_name parse_window_type(const char *type) {
|
||||
if (strcasecmp(type, "normal") == 0) {
|
||||
return NET_WM_WINDOW_TYPE_NORMAL;
|
||||
|
@ -461,7 +462,7 @@ enum criteria_token {
|
|||
T_CON_ID,
|
||||
T_CON_MARK,
|
||||
T_FLOATING,
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
T_CLASS,
|
||||
T_ID,
|
||||
T_INSTANCE,
|
||||
|
@ -487,7 +488,7 @@ static enum criteria_token token_from_name(char *name) {
|
|||
return T_CON_ID;
|
||||
} else if (strcmp(name, "con_mark") == 0) {
|
||||
return T_CON_MARK;
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
} else if (strcmp(name, "class") == 0) {
|
||||
return T_CLASS;
|
||||
} else if (strcmp(name, "id") == 0) {
|
||||
|
@ -566,7 +567,7 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) {
|
|||
case T_CON_MARK:
|
||||
pattern_create(&criteria->con_mark, value);
|
||||
break;
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
case T_CLASS:
|
||||
pattern_create(&criteria->class, value);
|
||||
break;
|
||||
|
@ -674,7 +675,7 @@ struct criteria *criteria_parse(char *raw, char **error_arg) {
|
|||
++head;
|
||||
|
||||
struct criteria *criteria = calloc(1, sizeof(struct criteria));
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
criteria->window_type = ATOM_LAST; // default value
|
||||
#endif
|
||||
char *name = NULL, *value = NULL;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "sway/input/seat.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/desktop/launcher.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/node.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
|
|
|
@ -243,13 +243,17 @@ static int output_repaint_timer_handler(void *data) {
|
|||
|
||||
output_configure_scene(output, &root->root_scene->tree.node, 1.0f);
|
||||
|
||||
if (output->gamma_lut_changed) {
|
||||
struct wlr_output_state pending;
|
||||
wlr_output_state_init(&pending);
|
||||
if (!wlr_scene_output_build_state(output->scene_output, &pending, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
struct wlr_scene_output_state_options opts = {
|
||||
.color_transform = output->color_transform,
|
||||
};
|
||||
|
||||
struct wlr_output_state pending;
|
||||
wlr_output_state_init(&pending);
|
||||
if (!wlr_scene_output_build_state(output->scene_output, &pending, &opts)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (output->gamma_lut_changed) {
|
||||
output->gamma_lut_changed = false;
|
||||
struct wlr_gamma_control_v1 *gamma_control =
|
||||
wlr_gamma_control_manager_v1_get_control(
|
||||
|
@ -259,17 +263,16 @@ static int output_repaint_timer_handler(void *data) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!wlr_output_commit_state(output->wlr_output, &pending)) {
|
||||
if (!wlr_output_test_state(output->wlr_output, &pending)) {
|
||||
wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
|
||||
wlr_output_state_finish(&pending);
|
||||
return 0;
|
||||
wlr_output_state_set_gamma_lut(&pending, 0, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
wlr_output_state_finish(&pending);
|
||||
return 0;
|
||||
}
|
||||
|
||||
wlr_scene_output_commit(output->scene_output, NULL);
|
||||
if (!wlr_output_commit_state(output->wlr_output, &pending)) {
|
||||
sway_log(SWAY_ERROR, "Page-flip failed on output %s", output->wlr_output->name);
|
||||
}
|
||||
wlr_output_state_finish(&pending);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -362,6 +365,26 @@ static void update_output_manager_config(struct sway_server *server) {
|
|||
ipc_event_output();
|
||||
}
|
||||
|
||||
static int timer_modeset_handle(void *data) {
|
||||
struct sway_server *server = data;
|
||||
wl_event_source_remove(server->delayed_modeset);
|
||||
server->delayed_modeset = NULL;
|
||||
|
||||
apply_all_output_configs();
|
||||
transaction_commit_dirty();
|
||||
update_output_manager_config(server);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void request_modeset(struct sway_server *server) {
|
||||
if (server->delayed_modeset == NULL) {
|
||||
server->delayed_modeset = wl_event_loop_add_timer(server->wl_event_loop,
|
||||
timer_modeset_handle, server);
|
||||
wl_event_source_timer_update(server->delayed_modeset, 10);
|
||||
}
|
||||
}
|
||||
|
||||
static void begin_destroy(struct sway_output *output) {
|
||||
struct sway_server *server = output->server;
|
||||
|
||||
|
@ -385,9 +408,7 @@ static void begin_destroy(struct sway_output *output) {
|
|||
output->wlr_output->data = NULL;
|
||||
output->wlr_output = NULL;
|
||||
|
||||
transaction_commit_dirty();
|
||||
|
||||
update_output_manager_config(server);
|
||||
request_modeset(server);
|
||||
}
|
||||
|
||||
static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||
|
@ -521,11 +542,7 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
|||
sway_session_lock_add_output(server->session_lock.lock, output);
|
||||
}
|
||||
|
||||
apply_all_output_configs();
|
||||
|
||||
transaction_commit_dirty();
|
||||
|
||||
update_output_manager_config(server);
|
||||
request_modeset(server);
|
||||
}
|
||||
|
||||
void handle_output_layout_change(struct wl_listener *listener,
|
||||
|
@ -677,5 +694,5 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener,
|
|||
break;
|
||||
}
|
||||
store_output_config(oc);
|
||||
apply_all_output_configs();
|
||||
request_modeset(output->server);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/node.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
@ -313,7 +314,7 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
|
||||
if (activated) {
|
||||
arrange_container(child, width, height - title_bar_height,
|
||||
false, 0);
|
||||
title_bar_height == 0, 0);
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
|
@ -342,7 +343,7 @@ static void arrange_children(enum sway_container_layout layout, list_t *children
|
|||
|
||||
if (activated) {
|
||||
arrange_container(child, width, height - title_height,
|
||||
false, 0);
|
||||
title_bar_height == 0, 0);
|
||||
} else {
|
||||
disable_container(child);
|
||||
}
|
||||
|
@ -761,7 +762,7 @@ static bool should_configure(struct sway_node *node,
|
|||
}
|
||||
struct sway_container_state *cstate = &node->sway_container->current;
|
||||
struct sway_container_state *istate = &instruction->container_state;
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
// Xwayland views are position-aware and need to be reconfigured
|
||||
// when their position changes.
|
||||
if (node->sway_container->view->type == SWAY_VIEW_XWAYLAND) {
|
||||
|
|
|
@ -289,6 +289,8 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
// XXX: https://github.com/swaywm/sway/issues/2176
|
||||
wlr_xdg_surface_schedule_configure(xdg_surface);
|
||||
wlr_xdg_toplevel_set_wm_capabilities(view->wlr_xdg_toplevel,
|
||||
XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
||||
// TODO: wlr_xdg_toplevel_set_bounds()
|
||||
return;
|
||||
}
|
||||
|
@ -575,7 +577,4 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) {
|
|||
wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base);
|
||||
|
||||
xdg_toplevel->base->data = xdg_shell_view;
|
||||
|
||||
wlr_xdg_toplevel_set_wm_capabilities(xdg_toplevel,
|
||||
XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "sway/layers.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/scene_descriptor.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/root.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
@ -107,7 +108,7 @@ struct sway_node *node_at_coords(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
if (scene_descriptor_try_get(current, SWAY_SCENE_DESC_XWAYLAND_UNMANAGED)) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "sway/input/seat.h"
|
||||
#include "sway/input/cursor.h"
|
||||
#include "sway/ipc-server.h"
|
||||
#include "sway/server.h"
|
||||
#include "log.h"
|
||||
|
||||
#if WLR_HAS_SESSION
|
||||
|
@ -508,12 +509,13 @@ static void handle_key_event(struct sway_keyboard *keyboard,
|
|||
}
|
||||
|
||||
if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||
// If the pressed event was sent to a client, also send the released
|
||||
// If the pressed event was sent to a client and we have a focused
|
||||
// surface immediately before this event, also send the released
|
||||
// event. In particular, don't send the released event to the IM grab.
|
||||
bool pressed_sent = update_shortcut_state(
|
||||
&keyboard->state_pressed_sent, event->keycode,
|
||||
event->state, keyinfo.keycode, 0);
|
||||
if (pressed_sent) {
|
||||
if (pressed_sent && seat->wlr_seat->keyboard_state.focused_surface) {
|
||||
wlr_seat_set_keyboard(wlr_seat, keyboard->wlr);
|
||||
wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
|
||||
event->keycode, event->state);
|
||||
|
@ -959,16 +961,8 @@ cleanup:
|
|||
free(sway_group);
|
||||
}
|
||||
|
||||
void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
||||
struct input_config *input_config =
|
||||
input_device_get_config(keyboard->seat_device->input_device);
|
||||
|
||||
if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr),
|
||||
"sway_keyboard_configure should not be called with a "
|
||||
"keyboard group's keyboard")) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void sway_keyboard_set_layout(struct sway_keyboard *keyboard,
|
||||
struct input_config *input_config) {
|
||||
struct xkb_keymap *keymap = sway_keyboard_compile_keymap(input_config, NULL);
|
||||
if (!keymap) {
|
||||
sway_log(SWAY_ERROR, "Failed to compile keymap. Attempting defaults");
|
||||
|
@ -984,31 +978,13 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
|||
!wlr_keyboard_keymaps_match(keyboard->keymap, keymap) : true;
|
||||
bool effective_layout_changed = keyboard->effective_layout != 0;
|
||||
|
||||
int repeat_rate = 25;
|
||||
if (input_config && input_config->repeat_rate != INT_MIN) {
|
||||
repeat_rate = input_config->repeat_rate;
|
||||
}
|
||||
int repeat_delay = 600;
|
||||
if (input_config && input_config->repeat_delay != INT_MIN) {
|
||||
repeat_delay = input_config->repeat_delay;
|
||||
}
|
||||
|
||||
bool repeat_info_changed = keyboard->repeat_rate != repeat_rate ||
|
||||
keyboard->repeat_delay != repeat_delay;
|
||||
|
||||
if (keymap_changed || repeat_info_changed || config->reloading) {
|
||||
if (keymap_changed || config->reloading) {
|
||||
xkb_keymap_unref(keyboard->keymap);
|
||||
keyboard->keymap = keymap;
|
||||
keyboard->effective_layout = 0;
|
||||
keyboard->repeat_rate = repeat_rate;
|
||||
keyboard->repeat_delay = repeat_delay;
|
||||
|
||||
sway_keyboard_group_remove_invalid(keyboard);
|
||||
|
||||
wlr_keyboard_set_keymap(keyboard->wlr, keyboard->keymap);
|
||||
wlr_keyboard_set_repeat_info(keyboard->wlr,
|
||||
keyboard->repeat_rate, keyboard->repeat_delay);
|
||||
|
||||
if (!keyboard->wlr->group) {
|
||||
sway_keyboard_group_add(keyboard);
|
||||
}
|
||||
|
@ -1059,6 +1035,49 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
|||
wlr_seat_set_keyboard(seat, keyboard->wlr);
|
||||
}
|
||||
|
||||
if (keymap_changed) {
|
||||
ipc_event_input("xkb_keymap",
|
||||
keyboard->seat_device->input_device);
|
||||
} else if (effective_layout_changed) {
|
||||
ipc_event_input("xkb_layout",
|
||||
keyboard->seat_device->input_device);
|
||||
}
|
||||
}
|
||||
|
||||
void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
||||
struct input_config *input_config =
|
||||
input_device_get_config(keyboard->seat_device->input_device);
|
||||
|
||||
if (!sway_assert(!wlr_keyboard_group_from_wlr_keyboard(keyboard->wlr),
|
||||
"sway_keyboard_configure should not be called with a "
|
||||
"keyboard group's keyboard")) {
|
||||
return;
|
||||
}
|
||||
|
||||
int repeat_rate = 25;
|
||||
if (input_config && input_config->repeat_rate != INT_MIN) {
|
||||
repeat_rate = input_config->repeat_rate;
|
||||
}
|
||||
int repeat_delay = 600;
|
||||
if (input_config && input_config->repeat_delay != INT_MIN) {
|
||||
repeat_delay = input_config->repeat_delay;
|
||||
}
|
||||
|
||||
bool repeat_info_changed = keyboard->repeat_rate != repeat_rate ||
|
||||
keyboard->repeat_delay != repeat_delay;
|
||||
|
||||
if (repeat_info_changed || config->reloading) {
|
||||
keyboard->repeat_rate = repeat_rate;
|
||||
keyboard->repeat_delay = repeat_delay;
|
||||
|
||||
wlr_keyboard_set_repeat_info(keyboard->wlr,
|
||||
keyboard->repeat_rate, keyboard->repeat_delay);
|
||||
}
|
||||
|
||||
if (!keyboard->seat_device->input_device->is_virtual) {
|
||||
sway_keyboard_set_layout(keyboard, input_config);
|
||||
}
|
||||
|
||||
wl_list_remove(&keyboard->keyboard_key.link);
|
||||
wl_signal_add(&keyboard->wlr->events.key, &keyboard->keyboard_key);
|
||||
keyboard->keyboard_key.notify = handle_keyboard_key;
|
||||
|
@ -1068,13 +1087,6 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
|
|||
&keyboard->keyboard_modifiers);
|
||||
keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers;
|
||||
|
||||
if (keymap_changed) {
|
||||
ipc_event_input("xkb_keymap",
|
||||
keyboard->seat_device->input_device);
|
||||
} else if (effective_layout_changed) {
|
||||
ipc_event_input("xkb_layout",
|
||||
keyboard->seat_device->input_device);
|
||||
}
|
||||
}
|
||||
|
||||
void sway_keyboard_destroy(struct sway_keyboard *keyboard) {
|
||||
|
|
|
@ -132,6 +132,16 @@ static bool set_click_method(struct libinput_device *device,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool set_clickfinger_button_map(struct libinput_device *device,
|
||||
enum libinput_config_clickfinger_button_map map) {
|
||||
if (libinput_device_config_click_get_clickfinger_button_map(device) == map) {
|
||||
return false;
|
||||
}
|
||||
sway_log(SWAY_DEBUG, "clickfinger_set_button_map(%d)", map);
|
||||
log_status(libinput_device_config_click_set_clickfinger_button_map(device, map));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool set_middle_emulation(struct libinput_device *dev,
|
||||
enum libinput_config_middle_emulation_state mid) {
|
||||
if (!libinput_device_config_middle_emulation_is_available(dev) ||
|
||||
|
@ -281,6 +291,9 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device
|
|||
if (ic->click_method != INT_MIN) {
|
||||
changed |= set_click_method(device, ic->click_method);
|
||||
}
|
||||
if (ic->clickfinger_button_map != INT_MIN) {
|
||||
changed |= set_clickfinger_button_map(device, ic->clickfinger_button_map);
|
||||
}
|
||||
if (ic->middle_emulation != INT_MIN) {
|
||||
changed |= set_middle_emulation(device, ic->middle_emulation);
|
||||
}
|
||||
|
@ -356,6 +369,8 @@ void sway_input_reset_libinput_device(struct sway_input_device *input_device) {
|
|||
libinput_device_config_left_handed_get_default(device));
|
||||
changed |= set_click_method(device,
|
||||
libinput_device_config_click_get_default_method(device));
|
||||
changed |= set_clickfinger_button_map(device,
|
||||
libinput_device_config_click_get_default_clickfinger_button_map(device));
|
||||
changed |= set_middle_emulation(device,
|
||||
libinput_device_config_middle_emulation_get_default_enabled(device));
|
||||
changed |= set_scroll_method(device,
|
||||
|
|
|
@ -190,7 +190,7 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) {
|
|||
node->sway_container->view : NULL;
|
||||
|
||||
if (view && seat_is_input_allowed(seat, view->surface)) {
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
if (view->type == SWAY_VIEW_XWAYLAND) {
|
||||
struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
|
||||
wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
|
||||
|
@ -802,11 +802,10 @@ static void seat_configure_keyboard(struct sway_seat *seat,
|
|||
return;
|
||||
}
|
||||
|
||||
// force notify reenter to pick up the new configuration. This reuses
|
||||
// Notify reenter to pick up the new configuration. This reuses
|
||||
// the current focused surface to avoid breaking input grabs.
|
||||
struct wlr_surface *surface = seat->wlr_seat->keyboard_state.focused_surface;
|
||||
if (surface) {
|
||||
wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat);
|
||||
seat_keyboard_notify_enter(seat, surface);
|
||||
}
|
||||
}
|
||||
|
@ -1002,7 +1001,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {
|
|||
setenv("XCURSOR_THEME", cursor_theme, 1);
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
if (server.xwayland.wlr_xwayland && (!server.xwayland.xcursor_manager ||
|
||||
!xcursor_manager_is_named(server.xwayland.xcursor_manager,
|
||||
cursor_theme) ||
|
||||
|
|
|
@ -11,11 +11,12 @@
|
|||
#include "sway/input/tablet.h"
|
||||
#include "sway/layers.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/scene_descriptor.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "log.h"
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
#include "sway/xwayland.h"
|
||||
#endif
|
||||
|
||||
|
@ -234,7 +235,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
|
|||
node->sway_container : NULL;
|
||||
|
||||
struct wlr_layer_surface_v1 *layer;
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct wlr_xwayland_surface *xsurface;
|
||||
#endif
|
||||
if ((layer = wlr_layer_surface_v1_try_from_wlr_surface(surface)) &&
|
||||
|
@ -268,7 +269,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
|
|||
seat_set_focus_container(seat, cont);
|
||||
seatop_begin_down(seat, node->sway_container, sx, sy);
|
||||
}
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
// Handle tapping on an xwayland unmanaged view
|
||||
else if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface)) &&
|
||||
xsurface->override_redirect &&
|
||||
|
@ -514,7 +515,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
|||
return;
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
// Handle clicking on xwayland unmanaged view
|
||||
struct wlr_xwayland_surface *xsurface;
|
||||
if (surface &&
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "sway/config.h"
|
||||
#include "sway/input/switch.h"
|
||||
#include "sway/server.h"
|
||||
#include "log.h"
|
||||
|
||||
struct sway_switch *sway_switch_create(struct sway_seat *seat,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/input/tablet.h"
|
||||
#include "sway/server.h"
|
||||
|
||||
#if WLR_HAS_LIBINPUT_BACKEND
|
||||
#include <wlr/backend/libinput.h>
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "sway/input/text_input.h"
|
||||
#include "sway/input/text_input_popup.h"
|
||||
#include "sway/layers.h"
|
||||
#include "sway/server.h"
|
||||
|
||||
static void input_popup_update(struct sway_input_popup *popup);
|
||||
|
||||
static struct sway_text_input *relay_get_focusable_text_input(
|
||||
|
@ -66,11 +68,13 @@ static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, void *
|
|||
struct sway_input_method_relay *relay = wl_container_of(listener, relay,
|
||||
input_method_keyboard_grab_destroy);
|
||||
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
|
||||
struct wlr_seat *wlr_seat = keyboard_grab->input_method->seat;
|
||||
wl_list_remove(&relay->input_method_keyboard_grab_destroy.link);
|
||||
|
||||
if (keyboard_grab->keyboard) {
|
||||
// send modifier state to original client
|
||||
wlr_seat_keyboard_notify_modifiers(keyboard_grab->input_method->seat,
|
||||
wlr_seat_set_keyboard(wlr_seat, keyboard_grab->keyboard);
|
||||
wlr_seat_keyboard_notify_modifiers(wlr_seat,
|
||||
&keyboard_grab->keyboard->modifiers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "log.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/ipc-json.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
|
@ -154,7 +155,7 @@ static json_object *ipc_json_output_mode_description(
|
|||
return mode_object;
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
static const char *ipc_json_xwindow_type_description(struct sway_view *view) {
|
||||
struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
|
||||
struct sway_xwayland *xwayland = &server.xwayland;
|
||||
|
@ -577,9 +578,10 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
|
|||
bool visible = view_is_visible(c->view);
|
||||
json_object_object_add(object, "visible", json_object_new_boolean(visible));
|
||||
|
||||
bool has_titlebar = c->title_bar.tree->node.enabled;
|
||||
struct wlr_box window_box = {
|
||||
c->pending.content_x - c->pending.x,
|
||||
(c->current.border == B_PIXEL) ? c->pending.content_y - c->pending.y : 0,
|
||||
has_titlebar ? 0 : c->pending.content_y - c->pending.y,
|
||||
c->pending.content_width,
|
||||
c->pending.content_height
|
||||
};
|
||||
|
@ -633,7 +635,7 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
|
|||
json_object_new_string(ipc_json_content_type_description(content_type)));
|
||||
}
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
if (c->view->type == SWAY_VIEW_XWAYLAND) {
|
||||
json_object_object_add(object, "window",
|
||||
json_object_new_int(view_get_x11_window_id(c->view)));
|
||||
|
@ -990,6 +992,18 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
|
|||
}
|
||||
json_object_object_add(object, "click_method",
|
||||
json_object_new_string(click_method));
|
||||
|
||||
const char *button_map = "unknown";
|
||||
switch (libinput_device_config_click_get_clickfinger_button_map(device)) {
|
||||
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM:
|
||||
button_map = "lrm";
|
||||
break;
|
||||
case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR:
|
||||
button_map = "lmr";
|
||||
break;
|
||||
}
|
||||
json_object_object_add(object, "clickfinger_button_map",
|
||||
json_object_new_string(button_map));
|
||||
}
|
||||
|
||||
if (libinput_device_config_middle_emulation_is_available(device)) {
|
||||
|
|
|
@ -155,6 +155,7 @@ sway_sources = files(
|
|||
'commands/input/accel_profile.c',
|
||||
'commands/input/calibration_matrix.c',
|
||||
'commands/input/click_method.c',
|
||||
'commands/input/clickfinger_button_map.c',
|
||||
'commands/input/drag.c',
|
||||
'commands/input/drag_lock.c',
|
||||
'commands/input/dwt.c',
|
||||
|
@ -203,6 +204,7 @@ sway_sources = files(
|
|||
'commands/output/toggle.c',
|
||||
'commands/output/transform.c',
|
||||
'commands/output/unplug.c',
|
||||
'commands/output/color_profile.c',
|
||||
|
||||
'tree/arrange.c',
|
||||
'tree/container.c',
|
||||
|
@ -232,7 +234,7 @@ sway_deps = [
|
|||
xcb_icccm,
|
||||
]
|
||||
|
||||
if have_xwayland
|
||||
if wlroots_features['xwayland']
|
||||
sway_sources += 'desktop/xwayland.c'
|
||||
endif
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include "sway/input/cursor.h"
|
||||
#include "sway/tree/root.h"
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
#include <wlr/xwayland/shell.h>
|
||||
#include "sway/xwayland.h"
|
||||
#endif
|
||||
|
@ -113,12 +113,13 @@ static bool is_privileged(const struct wl_global *global) {
|
|||
global == server.input->keyboard_shortcuts_inhibit->global ||
|
||||
global == server.input->virtual_keyboard->global ||
|
||||
global == server.input->virtual_pointer->global ||
|
||||
global == server.input->transient_seat_manager->global;
|
||||
global == server.input->transient_seat_manager->global ||
|
||||
global == server.xdg_output_manager_v1->global;
|
||||
}
|
||||
|
||||
static bool filter_global(const struct wl_client *client,
|
||||
const struct wl_global *global, void *data) {
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland;
|
||||
if (xwayland && global == xwayland->shell_v1->global) {
|
||||
return xwayland->server != NULL && client == xwayland->server->client;
|
||||
|
@ -275,7 +276,8 @@ bool server_init(struct sway_server *server) {
|
|||
wl_signal_add(&root->output_layout->events.change,
|
||||
&server->output_layout_change);
|
||||
|
||||
wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout);
|
||||
server->xdg_output_manager_v1 =
|
||||
wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout);
|
||||
|
||||
server->idle_notifier_v1 = wlr_idle_notifier_v1_create(server->wl_display);
|
||||
sway_idle_inhibit_manager_v1_init();
|
||||
|
@ -437,7 +439,7 @@ bool server_init(struct sway_server *server) {
|
|||
|
||||
void server_fini(struct sway_server *server) {
|
||||
// TODO: free sway-specific resources
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
wlr_xwayland_destroy(server->xwayland.wlr_xwayland);
|
||||
#endif
|
||||
wl_display_destroy_clients(server->wl_display);
|
||||
|
@ -447,7 +449,7 @@ void server_fini(struct sway_server *server) {
|
|||
}
|
||||
|
||||
bool server_start(struct sway_server *server) {
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
if (config->xwayland != XWAYLAND_MODE_DISABLED) {
|
||||
sway_log(SWAY_DEBUG, "Initializing Xwayland (lazy=%d)",
|
||||
config->xwayland == XWAYLAND_MODE_LAZY);
|
||||
|
|
|
@ -143,6 +143,12 @@ The following commands may only be used in the configuration file.
|
|||
*input* <identifier> click_method none|button_areas|clickfinger
|
||||
Changes the click method for the specified device.
|
||||
|
||||
*input* <identifier> clickfinger_button_map lrm|lmr
|
||||
Specifies which button mapping to use for clickfinger. _lrm_ treats 1 finger as
|
||||
left click, 2 fingers as right click, and 3 fingers as middle click. _lmr_
|
||||
treats 1 finger as left click, 2 fingers as middle click, and 3 fingers as
|
||||
right click.
|
||||
|
||||
*input* <identifier> drag enabled|disabled
|
||||
Enables or disables tap-and-drag for specified input device.
|
||||
|
||||
|
|
|
@ -1168,7 +1168,7 @@ following properties will be included for devices that support them:
|
|||
: Whether tap to click is enabled. It can be _enabled_ or _disabled_
|
||||
|- tap_button_map
|
||||
: string
|
||||
: The finger to button mapping in use. It can be _lmr_ or _lrm_
|
||||
: The finger to button mapping in use for tapping. It can be _lmr_ or _lrm_
|
||||
|- tap_drag
|
||||
: string
|
||||
: Whether tap-and-drag is enabled. It can be _enabled_ or _disabled_
|
||||
|
@ -1190,6 +1190,9 @@ following properties will be included for devices that support them:
|
|||
|- click_method
|
||||
: string
|
||||
: The click method in use. It can be _none_, _button_areas_, or _clickfinger_
|
||||
|- click_button_map
|
||||
: string
|
||||
: The finger to button mapping in use for clickfinger. It can be _lmr_ or _lrm_
|
||||
|- middle_emulation
|
||||
: string
|
||||
: Whether middle emulation is enabled. It can be _enabled_ or _disabled_
|
||||
|
|
|
@ -178,6 +178,18 @@ must be separated by one space. For example:
|
|||
updated to work with different bit depths. This command is experimental,
|
||||
and may be removed or changed in the future.
|
||||
|
||||
*output* <name> color_profile srgb|[icc <file>]
|
||||
Sets the color profile for an output. The default is _srgb_. <file> should be a
|
||||
path to a display ICC profile.
|
||||
|
||||
Not all renderers support this feature; currently it only works with the
|
||||
the Vulkan renderer. Even where supported, the application of the color
|
||||
profile may be inaccurate.
|
||||
|
||||
This command is experimental, and may be removed or changed in the future. It
|
||||
may have no effect or produce unexpected output when used together with future
|
||||
HDR support features.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
*sway*(5) *sway-input*(5)
|
||||
|
|
|
@ -294,6 +294,9 @@ void sway_text_node_set_text(struct sway_text_node *node, char *text) {
|
|||
|
||||
void sway_text_node_set_max_width(struct sway_text_node *node, int max_width) {
|
||||
struct text_buffer *buffer = wl_container_of(node, buffer, props);
|
||||
if (max_width == buffer->props.max_width) {
|
||||
return;
|
||||
}
|
||||
buffer->props.max_width = max_width;
|
||||
wlr_scene_buffer_set_dest_size(buffer->buffer_node,
|
||||
get_text_width(&buffer->props), buffer->props.height);
|
||||
|
@ -303,6 +306,9 @@ void sway_text_node_set_max_width(struct sway_text_node *node, int max_width) {
|
|||
|
||||
void sway_text_node_set_background(struct sway_text_node *node, float background[4]) {
|
||||
struct text_buffer *buffer = wl_container_of(node, buffer, props);
|
||||
if (memcmp(&node->background, background, sizeof(*background) * 4) == 0) {
|
||||
return;
|
||||
}
|
||||
memcpy(&node->background, background, sizeof(*background) * 4);
|
||||
render_backing_buffer(buffer);
|
||||
}
|
||||
|
|
|
@ -279,6 +279,7 @@ void output_destroy(struct sway_output *output) {
|
|||
list_free(output->workspaces);
|
||||
list_free(output->current.workspaces);
|
||||
wl_event_source_remove(output->repaint_timer);
|
||||
wlr_color_transform_unref(output->color_transform);
|
||||
free(output);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ struct sway_root *root_create(struct wl_display *wl_display) {
|
|||
root->layers.shell_top = alloc_scene_tree(root->layer_tree, &failed);
|
||||
root->layers.fullscreen = alloc_scene_tree(root->layer_tree, &failed);
|
||||
root->layers.fullscreen_global = alloc_scene_tree(root->layer_tree, &failed);
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
root->layers.unmanaged = alloc_scene_tree(root->layer_tree, &failed);
|
||||
#endif
|
||||
root->layers.shell_overlay = alloc_scene_tree(root->layer_tree, &failed);
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/config.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_buffer.h>
|
||||
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_fractional_scale_v1.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_server_decoration.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||
#include "config.h"
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
#include <wlr/xwayland.h>
|
||||
#endif
|
||||
#include "list.h"
|
||||
|
@ -126,7 +127,7 @@ const char *view_get_instance(struct sway_view *view) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
uint32_t view_get_x11_window_id(struct sway_view *view) {
|
||||
if (view->impl->get_int_prop) {
|
||||
return view->impl->get_int_prop(view, VIEW_PROP_X11_WINDOW_ID);
|
||||
|
@ -159,7 +160,7 @@ const char *view_get_shell(struct sway_view *view) {
|
|||
switch(view->type) {
|
||||
case SWAY_VIEW_XDG_SHELL:
|
||||
return "xdg_shell";
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
case SWAY_VIEW_XWAYLAND:
|
||||
return "xwayland";
|
||||
#endif
|
||||
|
@ -173,9 +174,9 @@ void view_get_constraints(struct sway_view *view, double *min_width,
|
|||
view->impl->get_constraints(view,
|
||||
min_width, max_width, min_height, max_height);
|
||||
} else {
|
||||
*min_width = DBL_MIN;
|
||||
*min_width = 1;
|
||||
*max_width = DBL_MAX;
|
||||
*min_height = DBL_MIN;
|
||||
*min_height = 1;
|
||||
*max_height = DBL_MAX;
|
||||
}
|
||||
}
|
||||
|
@ -365,8 +366,8 @@ void view_autoconfigure(struct sway_view *view) {
|
|||
|
||||
con->pending.content_x = x;
|
||||
con->pending.content_y = y;
|
||||
con->pending.content_width = width;
|
||||
con->pending.content_height = height;
|
||||
con->pending.content_width = fmax(width, 1);
|
||||
con->pending.content_height = fmax(height, 1);
|
||||
}
|
||||
|
||||
void view_set_activated(struct sway_view *view, bool activated) {
|
||||
|
@ -499,7 +500,7 @@ void view_execute_criteria(struct sway_view *view) {
|
|||
static void view_populate_pid(struct sway_view *view) {
|
||||
pid_t pid;
|
||||
switch (view->type) {
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
case SWAY_VIEW_XWAYLAND:;
|
||||
struct wlr_xwayland_surface *surf =
|
||||
wlr_xwayland_surface_try_from_wlr_surface(view->surface);
|
||||
|
@ -741,6 +742,14 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
|||
ws = select_workspace(view);
|
||||
}
|
||||
|
||||
if (ws && ws->output) {
|
||||
// Once the output is determined, we can notify the client early about
|
||||
// scale to reduce startup jitter.
|
||||
float scale = ws->output->wlr_output->scale;
|
||||
wlr_fractional_scale_v1_notify_scale(wlr_surface, scale);
|
||||
wlr_surface_set_preferred_buffer_scale(wlr_surface, ceil(scale));
|
||||
}
|
||||
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
struct sway_node *node =
|
||||
seat_get_focus_inactive(seat, ws ? &ws->node : &root->node);
|
||||
|
@ -838,7 +847,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
|||
|
||||
bool set_focus = should_focus(view);
|
||||
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct wlr_xwayland_surface *xsurface;
|
||||
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(wlr_surface))) {
|
||||
set_focus &= wlr_xwayland_icccm_input_model(xsurface) !=
|
||||
|
@ -927,11 +936,14 @@ void view_update_size(struct sway_view *view) {
|
|||
void view_center_and_clip_surface(struct sway_view *view) {
|
||||
struct sway_container *con = view->container;
|
||||
|
||||
bool clip_to_geometry = true;
|
||||
|
||||
if (container_is_floating(con)) {
|
||||
// We always center the current coordinates rather than the next, as the
|
||||
// geometry immediately affects the currently active rendering.
|
||||
int x = (int) fmax(0, (con->current.content_width - view->geometry.width) / 2);
|
||||
int y = (int) fmax(0, (con->current.content_height - view->geometry.height) / 2);
|
||||
clip_to_geometry = !view->using_csd;
|
||||
|
||||
wlr_scene_node_set_position(&view->content_tree->node, x, y);
|
||||
} else {
|
||||
|
@ -940,12 +952,16 @@ void view_center_and_clip_surface(struct sway_view *view) {
|
|||
|
||||
// only make sure to clip the content if there is content to clip
|
||||
if (!wl_list_empty(&con->view->content_tree->children)) {
|
||||
wlr_scene_subsurface_tree_set_clip(&con->view->content_tree->node, &(struct wlr_box){
|
||||
.x = con->view->geometry.x,
|
||||
.y = con->view->geometry.y,
|
||||
.width = con->current.content_width,
|
||||
.height = con->current.content_height,
|
||||
});
|
||||
struct wlr_box clip = {0};
|
||||
if (clip_to_geometry) {
|
||||
clip = (struct wlr_box){
|
||||
.x = con->view->geometry.x,
|
||||
.y = con->view->geometry.y,
|
||||
.width = con->current.content_width,
|
||||
.height = con->current.content_height,
|
||||
};
|
||||
}
|
||||
wlr_scene_subsurface_tree_set_clip(&con->view->content_tree->node, &clip);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -954,7 +970,7 @@ struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) {
|
|||
if ((xdg_surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface))) {
|
||||
return view_from_wlr_xdg_surface(xdg_surface);
|
||||
}
|
||||
#if HAVE_XWAYLAND
|
||||
#if WLR_HAS_XWAYLAND
|
||||
struct wlr_xwayland_surface *xsurface;
|
||||
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(wlr_surface))) {
|
||||
return view_from_wlr_xwayland_surface(xsurface);
|
||||
|
@ -1178,7 +1194,7 @@ void view_set_urgent(struct sway_view *view, bool enable) {
|
|||
|
||||
ipc_event_window(view->container, "urgent");
|
||||
|
||||
if (!container_is_scratchpad_hidden(view->container)) {
|
||||
if (!container_is_scratchpad_hidden_or_child(view->container)) {
|
||||
workspace_detect_urgent(view->container->pending.workspace);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "sway/input/seat.h"
|
||||
#include "sway/ipc-server.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/node.h"
|
||||
|
@ -707,6 +708,11 @@ void workspace_for_each_container(struct sway_workspace *ws,
|
|||
struct sway_container *workspace_find_container(struct sway_workspace *ws,
|
||||
bool (*test)(struct sway_container *con, void *data), void *data) {
|
||||
struct sway_container *result = NULL;
|
||||
if (ws == NULL){
|
||||
sway_log(SWAY_ERROR, "Cannot find container with no workspace.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Tiling
|
||||
for (int i = 0; i < ws->tiling->length; ++i) {
|
||||
struct sway_container *child = ws->tiling->items[i];
|
||||
|
|
|
@ -38,14 +38,14 @@ void xdg_activation_v1_handle_request_activate(struct wl_listener *listener,
|
|||
}
|
||||
|
||||
// This is an activation request. If this context is internal we have ctx->seat.
|
||||
struct sway_seat *seat = ctx->seat;
|
||||
if (!seat) {
|
||||
// Otherwise, use the seat indicated by the launcher client in set_serial
|
||||
seat = ctx->token->seat ? ctx->token->seat->data : NULL;
|
||||
if (ctx->seat) {
|
||||
view_request_activate(view, ctx->seat);
|
||||
return;
|
||||
}
|
||||
|
||||
if (seat && ctx->had_focused_surface) {
|
||||
view_request_activate(view, seat);
|
||||
// Otherwise, activate if passed from another focused client
|
||||
if (ctx->token->seat && ctx->had_focused_surface) {
|
||||
view_request_activate(view, ctx->token->seat->data);
|
||||
} else {
|
||||
// The token is valid, but cannot be used to activate a window
|
||||
view_request_urgent(view);
|
||||
|
|
Loading…
Reference in a new issue