-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
input management and seat #1505
Conversation
Attaching a touch device as a pointer would present a wl_pointer to the client and simulate that. Attaching n pointers as a touch device simulates a wl_touch with n touchpoints. Attaching a keyboard with layout/options/etc overrides that keyboard's default layout/options for any interactions that go through this seat. Attaching a device twice to anything should just update its options to match any extra parameters given. After config parsing, if no cursors were configured, add a default: If no seats were configured, add a default: |
|
Oh, I should mention that |
|
Also, another concern we should address is that previously sway input devices were identified with a consistent identifier based on libinput. We need to carry this identifier over, but there are additional constraints - we should be able to specify |
|
|
I don't think it makes sense to have cursor config and seat config in separate blocks since they are conceptually bound to each other. There is a 1:1 relationship between seat and cursor (necessary because there can only be a single pointer location within a surface per seat). It won't work well if seats share cursors because then they would be sharing the devices as well. If they share devices, surfaces then get double input events (one per seat). For instance, two button clicks on the surface when the user clicks once, two scrolls, two motion events, two dnd targets which is going to lead to a lot of nasty bugs that can't be fixed. Clipboard for cursor events is broken because only the first seat that wins the race to click the "copy" button gets the contents. Just picking a seat and going with that will break the clipboard for the same reason and is no different from just putting the device on that seat but with less predictability. I think this is a protocol limitation. Devices can live on multiple seats, but this is a really dumb thing to do and I doubt anyone would ever us this configuration except by mistake. In this case, the single device will control both cursors at the same time. |
And what if libinput is not in use for that backend? Should we just ignore all input configuration in that case? |
Cursors can be closely associated with seats I guess. However, I should note that I want you to be able to tie a keyboard into multiple seats, and we should work it out so that whichever seat got input last (from devices other than that keyboard) would propegate the keyboard events.
We should make up some other predictable device naming schema for that device. |
|
I'm messing with the rendering a little bit. It looks like we were trying to cram the buffer into the space of the desired window geometry. Window geometry is always smaller than the size of the buffer so this leads to scaling issues which 1) makes the windows look ugly when scaled and 2) completely screws up surface coordinate calculations. To avoid this, the approach is to always render the surface buffer as it is intended to be rendered. When the shell specifies window geometry, we place the top left corner of the window geometry at the top left corner of the sway container. Shell configure requests for size work on window geometry size and not buffer size so this gives us a good result with xdg-shell. wl-shell does not seem to have a way to get window geometry coordinates so this shell will never be completely supported by sway and we need to do crappy workarounds. Hopefully window maximization will clear this up a bit because it won't render shadows so window geometry offsets should be close to zero (untested). A consequence is we have to trust the shell surface to actually listen to our configure requests. If it doesn't, then I think we should call that a client bug and just clip the contents to the container extents (which should be done anyway to avoid shadows spilling over to adjacent containers). |
60fe301
to
5e9ee32
Compare
57613dd
to
9ae906c
Compare
|
The issue is that libinput is giving me two devices for the same keyboard and I was only configuring the first one which wasn't giving events because of an assumption that there would only be one device for the identifier. It works now. |
|
Can you take a look at this @emersion? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, wish I had more time to help more! This is starting to look good!
I have a segfault on shutdown with that, but had another one before the PR so not sure how much we care about these in that state, here it is:
==5562==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x7f8e3ec5a327 bp 0x7ffdb9ce8ea0 sp 0x7ffdb9ce8e78 T0)
==5562==The signal is caused by a WRITE memory access.
==5562==Hint: address points to the zero page.
#0 0x7f8e3ec5a326 in wl_list_remove (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0xc326)
#1 0x7f8e3e818920 in wlr_output_destroy ../types/wlr_output.c:300
#2 0x7f8e3e7fd606 in wlr_drm_backend_destroy ../backend/drm/backend.c:34
#3 0x7f8e3e7fb354 in wlr_backend_destroy ../backend/backend.c:36
#4 0x7f8e3e806d25 in multi_backend_destroy ../backend/multi/backend.c:35
#5 0x7f8e3e7fb354 in wlr_backend_destroy ../backend/backend.c:36
#6 0x55917aab44ae in server_fini ../sway/server.c:70
#7 0x55917aab3c6a in main ../sway/main.c:417
#8 0x7f8e3dd03560 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20560)
#9 0x55917aab2179 in _start (/opt/wayland/bin/sway+0x12179)
Could very well be in wlroots, I'm on today's master there (d654a12)
| return error; | ||
| } | ||
|
|
||
| if (config->reading && strcmp("{", argv[1]) == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The if (argc > 2) check should be done before this line and return an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, there's already checkarg(argc, "input", EXPECTED_AT_LEAST, 2)). So just remove the check, I guess? (And remove this useless return cmd_results_new(CMD_BLOCK_INPUT, NULL, NULL);)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the checkarg needs to expect 3 arguments for seat <name> <command> or seat <name> {, then the argc check will be useless. Maybe this was copied over from the back block, which doesn't require an identifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the command name is included in argc, is it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
argc is 1 for a command with no argument with just argv[0] set, so yes it is. You'll have 1 + number of arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about it. Right below, argv[0] is used as the device identifier and argv[1] is {.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, it gets the original args minus the first command. Going to fix it by doing another checkarg so a command like seat <name> attach is not valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is confusing. In sway's command handlers argv[0] is the first argument and argv[-1] is the command name.
sway/commands/seat.c
Outdated
| return cmd_results_new(CMD_BLOCK_SEAT, NULL, NULL); | ||
| } | ||
|
|
||
| if (argc > 2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here: useless because of checkarg.
sway/input/cursor.c
Outdated
| double y = cursor->cursor->y; | ||
|
|
||
| wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, | ||
| "left_ptr", cursor->cursor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a bug in wlroots about setting a hardware cursor's image twice (it fallbacks to software cursors, I'll fix that).
Setting the cursor image when it isn't needed is inefficient because it involves uploading the image to the GPU each time. This needs to be fixed here (maybe keep the name of the currently selected cursor in the struct?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dunno I'm not going to do the cursor until last and all of this will probably change. I'm happy if it just shows up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay just add a TODO then so we don't forget about it.
sway/input/keyboard.c
Outdated
|
|
||
| xkb_keymap_unref(keyboard->keymap); | ||
| keyboard->keymap = | ||
| xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to check if keyboard->keymap == NULL here in case the keymap doesn't exist.
|
@martinetd yeah that's a wlroots issue related to a recent change. Make an issue there and we'll investigate it. |
|
Ok I think I fixed everything. |
|
What about that |
|
My bad, for some reason I was still looking at the previous diff. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can confirm this addresses all previous issues I could see.
Got a couple more nitpicks that can be fixed now or later, nothing fancy.
|
|
||
| sway_log(L_DEBUG, "new_seat_config(%s)", name); | ||
| seat->name = strdup(name); | ||
| if (!sway_assert(seat->name, "could not allocate name for seat")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should free seat here
| seat->fallback = -1; | ||
| seat->attachments = create_list(); | ||
| if (!sway_assert(seat->attachments, | ||
| "could not allocate seat attachments list")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should free seat->name and seat here (free_seat_config isn't safe to use here because it doesn't check seat->attachments before using it)
sway/input/seat.c
Outdated
|
|
||
| seat->wlr_seat = wlr_seat_create(input->server->wl_display, seat_name); | ||
| if (!sway_assert(seat->wlr_seat, "could not allocate seat")) { | ||
| return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto should free seat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍
|
🎉 |
It's probably going to look a lot like rootston. An input manager that manages device add/remove and passes them to seats.
Tests:
weston-clickdotswaymsg input 0:0:X11_keyboard xkb_layout de.swaymsg seat seat0 attach 0:0:X11_keyboardFuture work: