├── lib ├── colors.js ├── style.js └── utils.js ├── resources ├── screenshots │ ├── yabai-uberbar.png │ └── yabai-uberbar-demo.gif ├── yabairc_vars ├── uber-bar-refresh ├── yabairc └── skhdrc ├── components ├── Spaces.jsx ├── Window.jsx ├── Space.jsx ├── Status.jsx └── Svg.jsx ├── package.json ├── bg.jsx ├── yabai-uberbar.jsx ├── scripts └── screens-scripts ├── LICENSE ├── .gitignore └── README.md /lib/colors.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | bg: '#222e39', 4 | accent: '#0081AD', 5 | }; 6 | 7 | -------------------------------------------------------------------------------- /resources/screenshots/yabai-uberbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamWagner/yabai-uberbar/HEAD/resources/screenshots/yabai-uberbar.png -------------------------------------------------------------------------------- /resources/screenshots/yabai-uberbar-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdamWagner/yabai-uberbar/HEAD/resources/screenshots/yabai-uberbar-demo.gif -------------------------------------------------------------------------------- /components/Spaces.jsx: -------------------------------------------------------------------------------- 1 | import Space from './Space.jsx'; 2 | 3 | // capture vars current, config and return space mapping function 4 | const reshapeSpaces = (current, config) => s => ({ 5 | space: s.space, windows: s.windows, current, config, 6 | }); 7 | 8 | const Spaces = ({ spaces, current, config }) => spaces 9 | .map(reshapeSpaces(current, config)) 10 | .map(Space); 11 | 12 | export default Spaces; 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yabai-uberbar", 3 | "version": "1.0.0", 4 | "description": "Personal [Übersicht](http://tracesof.net/uebersicht/) bar with graphic overview of windows on each space for use with [yabai](https://github.com/koekeishiya/yabai).", 5 | "main": "index.js", 6 | "directories": { 7 | "lib": "lib" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [], 13 | "author": "Adam Wagner", 14 | "license": "BSD 2-Clause License", 15 | "dependencies": { 16 | "shell-env": "^3.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bg.jsx: -------------------------------------------------------------------------------- 1 | /* eslint react/react-in-jsx-scope: off */ 2 | import { barBgStyle } from './lib/style'; 3 | import { defaultConfig } from './lib/utils'; 4 | 5 | export const command = './scripts/screens-scripts'; 6 | 7 | export const initialState = '[]'; 8 | 9 | export const refreshFrequency = false; 10 | 11 | export const updateState = event => event.output || initialState; 12 | 13 | export const render = (output) => { 14 | if (!output) return
error
; 15 | const data = JSON.parse(output); 16 | const config = data.config || defaultConfig; 17 | 18 | return
; 19 | }; 20 | -------------------------------------------------------------------------------- /resources/yabairc_vars: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ====== Variables ============================= 4 | 5 | # native, uber 6 | export BAR="uber" 7 | # export BAR="native" 8 | export WINDOW_GAP=10 9 | export PADDING=$WINDOW_GAP 10 | 11 | if test "$BAR" = 'uber'; then 12 | export YABAI_BAR="off" 13 | export BAR_HEIGHT=40 14 | elif test "$BAR" = 'native'; then 15 | export YABAI_BAR="on" 16 | export BAR_HEIGHT=$PADDING 17 | else 18 | export PADDING_TOP=$PADDING 19 | fi 20 | 21 | export PADDING_TOP=$((BAR_HEIGHT + PADDING)) 22 | export NORMAL_BORDER_COLOR=0x770fcbff 23 | export ACTIVE_BORDER_COLOR=0xff0fcbff 24 | export MOVE_BORDER_COLOR=0xffff0f77 25 | export RESIZE_BORDER_COLOR=0xffffa70f 26 | 27 | 28 | center_grid='26:26:5:5:16:16' 29 | small_center_grid='5:5:4:0:1:1' 30 | left_half='1:2:0:0:1:1' 31 | right_half='1:2:1:0:1:1' 32 | 33 | # ====== Output ============================= 34 | echo $BAR_HEIGHT 35 | -------------------------------------------------------------------------------- /yabai-uberbar.jsx: -------------------------------------------------------------------------------- 1 | /* eslint max-len: off */ 2 | /* eslint react/react-in-jsx-scope: off */ 3 | /* eslint import/no-unresolved: off */ 4 | import Spaces from './lib/Spaces.jsx'; 5 | import { backgroundStyle } from './lib/style'; 6 | import { defaultConfig } from './lib/utils'; 7 | 8 | export const command = './scripts/screens-scripts'; 9 | 10 | export const initialState = '[]'; 11 | 12 | export const refreshFrequency = false; 13 | 14 | export const updateState = event => event.output || initialState; 15 | 16 | export const render = (output) => { 17 | if (!output) return
error
; 18 | const data = JSON.parse(output); 19 | const config = data.config || defaultConfig; 20 | 21 | return ( 22 |
23 | 28 |
29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /scripts/screens-scripts: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/dash 2 | 3 | PATH=$(/usr/libexec/path_helper) 4 | resolution=$(yabai -m query --displays | jq -r '{screenWidth: .[0].frame.w, screenHeight: .[0].frame.h } | tostring') 5 | config="$(/Users/adamwagner/Programming/dotfiles/window-managers/yabai/yabairc_vars)" 6 | current=$(space-select) 7 | spaces=$(spaces-windows) 8 | 9 | # heredoc ~25ms faster than jq at constructing json output 10 | # details: {{{ 11 | # Benchmark #1: construct json output with jq 12 | # Time (mean ± σ): 189.7 ms ± 1.8 ms [User: 235.9 ms, System: 30.6 ms] 13 | # Range (min … max): 185.5 ms … 193.3 ms 15 runs 14 | 15 | # Benchmark #1: construct json output with heredoc 16 | # Time (mean ± σ): 165.0 ms ± 3.1 ms [User: 211.4 ms, System: 30.7 ms] 17 | # Range (min … max): 161.4 ms … 171.5 ms 17 runs 18 | # }}} 19 | cat < ( 8 | 17 | ); 18 | 19 | const Window = (win, barHeight) => { 20 | if (win.frame) { 21 | const winProps = computeWindow(win, barHeight); 22 | console.log('winProps:', winProps); 23 | 24 | return ( 25 | 26 | {win.floating && } 27 | 28 | { winProps.isZoomed && } 29 | 30 | ); 31 | } 32 | 33 | console.log('no windows'); 34 | 35 | return
No windows
; 36 | }; 37 | 38 | export default Window; 39 | -------------------------------------------------------------------------------- /lib/style.js: -------------------------------------------------------------------------------- 1 | /* eslint import/no-unresolved: off */ 2 | import { css } from 'uebersicht'; 3 | import colors from './colors'; 4 | 5 | export const spaceStyle = width => css` 6 | display: flex; 7 | width: ${width - 10}px; 8 | padding: 6px 0px; 9 | position: relative; 10 | svg { 11 | flex: 1 0 100%; 12 | display: block; 13 | height: auto; 14 | width: auto; 15 | fill: ${colors.bg} !important; 16 | opacity: 0.5; 17 | } 18 | 19 | svg > rect { 20 | fill: white; 21 | stroke: white; 22 | } 23 | 24 | svg path { 25 | fill: white !important; 26 | } 27 | `; 28 | 29 | export const currentStyle = css` 30 | svg { 31 | opacity: 1 !important; 32 | } 33 | svg > rect { 34 | fill: white !important; 35 | stroke: white !important; 36 | } 37 | `; 38 | 39 | export const backgroundStyle = config => css` 40 | height: ${parseInt(config.barHeight)}px; 41 | display: flex; 42 | `; 43 | 44 | 45 | export const barBgStyle = config => css` 46 | height: ${parseInt(config.barHeight)}px; 47 | position: fixed; 48 | z-index: 0; 49 | background: rgba(35, 33, 70, 0.3); 50 | top: 0px; 51 | right: 0px; 52 | left: 0px; 53 | `; 54 | -------------------------------------------------------------------------------- /components/Space.jsx: -------------------------------------------------------------------------------- 1 | /* eslint react/prop-types: off */ 2 | /* eslint import/no-unresolved: off */ 3 | import { React } from 'uebersicht'; 4 | import { computeSpace } from '../lib/utils'; 5 | import Window from './Window.jsx'; 6 | import { Svg, SvgGroup, CenteredText } from './Svg.jsx'; 7 | 8 | const SpaceNumber = ({ color, children }) => ( 9 | 10 | 11 | { children } 12 | 13 | 14 | ); 15 | 16 | const Space = ({ space, windows = [], current, config }) => { 17 | const { index, 18 | barHeight, 19 | screenWidth, 20 | screenHeight, 21 | hasWindows, 22 | spaceWindows, 23 | style, 24 | spaceIdxColor } = computeSpace(space, windows, current, config); 25 | 26 | return ( 27 |
28 | 29 | { hasWindows && spaceWindows.map(w => Window(w, barHeight)) } 30 | 31 | {index} 32 | 33 | 34 |
35 | ); 36 | }; 37 | 38 | export default Space; 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2020, Adam Wagner 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /resources/uber-bar-refresh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Modified from: https://github.com/marshallbrekka/yabai-config/ on 2020-02-09 3 | 4 | # NOTE: If uebersicht details change 5 | # and the websocket approach breaks, set compatibility_mode="true" 6 | compatibility_mode="false" 7 | 8 | # We can refresh ubersicht in 13ms instead of 117ms 9 | # by using `websocat` instead of Applescript (see details below). 10 | # If this ever breaks we can always fall back to using applescript script to regain functionality. 11 | # Performance details (2020-02-09): {{{ 12 | # Benchmark #1: websocat 13 | # Time (mean ± σ): 13.0 ms ± 2.6 ms 14 | # Range (min … max): 8.4 ms … 27.5 ms 170 runs 15 | 16 | # Benchmark #2: Applescript 17 | # Time (mean ± σ): 117.4 ms ± 16.8 ms 18 | # Range (min … max): 95.6 ms … 139.0 ms 22 runs 19 | # }}} 20 | if [[ $(type -P websocat) = "" || "$compatibility_mode" = "true" ]]; then 21 | echo "Falling back to applescript, websocat not installed. https://github.com/vi/websocat" 22 | osascript -e 'tell application id "tracesOf.Uebersicht" to refresh widget id "yabai-uberbar-jsx"' 23 | exit 0 24 | fi 25 | 26 | # This is the Uebersicht server address. 27 | HOST=127.0.0.1:41416 28 | 29 | payload="\"yabai-uberbar-jsx\"" 30 | ws_event="WIDGET_WANTS_REFRESH" 31 | # echo "Posting event ${ws_event} with payload ${payload}" 32 | # The server checks the origin to filter out invalid requests, so make sure we set it. 33 | echo "{\"type\":\"${ws_event}\",\"payload\":${payload}}" | 34 | websocat -E --origin http://$HOST ws://$HOST 35 | -------------------------------------------------------------------------------- /components/Status.jsx: -------------------------------------------------------------------------------- 1 | /* eslint react/react-in-jsx-scope: off */ 2 | 3 | import batteryLevels from './batteryLevels'; 4 | 5 | const getbatteryStatus = ({ amount, state }) => { 6 | amount = parseInt(amount); 7 | const isLoading = state === 'AC'; 8 | 9 | for (let i = 0; i <= batteryLevels.length - 1; i++) { 10 | const item = batteryLevels[i]; 11 | 12 | if (amount <= item.levelMax) { 13 | return ( 14 |
15 | {item.icon} 16 | 17 | {amount}% 18 | 19 |
20 | ); 21 | } 22 | } 23 | }; 24 | 25 | const getWifiStatus = ({ netStatus, netName }) => { 26 | const netIcons = { 27 | 'Wi-Fi': '', 28 | 'USB 10/100/1000 LAN': '', 29 | 'Apple USB Ethernet Adapter': '', 30 | none: '', 31 | }; 32 | netName = netName === 'none' ? 'Not connected' : netName; 33 | 34 | return ( 35 |
36 | {netIcons[netStatus]} 37 | {netName} 38 |
39 | ); 40 | }; 41 | 42 | const getDateTime = ({ time, date }) => ( 43 |
44 |
{time}
45 |
{date}
46 |
47 | ); 48 | 49 | const render = ({ output }) => { 50 | const values = output.split('@'); 51 | 52 | const dateTimeInfos = { 53 | time: values[0].replace(/^\s+|\s+$/g, ''), 54 | date: values[1], 55 | }; 56 | const batteryInfos = { 57 | amount: values[2], 58 | state: values[3].split(' ')[1], 59 | }; 60 | const wifiInfos = { 61 | netStatus: values[4].split(' ')[1], 62 | netName: values[5], 63 | }; 64 | 65 | return ( 66 |
67 |
{getbatteryStatus(batteryInfos)}
68 |
{getWifiStatus(wifiInfos)}
69 |
{getDateTime(dateTimeInfos)}
70 |
71 | ); 72 | }; 73 | 74 | export default render; 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /components/Svg.jsx: -------------------------------------------------------------------------------- 1 | /* eslint react/react-in-jsx-scope: off */ 2 | /* eslint react/prop-types: off */ 3 | /* eslint max-len: off */ 4 | 5 | const SvgRect = ({ width, height }) => ( 6 | 14 | ); 15 | 16 | const SvgGroup = ({ children }) => ( 17 | 18 | {children} 19 | 20 | ); 21 | 22 | const SvgBlur = () => ( 23 | 24 | 25 | 26 | 27 | 28 | ); 29 | 30 | const Svg = ({ width, height, children }) => ( 31 | 36 | 37 | 38 | {children} 39 | 40 | ); 41 | 42 | const CenteredText = ({ color, children }) => ( 43 | 50 | { children } 51 | 52 | ); 53 | 54 | const MaxIcon = ({ width, height }) => ( 55 | 62 | 63 | 64 | 65 | 66 | 67 | ); 68 | 69 | export { 70 | Svg, SvgRect, SvgGroup, SvgBlur, CenteredText, MaxIcon, 71 | }; 72 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | /* eslint import/no-unresolved: off */ 2 | import { css } from 'uebersicht'; 3 | import { spaceStyle, currentStyle } from './style'; 4 | import colors from './colors'; 5 | 6 | const windowIsZoomed = win => win['zoom-fullscreen'] === 1 || win['zoom-parent'] === 1; 7 | 8 | const computeStyle = (opacity = 0, color, z = 'initial') => css` 9 | opacity: ${opacity}; 10 | fill: ${color}!important; 11 | z-index: ${z}; 12 | `; 13 | 14 | export const defaultConfig = { 15 | barHeight: 50, 16 | resolution: { 17 | screenWidth: 1920, screenHeight: 1200, 18 | }, 19 | }; 20 | 21 | export const computeSpace = (space, windows, current, config) => { 22 | const index = space; 23 | 24 | const { barHeight, resolution } = config; 25 | const { screenWidth, screenHeight } = resolution; 26 | const barSpaceWidth = barHeight / (screenHeight / screenWidth); 27 | 28 | const hasWindows = windows.length > 0; 29 | const hasZoomed = windows.filter(windowIsZoomed).length > 0; 30 | 31 | const spaceIdxColor = hasWindows 32 | ? 'white' 33 | : colors.bg; 34 | 35 | const currentSpaceClass = (index === parseInt(current)) 36 | ? currentStyle 37 | : ''; 38 | 39 | const style = [spaceStyle(barSpaceWidth), currentSpaceClass].join(' '); 40 | 41 | if (hasWindows && hasZoomed) { 42 | // sort zoomed windows to end 43 | // will appear on top in svg z-index stack 44 | windows.sort(windowIsZoomed); 45 | } 46 | 47 | return { 48 | index, 49 | barHeight, 50 | screenWidth, 51 | screenHeight, 52 | hasWindows, 53 | hasZoomed, 54 | spaceWindows: windows, 55 | style, 56 | spaceIdxColor, 57 | }; 58 | }; 59 | 60 | 61 | export const computeWindow = (win, barHeight) => { 62 | const { frame, id, floating } = win; 63 | const opacity = floating 64 | ? 0.65 65 | : 1; 66 | 67 | const isZoomed = windowIsZoomed(win); 68 | const color = isZoomed 69 | ? colors.accent 70 | : 'inherit'; 71 | 72 | const { x, y, w, h } = frame; 73 | const margin = 15 / (barHeight / 100); 74 | 75 | const width = w - 2 * margin; 76 | const height = h - 2 * margin; 77 | const posX = x + margin; 78 | const posY = y + margin; 79 | const style = computeStyle(opacity, color); 80 | 81 | return { 82 | id, 83 | width, 84 | height, 85 | posX, 86 | posY, 87 | floating, 88 | isZoomed, 89 | style, 90 | margin, 91 | }; 92 | }; 93 | 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yabai-uberbar 2 | 3 | Personal [Übersicht](http://tracesof.net/uebersicht/) bar with graphic overview of windows on each space for use with [yabai](https://github.com/koekeishiya/yabai). 4 | 5 | _Disclaimers:_ 6 | - This has only been tested on my personal machine 7 | - Numerous values (especially script paths) are hardcoded and will likely require manual 8 | tweaking to work on your system 9 | 10 | *Screen Shots:* 11 | ![img](https://github.com/AdamWagner/yabai-uberbar/blob/master/resources/screenshots/yabai-uberbar.png?raw=true) 12 | ![img](https://github.com/AdamWagner/yabai-uberbar/blob/master/resources/screenshots/yabai-uberbar-demo.gif?raw=true) 13 | 14 | This widget is a heavily modified form of [blaadje/fancyBar](https://github.com/blaadje/fancyBar#readme), which itself was based on [apierz/nerdbar.widget](https://github.com/apierz/nerdbar.widget). 15 | 16 | 17 | ## Dependencies 18 | 19 | **Yabai dependencies** 20 | - [koekeishiya/yabai](https://github.com/koekeishiya/yabai): A tiling window manager for macOS based on binary space partitioning. 21 | - [koekeishiya/skhd](https://github.com/koekeishiya/skhd): Simple hotkey daemon for macOS. 22 | 23 | **Übersicht dependencies** 24 | - [nodejs](https://nodejs.org/en/): a JavaScript runtime built on Chrome's V8 JavaScript engine. 25 | - [felixhageloh/uebersicht](https://github.com/felixhageloh/uebersicht): Desktop widgets via a webview. 26 | 27 | **yabai-uberbar dependencies** 28 | - [stedolan/jq](https://github.com/stedolan/jq): Command-line JSON processor. 29 | - [dash shell](http://gondor.apana.org.au/~herbert/dash/): Lightweight, fast-starting shell. 30 | 31 | 32 | --- 33 | 34 | ## Installation 35 | 36 | **Install dependencies** 37 | ```bash 38 | brew install dash jq yabai skhd node 39 | brew cask install ubersicht 40 | ``` 41 | 42 | **Clone the widget to your Übersicht widget directory** 43 | ```bash 44 | # The default Übersicht widget directory: 45 | WIDGET_DIR="$HOME/Library/Application\ Support/Übersicht/widgets/yabai-uberbar.widget" 46 | git clone https://github.com/AdamWagner/yabai-uberbar.git "$WIDGET_DIR" 47 | ``` 48 | 49 | **Configure yabai** 50 | Use [yabai signals](https://github.com/koekeishiya/yabai/wiki/Commands#automation-with-rules-and-signals) to refresh Übersicht when you change space or create, destroy, move, or resize windows: 51 | 52 | Add the following to your `.yabairc` file: 53 | 54 | ```bash 55 | yabai -m signal --add event=space_changed action="uber-bar-refresh" 56 | yabai -m signal --add event=window_created action="uber-bar-refresh" 57 | yabai -m signal --add event=window_destroyed action="uber-bar-refresh" 58 | yabai -m signal --add event=window_moved action="uber-bar-refresh" 59 | yabai -m signal --add event=window_resized action="uber-bar-refresh" 60 | yabai -m signal --add event=bar_refresh action="uber-bar-refresh" 61 | ``` 62 | 63 | An example implementation of [uber-bar-refresh](https://github.com/AdamWagner/yabai-uberbar/blob/master/refresh) via Applescript is included. 64 | 65 | ## Enhancements / Fixes 66 | 67 | - Flesh out "zoomed window indicator" POC 68 | - Improve visibility of space index number against window edges 69 | - Faster performance. Consider [React-nodegui](https://react.nodegui.org/)? 70 | - Indicate active window 71 | - Indicate application running in active window 72 | - Multi-monitor support 73 | - Add time, date, battery, wifi, etc. See [/qhuyduong/yabai-status-bar](https://github.com/qhuyduong/yabai-status-bar/blob/master/scripts/right_bar.sh). 74 | 75 | -------------------------------------------------------------------------------- /resources/yabairc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env dash 2 | 3 | # Notes ------------------------------------------------------------------------ {{{ 4 | 5 | # Use jq to read & process yabai output: 6 | # https://github.com/koekeishiya/yabai/issues/18 7 | # yabai -m query --spaces --space 2 | jq .monitor 8 | 9 | # }}} 10 | 11 | # echo "$SHELL" 12 | . /Users/adamwagner/Programming/dotfiles/window-managers/yabai/yabairc_vars # source yabairc vars 13 | if pgrep sicht; then pkill sicht; fi # kill ubersicht if running 14 | if test $BAR = 'uber'; then uber-bar-refresh; fi 15 | 16 | # delete monocle mode lock files from previous sessions 17 | # from https://github.com/koekeishiya/yabai/issues/83 18 | find "${TMPDIR}" -type f -perm +111 -name "yabai_${USER}_monocle_mode_*" -delete 19 | 20 | # Bar settings {{{ 21 | yabai -m config status_bar "$YABAI_BAR" 22 | yabai -m config status_bar_icon_font "Operator Mono SSm Lig Book:Regular:13.0" 23 | yabai -m config status_bar_text_font "Operator Mono SSm Lig Book:Regular:13.0" 24 | yabai -m config status_bar_background_color 0xdd242e38 25 | yabai -m config status_bar_foreground_color 0xffa8a8a8 26 | 27 | yabai -m config status_bar_space_icon_strip 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 28 | 29 | yabai -m config status_bar_power_icon_strip   30 | yabai -m config status_bar_space_icon  31 | yabai -m config status_bar_clock_icon  32 | # }}} 33 | # Global settings {{{ 34 | yabai -m config layout bsp 35 | yabai -m config top_padding "$PADDING_TOP" 36 | yabai -m config bottom_padding "$PADDING" 37 | yabai -m config left_padding "$PADDING" 38 | yabai -m config right_padding "$PADDING" 39 | yabai -m config window_gap "$PADDING" 40 | 41 | yabai -m config split_ratio 0.5 42 | yabai -m config auto_balance off 43 | yabai -m config mouse_modifier ctrl 44 | yabai -m config mouse_action1 resize 45 | yabai -m config mouse_action2 move 46 | # }}} 47 | # Window settings {{{ 48 | yabai -m config window_shadow float 49 | yabai -m config window_topmost on 50 | yabai -m config window_opacity on 51 | yabai -m config window_opacity_duration 0.0 52 | yabai -m config active_window_opacity 1.0 53 | yabai -m config normal_window_opacity 1.0 54 | # Window border settings {{{ 55 | yabai -m config window_border on 56 | yabai -m config window_border_width 0 57 | yabai -m config window_border_radius 0 58 | yabai -m config active_window_border_topmost off 59 | yabai -m config window_border_placement inset # exterior (default), inset, interior 60 | 61 | yabai -m config normal_window_border_color 0x0045a1cc # nord snow storm gray 62 | yabai -m config active_window_border_color 0xff5e81ac # nord frost blue 63 | yabai -m config insert_window_border_color 0xffd48ead # nord aurora purple 64 | # }}} 65 | # }}} 66 | # Mouse settings {{{ 67 | yabai -m config mouse_follows_focus on 68 | yabai -m config focus_follows_mouse autofocus 69 | yabai -m config focus_follows_mouse off # off/autofocus/autoraise 70 | # }}} 71 | # Spaces can be assigned a label in yabai {{{ 72 | yabai -m space 1 --label Vim 73 | yabai -m space 2 --label Term 74 | yabai -m space 3 --label Browser 75 | yabai -m space 4 --label Music 76 | 77 | # Unfortunately, space labels can't be used in rules, 78 | # although could compute mission-control-index programatically to achieve the 79 | # same effect: $DOTFILES/scripts/yabai/space-label-to-index 80 | # yabai -m rule --add app="App Store" space="$(space-label-to-index 'Term')" 81 | 82 | 83 | # }}} 84 | # Window rules ================================================================= {{{ 85 | yabai -m rule --add app="ColorSlurp" manage=off border=off 86 | yabai -m rule --add label="Finder" app="^Finder$" title="(Co(py|nnect)|Move|Info|Pref)" manage=off border=off 87 | yabai -m rule --add app="App Store" manage=off border=off 88 | yabai -m rule --add title='.*Preferences.*' manage=off border=off topmost=on # float any window with "Preferences" in title 89 | yabai -m rule --add title='.*Install.*' manage=off border=off topmost=on # float installers 90 | yabai -m rule --add app="^System Preferences$" manage=off border=off # needed because ↑ doesn't cover sub-windows of system prefs. E.g., "General" 91 | yabai -m rule --add app="Activity Monitor" manage=off border=off 92 | yabai -m rule --add app="Calculator" manage=off border=off 93 | yabai -m rule --add app="Transmission" manage=off border=off 94 | yabai -m rule --add app="Dictionary" manage=off border=off 95 | yabai -m rule --add app="Messages" manage=off border=off 96 | yabai -m rule --add app="Preview" manage=off border=off 97 | yabai -m rule --add app="Xee³" manage=off border=off 98 | yabai -m rule --add app="^Simulator$" manage=off 99 | 100 | yabai -m rule --add app="Google Chrome" title="Task Manager" manage=off 101 | yabai -m rule --add app="iTerm2" manage=off border=off 102 | yabai -m rule --add app="iBooks" manage=off 103 | yabai -m rule --add app="Archive Utility" manage=off 104 | yabai -m rule --add app="The Unarchiver" manage=off 105 | yabai -m rule --add app="1Password 7" manage=off grid=4:4:1:1:2:2 106 | yabai -m rule --add app="Karabiner" manage=off 107 | yabai -m rule --add app="Transmission" manage=off 108 | yabai -m rule --add app="Simulator" manage=off 109 | yabai -m rule --add app="VLC" manage=off 110 | yabai -m rule --add app="snwe" sticky=on 111 | yabai -m rule --add app="mpv" grid=1:1:0:0:1:1 border=off manage=off 112 | yabai -m rule --add app="IINA" grid=1:1:0:0:1:1 border=off 113 | yabai -m rule --add app="IINA" title="Window" manage=off # preference window, open url 114 | yabai -m rule --add app="qutebrowser" manage=on # for frameless qutebrowser 115 | yabai -m rule --add app="Google Chrome" title=invalid opacity=0.0 # attempting tod hide the chrome status bar in bottom left ... it doesn't work 116 | yabai -m rule --add app="macfeh" manage=off border=off 117 | yabai -m rule --add app='^Google Chrome$' title='^Picture in Picture$' manage=off topmost=on sticky=on # Make Chrome Picture in Picture mode windows appear topmost and on all spaces 118 | yabai -m rule --add label="Safari" app="^Safari$" title="^(General|(Tab|Password|Website|Extension)s|AutoFill|Se(arch|curity)|Privacy|Advance)$" manage=off 119 | yabai -m rule --add app="kitty" title="dropdown" manage=off grid=8:8:1:1:6:6 border=on shadow=on sticky=on topmost=on 120 | # yabai -m signal --add event=application_launched app=kitty title=dropdown action='yabai -m windows "${YABAI_WINDOW_ID}" --toggle shadow' 121 | # }}} 122 | # Signals ================================================================= {{{ 123 | yabai -m signal --add event=space_changed action="yabai -m window --focus largest" # Focus window on space when app / window is closed 124 | yabai -m signal --add event=window_destroyed action="yabai -m query --windows --window &> /dev/null || yabai -m window --focus mouse" 125 | yabai -m signal --add event=application_terminated action="yabai -m query --windows --window &> /dev/null || yabai -m window --focus mouse" 126 | 127 | # Signals to power ubersicht bar {{{ 128 | yabai -m signal --add event=space_changed action="uber-bar-refresh" 129 | yabai -m signal --add event=window_created action="uber-bar-refresh" 130 | yabai -m signal --add event=window_destroyed action="uber-bar-refresh" 131 | yabai -m signal --add event=window_moved action="uber-bar-refresh" 132 | yabai -m signal --add event=window_resized action="uber-bar-refresh" 133 | yabai -m signal --add event=bar_refresh action="uber-bar-refresh" 134 | # }}} 135 | 136 | # }}} 137 | echo "yabai configuration loaded." 138 | -------------------------------------------------------------------------------- /resources/skhdrc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # shellcheck disable 3 | 4 | # TODO: find another way to share color vars between skhdrc and yabairc. THIS IS PROBABLY SLOW! 5 | :: default : yabai -m config active_window_border_color $(cat "/Users/adamwagner/Programming/dotfiles/window-managers/yabai/yabairc_vars" | grep NORMAL_BORDER_COLOR | cut -d "=" -f 2) 6 | :: focus @ : yabai -m config active_window_border_color $(cat "/Users/adamwagner/Programming/dotfiles/window-managers/yabai/yabairc_vars" | grep ACTIVE_BORDER_COLOR | cut -d "=" -f 2) 7 | :: move @ : yabai -m config active_window_border_color $(cat "/Users/adamwagner/Programming/dotfiles/window-managers/yabai/yabairc_vars" | grep MOVE_BORDER_COLOR | cut -d "=" -f 2) 8 | :: resize @ : yabai -m config active_window_border_color $(cat "/Users/adamwagner/Programming/dotfiles/window-managers/yabai/yabairc_vars" | grep RESIZE_BORDER_COLOR | cut -d "=" -f 2) 9 | :: passthrough 10 | 11 | 12 | # restart yabai 13 | shift + alt - r : "/Users/adamwagner/Programming/dotfiles/scripts/yabai/yabai-restart" 14 | 15 | # Float the next window and forward the keypress 16 | # cmd - 0x2B -> : \ 17 | # yabai -m signal --add label=float_next_window_created event=window_created action='yabai -m signal --remove float_next_window_created; yabai -m signal --remove float_next_application_launched; yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er ".floating == 0" && yabai -m window $YABAI_WINDOW_ID --toggle float' && \ 18 | # yabai -m signal --add label=float_next_application_launched event=application_launched action='yabai -m signal --remove float_next_window_created; yabai -m signal --remove float_next_application_launched; yabai -m query --windows | jq -r ".[] | select(.pid == $YABAI_PROCESS_ID && .floating == 0).id" | xargs -I{} yabai -m window {} --toggle float' 19 | 20 | # Snap floating windows {fullscreen, left, right} 21 | # Conflicts with default macos text selection! 22 | ctrl + alt - up : yabai -m window --grid 1:1:0:0:1:1 23 | ctrl + alt - left : yabai -m window --grid 1:2:0:0:1:1 24 | ctrl + alt - right : yabai -m window --grid 1:2:1:0:1:1 25 | 26 | # Focus windows with alt + vim keys without activating a mode 27 | # alt - j : win-focus south 28 | # alt - k : win-focus north 29 | # alt - l : win-focus east 30 | # alt - h : win-focus west 31 | 32 | # # old way 33 | alt - j : yabai -m window --focus south 34 | alt - k : yabai -m window --focus north 35 | alt - l : yabai -m window --focus east 36 | alt - h : yabai -m window --focus west 37 | 38 | # Making window parent is a common action, 39 | # so make available without mode 40 | alt - p : yabai -m window --toggle zoom-parent 41 | 42 | # --grid maximizes floating windows 43 | # alt - m : yabai -m window --grid 100:1:10:0:1:100 || yabai -m window --toggle zoom-fullscreen && uber-bar-refresh; 44 | alt - m : yabai -m window --toggle zoom-fullscreen && uber-bar-refresh; 45 | 46 | # Toggle yabai menu bar 47 | # (requires /bin/sh, not /usr/local/bin/dash) 48 | alt - b : yabai -m config status_bar $([ $(yabai -m config status_bar) == 'on' ] && echo off || echo on) 49 | 50 | # float / unfloat window and center on screen 51 | alt - t : yabai -m window --toggle float;\ 52 | yabai -m window --grid 8:8:1:1:6:6 53 | 54 | 55 | # Various attempts at picture-in-picture {{{ 56 | 57 | # TODO: Change to script to toggle between: 58 | # 2. picture-in-picture 59 | # 1. floating centered (qlt-t) 60 | # Currently, toggling out of pip will tile. If the win is then centered 61 | # (alt-t), it messes up the toggling states for the next alt-i. 62 | 63 | # toggle sticky, topmost and resize to picture-in-picture size 64 | # alt - i : yabai -m window --toggle sticky;\ 65 | # yabai -m window --toggle topmost;\ 66 | # yabai -m window --grid 5:5:4:0:1:1 67 | # }}} 68 | # https://github.com/koekeishiya/yabai/issues/286 69 | alt - i : yabai -m window --toggle sticky;\ 70 | yabai -m window --toggle topmost;\ 71 | yabai -m window --toggle border;\ 72 | yabai -m window --toggle pip 73 | 74 | # Basic 'switch desktop' 75 | cmd + ctrl - k : yabai -m space --focus next 76 | cmd + ctrl - j : yabai -m space --focus prev 77 | cmd + ctrl - h : yabai -m space --focus recent 78 | 79 | # expose with desktop preview 80 | cmd + ctrl - u : /Applications/missionControlFullDesktopBar.app/Contents/MacOS/missionControlFullDesktopBar -d -i 81 | 82 | # jump to space 83 | cmd + ctrl - 1 : yabai -m space --focus 1 84 | cmd + ctrl - 2 : yabai -m space --focus 2 85 | cmd + ctrl - 3 : yabai -m space --focus 3 86 | cmd + ctrl - 4 : yabai -m space --focus 4 87 | cmd + ctrl - 5 : yabai -m space --focus 5 88 | cmd + ctrl - 6 : yabai -m space --focus 6 89 | cmd + ctrl - 7 : yabai -m space --focus 7 90 | cmd + ctrl - 8 : yabai -m space --focus 8 91 | cmd + ctrl - 9 : yabai -m space --focus 9 92 | 93 | 94 | # Create desktop, move focused window, and follow 95 | cmd + ctrl - n : yabai -m space --create;\ 96 | id=$(yabai -m query --spaces | /usr/local/bin/jq '. | length');\ 97 | yabai -m window --space "$id";\ 98 | yabai -m space --focus "$id";\ 99 | 100 | 101 | # Create desktop and follow focus 102 | cmd + alt - n : yabai -m space --create;\ 103 | id=$(yabai -m query --spaces | jq '. | length');\ 104 | yabai -m space --focus "$id";\ 105 | 106 | 107 | # destroy desktop 108 | cmd + alt - w : space-destroy 109 | 110 | # FR: pass selector to space --destroy 111 | # yabai -m space --destroy 112 | 113 | # FR: pass selector to space --create to insert at index 114 | # yabai -m space --create 115 | 116 | 117 | # Move focused window `outta here!` 118 | move < u : $DOTFILES/scripts/yabai/win-auto-throw 119 | 120 | # move focussed window into dedicated space to right of current space 121 | move < g : win-throw-new-space "next" 122 | 123 | 124 | 125 | 126 | 127 | # modes 128 | # ┌┬┐┌─┐┌┬┐┌─┐┌─┐ 129 | # ││││ │ ││├┤ └─┐ 130 | # ┴ ┴└─┘─┴┘└─┘└─┘ 131 | # CTRL-SPACE is the global hotkey to toggle in/out of modal mode. Entry is 132 | # always to FOCUS mode. Getting out of any mode can also be done with ESCAPE. 133 | default < ctrl - space ; focus 134 | 135 | focus, move, resize < ctrl - space ; default 136 | focus, move, resize < escape ; default 137 | 138 | default < cmd + ctrl + shift - p ; passthrough 139 | passthrough < escape ; default 140 | 141 | 142 | # Once in FOCUS mode (or any other mode other than default), you can switch 143 | # modes with single keystroke. (mnemonic: letter corresponds to first letter of 144 | # mode name, with exception of warpnf, which is a variant invoked with shift) 145 | focus, move, resize < f ; focus 146 | focus, move, resize < w ; move 147 | focus, move, resize < r ; resize 148 | 149 | 150 | # In any chunkwm mode, switch desktop commands from above ↑ bring window along 151 | focus, move, resize < cmd + ctrl - k : yabai -m window --space next; yabai -m space --focus next 152 | focus, move, resize < cmd + ctrl - j : yabai -m window --space prev; yabai -m space --focus prev 153 | focus, move, resize < cmd + ctrl - h : yabai -m window --space prev; yabai -m space --focus recent 154 | 155 | # Move floating windows left / right (replace divvy) 156 | # FIX: conflict with toggling developer tools in chrome 157 | # cmd + alt - i : yabai -m window --grid 1:1:0:0:1:1 158 | # cmd + alt - j : yabai -m window --grid 1:2:0:0:1:1 159 | # cmd + alt - k : yabai -m window --grid 1:2:1:0:1:1 160 | # cmd + alt - l : yabai -m window --grid 1:5:5:0:1:1 161 | 162 | # The following keybindings are available in all modes. 163 | focus, move, resize < e : yabai -m space --balance 164 | focus, move, resize < x : yabai -m space --mirror x-axis 165 | focus, move, resize < y : yabai -m space --mirror y-axis 166 | focus, move, resize < space : yabai -m space --rotate 90 167 | 168 | focus, move, resize < m : yabai -m window --toggle zoom-fullscreen # mnemonic: monacle 169 | focus, move, resize < p : yabai -m window --toggle zoom-parent # mnemonic: _p_arent 170 | 171 | focus, move, resize < i : yabai -m window --toggle split # mnemonic: couldn't think of one! 172 | focus, move, resize < t : yabai -m window --toggle float # mnemonic: floa_t_ 173 | focus, move, resize < s : yabai -m window --toggle sticky # mnemonic: floa_t_ 174 | focus, move, resize < ctrl - e : yabai -m window --toggle fade 175 | 176 | 177 | # toggle desktop offset 178 | focus, move, resize < o : yabai -m space --toggle gap; yabai -m space --toggle padding 179 | 180 | # When in mode, use same keys to shift focus 181 | focus, move, resize < alt - k : yabai -m window --focus north 182 | focus, move, resize < alt - j : yabai -m window --focus south 183 | focus, move, resize < alt - l : yabai -m window --focus east 184 | focus, move, resize < alt - h : yabai -m window --focus west 185 | 186 | # No modifier moves 187 | focus < j : yabai -m window --focus south 188 | focus < k : yabai -m window --focus north 189 | focus < l : yabai -m window --focus east 190 | focus < h : yabai -m window --focus west 191 | 192 | 193 | # Change the layout mode of a desktop to one of the three supported modes. 194 | focus < cmd - b : yabai -m space --layout bsp 195 | focus < cmd - f : yabai -m space --layout float 196 | 197 | 198 | # Warp windows with direction keys in move mode 199 | move < k : yabai -m window --warp north 200 | move < j : yabai -m window --warp south 201 | move < l : yabai -m window --warp east 202 | move < h : yabai -m window --warp west 203 | 204 | cmd + shift - k : if-float 'cmd + shift - k' win-move-float 'k' 205 | cmd + shift - j : if-float 'cmd + shift - j' win-move-float 'j' 206 | cmd + shift - l : if-float 'cmd + shift - l' win-move-float 'l' 207 | cmd + shift - h : if-float 'cmd + shift - h' win-move-float 'h' 208 | 209 | # Swap windows by adding ctrl to vim keys 210 | move < ctrl - k : yabai -m window --swap north 211 | move < ctrl - j : yabai -m window --swap south 212 | move < ctrl - l : yabai -m window --swap east 213 | move < ctrl - h : yabai -m window --swap west 214 | 215 | 216 | # move active space left or right 217 | move < cmd - l : yabai -m space --move next; #skhd -k "o"; skhd -k "o"; skhd -k "escape"; 218 | move < cmd - h : yabai -m space --move prev; #skhd -k "o"; skhd -k "o"; skhd -k "escape"; 219 | 220 | # TODO: factor out space iteration 221 | # TODO: factor out follow / nofollow patterns 222 | 223 | 224 | # Update status color to force status bar to refresh 225 | fn + cmd + ctrl - h : yabai -m space --move prev && yabai -m config status_bar_foreground_color 0xff5e81ac 226 | fn + cmd + ctrl - l : yabai -m space --move next && yabai -m config status_bar_foreground_color 0xff5e81ac 227 | fn + cmd + ctrl - k : yabai -m space --display next && yabai -m config status_bar_foreground_color 0xff5e81ac 228 | fn + cmd + ctrl - j : yabai -m space --display prev && yabai -m config status_bar_foreground_color 0xff5e81ac 229 | 230 | 231 | 232 | # move window to space and follow. 233 | move < 1 : yabai -m window --space 1; yabai -m space --focus 1 234 | move < 2 : yabai -m window --space 2; yabai -m space --focus 2 235 | move < 3 : yabai -m window --space 3; yabai -m space --focus 3 236 | move < 4 : yabai -m window --space 4; yabai -m space --focus 4 237 | move < 5 : yabai -m window --space 5; yabai -m space --focus 5 238 | move < 6 : yabai -m window --space 6; yabai -m space --focus 6 239 | move < 7 : yabai -m window --space 7; yabai -m space --focus 7 240 | move < 8 : yabai -m window --space 8; yabai -m space --focus 8 241 | move < 9 : yabai -m window --space 9; yabai -m space --focus 9 242 | 243 | # move window to space *without* follow. 244 | move < ctrl - 1 : yabai -m window --space 1; skhd -k "escape"; 245 | move < ctrl - 2 : yabai -m window --space 2; skhd -k "escape"; 246 | move < ctrl - 3 : yabai -m window --space 3; skhd -k "escape"; 247 | move < ctrl - 4 : yabai -m window --space 4; skhd -k "escape"; 248 | move < ctrl - 5 : yabai -m window --space 5; skhd -k "escape"; 249 | move < ctrl - 6 : yabai -m window --space 6; skhd -k "escape"; 250 | move < ctrl - 7 : yabai -m window --space 7; skhd -k "escape"; 251 | move < ctrl - 8 : yabai -m window --space 8; skhd -k "escape"; 252 | move < ctrl - 9 : yabai -m window --space 9; skhd -k "escape"; 253 | 254 | 255 | 256 | 257 | 258 | 259 | # Resize in both directions without a modifier 260 | # Only one of the two chained commands gets executed in each of the four scenarios. 261 | # The setup can be described as moving the region separators in the specified direction instead of making the regions explicitly larger/smaller. 262 | # i3 style resize from here: https://github.com/koekeishiya/yabai/issues/21 263 | 264 | # resize < h : yabai -m window --resize left:-50:0 ; yabai -m window --resize right:-50:0 265 | # resize < j : yabai -m window --resize bottom:0:50 ; yabai -m window --resize top:0:50 266 | # resize < k : yabai -m window --resize top:0:-50 ; yabai -m window --resize bottom:0:-50 267 | # resize < l : yabai -m window --resize right:50:0 ; yabai -m window --resize left:50:0 268 | 269 | # resize < shift - h : yabai -m window --resize left:-300:0 ; yabai -m window --resize right:-300:0; 270 | # resize < shift - j : yabai -m window --resize bottom:0:300 ; yabai -m window --resize top:0:300 271 | # resize < shift - k : yabai -m window --resize top:0:-300 ; yabai -m window --resize bottom:0:-300 272 | # resize < shift - l : yabai -m window --resize right:300:0 ; yabai -m window --resize left:300:0 273 | 274 | 275 | 276 | # Updated resize logic from https://github.com/koekeishiya/yabai/issues/200 ---- 277 | # Downside is that it can only "grow" a window between two windows 278 | 279 | resize < h : yabai -m window west --resize right:-50:0 2> /dev/null || yabai -m window --resize right:-50:0 280 | resize < j : yabai -m window north --resize bottom:0:50 2> /dev/null || yabai -m window --resize bottom:0:50 281 | resize < k : yabai -m window south --resize top:0:-50 2> /dev/null || yabai -m window --resize top:0:-50 282 | resize < l : yabai -m window east --resize left:50:0 2> /dev/null || yabai -m window --resize left:50:0 283 | 284 | 285 | resize < shift - h : yabai -m window west --resize right:-300:0 2> /dev/null || yabai -m window --resize right:-300:0 286 | resize < shift - j : yabai -m window north --resize bottom:0:300 2> /dev/null || yabai -m window --resize bottom:0:300 287 | resize < shift - k : yabai -m window south --resize top:0:-300 2> /dev/null || yabai -m window --resize top:0:-300 288 | resize < shift - l : yabai -m window east --resize left:300:0 2> /dev/null || yabai -m window --resize left:300:0 289 | 290 | 291 | 292 | # inbox 293 | alt - g :osascript -e 'tell application id "com.runningwithcrayons.Alfred" to run trigger "googler" in workflow ".io.adamwagner.alfred.safari" with argument ""' 294 | 295 | # Adjust Gaps and Paddning: Minus/Plus key 296 | focus, resize, move < 0x18 : yabai -m space --padding rel:25:25:25:25; yabai -m space --gap rel:30 297 | focus, resize, move < 0x1B : yabai -m space --padding rel:-25:-25:-25:-25; yabai -m space --gap rel:-30 298 | # focus, resize, move < alt - 0x18 : yabai -m space --gap rel:30 299 | # focus, resize, move < alt - 0x1B : yabai -m space --gap rel:-30 300 | # focus, resize, move < shift - 0x18 : yabai -m space --padding rel:25:25:25:25 301 | # focus, resize, move < shift - 0x1B : yabai -m space --padding rel:-25:-25:-25:-25 302 | focus, resize, move < 0 : yabai -m space --toggle padding; yabai -m space --toggle gap 303 | 304 | 305 | 306 | # https://github.com/jonohrt/dotfiles/blob/master/.skhdrc ----------------------{{{ 307 | 308 | # # Set all windows on active space to zoom-fullscreen 309 | # shift + cmd - f: yabai -m query --windows --space \ 310 | # | jq -re '.[] | select(."zoom-fullscreen" == 0) | .id' \ 311 | # | xargs -I{} yabai -m window {} --toggle zoom-fullscreen 312 | 313 | # # Set all windows on active space back to normal 314 | # shift + cmd - e : yabai -m query --windows --space \ 315 | # | jq -re '.[] | select(."zoom-fullscreen" == 1) | .id' \ 316 | # | xargs -I{} yabai -m window {} --toggle zoom-fullscreen 317 | 318 | #}}} 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | --------------------------------------------------------------------------------