Jak czuwać monitor przy użyciu xset w konfiguracji z wieloma monitorami?

10

Podczas gdy dwa lub więcej monitorów pracuje razem, czy jest jakiś sposób na przełączenie jednego z nich w tryb gotowości / zawieszenie poprzez wydanie polecenia takiego jak xset dpms force suspend:? lub mając ustawiony w tym celu czas, np .: xset dpms 100 0 0który działa osobno na tych monitorach?

Mam dwa monitor współpracujące ze sobą, eDP1 (mój laptop) i VGA1 (monitor zewnętrzny).

Chcę, aby każdy z nich przeszedł osobno w tryb zawieszenia / gotowości, jeśli nie mam z nimi bezpośredniej interakcji, przypuszczam, że oglądam film na VGA1 i przez półtorej godziny eDP1 nic nie robi.

Nie jestem zainteresowany używaniem, xrandor --off --output eDP1ponieważ nie jest wystarczająco szybki do pracy.

Chcę, aby mój monitor był gotowy do pracy za pomocą prostego ruchu myszy, aby móc szybko przełączać się między nimi.

  • Uruchamianie: Ubuntu 18.04
  • Menedżer okien: OpenBox
Ravexina
źródło
Czy to z powodów energetycznych, czy może byłoby to rozwiązanie wizualne?
Jacob Vlijm
@Ravexina Pytanie, jak daleko posuwa się twoje podświetlenie eDP1? Czy całkowicie wyłącza jasność? Jeśli tak, czy mógłbyś przetestować dwa polecenia, które miałem w odpowiedzi na askubuntu.com/a/814043/295286 ? Z góry dziękuję za odpowiedź
Sergiy Kolodyazhnyy
1
@Ravexina zrobione, wydaje się działać bezbłędnie, ale będzie działało przez jeden dzień, opublikuje to późno wieczorem. Będzie rejestrować aktywność na ekranie, ale nigdy nie należy przyciemniać / wyłączać ekranu w miejscu, w którym aktualnie znajduje się mysz, prawda?
Jacob Vlijm
1
OK, więc prawdopodobnie spróbuję wdrożyć śledzenie okien w weekend. Niestety nie mam teraz zbyt dużo czasu, aby sobie z tym poradzić.
Sergiy Kolodyazhnyy
1
@Ravexina, dzięki. Prawdopodobnie wkrótce opublikuję inną (vala) wersję, uruchamianą przez aktywne okno lub (jeśli nie ma prawidłowego okna) przez działanie myszy. Zobaczymy również, czy możemy zrobić coś z podświetleniem, co prawdopodobnie również pozwoli zaoszczędzić trochę energii. Czas podczas bonusu jest po prostu zbyt krótki, ale pytanie jest wystarczająco interesujące, aby zagrać nieco dalej. Ciąg dalszy nastąpi. Jeszcze raz dziękuję.
Jacob Vlijm

Odpowiedzi:

5

Sterowanie poszczególnymi monitorami nie jest możliwe w Xset (a właściwie X11)

Jak sugeruje tytuł, nie jest to możliwe ze względu na sposób xset budowania i ze względu na używane funkcje X11. Jeśli spojrzymy na kod źródłowy, xsetwywołania DPMSForceLevel(dpy,DPMSModeSuspend)( wiersz 557 ), a zmienna wyświetlana dpypochodzi z XOpenDisplay()funkcji ( wiersz 203 ), a to z definicji :

Serwer wraz z ekranami i urządzeniami wejściowymi nazywany jest wyświetlaczem.

Innymi słowy, xsetstosuje ustawienia globalnie do całego wyświetlacza, a nie poszczególnych ekranów. xsetAby to działało, konieczna będzie zmiana kodu źródłowego. Wydaje się, że same rozszerzenia DPMS wywołują tylko cały ekran, a nie pojedyncze ekrany, więc nie można nawet napisać niestandardowego kodu za pomocą biblioteki X11.

/sysWydaje się, że ręczne kontrolowanie tego ustawienia za pośrednictwem podsystemu również nie działa

$ sudo bash -c 'echo Off > /sys/class/drm/card0-VGA-1/dpms'
[sudo] password for admin: 
bash: /sys/class/drm/card0-VGA-1/dpms: Permission denied

Ekrany są również usuwane z trybu DPMS, gdy wystąpią zdarzenia związane z klawiszem lub myszą, więc biorąc pod uwagę, że możesz chcieć poruszyć myszą lub użyć klawiatury, którekolwiek z tych działań spowoduje, że monitor opuści tryb DPMS.

Alternatywne obejścia

Najlepszą alternatywą (i faktycznie działającym fizycznie rozwiązaniem) jest xrandr- można jej użyć do kontroli poszczególnych „wyjść”. W szczególności,

xrandr --output VGA-1 -off

wyłączy to wyjście. Tak, wspomniałeś, że nie chcesz korzystać z tego rozwiązania, ponieważ nie jest ono wystarczająco szybkie, jednak jak dotąd jest ono najlepsze z dostępnych. Ma kilka zalet:

  • odporny na zdarzenia klawiszy i myszy
  • niezależnie kontroluje outpus w przeciwieństwie do xset

xrandr --output VGA-1 --brightness 0.1Będzie pokolorować ekran w taki sposób, że wydaje się, chociaż --brightnessjest oprogramowaniem, więc wyświetlacz nie jest faktycznie wygaszone na poziomie sprzętowym, ani nie jest ona wyłączona na poziomie sprzętowym. Wykonuje jednak funkcję wygaszania ekranu i jest również odporny na zdarzenia klawiszy / myszy.

Szukałem kodu źródłowego wygaszaczy ekranu Mate i Budgie, które są rozwidleniami wygaszacza ekranu GNOME, jednak w obu przypadkach wydają się być rozwiązaniem programowym, ponieważ w kodzie źródłowym nie ma wzmianki o DPMS.

Sergiy Kolodyazhnyy
źródło
Lubię alternatywy ... +1
Fabby
1
@Fabby Dzięki :) Do tej pory to najlepsze dostępne alternatywy
Sergiy Kolodyazhnyy
Myślę, że Menedżerowie okien wykonują pewne sztuczki i mogą zapewnić pewne haki. Istnieje witryna wymiany stosów o nazwie „Projektowanie oprogramowania” i może to być dobre miejsce, aby wprowadzić w błąd pomysł, że gdy główne okno (jak przeglądarka internetowa, ale nie Conky lub czas wyświetlania górnego paska) nie ma zmian pikseli w ciągu 10 minut, cały monitor (tylko jeden) zaczyna ściemniać w ciągu 30 sekund, aż stanie się całkowicie czarny. Następnie nawigacja myszą nad tym monitorem (zwykle używam 3 monitorów) przywraca jasność stopniowo w okresie od 1 do 5 sekund.
WinEunuuchs2Unix
@ WinEunuuchs2Unix Mam pomysł i jest kilka rzeczy, na które trzeba uważać, ale jest to trudne i tak zależy od danego menedżera okien. Problemem jest DPMS. Zarówno DPMS, jak i wszystko przyciemniają . Najlepsze, co możemy zrobić, to xrandr --offna razie
Sergiy Kolodyazhnyy
Moja wiedza na temat DPMS jest ograniczona. Myślę, że jest to oszczędność energii elektrycznej dla osoby stojącej / śpiącej. Istnieje również HDMI-CEC, który może dawać takie same wyniki, ale jest to dla mnie jeszcze bardziej czarna dziura magii. Nie wiem, czy w xrandr -offogóle wyłączy monitor. Może być taki sam, jak brightnessustawiony na zero? Co jest kolejnym problemem Mam program działający 24/7, który indywidualnie ustawia jasność i gamma dla 3 monitorów, czego nawet Windows nie jest w stanie zrobić. Nie jestem pewien, czy robi to lampka nocna, czerwona zmiana lub strumień. W każdym razie te programy mogą zostać pomieszane przez xrandr off. Przepraszamy za przejęcie Twojej odpowiedzi spekulacją :)
WinEunuuchs2Unix
4

Przez lata miałem taką konfigurację laptopa, że ​​kiedy pokrywa jest zamknięta, laptop zawiesza się, a monitory zewnętrzne gasną.

Z powodu chęci oglądania filmu przez 90 minut na monitorze zewnętrznym i zgaszania ekranu laptopa zmieniłem opcję zamykania pokrywy na „Nie rób nic”:

  • Zaleta: po zamknięciu pokrywy laptopa wszystkie okna laptopa znajdują się poniżej pełnego ekranu wideo.
  • Zaleta: po otwarciu okna pokrywy laptopa są przywracane i nie znajdują się już poniżej pełnego ekranu wideo.
  • Wada: muszę zrobić niepełny ekran wideo, aby uzyskać dostęp do menu górnego paska, aby wybrać opcję zawieszenia z menu koła zębatego.
  • Zaleta: gdy system jest zawieszony przez menu na monitorze zewnętrznym, otwarcie pokrywy laptopa nadal wznawia działanie systemu.

Nie używam DPMS do monitorów zewnętrznych, ale możesz sprawdzić swoje ustawienia za pomocą xset qpolecenia:

$ xset q
Keyboard Control:
  auto repeat:  on    key click percent:  0    LED mask:  00000002
  XKB indicators:
    00: Caps Lock:   off    01: Num Lock:    on     02: Scroll Lock: off
    03: Compose:     off    04: Kana:        off    05: Sleep:       off
    06: Suspend:     off    07: Mute:        off    08: Misc:        off
    09: Mail:        off    10: Charging:    off    11: Shift Lock:  off
    12: Group 2:     off    13: Mouse Keys:  off
  auto repeat delay:  500    repeat rate:  33
  auto repeating keys:  00ffffffdffffbbf
                        fadfffefffedffff
                        9fffffffffffffff
                        fff7ffffffffffff
  bell percent:  50    bell pitch:  400    bell duration:  100
Pointer Control:
  acceleration:  5/1    threshold:  5
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  0    cycle:  0
Colors:
  default colormap:  0xb3    BlackPixel:  0x0    WhitePixel:  0xffffff
Font Path:
  /usr/share/fonts/X11/misc,/usr/share/fonts/X11/Type1,built-ins
DPMS (Energy Star):
  Standby: 0    Suspend: 0    Off: 0
  DPMS is Disabled

Zwróć uwagę na te linie:

Screen Saver:
  prefer blanking:  yes
  • Prawdopodobnie byś chciał prefer blanking: no

Zwróć także uwagę na następujące linie:

DPMS (Energy Star):
  Standby: 0    Suspend: 0    Off: 0
  DPMS is Disabled
  • Prawdopodobnie zechcesz DPMS is enabledustawić monitor w razie Standbypotrzeby.

Mam nadzieję, że inni użytkownicy skorzystali z tych opcji i opublikują szczegółową odpowiedź.

WinEunuuchs2Unix
źródło
4

A może po prostu zamknąć laptopa?

Dlaczego?

Te dwa monitory to jeden obszar wyświetlania, więc wyłączenie jednego spowoduje szereg problemów, takich jak przerysowanie ekranu, przenoszenie aplikacji na główny monitor, ...

(Poszedłem tą drogą kilka lat temu i jedynym niezawodnym sposobem na zrobienie tego, co chcesz zrobić, jest naciśnięcie przycisku na zewnętrznym monitorze lub zamknięcie laptopa)

Upewnij się tylko, że ustawiłeś te ustawienia zasilania za pomocą gsettings set:

org.gnome.settings-daemon.plugins.power lid-close-suspend-with-external-monitor false
org.gnome.settings-daemon.plugins.power lid-close-ac-action 'nothing'
org.gnome.settings-daemon.plugins.power lid-close-battery-action 'nothing'
Fabby
źródło
W rzeczywistości jest to dobre rozwiązanie. Sprzęt, a do tego można skryptować. Jednak OP używa Openbox, co sugeruje, że zestawy ustawień mogą nie zadziałać. Dobrym rozwiązaniem może być dołączenie unix.stackexchange.com/a/52645/85039
Sergiy Kolodyazhnyy
4

Tymczasowy komentarz

  1. Na prośbę OP sprawiłem, że poniższy skrypt wyłącza ekran przy pomocy xrandr. Przy dłuższym teście wypadło to dość źle. Nie tyle wyłączenie nie powiodło się, ale przy ponownej aktywacji ekranu układ ekranu został całkowicie pomieszany. Z przyjemnością opublikuję go, aby sprawdzić, czy to działa w twoim przypadku, ale nie radzę go używać.
    W skrypcie wróciłem do ustawienia jasności na zero.
  2. Trwała dyskusja na temat tego, czy należy zdefiniować aktywny monitor według lokalizacji myszy lub lokalizacji aktywnego okna . Ten ostatni nie będzie działać, jeśli nie ma okna. Możemy w ogóle nie mieć okna (oprócz samego pulpitu), w którym to przypadku wybór okna do zaciemnienia będzie losowy (lub pęknie, jeśli nie uwzględnimy wyjątku). IMO jedyną opcją, która ma sens - i działałaby w przewidywalny sposób we wszystkich przypadkach - jest zdefiniowanie aktywnego ekranu według pozycji myszy. Ponadto w ten sposób menedżer okien decyduje, gdzie powinny pojawić się nowe okna.

Co zatem zmieniłem w tej wersji?
Czas bezczynności jest teraz domyślnie definiowany przez aktywność klawiatury i myszy. Obudzenie jest również wykonywane przez jedno z nich.


Automatycznie przyciemnij nieaktywny ekran

Jak powiedzieli moi współpracownicy, oddzielne wyłączanie ekranów z cli jest w najlepszym razie wyzwaniem i nie znalazłem też opcji.

Znalazłem sposób na automatyczne przyciemnienie wszystkich ekranów, z wyjątkiem tego, w którym znajduje się mysz, po czasie x.

No to ruszamy

#!/usr/bin/env python3
import subprocess
import gi
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk
import time
import sys


def get_idle():
    try:
        return int(subprocess.check_output("xprintidle")) / 1000
    except subprocess.CalledProcessError:
        return 0


def get_monitors():
    screen = Gdk.Screen.get_default()
    n_mons = display.get_n_monitors()
    mons = [screen.get_monitor_plug_name(i) for i in range(n_mons)]
    return mons


def set_mon_dimmed(mon, dim):
    print(mon, dim)
    val = "0.0" if dim else "1"
    try:
        subprocess.Popen(["xrandr", "--output", mon, "--brightness", val])
    except subprocess.CalledProcessError:
        print("oops")


def mousepos():
    # find out mouse location
    return Gdk.get_default_root_window().get_pointer()[1:3]


def get_currmonitor_atpos(x, y, display=None):
    """
    fetch the current monitor (obj) at position. display is optional to save
    fuel if it is already fetched elsewhere
    """
    if not display:
        display = Gdk.Display.get_default()
    return display.get_monitor_at_point(x, y)


display = Gdk.Display.get_default()
wait = int(sys.argv[1])
elapsed = 0
# set intervals to check
res = 2
monitors = [m for m in get_monitors()]
for m in monitors:
    set_mon_dimmed(m, False)

monrecord = {}
for m in monitors:
    monrecord[m] = {"idle": 0, "dimmed": False}

display = Gdk.Display.get_default()
idle1 = 0


while True:
    time.sleep(res)
    curr_mousepos = mousepos()
    activemon = get_currmonitor_atpos(
        curr_mousepos[0], curr_mousepos[1]
    ).get_model()
    idle2 = get_idle()
    if idle2 < idle1:
        monrecord[activemon]["idle"] = 0
        if monrecord[activemon]["dimmed"]:
            set_mon_dimmed(activemon, False)
            monrecord[activemon]["dimmed"] = False

    for m in monrecord.keys():
        curr_idle = monrecord[m]["idle"]
        print(m, curr_idle)
        if all([
            curr_idle > wait,
            monrecord[m]["dimmed"] is not True,
            m != activemon
        ]):
            set_mon_dimmed(m, True)
            monrecord[m]["dimmed"] = True         
        else:
            if m != activemon:
                monrecord[m]["idle"] = curr_idle + res

    idle1 = idle2

Jak skonfigurować

Konfiguracja jest prosta:

  1. Upewnij się, że masz oba python3-gii xprintidlezainstalowane

    sudo apt install python3-gi xprintidle
    
  2. Skopiuj powyższy skrypt do pustego pliku, zapisz go jako dim_inactivei wykonaj go

  3. Uruchom go za pomocą polecenia:

    /path/to/dim_inactive <idle_time_in_seconds>
    

    przykład:

    /path/to/dim_inactive 120
    

    przyciemni wszystkie ekrany, na których nie ma myszy po dwóch minutach

Dodatkowe informacje / objaśnienia

  • Skrypt wyświetla wszystkie ekrany podczas uruchamiania
  • Rejestruje czas bezczynności na monitor (prawdopodobnie ponad 2). Jeśli monitor nie jest dostępny przez x sekund, jest zaciemniony, oprócz monitora, na którym znajduje się mysz .
  • Zgodnie z dobrą (ale złą) tradycją Gnome ciągle psuje rzeczy i zmienia API. W wyniku uruchomienia tego skryptu w wersji 19.04 i nowszej pojawi się kilka przestarzałych ostrzeżeń. Jednocześnie nie psuje się na PEP8. Niemniej jednak zaktualizuje do najnowszych interfejsów API.
Jacob Vlijm
źródło
Bardzo miło, niemal kusiło mnie, aby napisać coś takiego. Ale wydaje mi się, że jest to powtarzany motyw - jak dotąd nie ma nic lepszego niż ściemnianie drugiego wyświetlacza za pomocą rozwiązań programowych, nic sprzętowego
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy Nah, tylko podświetlenie dodałoby coś, ale to wszystko, o ile teraz widzę. Pomyśl, że coś powinno być możliwe, ale prawdopodobnie będzie to zimny start, tak jak xrandr --offsądzę.
Jacob Vlijm
@JacobVlijm Tak, xrandr --offwolałbym w tym przypadku. Zwłaszcza, że ​​podświetlenie VGA nie może być sterowane programowo.
Sergiy Kolodyazhnyy
Dziękuję za wszystkie twoje wysiłki, ale dostaję najdziwniejsze zachowania ... Na przykład: przyciemnia monitory, ale 1w żadnym wypadku nie przywraca jasności . Kiedy wchodzę w interakcję z zewnętrznym wyświetlaczem za pomocą klawiatury i gdy mysz znajduje się na głównym ekranie, zewnętrzny staje się czarny po bezczynności. Kiedy nie mam interakcji z głównym wyświetlaczem, ale mysz tam jest, nic tam nie robi, a kiedy przesuwam mysz na inny główny ekran, nagle robi się czarny.
Ravexina
@Ravex (1) czy twoje monitory są dublowane? Jeśli nie, być może zatrzymałeś skrypt, gdy drugi ekran jest balnkowany. Naprawiono to teraz. (2) Dlaczego zdefiniowano aktywny ekran, moje myszy zostały wyjaśnione w [2] komentarza tymczasowego (3) Powinien zostać również naprawiony wraz ze zmianami w (1) (ta sama przyczyna) Huh, nie, trzeba zresetować czas bezczynności, zrobi że później dzisiaj.
Jacob Vlijm