Como colocar um monitor em espera usando o xset na configuração de vários monitores?

10

Enquanto dois ou mais monitores trabalham juntos, existe alguma maneira de colocar um deles em espera / suspensão, emitindo um comando como xset dpms force suspend:? ou com um tempo definido para esse fim, como: o xset dpms 100 0 0que funciona nesses monitores separadamente?

Eu tenho dois monitores trabalhando juntos, eDP1 (My Laptop) e VGA1 (An External monitor).

Eu quero que cada um deles entre no modo de suspensão / espera separadamente, se não estiver interagindo diretamente com eles, suponha que esteja assistindo a um filme no VGA1, e por uma hora e meia o eDP1 não faça nada.

Não estou interessado em usar xrandor --off --output eDP1porque não é rápido o suficiente para trabalhar.

Quero que meu monitor esteja pronto para funcionar, com um simples movimento do mouse, para poder alternar rapidamente entre eles.

  • Execução: Ubuntu 18.04
  • Gerenciador de Janelas: OpenBox
Ravexina
fonte
É por razões de energia ou seria uma solução visual?
Jacob Vlijm 28/03/19
@Ravexina Pergunta, até onde vai a luz de fundo do eDP1? Desativa o brilho todo o caminho? Se sim, você poderia testar os dois comandos que eu tinha na resposta askubuntu.com/a/814043/295286 ? Agradecemos antecipadamente a resposta #
Sergiy Kolodyazhnyy 28/03/19
1
@Ravexina feito, parece funcionar perfeitamente, mas continuará funcionando por um dia, publicará tarde desta noite. Ele mantém o registro da atividade por tela, mas nunca escurece / desliga a tela em que o mouse está atualmente, certo?
Jacob Vlijm 29/03/19
1
OK, provavelmente tentarei implementar o rastreamento de janelas no fim de semana. Infelizmente, não tenho muito tempo para lidar com essas coisas agora.
Sergiy Kolodyazhnyy 29/03/19
1
@Ravexina, obrigado. Provavelmente postarei outra versão (vala) em breve, acionada pela janela ativa ou (se não houver uma janela válida) pela ação do mouse. Também veremos se podemos fazer algo com luz de fundo, o que provavelmente também economizará energia. O tempo durante o bônus simplesmente é muito curto, mas a questão é interessante o suficiente para jogar um pouco mais. Continua. Obrigado mais uma vez.
Jacob Vlijm 31/03/19

Respostas:

5

Controlar monitores individuais não é possível com o xset (e o X11, na verdade)

Como o título sugere, não é possível por razões de como xset é construído e devido às funções do X11 que ele usa. Se olharmos para o código-fonte, xsetchamadas DPMSForceLevel(dpy,DPMSModeSuspend)( linha 557 ) e a variável DISPLAY dpyvem de XOpenDisplay()função ( linha 203 ), e que é por definição :

Um servidor, junto com suas telas e dispositivos de entrada, é chamado de exibição.

Em outras palavras, xsetaplica configurações globalmente a toda a exibição, não a telas individuais. Seria necessário alterar o xsetcódigo fonte para que isso funcionasse. As próprias extensões DPMS parecem chamar apenas a exibição inteira, não telas individuais, portanto, não é possível nem escrever código personalizado com a biblioteca X11.

O controle manual dessa configuração via /syssubsistema também não parece estar funcionando

$ 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

As telas também são retiradas do modo DPMS quando ocorrem eventos de tecla ou mouse; portanto, considerando que você pode mover o mouse ou usar o teclado, qualquer uma dessas ações faria o monitor sair do modo DPMS.

Soluções alternativas

A melhor alternativa (e a solução que realmente funciona fisicamente) é xrandr- ela poderia ser usada para controlar as "saídas" individuais. Em particular,

xrandr --output VGA-1 -off

irá definir essa saída. Sim, você mencionou que não deseja usar esta solução, pois ela não é rápida o suficiente, mas até agora é a melhor disponível. Tem algumas vantagens:

  • imune a eventos de chave e mouse
  • controla independentemente o outpus ao contrário xset

A xrandr --output VGA-1 --brightness 0.1tela será colorida de maneira que apareça, mesmo que --brightnessseja uma solução de software, para que a tela não fique realmente esmaecida no nível do hardware, nem no nível do hardware. No entanto, ele faz o trabalho de apagar uma tela e também é resistente a eventos de tecla / mouse.

Eu olhei o código fonte dos protetores de tela Mate e Budgie, que são bifurcações do protetor de tela GNOME, no entanto, em ambos os casos, eles parecem ser uma solução de software, já que não há menção de DPMS no código fonte.

Sergiy Kolodyazhnyy
fonte
Gosto das alternativas ... +1
Fabby
1
@Fabby Thanks :) Até agora, essas são as melhores alternativas disponíveis #
Sergiy Kolodyazhnyy
Eu acho que os gerenciadores de janelas estão fazendo alguns truques e podem fornecer alguns ganchos. Existe um site de troca de pilhas chamado "Design de Software" e pode ser um bom lugar para mudar a ideia de que quando uma janela principal (como um navegador da Web, mas não o Conky ou o tempo de exibição da barra superior) não tem alterações de pixel ao longo de 10 minutos, todo o monitor (apenas um) começa a escurecer por 30 segundos até ficar completamente preto. A navegação do mouse sobre esse monitor (normalmente uso 3 monitores) restaura o brilho gradualmente durante um período de 1 a 5 segundos.
WinEunuuchs2Unix 31/03/19
@ WinEunuuchs2Unix Eu tenho uma idéia e há algumas coisas a serem observadas, mas é complicado, e sim depende do gerenciador de janelas em questão. O problema é o DPMS. É tudo ou nada obscurecido com o DPMS. Melhor que podemos fazer é xrandr --off, por enquanto
Sergiy Kolodyazhnyy
Meu conhecimento sobre DPMS é limitado. Eu acho que é uma coisa de economizar eletricidade para standy / sleep. Também há HDMI-CEC que pode dar os mesmos resultados, mas isso é ainda mais um buraco negro de mágica para mim. Não sei se xrandr -offdesliga o monitor. Pode ser o mesmo que brightnessdefinido como zero? Qual é outro problema? Tenho um programa que funciona 24 horas por dia, 7 dias por semana, que define o brilho e a gama individualmente para 3 monitores que nem o Windows pode fazer. Não tenho certeza se a luz noturna, o desvio para o vermelho ou o fluxo o fazem. De qualquer forma, esses programas podem ficar confusos com o xrandr off. Desculpe pelo seqüestro de sua resposta com especulando :)
WinEunuuchs2Unix
4

Por anos, eu tinha o meu laptop configurado de forma que, quando a tampa estivesse fechada, o laptop fosse suspenso e os monitores externos ficassem em branco.

Por sua razão de querer assistir a um vídeo por 90 minutos no monitor externo e deixar a tela do laptop em branco, mudei a opção de fechar a tampa para "Não fazer nada":

  • Vantagem: Quando fecho a tampa do laptop, todas as janelas do laptop ficam abaixo do vídeo em tela cheia.
  • Vantagem: Quando abro, as janelas da tampa do laptop são restauradas e não ficam mais abaixo do vídeo em tela cheia.
  • Desvantagem: eu tenho que criar um vídeo não em tela cheia para acessar o menu da barra superior e selecionar suspender no menu de engrenagem.
  • Vantagem: Quando o sistema é suspenso por menu no monitor externo, a abertura da tampa do laptop ainda reinicia o sistema.

Não estou usando o DPMS para monitores externos, mas você pode verificar suas configurações com o 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

Observe estas linhas:

Screen Saver:
  prefer blanking:  yes
  • Você provavelmente iria querer prefer blanking: no

Observe também estas linhas:

DPMS (Energy Star):
  Standby: 0    Suspend: 0    Off: 0
  DPMS is Disabled
  • Você provavelmente deseja DPMS is enableddefinir o monitor Standbyquando desejar.

Esperamos que outros usuários tenham usado essas opções e postado uma resposta detalhada para você.

WinEunuuchs2Unix
fonte
4

Que tal simplesmente fechar o laptop?

Por quê?

Esses dois monitores são uma área de exibição, portanto, desligar um deles criará uma série de problemas como redesenho de tela, aplicativos movendo-se para o monitor principal, ...

(Eu segui esse caminho há alguns anos e a única maneira confiável que encontrei de fazer o que você quer fazer é pressionar o botão no monitor externo ou fechar o laptop)

Apenas certifique-se de definir essas configurações de energia com 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
fonte
Na verdade, esta é uma boa solução. O hardware, além disso, pode ser script. No entanto, o OP está usando o Openbox, o que sugere que gsettings pode não ter efeito. Para uma boa alternativa, convém incluir unix.stackexchange.com/a/52645/85039
Sergiy Kolodyazhnyy
4

Comentário temporário

  1. A pedido do OP, fiz o script abaixo desligar a tela por meio de xrandr. Em um teste mais longo, isso funcionou muito mal. Não muito o desligamento falhou, mas ao reativar a tela, o layout da tela estava totalmente bagunçado. Ficaria feliz em publicá-lo para ver se ele funciona no seu caso, mas meu conselho é não usá-lo.
    No script, voltei a definir o brilho como zero.
  2. Houve alguma discussão sobre se devemos definir o monitor ativo por localização do mouse ou por localização da janela ativa . O último não funcionará se não existir uma janela. Talvez não tenhamos uma janela (exceto a própria área de trabalho). Nesse caso, a escolha da janela para ocultar seria aleatória (ou quebrada, se não incluirmos a exceção). A IMO, a única opção que faz sentido - e funcionaria de maneira previsível em todos os casos - é definir a tela ativa pela posição do mouse. Além disso, é assim que o gerenciador de janelas decide onde novas janelas devem aparecer.

Então, o que eu mudei nesta versão?
O tempo ocioso agora é definido pela atividade do teclado e do mouse por padrão. Acordar também é feito por qualquer um.


Escurecer automaticamente a tela inativa

Como dito pelos meus colegas respondentes, desligar as telas do CLI separadamente é um desafio, na melhor das hipóteses, e também não encontrei uma opção.

O que eu encontrei é uma maneira de escurecer automaticamente todas as telas, exceto aquela em que o mouse está, após o tempo x.

Aqui vamos nós

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

Como configurar

A configuração é simples:

  1. Verifique se você possui os dois python3-gie xprintidleinstalou

    sudo apt install python3-gi xprintidle
    
  2. Copie o script acima em um arquivo vazio, salve-o como dim_inactivee torne-o executável

  3. Execute-o pelo comando:

    /path/to/dim_inactive <idle_time_in_seconds>
    

    um exemplo:

    /path/to/dim_inactive 120
    

    escurecerá todas as telas em que o mouse não estiver após dois minutos

Informações / explicações adicionais

  • O script lista todas as telas na inicialização
  • Ele mantém o registro se o tempo ocioso por monitor (possivelmente mais de 2). Se um monitor não for acessado por x segundos, ele ficará oculto, exceto pelo monitor em que o mouse está .
  • De acordo com uma boa (mas ruim) tradição, o Gnome continua quebrando coisas e mudando as APIs. Como resultado, ao executar este script em 19.04 e acima, você receberá alguns avisos preteridos. Ao mesmo tempo, não quebra no PEP8. No entanto, atualizará para as APIs mais recentes.
Jacob Vlijm
fonte
Muito bom, quase tentado a escrever algo assim também. Mas eu acho que é o tema repetido aqui - até agora não há nada melhor do que escurecimento outro monitor através de soluções de software, nada hardware-ish
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy Nah, apenas a luz de fundo adicionaria algo, mas é isso até onde eu posso ver agora. Acho que algo deveria ser possível, mas provavelmente terá um começo frio, como xrandr --offeu acho.
Jacob Vlijm 28/03/19
@JacobVlijm Sim, xrandr --offé o que eu preferiria neste caso. Especialmente porque a luz de fundo VGA não pode ser controlada por software.
Sergiy Kolodyazhnyy 28/03/19
Obrigado por todos os seus esforços, mas estou tendo os comportamentos mais estranhos ... Por exemplo: escurece os monitores, mas não redefine o brilho 1em nenhuma circunstância. Quando estou interagindo com a tela externa usando o teclado e enquanto o mouse está na tela principal, o externo fica preto após o tempo ocioso. Quando não tenho interação com a tela principal, mas o mouse está lá, ele não faz nada e, quando movo o mouse para outra tela principal, um fica iminentemente preto.
Ravexina 30/03/19
@Ravex (1) seus monitores são espelhados? Caso contrário, você pode ter parado o script com a segunda tela bloqueada. Corrigido isso agora. (2) Por que a tela ativa é definida, meus mousepos são explicados em [2] do comentário temporário (3) Também deve ser corrigido com as alterações em (1) (mesma causa) Ah, não, é necessário redefinir o tempo ocioso hoje mais tarde.
Jacob Vlijm 30/03/19