Как выделить текущий экран (или окно)?

11

Я использую две настройки экрана на работе, и хотя обычно это помогает больше, чем вредно, у меня есть некоторые проблемы с этим.

Одна из них - проблема с перемещением фокуса - иногда я ошибаюсь, набирая текст на неправильном экране (фокус - трейлинг моего курсора, но не всегда легко заметить, что курсор находится на другом экране, когда вы спешите). Это очень раздражает, когда вместо того, чтобы печатать, я вызываю множество различных действий (сочетания клавиш в Thunderbird).

Есть ли способ лучше выделить активный экран или окно (например, с помощью легко видимой границы - даже для развернутых окон)?

РЕДАКТИРОВАТЬ:

Я думаю, что хорошим решением будет какая-то короткая анимация, когда окно получает фокус.

Корда
источник
Какой DE? В gnome-shell вы можете использовать extensions.gnome.org/extension/891/windows-blur-effects
Rmano
1
@Rmano тег говорит о единстве :)
Джейкоб Влейм
1
@JacobVlijm ой --- правда.
Оставит

Ответы:

13

Выделите сфокусированный экран (или потушите при смене фокуса, см. РЕДАКТИРОВАТЬ ниже)

При параллельной установке двух мониторов (слева направо) приведенный ниже скрипт установит яркость монитора с фокусированным окном на «нормальное» (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

Как пользоваться

  1. Скрипт нуждается в wmctrl:

    sudo apt-get install wmctrl
  2. Скопируйте скрипт в пустой файл, сохраните его как highlight_focus.py

  3. Протестируйте его с помощью команды:

    python3 /path/to/highlight_focus.py

    При подключенном втором мониторе проверьте, работает ли скрипт должным образом.

  4. Если все работает нормально, добавьте его в автозагрузку приложений: Dash> Startup Applications> Добавить команду:

    /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 (чтобы получить идентификатор самого переднего окна)

Если позиция окна (x-) больше, чем x-разрешение левого экрана, окно, по-видимому, находится на правом экране, если только оно не превышает размер охвата двух экранов (тогда оно будет в рабочей области на право). следовательно:

if limit < pos < span:

определяет, находится ли окно на правом экране (где limitx-res левого экрана, posявляется x-позицией окна и spanявляется комбинированным x-res обоих экранов).

При изменении положения самого переднего окна (на левом или правом экране) сценарий устанавливает яркость обоих экранов с помощью 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
Якоб Влейм
источник
+1. Я всегда люблю твои ответы, Джейкоб. Хорошая работа.
Parto
Мне пришлось изменить , limit < pos < spanчтобы limit <= pos < spanполучить его работу. Во всяком случае, это действительно приятно. Однако я не уверен, хочу ли я, чтобы это работало таким образом (затемнение другого экрана). Я постараюсь изменить его, чтобы сделать один яркий «импульс» при смене активного экрана.
Корда
Я также добавил обработчик выхода, он сбрасывает яркость экрана до нормального значения. (так что он не останется серым, когда я убил скрипт во время тестирования). Не уверен, стоит ли мне добавлять это здесь - я не очень люблю Python, поэтому я не уверен, правильно ли я это сделал (но это работает)
korda
Я отредактировал твой ответ и добавил его.
Корда
1
@JacobVlijm Ух ты! ты рок
дхия
1

Я также нашел другое решение, которое немного отличается от того, что я хотел в первую очередь, но тоже отлично работает.

  1. устанавливать compizconfig-settings-manager compiz-plugins
  2. Запустить ccsm
  3. В Effectsразделе включить Animationsплагин
  4. В Focus Animationредактировании и выберите нужную анимацию.

Сработал только волновой эффект ... Так что если вам это не нравится, у вас будет такое же грустное лицо, как у меня.

Корда
источник
Додж также работает для меня, но только когда окно подъема было скрыто или частично скрыто за другим. Исчезновение дает странную, неприятную вспышку.
Пэдди Ландау