ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

修复基于java的应用程序在高DPI屏幕上的缩放

2019-08-07 17:10:08  阅读:820  来源: 互联网

标签:java resolution dpi scale-mode


有些应用程序(主要是基于java的)不遵循我在屏幕设置中设置的global 2x scale.所以这些应用程序在我的高DPI屏幕上非常小,3200x1800px.

如何以较小的屏幕分辨率运行这些应用程序?

解决方法:

一个主要的便利升级是使用后台脚本,自动设置每个应用程序的分辨率,同时可以一次为不同(多个)应用程序设置不同的分辨率.

这正是下面的脚本所做的.

默认分辨率为1680×1050的示例:

运行gedit,自动更改为640×480:

运行gnome-terminal,自动更改为1280×1024:

关闭应用程序后,分辨率将自动设置为1680×1050

如何使用

>将以下脚本复制到空文件中,将其另存为set_resolution.py
>在脚本的开头,在行中设置默认分辨率:

#--- set the default resolution below
default = "1680x1050"
#---

>在同一目录(文件夹)中,创建一个文本文件,名称为:procsdata.txt.在此文本文件中,设置所需的应用程序或进程,后跟空格,然后是所需的分辨率.每行一个应用程序或脚本,如下所示:

gedit 640x480
gnome-terminal 1280x1024
java 1280x1024

>通过命令运行脚本:

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

笔记

>虽然我现在运行了几个小时没有错误,但请彻底测试.如果可能发生错误,请发表评论.
>脚本 – 它在单个监视器设置上工作.

标签:java,resolution,dpi,scale-mode
来源: https://codeday.me/bug/20190807/1612384.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有