Korrektur der Skalierung von Java-basierten Anwendungen für einen hochauflösenden Bildschirm

24

Es gibt einige Anwendungen (hauptsächlich auf Java-Basis), die nicht der globalen 2x-Skala folgen, die ich in den Bildschirmeinstellungen festgelegt habe. Diese Apps sind auf meinem hochauflösenden Bildschirm mit 3200x1800px wirklich winzig .

Wie kann ich diese Apps in einer kleineren Bildschirmauflösung zum Laufen bringen?

rubo77
quelle
Idea / Android Studio hat einen Fehler und möglicherweise eine Lösung hier: code.google.com/p/android/issues/detail?id=68781
Anton
Das ist genau das gleiche Problem, aber ich habe auch dort keine Lösung gefunden.
Rubo77
Haben Sie versucht, AS / Idea mit -Dis.hidpi = true in der Befehlszeile auszuführen? Es ist sowieso keine allgemeine Lösung, aber ich hoffe, es wird helfen.
Anton
Ich änderte dies am Ende in data/bin/studio.sh: eval "$JDK/bin/java" $ALL_JVM_ARGS -Djb.restart.code=88 -Dis.hidpi=true $MAIN_CLASS_NAME "$@"- aber kein Effekt
rubo77
Ich habe eine "dynamische" Version hinzugefügt, die die Auflösung pro Fenster ändert. Es sollte auch gut funktionieren mit Alt-Tab.
Jacob Vlijm

Antworten:

15

Ein wichtiges Komfort-Upgrade wäre die Verwendung eines Hintergrundskripts, mit dem die Auflösung pro Anwendung automatisch festgelegt wird , während Sie verschiedene Auflösungen für verschiedene (mehrere) Anwendungen gleichzeitig festlegen können.

Genau das macht das folgende Skript.

Ein Beispiel für eine Standardauflösung von 1680x1050:

Bildbeschreibung hier eingeben

Läuft und geditwechselt automatisch zu 640x480:

Bildbeschreibung hier eingeben

Läuft und gnome-terminalwechselt automatisch zu 1280x1024:

Bildbeschreibung hier eingeben

Wenn die Anwendung geschlossen wird, wird die Auflösung automatisch auf zurückgesetzt 1680x1050

Wie benutzt man

  1. Kopieren Sie das folgende Skript in eine leere Datei und speichern Sie es unter set_resolution.py
  2. Stellen Sie im Kopf des Skripts Ihre Standardauflösung in der folgenden Zeile ein:

    #--- set the default resolution below
    default = "1680x1050"
    #---
  3. In dem gleichen Verzeichnis (Ordner), erstellen Sie eine Textdatei, genau benannt: procsdata.txt. Stellen Sie in dieser Textdatei die gewünschte Anwendung oder den gewünschten Prozess ein, gefolgt von einem Leerzeichen und der gewünschten Auflösung. Eine Anwendung oder ein Skript pro Zeile sieht folgendermaßen aus:

    gedit 640x480
    gnome-terminal 1280x1024
    java 1280x1024

    Bildbeschreibung hier eingeben

  4. Führen Sie das Skript mit folgendem Befehl aus:

    python3 /path/to/set_resolution.py

Hinweis

Die Skriptverwendung pgrep -f <process>, die alle Übereinstimmungen abfängt, einschließlich Skripten. Der mögliche Nachteil ist, dass es zu Namenskonflikten kommen kann, wenn eine Datei mit demselben Namen wie der Prozess geöffnet wird.
Wenn Sie auf solche Probleme stoßen, ändern Sie Folgendes:

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

in:

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

Das Drehbuch

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

Erläuterung

Beim Start des Skripts wird die Datei gelesen, in der Sie Ihre Anwendungen definiert haben, und die entsprechenden gewünschten Bildschirmauflösungen.

Anschließend werden die laufenden Prozesse (die pgrep -f <process>für jede Anwendung ausgeführt werden) überwacht und die Auflösung festgelegt, wenn die Anwendung gestartet wird.

Wenn pgrep -f <process>für keine der aufgelisteten Anwendungen eine Ausgabe erstellt wird, wird die Auflösung auf "Standard" gesetzt.


Bearbeiten:

"Dynamische" Version (wie gewünscht)

Während die obige Version mit mehreren aufgelisteten Anwendungen funktioniert, wird nur die Auflösung für jeweils eine Anwendung festgelegt .

Die folgende Version kann verschiedene Anwendungen mit einer unterschiedlichen (erforderlichen) Auflösung gleichzeitig ausführen. Das Hintergrundskript verfolgt die Anwendung mit der höchsten Priorität und stellt die Auflösung entsprechend ein. Es funktioniert auch gut mit Alt+ Tab.

Beachten Sie, dass dieses Verhalten möglicherweise ärgerlich ist, wenn Sie häufig zwischen dem Desktop und den aufgelisteten Anwendungen wechseln. Der Schalter für die häufige Auflösung ist möglicherweise zu viel.

Unterschiede in der Einrichtung

Das Setup ist ziemlich gleich, abgesehen von der Tatsache, dass dieses verwendet wmctrlund xdotool:

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

Das Drehbuch

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

Anmerkungen

  • Obwohl ich es jetzt mehrere Stunden ohne Fehler laufen habe, testen Sie es bitte gründlich. Falls ein Fehler auftreten sollte, hinterlassen Sie bitte einen Kommentar.
  • Das Skript funktioniert - wie es ist - auf einem einzelnen Monitor-Setup.
Jacob Vlijm
quelle
@ rubo77 Das Skript geht so wie es ist davon aus, dass nur eine der Anwendungen gleichzeitig ausgeführt wird. Wenn mehrere aufgelistete Anwendungen ausgeführt werden, wird eine ausgewählt, um zu verhindern, dass zu viele Auflösungsschalter hintereinander ausgeführt werden, da ein Wechsel zum Desktop dann auch zu einem Auflösungsschalter führen würde. Das kann ich aber ändern. Ich werde als Option einstellen.
Jacob Vlijm
Mit diesem Befehl können Sie den Namen einer App ermitteln, die Sie zur Konfigurationsdatei hinzufügen möchten: sleep 5 && cat "/proc/$(xdotool getwindowpid "$(xdotool getwindowfocus)")/comm"Fokussieren Sie die App innerhalb von 5 Sekunden und Sie erhalten den gewünschten Namen (Quelle: askubuntu.com/a/508539/34298 )
rubo77
weitere Diskussion am issuetracker in github.com/rubo77/set_resolution.py
rubo77
1
Dieses Skript enthält ein Update, das viele Probleme
behebt:
Könntest du dir das bitte ansehen und mir sagen, ob du denkst, dass es damit zusammenhängt? askubuntu.com/questions/742897/…
Kalamalka Kid
3

Testen Sie das Hinzufügen zu Ihrer Java-Befehlszeile: -Dsun.java2d.uiScale=2.0oder stellen Sie einen gewünschten Skalierungsfaktor ein.

epineda
quelle
2

Als Workaround

Ich habe ein Bash-Skript erstellt, das die Auflösung vor dem Start der Anwendung in fullHD ändert (in diesem Beispiel Android Studio) und beim Beenden der Anwendung wieder auf 3200x1800 zurücksetzt:

sudo nano /usr/local/bin/studio

Geben Sie dieses Skript ein:

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

und gib ihm ausführbare Rechte:

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

Dann können Sie es mit Alt+ startenF1 studio


Weitere Größenänderungsfaktoren für 2.0 finden Sie unter /ubuntu//a/486611/34298


Zum einfachen Ein- und Ausschalten des Zooms in Firefox verwenden Sie die Erweiterung Zoom Menu Elements

rubo77
quelle