Виправте масштабування програм на базі Java для екрана з високим рівнем DPI


24

Є деякі програми (в основному на основі Java), які не відповідають глобальній 2x масштабі, яку я встановив у налаштуваннях екрана. Тож ці програми справді крихітні на моєму високому екрані DPI з 3200x1800px.

Як можна запустити ці програми в меншій роздільній здатності екрана?


У Idea / Android Studio відкрито помилку та можливо вирішити тут: code.google.com/p/android/isissue/detail?id=68781
Антон

Точно те саме питання, але я також не знайшов рішення.
rubo77

Ви спробували запустити AS / Idea за допомогою -Dis.hidpi = true ключ у командному рядку? Це все-таки не загальне рішення, але я сподіваюся, що це допоможе.
Антон

Я змінив це наприкінці data/bin/studio.sh: eval "$JDK/bin/java" $ALL_JVM_ARGS -Djb.restart.code=88 -Dis.hidpi=true $MAIN_CLASS_NAME "$@"- але жодного ефекту
rubo77

Я додав "динамічну" версію, змінюючи роздільну здатність для кожного вікна. Він також повинен добре працювати з клавішею Alt.
Яків Влійм

Відповіді:


15

Основним зрушенням зручності було б використання фонового скрипту, автоматично встановлюючи роздільну здатність для кожної програми , в той час як ви можете встановлювати різні дозволи для різних (декількох) додатків одночасно.

Саме це робить сценарій нижче.

Приклад роздільної здатності за замовчуванням1680x1050 :

введіть тут опис зображення

Запуск gedit, автоматично змінюється на 640x480:

введіть тут опис зображення

Запуск gnome-terminal, автоматично змінюється на 1280x1024:

введіть тут опис зображення

Коли програма закрита, роздільна здатність автоматично повертається до 1680x1050

Як користуватись

  1. Скопіюйте сценарій нижче в порожній файл, збережіть його як set_resolution.py
  2. У голові сценарію встановіть роздільну здатність за замовчуванням у рядку:

    #--- set the default resolution below
    default = "1680x1050"
    #---
  3. У тій же директорії (папці), створіть текстовий файл, точно під назвою: procsdata.txt. У цьому текстовому файлі встановіть потрібну програму чи процес, після чого пробіл, а потім бажану роздільну здатність. Одне додаток або сценарій на рядок, виглядає так:

    gedit 640x480
    gnome-terminal 1280x1024
    java 1280x1024

    введіть тут опис зображення

  4. Запустіть скрипт командою:

    python3 /path/to/set_resolution.py

Примітка

Використання сценарію pgrep -f <process>, яке фіксує всі збіги, включаючи сценарії. Можливим недоліком є ​​те, що це може спричинити зіткнення імен під час відкриття файлу з тим самим іменем, що і процес.
Якщо у вас виникли подібні проблеми, змініть:

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

в:

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

Сценарій

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

Пояснення

Коли сценарій запускається, він зчитує файл, у якому ви визначили свої програми та відповідні потрібні роздільні можливості екрана.

Потім він слідкує за запущеними процесами (запущеними pgrep -f <process>для кожної програми) та встановлює роздільну здатність, якщо програма запускається.

Коли pgrep -f <process>не виробляється вихід для жодного із перелічених програм, вона встановлює роздільну здатність "за замовчуванням".


Редагувати:

"Динамічна" версія (за запитом)

Хоча версія вище працює з кількома переліченими програмами, вона встановлює роздільну здатність лише для однієї програми за один раз .

Версія нижче може обробляти різні програми з різною (необхідною) роздільною здатністю, яка працює одночасно. Фоновий скрипт буде відслідковувати те, що найбільше передній додаток, і відповідно встановлюватиме роздільну здатність. Також добре працює з Alt+ Tab.

Зауважте, що така поведінка може бути прикрою, якщо ви перемикаєтесь між робочим столом та переліченими програмами; перемикач частої роздільної здатності може бути занадто великим.

відмінності в налаштуванні

Настройка майже однакова, виходячи з того, що ця використовує wmctrlта xdotool:

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

Сценарій

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

Примітки

  • Хоча зараз я працюю протягом декількох годин без помилки, будь ласка, перевірити її ретельно. Якщо може статися помилка, залиште коментар.
  • Сценарій - як він є - працює на одній настройці монітора.

@ rubo77 Сценарій, як є, передбачає, що запускається лише одне з програм. Якщо запущено кілька перерахованих додатків, він вибирає одне, щоб запобігти занадто багато комутаторів роздільної здатності підряд, оскільки також перехід на робочий стіл призведе до перемикання роздільної здатності. Але я можу це змінити. Я поставлю як варіант.
Яків Влійм

Ви можете скористатися цією командою для з'ясування назви програми, яку ви хочете додати до конфігураційного файлу: sleep 5 && cat "/proc/$(xdotool getwindowpid "$(xdotool getwindowfocus)")/comm"зосередьте додаток протягом 5 секунд, і ви отримаєте потрібне ім'я (джерело: askubuntu.com/a/508539/34298 )
rubo77

подальше обговорення у Issetracker в github.com/rubo77/set_resolution.py
rubo77

1
Цей скрипт має оновлення, яке вирішує багато проблем на github.com/rubo77/set_resolution.py
rubo77

Ви можете, будь ласка, подивитись на це і сказати мені, чи вважаєте ви, що це пов'язано? askubuntu.com/questions/742897/…
Kalamalka Kid

3

Тестуйте додавання до вашого командного рядка java: -Dsun.java2d.uiScale=2.0або встановіть його на потрібний коефіцієнт масштабу.


2

Як вирішення

Я створив скрипт bash, який змінює роздільну здатність на fullHD перед запуском програми (на цьому іспиті Android Studio) і змінює його назад на 3200x1800, коли програма закриває:

sudo nano /usr/local/bin/studio

Введіть цей сценарій:

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

і надати їй виконуючі права:

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

Тоді ви можете почати це з Alt+F1 studio


Для інших факторів зміни розміру 2.0 див. Https://askubuntu.com/a/486611/34298


Для легкого вмикання та вимкнення масштабування у Firefox використовуйте розширення Елементи меню масштабування

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.