Last active
August 30, 2024 14:43
-
-
Save alphapapa/86a64b748012915961a83cd7e400a4af to your computer and use it in GitHub Desktop.
Raise an Emacs window or run Emacs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ** Vars | |
# *** Emacs version | |
emacs="emacs" | |
emacsclient="emacsclient" | |
emacsWindowClass="Emacs" | |
# ** Functions | |
function findEmacsWindows { | |
# Searching by window class or classname is not enough, because it | |
# also finds Emacs' invisible windows. But the invisible windows | |
# do not have WM_HINTS (although they do have | |
# WM_NORMAL_HINTS...sigh). So to find the regular Emacs windows, | |
# find the ones that have WM_HINTS. ... But sometimes Emacs | |
# opens more than one invisible window (?!). And one of those | |
# windows may have WM_HINTS! But it seems that only the real, | |
# usable window has "_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL". | |
# So grep for that to find the One True Window. | |
# | |
# ...the next day... | |
# | |
# Unbelievable. 24 hours later and I haven't changed anything but | |
# it is picking up one of the TWO invisible windows since now one | |
# of those invisible windows now has "_NET_WM_WINDOW_TYPE(ATOM) = | |
# _NET_WM_WINDOW_TYPE_NORMAL" even though it didn't before. So | |
# now I have to try something like the FOURTH different method of | |
# determining which Emacs window is the ACTUAL WINDOW... | |
# | |
# Ok, let's try looking for "window state:" which SHOULD only be | |
# listed for an actual, usable window... | |
for windowID in $(xdotool search --class $emacsWindowClass) | |
do | |
if [[ $(xprop -id $windowID WM_STATE) =~ "window state:" ]] | |
then | |
# Test against excludes | |
if ! [[ $(xprop -id $windowID WM_ICON_NAME) =~ "Matrix" ]] | |
then | |
# No excludes match: return window ID | |
echo $windowID | |
fi | |
fi | |
done | |
} | |
function ifset { | |
# Call like: if ifset command varname | |
# then | |
# for i in $varname | |
declare -n ref=$2 | |
ref=$($1) | |
[[ $ref ]] && return 0 || return 1 | |
} | |
# ** Main | |
# *** Check for xdotool | |
if ! type xdotool &>/dev/null # type works and is a bash builtin | |
then | |
message="Install xdotool." | |
echo "$message" | |
notify-send "$message" | |
exit 1 | |
fi | |
# *** Get current window | |
currentWindow=$(xdotool getwindowfocus) | |
# Get current window class (not classname) | |
currentWindowClass=$(xprop -id $currentWindow WM_CLASS | awk '{ print $4 }' | tr -d '"') | |
# *** Minimize, raise, or run Emacs | |
if [[ $currentWindowClass = $emacsWindowClass ]] | |
then | |
# Emacs is the active window. Minimize it. | |
$emacsclient -e "(switch-to-buffer \"*scratch*\")" | |
xdotool windowminimize $currentWindow &>/dev/null | |
else | |
# Emacs is not the active window. Try to raise an Emacs window. | |
if ifset findEmacsWindows emacsWindows | |
then | |
# Emacs windows found | |
for window in $emacsWindows | |
do | |
# Restore/unminimize, raise to top, and activate/focus | |
xdotool windowmap --sync $window windowraise $window windowactivate $window &>/dev/null | |
done | |
else | |
# No Emacs windows found. Run Emacs. | |
if pgrep -f "emacs --daemon" | |
then | |
$emacsclient -c -n | |
else | |
$emacs # NOTE: [2017-12-06 Wed 09:03] Launching the daemon directly causes theme issues, so don't for now: --daemon | |
#$emacsclient -c -n | |
fi | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment