如何判断全屏应用是否正在运行?

6 投票
3 回答
3039 浏览
提问于 2025-04-15 13:58

在Python中,有办法判断Linux上是否有全屏应用程序在运行吗?我觉得可能可以用Xlib来实现,但我还没找到具体的方法。

补充说明:我说的全屏是指整个屏幕上只有这个应用程序,比如说全屏游戏。

3 个回答

1

我只是更新一下Isaiah发的代码,因为那段代码对我来说没用。

这是一个初步版本,可以进一步简化。在我的测试中,这段代码运行得很好,它是一个叫做xkeysnail的项目的一部分,能够很好地获取窗口名称。

import sys
from time import sleep
import Xlib.display

def window_is_fullscreen(display=Xlib.display.Display()):
    """Check if window is fullscreen or not."""
    focused_window = display.get_input_focus().focus
    screen = display.screen()
    wm_info = win_width = get_focused_window_info(focused_window)
    win_width = get_focused_window_info(focused_window)['width']
    win_height = get_focused_window_info(focused_window)['height']
    reso = get_desktop_resolution(screen)
    # Desktop environments in general should appear in fullscreen,
    # generating false positives, a way to ignore them is necessary.
    if wm_info['class'] != 'xfdesktop':
        if win_width == reso['width'] and win_height == reso['height']:
            return True
        else:
            return False

def get_desktop_resolution(screen):
    """Get desktop resolution."""
    return {
        'width': screen.width_in_pixels, 
        'height': screen.height_in_pixels
    }

def get_focused_window_info(window):
    """Get info from focused window'"""
    wmname = window.get_wm_name()
    try:
        wmclass = window.get_wm_class()[0]
    except TypeError:
        wmclass = window.get_wm_class()
        pass
    wm_data = window.get_geometry()._data
    width = wm_data['width']
    height = wm_data['height']
    # workaround for Java app
    # https://github.com/JetBrains/jdk8u_jdk/blob/master/src/solaris/classes/sun/awt/X11/XFocusProxyWindow.java#L35
    if not wmclass and not wmname or "FocusProxy" in wmclass:
        parent_window = window.query_tree().parent
        if parent_window:
            return get_focused_window_info(parent_window)
    elif wmclass and wmname:
        return {'class': wmclass, 'name': wmname, 'width': width, 'height': height}
    elif wmclass and not wmname:
        return {'class': wmclass, 'width': width, 'height': height}
    elif not wmclass and wmname:
        return {'name': wmname, 'width': width, 'height': height}
    return None
    
while True:
    try:
        print(window_is_fullscreen(), end='\r')
        sleep(1)
    except KeyboardInterrupt:
        sys.exit(0)
5

如果你想运行的所有窗口管理器都支持一种叫做 EWMH 的标准,也就是扩展窗口管理器提示标准,那么有一些简单的方法可以做到这一点(比如通过 ctypes 和 Xlib 进行交互)。根窗口的 _NET_ACTIVE_WINDOW 属性可以告诉你哪个窗口是当前活动的窗口(如果有的话);而当前活动窗口的 _NET_WM_STATE 属性则是一个描述窗口状态的列表,如果这个窗口是全屏的,列表中会包含 _NET_WM_STATE_FULLSCREEN。当然,如果你有多个显示器,一个窗口可以在其中一个显示器上全屏,但并不一定是活动窗口;我相信还有其他情况,一个窗口可能全屏但并不是活动窗口——不过我觉得要覆盖所有这些情况,基本上需要对每个窗口检查一次 _NET_WM_STATE

3

找到了解决办法:

import Xlib.display

screen = Xlib.display.Display().screen()
root_win = screen.root

num_of_fs = 0
for window in root_win.query_tree()._data['children']:
    window_name = window.get_wm_name()
    width = window.get_geometry()._data["width"]
    height = window.get_geometry()._data["height"]

    if width == screen.width_in_pixels and height == screen.height_in_pixels:
        num_of_fs += 1

print num_of_fs

这个代码会输出全屏窗口的数量,对我来说通常是一个。当我在玩全屏游戏的时候,数量变成了两个。

撰写回答