mirror of
				https://codeberg.org/dwl/dwl.git
				synced 2025-10-31 20:14:20 +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, | ||||
| 	NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ | ||||
| #endif | ||||
| enum { SWIPE_LEFT, SWIPE_RIGHT, SWIPE_DOWN, SWIPE_UP }; | ||||
| 
 | ||||
| typedef union { | ||||
| 	int i; | ||||
| @ -111,6 +112,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 */ | ||||
| @ -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 void buffer_end_data_ptr_access(struct wlr_buffer *buffer); | ||||
| 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); | ||||
| @ -453,6 +463,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; | ||||
| 
 | ||||
| static char stext[256]; | ||||
| 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 */ | ||||
| #include "client.h" | ||||
| 
 | ||||
| static const unsigned int abzsquare = swipe_min_threshold * swipe_min_threshold; | ||||
| 
 | ||||
| /* function implementations */ | ||||
| void | ||||
| 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; | ||||
| 
 | ||||
| 	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,  | ||||
| @ -786,6 +807,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,  | ||||
| @ -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 | ||||
| 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,  | ||||
|  | ||||
							
								
								
									
										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