Napraw skalowanie aplikacji opartych na Javie dla ekranu o wysokiej DPI

24

Niektóre aplikacje (głównie oparte na Javie) nie są zgodne z globalną skalą 2x, którą ustawiłem w ustawieniach ekranu. Więc te aplikacje są naprawdę małe na moim ekranie o wysokiej DPI z rozdzielczością 3200x1800px.

Jak mogę uruchomić te aplikacje w mniejszej rozdzielczości ekranu?

rubo77
źródło
Idea / Android Studio ma otwarty błąd i możliwe rozwiązanie tutaj: code.google.com/p/android/issues/detail?id=68781
Anton
to dokładnie ten sam problem, ale ja też nie znalazłem rozwiązania.
rubo77
Czy próbowałeś uruchomić AS / Idea z -Dis.hidpi = true klucz w linii poleceń? W każdym razie nie jest to ogólne rozwiązanie, ale mam nadzieję, że to pomoże.
Anton
Zmieniłem to na końcu w data/bin/studio.sh: eval "$JDK/bin/java" $ALL_JVM_ARGS -Djb.restart.code=88 -Dis.hidpi=true $MAIN_CLASS_NAME "$@"- ale bez efektu
rubo77
Dodałem wersję „dynamiczną”, zmieniając rozdzielczość na okno. Powinno także działać poprawnie z klawiszem Alt-Tab.
Jacob Vlijm

Odpowiedzi:

15

Ważnym ulepszeniem byłoby użycie skryptu w tle, automatycznie ustawiającego rozdzielczość dla każdej aplikacji , podczas gdy można ustawić różne rozdzielczości dla różnych (wielu) aplikacji jednocześnie.

To właśnie robi poniższy skrypt.

Przykład domyślnej rozdzielczości 1680x1050:

wprowadź opis zdjęcia tutaj

Uruchomiony gedit, automatycznie zmienia się na 640x480:

wprowadź opis zdjęcia tutaj

Uruchomiony gnome-terminal, automatycznie zmienia się na 1280x1024:

wprowadź opis zdjęcia tutaj

Po zamknięciu aplikacji rozdzielczość jest automatycznie przywracana do 1680x1050

Jak używać

  1. Skopiuj poniższy skrypt do pustego pliku i zapisz go jako set_resolution.py
  2. W nagłówku skryptu ustaw domyślną rozdzielczość w wierszu:

    #--- set the default resolution below
    default = "1680x1050"
    #---
  3. W tym samym katalogu (folderu), utwórz plik tekstowy, dokładnie o nazwie: procsdata.txt. W tym pliku tekstowym ustaw żądaną aplikację lub proces, następnie spację, a następnie żądaną rozdzielczość. Jedna aplikacja lub skrypt na wiersz, wyglądający jak:

    gedit 640x480
    gnome-terminal 1280x1024
    java 1280x1024

    wprowadź opis zdjęcia tutaj

  4. Uruchom skrypt za pomocą polecenia:

    python3 /path/to/set_resolution.py

Uwaga

Zastosowanie skryptu pgrep -f <process>, który przechwytuje wszystkie dopasowania, w tym skrypty. Możliwym minusem jest to, że może powodować konflikty nazw podczas otwierania pliku o tej samej nazwie co proces.
Jeśli napotkasz takie problemy, zmień:

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

w:

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

Scenariusz

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

Wyjaśnienie

Po uruchomieniu skryptu odczytuje plik, w którym zdefiniowałeś aplikacje i odpowiadające im pożądane rozdzielczości ekranu.

Następnie śledzi uruchomione procesy (działające pgrep -f <process>dla każdej aplikacji) i ustawia rozdzielczość, jeśli aplikacja się uruchomi.

Gdy pgrep -f <process>nie generuje danych wyjściowych dla żadnej z wymienionych aplikacji, ustawia rozdzielczość na „domyślną”.


Edytować:

Wersja „dynamiczna” (na żądanie)

Chociaż powyższa wersja działa z wieloma wymienionymi aplikacjami, ustawia rozdzielczość tylko dla jednej aplikacji na raz .

Poniższa wersja może obsługiwać różne aplikacje o innej (wymaganej) rozdzielczości, działające jednocześnie. Skrypt w tle śledzi, która aplikacja znajduje się na pierwszym planie, i odpowiednio ustawia rozdzielczość. Działa również dobrze z Alt+ Tab.

Zauważ, że takie zachowanie może być denerwujące, jeśli często przełączasz się między aplikacjami na pulpicie a aplikacjami z listy; częsty przełącznik rozdzielczości może być za duży.

różnice w konfiguracji

Konfiguracja jest prawie taka sama, poza tym, że ta używa wmctrli xdotool:

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

Scenariusz

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

Notatki

  • Chociaż mam go teraz przez kilka godzin bez błędu, proszę go dokładnie przetestować. Jeśli wystąpi błąd, zostaw komentarz.
  • Skrypt - jak to działa - działa na konfiguracji z jednym monitorem.
Jacob Vlijm
źródło
@ rubo77 Skrypt, jak to jest, zakłada, że ​​tylko jedna aplikacja działa jednocześnie. Jeśli uruchomionych jest wiele aplikacji wymienionych na liście, wybiera jedną, aby zapobiec zbyt dużej liczbie przełączników rozdzielczości w jednym rzędzie, ponieważ przełączenie na pulpit spowodowałoby wówczas przełączenie rozdzielczości. Mogę to jednak zmienić. Ustawię jako opcję.
Jacob Vlijm
Możesz użyć tego polecenia, aby ustalić nazwę aplikacji, którą chcesz dodać do pliku konfiguracyjnego sleep 5 && cat "/proc/$(xdotool getwindowpid "$(xdotool getwindowfocus)")/comm": ustaw ostrość w ciągu 5 sekund, a otrzymasz żądaną nazwę (źródło: askubuntu.com/a/508539/34298 )
rubo77
dalsza dyskusja u emitenta w github.com/rubo77/set_resolution.py
rubo77
1
Ten skrypt ma aktualizację, która rozwiązuje wiele problemów na github.com/rubo77/set_resolution.py
rubo77
czy mógłbyś na to spojrzeć i powiedzieć, czy uważasz, że jest to powiązane? askubuntu.com/questions/742897/…
Kalamalka Kid
3

Przetestuj dodawanie do wiersza polecenia Java: -Dsun.java2d.uiScale=2.0lub ustaw odpowiedni współczynnik skali.

epineda
źródło
2

Jako obejście

Utworzyłem skrypt bash, który zmienia rozdzielczość na fullHD przed uruchomieniem aplikacji (w tym przykładzie Android Studio) i zmienia ją z powrotem na 3200 x 1800, gdy aplikacja zostanie zamknięta:

sudo nano /usr/local/bin/studio

Wpisz ten skrypt:

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

i nadać mu prawa do wykonywania:

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

Następnie możesz zacząć od Alt+F1 studio


Dla innych współczynników zmiany wielkości, które 2.0 zobacz /ubuntu//a/486611/34298


Aby łatwo włączać i wyłączać powiększanie w przeglądarce Firefox, użyj rozszerzenia Zoom Menu Elements

rubo77
źródło