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?


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.

@ 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.


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.