How to highlight current screen (or window)?
Highlight the focussed screen (or dim- flash on focus change, see EDIT further below)
In a side-by-side dual monitor setup (left-right), the script below will set the brightness of the monitor with the focussed window to "normal" (100%), while other one is dimmed to 60%.
If the focus changes, the brightness will follow the focus:
focus on (a window) on the right screen
focus on (a window) on the left screen
The script
#!/usr/bin/env python3
"""
In a side-by-side dual monitor setup (left-right), the script below will set
the brightness of the monitor with the focussed window to "normal" (100%),
while other one is dimmed to 60%. If the focus changes, the brightness will
follow the focus
"""
import subprocess
import time
def get_wposition():
# get the position of the currently frontmost window
try:
w_data = subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8").splitlines()
frontmost = subprocess.check_output(["xprop", "-root", "_NET_ACTIVE_WINDOW"]).decode("utf-8").split()[-1].strip()
z = 10-len(frontmost); frontmost = frontmost[:2]+z*"0"+frontmost[2:]
return [int(l.split()[2]) for l in w_data if frontmost in l][0]
except subprocess.CalledProcessError:
pass
def get_onscreen():
# get the size of the desktop, the names of both screens and the x-resolution of the left screen
resdata = subprocess.check_output(["xrandr"]).decode("utf-8")
if resdata.count(" connected") == 2:
resdata = resdata.splitlines()
r = resdata[0].split(); span = int(r[r.index("current")+1])
screens = [l for l in resdata if " connected" in l]
lr = [[(l.split()[0], int([s.split("x")[0] for s in l.split() if "+0+0" in s][0])) for l in screens if "+0+0" in l][0],
[l.split()[0] for l in screens if not "+0+0" in l][0]]
return [span, lr]
else:
print("no second screen seems to be connected")
def scr_position(span, limit, pos):
# determine if the frontmost window is on the left- or right screen
if limit < pos < span:
return [right_scr, left_scr]
else:
return [left_scr, right_scr]
def highlight(scr1, scr2):
# highlight the "active" window, dim the other one
action1 = "xrandr", "--output", scr1, "--brightness", "1.0"
action2 = "xrandr", "--output", scr2, "--brightness", "0.6"
for action in [action1, action2]:
subprocess.Popen(action)
# determine the screen setup
screendata = get_onscreen()
left_scr = screendata[1][0][0]; right_scr = screendata[1][1]
limit = screendata[1][0][1]; span = screendata[0]
# set initial highlight
oncurrent1 = scr_position(span, limit, get_wposition())
highlight(oncurrent1[0], oncurrent1[1])
while True:
time.sleep(0.5)
pos = get_wposition()
# bypass possible incidental failures of the wmctrl command
if pos != None:
oncurrent2 = scr_position(span, limit, pos)
# only set highlight if there is a change in active window
if oncurrent2 != oncurrent1:
highlight(oncurrent1[1], oncurrent1[0])
oncurrent1 = oncurrent2
How to use
-
The script needs
wmctrl
:sudo apt-get install wmctrl
Copy the script into an empty file, save it as
highlight_focus.py
-
Test- run it by the command:
python3 /path/to/highlight_focus.py
With the second monitor connected, test if the script works as expected.
-
If all works fine, add it to startup applications: Dash > Startup Applications > Add the command:
/bin/bash -c "sleep 15 && python3 /path/to/highlight_focus.py"
Notes
The script is extremely low on resources. To "save fuel", the screen setup; resolutions, span size etc. is read only once, during startup of the script (not included in the loop). That implies that you have to restart the script if you connect/disconnect the second monitor.
If you added it to startup applications, it means you have to log out/in after changes in monitor configuration.
-
If you'd prefer another brightness percentage for the dimmed screen, change the value in the line:
action2 = "xrandr", "--output", scr2, "--brightness", "0.6"
The value can be between 0,0
(black screen) and 1.0
(100%).
Explanation
On startup of the script, it determines:
- the spanning resolution of both screens
- the x-resolution of the left screen
- the names of both screens
Then, in a loop (once per second), it:
-
checks the position of the active window with the commands:
-
wmctrl -lG
(to get the list of windows and their positions) -
xprop -root _NET_ACTIVE_WINDOW
(to get the id of the frontmost window)
-
If the window's (x-) position is greater then the x-resolution of the left screen, the window apparently is on the right screen, unless it is greater then the spanning size of the two screens (then it would be on the workspace on the right). therefore:
if limit < pos < span:
determines if the window is on the right screen (where limit
is x-res of the left screen, pos
is the window's x-position and span
is the combined x-res of both screens).
If there is a change in the position of the frontmost window (on left screen or right screen), the script sets the brightness of both screens with the xrandr
command:
xrandr --output <screen_name> --brightness <value>
EDIT
Dim-flash the focussed screen instead of a permanent dimmed "unfocussed" screen
As requested in a comment and in chat, below a version of the script that gives a short dim flash on the newly focussed screen instead:
#!/usr/bin/env python3
"""
In a side-by-side dual monitor setup (left-right), the script below will give
a short dim- flash on the newly focussed screen if the focussed screen changes
"""
import subprocess
import time
def get_wposition():
# get the position of the currently frontmost window
try:
w_data = subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8").splitlines()
frontmost = subprocess.check_output(["xprop", "-root", "_NET_ACTIVE_WINDOW"]).decode("utf-8").split()[-1].strip()
z = 10-len(frontmost); frontmost = frontmost[:2]+z*"0"+frontmost[2:]
return [int(l.split()[2]) for l in w_data if frontmost in l][0]
except subprocess.CalledProcessError:
pass
def get_onscreen():
# get the size of the desktop, the names of both screens and the x-resolution of the left screen
resdata = subprocess.check_output(["xrandr"]).decode("utf-8")
if resdata.count(" connected") == 2:
resdata = resdata.splitlines()
r = resdata[0].split(); span = int(r[r.index("current")+1])
screens = [l for l in resdata if " connected" in l]
lr = [[(l.split()[0], int([s.split("x")[0] for s in l.split() if "+0+0" in s][0])) for l in screens if "+0+0" in l][0],
[l.split()[0] for l in screens if not "+0+0" in l][0]]
return [span, lr]
else:
print("no second screen seems to be connected")
def scr_position(span, limit, pos):
# determine if the frontmost window is on the left- or right screen
if limit < pos < span:
return [right_scr, left_scr]
else:
return [left_scr, right_scr]
def highlight(scr1):
# highlight the "active" window, dim the other one
subprocess.Popen([ "xrandr", "--output", scr1, "--brightness", "0.3"])
time.sleep(0.1)
subprocess.Popen([ "xrandr", "--output", scr1, "--brightness", "1.0"])
# determine the screen setup
screendata = get_onscreen()
left_scr = screendata[1][0][0]; right_scr = screendata[1][1]
limit = screendata[1][0][1]; span = screendata[0]
# set initial highlight
oncurrent1 = []
while True:
time.sleep(0.5)
pos = get_wposition()
# bypass possible incidental failures of the wmctrl command
if pos != None:
oncurrent2 = scr_position(span, limit, pos)
# only set highlight if there is a change in active window
if oncurrent2 != oncurrent1:
highlight(oncurrent2[0])
oncurrent1 = oncurrent2
I've also found another solution, that is bit different from what I wanted in the first place, but works fine too.
- Install
compizconfig-settings-manager compiz-plugins
- Run ccsm
- In
Effects
section enableAnimations
plugin - In
Focus Animation
edit and select desired animation.
Only wave effect worked... So if you don't like it, you will have face as sad as mine.