Skip to content

Instantly share code, notes, and snippets.

@peteruithoven
Last active March 2, 2023 06:31
Show Gist options
  • Save peteruithoven/db0cba0b0849c8cb5e267f6e75126304 to your computer and use it in GitHub Desktop.
Save peteruithoven/db0cba0b0849c8cb5e267f6e75126304 to your computer and use it in GitHub Desktop.
Crude quarter tiling tool for elementary OS
#!/bin/bash
# Crude quarter tiling tool
# Installation:
# Move file to: /usr/local/bin/quarter-tiler
# Make executable: sudo chmod +x /usr/local/bin/quarter-tiler
# Assign keyboard shortcuts to commands like "quarter-tiler topleft"
# Margins around windows (elementary OS native apps) (HiDPI)
MARGIN_TOP=130
MARGIN_RIGHT=158
MARGIN_BOTTOM=185
MARGIN_LEFT=158
# Desktops info
INFO=$(wmctrl -d | head -1)
# Desktop size
[[ $INFO =~ 'DG: '([0-9]+)'x'([0-9]+) ]]
WIDTH=${BASH_REMATCH[1]}
HEIGHT=${BASH_REMATCH[2]}
# Available width height, and offsets see: $ wmctrl -d
[[ $INFO =~ 'WA: '([0-9]+)','([0-9]+)' '([0-9]+)'x'([0-9]+) ]]
OFFSET_X=${BASH_REMATCH[1]}
OFFSET_Y=${BASH_REMATCH[2]}
AV_WIDTH=${BASH_REMATCH[3]}
AV_HEIGHT=${BASH_REMATCH[4]}
X_LEFT=$((0-($MARGIN_RIGHT+$OFFSET_X)))
X_CENTER=$(($AV_WIDTH/2+$MARGIN_RIGHT+$MARGIN_LEFT))
HALF_WIDTH=$X_CENTER
Y_TOP=$((0-($MARGIN_TOP-$OFFSET_Y)))
Y_CENTER=$(($Y_TOP+$HEIGHT/2))
HALF_HEIGHT=$(($AV_HEIGHT/2+$MARGIN_TOP+$MARGIN_BOTTOM))
SIZE=$HALF_WIDTH,$HALF_HEIGHT
case "$1" in
topleft)
CMD="wmctrl -r :ACTIVE: -e 0,$X_LEFT,$Y_TOP,$SIZE"
;;
topright)
CMD="wmctrl -r :ACTIVE: -e 0,$X_CENTER,$Y_TOP,$SIZE"
;;
bottomleft)
CMD="wmctrl -r :ACTIVE: -e 0,$X_LEFT,$Y_CENTER,$SIZE"
;;
bottomright)
CMD="wmctrl -r :ACTIVE: -e 0,$X_CENTER,$Y_CENTER,$SIZE"
;;
esac
# In case window is tiled, disable tile
wmctrl -r :ACTIVE: -b remove,maximized_vert
# Wait for transition
sleep 0.1s
eval $($CMD)
@jchannon
Copy link

jchannon commented Nov 8, 2018

If you change monitors/resolutions this will fail slightly.

Have amended the script to get the resolutions of the monitors below

RESOLUTIONS=$(wmctrl -d | head -1 | awk '{x=$4"x"$9; print x}')
j1=$(echo $RESOLUTIONS | cut -d'x' -f1)
j2=$(echo $RESOLUTIONS | cut -d'x' -f2)
j3=$(echo $RESOLUTIONS | cut -d'x' -f3)
j4=$(echo $RESOLUTIONS | cut -d'x' -f4)

AV_WIDTH=$j3
AV_HEIGHT=$j4
# Desktop size
WIDTH=$j1
HEIGHT=$j2

@peteruithoven
Copy link
Author

Awesome!
I also discovered that WA lists an X and Y offset, to account for the Wingpanel for example.
I've now used a new trick I discovered with BASH_REMATCH.

@peteruithoven
Copy link
Author

Another small issue was that it wouldn't affect left/right tiles windows. I've found that I could remove the tile using:

wmctrl -r :ACTIVE: -b remove,maximized_vert

@peteruithoven
Copy link
Author

If only we could automatically adjust those window margins...
wmctrl -lx gives us the list of windows, with app name:

0x01e00003 -1 plank.Plank           xps plank
0x03600045  0 Navigator.Firefox     xps Crude quarter tiling tool for elementary OS - Mozilla Firefox
0x036000ae  0 Navigator.Firefox     xps (922) Watch Later Playlist - YouTube - Mozilla Firefox
0x04400001  0 atom.Atom             xps bash.txt — ~/Nextcloud/Notes — Atom
0x0580001a  0 io.elementary.photos.Io.elementary.photos  xps login-unlock-storyboard.png (/tmp/mozilla_peteruithoven0) - Photos
0x06000006  0 gitkraken.GitKraken   xps GitKraken
0x048141f0  0 io.elementary.terminal.Io.elementary.terminal  xps wingpanel
0x01c00003  0 wingpanel.Wingpanel   xps wingpanel
0x0500006a  0 freecad.Freecad       xps FreeCAD
0x04e0002c  0 cura.cura             N/A Ultimaker Cura
0x05400007  0 gnome-mpv.Gnome-mpv   xps GNOME MPV
0x06a00001  0 spotify.Spotify       xps Spotify
0x03214c8f  0 io.elementary.appcenter.Io.elementary.appcenter  xps io.elementary.appcenter
0x0700002a  0 com.github.davidmhewitt.torrential.Com.github.davidmhewitt.torrential  xps com.github.davidmhewitt.torrential
0x0481b43c  0 io.elementary.terminal.Io.elementary.terminal  xps wmctrl -lx
0x04856255  0 io.elementary.terminal.Io.elementary.terminal  xps bin: nano

Seeing that all native elementary apps these days use io.elementary or com.github prefixes this could be used to determine the appropriate margin with some certainty... Except that apps like Firefox and Gnome-mpv also have the native margins.
And I don't know how to retrieve the current window name.

@peteruithoven
Copy link
Author

@jchannon

pretty sure i found something last night to get current window name but of course cant find it now
https://superuser.com/a/615946/61031

@rijesha
Copy link

rijesha commented Nov 15, 2019

I did something like this to change the margins depending on the process.

APPNAME=$(wmctrl -lx | grep $(xprop -root | grep _NET_ACTIVE_WINDOW | head -1 | \
    awk '{print $5}' | sed 's/,//' | sed 's/^0x/0x0/') | cut -d " " -f 4)

echo $APPNAME

MARGIN_TOP=0
MARGIN_RIGHT=0
MARGIN_BOTTOM=0
MARGIN_LEFT=0

if [[ $APPNAME == io.elementary* ]] || [[ $APPNAME == gedit* ]] ;
then
    echo $APPNAME
    # Margins around windows (elementary OS native apps) (HiDPI)
    MARGIN_TOP=130
    MARGIN_RIGHT=158
    MARGIN_BOTTOM=185
    MARGIN_LEFT=158
fi

@fix777
Copy link

fix777 commented Mar 2, 2023

# In case window is tiled, disable tile
wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz

Add remove maximized_horz would be better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment