mirror of
https://github.com/swaywm/sway.git
synced 2024-11-24 08:51:27 +00:00
Merge branch 'swaywm:master' into drag_mode
This commit is contained in:
commit
d4405b7349
|
@ -267,6 +267,7 @@ sway_cmd input_cmd_scroll_factor;
|
|||
sway_cmd input_cmd_repeat_delay;
|
||||
sway_cmd input_cmd_repeat_rate;
|
||||
sway_cmd input_cmd_scroll_button;
|
||||
sway_cmd input_cmd_scroll_button_lock;
|
||||
sway_cmd input_cmd_scroll_method;
|
||||
sway_cmd input_cmd_tap;
|
||||
sway_cmd input_cmd_tap_button_map;
|
||||
|
|
|
@ -161,6 +161,7 @@ struct input_config {
|
|||
int repeat_delay;
|
||||
int repeat_rate;
|
||||
int scroll_button;
|
||||
int scroll_button_lock;
|
||||
int scroll_method;
|
||||
int send_events;
|
||||
int tap;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_idle.h>
|
||||
#include "sway/server.h"
|
||||
|
||||
enum sway_idle_inhibit_mode {
|
||||
INHIBIT_IDLE_APPLICATION, // Application set inhibitor (when visible)
|
||||
|
@ -16,12 +15,9 @@ struct sway_idle_inhibit_manager_v1 {
|
|||
struct wlr_idle_inhibit_manager_v1 *wlr_manager;
|
||||
struct wl_listener new_idle_inhibitor_v1;
|
||||
struct wl_list inhibitors;
|
||||
|
||||
struct wlr_idle *idle;
|
||||
};
|
||||
|
||||
struct sway_idle_inhibitor_v1 {
|
||||
struct sway_idle_inhibit_manager_v1 *manager;
|
||||
struct wlr_idle_inhibitor_v1 *wlr_inhibitor;
|
||||
struct sway_view *view;
|
||||
enum sway_idle_inhibit_mode mode;
|
||||
|
@ -33,8 +29,7 @@ struct sway_idle_inhibitor_v1 {
|
|||
bool sway_idle_inhibit_v1_is_active(
|
||||
struct sway_idle_inhibitor_v1 *inhibitor);
|
||||
|
||||
void sway_idle_inhibit_v1_check_active(
|
||||
struct sway_idle_inhibit_manager_v1 *manager);
|
||||
void sway_idle_inhibit_v1_check_active(void);
|
||||
|
||||
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
||||
enum sway_idle_inhibit_mode mode);
|
||||
|
@ -48,6 +43,6 @@ struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_application_inhibitor_for_vi
|
|||
void sway_idle_inhibit_v1_user_inhibitor_destroy(
|
||||
struct sway_idle_inhibitor_v1 *inhibitor);
|
||||
|
||||
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
|
||||
struct wl_display *wl_display, struct wlr_idle *idle);
|
||||
bool sway_idle_inhibit_manager_v1_init(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,7 +35,6 @@ struct sway_cursor {
|
|||
pixman_region32_t confine; // invalid if active_constraint == NULL
|
||||
bool active_confine_requires_warp;
|
||||
|
||||
struct wlr_pointer_gestures_v1 *pointer_gestures;
|
||||
struct wl_listener hold_begin;
|
||||
struct wl_listener hold_end;
|
||||
struct wl_listener pinch_begin;
|
||||
|
@ -53,6 +52,7 @@ struct sway_cursor {
|
|||
|
||||
struct wl_listener touch_down;
|
||||
struct wl_listener touch_up;
|
||||
struct wl_listener touch_cancel;
|
||||
struct wl_listener touch_motion;
|
||||
struct wl_listener touch_frame;
|
||||
bool simulating_pointer_from_touch;
|
||||
|
|
|
@ -25,6 +25,7 @@ struct sway_input_manager {
|
|||
struct wlr_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
|
||||
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
|
||||
struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
|
||||
struct wlr_pointer_gestures_v1 *pointer_gestures;
|
||||
|
||||
struct wl_listener new_input;
|
||||
struct wl_listener inhibit_activate;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "sway/input/text_input.h"
|
||||
|
||||
struct sway_seat;
|
||||
struct render_context;
|
||||
|
||||
struct sway_seatop_impl {
|
||||
void (*button)(struct sway_seat *seat, uint32_t time_msec,
|
||||
|
@ -43,14 +44,15 @@ struct sway_seatop_impl {
|
|||
struct wlr_touch_up_event *event);
|
||||
void (*touch_down)(struct sway_seat *seat,
|
||||
struct wlr_touch_down_event *event, double lx, double ly);
|
||||
void (*touch_cancel)(struct sway_seat *seat,
|
||||
struct wlr_touch_cancel_event *event);
|
||||
void (*tablet_tool_motion)(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool, uint32_t time_msec);
|
||||
void (*tablet_tool_tip)(struct sway_seat *seat, struct sway_tablet_tool *tool,
|
||||
uint32_t time_msec, enum wlr_tablet_tool_tip_state state);
|
||||
void (*end)(struct sway_seat *seat);
|
||||
void (*unref)(struct sway_seat *seat, struct sway_container *con);
|
||||
void (*render)(struct sway_seat *seat, struct sway_output *output,
|
||||
const pixman_region32_t *damage);
|
||||
void (*render)(struct sway_seat *seat, struct render_context *ctx);
|
||||
bool allow_set_cursor;
|
||||
};
|
||||
|
||||
|
@ -102,8 +104,9 @@ struct sway_seat {
|
|||
struct sway_workspace *workspace;
|
||||
char *prev_workspace_name; // for workspace back_and_forth
|
||||
|
||||
// If the focused layer is set, views cannot receive keyboard focus
|
||||
struct wlr_layer_surface_v1 *focused_layer;
|
||||
// If the exclusive layer is set, views cannot receive keyboard focus
|
||||
bool has_exclusive_layer;
|
||||
|
||||
// If exclusive_client is set, no other clients will receive input events
|
||||
struct wl_client *exclusive_client;
|
||||
|
@ -338,6 +341,9 @@ void seatop_touch_up(struct sway_seat *seat,
|
|||
void seatop_touch_down(struct sway_seat *seat,
|
||||
struct wlr_touch_down_event *event, double lx, double ly);
|
||||
|
||||
void seatop_touch_cancel(struct sway_seat *seat,
|
||||
struct wlr_touch_cancel_event *event);
|
||||
|
||||
void seatop_rebase(struct sway_seat *seat, uint32_t time_msec);
|
||||
|
||||
/**
|
||||
|
@ -356,8 +362,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con);
|
|||
* Instructs a seatop to render anything that it needs to render
|
||||
* (eg. dropzone for move-tiling)
|
||||
*/
|
||||
void seatop_render(struct sway_seat *seat, struct sway_output *output,
|
||||
const pixman_region32_t *damage);
|
||||
void seatop_render(struct sway_seat *seat, struct render_context *ctx);
|
||||
|
||||
bool seatop_allows_set_cursor(struct sway_seat *seat);
|
||||
|
||||
|
|
|
@ -55,6 +55,10 @@ struct sway_layer_subsurface {
|
|||
};
|
||||
|
||||
struct sway_output;
|
||||
|
||||
struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
||||
struct wlr_surface *surface);
|
||||
|
||||
void arrange_layers(struct sway_output *output);
|
||||
|
||||
struct sway_layer_surface *layer_from_wlr_layer_surface_v1(
|
||||
|
|
|
@ -57,6 +57,7 @@ struct sway_output {
|
|||
uint32_t refresh_nsec;
|
||||
int max_render_time; // In milliseconds
|
||||
struct wl_event_source *repaint_timer;
|
||||
bool gamma_lut_changed;
|
||||
};
|
||||
|
||||
struct sway_output_non_desktop {
|
||||
|
@ -65,6 +66,14 @@ struct sway_output_non_desktop {
|
|||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct render_context {
|
||||
struct sway_output *output;
|
||||
struct wlr_renderer *renderer;
|
||||
const pixman_region32_t *output_damage;
|
||||
|
||||
struct wlr_render_pass *pass;
|
||||
};
|
||||
|
||||
struct sway_output *output_create(struct wlr_output *wlr_output);
|
||||
|
||||
void output_destroy(struct sway_output *output);
|
||||
|
@ -115,7 +124,7 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output);
|
|||
|
||||
struct sway_workspace *output_get_active_workspace(struct sway_output *output);
|
||||
|
||||
void output_render(struct sway_output *output, pixman_region32_t *damage);
|
||||
void output_render(struct render_context *ctx);
|
||||
|
||||
void output_surface_for_each_surface(struct sway_output *output,
|
||||
struct wlr_surface *surface, double ox, double oy,
|
||||
|
@ -168,8 +177,7 @@ void output_get_box(struct sway_output *output, struct wlr_box *box);
|
|||
enum sway_container_layout output_get_default_layout(
|
||||
struct sway_output *output);
|
||||
|
||||
void render_rect(struct sway_output *output,
|
||||
const pixman_region32_t *output_damage, const struct wlr_box *_box,
|
||||
void render_rect(struct render_context *ctx, const struct wlr_box *_box,
|
||||
float color[static 4]);
|
||||
|
||||
void premultiply_alpha(float color[4], float opacity);
|
||||
|
@ -180,6 +188,8 @@ enum wlr_direction opposite_direction(enum wlr_direction d);
|
|||
|
||||
void handle_output_layout_change(struct wl_listener *listener, void *data);
|
||||
|
||||
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data);
|
||||
|
||||
void handle_output_manager_apply(struct wl_listener *listener, void *data);
|
||||
|
||||
void handle_output_manager_test(struct wl_listener *listener, void *data);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include "config.h"
|
||||
#include "list.h"
|
||||
#include "sway/desktop/idle_inhibit_v1.h"
|
||||
#if HAVE_XWAYLAND
|
||||
#include "sway/xwayland.h"
|
||||
#endif
|
||||
|
@ -53,7 +54,7 @@ struct sway_server {
|
|||
|
||||
struct wlr_idle *idle;
|
||||
struct wlr_idle_notifier_v1 *idle_notifier_v1;
|
||||
struct sway_idle_inhibit_manager_v1 *idle_inhibit_manager_v1;
|
||||
struct sway_idle_inhibit_manager_v1 idle_inhibit_manager_v1;
|
||||
|
||||
struct wlr_layer_shell_v1 *layer_shell;
|
||||
struct wl_listener layer_shell_surface;
|
||||
|
@ -91,6 +92,9 @@ struct sway_server {
|
|||
struct wl_listener output_manager_apply;
|
||||
struct wl_listener output_manager_test;
|
||||
|
||||
struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1;
|
||||
struct wl_listener gamma_control_set_gamma;
|
||||
|
||||
struct {
|
||||
bool locked;
|
||||
struct wlr_session_lock_manager_v1 *manager;
|
||||
|
|
|
@ -160,6 +160,8 @@ struct sway_xwayland_view {
|
|||
struct wl_listener set_window_type;
|
||||
struct wl_listener set_hints;
|
||||
struct wl_listener set_decorations;
|
||||
struct wl_listener associate;
|
||||
struct wl_listener dissociate;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
|
@ -177,6 +179,8 @@ struct sway_xwayland_unmanaged {
|
|||
struct wl_listener request_fullscreen;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener set_geometry;
|
||||
struct wl_listener associate;
|
||||
struct wl_listener dissociate;
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
|
|
|
@ -48,7 +48,6 @@ wlroots = dependency('wlroots', version: wlroots_version)
|
|||
wlroots_features = {
|
||||
'xwayland': false,
|
||||
'libinput_backend': false,
|
||||
'gles2_renderer': false,
|
||||
'session': false,
|
||||
}
|
||||
foreach name, _ : wlroots_features
|
||||
|
@ -75,7 +74,6 @@ pango = dependency('pango')
|
|||
pangocairo = dependency('pangocairo')
|
||||
gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: get_option('gdk-pixbuf'))
|
||||
pixman = dependency('pixman-1')
|
||||
glesv2 = wlroots_features['gles2_renderer'] ? dependency('glesv2') : null_dep
|
||||
libevdev = dependency('libevdev')
|
||||
libinput = wlroots_features['libinput_backend'] ? dependency('libinput', version: '>=1.21.0') : null_dep
|
||||
xcb = dependency('xcb', required: get_option('xwayland'))
|
||||
|
|
|
@ -41,7 +41,7 @@ struct cmd_results *cmd_inhibit_idle(int argc, char **argv) {
|
|||
sway_idle_inhibit_v1_user_inhibitor_destroy(inhibitor);
|
||||
} else {
|
||||
inhibitor->mode = mode;
|
||||
sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
|
||||
sway_idle_inhibit_v1_check_active();
|
||||
}
|
||||
} else if (!clear) {
|
||||
sway_idle_inhibit_v1_user_inhibitor_register(con->view, mode);
|
||||
|
|
|
@ -27,6 +27,7 @@ static const struct cmd_handler input_handlers[] = {
|
|||
{ "repeat_rate", input_cmd_repeat_rate },
|
||||
{ "rotation_angle", input_cmd_rotation_angle },
|
||||
{ "scroll_button", input_cmd_scroll_button },
|
||||
{ "scroll_button_lock", input_cmd_scroll_button_lock },
|
||||
{ "scroll_factor", input_cmd_scroll_factor },
|
||||
{ "scroll_method", input_cmd_scroll_method },
|
||||
{ "tap", input_cmd_tap },
|
||||
|
|
26
sway/commands/input/scroll_button_lock.c
Normal file
26
sway/commands/input/scroll_button_lock.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include <libinput.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "util.h"
|
||||
|
||||
struct cmd_results *input_cmd_scroll_button_lock(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "scroll_button_lock", 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 (parse_boolean(argv[0], true)) {
|
||||
ic->scroll_button_lock = LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED;
|
||||
} else {
|
||||
ic->scroll_button_lock = LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED;
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
|
@ -35,6 +35,7 @@ struct input_config *new_input_config(const char* identifier) {
|
|||
input->pointer_accel = FLT_MIN;
|
||||
input->scroll_factor = FLT_MIN;
|
||||
input->scroll_button = INT_MIN;
|
||||
input->scroll_button_lock = INT_MIN;
|
||||
input->scroll_method = INT_MIN;
|
||||
input->left_handed = INT_MIN;
|
||||
input->repeat_delay = INT_MIN;
|
||||
|
@ -96,6 +97,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) {
|
|||
if (src->scroll_button != INT_MIN) {
|
||||
dst->scroll_button = src->scroll_button;
|
||||
}
|
||||
if (src->scroll_button_lock != INT_MIN) {
|
||||
dst->scroll_button_lock = src->scroll_button_lock;
|
||||
}
|
||||
if (src->send_events != INT_MIN) {
|
||||
dst->send_events = src->send_events;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
static void destroy_inhibitor(struct sway_idle_inhibitor_v1 *inhibitor) {
|
||||
wl_list_remove(&inhibitor->link);
|
||||
wl_list_remove(&inhibitor->destroy.link);
|
||||
sway_idle_inhibit_v1_check_active(inhibitor->manager);
|
||||
sway_idle_inhibit_v1_check_active();
|
||||
free(inhibitor);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,6 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
inhibitor->manager = manager;
|
||||
inhibitor->mode = INHIBIT_IDLE_APPLICATION;
|
||||
inhibitor->wlr_inhibitor = wlr_inhibitor;
|
||||
wl_list_insert(&manager->inhibitors, &inhibitor->link);
|
||||
|
@ -43,33 +42,34 @@ void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
|
|||
inhibitor->destroy.notify = handle_destroy;
|
||||
wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->destroy);
|
||||
|
||||
sway_idle_inhibit_v1_check_active(manager);
|
||||
sway_idle_inhibit_v1_check_active();
|
||||
}
|
||||
|
||||
void sway_idle_inhibit_v1_user_inhibitor_register(struct sway_view *view,
|
||||
enum sway_idle_inhibit_mode mode) {
|
||||
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||
|
||||
struct sway_idle_inhibitor_v1 *inhibitor =
|
||||
calloc(1, sizeof(struct sway_idle_inhibitor_v1));
|
||||
if (!inhibitor) {
|
||||
return;
|
||||
}
|
||||
|
||||
inhibitor->manager = server.idle_inhibit_manager_v1;
|
||||
inhibitor->mode = mode;
|
||||
inhibitor->view = view;
|
||||
wl_list_insert(&inhibitor->manager->inhibitors, &inhibitor->link);
|
||||
wl_list_insert(&manager->inhibitors, &inhibitor->link);
|
||||
|
||||
inhibitor->destroy.notify = handle_destroy;
|
||||
wl_signal_add(&view->events.unmap, &inhibitor->destroy);
|
||||
|
||||
sway_idle_inhibit_v1_check_active(inhibitor->manager);
|
||||
sway_idle_inhibit_v1_check_active();
|
||||
}
|
||||
|
||||
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
|
||||
struct sway_view *view) {
|
||||
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||
struct sway_idle_inhibitor_v1 *inhibitor;
|
||||
wl_list_for_each(inhibitor, &server.idle_inhibit_manager_v1->inhibitors,
|
||||
link) {
|
||||
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
|
||||
if (inhibitor->mode != INHIBIT_IDLE_APPLICATION &&
|
||||
inhibitor->view == view) {
|
||||
return inhibitor;
|
||||
|
@ -80,9 +80,9 @@ struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_user_inhibitor_for_view(
|
|||
|
||||
struct sway_idle_inhibitor_v1 *sway_idle_inhibit_v1_application_inhibitor_for_view(
|
||||
struct sway_view *view) {
|
||||
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||
struct sway_idle_inhibitor_v1 *inhibitor;
|
||||
wl_list_for_each(inhibitor, &server.idle_inhibit_manager_v1->inhibitors,
|
||||
link) {
|
||||
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
|
||||
if (inhibitor->mode == INHIBIT_IDLE_APPLICATION &&
|
||||
view_from_wlr_surface(inhibitor->wlr_inhibitor->surface) == view) {
|
||||
return inhibitor;
|
||||
|
@ -131,8 +131,8 @@ bool sway_idle_inhibit_v1_is_active(struct sway_idle_inhibitor_v1 *inhibitor) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void sway_idle_inhibit_v1_check_active(
|
||||
struct sway_idle_inhibit_manager_v1 *manager) {
|
||||
void sway_idle_inhibit_v1_check_active(void) {
|
||||
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||
struct sway_idle_inhibitor_v1 *inhibitor;
|
||||
bool inhibited = false;
|
||||
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
|
||||
|
@ -140,28 +140,22 @@ void sway_idle_inhibit_v1_check_active(
|
|||
break;
|
||||
}
|
||||
}
|
||||
wlr_idle_set_enabled(manager->idle, NULL, !inhibited);
|
||||
wlr_idle_set_enabled(server.idle, NULL, !inhibited);
|
||||
wlr_idle_notifier_v1_set_inhibited(server.idle_notifier_v1, inhibited);
|
||||
}
|
||||
|
||||
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
|
||||
struct wl_display *wl_display, struct wlr_idle *idle) {
|
||||
struct sway_idle_inhibit_manager_v1 *manager =
|
||||
calloc(1, sizeof(struct sway_idle_inhibit_manager_v1));
|
||||
if (!manager) {
|
||||
return NULL;
|
||||
bool sway_idle_inhibit_manager_v1_init(void) {
|
||||
struct sway_idle_inhibit_manager_v1 *manager = &server.idle_inhibit_manager_v1;
|
||||
|
||||
manager->wlr_manager = wlr_idle_inhibit_v1_create(server.wl_display);
|
||||
if (!manager->wlr_manager) {
|
||||
return false;
|
||||
}
|
||||
|
||||
manager->wlr_manager = wlr_idle_inhibit_v1_create(wl_display);
|
||||
if (!manager->wlr_manager) {
|
||||
free(manager);
|
||||
return NULL;
|
||||
}
|
||||
manager->idle = idle;
|
||||
wl_signal_add(&manager->wlr_manager->events.new_inhibitor,
|
||||
&manager->new_idle_inhibitor_v1);
|
||||
manager->new_idle_inhibitor_v1.notify = handle_idle_inhibitor_v1;
|
||||
wl_list_init(&manager->inhibitors);
|
||||
|
||||
return manager;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,39 @@
|
|||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
|
||||
struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
||||
struct wlr_surface *surface) {
|
||||
struct wlr_layer_surface_v1 *layer;
|
||||
do {
|
||||
if (!surface) {
|
||||
return NULL;
|
||||
}
|
||||
// Topmost layer surface
|
||||
if ((layer = wlr_layer_surface_v1_try_from_wlr_surface(surface))) {
|
||||
return layer;
|
||||
}
|
||||
// Layer subsurface
|
||||
if (wlr_subsurface_try_from_wlr_surface(surface)) {
|
||||
surface = wlr_surface_get_root_surface(surface);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Layer surface popup
|
||||
struct wlr_xdg_surface * xdg_popup = NULL;
|
||||
if ((xdg_popup = wlr_xdg_surface_try_from_wlr_surface(surface)) &&
|
||||
xdg_popup->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
||||
if (!xdg_popup->popup->parent) {
|
||||
return NULL;
|
||||
}
|
||||
surface = wlr_surface_get_root_surface(xdg_popup->popup->parent);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Return early if the surface is not a layer/xdg_popup/sub surface
|
||||
return NULL;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
static void apply_exclusive(struct wlr_box *usable_area,
|
||||
uint32_t anchor, int32_t exclusive,
|
||||
int32_t margin_top, int32_t margin_right,
|
||||
|
@ -218,8 +251,9 @@ void arrange_layers(struct sway_output *output) {
|
|||
for (size_t i = 0; i < nlayers; ++i) {
|
||||
wl_list_for_each_reverse(layer,
|
||||
&output->layers[layers_above_shell[i]], link) {
|
||||
if (layer->layer_surface->current.keyboard_interactive &&
|
||||
layer->layer_surface->mapped) {
|
||||
if (layer->layer_surface->current.keyboard_interactive
|
||||
== ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE &&
|
||||
layer->layer_surface->surface->mapped) {
|
||||
topmost = layer;
|
||||
break;
|
||||
}
|
||||
|
@ -231,10 +265,12 @@ void arrange_layers(struct sway_output *output) {
|
|||
|
||||
struct sway_seat *seat;
|
||||
wl_list_for_each(seat, &server.input->seats, link) {
|
||||
seat->has_exclusive_layer = false;
|
||||
if (topmost != NULL) {
|
||||
seat_set_focus_layer(seat, topmost->layer_surface);
|
||||
} else if (seat->focused_layer &&
|
||||
!seat->focused_layer->current.keyboard_interactive) {
|
||||
seat->focused_layer->current.keyboard_interactive
|
||||
!= ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
|
||||
seat_set_focus_layer(seat, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +289,7 @@ static struct sway_layer_surface *find_mapped_layer_by_client(
|
|||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], link) {
|
||||
struct wl_resource *resource = lsurface->layer_surface->resource;
|
||||
if (wl_resource_get_client(resource) == client
|
||||
&& lsurface->layer_surface->mapped) {
|
||||
&& lsurface->layer_surface->surface->mapped) {
|
||||
return lsurface;
|
||||
}
|
||||
}
|
||||
|
@ -293,8 +329,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) {
|
|||
|
||||
bool layer_changed = false;
|
||||
if (layer_surface->current.committed != 0
|
||||
|| layer->mapped != layer_surface->mapped) {
|
||||
layer->mapped = layer_surface->mapped;
|
||||
|| layer->mapped != layer_surface->surface->mapped) {
|
||||
layer->mapped = layer_surface->surface->mapped;
|
||||
layer_changed = layer->layer != layer_surface->current.layer;
|
||||
if (layer_changed) {
|
||||
wl_list_remove(&layer->link);
|
||||
|
@ -312,6 +348,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) {
|
|||
bool extent_changed =
|
||||
memcmp(&old_extent, &layer->extent, sizeof(struct wlr_box)) != 0;
|
||||
if (extent_changed || layer_changed) {
|
||||
old_extent.x += output->lx;
|
||||
old_extent.y += output->ly;
|
||||
output_damage_box(output, &old_extent);
|
||||
output_damage_surface(output, layer->geo.x, layer->geo.y,
|
||||
layer_surface->surface, true);
|
||||
|
@ -347,7 +385,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, sway_layer, destroy);
|
||||
sway_log(SWAY_DEBUG, "Layer surface destroyed (%s)",
|
||||
sway_layer->layer_surface->namespace);
|
||||
if (sway_layer->layer_surface->mapped) {
|
||||
if (sway_layer->layer_surface->surface->mapped) {
|
||||
unmap(sway_layer);
|
||||
}
|
||||
|
||||
|
@ -452,9 +490,9 @@ static struct sway_layer_subsurface *create_subsurface(
|
|||
wl_list_insert(&layer_surface->subsurfaces, &subsurface->link);
|
||||
|
||||
subsurface->map.notify = subsurface_handle_map;
|
||||
wl_signal_add(&wlr_subsurface->events.map, &subsurface->map);
|
||||
wl_signal_add(&wlr_subsurface->surface->events.map, &subsurface->map);
|
||||
subsurface->unmap.notify = subsurface_handle_unmap;
|
||||
wl_signal_add(&wlr_subsurface->events.unmap, &subsurface->unmap);
|
||||
wl_signal_add(&wlr_subsurface->surface->events.unmap, &subsurface->unmap);
|
||||
subsurface->destroy.notify = subsurface_handle_destroy;
|
||||
wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
|
||||
subsurface->commit.notify = subsurface_handle_commit;
|
||||
|
@ -569,9 +607,9 @@ static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
|
|||
popup->parent_layer = parent;
|
||||
|
||||
popup->map.notify = popup_handle_map;
|
||||
wl_signal_add(&wlr_popup->base->events.map, &popup->map);
|
||||
wl_signal_add(&wlr_popup->base->surface->events.map, &popup->map);
|
||||
popup->unmap.notify = popup_handle_unmap;
|
||||
wl_signal_add(&wlr_popup->base->events.unmap, &popup->unmap);
|
||||
wl_signal_add(&wlr_popup->base->surface->events.unmap, &popup->unmap);
|
||||
popup->destroy.notify = popup_handle_destroy;
|
||||
wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
|
||||
popup->commit.notify = popup_handle_commit;
|
||||
|
@ -659,9 +697,9 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
|
|||
sway_layer->destroy.notify = handle_destroy;
|
||||
wl_signal_add(&layer_surface->events.destroy, &sway_layer->destroy);
|
||||
sway_layer->map.notify = handle_map;
|
||||
wl_signal_add(&layer_surface->events.map, &sway_layer->map);
|
||||
wl_signal_add(&layer_surface->surface->events.map, &sway_layer->map);
|
||||
sway_layer->unmap.notify = handle_unmap;
|
||||
wl_signal_add(&layer_surface->events.unmap, &sway_layer->unmap);
|
||||
wl_signal_add(&layer_surface->surface->events.unmap, &sway_layer->unmap);
|
||||
sway_layer->new_popup.notify = handle_new_popup;
|
||||
wl_signal_add(&layer_surface->events.new_popup, &sway_layer->new_popup);
|
||||
sway_layer->new_subsurface.notify = handle_new_subsurface;
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/config.h>
|
||||
#include <wlr/backend/headless.h>
|
||||
#include <wlr/render/swapchain.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_buffer.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
@ -264,7 +266,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output,
|
|||
double ox = drag_icon->x - output->lx;
|
||||
double oy = drag_icon->y - output->ly;
|
||||
|
||||
if (drag_icon->wlr_drag_icon->mapped) {
|
||||
if (drag_icon->wlr_drag_icon->surface->mapped) {
|
||||
output_surface_for_each_surface(output,
|
||||
drag_icon->wlr_drag_icon->surface, ox, oy,
|
||||
iterator, user_data);
|
||||
|
@ -294,7 +296,7 @@ static void output_for_each_surface(struct sway_output *output,
|
|||
if (lock_surface->output != output->wlr_output) {
|
||||
continue;
|
||||
}
|
||||
if (!lock_surface->mapped) {
|
||||
if (!lock_surface->surface->mapped) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -456,7 +458,7 @@ static void count_surface_iterator(struct sway_output *output,
|
|||
}
|
||||
|
||||
static bool scan_out_fullscreen_view(struct sway_output *output,
|
||||
struct sway_view *view) {
|
||||
struct wlr_output_state *pending, struct sway_view *view) {
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct sway_workspace *workspace = output->current.active_workspace;
|
||||
if (!sway_assert(workspace, "Expected an active workspace")) {
|
||||
|
@ -522,15 +524,16 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
|
|||
return false;
|
||||
}
|
||||
|
||||
wlr_output_attach_buffer(wlr_output, &surface->buffer->base);
|
||||
if (!wlr_output_test(wlr_output)) {
|
||||
wlr_output_state_set_buffer(pending, &surface->buffer->base);
|
||||
|
||||
if (!wlr_output_test_state(wlr_output, pending)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wlr_presentation_surface_sampled_on_output(server.presentation, surface,
|
||||
wlr_output);
|
||||
|
||||
return wlr_output_commit(wlr_output);
|
||||
return wlr_output_commit_state(wlr_output, pending);
|
||||
}
|
||||
|
||||
static void get_frame_damage(struct sway_output *output,
|
||||
|
@ -563,6 +566,7 @@ static int output_repaint_timer_handler(void *data) {
|
|||
wlr_output->frame_pending = false;
|
||||
|
||||
if (!wlr_output->needs_frame &&
|
||||
!output->gamma_lut_changed &&
|
||||
!pixman_region32_not_empty(&output->damage_ring.current)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -577,16 +581,31 @@ static int output_repaint_timer_handler(void *data) {
|
|||
fullscreen_con = workspace->current.fullscreen;
|
||||
}
|
||||
|
||||
pixman_region32_t frame_damage;
|
||||
get_frame_damage(output, &frame_damage);
|
||||
wlr_output_set_damage(wlr_output, &frame_damage);
|
||||
pixman_region32_fini(&frame_damage);
|
||||
struct wlr_output_state pending = {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(
|
||||
server.gamma_control_manager_v1, wlr_output);
|
||||
if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
|
||||
goto out;
|
||||
}
|
||||
if (!wlr_output_test_state(wlr_output, &pending)) {
|
||||
wlr_output_state_finish(&pending);
|
||||
pending = (struct wlr_output_state){0};
|
||||
wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
|
||||
}
|
||||
}
|
||||
|
||||
pending.committed |= WLR_OUTPUT_STATE_DAMAGE;
|
||||
get_frame_damage(output, &pending.damage);
|
||||
|
||||
if (fullscreen_con && fullscreen_con->view && !debug.noscanout) {
|
||||
// Try to scan-out the fullscreen view
|
||||
static bool last_scanned_out = false;
|
||||
bool scanned_out =
|
||||
scan_out_fullscreen_view(output, fullscreen_con->view);
|
||||
scan_out_fullscreen_view(output, &pending, fullscreen_con->view);
|
||||
|
||||
if (scanned_out && !last_scanned_out) {
|
||||
sway_log(SWAY_DEBUG, "Scanning out fullscreen view on %s",
|
||||
|
@ -600,33 +619,68 @@ static int output_repaint_timer_handler(void *data) {
|
|||
last_scanned_out = scanned_out;
|
||||
|
||||
if (scanned_out) {
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wlr_output_configure_primary_swapchain(wlr_output, &pending, &wlr_output->swapchain)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
int buffer_age;
|
||||
if (!wlr_output_attach_render(output->wlr_output, &buffer_age)) {
|
||||
return 0;
|
||||
struct wlr_buffer *buffer = wlr_swapchain_acquire(wlr_output->swapchain, &buffer_age);
|
||||
if (buffer == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct wlr_render_pass *render_pass = wlr_renderer_begin_buffer_pass(
|
||||
wlr_output->renderer, buffer, NULL);
|
||||
if (render_pass == NULL) {
|
||||
wlr_buffer_unlock(buffer);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_init(&damage);
|
||||
wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage);
|
||||
|
||||
if (debug.damage == DAMAGE_RERENDER) {
|
||||
int width, height;
|
||||
wlr_output_transformed_resolution(wlr_output, &width, &height);
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, width, height);
|
||||
}
|
||||
|
||||
struct render_context ctx = {
|
||||
.output_damage = &damage,
|
||||
.renderer = wlr_output->renderer,
|
||||
.output = output,
|
||||
.pass = render_pass,
|
||||
};
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
output_render(output, &damage);
|
||||
output_render(&ctx);
|
||||
|
||||
pixman_region32_fini(&damage);
|
||||
|
||||
if (!wlr_output_commit(wlr_output)) {
|
||||
return 0;
|
||||
if (!wlr_render_pass_submit(render_pass)) {
|
||||
wlr_buffer_unlock(buffer);
|
||||
goto out;
|
||||
}
|
||||
|
||||
wlr_output_state_set_buffer(&pending, buffer);
|
||||
wlr_buffer_unlock(buffer);
|
||||
|
||||
if (!wlr_output_commit_state(wlr_output, &pending)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
wlr_damage_ring_rotate(&output->damage_ring);
|
||||
output->last_frame = now;
|
||||
|
||||
out:
|
||||
wlr_output_state_finish(&pending);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1042,6 +1096,21 @@ void handle_output_layout_change(struct wl_listener *listener,
|
|||
update_output_manager_config(server);
|
||||
}
|
||||
|
||||
void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) {
|
||||
struct sway_server *server =
|
||||
wl_container_of(listener, server, gamma_control_set_gamma);
|
||||
const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
|
||||
|
||||
struct sway_output *output = event->output->data;
|
||||
|
||||
if(!output) {
|
||||
return;
|
||||
}
|
||||
|
||||
output->gamma_lut_changed = true;
|
||||
wlr_output_schedule_frame(output->wlr_output);
|
||||
}
|
||||
|
||||
static void output_manager_apply(struct sway_server *server,
|
||||
struct wlr_output_configuration_v1 *config, bool test_only) {
|
||||
// TODO: perform atomic tests on the whole backend atomically
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -344,7 +344,7 @@ static void transaction_progress(void) {
|
|||
server.queued_transaction = NULL;
|
||||
|
||||
if (!server.pending_transaction) {
|
||||
sway_idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
|
||||
sway_idle_inhibit_v1_check_active();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,8 +104,8 @@ static struct sway_xdg_popup *popup_create(
|
|||
wl_signal_add(&xdg_surface->events.destroy, &popup->destroy);
|
||||
popup->destroy.notify = popup_handle_destroy;
|
||||
|
||||
wl_signal_add(&xdg_surface->events.map, &popup->child.surface_map);
|
||||
wl_signal_add(&xdg_surface->events.unmap, &popup->child.surface_unmap);
|
||||
wl_signal_add(&xdg_surface->surface->events.map, &popup->child.surface_map);
|
||||
wl_signal_add(&xdg_surface->surface->events.unmap, &popup->child.surface_unmap);
|
||||
|
||||
popup_unconstrain(popup);
|
||||
|
||||
|
@ -344,7 +344,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
|||
struct wlr_xdg_toplevel *toplevel = xdg_shell_view->view.wlr_xdg_toplevel;
|
||||
struct sway_view *view = &xdg_shell_view->view;
|
||||
|
||||
if (!toplevel->base->mapped) {
|
||||
if (!toplevel->base->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -529,10 +529,10 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
|
|||
xdg_shell_view->view.wlr_xdg_toplevel = xdg_surface->toplevel;
|
||||
|
||||
xdg_shell_view->map.notify = handle_map;
|
||||
wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map);
|
||||
wl_signal_add(&xdg_surface->surface->events.map, &xdg_shell_view->map);
|
||||
|
||||
xdg_shell_view->unmap.notify = handle_unmap;
|
||||
wl_signal_add(&xdg_surface->events.unmap, &xdg_shell_view->unmap);
|
||||
wl_signal_add(&xdg_surface->surface->events.unmap, &xdg_shell_view->unmap);
|
||||
|
||||
xdg_shell_view->destroy.notify = handle_destroy;
|
||||
wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy);
|
||||
|
|
|
@ -125,8 +125,10 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
static void unmanaged_handle_request_activate(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xwayland_surface *xsurface = data;
|
||||
if (!xsurface->mapped) {
|
||||
struct sway_xwayland_unmanaged *surface =
|
||||
wl_container_of(listener, surface, request_activate);
|
||||
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
|
@ -138,12 +140,29 @@ static void unmanaged_handle_request_activate(struct wl_listener *listener, void
|
|||
seat_set_focus_surface(seat, xsurface->surface, false);
|
||||
}
|
||||
|
||||
static void unmanaged_handle_associate(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_unmanaged *surface =
|
||||
wl_container_of(listener, surface, associate);
|
||||
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||
wl_signal_add(&xsurface->surface->events.map, &surface->map);
|
||||
surface->map.notify = unmanaged_handle_map;
|
||||
wl_signal_add(&xsurface->surface->events.unmap, &surface->unmap);
|
||||
surface->unmap.notify = unmanaged_handle_unmap;
|
||||
}
|
||||
|
||||
static void unmanaged_handle_dissociate(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_unmanaged *surface =
|
||||
wl_container_of(listener, surface, dissociate);
|
||||
wl_list_remove(&surface->map.link);
|
||||
wl_list_remove(&surface->unmap.link);
|
||||
}
|
||||
|
||||
static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_unmanaged *surface =
|
||||
wl_container_of(listener, surface, destroy);
|
||||
wl_list_remove(&surface->request_configure.link);
|
||||
wl_list_remove(&surface->map.link);
|
||||
wl_list_remove(&surface->unmap.link);
|
||||
wl_list_remove(&surface->associate.link);
|
||||
wl_list_remove(&surface->dissociate.link);
|
||||
wl_list_remove(&surface->destroy.link);
|
||||
wl_list_remove(&surface->override_redirect.link);
|
||||
wl_list_remove(&surface->request_activate.link);
|
||||
|
@ -159,7 +178,7 @@ static void unmanaged_handle_override_redirect(struct wl_listener *listener, voi
|
|||
wl_container_of(listener, surface, override_redirect);
|
||||
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||
|
||||
bool mapped = xsurface->mapped;
|
||||
bool mapped = xsurface->surface != NULL && xsurface->surface->mapped;
|
||||
if (mapped) {
|
||||
unmanaged_handle_unmap(&surface->unmap, NULL);
|
||||
}
|
||||
|
@ -186,10 +205,10 @@ static struct sway_xwayland_unmanaged *create_unmanaged(
|
|||
wl_signal_add(&xsurface->events.request_configure,
|
||||
&surface->request_configure);
|
||||
surface->request_configure.notify = unmanaged_handle_request_configure;
|
||||
wl_signal_add(&xsurface->events.map, &surface->map);
|
||||
surface->map.notify = unmanaged_handle_map;
|
||||
wl_signal_add(&xsurface->events.unmap, &surface->unmap);
|
||||
surface->unmap.notify = unmanaged_handle_unmap;
|
||||
wl_signal_add(&xsurface->events.associate, &surface->associate);
|
||||
surface->associate.notify = unmanaged_handle_associate;
|
||||
wl_signal_add(&xsurface->events.dissociate, &surface->dissociate);
|
||||
surface->dissociate.notify = unmanaged_handle_dissociate;
|
||||
wl_signal_add(&xsurface->events.destroy, &surface->destroy);
|
||||
surface->destroy.notify = unmanaged_handle_destroy;
|
||||
wl_signal_add(&xsurface->events.set_override_redirect, &surface->override_redirect);
|
||||
|
@ -472,8 +491,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
|||
wl_list_remove(&xwayland_view->set_window_type.link);
|
||||
wl_list_remove(&xwayland_view->set_hints.link);
|
||||
wl_list_remove(&xwayland_view->set_decorations.link);
|
||||
wl_list_remove(&xwayland_view->map.link);
|
||||
wl_list_remove(&xwayland_view->unmap.link);
|
||||
wl_list_remove(&xwayland_view->associate.link);
|
||||
wl_list_remove(&xwayland_view->dissociate.link);
|
||||
wl_list_remove(&xwayland_view->override_redirect.link);
|
||||
view_begin_destroy(&xwayland_view->view);
|
||||
}
|
||||
|
@ -495,8 +514,8 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
|
|||
static void handle_map(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_view *xwayland_view =
|
||||
wl_container_of(listener, xwayland_view, map);
|
||||
struct wlr_xwayland_surface *xsurface = data;
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
|
||||
view->natural_width = xsurface->width;
|
||||
view->natural_height = xsurface->height;
|
||||
|
@ -515,10 +534,10 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
|||
static void handle_override_redirect(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_view *xwayland_view =
|
||||
wl_container_of(listener, xwayland_view, override_redirect);
|
||||
struct wlr_xwayland_surface *xsurface = data;
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
|
||||
bool mapped = xsurface->mapped;
|
||||
bool mapped = xsurface->surface != NULL && xsurface->surface->mapped;
|
||||
if (mapped) {
|
||||
handle_unmap(&xwayland_view->unmap, NULL);
|
||||
}
|
||||
|
@ -537,7 +556,7 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
|
|||
struct wlr_xwayland_surface_configure_event *ev = data;
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
wlr_xwayland_surface_configure(xsurface, ev->x, ev->y,
|
||||
ev->width, ev->height);
|
||||
return;
|
||||
|
@ -566,7 +585,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
|||
wl_container_of(listener, xwayland_view, request_fullscreen);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
container_set_fullscreen(view->container, xsurface->fullscreen);
|
||||
|
@ -580,7 +599,7 @@ static void handle_request_minimize(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, request_minimize);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -595,7 +614,7 @@ static void handle_request_move(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, request_move);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
if (!container_is_floating(view->container) ||
|
||||
|
@ -611,7 +630,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, request_resize);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
if (!container_is_floating(view->container)) {
|
||||
|
@ -627,7 +646,7 @@ static void handle_request_activate(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, request_activate);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
view_request_activate(view, NULL);
|
||||
|
@ -640,7 +659,7 @@ static void handle_set_title(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, set_title);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
view_update_title(view, false);
|
||||
|
@ -652,7 +671,7 @@ static void handle_set_class(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, set_class);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
view_execute_criteria(view);
|
||||
|
@ -663,7 +682,7 @@ static void handle_set_role(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, set_role);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
view_execute_criteria(view);
|
||||
|
@ -699,7 +718,7 @@ static void handle_set_window_type(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, set_window_type);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
view_execute_criteria(view);
|
||||
|
@ -710,7 +729,7 @@ static void handle_set_hints(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, xwayland_view, set_hints);
|
||||
struct sway_view *view = &xwayland_view->view;
|
||||
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||
if (!xsurface->mapped) {
|
||||
if (xsurface->surface == NULL || !xsurface->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
const bool hints_urgency = xcb_icccm_wm_hints_get_urgency(xsurface->hints);
|
||||
|
@ -725,6 +744,24 @@ static void handle_set_hints(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_associate(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_view *xwayland_view =
|
||||
wl_container_of(listener, xwayland_view, associate);
|
||||
struct wlr_xwayland_surface *xsurface =
|
||||
xwayland_view->view.wlr_xwayland_surface;
|
||||
wl_signal_add(&xsurface->surface->events.unmap, &xwayland_view->unmap);
|
||||
xwayland_view->unmap.notify = handle_unmap;
|
||||
wl_signal_add(&xsurface->surface->events.map, &xwayland_view->map);
|
||||
xwayland_view->map.notify = handle_map;
|
||||
}
|
||||
|
||||
static void handle_dissociate(struct wl_listener *listener, void *data) {
|
||||
struct sway_xwayland_view *xwayland_view =
|
||||
wl_container_of(listener, xwayland_view, dissociate);
|
||||
wl_list_remove(&xwayland_view->map.link);
|
||||
wl_list_remove(&xwayland_view->unmap.link);
|
||||
}
|
||||
|
||||
struct sway_view *view_from_wlr_xwayland_surface(
|
||||
struct wlr_xwayland_surface *xsurface) {
|
||||
return xsurface->data;
|
||||
|
@ -794,11 +831,11 @@ struct sway_xwayland_view *create_xwayland_view(struct wlr_xwayland_surface *xsu
|
|||
&xwayland_view->set_decorations);
|
||||
xwayland_view->set_decorations.notify = handle_set_decorations;
|
||||
|
||||
wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap);
|
||||
xwayland_view->unmap.notify = handle_unmap;
|
||||
wl_signal_add(&xsurface->events.associate, &xwayland_view->associate);
|
||||
xwayland_view->associate.notify = handle_associate;
|
||||
|
||||
wl_signal_add(&xsurface->events.map, &xwayland_view->map);
|
||||
xwayland_view->map.notify = handle_map;
|
||||
wl_signal_add(&xsurface->events.dissociate, &xwayland_view->dissociate);
|
||||
xwayland_view->dissociate.notify = handle_dissociate;
|
||||
|
||||
wl_signal_add(&xsurface->events.set_override_redirect,
|
||||
&xwayland_view->override_redirect);
|
||||
|
|
|
@ -236,7 +236,7 @@ void cursor_update_image(struct sway_cursor *cursor,
|
|||
// Try a node's resize edge
|
||||
enum wlr_edges edge = find_resize_edge(node->sway_container, NULL, cursor);
|
||||
if (edge == WLR_EDGE_NONE) {
|
||||
cursor_set_image(cursor, "left_ptr", NULL);
|
||||
cursor_set_image(cursor, "default", NULL);
|
||||
} else if (container_is_floating(node->sway_container)) {
|
||||
cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL);
|
||||
} else {
|
||||
|
@ -247,12 +247,12 @@ void cursor_update_image(struct sway_cursor *cursor,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
cursor_set_image(cursor, "left_ptr", NULL);
|
||||
cursor_set_image(cursor, "default", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void cursor_hide(struct sway_cursor *cursor) {
|
||||
wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
|
||||
wlr_cursor_unset_image(cursor->cursor);
|
||||
cursor->hidden = true;
|
||||
wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat);
|
||||
}
|
||||
|
@ -509,6 +509,24 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_touch_cancel(struct wl_listener *listener, void *data) {
|
||||
struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_cancel);
|
||||
struct wlr_touch_cancel_event *event = data;
|
||||
cursor_handle_activity_from_device(cursor, &event->touch->base);
|
||||
|
||||
struct sway_seat *seat = cursor->seat;
|
||||
|
||||
if (cursor->simulating_pointer_from_touch) {
|
||||
if (cursor->pointer_touch_id == cursor->seat->touch_id) {
|
||||
cursor->pointer_touch_up = true;
|
||||
dispatch_cursor_button(cursor, &event->touch->base,
|
||||
event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED);
|
||||
}
|
||||
} else {
|
||||
seatop_touch_cancel(seat, event);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
||||
struct sway_cursor *cursor =
|
||||
wl_container_of(listener, cursor, touch_motion);
|
||||
|
@ -1050,10 +1068,9 @@ void cursor_set_image(struct sway_cursor *cursor, const char *image,
|
|||
}
|
||||
|
||||
if (!image) {
|
||||
wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
|
||||
wlr_cursor_unset_image(cursor->cursor);
|
||||
} else if (!current_image || strcmp(current_image, image) != 0) {
|
||||
wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image,
|
||||
cursor->cursor);
|
||||
wlr_cursor_set_xcursor(cursor->cursor, cursor->xcursor_manager, image);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1100,6 +1117,7 @@ void sway_cursor_destroy(struct sway_cursor *cursor) {
|
|||
wl_list_remove(&cursor->frame.link);
|
||||
wl_list_remove(&cursor->touch_down.link);
|
||||
wl_list_remove(&cursor->touch_up.link);
|
||||
wl_list_remove(&cursor->touch_cancel.link);
|
||||
wl_list_remove(&cursor->touch_motion.link);
|
||||
wl_list_remove(&cursor->touch_frame.link);
|
||||
wl_list_remove(&cursor->tool_axis.link);
|
||||
|
@ -1136,9 +1154,6 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
|
|||
wl_list_init(&cursor->image_surface_destroy.link);
|
||||
cursor->image_surface_destroy.notify = handle_image_surface_destroy;
|
||||
|
||||
// gesture events
|
||||
cursor->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display);
|
||||
|
||||
wl_signal_add(&wlr_cursor->events.hold_begin, &cursor->hold_begin);
|
||||
cursor->hold_begin.notify = handle_pointer_hold_begin;
|
||||
wl_signal_add(&wlr_cursor->events.hold_end, &cursor->hold_end);
|
||||
|
@ -1181,6 +1196,9 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
|
|||
wl_signal_add(&wlr_cursor->events.touch_up, &cursor->touch_up);
|
||||
cursor->touch_up.notify = handle_touch_up;
|
||||
|
||||
wl_signal_add(&wlr_cursor->events.touch_cancel, &cursor->touch_cancel);
|
||||
cursor->touch_cancel.notify = handle_touch_cancel;
|
||||
|
||||
wl_signal_add(&wlr_cursor->events.touch_motion,
|
||||
&cursor->touch_motion);
|
||||
cursor->touch_motion.notify = handle_touch_motion;
|
||||
|
|
|
@ -495,6 +495,8 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
|
|||
wl_signal_add(&input->keyboard_shortcuts_inhibit->events.new_inhibitor,
|
||||
&input->keyboard_shortcuts_inhibit_new_inhibitor);
|
||||
|
||||
input->pointer_gestures = wlr_pointer_gestures_v1_create(server->wl_display);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
|
@ -532,6 +534,18 @@ static void retranslate_keysyms(struct input_config *input_config) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < config->input_type_configs->length; ++i) {
|
||||
struct input_config *ic = config->input_type_configs->items[i];
|
||||
if (ic->xkb_layout || ic->xkb_file) {
|
||||
// this is the first config with xkb_layout or xkb_file
|
||||
if (ic->identifier == input_config->identifier) {
|
||||
translate_keysyms(ic);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void input_manager_configure_input(
|
||||
|
|
|
@ -166,6 +166,18 @@ static bool set_scroll_button(struct libinput_device *dev, uint32_t button) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool set_scroll_button_lock(struct libinput_device *dev,
|
||||
enum libinput_config_scroll_button_lock_state lock) {
|
||||
uint32_t scroll = libinput_device_config_scroll_get_methods(dev);
|
||||
if ((scroll & ~LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0 ||
|
||||
libinput_device_config_scroll_get_button_lock(dev) == lock) {
|
||||
return false;
|
||||
}
|
||||
sway_log(SWAY_DEBUG, "scroll_set_button_lock(%" PRIu32 ")", lock);
|
||||
log_status(libinput_device_config_scroll_set_button_lock(dev, lock));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool set_dwt(struct libinput_device *device, bool dwt) {
|
||||
if (!libinput_device_config_dwt_is_available(device) ||
|
||||
libinput_device_config_dwt_get_enabled(device) == dwt) {
|
||||
|
@ -276,6 +288,9 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device
|
|||
if (ic->scroll_button != INT_MIN) {
|
||||
changed |= set_scroll_button(device, ic->scroll_button);
|
||||
}
|
||||
if (ic->scroll_button_lock != INT_MIN) {
|
||||
changed |= set_scroll_button_lock(device, ic->scroll_button_lock);
|
||||
}
|
||||
if (ic->dwt != INT_MIN) {
|
||||
changed |= set_dwt(device, ic->dwt);
|
||||
}
|
||||
|
|
|
@ -367,7 +367,7 @@ static void handle_new_node(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
static void drag_icon_damage_whole(struct sway_drag_icon *icon) {
|
||||
if (!icon->wlr_drag_icon->mapped) {
|
||||
if (!icon->wlr_drag_icon->surface->mapped) {
|
||||
return;
|
||||
}
|
||||
desktop_damage_surface(icon->wlr_drag_icon->surface, icon->x, icon->y, true);
|
||||
|
@ -511,9 +511,9 @@ static void handle_start_drag(struct wl_listener *listener, void *data) {
|
|||
icon->surface_commit.notify = drag_icon_handle_surface_commit;
|
||||
wl_signal_add(&wlr_drag_icon->surface->events.commit, &icon->surface_commit);
|
||||
icon->unmap.notify = drag_icon_handle_unmap;
|
||||
wl_signal_add(&wlr_drag_icon->events.unmap, &icon->unmap);
|
||||
wl_signal_add(&wlr_drag_icon->surface->events.unmap, &icon->unmap);
|
||||
icon->map.notify = drag_icon_handle_map;
|
||||
wl_signal_add(&wlr_drag_icon->events.map, &icon->map);
|
||||
wl_signal_add(&wlr_drag_icon->surface->events.map, &icon->map);
|
||||
icon->destroy.notify = drag_icon_handle_destroy;
|
||||
wl_signal_add(&wlr_drag_icon->events.destroy, &icon->destroy);
|
||||
|
||||
|
@ -671,7 +671,7 @@ static void seat_update_capabilities(struct sway_seat *seat) {
|
|||
} else {
|
||||
wlr_seat_set_capabilities(seat->wlr_seat, caps);
|
||||
if ((previous_caps & WL_SEAT_CAPABILITY_POINTER) == 0) {
|
||||
cursor_set_image(seat->cursor, "left_ptr", NULL);
|
||||
cursor_set_image(seat->cursor, "default", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1039,7 +1039,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {
|
|||
|
||||
wlr_xcursor_manager_load(server.xwayland.xcursor_manager, 1);
|
||||
struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor(
|
||||
server.xwayland.xcursor_manager, "left_ptr", 1);
|
||||
server.xwayland.xcursor_manager, "default", 1);
|
||||
if (xcursor != NULL) {
|
||||
struct wlr_xcursor_image *image = xcursor->images[0];
|
||||
wlr_xwayland_set_cursor(
|
||||
|
@ -1082,7 +1082,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {
|
|||
|
||||
// Reset the cursor so that we apply it to outputs that just appeared
|
||||
cursor_set_image(seat->cursor, NULL, NULL);
|
||||
cursor_set_image(seat->cursor, "left_ptr", NULL);
|
||||
cursor_set_image(seat->cursor, "default", NULL);
|
||||
wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x,
|
||||
seat->cursor->cursor->y);
|
||||
}
|
||||
|
@ -1295,11 +1295,15 @@ static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *n
|
|||
}
|
||||
|
||||
void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
|
||||
if (seat->focused_layer) {
|
||||
// Prevents the layer from losing focus if it has keyboard exclusivity
|
||||
if (seat->has_exclusive_layer) {
|
||||
struct wlr_layer_surface_v1 *layer = seat->focused_layer;
|
||||
seat_set_focus_layer(seat, NULL);
|
||||
seat_set_workspace_focus(seat, node);
|
||||
seat_set_focus_layer(seat, layer);
|
||||
} else if (seat->focused_layer) {
|
||||
seat_set_focus_layer(seat, NULL);
|
||||
seat_set_workspace_focus(seat, node);
|
||||
} else {
|
||||
seat_set_workspace_focus(seat, node);
|
||||
}
|
||||
|
@ -1347,14 +1351,20 @@ void seat_set_focus_layer(struct sway_seat *seat,
|
|||
seat_set_focus(seat, previous);
|
||||
}
|
||||
return;
|
||||
} else if (!layer || seat->focused_layer == layer) {
|
||||
} else if (!layer) {
|
||||
return;
|
||||
}
|
||||
assert(layer->mapped);
|
||||
seat_set_focus_surface(seat, layer->surface, true);
|
||||
if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
|
||||
seat->focused_layer = layer;
|
||||
assert(layer->surface->mapped);
|
||||
if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP &&
|
||||
layer->current.keyboard_interactive
|
||||
== ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
|
||||
seat->has_exclusive_layer = true;
|
||||
}
|
||||
if (seat->focused_layer == layer) {
|
||||
return;
|
||||
}
|
||||
seat_set_focus_surface(seat, layer->surface, true);
|
||||
seat->focused_layer = layer;
|
||||
}
|
||||
|
||||
void seat_set_exclusive_client(struct sway_seat *seat,
|
||||
|
@ -1638,6 +1648,12 @@ void seatop_touch_down(struct sway_seat *seat, struct wlr_touch_down_event *even
|
|||
}
|
||||
}
|
||||
|
||||
void seatop_touch_cancel(struct sway_seat *seat, struct wlr_touch_cancel_event *event) {
|
||||
if (seat->seatop_impl->touch_cancel) {
|
||||
seat->seatop_impl->touch_cancel(seat, event);
|
||||
}
|
||||
}
|
||||
|
||||
void seatop_tablet_tool_tip(struct sway_seat *seat,
|
||||
struct sway_tablet_tool *tool, uint32_t time_msec,
|
||||
enum wlr_tablet_tool_tip_state state) {
|
||||
|
@ -1726,10 +1742,9 @@ void seatop_end(struct sway_seat *seat) {
|
|||
seat->seatop_impl = NULL;
|
||||
}
|
||||
|
||||
void seatop_render(struct sway_seat *seat, struct sway_output *output,
|
||||
const pixman_region32_t *damage) {
|
||||
void seatop_render(struct sway_seat *seat, struct render_context *ctx) {
|
||||
if (seat->seatop_impl->render) {
|
||||
seat->seatop_impl->render(seat, output, damage);
|
||||
seat->seatop_impl->render(seat, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <float.h>
|
||||
#include <libevdev/libevdev.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include <wlr/types/wlr_tablet_v2.h>
|
||||
#include <wlr/types/wlr_xcursor_manager.h>
|
||||
#include "gesture.h"
|
||||
|
@ -9,6 +10,7 @@
|
|||
#include "sway/input/cursor.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/input/tablet.h"
|
||||
#include "sway/layers.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
|
@ -365,10 +367,9 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
|||
return;
|
||||
}
|
||||
|
||||
// Handle clicking a layer surface
|
||||
struct wlr_layer_surface_v1 *layer;
|
||||
if (surface &&
|
||||
(layer = wlr_layer_surface_v1_try_from_wlr_surface(surface))) {
|
||||
// Handle clicking a layer surface and its popups/subsurfaces
|
||||
struct wlr_layer_surface_v1 *layer = NULL;
|
||||
if ((layer = toplevel_layer_surface_from_surface(surface))) {
|
||||
if (layer->current.keyboard_interactive) {
|
||||
seat_set_focus_layer(seat, layer);
|
||||
transaction_commit_dirty();
|
||||
|
@ -545,6 +546,21 @@ static void check_focus_follows_mouse(struct sway_seat *seat,
|
|||
if (wlr_output == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
node_at_coords(seat, seat->cursor->cursor->x, seat->cursor->cursor->y,
|
||||
&surface, &sx, &sy);
|
||||
|
||||
// Focus topmost layer surface
|
||||
struct wlr_layer_surface_v1 *layer = NULL;
|
||||
if ((layer = toplevel_layer_surface_from_surface(surface)) &&
|
||||
layer->current.keyboard_interactive) {
|
||||
seat_set_focus_layer(seat, layer);
|
||||
transaction_commit_dirty();
|
||||
return;
|
||||
}
|
||||
|
||||
struct sway_output *hovered_output = wlr_output->data;
|
||||
if (focus && hovered_output != node_get_output(focus)) {
|
||||
struct sway_workspace *ws = output_get_active_workspace(hovered_output);
|
||||
|
@ -934,7 +950,7 @@ static void handle_hold_begin(struct sway_seat *seat,
|
|||
// ... otherwise forward to client
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_hold_begin(
|
||||
cursor->pointer_gestures, cursor->seat->wlr_seat,
|
||||
server.input->pointer_gestures, cursor->seat->wlr_seat,
|
||||
event->time_msec, event->fingers);
|
||||
}
|
||||
}
|
||||
|
@ -946,7 +962,7 @@ static void handle_hold_end(struct sway_seat *seat,
|
|||
if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_HOLD)) {
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_hold_end(
|
||||
cursor->pointer_gestures, cursor->seat->wlr_seat,
|
||||
server.input->pointer_gestures, cursor->seat->wlr_seat,
|
||||
event->time_msec, event->cancelled);
|
||||
return;
|
||||
}
|
||||
|
@ -979,7 +995,7 @@ static void handle_pinch_begin(struct sway_seat *seat,
|
|||
// ... otherwise forward to client
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_pinch_begin(
|
||||
cursor->pointer_gestures, cursor->seat->wlr_seat,
|
||||
server.input->pointer_gestures, cursor->seat->wlr_seat,
|
||||
event->time_msec, event->fingers);
|
||||
}
|
||||
}
|
||||
|
@ -995,7 +1011,7 @@ static void handle_pinch_update(struct sway_seat *seat,
|
|||
// ... otherwise forward to client
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_pinch_update(
|
||||
cursor->pointer_gestures,
|
||||
server.input->pointer_gestures,
|
||||
cursor->seat->wlr_seat,
|
||||
event->time_msec, event->dx, event->dy,
|
||||
event->scale, event->rotation);
|
||||
|
@ -1009,7 +1025,7 @@ static void handle_pinch_end(struct sway_seat *seat,
|
|||
if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_PINCH)) {
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_pinch_end(
|
||||
cursor->pointer_gestures, cursor->seat->wlr_seat,
|
||||
server.input->pointer_gestures, cursor->seat->wlr_seat,
|
||||
event->time_msec, event->cancelled);
|
||||
return;
|
||||
}
|
||||
|
@ -1042,7 +1058,7 @@ static void handle_swipe_begin(struct sway_seat *seat,
|
|||
// ... otherwise forward to client
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_swipe_begin(
|
||||
cursor->pointer_gestures, cursor->seat->wlr_seat,
|
||||
server.input->pointer_gestures, cursor->seat->wlr_seat,
|
||||
event->time_msec, event->fingers);
|
||||
}
|
||||
}
|
||||
|
@ -1059,7 +1075,7 @@ static void handle_swipe_update(struct sway_seat *seat,
|
|||
// ... otherwise forward to client
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_swipe_update(
|
||||
cursor->pointer_gestures, cursor->seat->wlr_seat,
|
||||
server.input->pointer_gestures, cursor->seat->wlr_seat,
|
||||
event->time_msec, event->dx, event->dy);
|
||||
}
|
||||
}
|
||||
|
@ -1070,7 +1086,7 @@ static void handle_swipe_end(struct sway_seat *seat,
|
|||
struct seatop_default_event *seatop = seat->seatop_data;
|
||||
if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_SWIPE)) {
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_swipe_end(cursor->pointer_gestures,
|
||||
wlr_pointer_gestures_v1_send_swipe_end(server.input->pointer_gestures,
|
||||
cursor->seat->wlr_seat, event->time_msec, event->cancelled);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -64,11 +64,11 @@ static void handle_touch_up(struct sway_seat *seat,
|
|||
}
|
||||
}
|
||||
|
||||
wlr_seat_touch_notify_up(seat->wlr_seat, event->time_msec, event->touch_id);
|
||||
|
||||
if (wl_list_empty(&e->point_events)) {
|
||||
seatop_begin_default(seat);
|
||||
}
|
||||
|
||||
wlr_seat_touch_notify_up(seat->wlr_seat, event->time_msec, event->touch_id);
|
||||
}
|
||||
|
||||
static void handle_touch_down(struct sway_seat *seat,
|
||||
|
@ -104,6 +104,28 @@ static void handle_touch_down(struct sway_seat *seat,
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_touch_cancel(struct sway_seat *seat,
|
||||
struct wlr_touch_cancel_event *event) {
|
||||
struct seatop_down_event *e = seat->seatop_data;
|
||||
struct seatop_touch_point_event *point_event, *tmp;
|
||||
|
||||
wl_list_for_each_safe(point_event, tmp, &e->point_events, link) {
|
||||
if (point_event->touch_id == event->touch_id) {
|
||||
wl_list_remove(&point_event->link);
|
||||
free(point_event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (e->surface) {
|
||||
wlr_seat_touch_notify_cancel(seat->wlr_seat, e->surface);
|
||||
}
|
||||
|
||||
if (wl_list_empty(&e->point_events)) {
|
||||
seatop_begin_default(seat);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_pointer_axis(struct sway_seat *seat,
|
||||
struct wlr_pointer_axis_event *event) {
|
||||
struct sway_input_device *input_device =
|
||||
|
@ -189,6 +211,7 @@ static const struct sway_seatop_impl seatop_impl = {
|
|||
.touch_motion = handle_touch_motion,
|
||||
.touch_up = handle_touch_up,
|
||||
.touch_down = handle_touch_down,
|
||||
.touch_cancel = handle_touch_cancel,
|
||||
.unref = handle_unref,
|
||||
.end = handle_end,
|
||||
.allow_set_cursor = true,
|
||||
|
|
|
@ -31,21 +31,20 @@ struct seatop_move_tiling_event {
|
|||
bool insert_after_target;
|
||||
};
|
||||
|
||||
static void handle_render(struct sway_seat *seat,
|
||||
struct sway_output *output, const pixman_region32_t *damage) {
|
||||
static void handle_render(struct sway_seat *seat, struct render_context *ctx) {
|
||||
struct seatop_move_tiling_event *e = seat->seatop_data;
|
||||
if (!e->threshold_reached) {
|
||||
return;
|
||||
}
|
||||
if (e->target_node && node_get_output(e->target_node) == output) {
|
||||
if (e->target_node && node_get_output(e->target_node) == ctx->output) {
|
||||
float color[4];
|
||||
memcpy(&color, config->border_colors.focused.indicator,
|
||||
sizeof(float) * 4);
|
||||
premultiply_alpha(color, 0.5);
|
||||
struct wlr_box box;
|
||||
memcpy(&box, &e->drop_box, sizeof(struct wlr_box));
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_rect(output, damage, &box, color);
|
||||
scale_box(&box, ctx->output->wlr_output->scale);
|
||||
render_rect(ctx, &box, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1019,6 +1019,17 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
|
|||
uint32_t button = libinput_device_config_scroll_get_button(device);
|
||||
json_object_object_add(object, "scroll_button",
|
||||
json_object_new_int(button));
|
||||
const char *lock = "unknown";
|
||||
switch (libinput_device_config_scroll_get_button_lock(device)) {
|
||||
case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED:
|
||||
lock = "enabled";
|
||||
break;
|
||||
case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED:
|
||||
lock = "disabled";
|
||||
break;
|
||||
}
|
||||
json_object_object_add(object, "scroll_button_lock",
|
||||
json_object_new_string(lock));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ static void destroy_lock_surface(struct sway_session_lock_surface *surf) {
|
|||
|
||||
struct wlr_session_lock_surface_v1 *other;
|
||||
wl_list_for_each(other, &server.session_lock.lock->surfaces, link) {
|
||||
if (other != surf->lock_surface && other->mapped) {
|
||||
if (other != surf->lock_surface && other->surface->mapped) {
|
||||
next_focus = other->surface;
|
||||
break;
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ static void handle_new_surface(struct wl_listener *listener, void *data) {
|
|||
surf->surface = lock_surface->surface;
|
||||
surf->output = output;
|
||||
surf->map.notify = handle_surface_map;
|
||||
wl_signal_add(&lock_surface->events.map, &surf->map);
|
||||
wl_signal_add(&lock_surface->surface->events.map, &surf->map);
|
||||
surf->destroy.notify = handle_surface_destroy;
|
||||
wl_signal_add(&lock_surface->events.destroy, &surf->destroy);
|
||||
surf->surface_commit.notify = handle_surface_commit;
|
||||
|
|
|
@ -172,6 +172,7 @@ sway_sources = files(
|
|||
'commands/input/repeat_delay.c',
|
||||
'commands/input/repeat_rate.c',
|
||||
'commands/input/scroll_button.c',
|
||||
'commands/input/scroll_button_lock.c',
|
||||
'commands/input/scroll_factor.c',
|
||||
'commands/input/scroll_method.c',
|
||||
'commands/input/tap.c',
|
||||
|
@ -223,7 +224,6 @@ sway_deps = [
|
|||
math,
|
||||
pango,
|
||||
pcre2,
|
||||
glesv2,
|
||||
pixman,
|
||||
threads,
|
||||
wayland_server,
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#endif
|
||||
|
||||
#define SWAY_XDG_SHELL_VERSION 2
|
||||
#define SWAY_LAYER_SHELL_VERSION 3
|
||||
#define SWAY_LAYER_SHELL_VERSION 4
|
||||
|
||||
#if WLR_HAS_DRM_BACKEND
|
||||
static void handle_drm_lease_request(struct wl_listener *listener, void *data) {
|
||||
|
@ -114,7 +114,11 @@ bool server_init(struct sway_server *server) {
|
|||
server->data_device_manager =
|
||||
wlr_data_device_manager_create(server->wl_display);
|
||||
|
||||
wlr_gamma_control_manager_v1_create(server->wl_display);
|
||||
server->gamma_control_manager_v1 =
|
||||
wlr_gamma_control_manager_v1_create(server->wl_display);
|
||||
server->gamma_control_set_gamma.notify = handle_gamma_control_set_gamma;
|
||||
wl_signal_add(&server->gamma_control_manager_v1->events.set_gamma,
|
||||
&server->gamma_control_set_gamma);
|
||||
|
||||
server->new_output.notify = handle_new_output;
|
||||
wl_signal_add(&server->backend->events.new_output, &server->new_output);
|
||||
|
@ -126,8 +130,7 @@ bool server_init(struct sway_server *server) {
|
|||
|
||||
server->idle = wlr_idle_create(server->wl_display);
|
||||
server->idle_notifier_v1 = wlr_idle_notifier_v1_create(server->wl_display);
|
||||
server->idle_inhibit_manager_v1 =
|
||||
sway_idle_inhibit_manager_v1_create(server->wl_display, server->idle);
|
||||
sway_idle_inhibit_manager_v1_init();
|
||||
|
||||
server->layer_shell = wlr_layer_shell_v1_create(server->wl_display,
|
||||
SWAY_LAYER_SHELL_VERSION);
|
||||
|
|
|
@ -185,6 +185,9 @@ The following commands may only be used in the configuration file.
|
|||
debug-events*, or as a x11 mouse button (button[1-3,8,9]). If set to
|
||||
_disable_, it disables the scroll_method on_button_down.
|
||||
|
||||
*input* <identifier> scroll_button_lock enabled|disabled
|
||||
Enables or disables scroll button lock for specified input device.
|
||||
|
||||
*input* <identifier> scroll_factor <floating point value>
|
||||
Changes the scroll factor for the specified input device. Scroll speed will
|
||||
be scaled by the given value, which must be non-negative.
|
||||
|
|
|
@ -1195,6 +1195,9 @@ following properties will be included for devices that support them:
|
|||
: int
|
||||
: The scroll button to use when _scroll_method_ is _on_button_down_. This
|
||||
will be given as an input event code
|
||||
|- scroll_button_lock
|
||||
: string
|
||||
: Whether scroll button lock is enabled. It can be _enabled_ or _disabled_
|
||||
|- dwt
|
||||
: string
|
||||
: Whether disable-while-typing is enabled. It can be _enabled_ or _disabled_
|
||||
|
|
|
@ -389,8 +389,8 @@ runtime.
|
|||
for_window <criteria> move container to output <output>
|
||||
|
||||
*bindsym* [--whole-window] [--border] [--exclude-titlebar] [--release] [--locked] \
|
||||
[--to-code] [--input-device=<device>] [--no-warn] [--no-repeat] [Group<1-4>+]<key combo> \
|
||||
<command>
|
||||
[--to-code] [--input-device=<device>] [--no-warn] [--no-repeat] [--inhibited] \
|
||||
[Group<1-4>+]<key combo> <command>
|
||||
Binds _key combo_ to execute the sway command _command_ when pressed. You
|
||||
may use XKB key names here (*wev*(1) is a good tool for discovering these).
|
||||
With the flag _--release_, the command is executed when the key combo is
|
||||
|
@ -454,7 +454,8 @@ runtime.
|
|||
```
|
||||
|
||||
*bindcode* [--whole-window] [--border] [--exclude-titlebar] [--release] \
|
||||
[--locked] [--input-device=<device>] [--no-warn] [Group<1-4>+]<code> <command>
|
||||
[--locked] [--input-device=<device>] [--no-warn] [--no-repeat] [--inhibited] \
|
||||
[Group<1-4>+]<code> <command>
|
||||
is also available for binding with key/button codes instead of key/button names.
|
||||
|
||||
*bindswitch* [--locked] [--no-warn] [--reload] <switch>:<state> <command>
|
||||
|
|
|
@ -17,7 +17,7 @@ void xdg_activation_v1_handle_request_activate(struct wl_listener *listener,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!xdg_surface->mapped) {
|
||||
if (!xdg_surface->surface->mapped) {
|
||||
// This is a startup notification. If we are tracking it, the data
|
||||
// field is a launcher_ctx.
|
||||
struct launcher_ctx *ctx = event->token->data;
|
||||
|
|
|
@ -82,7 +82,7 @@ void update_cursor(struct swaybar_seat *seat) {
|
|||
pointer->cursor_theme = wl_cursor_theme_load(
|
||||
cursor_theme, cursor_size * scale, seat->bar->shm);
|
||||
struct wl_cursor *cursor;
|
||||
cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr");
|
||||
cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "default");
|
||||
pointer->cursor_image = cursor->images[0];
|
||||
wl_surface_set_buffer_scale(pointer->cursor_surface, scale);
|
||||
wl_surface_attach(pointer->cursor_surface,
|
||||
|
@ -207,7 +207,7 @@ static void workspace_next(struct swaybar *bar, struct swaybar_output *output,
|
|||
}
|
||||
}
|
||||
|
||||
if (new) {
|
||||
if (new && new != active) {
|
||||
ipc_send_workspace_command(bar, new->name);
|
||||
|
||||
// Since we're asking Sway to switch to 'new', it should become visible.
|
||||
|
|
|
@ -426,12 +426,9 @@ bool ipc_initialize(struct swaybar *bar) {
|
|||
}
|
||||
free(res);
|
||||
|
||||
struct swaybar_config *config = bar->config;
|
||||
char subscribe[128]; // suitably large buffer
|
||||
len = snprintf(subscribe, 128,
|
||||
"[ \"barconfig_update\" , \"bar_state_update\" %s %s ]",
|
||||
config->binding_mode_indicator ? ", \"mode\"" : "",
|
||||
config->workspace_buttons ? ", \"workspace\"" : "");
|
||||
char *subscribe =
|
||||
"[ \"barconfig_update\", \"bar_state_update\", \"mode\", \"workspace\" ]";
|
||||
len = strlen(subscribe);
|
||||
free(ipc_single_command(bar->ipc_event_socketfd,
|
||||
IPC_SUBSCRIBE, subscribe, &len));
|
||||
return true;
|
||||
|
|
|
@ -106,7 +106,7 @@ static int register_host(sd_bus_message *msg, void *data, sd_bus_error *error) {
|
|||
sway_log(SWAY_DEBUG, "Registering Status Notifier Host '%s'", service);
|
||||
list_add(watcher->hosts, strdup(service));
|
||||
sd_bus_emit_signal(watcher->bus, obj_path, watcher->interface,
|
||||
"StatusNotifierHostRegistered", "s", service);
|
||||
"StatusNotifierHostRegistered", "");
|
||||
} else {
|
||||
sway_log(SWAY_DEBUG, "Status Notifier Host '%s' already registered", service);
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ static void update_cursor(struct swaynag_seat *seat) {
|
|||
pointer->cursor_theme = wl_cursor_theme_load(
|
||||
cursor_theme, cursor_size * swaynag->scale, swaynag->shm);
|
||||
struct wl_cursor *cursor =
|
||||
wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr");
|
||||
wl_cursor_theme_get_cursor(pointer->cursor_theme, "default");
|
||||
pointer->cursor_image = cursor->images[0];
|
||||
wl_surface_set_buffer_scale(pointer->cursor_surface,
|
||||
swaynag->scale);
|
||||
|
|
Loading…
Reference in a new issue