Skip to main content
 首页 » 编程设计

python之使用 python-wnck 生成和移动后窗口位置稍微偏离

2025年05月04日10Leo_wl

我制作了这个 Python 脚本:

from gi.repository import Gtk, Gdk, GdkX11, Wnck 
from subprocess import PIPE, Popen 
 
 
class WindowError(Exception): 
    pass 
 
 
def undecorate(aWindow): 
    gdkdis = GdkX11.X11Display.get_default() 
    gdkwin = GdkX11.X11Window.foreign_new_for_display(gdkdis, aWindow.get_xid()) 
    gdkwin.set_decorations(Gdk.WMDecoration.BORDER) 
 
def dropdown(aTitle): 
    Gtk.main_iteration() 
 
    screen = Wnck.Screen.get_default() 
    screen.force_update() 
 
    for window in screen.get_windows(): 
        if window.get_name() == aTitle: 
            timestamp = Gtk.get_current_event_time() 
 
            undecorate(window) 
 
            window.set_skip_pager(True) 
            window.set_skip_tasklist(True) 
            window.stick() 
            window.pin() 
 
            window.maximize_horizontally() 
            window.set_geometry(Wnck.WindowGravity.STATIC,  
                                Wnck.WindowMoveResizeMask.Y,  
                                0, 0, -1, -1) 
 
            window.activate(timestamp) 
            window.unminimize(timestamp) 
 
            break 
    else: 
        raise WindowError('Window with title "{}" not found'.format(aTitle)) 
 
def getActive(): 
    Gtk.main_iteration() 
 
    screen = Wnck.Screen.get_default() 
    screen.force_update() 
 
    return screen.get_active_window() 
 
 
def main(): 
    active = getActive() 
 
    if active.get_name() == 'Dropdown Terminal': 
        if active.is_minimized(): 
            dropdown('Dropdown Terminal') 
        else: 
            active.minimize() 
            return 
    else: 
        try: 
            dropdown('Dropdown Terminal') 
        except WindowError: 
            Popen(['roxterm', '--profile=Dropdown'], stdout=PIPE, stderr=PIPE) 
            dropdown('Dropdown Terminal') 
 
 
if __name__ == "__main__": 
    main() 

它的作用是让 roxterm 像 Guake 一样工作。我遇到的唯一问题是当我打开一个新的 roxterm 实例并将窗口移动到 (0,0) 时,窗口的最终 y 位置向下几个可见像素。我使用 wnck 库中的 set_geometry 函数来执行此操作。关于如何解决它的任何想法?谢谢。

请您参考如下方法:

糟糕,忘了说我已经解决了这个问题。我更改了代码中的一些内容,但我认为使用 GdkWindow 来重新定位而不是 Wnck 可以解决定位问题。此版本使下拉终端保持打开状态,直到再次按下热键。顺便说一句,我通过在 Gnome 的键盘首选项中添加自定义热键将热键映射到此脚本。

from gi.repository import Gtk, Gdk, GdkX11, Wnck 
from subprocess import PIPE, Popen 
 
 
class WindowError(Exception): 
    pass 
 
 
def getScreen(): 
    Gtk.main_iteration() 
 
    screen = Wnck.Screen.get_default() 
    screen.force_update() 
 
    return screen 
 
def getGDKWindow(aWindow): 
    gdkdisplay = GdkX11.X11Display.get_default() 
    gdkwindow  = GdkX11.X11Window.foreign_new_for_display(gdkdisplay, aWindow.get_xid()) 
 
    return gdkwindow 
 
def getWindow(aTitle): 
    screen = getScreen() 
    active = screen.get_active_window() 
 
    if active.get_name() == aTitle: 
        return active 
 
    for window in screen.get_windows(): 
        if window.get_name() == aTitle: 
            return window 
 
    return None 
 
def adjust(aWindow): 
    gdkwindow = getGDKWindow(aWindow) 
 
    gdkwindow.set_decorations(Gdk.WMDecoration.BORDER) 
    gdkwindow.move(0,0) 
 
    aWindow.set_skip_pager(True) 
    aWindow.set_skip_tasklist(True) 
 
    aWindow.maximize_horizontally() 
 
    aWindow.stick() 
    aWindow.make_above() 
 
 
def onWindowOpen(aScreen, aWindow, aData): 
    if aWindow.get_name() == aData: 
        adjust(aWindow) 
 
        Gtk.main_quit() 
 
 
def main(): 
    timestamp = Gtk.get_current_event_time() 
    window      = getWindow('Dropdown Terminal') 
 
    if window: 
        if window.is_minimized(): 
            window.activate(timestamp) 
            window.unminimize(timestamp) 
        else: 
            window.minimize() 
    else: 
        Popen(['roxterm', '--separate', '--profile=Dropdown', '--directory=.']) 
 
        getScreen().connect('window-opened', onWindowOpen, 'Dropdown Terminal') 
 
        Gtk.main() 
 
 
if __name__ == "__main__": 
    main()