nikitabobko / AeroSpace

AeroSpace is an i3-like tiling window manager for macOS
https://nikitabobko.github.io/AeroSpace/guide
MIT License
6.22k stars 101 forks source link

Is there a way to bring the window of a specific app from another workspace to current workspace and send it back using a single keybind? #296

Open farhantamzid opened 3 months ago

farhantamzid commented 3 months ago

I usually have Safari open on workspace E, vscode on R and my terminal on T.

For example: Let's say I'm using safari on workspace E and I need to do something on my terminal. I want to bring terminal from workspace T to my current workspace E using a specific keybind, and when im done using the terminal i can use the same keybind to send the terminal back to workspace T.

I've already been able to get something along the lines of that to work. Since I dont know if specific app windows can be grabbed through its id or not, ive basically gone around the issue and botched a few things up.

The way I have it set up right now, I have to use a keybinds to move the node from terminal to safari, and another keybind to move it back to T. And since I want to be able to do this with my vs code workspace as well, i have another two keybinds setup for that as well. (As well as another two for when i want to use VSCode+Safari)

aerospace_config.txt

This achieves what I need, but its very demanding to remember all the combinations of different keybinds, for 3 different workspaces. I imagine it would be possible to use only a single keybind to achieve this if somehow the window can be grabbed through the app ID and not have to specify the workspace or the node everytime. So that the window gets grabbed regardless of which workspace its in.

Is this currently possible? and if not, are there any plans of implementing a feature like this in the future? Thank you so much <3

farhantamzid commented 3 months ago

fixed config file with proper comments. the other file is messed up.

aerospace_config.txt

Petemir commented 1 month ago

I wanted to achieve a similar thing to what you are doing, but having what you call "workspace T" as a "storage workspace" to hide several apps (i.e., a scratchpad).

I took the script by @hauang65 from #272 and modified it a bit:

#!/usr/bin/env bash

APP_ID=$1
APP_NAME=$2

focus_app() {
  current_workspace=$(aerospace list-workspaces --focused)
  app_window_id=$(aerospace list-windows --all --format "%{window-id}%{right-padding} | %{app-name}" | grep $APP_NAME | cut -d' ' -f1 | sed '1p;d')
  aerospace focus --window-id $app_window_id
  aerospace move-node-to-workspace $current_workspace
  aerospace workspace $current_workspace
  aerospace move-mouse window-lazy-center
}

app_closed() {
  if [ "$(aerospace list-windows --all --format '%{app-name}' | grep $APP_NAME)" == "" ]; then
    true
  else
    false
  fi
}

app_focused() {
  if [ "$(aerospace list-windows --focused --format "%{app-bundle-id}")" == "$APP_ID" ]; then
    true
  else
    false
  fi
}

unfocus_app() {
  aerospace move-node-to-workspace scratchpad
}

if app_closed; then
  open -a $APP_NAME
  sleep 0.5
else
  if app_focused; then
    unfocus_app
  else
    focus_app
  fi
fi

Basically:

This script is binded to only one shortcut per app, and it receives as a parameter the app's bundle id and the app's name (although you could only have one of the two parameters, I found it useful when dealing with e.g. PWA from chrome, which share the app's name but do not share the bundle id).

As an example keybind: alt-shift-t = 'exec-and-forget /PATH/TO/SCRIPT/script.sh com.github.wez.wezterm WezTerm'

This isn't exactly what you asked for, though. In order to achieve what (I think that) you want, you would need to save your desired app's workspace ("T") on a file, as a variable wouldn't survive to two different executions of the script.

There are some caveats (that I found so far, at least) to my modified script:

Edit: I just saw that the feature I wanted to request at the end is actually covered by #186 :) .

x418 commented 4 weeks ago

I wanted to achieve a similar thing to what you are doing, but having what you call "workspace T" as a "storage workspace" to hide several apps (i.e., a scratchpad).

I took the script by @hauang65 from #272 and modified it a bit:

This is such a funny coincidence. I also took inspiration from that script and did something similar (except I call my workspace NSP like xmonad). I didn't think of the aerospace move-mouse window-lazy-center like your script. Pretty neat. Thanks for attaching it here.

Did you find a way to get the flickering (from workspace switching) to go away?

farhantamzid commented 4 weeks ago

I wanted to achieve a similar thing to what you are doing, but having what you call "workspace T" as a "storage workspace" to hide several apps (i.e., a scratchpad).

I took the script by @hauang65 from #272 and modified it a bit:

#!/usr/bin/env bash

APP_ID=$1
APP_NAME=$2

focus_app() {
  current_workspace=$(aerospace list-workspaces --focused)
  app_window_id=$(aerospace list-windows --all --format "%{window-id}%{right-padding} | %{app-name}" | grep $APP_NAME | cut -d' ' -f1 | sed '1p;d')
  aerospace focus --window-id $app_window_id
  aerospace move-node-to-workspace $current_workspace
  aerospace workspace $current_workspace
  aerospace move-mouse window-lazy-center
}

app_closed() {
  if [ "$(aerospace list-windows --all --format '%{app-name}' | grep $APP_NAME)" == "" ]; then
    true
  else
    false
  fi
}

app_focused() {
  if [ "$(aerospace list-windows --focused --format "%{app-bundle-id}")" == "$APP_ID" ]; then
    true
  else
    false
  fi
}

unfocus_app() {
  aerospace move-node-to-workspace scratchpad
}

if app_closed; then
  open -a $APP_NAME
  sleep 0.5
else
  if app_focused; then
    unfocus_app
  else
    focus_app
  fi
fi

Basically:

  • if the app is closed, open it (which will focus on the app by default).
  • if the app is open

    • if it is focused, unfocus it (i.e., send it to the scratchpad)

    • if it is unfocused

    • save the current workspace ("original workspace") in a variable

    • focus on the desired app

    • move the (now focused) desired app to the "original workspace"

    • switch to the "original workspace"

    • focus the mouse on the app's window

This script is binded to only one shortcut per app, and it receives as a parameter the app's bundle id and the app's name (although you could only have one of the two parameters, I found it useful when dealing with e.g. PWA from chrome, which share the app's name but do not share the bundle id).

As an example keybind: alt-shift-t = 'exec-and-forget /PATH/TO/SCRIPT/script.sh com.github.wez.wezterm WezTerm'

This isn't exactly what you asked for, though. In order to achieve what (I think that) you want, you would need to save your desired app's workspace ("T") on a file, as a variable wouldn't survive to two different executions of the script.

There are some caveats (that I found so far, at least) to my modified script:

  • If you have two windows with the same bundle ID, it will grab the first one on the list.
  • I get some kind of "race condition" when using the AutoRaise app (which changes the app focus from mouse movements). If I accidentally move the mouse to a different application between the lines aerospace focus --window-id $app_window_id and aerospace move-node-to-workspace $current_workspace, the focused window will change, and this window will be sent instead to the original workspace, rather than the desired app's window. This could be solved by having a new "move-window" command for AeroSpace which moves a window based on some filter (such as app-id, window-id, app-bundle-id), as the first three lines of the "if it is unfocused" branch could be merged into only one command. I have to create the feature request for this, though :).

Edit: I just saw that the feature I wanted to request at the end is actually covered by #186 :) .

Stellar work. I actually ended up moving over to yabai and giving up on aerospace. I found yabai to be much more customizable to my specific preferences. I have a really nice config working on yabai for my personal preferences.

Some features:

so for example, if im working on a project in vscode, i bring over the terminal for a quick little command or whatever and I move over to my safari workspace without sending terminal back to workspace T, its a non issue, Because pressing cmd+T always checks if the terminal window is present in workspace T, if its not, it searches through all open workspaces and brings it over.

This allows for very little mental headroom needed on my part because i know that no matter what, cmd+T will ALWAYS bring up terminal, cmd+S will always bring up safari and cmd+V will always bring up vscode.

Petemir commented 4 weeks ago

I wanted to achieve a similar thing to what you are doing, but having what you call "workspace T" as a "storage workspace" to hide several apps (i.e., a scratchpad). I took the script by @hauang65 from #272 and modified it a bit:

I didn't think of the aerospace move-mouse window-lazy-center like your script. Pretty neat. Thanks for attaching it here.

No problem! Glad you like it :). I didn't think about it at first neither, but because I'm also using AutoRaise (i.e. focus follows mouse) whenever I used that script to bring a floating window from another workspace, when I returned to the original workspace the mouse would be anywhere, so when I moved it I would lose the focus from the sticky window and lose it in the background. Luckily AeroSpace had that command available!

Did you find a way to get the flickering (from workspace switching) to go away?

I'm not sure exactly what you mean, if generic flickers of using AeroSpace (which I have, every now and then), or of the flickering that is generated by the script because of moving to the "scratchpad workspace" and then back. In the latter case, no, I wasn't able to fix it, but I know that it will be possible to fix it when #186 it's done, as it will be possible to bring windows by their id to the current workspace.

Stellar work. I actually ended up moving over to yabai and giving up on aerospace. I found yabai to be much more customizable to my specific preferences. I have a really nice config working on yabai for my personal preferences.

Great to hear that you found a solution that works for you! Indeed what you list seems interesting. But my Linux laptop just broke, I was forced to steal my wife's mac (and lost two weeks adapting my workflow) so I can finish my neverending PhD... so I cannot waste time jumping to any other program anytime soon 😅.

x418 commented 3 weeks ago

I'm not sure exactly what you mean, if generic flickers of using AeroSpace (which I have, every now and then), or of the flickering that is generated by the script because of moving to the "scratchpad workspace" and then back. In the latter case, no, I wasn't able to fix it, but I know that it will be possible to fix it when https://github.com/nikitabobko/AeroSpace/issues/186 it's done, as it will be possible to bring windows by their id to the current workspace.

Yes, I meant the latter as it's a bit more pronounced in my case (I have three scratchpad apps). Really look forward to #186 as it's going to make me stick to the Mac even if I would dearly miss the configurability of xmonad.

Good luck with your PhD!