This commits enables the use of a combination of modifier keys for the floating_modifier command.

Using mostly the same code as sway/commands/bar/modifier.c to modify sway/commands/floating_modifier.c.
sway/input/cursor.c and sway/input/seatop_default.c are changed to check if all floating modifier keys are pressed, instead of just one.
This commit is contained in:
carpetoctopus 2026-05-01 13:43:31 +00:00
parent c857ca3a97
commit 7a2c9473fa
3 changed files with 31 additions and 13 deletions

View file

@ -8,17 +8,12 @@ struct cmd_results *cmd_floating_modifier(int argc, char **argv) {
if ((error = checkarg(argc, "floating_modifier", EXPECTED_AT_LEAST, 1))) {
return error;
}
if (strcasecmp(argv[0], "none") == 0) {
config->floating_mod = 0;
return cmd_results_new(CMD_SUCCESS, NULL);
}
uint32_t mod = get_modifier_mask_by_name(argv[0]);
if (!mod) {
return cmd_results_new(CMD_INVALID, "Invalid modifier");
}
if (argc == 1 || strcasecmp(argv[1], "normal") == 0) {
config->floating_mod_inverse = false;
} else if (strcasecmp(argv[1], "inverse") == 0) {
@ -28,6 +23,26 @@ struct cmd_results *cmd_floating_modifier(int argc, char **argv) {
"Usage: floating_modifier <mod> [inverse|normal]");
}
uint32_t mod = 0;
list_t *split = split_string(argv[0], "+");
for (int i = 0; i < split->length; ++i) {
uint32_t tmp_mod;
if ((tmp_mod = get_modifier_mask_by_name(split->items[i])) > 0) {
mod |= tmp_mod;
} else if (strcmp(split->items[i], "none") == 0) {
error = cmd_results_new(CMD_INVALID,
"none cannot be used along with other modifiers");
list_free_items_and_destroy(split);
return error;
} else {
error = cmd_results_new(CMD_INVALID,
"Invalid modifier '%s'", (char *)split->items[i]);
list_free_items_and_destroy(split);
return error;
}
}
list_free_items_and_destroy(split);
config->floating_mod = mod;
return cmd_results_new(CMD_SUCCESS, NULL);

View file

@ -746,7 +746,7 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
// TODO: floating resize should support graphics tablet events
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(cursor->seat->wlr_seat);
uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
bool mod_pressed = modifiers & config->floating_mod;
bool mod_pressed = (modifiers & config->floating_mod) == config->floating_mod;
bool surface_supports_tablet_events =
surface && wlr_surface_accepts_tablet_v2(surface, tablet_v2);

View file

@ -248,10 +248,13 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
bool is_floating_or_child = container_is_floating_or_child(cont);
bool is_fullscreen_or_child = container_is_fullscreen_or_child(cont);
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
bool mod_pressed = keyboard &&
(wlr_keyboard_get_modifiers(keyboard) & config->floating_mod);
// Handle beginning floating move
bool mod_pressed = 0;
if (keyboard) {
uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard);
mod_pressed = (modifiers & config->floating_mod) == config->floating_mod;
}
// Handle beginning floating move
if (is_floating_or_child && !is_fullscreen_or_child && mod_pressed) {
seat_set_focus_container(seat,
seat_get_focus_inactive_view(seat, &cont->node));
@ -356,7 +359,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
bool mod_pressed = modifiers & config->floating_mod;
bool mod_pressed = (modifiers & config->floating_mod) == config->floating_mod;
uint32_t mod_move_btn = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
uint32_t mod_resize_btn = config->floating_mod_inverse ? BTN_LEFT : BTN_RIGHT;
bool mod_move_btn_pressed = mod_pressed && button == mod_move_btn;