Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to keep cursor active when using seat * hide_cursor. #8321

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/sway/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ enum seat_config_hide_cursor_when_typing {
HIDE_WHEN_TYPING_DISABLE,
};

enum seat_config_hide_cursor_but_keep_active {
HIDE_CURSOR_BUT_KEEP_ACTIVE_DEFAULT, // the default is currently disabled
HIDE_CURSOR_BUT_KEEP_ACTIVE_ENABLE,
HIDE_CURSOR_BUT_KEEP_ACTIVE_DISABLE,
};

enum seat_config_allow_constrain {
CONSTRAIN_DEFAULT, // the default is currently enabled
CONSTRAIN_ENABLE,
Expand Down Expand Up @@ -243,6 +249,7 @@ struct seat_config {
list_t *attachments; // list of seat_attachment configs
int hide_cursor_timeout;
enum seat_config_hide_cursor_when_typing hide_cursor_when_typing;
enum seat_config_hide_cursor_but_keep_active hide_cursor_but_keep_active;
enum seat_config_allow_constrain allow_constrain;
enum seat_config_shortcuts_inhibit shortcuts_inhibit;
enum seat_keyboard_grouping keyboard_grouping;
Expand Down
4 changes: 0 additions & 4 deletions include/sway/input/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@ struct sway_cursor {

struct wl_event_source *hide_source;
bool hidden;
// This field is just a cache of the field in seat_config in order to avoid
// costly seat_config lookups on every keypress. HIDE_WHEN_TYPING_DEFAULT
// indicates that there is no cached value.
enum seat_config_hide_cursor_when_typing hide_when_typing;

size_t pressed_button_count;
};
Expand Down
5 changes: 1 addition & 4 deletions include/sway/input/seat.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct sway_drag {
struct sway_seat {
struct wlr_seat *wlr_seat;
struct sway_cursor *cursor;
struct seat_config *config;

// Seat scene tree structure
// - scene_tree
Expand Down Expand Up @@ -243,10 +244,6 @@ void seat_for_each_node(struct sway_seat *seat,

void seat_apply_config(struct sway_seat *seat, struct seat_config *seat_config);

struct seat_config *seat_get_config(struct sway_seat *seat);

struct seat_config *seat_get_config_by_name(const char *name);

void seat_idle_notify_activity(struct sway_seat *seat,
enum sway_input_idle_source source);

Expand Down
18 changes: 8 additions & 10 deletions sway/commands/seat/hide_cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,15 @@ struct cmd_results *seat_cmd_hide_cursor(int argc, char **argv) {
}
seat_config->hide_cursor_timeout = timeout;
} else {
if (strcmp(argv[0], "when-typing") != 0) {
if (strcmp(argv[0], "when-typing") == 0) {
seat_config->hide_cursor_when_typing = parse_boolean(argv[1], true) ?
HIDE_WHEN_TYPING_ENABLE : HIDE_WHEN_TYPING_DISABLE;
} else if (strcmp(argv[0], "but-keep-active") == 0) {
seat_config->hide_cursor_but_keep_active = parse_boolean(argv[1], true) ?
HIDE_CURSOR_BUT_KEEP_ACTIVE_ENABLE : HIDE_CURSOR_BUT_KEEP_ACTIVE_DISABLE;
} else {
return cmd_results_new(CMD_INVALID,
"Expected 'hide_cursor <timeout>|when-typing [enable|disable]'");
}
seat_config->hide_cursor_when_typing = parse_boolean(argv[1], true) ?
HIDE_WHEN_TYPING_ENABLE : HIDE_WHEN_TYPING_DISABLE;

// Invalidate all the caches for this config
struct sway_seat *seat = NULL;
wl_list_for_each(seat, &server.input->seats, link) {
seat->cursor->hide_when_typing = HIDE_WHEN_TYPING_DEFAULT;
"Expected 'hide_cursor <timeout>|when-typing|but-keep-active [enable|disable]'");
}
}

Expand Down
5 changes: 5 additions & 0 deletions sway/config/seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct seat_config *new_seat_config(const char* name) {
}
seat->hide_cursor_timeout = -1;
seat->hide_cursor_when_typing = HIDE_WHEN_TYPING_DEFAULT;
seat->hide_cursor_but_keep_active = HIDE_CURSOR_BUT_KEEP_ACTIVE_DEFAULT;
seat->allow_constrain = CONSTRAIN_DEFAULT;
seat->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT;
seat->keyboard_grouping = KEYBOARD_GROUP_DEFAULT;
Expand Down Expand Up @@ -154,6 +155,10 @@ void merge_seat_config(struct seat_config *dest, struct seat_config *source) {
dest->hide_cursor_when_typing = source->hide_cursor_when_typing;
}

if (source->hide_cursor_but_keep_active != HIDE_CURSOR_BUT_KEEP_ACTIVE_DEFAULT) {
dest->hide_cursor_but_keep_active = source->hide_cursor_but_keep_active;
}

if (source->allow_constrain != CONSTRAIN_DEFAULT) {
dest->allow_constrain = source->allow_constrain;
}
Expand Down
34 changes: 8 additions & 26 deletions sway/input/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ void cursor_update_image(struct sway_cursor *cursor,
static void cursor_hide(struct sway_cursor *cursor) {
wlr_cursor_unset_image(cursor->cursor);
cursor->hidden = true;
wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat);
if (cursor->seat->config->hide_cursor_but_keep_active
!= HIDE_CURSOR_BUT_KEEP_ACTIVE_ENABLE) {
wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat);
}
}

static int hide_notify(void *data) {
Expand All @@ -198,10 +201,8 @@ int cursor_get_timeout(struct sway_cursor *cursor) {
return 0;
}

struct seat_config *sc = seat_get_config(cursor->seat);
if (!sc) {
sc = seat_get_config_by_name("*");
}
struct seat_config *sc = cursor->seat->config;

int timeout = sc ? sc->hide_cursor_timeout : 0;
if (timeout < 0) {
timeout = 0;
Expand All @@ -214,23 +215,7 @@ void cursor_notify_key_press(struct sway_cursor *cursor) {
return;
}

if (cursor->hide_when_typing == HIDE_WHEN_TYPING_DEFAULT) {
// No cached value, need to lookup in the seat_config
const struct seat_config *seat_config = seat_get_config(cursor->seat);
if (!seat_config) {
seat_config = seat_get_config_by_name("*");
if (!seat_config) {
return;
}
}
cursor->hide_when_typing = seat_config->hide_cursor_when_typing;
// The default is currently disabled
if (cursor->hide_when_typing == HIDE_WHEN_TYPING_DEFAULT) {
cursor->hide_when_typing = HIDE_WHEN_TYPING_DISABLE;
}
}

if (cursor->hide_when_typing == HIDE_WHEN_TYPING_ENABLE) {
if (cursor->seat->config->hide_cursor_when_typing == HIDE_WHEN_TYPING_ENABLE) {
cursor_hide(cursor);
}
}
Expand Down Expand Up @@ -1339,10 +1324,7 @@ void handle_pointer_constraint(struct wl_listener *listener, void *data) {

void sway_cursor_constrain(struct sway_cursor *cursor,
struct wlr_pointer_constraint_v1 *constraint) {
struct seat_config *config = seat_get_config(cursor->seat);
if (!config) {
config = seat_get_config_by_name("*");
}
struct seat_config *config = cursor->seat->config;

if (!config || config->allow_constrain == CONSTRAIN_DISABLE) {
return;
Expand Down
36 changes: 18 additions & 18 deletions sway/input/input-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,15 @@ static struct sway_input_device *input_sway_device_from_wlr(
static bool input_has_seat_fallback_configuration(void) {
struct sway_seat *seat = NULL;
wl_list_for_each(seat, &server.input->seats, link) {
struct seat_config *seat_config = seat_get_config(seat);
struct seat_config *seat_config = NULL;
struct seat_config *sc = NULL;
for (int i = 0; i < config->seat_configs->length; ++i ) {
sc = config->seat_configs->items[i];
if (strcmp(seat->wlr_seat->name, sc->name) == 0) {
seat_config = sc;
break;
}
}
if (seat_config && strcmp(seat_config->name, "*") != 0
&& seat_config->fallback != -1) {
return true;
Expand Down Expand Up @@ -257,10 +265,9 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
bool added = false;
struct sway_seat *seat = NULL;
wl_list_for_each(seat, &input->seats, link) {
struct seat_config *seat_config = seat_get_config(seat);
bool has_attachment = seat_config &&
(seat_config_get_attachment(seat_config, input_device->identifier) ||
seat_config_get_attachment(seat_config, "*"));
bool has_attachment = seat->config &&
(seat_config_get_attachment(seat->config, input_device->identifier) ||
seat_config_get_attachment(seat->config, "*"));

if (has_attachment) {
seat_add_device(seat, input_device);
Expand All @@ -270,8 +277,7 @@ static void handle_new_input(struct wl_listener *listener, void *data) {

if (!added) {
wl_list_for_each(seat, &input->seats, link) {
struct seat_config *seat_config = seat_get_config(seat);
if (seat_config && seat_config->fallback == 1) {
if (seat->config && seat->config->fallback == 1) {
seat_add_device(seat, input_device);
added = true;
}
Expand Down Expand Up @@ -336,13 +342,8 @@ static void handle_keyboard_shortcuts_inhibit_new_inhibitor(
}

if (inhibit == SHORTCUTS_INHIBIT_DEFAULT) {
struct seat_config *config = seat_get_config(seat);
if (!config) {
config = seat_get_config_by_name("*");
}

if (config) {
inhibit = config->shortcuts_inhibit;
if (seat->config) {
inhibit = seat->config->shortcuts_inhibit;
}
}

Expand Down Expand Up @@ -633,7 +634,7 @@ void input_manager_apply_seat_config(struct seat_config *seat_config) {
wl_list_for_each(seat, &server.input->seats, link) {
// Only apply the wildcard config directly if there is no seat
// specific config
struct seat_config *sc = seat_get_config(seat);
struct seat_config *sc = seat->config;
if (!sc) {
sc = seat_config;
}
Expand All @@ -655,7 +656,7 @@ void input_manager_apply_seat_config(struct seat_config *seat_config) {
list_t *seat_list = create_list();
struct sway_seat *seat = NULL;
wl_list_for_each(seat, &server.input->seats, link) {
struct seat_config *seat_config = seat_get_config(seat);
struct seat_config *seat_config = seat->config;
if (!seat_config) {
continue;
}
Expand Down Expand Up @@ -683,8 +684,7 @@ void input_manager_apply_seat_config(struct seat_config *seat_config) {
}
} else {
wl_list_for_each(seat, &server.input->seats, link) {
struct seat_config *seat_config = seat_get_config(seat);
if (seat_config && seat_config->fallback == 1) {
if (seat->config && seat->config->fallback == 1) {
seat_add_device(seat, input_device);
} else {
seat_remove_device(seat, input_device);
Expand Down
11 changes: 2 additions & 9 deletions sway/input/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,10 +831,7 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
}

struct sway_seat *seat = keyboard->seat_device->sway_seat;
struct seat_config *sc = seat_get_config(seat);
if (!sc) {
sc = seat_get_config_by_name("*");
}
struct seat_config *sc = seat->config;

switch (sc ? sc->keyboard_grouping : KEYBOARD_GROUP_DEFAULT) {
case KEYBOARD_GROUP_NONE:
Expand All @@ -854,17 +851,13 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) {
static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
struct sway_input_device *device = keyboard->seat_device->input_device;
struct sway_seat *seat = keyboard->seat_device->sway_seat;
struct seat_config *sc = seat_get_config(seat);
struct seat_config *sc = seat->config;

if (device->is_virtual) {
// Virtual devices should not be grouped
return;
}

if (!sc) {
sc = seat_get_config_by_name("*");
}

if (sc && sc->keyboard_grouping == KEYBOARD_GROUP_NONE) {
// Keyboard grouping is disabled for the seat
return;
Expand Down
35 changes: 4 additions & 31 deletions sway/input/seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -984,13 +984,9 @@ void seat_configure_xcursor(struct sway_seat *seat) {
unsigned cursor_size = 24;
const char *cursor_theme = NULL;

const struct seat_config *seat_config = seat_get_config(seat);
if (!seat_config) {
seat_config = seat_get_config_by_name("*");
}
if (seat_config) {
cursor_size = seat_config->xcursor_theme.size;
cursor_theme = seat_config->xcursor_theme.name;
if (seat->config) {
cursor_size = seat->config->xcursor_theme.size;
cursor_theme = seat->config->xcursor_theme.name;
}

if (seat == input_manager_get_default_seat()) {
Expand Down Expand Up @@ -1493,6 +1489,7 @@ void seat_apply_config(struct sway_seat *seat,
return;
}

seat->config = seat_config;
seat->idle_inhibit_sources = seat_config->idle_inhibit_sources;
seat->idle_wake_sources = seat_config->idle_wake_sources;

Expand All @@ -1503,30 +1500,6 @@ void seat_apply_config(struct sway_seat *seat,
}
}

struct seat_config *seat_get_config(struct sway_seat *seat) {
struct seat_config *seat_config = NULL;
for (int i = 0; i < config->seat_configs->length; ++i ) {
seat_config = config->seat_configs->items[i];
if (strcmp(seat->wlr_seat->name, seat_config->name) == 0) {
return seat_config;
}
}

return NULL;
}

struct seat_config *seat_get_config_by_name(const char *name) {
struct seat_config *seat_config = NULL;
for (int i = 0; i < config->seat_configs->length; ++i ) {
seat_config = config->seat_configs->items[i];
if (strcmp(name, seat_config->name) == 0) {
return seat_config;
}
}

return NULL;
}

void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec,
uint32_t button, enum wl_pointer_button_state state) {
seat->last_button_serial = wlr_seat_pointer_notify_button(seat->wlr_seat,
Expand Down
5 changes: 4 additions & 1 deletion sway/sway-input.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ correct seat.
Set this seat as the fallback seat. A fallback seat will attach any device
not explicitly attached to another seat (similar to a "default" seat).

*seat* <name> hide_cursor <timeout>|when-typing [enable|disable]
*seat* <name> hide_cursor <timeout>|when-typing|but-keep-active [enable|disable]
Hides the cursor image after the specified event occurred.

If _timeout_ is specified, then the cursor will be hidden after _timeout_
Expand All @@ -273,6 +273,9 @@ correct seat.
certain types of software (Gimp, Blender etc) that rely on simultaneous
input from mouse and keyboard.

If _but-keep-active_ is enabled, then the cursor will remain active when
hidden. This solves the issues with _when-typing_ as mentioned above.

*seat* <name> idle_inhibit <sources...>
Sets the set of input event sources which can prevent the seat from
becoming idle, as a space separated list of source names. Valid names are
Expand Down