显示桌面功能
2019年08月04日

概述

最近有一个需求,想通过 + d切换显示桌面,但是在网上搜了下发现,xfce4不支持show desktop功能的修改.

于是开始曲线救国,找到两个方法:

方法一 编译C源码,实现切换:

#include <X11/Xatom.h>
#include <X11/Xlib.h>

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        Display *d;
        Window root;
        Atom _NET_SHOWING_DESKTOP, actual_type;
        int actual_format, error, current;
        unsigned long nitems, after;
        unsigned char *data = NULL;

        /* Open the default display */
        if(!(d = XOpenDisplay(NULL))) {
                fprintf(stderr, "Cannot open display \"%s\".\n", XDisplayName(NULL));
                exit(EXIT_FAILURE);
        }

        /* This is the default root window */
        root = DefaultRootWindow(d);

        /* find the Atom for _NET_SHOWING_DESKTOP */
        _NET_SHOWING_DESKTOP = XInternAtom(d, "_NET_SHOWING_DESKTOP", False);

        /* Obtain the current state of _NET_SHOWING_DESKTOP on the default root window */
        error = XGetWindowProperty(d, root, _NET_SHOWING_DESKTOP, 0, 1, False, XA_CARDINAL,
                                  &actual_type, &actual_format, &nitems, &after, &data);
        if(error != Success) {
                fprintf(stderr, "Received error %d!\n", error);
                XCloseDisplay(d);
                exit(EXIT_FAILURE);
        }

        /* The current state should be in data[0] */
        if(data) {
                current = data[0];
                XFree(data);
                data = NULL;
        }

        /* If nitems is 0, forget about data[0] and assume that current should be False */
        if(!nitems) {
                fprintf(stderr, "Unexpected result.\n");
                fprintf(stderr, "Assuming unshown desktop!\n");
                current = False;
        }

        /* Initialize Xevent struct */
        XEvent xev = {
                .xclient = {
                        .type = ClientMessage,
                        .send_event = True,
                        .display = d,
                        .window = root,
                        .message_type = _NET_SHOWING_DESKTOP,
                        .format = 32,
                        .data.l[0] = !current /* That’s what we want the new state to be */
                }
        };

        /* Send the event to the window manager */
        XSendEvent(d, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);

        XCloseDisplay(d);
        exit(EXIT_SUCCESS);

        return 0;
}

幸运的是,如果你知道一个小Xlib,很容易做出你自己的命令切换所有支持它的窗口管理器上的“show desktop”(支持“show desktop”功能,wm应该符合部分EWMH文件)。我们很幸运,因为Xfce(以及其他WM)确实支持这种扩展。
所以这是代码。首先,它在根窗口中查询“show desktop”属性的状态,然后,它发送一个请求,使“show desktop”属性与发现的任何内容相反。

  1. 编译
    因此,要编译该东西,首先只需将代码复制并粘贴到文本文件中(出于我们的目的,我将其称为sdtoggle.c)。然后,编译它(你必须在你的系统上安装libX11及其头文件):
gcc -o sdtoggle -lX11 sdtoggle.c
  1. 执行
    现在,您有一个可执行文件(即sdtoggle),它应该切换“show desktop”属性(在终端中尝试并查找任何错误消息):
./sdtoggle; sleep 2; ./sdtoggle

一旦你确认它按预期工作(上面的行应该最小化所有窗口,暂停两秒,然后重新打开那些被最小化的窗口),你可以继续将它放在安全的地方(例如,/ usr / local / bin)。然后添加执行新命令的键盘快捷键,您应该进行设置。

方法二 使用wmctrl切换:

  1. 编写脚本
vim ~/bin/sdtoggle.sh
if xprop -root  _NET_SHOWING_DESKTOP|egrep '= 1' ; then 
  wmctrl -k off ; 
else 
  wmctrl -k on ;
fi
  1. 设置系统按键 super + d
  2. 使用

参考链接

原讨论链接

总结

两种办法都能实现切换桌面显示的功能,c源码需要引用libc,这对于一些开袋即食的发行版,需要安装一些库的源码文件,才能正常编译.wmctrl只是一个小程序,建议选择后者.