mirror of
https://github.com/swaywm/sway.git
synced 2026-04-23 06:46:27 -04:00
Merge 2e64eeda42 into 78b5c0a77e
This commit is contained in:
commit
3074bf0c97
17 changed files with 437 additions and 0 deletions
|
|
@ -202,6 +202,7 @@ sway_cmd cmd_ws_auto_back_and_forth;
|
|||
sway_cmd cmd_xwayland;
|
||||
|
||||
sway_cmd bar_cmd_bindcode;
|
||||
sway_cmd bar_cmd_bindgesture;
|
||||
sway_cmd bar_cmd_binding_mode_indicator;
|
||||
sway_cmd bar_cmd_bindsym;
|
||||
sway_cmd bar_cmd_colors;
|
||||
|
|
@ -228,6 +229,7 @@ sway_cmd bar_cmd_tray_bindsym;
|
|||
sway_cmd bar_cmd_tray_output;
|
||||
sway_cmd bar_cmd_tray_padding;
|
||||
sway_cmd bar_cmd_unbindcode;
|
||||
sway_cmd bar_cmd_unbindgesture;
|
||||
sway_cmd bar_cmd_unbindsym;
|
||||
sway_cmd bar_cmd_wrap_scroll;
|
||||
sway_cmd bar_cmd_workspace_buttons;
|
||||
|
|
|
|||
|
|
@ -350,6 +350,7 @@ struct bar_config {
|
|||
list_t *outputs;
|
||||
char *position;
|
||||
list_t *bindings;
|
||||
list_t *gestures;
|
||||
char *status_command;
|
||||
enum pango_markup_config pango_markup;
|
||||
char *font;
|
||||
|
|
@ -403,6 +404,11 @@ struct bar_binding {
|
|||
char *command;
|
||||
};
|
||||
|
||||
struct bar_gesture {
|
||||
struct gesture gesture;
|
||||
char *command;
|
||||
};
|
||||
|
||||
#if HAVE_TRAY
|
||||
struct tray_binding {
|
||||
uint32_t button;
|
||||
|
|
@ -713,6 +719,8 @@ void free_bar_config(struct bar_config *bar);
|
|||
|
||||
void free_bar_binding(struct bar_binding *binding);
|
||||
|
||||
void free_bar_gesture(struct bar_gesture *binding);
|
||||
|
||||
void free_workspace_config(struct workspace_config *wsc);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "pool-buffer.h"
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
|
||||
struct swaybar_config;
|
||||
struct swaybar_output;
|
||||
|
|
@ -31,6 +32,7 @@ struct swaybar {
|
|||
struct zwlr_layer_shell_v1 *layer_shell;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
struct wl_shm *shm;
|
||||
struct zwp_pointer_gestures_v1 *pointer_gestures;
|
||||
|
||||
struct swaybar_config *config;
|
||||
struct status_line *status;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdint.h>
|
||||
#include <wayland-client.h>
|
||||
#include "../include/config.h"
|
||||
#include "gesture.h"
|
||||
#include "list.h"
|
||||
#include "util.h"
|
||||
#include <pango/pangocairo.h>
|
||||
|
|
@ -25,6 +26,11 @@ struct swaybar_binding {
|
|||
bool release;
|
||||
};
|
||||
|
||||
struct swaybar_gesture {
|
||||
struct gesture gesture;
|
||||
char *command;
|
||||
};
|
||||
|
||||
struct swaybar_config {
|
||||
char *status_command;
|
||||
bool pango_markup;
|
||||
|
|
@ -41,6 +47,7 @@ struct swaybar_config {
|
|||
bool workspace_buttons;
|
||||
uint32_t workspace_min_width;
|
||||
list_t *bindings;
|
||||
list_t *gestures;
|
||||
struct wl_list outputs; // config_output::link
|
||||
int height;
|
||||
int status_padding;
|
||||
|
|
@ -91,5 +98,6 @@ struct swaybar_config *init_config(void);
|
|||
void free_config(struct swaybar_config *config);
|
||||
uint32_t parse_position(const char *position);
|
||||
void free_binding(struct swaybar_binding *binding);
|
||||
void free_gesture(struct swaybar_gesture *gesture);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <wayland-client.h>
|
||||
#include <stdbool.h>
|
||||
#include "gesture.h"
|
||||
#include "list.h"
|
||||
|
||||
#define SWAY_SCROLL_UP KEY_MAX + 1
|
||||
|
|
@ -66,6 +67,10 @@ struct swaybar_seat {
|
|||
struct wl_seat *wl_seat;
|
||||
struct swaybar_pointer pointer;
|
||||
struct swaybar_touch touch;
|
||||
struct zwp_pointer_gesture_hold_v1 *hold;
|
||||
struct zwp_pointer_gesture_pinch_v1 *pinch;
|
||||
struct zwp_pointer_gesture_swipe_v1 *swipe;
|
||||
struct gesture_tracker gestures;
|
||||
struct wl_list link; // swaybar_seat:link
|
||||
struct swaybar_scroll_axis axis[2];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@ bool handle_ipc_readable(struct swaybar *bar);
|
|||
bool ipc_get_workspaces(struct swaybar *bar);
|
||||
void ipc_send_workspace_command(struct swaybar *bar, const char *ws);
|
||||
void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind);
|
||||
void ipc_execute_gesture(struct swaybar *bar, struct swaybar_gesture *gest);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ protocols = [
|
|||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml'],
|
||||
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
||||
['wlr-layer-shell-unstable-v1.xml'],
|
||||
|
|
@ -25,6 +26,7 @@ protocols = [
|
|||
client_protocols = [
|
||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'],
|
||||
['wlr-layer-shell-unstable-v1.xml'],
|
||||
['wlr-input-inhibitor-unstable-v1.xml'],
|
||||
]
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
// Must be in alphabetical order for bsearch
|
||||
static const struct cmd_handler bar_handlers[] = {
|
||||
{ "bindcode", bar_cmd_bindcode },
|
||||
{ "bindgesture", bar_cmd_bindgesture },
|
||||
{ "binding_mode_indicator", bar_cmd_binding_mode_indicator },
|
||||
{ "bindsym", bar_cmd_bindsym },
|
||||
{ "colors", bar_cmd_colors },
|
||||
|
|
@ -34,6 +35,7 @@ static const struct cmd_handler bar_handlers[] = {
|
|||
{ "tray_output", bar_cmd_tray_output },
|
||||
{ "tray_padding", bar_cmd_tray_padding },
|
||||
{ "unbindcode", bar_cmd_unbindcode },
|
||||
{ "unbindgesture", bar_cmd_unbindgesture },
|
||||
{ "unbindsym", bar_cmd_unbindsym },
|
||||
{ "workspace_buttons", bar_cmd_workspace_buttons },
|
||||
{ "workspace_min_width", bar_cmd_workspace_min_width },
|
||||
|
|
|
|||
109
sway/commands/bar/gesture.c
Normal file
109
sway/commands/bar/gesture.c
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "log.h"
|
||||
#include "stringop.h"
|
||||
#include "sway/commands.h"
|
||||
|
||||
/**
|
||||
* Add gesture binding to config
|
||||
*/
|
||||
static struct cmd_results *bar_gesture_add(
|
||||
struct bar_gesture *binding, const char *name) {
|
||||
list_t *gestures = config->current_bar->gestures;
|
||||
|
||||
// overwrite the binding if it already exists
|
||||
bool overwritten = false;
|
||||
for (int i = 0; i < gestures->length; ++i) {
|
||||
struct bar_gesture *current = gestures->items[i];
|
||||
if (gesture_equal(¤t->gesture, &binding->gesture)) {
|
||||
|
||||
overwritten = true;
|
||||
gestures->items[i] = binding;
|
||||
free_bar_gesture(current);
|
||||
sway_log(SWAY_DEBUG, "[bar %s] Updated gesture for %s",
|
||||
config->current_bar->id, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!overwritten) {
|
||||
list_add(gestures, binding);
|
||||
sway_log(SWAY_DEBUG, "[bar %s] Added binding for %s",
|
||||
config->current_bar->id, name);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove gesture binding from config
|
||||
*/
|
||||
static struct cmd_results *bar_gesture_remove(
|
||||
struct bar_gesture *binding, const char *name) {
|
||||
list_t *gestures = config->current_bar->gestures;
|
||||
|
||||
for (int i = 0; i < gestures->length; ++i) {
|
||||
struct bar_gesture *current = gestures->items[i];
|
||||
if (gesture_equal(¤t->gesture, &binding->gesture)) {
|
||||
sway_log(SWAY_DEBUG, "[bar %s] Unbound binding for %s",
|
||||
config->current_bar->id, name);
|
||||
|
||||
free_bar_gesture(current);
|
||||
free_bar_gesture(binding);
|
||||
list_del(gestures, i);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
free_bar_gesture(binding);
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Could not find gesture for [bar %s] %s",
|
||||
config->current_bar->id, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and execute bindgesture or unbindgesture command.
|
||||
*/
|
||||
static struct cmd_results *bar_cmd_gesture(int argc, char **argv, bool unbind) {
|
||||
int minargs = 2;
|
||||
char *bindtype = "bindgesture";
|
||||
if (unbind) {
|
||||
minargs--;
|
||||
bindtype = "unbindgesture";
|
||||
}
|
||||
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, minargs))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
struct bar_gesture *binding = calloc(1, sizeof(struct bar_gesture));
|
||||
if (!binding) {
|
||||
return cmd_results_new(CMD_FAILURE, "Unable to allocate binding");
|
||||
}
|
||||
char *errmsg = NULL;
|
||||
if ((errmsg = gesture_parse(argv[0], &binding->gesture))) {
|
||||
free(binding);
|
||||
struct cmd_results *final = cmd_results_new(
|
||||
CMD_FAILURE, "Invalid %s command (%s)", bindtype, errmsg);
|
||||
free(errmsg);
|
||||
return final;
|
||||
}
|
||||
|
||||
if (unbind) {
|
||||
return bar_gesture_remove(binding, argv[0]);
|
||||
}
|
||||
binding->command = join_args(argv + 1, argc - 1);
|
||||
return bar_gesture_add(binding, argv[0]);
|
||||
}
|
||||
|
||||
struct cmd_results *bar_cmd_bindgesture(int argc, char **argv) {
|
||||
return bar_cmd_gesture(argc, argv, false);
|
||||
}
|
||||
|
||||
struct cmd_results *bar_cmd_unbindgesture(int argc, char **argv) {
|
||||
return bar_cmd_gesture(argc, argv, true);
|
||||
}
|
||||
|
|
@ -27,6 +27,14 @@ void free_bar_binding(struct bar_binding *binding) {
|
|||
free(binding);
|
||||
}
|
||||
|
||||
void free_bar_gesture(struct bar_gesture *gesture) {
|
||||
if (!gesture) {
|
||||
return;
|
||||
}
|
||||
free(gesture->command);
|
||||
free(gesture);
|
||||
}
|
||||
|
||||
void free_bar_config(struct bar_config *bar) {
|
||||
if (!bar) {
|
||||
return;
|
||||
|
|
@ -45,6 +53,12 @@ void free_bar_config(struct bar_config *bar) {
|
|||
}
|
||||
}
|
||||
list_free(bar->bindings);
|
||||
if (bar->gestures) {
|
||||
for (int i = 0; i < bar->gestures->length; i++) {
|
||||
free_bar_gesture(bar->gestures->items[i]);
|
||||
}
|
||||
}
|
||||
list_free(bar->gestures);
|
||||
list_free_items_and_destroy(bar->outputs);
|
||||
if (bar->client != NULL) {
|
||||
wl_client_destroy(bar->client);
|
||||
|
|
@ -115,6 +129,9 @@ struct bar_config *default_bar_config(void) {
|
|||
if (!(bar->bindings = create_list())) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (!(bar->gestures = create_list())) {
|
||||
goto cleanup;
|
||||
}
|
||||
// set default colors
|
||||
if (!(bar->colors.background = strndup("#000000ff", 9))) {
|
||||
goto cleanup;
|
||||
|
|
|
|||
|
|
@ -1298,6 +1298,25 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
|
|||
json_object_object_add(json, "bindings", bindings);
|
||||
}
|
||||
|
||||
if (bar->gestures->length > 0) {
|
||||
json_object *gestures = json_object_new_array();
|
||||
for (int i = 0; i < bar->gestures->length; ++i) {
|
||||
struct bar_gesture *binding = bar->gestures->items[i];
|
||||
struct gesture *gesture = &binding->gesture;
|
||||
json_object *bind = json_object_new_object();
|
||||
json_object_object_add(bind, "type",
|
||||
json_object_new_int(gesture->type));
|
||||
json_object_object_add(bind, "fingers",
|
||||
json_object_new_int(gesture->fingers));
|
||||
json_object_object_add(bind, "directions",
|
||||
json_object_new_int(gesture->directions));
|
||||
json_object_object_add(bind, "command",
|
||||
json_object_new_string(binding->command));
|
||||
json_object_array_add(gestures, bind);
|
||||
}
|
||||
json_object_object_add(json, "gestures", gestures);
|
||||
}
|
||||
|
||||
// Add outputs if defined
|
||||
if (bar->outputs && bar->outputs->length > 0) {
|
||||
json_object *outputs = json_object_new_array();
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ sway_sources = files(
|
|||
'commands/bar/colors.c',
|
||||
'commands/bar/font.c',
|
||||
'commands/bar/gaps.c',
|
||||
'commands/bar/gesture.c',
|
||||
'commands/bar/height.c',
|
||||
'commands/bar/hidden_state.c',
|
||||
'commands/bar/icon_theme.c',
|
||||
|
|
|
|||
|
|
@ -27,6 +27,14 @@ runtime.
|
|||
an event code, which can be obtaining from *libinput debug-events*. To
|
||||
disable the default behavior for a button, use the command _nop_.
|
||||
|
||||
*bindgesture* <gesture>[:<fingers>][:directions] <command>
|
||||
Executes _command_ when the _gesture_ has been detected. _gesture_ can be
|
||||
_hold_, _pinch_ or _swipe_. The optional _fingers_ allows you to limit the
|
||||
binding to gestures with only a certain number of finger. The optional
|
||||
_directions_ allows you to limit the binding to a gesture in a certain
|
||||
direction, i.e. either _up_, _down_, _left_ or _right_ as well as
|
||||
_inward_, _outward_, _clockwise_ and _counterclockwise_.
|
||||
|
||||
*bindsym* [--release] button[1-9]|<event-name> <command>
|
||||
Executes _command_ when the mouse button has been pressed (or if _released_
|
||||
is given, when the button has been released). The buttons can be given as a
|
||||
|
|
@ -128,6 +136,9 @@ runtime.
|
|||
*unbindcode* [--release] <event-code>
|
||||
Removes the binding with the given <event-code>.
|
||||
|
||||
*unbindgesture* <gesture>[:<fingers>][:directions]
|
||||
Removes the gesture binding with the given <gesture>, etc.
|
||||
|
||||
*unbindsym* [--release] button[1-9]|<event-name>
|
||||
Removes the binding with the given <button> or <event-name>.
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "pool-buffer.h"
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
|
||||
void free_workspaces(struct wl_list *list) {
|
||||
struct swaybar_workspace *ws, *tmp;
|
||||
|
|
@ -362,6 +363,9 @@ static void handle_global(void *data, struct wl_registry *registry,
|
|||
} else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) {
|
||||
bar->xdg_output_manager = wl_registry_bind(registry, name,
|
||||
&zxdg_output_manager_v1_interface, 2);
|
||||
} else if (strcmp(interface, zwp_pointer_gestures_v1_interface.name) == 0) {
|
||||
bar->pointer_gestures = wl_registry_bind(registry, name,
|
||||
&zwp_pointer_gestures_v1_interface, 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ struct swaybar_config *init_config(void) {
|
|||
config->workspace_buttons = true;
|
||||
config->workspace_min_width = 0;
|
||||
config->bindings = create_list();
|
||||
config->gestures = create_list();
|
||||
wl_list_init(&config->outputs);
|
||||
config->status_padding = 1;
|
||||
config->status_edge_padding = 3;
|
||||
|
|
@ -93,6 +94,14 @@ void free_binding(struct swaybar_binding *binding) {
|
|||
free(binding);
|
||||
}
|
||||
|
||||
void free_gesture(struct swaybar_gesture *gesture) {
|
||||
if (!gesture) {
|
||||
return;
|
||||
}
|
||||
free(gesture->command);
|
||||
free(gesture);
|
||||
}
|
||||
|
||||
#if HAVE_TRAY
|
||||
void free_tray_binding(struct tray_binding *binding) {
|
||||
if (!binding) {
|
||||
|
|
@ -114,6 +123,11 @@ void free_config(struct swaybar_config *config) {
|
|||
free_binding(binding);
|
||||
}
|
||||
list_free(config->bindings);
|
||||
for (int i = 0; i < config->gestures->length; i++) {
|
||||
struct swaybar_gesture *gesture = config->gestures->items[i];
|
||||
free_gesture(gesture);
|
||||
}
|
||||
list_free(config->gestures);
|
||||
struct config_output *coutput, *tmp;
|
||||
wl_list_for_each_safe(coutput, tmp, &config->outputs, link) {
|
||||
wl_list_remove(&coutput->link);
|
||||
|
|
|
|||
198
swaybar/input.c
198
swaybar/input.c
|
|
@ -9,6 +9,7 @@
|
|||
#include "swaybar/config.h"
|
||||
#include "swaybar/input.h"
|
||||
#include "swaybar/ipc.h"
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
|
||||
void free_hotspots(struct wl_list *list) {
|
||||
struct swaybar_hotspot *hotspot, *tmp;
|
||||
|
|
@ -118,6 +119,11 @@ static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer,
|
|||
uint32_t serial, struct wl_surface *surface) {
|
||||
struct swaybar_seat *seat = data;
|
||||
seat->pointer.current = NULL;
|
||||
|
||||
// Cancel any ongoing gesture if pointer leaves bar
|
||||
if(!gesture_tracker_check(&seat->gestures, GESTURE_TYPE_NONE)) {
|
||||
gesture_tracker_cancel(&seat->gestures);
|
||||
}
|
||||
}
|
||||
|
||||
static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
||||
|
|
@ -461,6 +467,174 @@ static const struct wl_touch_listener touch_listener = {
|
|||
.orientation = wl_touch_orientation,
|
||||
};
|
||||
|
||||
|
||||
static bool gesture_on_bar(struct swaybar_seat *seat,
|
||||
struct wl_surface *surface) {
|
||||
struct swaybar_output *output;
|
||||
|
||||
wl_list_for_each(output, &seat->bar->outputs, link) {
|
||||
if (output->surface == surface) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if bar has any binding for gesture
|
||||
static bool bar_gestures_check(struct swaybar *bar,
|
||||
enum gesture_type type, uint8_t fingers) {
|
||||
for (int i = 0; i < bar->config->gestures->length; i++) {
|
||||
struct swaybar_gesture *binding = bar->config->gestures->items[i];
|
||||
if (gesture_check(&binding->gesture, type, fingers)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check bar gesture binding for match
|
||||
static struct swaybar_gesture *bar_gestures_match(struct swaybar *bar,
|
||||
struct gesture *gesture) {
|
||||
struct swaybar_gesture *current = NULL;
|
||||
|
||||
for (int i = 0; i < bar->config->gestures->length; i++) {
|
||||
struct swaybar_gesture *binding = bar->config->gestures->items[i];
|
||||
if (gesture_match(&binding->gesture, gesture, false)) {
|
||||
if (current &&
|
||||
gesture_compare(¤t->gesture, &binding->gesture) < 0) {
|
||||
continue;
|
||||
}
|
||||
current = binding;
|
||||
}
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
static void gesture_begin(struct swaybar_seat* seat, struct wl_surface *surface,
|
||||
enum gesture_type type, uint8_t fingers) {
|
||||
// We only want to respond to holds on a bar surface
|
||||
if (!gesture_on_bar(seat, surface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure there is a binding for this gesture
|
||||
if (!bar_gestures_check(seat->bar, type, fingers)) {
|
||||
sway_log(SWAY_DEBUG, "Ignore tracking gesture without binding: %s:%u:any",
|
||||
gesture_type_string(type), fingers);
|
||||
return;
|
||||
}
|
||||
|
||||
gesture_tracker_begin(&seat->gestures, type, fingers);
|
||||
}
|
||||
|
||||
static void gesture_end(struct swaybar_seat* seat, enum gesture_type type,
|
||||
bool cancelled) {
|
||||
|
||||
if (!gesture_tracker_check(&seat->gestures, type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cancelled) {
|
||||
gesture_tracker_cancel(&seat->gestures);
|
||||
return;
|
||||
}
|
||||
|
||||
struct gesture *gesture = gesture_tracker_end(&seat->gestures);
|
||||
struct swaybar_gesture* binding = bar_gestures_match(seat->bar, gesture);
|
||||
|
||||
if (binding) {
|
||||
ipc_execute_gesture(seat->bar, binding);
|
||||
}
|
||||
}
|
||||
|
||||
static void hold_begin(void *data, struct zwp_pointer_gesture_hold_v1 *wl_hold,
|
||||
uint32_t serial, uint32_t time,struct wl_surface *surface,
|
||||
uint32_t fingers) {
|
||||
struct swaybar_seat *seat = data;
|
||||
gesture_begin(seat, surface, GESTURE_TYPE_HOLD, fingers);
|
||||
}
|
||||
|
||||
static void hold_end(void *data,
|
||||
struct zwp_pointer_gesture_hold_v1 *wl_hold,
|
||||
uint32_t serial, uint32_t time, int32_t cancelled) {
|
||||
struct swaybar_seat *seat = data;
|
||||
gesture_end(seat, GESTURE_TYPE_HOLD, cancelled);
|
||||
}
|
||||
|
||||
static const struct zwp_pointer_gesture_hold_v1_listener hold_listener = {
|
||||
.begin = hold_begin,
|
||||
.end = hold_end,
|
||||
};
|
||||
|
||||
static void pinch_begin(void *data,
|
||||
struct zwp_pointer_gesture_pinch_v1 *wl_pinch, uint32_t serial,
|
||||
uint32_t time, struct wl_surface *surface, uint32_t fingers) {
|
||||
struct swaybar_seat *seat = data;
|
||||
gesture_begin(seat, surface, GESTURE_TYPE_PINCH, fingers);
|
||||
}
|
||||
|
||||
static void pinch_update(void *data,
|
||||
struct zwp_pointer_gesture_pinch_v1 *wl_pinch,
|
||||
uint32_t time, wl_fixed_t dx, wl_fixed_t dy,
|
||||
wl_fixed_t scale, wl_fixed_t rotation) {
|
||||
struct swaybar_seat *seat = data;
|
||||
if (gesture_tracker_check(&seat->gestures, GESTURE_TYPE_PINCH)) {
|
||||
gesture_tracker_update(&seat->gestures,
|
||||
wl_fixed_to_double(dx), wl_fixed_to_double(dy),
|
||||
wl_fixed_to_double(scale),
|
||||
wl_fixed_to_double(rotation));
|
||||
}
|
||||
}
|
||||
|
||||
static void pinch_end(void *data,
|
||||
struct zwp_pointer_gesture_pinch_v1 *wl_pinch,
|
||||
uint32_t serial, uint32_t time, int32_t cancelled) {
|
||||
struct swaybar_seat *seat = data;
|
||||
gesture_end(seat, GESTURE_TYPE_PINCH, cancelled);
|
||||
}
|
||||
|
||||
static const struct zwp_pointer_gesture_pinch_v1_listener pinch_listener = {
|
||||
.begin = pinch_begin,
|
||||
.update = pinch_update,
|
||||
.end = pinch_end,
|
||||
};
|
||||
|
||||
static void swipe_begin(void *data,
|
||||
struct zwp_pointer_gesture_swipe_v1 *wl_swipe,
|
||||
uint32_t serial, uint32_t time,
|
||||
struct wl_surface *surface, uint32_t fingers) {
|
||||
struct swaybar_seat *seat = data;
|
||||
gesture_begin(seat, surface, GESTURE_TYPE_SWIPE, fingers);
|
||||
}
|
||||
|
||||
static void swipe_update(void *data,
|
||||
struct zwp_pointer_gesture_swipe_v1 *wl_swipe,
|
||||
uint32_t time, wl_fixed_t dx, wl_fixed_t dy) {
|
||||
struct swaybar_seat *seat = data;
|
||||
if (gesture_tracker_check(&seat->gestures, GESTURE_TYPE_SWIPE)) {
|
||||
gesture_tracker_update(&seat->gestures,
|
||||
wl_fixed_to_double(dx), wl_fixed_to_double(dy),
|
||||
NAN, NAN);
|
||||
}
|
||||
}
|
||||
|
||||
static void swipe_end(void *data,
|
||||
struct zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1,
|
||||
uint32_t serial, uint32_t time, int32_t cancelled) {
|
||||
struct swaybar_seat *seat = data;
|
||||
gesture_end(seat, GESTURE_TYPE_SWIPE, cancelled);
|
||||
}
|
||||
|
||||
static const struct zwp_pointer_gesture_swipe_v1_listener swipe_listener = {
|
||||
.begin = swipe_begin,
|
||||
.update = swipe_update,
|
||||
.end = swipe_end,
|
||||
};
|
||||
|
||||
|
||||
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||
enum wl_seat_capability caps) {
|
||||
struct swaybar_seat *seat = data;
|
||||
|
|
@ -479,6 +653,21 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
assert(seat->pointer.cursor_surface);
|
||||
}
|
||||
wl_pointer_add_listener(seat->pointer.pointer, &pointer_listener, seat);
|
||||
|
||||
seat->hold = zwp_pointer_gestures_v1_get_hold_gesture(
|
||||
seat->bar->pointer_gestures, seat->pointer.pointer);
|
||||
zwp_pointer_gesture_hold_v1_add_listener(seat->hold,
|
||||
&hold_listener, seat);
|
||||
|
||||
seat->pinch = zwp_pointer_gestures_v1_get_pinch_gesture(
|
||||
seat->bar->pointer_gestures, seat->pointer.pointer);
|
||||
zwp_pointer_gesture_pinch_v1_add_listener(seat->pinch,
|
||||
&pinch_listener, seat);
|
||||
|
||||
seat->swipe = zwp_pointer_gestures_v1_get_swipe_gesture(
|
||||
seat->bar->pointer_gestures, seat->pointer.pointer);
|
||||
zwp_pointer_gesture_swipe_v1_add_listener(seat->swipe,
|
||||
&swipe_listener, seat);
|
||||
}
|
||||
if (!have_touch && seat->touch.touch != NULL) {
|
||||
wl_touch_release(seat->touch.touch);
|
||||
|
|
@ -515,6 +704,15 @@ void swaybar_seat_free(struct swaybar_seat *seat) {
|
|||
if (seat->touch.touch != NULL) {
|
||||
wl_touch_release(seat->touch.touch);
|
||||
}
|
||||
if (seat->hold != NULL) {
|
||||
zwp_pointer_gesture_hold_v1_destroy(seat->hold);
|
||||
}
|
||||
if (seat->pinch != NULL) {
|
||||
zwp_pointer_gesture_pinch_v1_destroy(seat->pinch);
|
||||
}
|
||||
if (seat->swipe != NULL) {
|
||||
zwp_pointer_gesture_swipe_v1_destroy(seat->swipe);
|
||||
}
|
||||
wl_seat_destroy(seat->wl_seat);
|
||||
wl_list_remove(&seat->link);
|
||||
free(seat);
|
||||
|
|
|
|||
|
|
@ -140,6 +140,30 @@ static bool ipc_parse_config(
|
|||
}
|
||||
}
|
||||
|
||||
json_object *gestures = json_object_object_get(bar_config, "gestures");
|
||||
while (config->gestures->length) {
|
||||
struct swaybar_gesture *binding = config->gestures->items[0];
|
||||
list_del(config->gestures, 0);
|
||||
free_gesture(binding);
|
||||
}
|
||||
if (gestures) {
|
||||
int length = json_object_array_length(gestures);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
json_object *bindobj = json_object_array_get_idx(gestures, i);
|
||||
struct swaybar_gesture *binding =
|
||||
calloc(1, sizeof(struct swaybar_gesture));
|
||||
binding->gesture.type = json_object_get_int(
|
||||
json_object_object_get(bindobj, "type"));
|
||||
binding->gesture.fingers = json_object_get_int(
|
||||
json_object_object_get(bindobj, "fingers"));
|
||||
binding->gesture.directions = json_object_get_int(
|
||||
json_object_object_get(bindobj, "directions"));
|
||||
binding->command = strdup(json_object_get_string(
|
||||
json_object_object_get(bindobj, "command")));
|
||||
list_add(config->gestures, binding);
|
||||
}
|
||||
}
|
||||
|
||||
json_object *colors = json_object_object_get(bar_config, "colors");
|
||||
if (colors) {
|
||||
ipc_parse_colors(config, colors);
|
||||
|
|
@ -416,6 +440,16 @@ void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) {
|
|||
IPC_COMMAND, bind->command, &len));
|
||||
}
|
||||
|
||||
void ipc_execute_gesture(struct swaybar *bar, struct swaybar_gesture *bind) {
|
||||
char *description = gesture_to_string(&bind->gesture);
|
||||
sway_log(SWAY_DEBUG, "Executing binding for gesture %s: `%s`",
|
||||
description, bind->command);
|
||||
free(description);
|
||||
uint32_t len = strlen(bind->command);
|
||||
free(ipc_single_command(bar->ipc_socketfd,
|
||||
IPC_COMMAND, bind->command, &len));
|
||||
}
|
||||
|
||||
bool ipc_initialize(struct swaybar *bar) {
|
||||
uint32_t len = strlen(bar->id);
|
||||
char *res = ipc_single_command(bar->ipc_socketfd,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue