在多显示器设置中,如何防止新窗口放错位置(顶部栏被隐藏)?

在多显示器设置中,如何防止新窗口放错位置(顶部栏被隐藏)?

我正在使用 Ubuntu 18.04 桌面和默认的图像查看器软件。

有一个奇怪而又令人沮丧的情况,当我打开特定尺寸的图像(今天是 960x960)时,窗口会总是出现在我的左上角次要的屏幕顶部的栏(我们用来拖动它的栏,我不记得它的名字了)像这样隐藏起来在此处输入图片描述 我使用一对屏幕,左侧的大屏幕作为主屏幕,右侧的小屏幕作为辅助屏幕。侧边栏位于辅助屏幕中。

奇怪的是其他尺寸,如 400x400在此处输入图片描述或 1920x1200在此处输入图片描述很好。

所以我的问题是,是否可以使其在当前显示器中打开且顶部栏不丢失?

答案1

有报告称,当两个显示器未在顶部对齐时,窗口会被裁剪:

屏幕显示.png

为了确认它们沿着顶部完美排列,请使用xrandr

$ xrandr | grep " connected" | grep "+0"

HDMI-0 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 1107mm x 623mm
DP-1-1 connected 3840x2160+1920+0 (normal left inverted right x axis y axis) 1600mm x 900mm

确认+0两个显示器均已对齐至顶部。

答案2

我们只能猜测问题的原因,但我不知道如何真正解决问题。不过,我们可以通过一种变通方法修复错误的窗口位置。

原则

这个类似守护进程的小进程将等待在任何显示器上创建任何窗口,并“负面”展示位置(x 或 y),并将其移动到相应显示器上 x=80px、y=80px 的位置:

在此处输入图片描述

它通过查看新创建的窗口的东南角来实现这一点。东南角被认为是它应该完全放置在的显示器上。窗口西北角的位置是触发操作(将窗口移到更好的位置)或保留窗口的触发器:它不应该位于东南角所在的显示器的左侧或上方。

在所有其他情况下,窗口将完全保留。请注意:

  • 这个过程不会造成任何负担,它只是在等待时机发生,只有当新窗口放错位置时才会采取行动(而不是轮询过程)。
  • 由于我没有三台显示器,因此我无法按照您的设置进行测试。不过我预计不会出现任何问题。
  • 该过程是可扩展的,依靠 Wnck 和 Gdk 之间的“翻译”来处理扩展。

代码

#!/usr/bin/env python3

import gi
gi.require_version("Gtk", "3.0")
gi.require_version("Wnck", "3.0")
from gi.repository import Gtk, Wnck, Gdk

class WatchOut:
    def __init__(self):
        self.wnckscr = Wnck.Screen.get_default()
        self.gdkdsp = Gdk.Display.get_default()
        self.wnckscr.connect("window_opened", self.checkonwin)
        Gtk.main()

    def actoncreate(self, window):
        wingeo = window.get_geometry();
        # get window geo, take SE as reference, abs numbers
        nw_x = wingeo.xp
        nw_y = wingeo.yp
        se_x = nw_x + wingeo.widthp
        se_y = nw_y + wingeo.heightp
        # get scale
        defmon = self.gdkdsp.get_primary_monitor()
        scale = defmon.get_scale_factor()
        # get monitor with window, gdk uses scaled(!)
        currmon = self.gdkdsp.get_monitor_at_point(se_x/scale, se_y/scale)
        # gdk uses scaled numbers!
        mongeo = currmon.get_geometry() 
        mondata = [n * scale for n in [
            mongeo.x, mongeo.y, mongeo.width, mongeo.height
        ]]
        # check if action is needed, calc in abs numbers!
        # if winx < monitorx -and/or- winy < monitory, move window
        if any([nw_x < mondata[0], nw_y < mondata[1]]):
            self.move(
                window, mondata[0] + 80, mondata[1] + 80, 700, 700
            )

    def move(self, win, x, y, w, h):
        g = Wnck.WindowGravity.NORTHWEST
        flags = Wnck.WindowMoveResizeMask.X | \
            Wnck.WindowMoveResizeMask.Y | \
            Wnck.WindowMoveResizeMask.WIDTH | \
            Wnck.WindowMoveResizeMask.HEIGHT
        win.set_geometry(g, flags, x, y, w, h)

    def checkonwin(self, scr, newwin):
        if newwin.get_window_type () == Wnck.WindowType.NORMAL:
            self.actoncreate(newwin)

WatchOut()

如何使用

  1. 将上述代码复制到一个空文件中,保存为watchout.py
  2. 使用以下命令从终端进行测试运行:

    python3 /path/to/watchout.py
    

    尝试打开具有错误位置的应用程序,从您的问题来看,这应该是相当可预测的。

  3. 如果一切正常,请将其添加到启动应用程序中。您可能需要在启动该过程之前设置一个小中断,以确保它不会在未完成的桌面加载时中断。

相关内容