Compare commits

...

7 Commits

Author SHA1 Message Date
julmajustus
2cd54ba5fb Add btrtile
Patch refactor, updated readme.

Added link for with gapps patch to readme.
2025-01-01 23:36:19 +00:00
A Frederick Christensen
b279ebde1c
tablet-input: Update patch and squash commits 2025-01-01 16:51:07 -06:00
A Frederick Christensen
af2391cb80
less-simple-touch-input: rename to touch-input
Former maintainer @fauxmight taking over patch maintenance. @minego notes
a lack of available time: https://codeberg.org/dwl/dwl-patches/pulls/102#issuecomment-2557944
Thank you for all your work, @minego!
2025-01-01 16:36:24 -06:00
fauxmight
3c43c107ca Update patches/tablet-input/README.md
Minor cleanups
2025-01-01 22:11:47 +00:00
A Frederick Christensen
5e744ae3ff
tablet-input: README.md formatting 2025-01-01 16:06:37 -06:00
A Frederick Christensen
45dbbf1c54
tablet-input: clarify argument order of wlr_surface_accepts_tablet_v2 2025-01-01 15:53:19 -06:00
Palanix
4e476edc87
Rename monfig to monitorconfig. Closes #139 2025-01-01 21:37:41 +01:00
9 changed files with 2439 additions and 2 deletions

106
patches/btrtile/README.md Normal file
View File

@ -0,0 +1,106 @@
### Description
# btrtile — A Focus-Driven Tiling Layout
It provides a focus-driven, mouse- and keyboard-friendly tiling layout that grants you granular control over how clients are placed and resized.
![btrtile in action](./demos/btrtiledemo.gif)
---
# Why btrtile
While dwls patches folder is full of different layouts, I couldn't find suitable layout that would work well with my workflow and single ultrawide monitor setup. btrtile aims to solve that by introducing a layout strategy that splits clients according to user focus and pointer position.
---
# Features
- **Combined Tiling and Management**
Combines tiling layout and management of clients under one patchset.
- **Focus-Driven Splits**
When you add a new client, btrtile checks where your pointer is relative to the focused clients geometry.
- If the pointer is on the left half (for a horizontally large client), the new client spawns on the left side, and vice versa.
- By default, new splits are 50/50.
- **Adaptive Splitting**
- If the area to be split is wider than its height, btrtile does a horizontal split.
- Otherwise, it does a vertical split.
- **Keyboard and Mouse Driven**
- Supports keyboard-based commands for quick ratio adjustments and client swapping.
- Mouse-based resizing and moving are integrated for more intuitive manipulation.
---
# How It Works
btrtile organizes clients using a binary tree data structure that represents splits either vertically or horizontally.
When a new client appears:
1. **Focused Client Detection**
btrtile checks your pointer location to find which client (if any) youre interacting with.
2. **Split Creation**
- If theres a focused client, btrtile creates a split node around it, placing the new client on the side where your pointer is.
3. **Ratio Management**
Each split node has a `split_ratio` (defaulting to 0.5). This ratio defines how much space is allocated to each child node. You can adjust this ratio using keyboard or mouse actions.
---
# What It Doesnt Handle
- **Multi-Tag client Management**
btrtile intentionally reverts clients to a single tag if they span multiple tags. This prevents potential inconsistencies or duplicate entries in its per-tag client tree.
- If you attempt to place a single client on multiple tags while using the btrtile layout, btrtile will enforce a single-tag assignment to maintain stability.
- **Suckless philosophy**
- Yea, it's a bloat. I tried to hide the suck inside a single file as much I could. While this approach is not ideal, it's how it's at least for now.
---
# Configuring btrtile
btrtile adds couple variables to config.h to fine tune the mouse resizing of tiled clients.
1. **resize_factor**
- A multiplier to transfer pointer movement to client weight ratio. Depends heavily on mouse sensivity.
Defaults to 0.0002f.
2. **resize_interval_ms**
- A time based resize call limiter. Depends on framerate and screen refresh rate.
Defaults to 16ms. (~60 resize updates per second)
Fine tune these values to find the best values for your setup, smoother resizing can significally increase cpu overhead.
If mouse resizing feels sluggish, you can try compiling dwl with more aggressive optimization flags like -O2/-O3.
---
# Patch recommendations
1. **Patches that I use with my btrtile**
- [focusdir](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/focusdir)
Great patch to move focus between clients.
- [rotatetags](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/rotatetags)
Good patch to rotate the view or shift clients between tags.
- [warpcursor](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/warpcursor)
Moves cursor location to focused client.
- [pertag](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/pertag)
Allows each tag to have individual layout setups.
- [gaps](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/gaps)
Add gaps between clients.
---
### Download
- [0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/btrtile/btrtile-v0.7.patch)
- [0.7 WITH gapps](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/btrtile/btrtile-v0.7-gapps.patch)
### Authors
- [julmajustus](https://codeberg.org/julmajustus)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 MiB

View File

@ -2,8 +2,8 @@
Allows more monitor configuration in config.h
### Download
- [git branch](https://codeberg.org/Palanix/dwl/src/branch/monfig)
- [2024-02-15](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/monfig/monfig.patch)
- [git branch](https://codeberg.org/Palanix/dwl/src/branch/monitorconfig)
- [2024-02-15](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/monitorconfig/monitorconfig.patch)
### Authors
- [Palanix](https://codeberg.org/Palanix)

View File

@ -3,6 +3,17 @@ implements wlr-tablet-v2 for drawing tablets and supports cursor emulation
inspired by @guyuming76's [branch](https://codeberg.org/guyuming76/dwl/commits/branch/graphic_tablet), with coding help from @Palanix and testing by @Thanatos
**Please note:** wlroots modified the order of arguments to the function `wlr_surface_accepts_tablet_v2`
In versions less than or equal to 0.18.1 (against which, dwl 0.7 is typically built), the order is `tablet, surface`.
In the master branch and (anticipated) in versions later than 0.18.1, the order is `surface, tablet`.
The git branch for this patch uses the `surface, tablet` order.
If you are attempting to use this codebase to make your own modifications to the patch, there is only one call to the `wlr_surface_accepts_tablet_v2` function, but you will need to make the argument order change if you expect to build against wlroots 0.18.1 or earlier.
The `0.7` patch linked here accounts for the change and uses the `tablet, surface` order, but the patch is orphaned from a codebase.
There was discussion of this matter in [Issue #141](https://codeberg.org/dwl/dwl-patches/issues/141).
### Download
- [git branch](https://codeberg.org/fauxmight/dwl/src/branch/tablet-input)
- [main 2025-01-01](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/tablet-input/tablet-input.patch)

View File

@ -0,0 +1,20 @@
### Description
Adds touchscreen functionality.
KNOWN BUGS:
- Sometimes, the pointer moves to where the screen is pressed, but the button press doesn't occur until the screen is touched AGAIN. This means that if you touch to click button 'Q' on the screen (for instance), nothing happens; then you touch elsewhere on the screen and THEN button 'Q' registers a click. This is annoying, doesn't always happen, and I don't yet know how to fix it.
### Download
- [git branch](https://codeberg.org/fauxmight/dwl/src/branch/touch-input)
- [2025-01-01](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/less-simple-touch-input/less-simple-touch-input.patch)
### Authors
- [fauxmight](https://codeberg.org/fauxmight)
- [minego](https://codeberg.org/minego)
- [Unprex](https://github.com/Unprex)
### Changelog
- 2025-01-01 @fauxmight took over maintenance. Previous maintainer @minego notes [lack of available time](https://codeberg.org/dwl/dwl-patches/pulls/102#issuecomment-2557944)
- 2024-02-11 Corrected issue where motion events where not sending notifications for unfocused clients such as an on screen keyboard
- 2024-03-26 Rebased, and removed #ifdef's for the pointer constraints patch which has been merged into upstream
- 2024-03-28 Removed debug

View File

@ -0,0 +1,238 @@
From 0eda173488e6ef3b0c7744e8cef0b3e0dfc81605 Mon Sep 17 00:00:00 2001
From: Micah N Gorrell <m@minego.net>
Date: Fri, 9 Feb 2024 17:08:20 -0700
Subject: [PATCH] Add support for touch screen input devices, and send the
appropriate events to clients
---
dwl.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 150 insertions(+)
diff --git a/dwl.c b/dwl.c
index 0eba3e9..c9eb7fb 100644
--- a/dwl.c
+++ b/dwl.c
@@ -51,6 +51,7 @@
#include <wlr/types/wlr_session_lock_v1.h>
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
#include <wlr/types/wlr_subcompositor.h>
+#include <wlr/types/wlr_touch.h>
#include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h>
@@ -165,6 +166,12 @@ typedef struct {
struct wl_listener destroy;
} KeyboardGroup;
+typedef struct TouchGroup {
+ struct wl_list link;
+ struct wlr_touch *touch;
+ Monitor *m;
+} TouchGroup;
+
typedef struct {
/* Must keep this field first */
unsigned int type; /* LayerShell */
@@ -271,7 +278,9 @@ static void createnotify(struct wl_listener *listener, void *data);
static void createpointer(struct wlr_pointer *pointer);
static void createpointerconstraint(struct wl_listener *listener, void *data);
static void createpopup(struct wl_listener *listener, void *data);
+static void createtouch(struct wlr_touch *touch);
static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint);
+static void createtouch(struct wlr_touch *touch);
static void cursorframe(struct wl_listener *listener, void *data);
static void cursorwarptohint(void);
static void destroydecoration(struct wl_listener *listener, void *data);
@@ -342,6 +351,10 @@ static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
+static void touchdown(struct wl_listener *listener, void *data);
+static void touchup(struct wl_listener *listener, void *data);
+static void touchframe(struct wl_listener *listener, void *data);
+static void touchmotion(struct wl_listener *listener, void *data);
static void unlocksession(struct wl_listener *listener, void *data);
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
static void unmapnotify(struct wl_listener *listener, void *data);
@@ -410,6 +423,7 @@ static struct wlr_output_layout *output_layout;
static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static struct wl_list touches;
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
@@ -1129,6 +1143,16 @@ createpopup(struct wl_listener *listener, void *data)
LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup);
}
+void
+createtouch(struct wlr_touch *wlr_touch)
+{
+ TouchGroup *touch = ecalloc(1, sizeof(TouchGroup));
+
+ touch->touch = wlr_touch;
+ wl_list_insert(&touches, &touch->link);
+ wlr_cursor_attach_input_device(cursor, &wlr_touch->base);
+}
+
void
cursorconstrain(struct wlr_pointer_constraint_v1 *constraint)
{
@@ -1534,6 +1558,9 @@ inputdevice(struct wl_listener *listener, void *data)
case WLR_INPUT_DEVICE_POINTER:
createpointer(wlr_pointer_from_input_device(device));
break;
+ case WLR_INPUT_DEVICE_TOUCH:
+ createtouch(wlr_touch_from_input_device(device));
+ break;
default:
/* TODO handle other input device types */
break;
@@ -1546,6 +1573,8 @@ inputdevice(struct wl_listener *listener, void *data)
caps = WL_SEAT_CAPABILITY_POINTER;
if (!wl_list_empty(&kb_group->wlr_group->devices))
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+ if (!wl_list_empty(&touches))
+ caps |= WL_SEAT_CAPABILITY_TOUCH;
wlr_seat_set_capabilities(seat, caps);
}
@@ -2557,6 +2586,13 @@ setup(void)
LISTEN_STATIC(&cursor->events.axis, axisnotify);
LISTEN_STATIC(&cursor->events.frame, cursorframe);
+ wl_list_init(&touches);
+
+ LISTEN_STATIC(&cursor->events.touch_down, touchdown);
+ LISTEN_STATIC(&cursor->events.touch_frame, touchframe);
+ LISTEN_STATIC(&cursor->events.touch_motion, touchmotion);
+ LISTEN_STATIC(&cursor->events.touch_up, touchup);
+
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape);
@@ -2727,6 +2763,120 @@ toggleview(const Arg *arg)
printstatus();
}
+void
+touchdown(struct wl_listener *listener, void *data)
+{
+ struct wlr_touch_down_event *event = data;
+ double lx, ly;
+ double sx, sy;
+ struct wlr_surface *surface;
+ Client *c = NULL;
+ uint32_t serial = 0;
+ Monitor *m;
+
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+
+ // Map the input to the appropriate output, to ensure that rotation is
+ // handled.
+ wl_list_for_each(m, &mons, link) {
+ if (m == NULL || m->wlr_output == NULL) {
+ continue;
+ }
+ if (event->touch->output_name != NULL && 0 != strcmp(event->touch->output_name, m->wlr_output->name)) {
+ continue;
+ }
+
+ wlr_cursor_map_input_to_output(cursor, &event->touch->base, m->wlr_output);
+ }
+
+ wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, event->x, event->y, &lx, &ly);
+
+ /* Find the client under the pointer and send the event along. */
+ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
+ if (sloppyfocus)
+ focusclient(c, 0);
+
+ if (surface != NULL) {
+ serial = wlr_seat_touch_notify_down(seat, surface, event->time_msec, event->touch_id, sx, sy);
+ }
+
+ if (serial && wlr_seat_touch_num_points(seat) == 1) {
+ /* Emulate a mouse click if the touch event wasn't handled */
+ struct wlr_pointer_button_event *button_event = data;
+ struct wlr_pointer_motion_absolute_event *motion_event = data;
+ double dx, dy;
+
+ wlr_cursor_absolute_to_layout_coords(cursor, &motion_event->pointer->base, motion_event->x, motion_event->y, &lx, &ly);
+ wlr_cursor_warp_closest(cursor, &motion_event->pointer->base, lx, ly);
+ dx = lx - cursor->x;
+ dy = ly - cursor->y;
+ motionnotify(motion_event->time_msec, &motion_event->pointer->base, dx, dy, dx, dy);
+
+ button_event->button = BTN_LEFT;
+ button_event->state = WLR_BUTTON_PRESSED;
+ buttonpress(listener, button_event);
+ }
+}
+
+void
+touchup(struct wl_listener *listener, void *data)
+{
+ struct wlr_touch_up_event *event = data;
+
+ if (!wlr_seat_touch_get_point(seat, event->touch_id)) {
+ return;
+ }
+
+ if (wlr_seat_touch_num_points(seat) == 1) {
+ struct wlr_pointer_button_event *button_event = data;
+
+ button_event->button = BTN_LEFT;
+ button_event->state = WLR_BUTTON_RELEASED;
+ buttonpress(listener, button_event);
+ }
+
+ wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id);
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+}
+
+void
+touchframe(struct wl_listener *listener, void *data)
+{
+ wlr_seat_touch_notify_frame(seat);
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+}
+
+void
+touchmotion(struct wl_listener *listener, void *data)
+{
+ struct wlr_touch_motion_event *event = data;
+ double lx, ly;
+ double sx, sy;
+ struct wlr_surface *surface;
+ Client *c = NULL;
+
+ if (!wlr_seat_touch_get_point(seat, event->touch_id)) {
+ return;
+ }
+
+ wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, event->x, event->y, &lx, &ly);
+ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy);
+
+ if (c != NULL && surface != NULL) {
+ if (sloppyfocus)
+ focusclient(c, 0);
+ wlr_seat_touch_point_focus(seat, surface, event->time_msec, event->touch_id, sx, sy);
+ } else {
+ if (sloppyfocus)
+ focusclient(NULL, 0);
+ wlr_seat_touch_point_clear_focus(seat, event->time_msec, event->touch_id);
+ }
+ wlr_seat_touch_notify_motion(seat, event->time_msec, event->touch_id, sx, sy);
+
+ wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
+}
+
+
void
unlocksession(struct wl_listener *listener, void *data)
{
--
2.47.0