Исправить масштабирование Java-приложений для экрана с высоким DPI

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

Как я могу заставить эти приложения работать с меньшим разрешением экрана?

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

    Это именно то, что делает сценарий ниже.

    Пример разрешения по умолчанию 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> не производит вывод для любого из перечисленных приложений, он устанавливает разрешение «default».


    Редактировать:

    «Динамическая» версия (по запросу)

    Хотя приведенная выше версия работает с несколькими перечисленными приложениями, она только устанавливает разрешение для одного приложения за раз .

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

    Обратите внимание, что это поведение может быть раздражающим, если вы много переключаете между рабочим столом и перечисленными приложениями; частой переключатель разрешения может быть слишком большим.

    различия в настройке

    Настройка примерно такая же, appart из того факта, что этот использует 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 

    Заметки

    • Несмотря на то, что у меня он работает в течение нескольких часов без ошибок, пожалуйста, тщательно протестируйте его. Если произошла ошибка, оставьте комментарий.
    • Сценарий – он работает на одной настройке монитора.

    Как обходной путь

    Я создал сценарий bash, который меняет разрешение на fullHD до того, как он запустит приложение (на этом примере Android Studio) и изменит его на 3200×1800, когда приложение завершает работу:

     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 

    Затем вы можете запустить его с studio Alt + F1


    Для других коэффициентов изменения размера, которые см. На странице https://askubuntu.com/a/486611/34298


    Для простого включения и выключения трансфокатора в Firefox используйте элементы меню Zoom Zoom