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


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редактировании и выберите нужную анимацию.

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


Додж также работает для меня, но только когда окно подъема было скрыто или частично скрыто за другим. Исчезновение дает странную, неприятную вспышку.
Пэдди Ландау
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.