linux系统是否开启透明策略

开篇:本着开源的精神,分享开源代码之美。

本文开发环境的配置
所需文件优麒麟/UOS 等deb系中标麒麟等fedora系
qt的x11extras模块建议安装QtCreator工具获得QtCreator或者yum install qt5-qtX11extras-devel
libQtCore.so等qt基础库同上yum install qt5-qtbase
Xlib.hapt install libx11-devyum install libX11-devel
gdk/gdk.h 或 gtk/gtk.hapt install libgtk-3-devyum install gtk3-devel
  • 若无法安装,建议先考虑apt或者yum源的问题,或者查找别的原因。
  • 本篇重在查看linux系统是否开启或是否支持窗口透明策略,而不是如何设置窗口透明
  • 本篇所有代码均在以下平台测试成功
    • 优麒麟社区版20.04(deb系)
    • 中标麒麟兆芯B61(rpm系)

1、概念说明

透明策略一般是指窗口透明:即透过某一个应用的窗体,可以看到后一个窗体上的文字等信息,或者可以看见桌面上的图标等信息。

2、inux 系统如何做到对透明窗体的支持?(这里未做认真调研)

以fedora的rpm系为例:在基于X window的linux系统上,默认是安装了compiz这个软件包,可以使用Open-GL对工作空间进行渲染。也即,开启这一效果是耗费CPU性能的。

3、如何查看linux是否支持透明策略?或者是否开启透明策略?

1. linux shell命令(以fedora的MATE系为例)```shellgsettings get org.mate.Marco.general compositing-manager# 结果为true表明已经开启透明策略,false则表示不支持或者未开启```
2. ubuntun系不太清楚

4、 代码层面查看linux系统窗口透明的支持状态

1.1 gdk/gtk API 源码文件 composited.c

#include 
#include 
#include int main(int argc, char* argv[]){GtkWidget* window;GdkScreen* screen;gboolean support;gtk_init(&argc,&argv);//gtk环境初始化,一般gtk/gdk代码都要增加这个,否则运行报错window = gtk_window_new(GTK_WINDOW_TOPLEVEL);		//创建一个带边框的gtk窗体screen = gtk_widget_get_screen(GTK_WIDGET(window)); //获取窗体对应的GdkScreensupport = gdk_screen_is_composited(screen);			//检测GdkScreen是否透明//gtk_widget_show_all(window);//gtk_main();gtk_widget_destroy(window);							//销毁窗体printf("suppoer = %d\n",support);return 0;
}

1.2、对应的Makefile.am文件

CC = gcc
RM = rm -f
# 指定预处理阶段头文件查找目录(gcc -I)
CPPFLAGS = `pkg-config --cflags gtk+-3.0 gdk-3.0`
# 指定链接阶段要链接的库(gcc -l)
LIBS = `pkg-config --libs gtk+-3.0 gdk-3.0`
# 源码文件
src = composited.c
# 同名中间目标文件 -> .c 替换为 .o
obj = $(patsubst %.c,%.o,$(src))
# 最终目标:同名二进制文件 -> 文件去掉 .c 后缀
target = $(patsubst %.c,%,$(src))
# 指定最终要生成的所有目标文件
all:$(target)
# 二进制文件依赖 .o 文件
# $< 代指第一个依赖,即 $(obj)
# $@ 代指目标文件,即 $(target)
$(target):$(obj)$(CC) $< -o $@ $(LIBS)#同名 .o 依靠 同名.c文件来生成
# $< 代指第一个依赖,即 同名 .c 文件
%.o:%.c$(CC) -c $< $(CPPFLAGS).PHONY:clean
# make clean 删除 .o 和 二进制文件
clean:$(RM) $(obj) $(target)

2.1 qt / X API 项目源码

#include <QApplication>
#include <QString>
#include <QScreen>
#include <QDebug>
#include <QX11Info>
#include <X11/Xlib.h>int main(int argc,char* argv[]){QApplication a(argc,argv);int num;Display* dpy;QString tmp;Atom tmpAtom;Window xWindow;num = QX11Info::appScreen();							//获取显示该窗体的屏幕编号dpy = QX11Info::display();								//获取显示该窗体的Displaytmp = QString("_NET_WM_CM_S%1").arg(num);				//查看透明策略的固定字符串tmpAtom = XInternAtom(dpy,tmp.toLatin1().data(),num);	//返回与第二个参数有关的atom标识符xWindow = XGetSelectionOwner(dpy,tmpAtom);				//返回与第二个atom标识符有关的窗体idqDebug()<<(xWindow != None)<<endl;			//id为0则表示不支持透明策略。//XCloseDisplay(dpy);return a.exec();
}

2.2 项目pro文件

#代码中用到了QT的x11相关接口,所以需要添加x11extras模块
QT += widgets gui x11extrasCONFIG += c11 console
CONFIG -= app_bundleTEMPLATE = app
TARGET = composited
DEPENDPATH += .
INCLUDEPATH += .
# 项目中用到了Xlib的代码,所以增加以下链接库
LIBS += -lX11 -lXrandr# Input
SOURCES += composited.cpp

3.纯 X 代码

/* compile: gcc composited.c  -o composited -lX11* 代码编写与测试平台:中标兆芯B61(rpm系)
*/
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>int main(int argc,char* argv[]){int num;Display* dpy;Screen* screen;char tmp[32];Atom tmpAtom;Window xWindow;memset(tmp,0,sizeof(tmp));dpy = XOpenDisplay(NULL);					//获取默认的Displayscreen = DefaultScreenOfDisplay(dpy);		//获取Display默认的屏幕num = XScreenNumberOfScreen(screen);		//获取屏幕的编号sprintf(tmp,"_NET_WM_CM_S%d",num);			//特殊格式//printf("%s %d\n",tmp,num);tmpAtom = XInternAtom(dpy,tmp,num);			//见上面注释xWindow = XGetSelectionOwner(dpy,tmpAtom);	//同上printf("%d\n",xWindow != None);				//id不为0即表示支持透明策略XCloseDisplay(dpy);							//关闭Displayreturn 0;
}

5、额外说明

有兴趣的读者可以下载gtk-3.0源码,对 gdk_screen_is_composited() 函数源码跟踪,可以发现,其判断系统透明策略的本质就在于后2个代码中的 XInternAtom() 和 XGetSelectionOwner()


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部