我在工作中使用双屏设置,虽然它通常利大于弊,但我还是遇到了一些问题。
其中之一是焦点尾随问题 - 有时我会错误地在错误的屏幕上打字(焦点尾随我的光标,但当你匆忙做事时并不总是容易注意到光标在另一个屏幕上)。当我不打字而执行大量不同的操作(Thunderbird 中的一键快捷方式)时,这非常烦人。
有没有办法更好地突出显示活动屏幕或窗口(例如,使用容易看到的边框 - 即使对于最大化的窗口)?
编辑:
我认为好的解决方案是在窗口获得焦点时出现某种简短的动画。
答案1
突出显示聚焦的屏幕(或焦点改变时变暗闪烁,请参阅下面的编辑)
在并排双显示器设置(左右)中,下面的脚本将焦点窗口的显示器的亮度设置为“正常”(100%),而另一个显示器的亮度则调暗至 60%。
如果焦点改变,亮度也会跟随焦点:
剧本
#!/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
如何使用
该脚本需要
wmctrl
:sudo apt-get install wmctrl
将脚本复制到一个空文件中,另存为
highlight_focus.py
通过命令测试运行:
python3 /path/to/highlight_focus.py
连接第二台显示器,测试脚本是否按预期工作。
如果一切正常,将其添加到启动应用程序:Dash>启动应用程序>添加命令:
/bin/bash -c "sleep 15 && python3 /path/to/highlight_focus.py"
笔记
该脚本占用的资源极少。为了“节省燃料”,屏幕设置;分辨率、跨度大小等仅在脚本启动时读取一次(不包含在循环中)。这意味着如果您连接/断开第二台显示器,则必须重新启动脚本。
如果将其添加到启动应用程序,则意味着您必须在监视器配置更改后注销/登录。
如果您希望暗淡的屏幕使用其他亮度百分比,请更改以下行中的值:
action2 = "xrandr", "--output", scr2, "--brightness", "0.6"
该值可以介于0,0
(黑屏) 和1.0
(100%) 之间。
解释
在脚本启动时,它会确定:
- 两个屏幕的跨度分辨率
- 左屏幕的 x 分辨率
- 两个屏幕的名称
然后,在循环中(每秒一次),它:
使用以下命令检查活动窗口的位置:
wmctrl -lG
(获取窗口列表及其位置)xprop -root _NET_ACTIVE_WINDOW
(获取最前面窗口的 ID)
如果窗口的 (x-) 位置大于左屏幕的 x 分辨率,则窗口显然位于右屏幕上,除非它大于两个屏幕的跨度尺寸(那么它将位于右侧的工作区)。因此:
if limit < pos < span:
确定窗口是否位于右侧屏幕上(其中limit
是左侧屏幕的 x 分辨率,pos
是窗口的 x 位置,span
是两个屏幕的组合 x 分辨率)。
如果最前面的窗口的位置发生变化(在左屏幕或右屏幕上),脚本使用以下命令设置两个屏幕的亮度xrandr
:
xrandr --output <screen_name> --brightness <value>
编辑
使聚焦的屏幕暗淡闪烁,而不是使“未聚焦”的屏幕永久暗淡
根据评论和聊天中的要求,以下脚本版本会在新聚焦的屏幕上发出短暂暗淡的闪光:
#!/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
答案2
我还发现了另一种解决方案,它与我最初想要的有点不同,但也能正常工作。
- 安装
compizconfig-settings-manager compiz-plugins
- 运行 ccsm
- 在启用插件
Effects
部分Animations
- 编辑
Focus Animation
并选择所需的动画。
只有波浪效果起作用...所以如果你不喜欢它,你就会像我一样悲伤。