mirror of
				https://codeberg.org/dwl/dwl.git
				synced 2025-10-31 03:54:15 +00:00 
			
		
		
		
	apply gestures
This commit is contained in:
		
							parent
							
								
									6d3ae4d787
								
							
						
					
					
						commit
						7b68298e19
					
				
							
								
								
									
										68
									
								
								dwl.c
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								dwl.c
									
									
									
									
									
								
							| @ -95,6 +95,7 @@ enum { ClkTagBar, ClkLtSymbol, ClkStatus, ClkTitle, ClkClient, ClkRoot }; /* cli | |||||||
| enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, | enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, | ||||||
| 	NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ | 	NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ | ||||||
| #endif | #endif | ||||||
|  | enum { SWIPE_LEFT, SWIPE_RIGHT, SWIPE_DOWN, SWIPE_UP }; | ||||||
| 
 | 
 | ||||||
| typedef union { | typedef union { | ||||||
| 	int i; | 	int i; | ||||||
| @ -111,6 +112,14 @@ typedef struct { | |||||||
| 	const Arg arg; | 	const Arg arg; | ||||||
| } Button; | } Button; | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  | 	unsigned int mod; | ||||||
|  | 	unsigned int motion; | ||||||
|  | 	unsigned int fingers_count; | ||||||
|  | 	void (*func)(const Arg *); | ||||||
|  | 	const Arg arg; | ||||||
|  | } Gesture; | ||||||
|  | 
 | ||||||
| typedef struct Monitor Monitor; | typedef struct Monitor Monitor; | ||||||
| typedef struct { | typedef struct { | ||||||
| 	/* Must keep these three elements in this order */ | 	/* Must keep these three elements in this order */ | ||||||
| @ -278,6 +287,7 @@ static void buffer_destroy(struct wlr_buffer *buffer); | |||||||
| static bool buffer_begin_data_ptr_access(struct wlr_buffer *buffer, uint32_t flags, void **data, uint32_t *format, size_t *stride); | static bool buffer_begin_data_ptr_access(struct wlr_buffer *buffer, uint32_t flags, void **data, uint32_t *format, size_t *stride); | ||||||
| static void buffer_end_data_ptr_access(struct wlr_buffer *buffer); | static void buffer_end_data_ptr_access(struct wlr_buffer *buffer); | ||||||
| static void buttonpress(struct wl_listener *listener, void *data); | static void buttonpress(struct wl_listener *listener, void *data); | ||||||
|  | static int ongesture(struct wlr_pointer_swipe_end_event *event); | ||||||
| static void swipe_begin(struct wl_listener *listener, void *data); | static void swipe_begin(struct wl_listener *listener, void *data); | ||||||
| static void swipe_update(struct wl_listener *listener, void *data); | static void swipe_update(struct wl_listener *listener, void *data); | ||||||
| static void swipe_end(struct wl_listener *listener, void *data); | static void swipe_end(struct wl_listener *listener, void *data); | ||||||
| @ -453,6 +463,10 @@ static struct wlr_box sgeom; | |||||||
| static struct wl_list mons; | static struct wl_list mons; | ||||||
| static Monitor *selmon; | static Monitor *selmon; | ||||||
| 
 | 
 | ||||||
|  | static uint32_t swipe_fingers = 0; | ||||||
|  | static double swipe_dx = 0; | ||||||
|  | static double swipe_dy = 0; | ||||||
|  | 
 | ||||||
| static char stext[256]; | static char stext[256]; | ||||||
| static struct wl_event_source *status_event_source; | static struct wl_event_source *status_event_source; | ||||||
| 
 | 
 | ||||||
| @ -481,6 +495,8 @@ static xcb_atom_t netatom[NetLast]; | |||||||
| /* attempt to encapsulate suck into one file */ | /* attempt to encapsulate suck into one file */ | ||||||
| #include "client.h" | #include "client.h" | ||||||
| 
 | 
 | ||||||
|  | static const unsigned int abzsquare = swipe_min_threshold * swipe_min_threshold; | ||||||
|  | 
 | ||||||
| /* function implementations */ | /* function implementations */ | ||||||
| void | void | ||||||
| applybounds(Client *c, struct wlr_box *bbox) | applybounds(Client *c, struct wlr_box *bbox) | ||||||
| @ -772,6 +788,11 @@ swipe_begin(struct wl_listener *listener, void *data) | |||||||
| { | { | ||||||
| 	struct wlr_pointer_swipe_begin_event *event = data; | 	struct wlr_pointer_swipe_begin_event *event = data; | ||||||
| 
 | 
 | ||||||
|  | 	swipe_fingers = event->fingers; | ||||||
|  | 	// Reset swipe distance at the beginning of a swipe
 | ||||||
|  | 	swipe_dx = 0; | ||||||
|  | 	swipe_dy = 0; | ||||||
|  | 
 | ||||||
| 	// Forward swipe begin event to client
 | 	// Forward swipe begin event to client
 | ||||||
| 	wlr_pointer_gestures_v1_send_swipe_begin( | 	wlr_pointer_gestures_v1_send_swipe_begin( | ||||||
| 		pointer_gestures,  | 		pointer_gestures,  | ||||||
| @ -786,6 +807,11 @@ swipe_update(struct wl_listener *listener, void *data) | |||||||
| { | { | ||||||
| 	struct wlr_pointer_swipe_update_event *event = data; | 	struct wlr_pointer_swipe_update_event *event = data; | ||||||
| 
 | 
 | ||||||
|  | 	swipe_fingers = event->fingers; | ||||||
|  | 	// Accumulate swipe distance
 | ||||||
|  | 	swipe_dx += event->dx; | ||||||
|  | 	swipe_dy += event->dy; | ||||||
|  | 
 | ||||||
| 	// Forward swipe update event to client
 | 	// Forward swipe update event to client
 | ||||||
| 	wlr_pointer_gestures_v1_send_swipe_update( | 	wlr_pointer_gestures_v1_send_swipe_update( | ||||||
| 		pointer_gestures,  | 		pointer_gestures,  | ||||||
| @ -796,11 +822,53 @@ swipe_update(struct wl_listener *listener, void *data) | |||||||
| 	); | 	); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int | ||||||
|  | ongesture(struct wlr_pointer_swipe_end_event *event) | ||||||
|  | { | ||||||
|  | 	struct wlr_keyboard *keyboard; | ||||||
|  | 	uint32_t mods; | ||||||
|  | 	const Gesture *g; | ||||||
|  | 	unsigned int motion; | ||||||
|  | 	unsigned int adx = (int)round(fabs(swipe_dx)); | ||||||
|  | 	unsigned int ady = (int)round(fabs(swipe_dy)); | ||||||
|  | 	int handled = 0; | ||||||
|  | 
 | ||||||
|  | 	if (event->cancelled) { | ||||||
|  | 		return handled; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Require absolute distance movement beyond a small thresh-hold
 | ||||||
|  | 	if (adx * adx + ady * ady < abzsquare) { | ||||||
|  | 		return handled; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (adx > ady) { | ||||||
|  | 		motion = swipe_dx < 0 ? SWIPE_LEFT : SWIPE_RIGHT; | ||||||
|  | 	} else { | ||||||
|  | 		motion = swipe_dy < 0 ? SWIPE_UP : SWIPE_DOWN; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	keyboard = wlr_seat_get_keyboard(seat); | ||||||
|  | 	mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; | ||||||
|  | 	for (g = gestures; g < END(gestures); g++) { | ||||||
|  | 		if (CLEANMASK(mods) == CLEANMASK(g->mod) && | ||||||
|  | 			 swipe_fingers == g->fingers_count && | ||||||
|  | 			 motion == g->motion && g->func) { | ||||||
|  | 			g->func(&g->arg); | ||||||
|  | 			handled = 1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return handled; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| swipe_end(struct wl_listener *listener, void *data) | swipe_end(struct wl_listener *listener, void *data) | ||||||
| { | { | ||||||
| 	struct wlr_pointer_swipe_end_event *event = data; | 	struct wlr_pointer_swipe_end_event *event = data; | ||||||
| 
 | 
 | ||||||
|  | 	// TODO: should we stop here if the event has been handled?
 | ||||||
|  | 	ongesture(event); | ||||||
|  | 
 | ||||||
| 	// Forward swipe end event to client
 | 	// Forward swipe end event to client
 | ||||||
| 	wlr_pointer_gestures_v1_send_swipe_end( | 	wlr_pointer_gestures_v1_send_swipe_end( | ||||||
| 		pointer_gestures,  | 		pointer_gestures,  | ||||||
|  | |||||||
							
								
								
									
										23
									
								
								patches/gestures/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								patches/gestures/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | ### Description | ||||||
|  | Add swipe gestures to trigger functions, similar to [libinput-gestures](https://github.com/bulletmark/libinput-gestures/tree/master). It supports the following gestures: `SWIPE_UP`, `SWIPE_DOWN`, `SWIPE_LEFT` and `SWIPE_RIGHT` | ||||||
|  | 
 | ||||||
|  | > NOTE: It requires that you have previously applied [pointer-gestures-unstable-v1](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/pointer-gestures-unstable-v1) | ||||||
|  | 
 | ||||||
|  | ```c | ||||||
|  | static const Gesture gestures[] = { | ||||||
|  |   /* modifier gesture       fingers_count   function    argument */ | ||||||
|  |   { MODKEY,   SWIPE_LEFT,   4,              shiftview,  { .i = 1 } }, | ||||||
|  |   { 0,        SWIPE_RIGHT,  4,              shiftview,  { .i = -1 } }, | ||||||
|  | }; | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | **NOTE:** the example above requires the following patch [shiftview](https://codeberg.org/dwl/dwl-patches/wiki/shiftview) | ||||||
|  | 
 | ||||||
|  | ### Download | ||||||
|  | - [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/gestures) | ||||||
|  | - [2024-07-09](https://codeberg.org/dwl/dwl-patches/raw/commit/13d96b51b54500dd24544cf3a73c61b7a1414bc6/patches/gestures/gestures.patch) | ||||||
|  | - [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/be3735bc6a5c64ff76c200a8679453bd179be456/gestures/gestures.patch) | ||||||
|  | - [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/655fd2916c1bcaa022ce6dcdfb370051cf64df66/gestures/gestures.patch) | ||||||
|  | 
 | ||||||
|  | ### Authors | ||||||
|  | - [wochap](https://codeberg.org/wochap) | ||||||
							
								
								
									
										169
									
								
								patches/gestures/gestures.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								patches/gestures/gestures.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,169 @@ | |||||||
|  | From 42f97e88bd901d81b81da61c44a790b583706308 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: wochap <gean.marroquin@gmail.com> | ||||||
|  | Date: Fri, 5 Jul 2024 11:18:49 -0500 | ||||||
|  | Subject: [PATCH] implement gestures | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  config.def.h |  9 +++++++ | ||||||
|  |  dwl.c        | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  2 files changed, 77 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/config.def.h b/config.def.h
 | ||||||
|  | index 22d2171..8b75564 100644
 | ||||||
|  | --- a/config.def.h
 | ||||||
|  | +++ b/config.def.h
 | ||||||
|  | @@ -14,6 +14,8 @@ static const float urgentcolor[]           = COLOR(0xff0000ff);
 | ||||||
|  |  /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ | ||||||
|  |  static const float fullscreen_bg[]         = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ | ||||||
|  |   | ||||||
|  | +static const unsigned int swipe_min_threshold = 0;
 | ||||||
|  | +
 | ||||||
|  |  /* tagging - TAGCOUNT must be no greater than 31 */ | ||||||
|  |  #define TAGCOUNT (9) | ||||||
|  |   | ||||||
|  | @@ -174,3 +176,10 @@ static const Button buttons[] = {
 | ||||||
|  |  	{ MODKEY, BTN_MIDDLE, togglefloating, {0} }, | ||||||
|  |  	{ MODKEY, BTN_RIGHT,  moveresize,     {.ui = CurResize} }, | ||||||
|  |  }; | ||||||
|  | +
 | ||||||
|  | +static const Gesture gestures[] = {
 | ||||||
|  | +	// { MODKEY, SWIPE_LEFT, 4, shiftview, { .i = 1 } },
 | ||||||
|  | +	// { MODKEY, SWIPE_RIGHT, 4, shiftview, { .i = -1 } },
 | ||||||
|  | +	{ MODKEY, SWIPE_UP, 3, focusstack, {.i = 1} },
 | ||||||
|  | +	{ MODKEY, SWIPE_DOWN, 3, focusstack, {.i = -1} },
 | ||||||
|  | +};
 | ||||||
|  | diff --git a/dwl.c b/dwl.c
 | ||||||
|  | index ded83e2..5d861e8 100644
 | ||||||
|  | --- a/dwl.c
 | ||||||
|  | +++ b/dwl.c
 | ||||||
|  | @@ -88,6 +88,7 @@ enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrOverlay, LyrBlock,
 | ||||||
|  |  enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, | ||||||
|  |  	NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ | ||||||
|  |  #endif | ||||||
|  | +enum { SWIPE_LEFT, SWIPE_RIGHT, SWIPE_DOWN, SWIPE_UP };
 | ||||||
|  |   | ||||||
|  |  typedef union { | ||||||
|  |  	int i; | ||||||
|  | @@ -103,6 +104,14 @@ typedef struct {
 | ||||||
|  |  	const Arg arg; | ||||||
|  |  } Button; | ||||||
|  |   | ||||||
|  | +typedef struct {
 | ||||||
|  | +	unsigned int mod;
 | ||||||
|  | +	unsigned int motion;
 | ||||||
|  | +	unsigned int fingers_count;
 | ||||||
|  | +	void (*func)(const Arg *);
 | ||||||
|  | +	const Arg arg;
 | ||||||
|  | +} Gesture;
 | ||||||
|  | +
 | ||||||
|  |  typedef struct Monitor Monitor; | ||||||
|  |  typedef struct { | ||||||
|  |  	/* Must keep these three elements in this order */ | ||||||
|  | @@ -251,6 +260,7 @@ static void arrangelayer(Monitor *m, struct wl_list *list,
 | ||||||
|  |  static void arrangelayers(Monitor *m); | ||||||
|  |  static void axisnotify(struct wl_listener *listener, void *data); | ||||||
|  |  static void buttonpress(struct wl_listener *listener, void *data); | ||||||
|  | +static int ongesture(struct wlr_pointer_swipe_end_event *event);
 | ||||||
|  |  static void swipe_begin(struct wl_listener *listener, void *data); | ||||||
|  |  static void swipe_update(struct wl_listener *listener, void *data); | ||||||
|  |  static void swipe_end(struct wl_listener *listener, void *data); | ||||||
|  | @@ -416,6 +426,10 @@ static struct wlr_box sgeom;
 | ||||||
|  |  static struct wl_list mons; | ||||||
|  |  static Monitor *selmon; | ||||||
|  |   | ||||||
|  | +static uint32_t swipe_fingers = 0;
 | ||||||
|  | +static double swipe_dx = 0;
 | ||||||
|  | +static double swipe_dy = 0;
 | ||||||
|  | +
 | ||||||
|  |  #ifdef XWAYLAND | ||||||
|  |  static void activatex11(struct wl_listener *listener, void *data); | ||||||
|  |  static void associatex11(struct wl_listener *listener, void *data); | ||||||
|  | @@ -435,6 +449,8 @@ static xcb_atom_t netatom[NetLast];
 | ||||||
|  |  /* attempt to encapsulate suck into one file */ | ||||||
|  |  #include "client.h" | ||||||
|  |   | ||||||
|  | +static const unsigned int abzsquare = swipe_min_threshold * swipe_min_threshold;
 | ||||||
|  | +
 | ||||||
|  |  /* function implementations */ | ||||||
|  |  void | ||||||
|  |  applybounds(Client *c, struct wlr_box *bbox) | ||||||
|  | @@ -657,6 +673,11 @@ swipe_begin(struct wl_listener *listener, void *data)
 | ||||||
|  |  { | ||||||
|  |  	struct wlr_pointer_swipe_begin_event *event = data; | ||||||
|  |   | ||||||
|  | +	swipe_fingers = event->fingers;
 | ||||||
|  | +	// Reset swipe distance at the beginning of a swipe
 | ||||||
|  | +	swipe_dx = 0;
 | ||||||
|  | +	swipe_dy = 0;
 | ||||||
|  | +
 | ||||||
|  |  	// Forward swipe begin event to client | ||||||
|  |  	wlr_pointer_gestures_v1_send_swipe_begin( | ||||||
|  |  		pointer_gestures,  | ||||||
|  | @@ -671,6 +692,11 @@ swipe_update(struct wl_listener *listener, void *data)
 | ||||||
|  |  { | ||||||
|  |  	struct wlr_pointer_swipe_update_event *event = data; | ||||||
|  |   | ||||||
|  | +	swipe_fingers = event->fingers;
 | ||||||
|  | +	// Accumulate swipe distance
 | ||||||
|  | +	swipe_dx += event->dx;
 | ||||||
|  | +	swipe_dy += event->dy;
 | ||||||
|  | +
 | ||||||
|  |  	// Forward swipe update event to client | ||||||
|  |  	wlr_pointer_gestures_v1_send_swipe_update( | ||||||
|  |  		pointer_gestures,  | ||||||
|  | @@ -681,11 +707,53 @@ swipe_update(struct wl_listener *listener, void *data)
 | ||||||
|  |  	); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +int
 | ||||||
|  | +ongesture(struct wlr_pointer_swipe_end_event *event)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_keyboard *keyboard;
 | ||||||
|  | +	uint32_t mods;
 | ||||||
|  | +	const Gesture *g;
 | ||||||
|  | +	unsigned int motion;
 | ||||||
|  | +	unsigned int adx = (int)round(fabs(swipe_dx));
 | ||||||
|  | +	unsigned int ady = (int)round(fabs(swipe_dy));
 | ||||||
|  | +	int handled = 0;
 | ||||||
|  | +
 | ||||||
|  | +	if (event->cancelled) {
 | ||||||
|  | +		return handled;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	// Require absolute distance movement beyond a small thresh-hold
 | ||||||
|  | +	if (adx * adx + ady * ady < abzsquare) {
 | ||||||
|  | +		return handled;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (adx > ady) {
 | ||||||
|  | +		motion = swipe_dx < 0 ? SWIPE_LEFT : SWIPE_RIGHT;
 | ||||||
|  | +	} else {
 | ||||||
|  | +		motion = swipe_dy < 0 ? SWIPE_UP : SWIPE_DOWN;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	keyboard = wlr_seat_get_keyboard(seat);
 | ||||||
|  | +	mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
 | ||||||
|  | +	for (g = gestures; g < END(gestures); g++) {
 | ||||||
|  | +		if (CLEANMASK(mods) == CLEANMASK(g->mod) &&
 | ||||||
|  | +			 swipe_fingers == g->fingers_count &&
 | ||||||
|  | +			 motion == g->motion && g->func) {
 | ||||||
|  | +			g->func(&g->arg);
 | ||||||
|  | +			handled = 1;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +	return handled;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  void | ||||||
|  |  swipe_end(struct wl_listener *listener, void *data) | ||||||
|  |  { | ||||||
|  |  	struct wlr_pointer_swipe_end_event *event = data; | ||||||
|  |   | ||||||
|  | +	// TODO: should we stop here if the event has been handled?
 | ||||||
|  | +	ongesture(event);
 | ||||||
|  | +
 | ||||||
|  |  	// Forward swipe end event to client | ||||||
|  |  	wlr_pointer_gestures_v1_send_swipe_end( | ||||||
|  |  		pointer_gestures,  | ||||||
|  | -- 
 | ||||||
|  | 2.45.1 | ||||||
							
								
								
									
										16
									
								
								patches/pointer-gestures-unstable-v1/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								patches/pointer-gestures-unstable-v1/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | ### Description | ||||||
|  | Forward the following events to client: | ||||||
|  | swipe_begin, swipe_update, swipe_end, pinch_begin, pinch_update and pinch_end | ||||||
|  | 
 | ||||||
|  | This patch allows you to pinch zoom in Chrome, for example. In combination with the following patches [gestures](https://codeberg.org/dwl/dwl-patches/wiki/gestures) and [shiftview](https://codeberg.org/dwl/dwl-patches/wiki/shiftview), it would allow you to switch workspaces by performing a 3-finger swipe on your touchpad. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### Download | ||||||
|  | - [git branch](https://codeberg.org/wochap/dwl/src/branch/v0.5/pointer-gestures-unstable-v1) | ||||||
|  | - [2024-07-12](https://codeberg.org/dwl/dwl-patches/raw/commit/05dbce217b676e989b0fc9e0eecf83b386ac9e07/patches/pointer-gestures-unstable-v1/pointer-gestures-unstable-v1.patch) | ||||||
|  | - [2024-07-09](https://codeberg.org/dwl/dwl-patches/raw/commit/2322f3efeae8da44227e0acc760ffd3dea153716/patches/pointer-gestures-unstable-v1/pointer-gestures-unstable-v1.patch) | ||||||
|  | - [2024-04-11](https://codeberg.org/dwl/dwl-patches/raw/commit/c676de59d51e613bd52ac46c77a24b1cac9a61a1/pointer-gestures-unstable-v1/pointer-gestures-unstable-v1.patch) | ||||||
|  | - [v0.5](https://codeberg.org/dwl/dwl-patches/raw/commit/fc4146f3068dcd46035a2a11fe9d6109a97ae6d6/pointer-gestures-unstable-v1/pointer-gestures-unstable-v1.patch) | ||||||
|  | 
 | ||||||
|  | ### Authors | ||||||
|  | - [wochap](https://codeberg.org/wochap) | ||||||
| @ -0,0 +1,186 @@ | |||||||
|  | From be7e98d28fc59aab67026e7d5efdcaeb26029713 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: wochap <gean.marroquin@gmail.com> | ||||||
|  | Date: Fri, 12 Jul 2024 11:30:17 -0500 | ||||||
|  | Subject: [PATCH] implement pointer-gestures-unstable-v1 | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  dwl.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 136 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/dwl.c b/dwl.c
 | ||||||
|  | index dc0437e..e5805b1 100644
 | ||||||
|  | --- a/dwl.c
 | ||||||
|  | +++ b/dwl.c
 | ||||||
|  | @@ -38,6 +38,7 @@
 | ||||||
|  |  #include <wlr/types/wlr_output_power_management_v1.h> | ||||||
|  |  #include <wlr/types/wlr_pointer.h> | ||||||
|  |  #include <wlr/types/wlr_pointer_constraints_v1.h> | ||||||
|  | +#include <wlr/types/wlr_pointer_gestures_v1.h>
 | ||||||
|  |  #include <wlr/types/wlr_presentation_time.h> | ||||||
|  |  #include <wlr/types/wlr_primary_selection.h> | ||||||
|  |  #include <wlr/types/wlr_primary_selection_v1.h> | ||||||
|  | @@ -250,6 +251,14 @@ static void arrangelayer(Monitor *m, struct wl_list *list,
 | ||||||
|  |  static void arrangelayers(Monitor *m); | ||||||
|  |  static void axisnotify(struct wl_listener *listener, void *data); | ||||||
|  |  static void buttonpress(struct wl_listener *listener, void *data); | ||||||
|  | +static void swipe_begin(struct wl_listener *listener, void *data);
 | ||||||
|  | +static void swipe_update(struct wl_listener *listener, void *data);
 | ||||||
|  | +static void swipe_end(struct wl_listener *listener, void *data);
 | ||||||
|  | +static void pinch_begin(struct wl_listener *listener, void *data);
 | ||||||
|  | +static void pinch_update(struct wl_listener *listener, void *data);
 | ||||||
|  | +static void pinch_end(struct wl_listener *listener, void *data);
 | ||||||
|  | +static void hold_begin(struct wl_listener *listener, void *data);
 | ||||||
|  | +static void hold_end(struct wl_listener *listener, void *data);
 | ||||||
|  |  static void chvt(const Arg *arg); | ||||||
|  |  static void checkidleinhibitor(struct wlr_surface *exclude); | ||||||
|  |  static void cleanup(void); | ||||||
|  | @@ -383,6 +392,7 @@ static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
 | ||||||
|  |  static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; | ||||||
|  |  static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr; | ||||||
|  |  static struct wlr_output_power_manager_v1 *power_mgr; | ||||||
|  | +static struct wlr_pointer_gestures_v1 *pointer_gestures;
 | ||||||
|  |   | ||||||
|  |  static struct wlr_pointer_constraints_v1 *pointer_constraints; | ||||||
|  |  static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr; | ||||||
|  | @@ -644,6 +654,122 @@ buttonpress(struct wl_listener *listener, void *data)
 | ||||||
|  |  			event->time_msec, event->button, event->state); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void
 | ||||||
|  | +swipe_begin(struct wl_listener *listener, void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_pointer_swipe_begin_event *event = data;
 | ||||||
|  | +
 | ||||||
|  | +	// Forward swipe begin event to client
 | ||||||
|  | +	wlr_pointer_gestures_v1_send_swipe_begin(
 | ||||||
|  | +		pointer_gestures, 
 | ||||||
|  | +		seat,
 | ||||||
|  | +		event->time_msec,
 | ||||||
|  | +		event->fingers
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +swipe_update(struct wl_listener *listener, void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_pointer_swipe_update_event *event = data;
 | ||||||
|  | +
 | ||||||
|  | +	// Forward swipe update event to client
 | ||||||
|  | +	wlr_pointer_gestures_v1_send_swipe_update(
 | ||||||
|  | +		pointer_gestures, 
 | ||||||
|  | +		seat,
 | ||||||
|  | +		event->time_msec,
 | ||||||
|  | +		event->dx,
 | ||||||
|  | +		event->dy
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +swipe_end(struct wl_listener *listener, void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_pointer_swipe_end_event *event = data;
 | ||||||
|  | +
 | ||||||
|  | +	// Forward swipe end event to client
 | ||||||
|  | +	wlr_pointer_gestures_v1_send_swipe_end(
 | ||||||
|  | +		pointer_gestures, 
 | ||||||
|  | +		seat,
 | ||||||
|  | +		event->time_msec,
 | ||||||
|  | +		event->cancelled
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +pinch_begin(struct wl_listener *listener, void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_pointer_pinch_begin_event *event = data;
 | ||||||
|  | +
 | ||||||
|  | +	// Forward pinch begin event to client
 | ||||||
|  | +	wlr_pointer_gestures_v1_send_pinch_begin(
 | ||||||
|  | +		pointer_gestures, 
 | ||||||
|  | +		seat,
 | ||||||
|  | +		event->time_msec,
 | ||||||
|  | +		event->fingers
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +pinch_update(struct wl_listener *listener, void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_pointer_pinch_update_event *event = data;
 | ||||||
|  | +
 | ||||||
|  | +	// Forward pinch update event to client
 | ||||||
|  | +	wlr_pointer_gestures_v1_send_pinch_update(
 | ||||||
|  | +		pointer_gestures,
 | ||||||
|  | +		seat,
 | ||||||
|  | +		event->time_msec,
 | ||||||
|  | +		event->dx,
 | ||||||
|  | +		event->dy,
 | ||||||
|  | +		event->scale,
 | ||||||
|  | +		event->rotation
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +pinch_end(struct wl_listener *listener, void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_pointer_pinch_end_event *event = data;
 | ||||||
|  | +
 | ||||||
|  | +	// Forward pinch end event to client
 | ||||||
|  | +	wlr_pointer_gestures_v1_send_pinch_end(
 | ||||||
|  | +		pointer_gestures,
 | ||||||
|  | +		seat,
 | ||||||
|  | +		event->time_msec,
 | ||||||
|  | +		event->cancelled
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +hold_begin(struct wl_listener *listener, void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_pointer_hold_begin_event *event = data;
 | ||||||
|  | +
 | ||||||
|  | +	// Forward hold begin event to client
 | ||||||
|  | +	wlr_pointer_gestures_v1_send_hold_begin(
 | ||||||
|  | +		pointer_gestures,
 | ||||||
|  | +		seat,
 | ||||||
|  | +		event->time_msec,
 | ||||||
|  | +		event->fingers
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +hold_end(struct wl_listener *listener, void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	struct wlr_pointer_hold_end_event *event = data;
 | ||||||
|  | +
 | ||||||
|  | +	// Forward hold end event to client
 | ||||||
|  | +	wlr_pointer_gestures_v1_send_hold_end(
 | ||||||
|  | +		pointer_gestures,
 | ||||||
|  | +		seat,
 | ||||||
|  | +		event->time_msec,
 | ||||||
|  | +		event->cancelled
 | ||||||
|  | +	);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  void | ||||||
|  |  chvt(const Arg *arg) | ||||||
|  |  { | ||||||
|  | @@ -2556,6 +2682,16 @@ setup(void)
 | ||||||
|  |  	virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(dpy); | ||||||
|  |  	LISTEN_STATIC(&virtual_pointer_mgr->events.new_virtual_pointer, virtualpointer); | ||||||
|  |   | ||||||
|  | +	pointer_gestures = wlr_pointer_gestures_v1_create(dpy);
 | ||||||
|  | +	LISTEN_STATIC(&cursor->events.swipe_begin, swipe_begin);
 | ||||||
|  | +	LISTEN_STATIC(&cursor->events.swipe_update, swipe_update);
 | ||||||
|  | +	LISTEN_STATIC(&cursor->events.swipe_end, swipe_end);
 | ||||||
|  | +	LISTEN_STATIC(&cursor->events.pinch_begin, pinch_begin);
 | ||||||
|  | +	LISTEN_STATIC(&cursor->events.pinch_update, pinch_update);
 | ||||||
|  | +	LISTEN_STATIC(&cursor->events.pinch_end, pinch_end);
 | ||||||
|  | +	LISTEN_STATIC(&cursor->events.hold_begin, hold_begin);
 | ||||||
|  | +	LISTEN_STATIC(&cursor->events.hold_end, hold_end);
 | ||||||
|  | +
 | ||||||
|  |  	seat = wlr_seat_create(dpy, "seat0"); | ||||||
|  |  	LISTEN_STATIC(&seat->events.request_set_cursor, setcursor); | ||||||
|  |  	LISTEN_STATIC(&seat->events.request_set_selection, setsel); | ||||||
|  | -- 
 | ||||||
|  | 2.45.1 | ||||||
							
								
								
									
										9
									
								
								patches/shiftview/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								patches/shiftview/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | ### Description | ||||||
|  | Add keybindings to cycle through tags with visible clients. | ||||||
|  | 
 | ||||||
|  | ### Download | ||||||
|  | - [git branch](https://codeberg.org/guidocella/dwl/src/branch/shiftview) | ||||||
|  | - [2024-01-27](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/shiftview/shiftview.patch) | ||||||
|  | 
 | ||||||
|  | ### Authors | ||||||
|  | - [Guido Cella](https://codeberg.org/guidocella) | ||||||
							
								
								
									
										76
									
								
								patches/shiftview/shiftview.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								patches/shiftview/shiftview.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | |||||||
|  | From 40f9140742277d0298988990264f4b6a738f8122 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Guido Cella <guido@guidocella.xyz> | ||||||
|  | Date: Sat, 27 Jan 2024 22:43:29 +0100 | ||||||
|  | Subject: [PATCH] cycle through tags | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  config.def.h |  4 ++++ | ||||||
|  |  shiftview.c  | 34 ++++++++++++++++++++++++++++++++++ | ||||||
|  |  2 files changed, 38 insertions(+) | ||||||
|  |  create mode 100644 shiftview.c | ||||||
|  | 
 | ||||||
|  | diff --git a/config.def.h b/config.def.h
 | ||||||
|  | index 9009517..8d77ec0 100644
 | ||||||
|  | --- a/config.def.h
 | ||||||
|  | +++ b/config.def.h
 | ||||||
|  | @@ -117,6 +117,8 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
 | ||||||
|  |  static const char *termcmd[] = { "foot", NULL }; | ||||||
|  |  static const char *menucmd[] = { "bemenu-run", NULL }; | ||||||
|  |   | ||||||
|  | +#include "shiftview.c"
 | ||||||
|  | +
 | ||||||
|  |  static const Key keys[] = { | ||||||
|  |  	/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ | ||||||
|  |  	/* modifier                  key                 function        argument */ | ||||||
|  | @@ -130,6 +132,8 @@ static const Key keys[] = {
 | ||||||
|  |  	{ MODKEY,                    XKB_KEY_l,          setmfact,       {.f = +0.05f} }, | ||||||
|  |  	{ MODKEY,                    XKB_KEY_Return,     zoom,           {0} }, | ||||||
|  |  	{ MODKEY,                    XKB_KEY_Tab,        view,           {0} }, | ||||||
|  | +	{ MODKEY,                    XKB_KEY_a,          shiftview,      { .i = -1 } },
 | ||||||
|  | +	{ MODKEY,                    XKB_KEY_semicolon,  shiftview,      { .i = 1 } },
 | ||||||
|  |  	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C,          killclient,     {0} }, | ||||||
|  |  	{ MODKEY,                    XKB_KEY_t,          setlayout,      {.v = &layouts[0]} }, | ||||||
|  |  	{ MODKEY,                    XKB_KEY_f,          setlayout,      {.v = &layouts[1]} }, | ||||||
|  | diff --git a/shiftview.c b/shiftview.c
 | ||||||
|  | new file mode 100644 | ||||||
|  | index 0000000..fa53db0
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/shiftview.c
 | ||||||
|  | @@ -0,0 +1,34 @@
 | ||||||
|  | +// "arg->i" stores the number of tags to shift right (positive value)
 | ||||||
|  | +//          or left (negative value)
 | ||||||
|  | +void
 | ||||||
|  | +shiftview(const Arg *arg)
 | ||||||
|  | +{
 | ||||||
|  | +	Arg a;
 | ||||||
|  | +	Client *c;
 | ||||||
|  | +	bool visible = false;
 | ||||||
|  | +	int i = arg->i;
 | ||||||
|  | +	int count = 0;
 | ||||||
|  | +	int nextseltags, curseltags = selmon->tagset[selmon->seltags];
 | ||||||
|  | +
 | ||||||
|  | +	do {
 | ||||||
|  | +		if (i > 0) // left circular shift
 | ||||||
|  | +            nextseltags = (curseltags << i) | (curseltags >> (TAGCOUNT - i));
 | ||||||
|  | +        else // right circular shift
 | ||||||
|  | +			nextseltags = curseltags >> (-i) | (curseltags << (TAGCOUNT + i));
 | ||||||
|  | +
 | ||||||
|  | +        // Check if the tag is visible
 | ||||||
|  | +        wl_list_for_each(c, &clients, link) {
 | ||||||
|  | +            if (c->mon == selmon && nextseltags & c->tags) {
 | ||||||
|  | +                visible = true;
 | ||||||
|  | +                break;
 | ||||||
|  | +            }
 | ||||||
|  | +        }
 | ||||||
|  | +
 | ||||||
|  | +		i += arg->i;
 | ||||||
|  | +    } while (!visible && ++count <= TAGCOUNT);
 | ||||||
|  | +
 | ||||||
|  | +    if (count <= TAGCOUNT) {
 | ||||||
|  | +        a.i = nextseltags;
 | ||||||
|  | +        view(&a);
 | ||||||
|  | +    }
 | ||||||
|  | +}
 | ||||||
|  | -- 
 | ||||||
|  | 2.43.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										34
									
								
								shiftview.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								shiftview.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // "arg->i" stores the number of tags to shift right (positive value)
 | ||||||
|  | //          or left (negative value)
 | ||||||
|  | void | ||||||
|  | shiftview(const Arg *arg) | ||||||
|  | { | ||||||
|  | 	Arg a; | ||||||
|  | 	Client *c; | ||||||
|  | 	bool visible = false; | ||||||
|  | 	int i = arg->i; | ||||||
|  | 	int count = 0; | ||||||
|  | 	int nextseltags, curseltags = selmon->tagset[selmon->seltags]; | ||||||
|  | 
 | ||||||
|  | 	do { | ||||||
|  | 		if (i > 0) // left circular shift
 | ||||||
|  |             nextseltags = (curseltags << i) | (curseltags >> (TAGCOUNT - i)); | ||||||
|  |         else // right circular shift
 | ||||||
|  | 			nextseltags = curseltags >> (-i) | (curseltags << (TAGCOUNT + i)); | ||||||
|  | 
 | ||||||
|  |         // Check if the tag is visible
 | ||||||
|  |         wl_list_for_each(c, &clients, link) { | ||||||
|  |             if (c->mon == selmon && nextseltags & c->tags) { | ||||||
|  |                 visible = true; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 		i += arg->i; | ||||||
|  |     } while (!visible && ++count <= TAGCOUNT); | ||||||
|  | 
 | ||||||
|  |     if (count <= TAGCOUNT) { | ||||||
|  |         a.i = nextseltags; | ||||||
|  |         view(&a); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Wilkenfeld
						Wilkenfeld