Skip to content

Conversation

@smichel17
Copy link
Member

@smichel17 smichel17 commented Sep 22, 2025

Overview

I use paperWM with multiple monitors, but have always struggled with the hotkeys for movement. I've memorized them out of necessity, but…

…let's be honest, they make no sense.

  • <Super> with Left and Right arrows, or comma/period, are the hotkeys for switching windows. Ok.
  • Add either Shift or Ctrl to comma/period to drag the window instead. Great.
  • For arrows, Ctrl works the same way, but shift suddenly moves the focus between monitors. ???
  • Okay so to move the current window to a different monitor, now I use <Super><Ctrl><Shift>Left. That's a lot of keys but I guess once I understand that <Shift>Left is moving monitors then adding control grabs the window.
  • <Ctrl><Alt>Left moves the entire workspace. Why does a less common, larger action, require fewer modifiers than moving just one window? Why doesn't it use <Meta> like all other PaperWM "Window manager" hotkeys?

I can go on, but I think my point is made.

Recently I saw the new actions added in #775, and it was a serious 💡 🤯 revelation for me. Obviously this is how PaperWM is supposed to work. If you are switching left and you reach the end of one monitor, the same hotkey just keeps going left.

Well, kinda. There were a few things missing, which I have added in three separate PRs:

  1. Global switch windows - move to **visually** closest window #1076 « 📌 YOU ARE HERE
  2. Global move -- allow switching to empty monitors #1081
  3. Add global move selected window hotkey #1082

This PR

Intuitively, I expected that "keep going left" would focus the window that I already see active when looking at the monitor to the left. If I'm only using the keyboard it works great, but if I have the windows like this:

Two workspaces; each letter is a window; uppercase means focused.

[A b c d] [e f g h]

And each window is 50% size, so they're currently visible on two monitors like this:

[A b] [e f]

If I use my mouse to select E

[a b] [E f]

And then use the keyboard shortcut to move left, I get whiplash as the left monitor whisks everything away to focus D.

[c D] [e f]

This PR changes it to just activate the closest visible window on the monitor.

[a B] [e f]

@dawsers Can you play around with this and tell me what you think of it?

@github-actions
Copy link

Thanks for your contribution! We don't accept pull requests to the release branch. I have rebased your pull request onto develop, check for any conflicts.

@github-actions github-actions bot changed the base branch from release to develop September 22, 2025 21:20
@smichel17
Copy link
Member Author

smichel17 commented Sep 22, 2025

smichel17 wants to merge 7 commits into develop from sm/universal-move

This branch name is foreshadowing… after polishing a bit, I think we should make this the default hotkey for movement.

@dawsers
Copy link
Collaborator

dawsers commented Sep 22, 2025

@dawsers Can you play around with this and tell me what you think of it?

Sorry, I am no longer using PaperWM, I ended up writing my own thing, scroll.

I don't remember how it works, but if what you say is what happens, then you are totally right, the more intuitive behavior would be to focus on the closest window on the other monitor that can be seen.

@smichel17
Copy link
Member Author

No worries. Thank you for the inspiration!

No braces around if statements make me nervous.
We have two direction enums, which basically mean the same thing.
Previously we were figuring out which monitor we need to go to depending
on which way we were going out of bounds, but that's unnecessary, since
we already know which direction we're heading.

If this mapping is needed elsewhere I'll move it into a util or
something.
In the diagrams below, assume parens are workspaces, brackets are
windows currently showing on a monitor, and letters are windows.
Uppercase means focused, and assume all windows are 50% sized.

If we start like this:

    ([A b] c d) ([e f])

Then I use the mouse to move to the monitor to the right:

    ([a b] c d) ([E, f])

Then I use this keybind to move left again. I'd get whiplash as the
monitor on the left spins to move windows c and d back onscreen.

    (a b [c D]) ([u, f])

Now, instead it'll just pick the closest window on screen:

    ([a B] c d) ([e, f])

Which makes sense visually, since in this situation I'm thinking "I want
to move left" and what I see is this transition:

    [a b][E f]
    [a B][e f]

It might make sense to add some margin here in case window c is just
barely peeking a few pixels on screen (in which case we might still
prefer to focus window b).

Also, some small code cleanup: using more `const`

It's hard for me to keep track of what variables mean, when we are
re-assigning them. So, create a new variable to track the new space, and
make everything const so we know it's not being updated.

_Maybe_ re-using a variable saves a few bytes of memory, or a little bit
of extra garbage collection time, but this function is only being run
once per user input, so I doubt it's a significant performance impact.
@smichel17 smichel17 force-pushed the sm/universal-move branch 2 times, most recently from 439c318 to a16a6e4 Compare September 26, 2025 13:47
@smichel17 smichel17 marked this pull request as ready for review September 26, 2025 13:48
@smichel17 smichel17 changed the title Global switch workspaces - move to active window, not "closest" window Global switch windows - move to **visually** closest window Sep 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants