Come mettere in standby un monitor usando xset nella configurazione multi monitor?


10

Mentre due o più monitor lavorano insieme, c'è un modo per metterne uno in standby / sospendere emettendo un comando come xset dpms force suspend:? o avere un tempo impostato a tale scopo come: xset dpms 100 0 0che funziona separatamente su questi monitor?

Ho due monitor che lavorano uno accanto all'altro, eDP1 (il mio laptop) e VGA1 (un monitor esterno).

Voglio che ognuno di essi vada in modalità sospensione / standby separatamente se non interagisco direttamente con loro, supponiamo che stia guardando un film su VGA1 e che per un'ora e mezza eDP1 non faccia nulla.

Non mi interessa usare xrandor --off --output eDP1perché non è abbastanza veloce con cui lavorare.

Voglio che il mio monitor sia pronto per funzionare, con un semplice movimento del mouse in modo da poter passare rapidamente da uno all'altro.

  • In esecuzione: Ubuntu 18.04
  • Window Manager: OpenBox

È per ragioni energetiche o una soluzione visiva farebbe?
Jacob Vlijm,

@Ravexina Domanda, fino a che punto arriva la tua retroilluminazione eDP1? Disattiva completamente la luminosità? In caso affermativo, potresti testare i due comandi che avevo nella domanda di askubuntu.com/a/814043/295286 ? Grazie in anticipo per la risposta
Sergiy Kolodyazhnyy,

1
@Ravexina fatto, sembra funzionare alla perfezione, ma continuerà a funzionare per un giorno, lo pubblicherà stasera. Manterrà la registrazione sull'attività per schermo, ma non oscurerà / spegnerà mai lo schermo in cui si trova attualmente il mouse, giusto?
Jacob Vlijm,

1
OK, allora probabilmente proverò ad implementare il monitoraggio di Windows nel fine settimana. Purtroppo non ho molto tempo per affrontare queste cose in questo momento.
Sergiy Kolodyazhnyy,

1
@Ravexina, grazie. Probabilmente pubblicherò presto un'altra versione (vala), attivata da una finestra attiva o (se non esiste una finestra valida) dall'azione del mouse. Vedremo anche se possiamo fare qualcosa con la retroilluminazione, che probabilmente farà risparmiare anche un po 'di energia. Il tempo durante il bonus è semplicemente troppo breve, ma la domanda è abbastanza interessante da giocare ancora un po '. Continua. Grazie ancora.
Jacob Vlijm

Risposte:


5

Il controllo dei singoli monitor non è possibile con xset (e X11 in realtà)

Come suggerisce il titolo, non è possibile per motivi di come xset è costruito e a causa delle funzioni X11 che utilizza. Se osserviamo il codice sorgente, le xsetchiamate DPMSForceLevel(dpy,DPMSModeSuspend)( linea 557 ) e la variabile di visualizzazione dpyproviene dalla XOpenDisplay()funzione ( linea 203 ), ed è per definizione :

Un server, insieme ai suoi schermi e dispositivi di input, è chiamato display.

In altre parole, xsetapplica le impostazioni a livello globale all'intero display, non alle singole schermate. Sarebbe necessario cambiare xsetil codice sorgente affinché funzioni. Le stesse estensioni DPMS sembrano chiamare solo l'intero display, non singole schermate, quindi non è nemmeno possibile scrivere codice personalizzato con la libreria X11.

Anche il controllo manuale di tale impostazione tramite /syssottosistema non sembra funzionare

$ 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

Le schermate vengono inoltre eliminate dalla modalità DPMS quando si verificano eventi del tasto o del mouse, pertanto, considerando che è possibile spostare il mouse o utilizzare la tastiera, una di queste azioni farebbe uscire il monitor dalla modalità DPMS.

Soluzioni alternative

La migliore alternativa (e la soluzione effettivamente funzionante) è xrandr- potrebbe essere utilizzata per controllare i singoli "output". In particolare,

xrandr --output VGA-1 -off

imposterà quell'uscita. Sì, hai detto che non vuoi utilizzare questa soluzione poiché non è abbastanza veloce, tuttavia finora è la migliore disponibile. Ha un paio di vantaggi:

  • immune agli eventi chiave e del mouse
  • controlla indipendentemente l'outpus diversamente xset

Il xrandr --output VGA-1 --brightness 0.1sarà Colorize schermo in modo tale che risulta spento, anche se --brightnessè una soluzione software, quindi il display non è effettivamente inattivo a livello hardware, né è spento a livello hardware. Tuttavia, svolge il compito di oscurare uno schermo ed è anche resistente agli eventi chiave / mouse.

Ho cercato il codice sorgente degli screensaver Mate e Budgie, che sono entrambi fork di screensaver GNOME, tuttavia in entrambi i casi sembrano essere una soluzione software, dal momento che non c'è menzione di DPMS nel codice sorgente.


Mi piacciono le alternative ... +1
Fabby

1
@Fabby Grazie :) Finora sono le migliori alternative disponibili
Sergiy Kolodyazhnyy,

Penso che i Window Manager stiano facendo alcuni trucchi e potrebbero fornire alcuni agganci. Esiste un sito di scambio di stack chiamato "Software Design" e potrebbe essere un buon posto per far passare l'idea che quando una finestra principale (come un browser web ma non Conky o il tempo di visualizzazione della barra superiore) non ha cambiamenti di pixel nell'arco di 10 minuti il l'intero monitor (solo uno) inizia a oscurarsi per oltre 30 secondi fino a quando non è completamente nero. Quindi, spostando il mouse su quel monitor (di solito uso 3 monitor) ripristina gradualmente la luminosità in un periodo da 1 a 5 secondi.
WinEunuuchs2Unix

@ WinEunuuchs2Unix Ho un'idea e ci sono alcune cose da tenere d'occhio, ma è complicato e sì dipende dal gestore delle finestre in questione. Il problema è il DPMS. È debole o tutto con DPMS. Il meglio che possiamo fare è xrandr --offper ora
Sergiy Kolodyazhnyy

La mia conoscenza del DPMS è limitata. Penso che sia un risparmio di elettricità per stare in piedi / dormire. C'è anche HDMI-CEC che potrebbe dare gli stessi risultati, ma per me è ancora più un buco nero di magia. Non so xrandr -offnemmeno se spegne il monitor. Potrebbe essere uguale brightnessa zero? Il che è un altro problema: ho un programma in esecuzione 24 ore su 24, 7 giorni su 7, che imposta la luminosità e la gamma singolarmente per 3 monitor che nemmeno Windows può fare. Non sono sicuro che la luce notturna, lo spostamento rosso o il flusso lo facciano. Comunque quei programmi potrebbero essere incasinati da xrandr off.
Ci

4

Per anni ho installato il mio laptop in modo tale che quando il coperchio fosse chiuso il laptop si sarebbe sospeso e i monitor esterni sarebbero rimasti vuoti.

Per la tua ragione di voler guardare un video per 90 minuti su monitor esterno e lasciare lo schermo del laptop vuoto, ho cambiato l'opzione di chiusura del coperchio in "Non fare nulla":

  • Vantaggio: quando chiudo il coperchio del laptop tutte le finestre del laptop passano sotto il video a schermo intero.
  • Vantaggio: quando apro le finestre del coperchio del laptop vengono ripristinate e non sono più sotto il video a schermo intero.
  • Svantaggio: devo selezionare il video non a schermo intero per accedere al menu della barra superiore per selezionare la sospensione dal menu a forma di ingranaggio.
  • Vantaggio: quando il sistema è sospeso dal menu sul monitor esterno, l'apertura del coperchio del laptop riprende comunque il sistema.

Non sto usando DPMS per monitor esterni ma potresti controllare le tue impostazioni con il xset qcomando:

$ 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

Nota queste righe:

Screen Saver:
  prefer blanking:  yes
  • Probabilmente vorresti prefer blanking: no

Notare anche queste righe:

DPMS (Energy Star):
  Standby: 0    Suspend: 0    Off: 0
  DPMS is Disabled
  • Probabilmente vorrai DPMS is enabledimpostare il monitor su Standbyquando lo desideri.

Spero che altri utenti abbiano usato queste opzioni e postino una risposta dettagliata per te.


4

Che ne dici di chiudere semplicemente il laptop?

Perché?

Questi due monitor sono un'area di visualizzazione, quindi la disattivazione creerà una serie di problemi come il ridisegno dello schermo, le applicazioni che si spostano sul monitor principale, ...

(Ho percorso quella strada qualche anno fa e l'unico modo affidabile che ho trovato di fare quello che vuoi fare è premere il pulsante sul monitor esterno o chiudere il laptop)

Assicurati di aver impostato queste impostazioni di risparmio energia con 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'

In realtà, questa è una bella soluzione. Hardware, oltre a questo può essere programmato. Tuttavia, OP utilizza Openbox, il che suggerisce che gsettings potrebbe non avere effetto. Per una buona alternativa, potresti voler includere unix.stackexchange.com/a/52645/85039
Sergiy Kolodyazhnyy

4

Commento temporaneo

  1. Su richiesta di OP, ho fatto in modo che lo script seguente spegnesse lo schermo mediante xrandr. Su un test più lungo, questo ha funzionato piuttosto male. Non tanto lo spegnimento non è riuscito, ma alla riattivazione dello schermo, il layout dello schermo è stato completamente incasinato. Sarei felice di pubblicarlo per vedere se funziona nel tuo caso, ma il mio consiglio è di non usarlo.
    Nella sceneggiatura, invece, sono tornato a impostare la luminosità su zero.
  2. Si è discusso di come dovremmo definire il monitor attivo in base alla posizione del mouse o alla posizione della finestra attiva . Quest'ultimo non funzionerà se non esiste alcuna finestra. Potremmo non avere affatto una finestra (a parte il desktop stesso) nel qual caso la scelta della finestra da oscurare sarebbe casuale (o spezzerebbe se non includessimo l'eccezione). L'unica opzione IMO che ha senso - e funzionerebbe in modo prevedibile in tutti i casi - è definire lo schermo attivo in base alla posizione del mouse. Inoltre, è così che il gestore delle finestre decide dove dovrebbero apparire le nuove finestre.

Quindi cosa ho cambiato in questa versione?
Il tempo di inattività è ora definito dall'attività della tastiera e del mouse per impostazione predefinita. Anche il risveglio viene eseguito da uno dei due.


Schermo inattivo con attenuazione automatica

Come hanno detto i miei compagni di risposta, spegnere gli schermi separatamente da cli è una sfida nella migliore delle ipotesi, e non ho nemmeno trovato un'opzione.

Quello che ho trovato è un modo per oscurare automaticamente tutte le schermate, tranne quella in cui si trova il mouse, dopo x tempo.

Eccoci qui

#!/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

Come impostare

L'installazione è semplice:

  1. Assicuratevi di avere entrambi python3-gie xprintidleinstallato

    sudo apt install python3-gi xprintidle
    
  2. Copia lo script sopra in un file vuoto, salvalo come dim_inactivee rendilo eseguibile

  3. Eseguilo con il comando:

    /path/to/dim_inactive <idle_time_in_seconds>
    

    un esempio:

    /path/to/dim_inactive 120
    

    oscurerà tutte le schermate in cui il mouse non è dopo due minuti

Ulteriori informazioni / spiegazioni

  • Lo script elenca tutte le schermate all'avvio
  • Tiene traccia se il tempo di inattività per monitor (forse più di 2). Se non si accede a un monitor per x secondi, viene oscurato, a parte il monitor in cui si trova il mouse .
  • Secondo una buona (ma cattiva) tradizione, Gnome continua a rompere le cose e continua a cambiare le API. Di conseguenza, eseguendo questo script su 19.04 e versioni successive, riceverai alcuni avvisi obsoleti. Allo stesso tempo, non si rompe su PEP8. Si aggiornerà comunque alle ultime API.

Molto bello, quasi tentato di scrivere anche qualcosa del genere. Ma immagino che questo sia il tema ripetuto qui - finora non c'è niente di meglio che oscurare l'altro display tramite soluzioni software, niente di hardware
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy Nah, solo la retroilluminazione aggiungerebbe qualcosa, ma è tutto ciò che posso vedere ora. Pensa che qualcosa dovrebbe essere possibile, ma probabilmente avrà un inizio a freddo, proprio come xrandr --offimmagino.
Jacob Vlijm,

@JacobVlijm Sì, xrandr --offè quello che preferirei in questo caso. Soprattutto perché la retroilluminazione VGA non può essere controllata da software.
Sergiy Kolodyazhnyy,

Grazie per tutti i tuoi sforzi, ma sto ottenendo i comportamenti più strani ... Ad esempio: oscura i monitor ma non ripristina la luminosità 1in nessuna circostanza. Quando interagisco con il display esterno usando la tastiera e mentre il mouse è nel display principale, quello esterno diventa nero dopo il tempo di inattività. Quando non ho alcuna interazione con il display principale ma il mouse è lì, non fa nulla lì e quando sposto il mouse su un altro display, quello imminente diventa nero.
Ravexina,

@Ravex (1) i tuoi monitor sono speculari? In caso contrario, potresti aver interrotto lo script con la seconda schermata bardata. Risolto questo ora. (2) Perché è definito lo schermo attivo il mio mousepos è spiegato in [2] del commento temporaneo (3) Dovrebbe anche essere risolto con le modifiche in (1) (stessa causa) Eh, no, è necessario ripristinare il tempo di inattività, lo farà quello più tardi oggi.
Jacob Vlijm,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.