2008年5月14日星期三

Linux桌面实用工具

第一个就是大名鼎鼎的jump-or-exec,貌似我的代码是从不知道那个地方抄来的,作者莫怪。


#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

int
main(int argc, char* argv[])
{
if (argc < 3) {
fprintf(stderr, "Usage: %s resource_name start_command\n\n", argv[0]);
fprintf(stderr, "resource_name: the window's X resource name.\n");
fprintf(stderr, "start_command: the command to start a new window.\n");
return 0;
}

const char *res_class = argv[1];
printf("The inputed resource name is %s.\n", res_class);

Display *display = XOpenDisplay(NULL);
if (!display) {
fprintf(stderr, "This program should be run within X environment.\n");
return 1;
}
Window root = DefaultRootWindow(display);
Window *windows = NULL;
unsigned long win_num, i = 0;
Atom actual_return_type;
int actual_format_return;
unsigned long bytes;
XGetWindowProperty(display,
root,
XInternAtom(display, "_NET_CLIENT_LIST", False),
0,
1024,
False,
XA_WINDOW,
&actual_return_type,
&actual_format_return,
&win_num,
&bytes,
(unsigned char**) &windows);
printf("Found %d windows.\n", win_num);

for (; i < win_num; ++i) {
XClassHint hint;
memset(&hint, 0, sizeof(hint));
XGetClassHint(display, windows[i], &hint);
printf("%s\n", hint.res_class);
if (hint.res_class) {
if (strcasecmp(res_class, hint.res_class) == 0) {
printf("Found!!!\n");
XMapRaised(display, windows[i]);
XCloseDisplay(display);
return 0;
}
}
}

/* Reach here means the window with the name was not found. */
system(argv[2]);

if (windows)
XFree(windows);
return 0;
}


用法:

$ jump-or-exec gecko firefox

其中第一个参数为窗口的class名称,可用xprop命令查看,记得是WM_CLASS属性中的第二个字符串;第二个参数为启动该程序的命令。

第二个工具就是用来控制当前窗口的透明度的,当然前提就是你的WM要支持真透明。比如我用的Xfce4,再用之前就要先开启设置->窗口管理器调整->混合设置->允许混合显示。另外你用的xorg也要支持,并且在你的xorg.conf文件中要有这么一段:


Section "Extensions"
Option "Composite" "true"
EndSection


代码如下:

#include <X11/Xlib.h>
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define OPACITY 0xffff

int
main(int argc, char* argv[])
{
if (argc < 2) {
fprintf(stderr, "Usage: %s step\n\n", argv[0]);
fprintf(stderr, "step: to in(de)crease opacity of current window.\n");
fprintf(stderr, " Maybe negative.\n");
return 0;
}

int step = atoi(argv[1]);

Display *display = XOpenDisplay(NULL);
if (!display) {
fprintf(stderr, "This program should be run within X environment.\n");
return 1;
}

Atom opacity_atom = XInternAtom(display, "_NET_WM_WINDOW_OPACITY", 0);

Atom actual;
int result, format;
unsigned long n, left;
unsigned char *data;

result = XGetWindowProperty(display, DefaultRootWindow(display),
XInternAtom(display, "_NET_ACTIVE_WINDOW", 0),
0L, 1L, False, XA_WINDOW, &actual, &format,
&n, &left, &data);
if (result != Success || !n || !data)
return 0;
Window active = *((Window *)data);
XClassHint hint;
memset(&hint, 0, sizeof(XClassHint));
XGetClassHint(display, active, &hint);
printf("resource name: %s\n", hint.res_name);

result = XGetWindowProperty(display, active, opacity_atom,
0L, 1L, False, XA_CARDINAL, &actual, &format,
&n, &left, &data);
int opacity = OPACITY;
if (result == Success && n && data) {
CARD32 value;
memcpy(&value, data, sizeof(CARD32));
XFree(data);
opacity = value >> 16;
printf("opacity: %d\n", opacity);
}
opacity += OPACITY * step / 100;
if (opacity < 0)
opacity = 0;
if (opacity > OPACITY)
opacity = OPACITY;
CARD32 value32 = opacity << 16 | opacity;
XChangeProperty(display, active, opacity_atom, XA_CARDINAL,
32, PropModeReplace, (unsigned char *)&value32, 1);

XSync(display, False);

return 0;
}


用法:

$ opacity -20

参数的意思是透明度的调整数值,-20就是“不透明度”-20啦。呃,当初没意识到这个问题,算了。

这两个程序在编译时别忘了加上xlib的编译参数,不知道的话就用pkg-config吧。

嗯,它们的优点就是独立于你所用的WM,配合上xbindkeys这个小软件的话就更加完美了。

嗯,就酱。

没有评论: