Comment mettre en veille un moniteur en utilisant xset dans une configuration multi-écrans?


10

Tout en ayant deux ou plusieurs moniteurs travaillant ensemble, existe-t-il un moyen de mettre un seul d'entre eux en veille / suspendre en émettant une commande comme xset dpms force suspend:? ou avoir un temps défini à cet effet comme: xset dpms 100 0 0qui fonctionne sur ces moniteurs séparément?

J'ai deux moniteurs qui fonctionnent ensemble, eDP1 (Mon ordinateur portable) et VGA1 (Un moniteur externe).

Je veux que chacun d'eux passe en mode suspension / veille séparément si je n'interagis pas directement avec eux, supposons que je regarde un film sur VGA1, et pendant une heure et demie, eDP1 ne fait rien.

Je ne suis pas intéressé à utiliser xrandor --off --output eDP1car ce n'est pas assez rapide pour travailler avec.

Je veux que mon moniteur soit prêt à fonctionner, avec un simple mouvement de souris pour pouvoir basculer rapidement entre eux.

  • En cours d'exécution: Ubuntu 18.04
  • Gestionnaire de fenêtres: OpenBox

Est-ce pour des raisons énergétiques, ou une solution visuelle ferait-elle l'affaire?
Jacob Vlijm

@Ravexina Question, jusqu'où va votre rétro-éclairage eDP1? Désactive-t-il complètement la luminosité? Si oui, pourriez-vous s'il vous plaît tester les deux commandes que j'avais dans la réponse askubuntu.com/a/814043/295286 ? Merci d'avance pour la réponse
Sergiy Kolodyazhnyy

1
@Ravexina fait, semble fonctionner sans problème, mais le fera fonctionner pendant une journée, le publiera tard ce soir. Il gardera une trace de l'activité par écran, mais ne diminuera / éteindra jamais l'écran là où se trouve la souris, non?
Jacob Vlijm

1
OK, j'essaierai probablement d'implémenter le suivi de Windows le week-end. Malheureusement, je n'ai pas beaucoup de temps pour m'occuper de ces choses en ce moment.
Sergiy Kolodyazhnyy

1
@Ravexina, merci. Je publierai probablement une autre version (vala) bientôt, déclenchée par une fenêtre active ou (s'il n'y a pas de fenêtre valide) par l'action de la souris. Nous verrons également si nous pouvons faire quelque chose avec le rétro-éclairage, ce qui économisera probablement aussi de l'énergie. Le temps pendant le bonus est tout simplement trop court, mais la question est suffisamment intéressante pour jouer un peu plus loin. À suivre. Encore merci.
Jacob Vlijm

Réponses:


5

Le contrôle de moniteurs individuels n'est pas possible avec xset (et X11 en fait)

Comme le titre l' indique, il est impossible pour des raisons de la façon dont xset est construit et en raison des fonctions qu'il utilise X11. Si nous regardons le code source, les xsetappels DPMSForceLevel(dpy,DPMSModeSuspend)( ligne 557 ), et la variable d'affichage dpyvient de la XOpenDisplay()fonction ( ligne 203 ), et c'est par définition :

Un serveur, avec ses écrans et ses périphériques d'entrée, est appelé affichage.

En d'autres termes, xsetapplique les paramètres globalement à l'ensemble de l'affichage, pas aux écrans individuels. Il serait nécessaire de changer xsetle code source pour que cela fonctionne. Les extensions DPMS elles-mêmes ne semblent généralement appeler que l'affichage entier, pas les écrans individuels, il n'est donc pas possible même d'écrire du code personnalisé avec la bibliothèque X11.

Le contrôle manuel de ce paramètre via le /syssous-système ne semble pas non plus fonctionner

$ 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

Les écrans sont également retirés du mode DPMS lorsque des événements de touches ou de souris se produisent, de sorte que si vous souhaitez déplacer votre souris ou utiliser le clavier, l'une de ces actions entraînerait la sortie du moniteur du mode DPMS.

Solutions de rechange

La meilleure alternative (et réellement la solution qui fonctionne physiquement) est xrandr- elle pourrait être utilisée pour contrôler les "sorties" individuelles. En particulier,

xrandr --output VGA-1 -off

désactivera cette sortie. Oui, vous avez mentionné que vous ne vouliez pas utiliser cette solution car elle n'est pas assez rapide, mais jusqu'à présent, c'est la meilleure disponible. Il présente deux avantages:

  • insensible aux événements des touches et des souris
  • contrôle indépendamment l'outpus contrairement xset

Le xrandr --output VGA-1 --brightness 0.1colorisera l'écran de telle sorte qu'il apparaît éteint, même s'il --brightnesss'agit d'une solution logicielle, de sorte que l'affichage n'est pas réellement atténué au niveau matériel, ni éteint au niveau matériel. Cependant, il fait le travail de masquer un écran et résiste également aux événements de touches / souris.

J'ai regardé le code source des économiseurs d'écran Mate et Budgie, qui sont tous deux des fourches de l'économiseur d'écran GNOME, mais dans les deux cas, ils semblent être une solution logicielle, car il n'y a aucune mention de DPMS dans le code source.


J'aime les alternatives ... +1
Fabby

1
@Fabby Merci :) Jusqu'à présent, ce sont les meilleures alternatives disponibles
Sergiy Kolodyazhnyy

Je pense que les gestionnaires de fenêtres font des tours et pourraient fournir des crochets. Il existe un site d'échange de pile appelé "Software Design" et il pourrait être un bon endroit pour faire flotter l'idée que lorsqu'une fenêtre principale (comme un navigateur Web mais pas Conky ou la barre supérieure affichant l'heure) n'a pas de changement de pixel pendant 10 minutes le moniteur entier (un seul) commence à s'assombrir pendant 30 secondes jusqu'à ce qu'il soit complètement noir. Ensuite, naviguer avec la souris sur ce moniteur (j'utilise généralement 3 moniteurs) restaure progressivement la luminosité sur une période de 1 à 5 secondes.
WinEunuuchs2Unix

@ WinEunuuchs2Unix J'ai une idée et il y a quelques choses à surveiller, mais c'est délicat, et oui dépend du gestionnaire de fenêtres en question. Le problème est le DPMS. Soit tout est sombre, soit rien avec DPMS. Le mieux que nous puissions faire est xrandr --offpour l'instant
Sergiy Kolodyazhnyy

Mes connaissances DPMS sont limitées. Je pense que c'est une économie d'énergie pour le standy / sommeil. Il y a aussi HDMI-CEC qui pourrait donner les mêmes résultats mais c'est encore plus un trou noir de magie pour moi. Je ne sais pas si xrandr -offmême éteint le moniteur. Il pourrait être identique brightnessà zéro? Ce qui est un autre problème, j'ai un programme fonctionnant 24h / 24 et 7j / 7 qui définit la luminosité et le gamma individuellement pour 3 moniteurs, ce que même Windows ne peut pas faire. Je ne sais pas si la lumière de nuit, le décalage vers le rouge ou le flux le font. Quoi qu'il en soit, ces programmes pourraient être gâchés par xrandr off. Désolé d'avoir détourné votre réponse en spéculant :)
WinEunuuchs2Unix

4

Pendant des années, j'ai installé mon ordinateur portable de telle sorte que lorsque le couvercle est fermé, l'ordinateur portable se suspend et les moniteurs externes deviennent vides.

Pour votre raison de vouloir regarder une vidéo pendant 90 minutes sur un moniteur externe et que l'écran de l'ordinateur portable se vide, j'ai changé l'option de fermeture du couvercle en "Ne rien faire":

  • Avantage: lorsque je ferme le couvercle de l'ordinateur portable, toutes les fenêtres d'ordinateur portable passent sous la vidéo plein écran.
  • Avantage: lorsque j'ouvre le couvercle du portable, les fenêtres sont restaurées et ne sont plus en dessous de la vidéo plein écran.
  • Inconvénient: je dois faire de la vidéo en mode non plein écran pour accéder au menu de la barre supérieure et sélectionner suspendre dans le menu de l'équipement.
  • Avantage: lorsque le système est suspendu par le menu sur un moniteur externe, l'ouverture du couvercle de l'ordinateur portable reprend toujours le système.

Je n'utilise pas DPMS pour les moniteurs externes mais vous pouvez vérifier vos paramètres avec la xset qcommande:

$ 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

Remarquez ces lignes:

Screen Saver:
  prefer blanking:  yes
  • Vous voudriez probablement prefer blanking: no

Notez également ces lignes:

DPMS (Energy Star):
  Standby: 0    Suspend: 0    Off: 0
  DPMS is Disabled
  • Vous voudrez probablement DPMS is enabledrégler le moniteur sur votre Standbychoix.

J'espère que d'autres utilisateurs ont utilisé ces options et publié une réponse détaillée pour vous.


4

Que diriez-vous de simplement fermer l'ordinateur portable?

Pourquoi?

Ces deux moniteurs sont une zone d'affichage, donc la désactivation de l'un créera un certain nombre de problèmes tels que le redessin de l'écran, le déplacement des applications vers le moniteur principal, ...

(J'ai emprunté cette voie il y a quelques années et le seul moyen fiable que j'ai trouvé de faire ce que vous voulez faire est d'appuyer sur le bouton du moniteur externe ou de fermer l'ordinateur portable)

Assurez-vous simplement de définir ces paramètres d'alimentation avec 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'

En fait, c'est une bonne solution. Le matériel, plus cela peut être scripté. Cependant, OP utilise Openbox, ce qui suggère que les paramètres peuvent ne pas prendre effet. Pour une bonne alternative, vous pouvez inclure unix.stackexchange.com/a/52645/85039
Sergiy Kolodyazhnyy

4

Commentaire temporaire

  1. À la demande de OP, j'ai fait le script ci-dessous éteindre l'écran au moyen de xrandr. Sur un test plus long, cela a très mal fonctionné. Non pas que la mise hors tension ait échoué, mais lors de la réactivation de l'écran, la disposition de l'écran était complètement foirée. Je serais heureux de le poster pour voir si cela fonctionne dans votre cas, mais mon conseil est de ne pas l'utiliser.
    Dans le script, je suis retourné à la mise à zéro de la luminosité.
  2. Il y a eu une discussion sur la question de savoir si nous devrions définir le moniteur actif par emplacement de la souris ou par emplacement de la fenêtre active . Ce dernier ne fonctionnera pas si aucune fenêtre n'existe. Nous pourrions ne pas avoir de fenêtre du tout (à part le bureau lui-même), auquel cas le choix de la fenêtre à masquer serait aléatoire (ou se briserait si nous n'incluions pas l'exception). IMO la seule option qui a du sens - et fonctionnerait de manière prévisible dans tous les cas - est de définir l'écran actif par la position de la souris. De plus, c'est également ainsi que le gestionnaire de fenêtres décide où les nouvelles fenêtres doivent apparaître.

Alors qu'est-ce que j'ai changé dans cette version?
Le temps d'inactivité est désormais défini par l'activité du clavier et de la souris par défaut. Le réveil se fait également par l'un ou l'autre.


Tamiser automatiquement l'écran inactif

Comme l'ont dit mes collègues répondeurs, éteindre les écrans de cli séparément est au mieux un défi, et je n'ai pas trouvé d'option non plus.

Ce que j'ai trouvé est un moyen de réduire automatiquement tous les écrans, sauf celui où se trouve la souris, après x fois.

Et c'est parti

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

Comment installer

La configuration est simple:

  1. Assurez-vous d'avoir les deux python3-giet xprintidleinstallés

    sudo apt install python3-gi xprintidle
    
  2. Copiez le script ci-dessus dans un fichier vide, enregistrez-le sous dim_inactiveet rendez-le exécutable

  3. Exécutez-le par la commande:

    /path/to/dim_inactive <idle_time_in_seconds>
    

    un exemple:

    /path/to/dim_inactive 120
    

    assombrit tous les écrans où la souris n'est pas au bout de deux minutes

Informations supplémentaires / explication

  • Le script répertorie tous les écrans au démarrage
  • Il enregistre le temps d'inactivité par moniteur (éventuellement plus de 2). Si un moniteur n'est pas accessible pendant x secondes, il est noirci, à l' exception du moniteur où se trouve la souris .
  • Selon une bonne (mais mauvaise) tradition, Gnome continue de casser des trucs et de changer les API. Par conséquent, en exécutant ce script à partir de la version 19.04, vous obtiendrez quelques avertissements obsolètes. En même temps, il ne casse pas sur PEP8. Mettra néanmoins à jour les dernières API.

Très sympa, presque tenté d'écrire aussi quelque chose comme ça. Mais je suppose que c'est le thème répété ici - jusqu'à présent, il n'y a rien de mieux que d'atténuer l'autre écran via des solutions logicielles, rien de matériel
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy Nah, seul le rétro-éclairage ajouterait quelque chose, mais c'est tout ce que je peux voir maintenant. Pensez que quelque chose devrait être possible, mais aura probablement un démarrage à froid, tout comme xrandr --offje suppose.
Jacob Vlijm

@JacobVlijm Ouais, xrandr --offc'est ce que je préférerais dans ce cas. D'autant plus que le rétroéclairage VGA ne peut pas être contrôlé par logiciel.
Sergiy Kolodyazhnyy

Merci pour tous vos efforts, mais j'obtiens les comportements les plus étranges ... Par exemple: il atténue les moniteurs mais ne réinitialise 1en aucun cas la luminosité . Lorsque j'interagis avec un écran externe à l'aide du clavier et lorsque la souris est dans l'écran principal, celui-ci devient noir après une période d'inactivité. Lorsque je n'ai aucune interaction avec l'écran principal mais que la souris est là, elle n'y fait rien et lorsque je déplace la souris vers un autre écran principal, le noir devient imminent.
Ravexina

@Ravex (1) vos moniteurs sont-ils en miroir? Sinon, vous avez peut-être arrêté le script avec le deuxième écran annulé. Corrigé cela maintenant. (2) Pourquoi l'écran actif est défini, mon tapis de souris est expliqué dans [2] du commentaire temporaire (3) Devrait aussi être corrigé avec les changements dans (1) (même cause) Huh, non, besoin de réinitialiser le temps d'inactivité que plus tard dans la journée.
Jacob Vlijm
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.