Whoa: Weston, the reference compositor for #Wayland, supports multiple physical independent mice at the same time! 😀

"New mouse, who dis?"

(See toot later in the thread for how to set this up!)

There are couple of surprises around window interaction:

- Once a cursor starts to resize/move a window, those actions are not possible for the other one.
- One cursor can open a menu, and the other one can use it, that one works pretty well!
- Closing a window with one cursor, while the other drags it, makes the second one *disappear*! :D

I mean, these are really hard UI questions to solve! Often, it's not clear to me what the correct behavior should be!

Okay, let's try some applications, and see how they deal with multiple mice! 😈

First up: Gedit, a GTK application.

Both cursors can place the cursor and select text, but movement from one cursor "interrupts" the selection of the other one. Not very satisfying.

Imagine how cool it would be if both had their own selections + cursors!! That would allow a really neat form of collaboration within the same document!

Next up: Chromium! It has a very pragmatic solution: It just *ignores* all cursors but the first one!

In the video, the arrow-shaped cursor can click on stuff. The turtle has no power here.

In Firefox, it seems like all mouse events are mashed together, and are seen as coming from the same device.

That means that both cursors can click – if the other one "holds still". Otherwise, I guess Firefox is very confused by a click on a link while the mouse is not in it! 😆

Selections feel strange – the last-moving cursor will determine the selection.

Also notice how, if one cursor hovers a link, *both* turn into hand icons!

Of course, we *had* to try a drawing application next!

Here's @tldraw (in Firefox)! 

Collaborative drawing at it's best! 💚

Finally, I tried attaching an additional keyboard and assigned them to a different "seat"!

That worked really well! In Weston, each "seat" has its own keyboard focus, so you can actually work side-by-side with two mice + two keyboards independently!

Also!!! The two seats have their own (independent) clipboards!!!! Whatttt! 🤯

I totally didn't expect this. But multi-seat as a concept seems deeply integrated into libinput + #Wayland! Now it's up to GUI toolkits and compositors to support it!

Tried it again, and the independent clipboards still seem a bit glitchy after all… :(

An issue asking for proper support in GTK was closed five years ago, for example… https://gitlab.gnome.org/GNOME/gtk/-/issues/1574

Per-seat clipboard on Wayland (#1574) · Issues · GNOME / gtk · GitLab

Context On Wayland, all input devices (mice, keyboard, etc) are grouped into so-called seats, represented by the wl_seat interface....

GitLab
Side note: I think more window managers should support *this* feature!

Very useful when your very long line of code doesn't fit on your screen, for example! :P

(Shout-out to @xssfox, who first did this on X.org! https://sprocketfox.io/xssfox/2021/12/02/xrandr/)

Okay, here's how to set this up!

You need to create a udev rule for the "second" input device that sets ENV{WL_SEAT} to a string other than "default", and then start Weston from a virtual console. (At least, starting it from another Wayland session didn't work for me.) That's it!

The WL_SEAT property is what Wayland refers to as a "logical seat". Assign the same seat name to a mouse and a keyboard to make them work together! The default seat is "default".

Detailed steps:

1. Use `sudo libinput list-devices` to find the device file (like "/dev/input/event12")
2. Use `udevadm info -a /dev/input/event12` to find the parent device with a catchy ATTRS{name}.
3. Create a file /run/udev/rules.d/00-multiseat.rules like this:

ATTRS{name}=="Name of your mouse" ENV{WL_SEAT}="second"

(Note: This is a single line)

4. Run `sudo udevadm trigger` to apply the new rules.

You can check again with `sudo libinput list-devices`. The device's "Seat" should now say "seat0, second"!

You could try this script (requires zenity & possibly more tools? Please read before running!) https://github.com/n3rdopolis/rebeccablackos/blob/master/rebeccablackos_files/usr/bin/configureseats

(Doesn't work on #NixOS, where /etc/udev is read-only. 💀)

I'd love to have a little command line helper tool to help set this up, for an arbitrary number of mice! :D

rebeccablackos/rebeccablackos_files/usr/bin/configureseats at master · n3rdopolis/rebeccablackos

Git mirror of the SVN for the fan made RebeccaBlackOS - n3rdopolis/rebeccablackos

GitHub

This was a fun afternoon! Thanks for following along.

Let me know which other programs I should try with multiple mice! :D

Looks like SDL (the multimedia library) very recently merged support for multi-seat input! https://www.phoronix.com/news/SDL-Merges-Wayland-Multi-Seat

So… many-mouse games should be possible on Wayland? :3

SDL Merges Wayland Multi-Seat Support

An interesting merge this weekend to the Simple DirectMedia Library (SDL) that is widely-used by cross-platform games and other applications for software/hardware abstractions is Wayland multi-seat support

Still fascinated by the idea of applications with multi-mouse input (see above thread)…

So I thought I'd give it a try! The first step was to hack my Wayland compositor #niri to track multiple mouse positions, and forward them to client applications. When receiving an event from libinput, you can tell which device it originated from!

Never really done any Wayland programming, so I'm pretty excited that this works! Also, niri is written in Rust, so it was quite a pleasant experience!

Next, I tried to write some multi-mouse client applications!

My first attempt was a Rust program written using the smithay_client_toolkit. Events callbacks come with a reference to the "pointer" that caused it. In the logs to the left, you can see that I can in fact differentiate the two mouse devices there. Very neat, and a perfectly fine proof of concept.

But this library is super low-level. I wanted something more convenient for actually trying to write some fun demos.

Next, I thought: Oh I know, I'll write a GTK application! So I fumbled my way through setting one up in Rust, and on adding a custom "widget" that can receive motion events.

Problem is: I know next to nothing about GTK. Do I really need to do:

let wayland_seat: WaylandSeat = seat.downcast::<WaylandSeat>().unwrap();
let wl_seat_ptr = gdk_wayland_seat_get_wl_seat(wayland_seat.to_glib_none().0);

to differentiate the event's seat? At least, this worked as well! But it would *really* slow me down.

I always had a good time writing games in the LÖVE engine! <3 So I forked LÖVE, and found an easy way to return the mouse device ID when users receive a "mousemoved" callback in Lua!

But… the ID was always 0 – for both devices! :(

LÖVE is built on top of the graphics library SDL, which I knew had introduced some multi-seat features on Wayland recently. So maybe SDL was the culprit?

So I tried it in pure #SDL3! I thought I'd never have to code something in C again, but here we are.

And indeed: The device IDs are always 0 there, as well – making it impossible to differentiate my two mice.

I haven't figured out why yet; might need some deep-dive into the SDL code to find out? Or maybe I'm not passing the events in properly from "above" (my hacked niri compositor). But given that the other approaches worked, it's maybe something in the SDL pipeline…

I figured it out! Mouse IDs for events are only available in "relative mode" for some reason; which you can enable using SDL_SetWindowRelativeMouseMode(true).

Using love.mouse.setRelativeMode(true), it also kinda works in LÖVE! \o/ Still have to "constrain" the other mouse in the window.

But this should be good enough to have some fun with this tomorrow! :3

Alright, with a little change in SDL to also return device IDs in "absolute mode", I can now write multi-mouse applications in the LÖVE game engine! \o/

Here's a little physics playground! Already a lot of fun with two people! :D

#love2d #sdl3 #multiseat

Sadly, this will probably only ever run on my laptop, as it requires:

1. A Wayland compositor that supports multiple mice (I hacked that into niri, but Weston would also work).
2. A little change in SDL to forward the device IDs to the user.
3. Several small changes in LÖVE to forward those into Lua land.

Will try to publish my patches in a couple of days, though!

@blinry oh yeah, I assumed you were reading the devices directly. When you're not in relative the event data is either 0 to indicate virtual or SDL_TOUCH_MOUSEID to indicate touch.
@raptor85 Do you have any insight into why that distinction is being made? Having access to the device ID would be pretty cool also outside of relative mode!
@blinry the virtual device is essentially all mice combined, it's not a specific hardware device, it's effectively the system cursor.

@blinry 0 is an impossible ID, that indicates there was an error.

Try calling SDL_GetMice() then iterating the array of SDL_MouseID calling SDL_GetMouseNameForID for each, should give you a list of valid devices, if not it's not even detecting that your device is a mouse!

RE: https://chaos.social/@blinry/115974920876848092

@raptor85 Thanks for those ideas! I figured out the problem:

@blinry likewise, my “mouse” is a massive multitouch display for casino games which we never really seem to take advantage of multitouch capabilities… so much potential for little interactive features.
@blinry That sounds like fun options for collaborative editing. Like cryptpad code for something graphical?
@marco_m_aus_f Right?! That's what I'm thinking, too!
@blinry Collaborative doodling 😃

@marco_m_aus_f @blinry I was thinking pair programming with one computer. You can use the mouse to say "here". Next level: separate copy+paste buffers per mouse. Or one can scroll and click through the docs without stealing keyboard focus from the other.

(Now I also want multiple keyboards and separate typing cursors)

It's really like collaborative editing, but with access to more than one document / program. With access to all applications on the device.

@blinry I was trying to figure out what your example reminded me of, and then it hit me: the Steam Deck has dual touchpads, one for each thumb, and it can track each independently. When you pull up the on-screen keyboard, you can use the touchpads independently to input text. It looks a lot like your turtles.
@blinry that's awesome! Though I will point out that multi mouse support has totally been possible all along (even back in X11) if you use direct input device access instead of using input events from the windowing system. I played with that a bunch back when I was still making games in Crystal Space.
@blinry some kind of game? Not sure if any would support this. Needs to be developed!
@blinry Good thing! Random scripts writing things into system file is only creating chaos.
@blinry have you by change tried if it also works with a monitor or GPU the same? I've a KVM integrated into the server mainboard and it would be great to put that onto it's own seat and have a dedicated GUI running there. Otherwise it always causes bad application behavior with graphics acceleration when it pics the wrong GPU to run on...
@agowa338 I *think* that's what the physical seats are for! ENV{ID_SEAT}. But I haven't tried it at all! https://www.freedesktop.org/wiki/Software/systemd/multiseat/
multiseat

@blinry I tried to use seats a few years ago, but documentation was shit. I never figured out how to properly configure them. I didn't even find that it was a udev rule thing back then.
Also a lot of people in forums and mailing lists told me that they're not even aware of that feature existing to begin with. (there wasn't a single one that know that this feature exists and also knew how it worked)
So at some point I just gave up on it.

Maybe it's time to check it out again by now.

@agowa338 @blinry that's always sad because people put a lot of time and effort making multiseat possible and having it be inaccessible due to poor documentation doesn't provide any value for the people who might find it useful

@blinry @agowa338

Physical seats effectively signal "this is a different computer" except it shares some of the same hardware.

Logical seats effectively signal "this is a different person" so they share the environment but work independently within that environment (mouse, keyboard focus, etc).

Except sometimes a logical seat is a different *hand*, not person (because you may want left and right hand to work independently, hence two logical seats) and wheee, off into the rabbit hole we go.

@blinry @xssfox Oh, ironically I thought xssfox did it with wayland when I saw the images online at the time.
@blinry @xssfox oh noes...
Reminds me of a colleague who, after being told the rule of thumb that a function should not be longer than the screen, showed us that one of his his ultra wide monitors was in landscape mode 🙈
@DerPumu I'm a Java dev, but no
@robinsyl Yeah, in my Java times, I was glad for wider screens rather than taller ones 😜
@DerPumu but then you can't see the stacktrace
@blinry Ja, aber sowas führt zu… https://estrogen.network/notes/a8wokso2w2ubchev … so was. 🙃
amy (@amythegay)

Die Bahn hats mit der Neigetechnik wieder übertrieben und macht jetzt der Wuppertaler Schwebebahn Konkurrenz 📎

e2net
@blinry 90°-steps rotating could be neat but freely rotating… I feel like it's more a meme than anything else

@lanodan @blinry Weston is a bit of a demo of what compositors can do too vs something they expect you to fully use for your desktop.

And rotation would e.g. be useful for a specialized compositor for tabletop applications. (had to fake that many years ago for a floor-scale display, doing an actual compositor would've been fun)

@lanodan @blinry (in general, if you dig deeper into Wayland protocols, there is a bunch of stuff no desktop compositor implements, but is useful for more specialized applications, industrial HMI, automotive interfaces, that kind of thing)
@lanodan @blinry I can imagine some scenarios where it might be useful. Perhaps as a setup for people that have difficulty maintaining posture or something. Not sure why you wouldn't just angle the whole screen at that point though.
@blinry as someone who still prefers outline moving/resizing, I most certainly hope not!
@scruss @blinry how does this affect outline moving/resizing?
@blinry im hyperventilating

@blinry i want a button that shakes it all up and tumbles the windows ontop of each other like theyve been dumped out of a bucket

i would use this responsibly i promise

@SarraceniaWilds Hehe :) And maybe a small fireplace to the side, so that you can finally BURN the windows that annoy you? 🔥 https://en.wikipedia.org/wiki/Little_Inferno
Little Inferno - Wikipedia

@blinry yes yes yes and if the cursor gets too close it catches fire and changes its icons to various charcoal lumps or burnt twigs
@blinry computers should be fun

@SarraceniaWilds Ha yeah!

Maybe Firefox would be immune? And all note-taking apps are extremely flammable!

@blinry i need this to be real so i can open an issue in the repository that devolves into pokemon like discourse about which software will and wont burn

@SarraceniaWilds @blinry YES

I WOULD ALSO ONLY USE THIS RESPONSIBLY I SWEAR

@blinry That's what Squeak/Smalltalk always made fun to do.
But it is not a window manager in the traditional sense, so there's that.
@blinry one fun detail is that Weston implements remote desktop through a plugin that when a client connects generates a virtual second seat and thus doesn't have to consider remote use cases deeper in the codebase.