Solucione el escalado de aplicaciones basadas en Java para una pantalla de DPI alto

24

Hay algunas aplicaciones (principalmente basadas en Java) que no siguen la escala global 2x que configuré en la configuración de la pantalla. Entonces, estas aplicaciones son realmente pequeñas en mi pantalla de DPI alto con 3200x1800px.

¿Cómo puedo hacer que estas aplicaciones se ejecuten en una resolución de pantalla más pequeña?

rubo77
fuente
Idea / Android Studio tiene un error abierto y posiblemente una solución aquí: code.google.com/p/android/issues/detail?id=68781
Anton
es exactamente el mismo problema, pero tampoco encontré una solución allí.
rubo77
¿Has intentado ejecutar AS / Idea con -Dis.hidpi = clave verdadera en la línea de comandos? No es una solución general, de todos modos, pero espero que ayude.
Anton
Cambié esto al final en data/bin/studio.sh: eval "$JDK/bin/java" $ALL_JVM_ARGS -Djb.restart.code=88 -Dis.hidpi=true $MAIN_CLASS_NAME "$@"- pero sin efecto
rubo77
Agregué una versión "dinámica", cambiando la resolución por ventana. También debería funcionar bien con alt-tab.
Jacob Vlijm

Respuestas:

15

Una actualización de conveniencia importante sería usar un script de fondo, configurando automáticamente la resolución por aplicación , mientras que puede establecer diferentes resoluciones para diferentes (múltiples) aplicaciones a la vez.

Eso es exactamente lo que hace el siguiente script.

Un ejemplo de una resolución predeterminada de 1680x1050:

ingrese la descripción de la imagen aquí

En ejecución gedit, cambiando automáticamente a 640x480:

ingrese la descripción de la imagen aquí

En ejecución gnome-terminal, cambiando automáticamente a 1280x1024:

ingrese la descripción de la imagen aquí

Cuando se cierra la aplicación, la resolución se vuelve a establecer automáticamente en 1680x1050

Cómo utilizar

  1. Copie el script a continuación en un archivo vacío, guárdelo como set_resolution.py
  2. En el encabezado del script, establezca su resolución predeterminada, en la línea:

    #--- set the default resolution below
    default = "1680x1050"
    #---
  3. En el mismo directorio (carpeta), crear un archivo de texto, exactamente llamado: procsdata.txt. En este archivo de texto, configure la aplicación o proceso deseado, seguido de un espacio, seguido de la resolución deseada. Una aplicación o script por línea, que se ve así:

    gedit 640x480
    gnome-terminal 1280x1024
    java 1280x1024

    ingrese la descripción de la imagen aquí

  4. Ejecute el script con el comando:

    python3 /path/to/set_resolution.py

Nota

El uso del script pgrep -f <process>, que captura todas las coincidencias, incluidos los scripts. La posible desventaja es que puede causar conflictos de nombres al abrir un archivo con el mismo nombre que el proceso.
Si tiene problemas como ese, cambie:

matches.append([p, subprocess.check_output(["pgrep", "-f", p]).decode("utf-8")])

dentro:

matches.append([p, subprocess.check_output(["pgrep", p]).decode("utf-8")])

La secuencia de comandos

#!/usr/bin/env python3
import subprocess
import os
import time

#--- set the default resolution below
default = "1680x1050"
#---

# read the datafile
curr_dir = os.path.dirname(os.path.abspath(__file__))
datafile = curr_dir+"/procsdata.txt"
procs_data = [l.split() for l in open(datafile).read().splitlines() if not l == "\n"]
procs = [pdata[0] for pdata in procs_data]

def check_matches():
    # function to find possible running (listed) applications
    matches = []
    for p in procs:
        try:
            matches.append([p, subprocess.check_output(["pgrep", "-f", p]).decode("utf-8")])
        except subprocess.CalledProcessError:
            pass
    match = matches[-1][0] if len(matches) != 0 else None
    return match

matches1 = check_matches()

while True:
    time.sleep(2)
    matches2 = check_matches()
    if matches2 == matches1:
        pass
    else:
        if matches2 != None:
            # a listed application started up since two seconds ago
            resdata = [("x").join(item[1].split("x")) for item in \
                       procs_data if item[0] == matches2][0]
        elif matches2 == None:
            # none of the listed applications is running any more
            resdata = default
        subprocess.Popen(["xrandr", "-s", resdata])
    matches1 = matches2
    time.sleep(1)

Explicación

Cuando se inicia el script, lee el archivo en el que definió sus aplicaciones y sus correspondientes resoluciones de pantalla deseadas.

Luego vigila los procesos en ejecución (en ejecución pgrep -f <process> para cada una de las aplicaciones) y establece la resolución si la aplicación se inicia.

Cuando pgrep -f <process>no produce resultados para ninguna de las aplicaciones enumeradas, establece la resolución en "predeterminada".


Editar:

Versión "dinámica" (según lo solicitado)

Si bien la versión anterior funciona con varias aplicaciones enumeradas, solo establece la resolución para una aplicación a la vez .

La siguiente versión puede manejar diferentes aplicaciones con una resolución diferente (requerida), ejecutándose al mismo tiempo. El script de fondo hará un seguimiento de cuál es la aplicación más avanzada y establecerá la resolución en consecuencia. También funciona bien con Alt+Tab .

Tenga en cuenta que este comportamiento puede ser molesto si cambia mucho entre el escritorio y las aplicaciones enumeradas; El cambio de resolución frecuente puede ser demasiado.

diferencias en cómo configurar

La configuración es más o menos la misma, aparte del hecho de que esta usa wmctrly xdotool:

sudo apt-get install wmctrl
sudo apt-get install xdotool

La secuencia de comandos

#!/usr/bin/env python3
import subprocess
import os
import sys
import time

#--- set default resolution below
resolution = "1680x1050"
#---

curr_dir = os.path.dirname(os.path.abspath(__file__))
datafile = curr_dir+"/procsdata.txt"
applist = [l.split() for l in open(datafile).read().splitlines()]
apps = [item[0] for item in applist]

def get(cmd):
    try:
        return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
    except subprocess.CalledProcessError:
        pass

def get_pids():
    # returns pids of listed applications; seems ok
    runs = []
    for item in apps:
        pid = get("pgrep -f "+item)
        if pid != None:
            runs.append((item, pid.strip()))    
    return runs

def check_frontmost():
    # returns data on the frontmost window; seems ok
    frontmost = str(hex(int(get("xdotool getwindowfocus").strip())))
    frontmost = frontmost[:2]+"0"+frontmost[2:]
    try:
        wlist = get("wmctrl -lpG").splitlines()
        return [l for l in wlist if frontmost in l]
    except subprocess.CalledProcessError:
        pass

def front_pid():
    # returns the frontmost pid, seems ok
    return check_frontmost()[0].split()[2]

def matching():
    # nakijken
    running = get_pids(); frontmost = check_frontmost()
    if all([frontmost != None, len(running) != 0]):
        matches = [item[0] for item in running if item[1] == frontmost[0].split()[2]]
        if len(matches) != 0:
            return matches[0]
    else:
        pass

trigger1 = matching()

while True:
    time.sleep(1)
    trigger2 = matching()
    if trigger2 != trigger1:
        if trigger2 == None:
            command = "xrandr -s "+resolution
        else:
            command = "xrandr -s "+[it[1] for it in applist if it[0] == trigger2][0]
        subprocess.Popen(["/bin/bash", "-c", command])
        print(trigger2, command)
    trigger1 = trigger2

Notas

  • Aunque lo tengo funcionando durante varias horas sin un error ahora, pruébelo a fondo. Si se produce un error, deje un comentario.
  • El script, tal como está, funciona en una configuración de monitor único.
Jacob Vlijm
fuente
@ rubo77 El script, tal como está, supone que solo una de las aplicaciones se ejecuta a la vez. Si se ejecutan varias aplicaciones enumeradas, elige una, para evitar demasiados cambios de resolución seguidos, ya que también cambiar al escritorio provocaría un cambio de resolución. Sin embargo, puedo cambiar eso. Estableceré como una opción.
Jacob Vlijm
Puede usar este comando para averiguar el nombre de una aplicación que desea agregar al archivo de configuración: sleep 5 && cat "/proc/$(xdotool getwindowpid "$(xdotool getwindowfocus)")/comm"enfoque la aplicación en 5 segundos y obtenga el nombre deseado (fuente: askubuntu.com/a/508539/34298 )
rubo77
Discusión adicional en el rastreador de problemas en github.com/rubo77/set_resolution.py
rubo77
1
Este script tiene una actualización que resuelve muchos problemas en github.com/rubo77/set_resolution.py
rubo77
¿Podrías mirar esto y decirme si crees que está relacionado? askubuntu.com/questions/742897/…
Kalamalka Kid
3

Pruebe agregar a su línea de comando java: -Dsun.java2d.uiScale=2.0o configúrelo en el factor de escala que desee.

epineda
fuente
2

Como una solución

Creé un script bash que cambia la resolución a fullHD antes de que inicie la aplicación (en este ejemplo, Android Studio) y la cambia de nuevo a 3200x1800 cuando la aplicación se cierra:

sudo nano /usr/local/bin/studio

Ingrese este script:

#!/bin/bash
# set scaling to x1.0
gsettings set org.gnome.desktop.interface scaling-factor 1
gsettings set com.ubuntu.user-interface scale-factor "{'HDMI1': 8, 'eDP1': 8}"
xrandr -s 1920x1080
# call your program
/usr/share/android-studio/data/bin/studio.sh
# set scaling to x2.0
gsettings set org.gnome.desktop.interface scaling-factor 2
gsettings set com.ubuntu.user-interface scale-factor "{'HDMI1': 8, 'eDP1': 16}"
xrandr -s 3200x1800

y darle derechos de ejecución:

sudo chmod +x /usr/local/bin/studio

Entonces puedes comenzar con Alt+F1 studio


Para otros factores de cambio de tamaño que 2.0 ver /ubuntu//a/486611/34298


Para activar y desactivar fácilmente el zoom en Firefox, use la extensión Elementos del menú Zoom

rubo77
fuente