2022-04-24 14:52:13 +08:00
|
|
|
/*
|
2022-05-15 12:10:42 +08:00
|
|
|
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
2022-04-24 14:52:13 +08:00
|
|
|
*
|
|
|
|
* Author: weizhixiang <weizhixiang@uniontech.com>
|
|
|
|
*
|
|
|
|
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "xcbutils.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
XCBUtils::XCBUtils()
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
m_connect = xcb_connect(nullptr, &m_screenNum); // nullptr表示默认使用环境变量$DISPLAY获取屏幕
|
|
|
|
if (xcb_connection_has_error(m_connect)) {
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << "XCBUtils: init xcb_connect error" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!xcb_ewmh_init_atoms_replies(&m_ewmh,
|
|
|
|
xcb_ewmh_init_atoms(m_connect, &m_ewmh), // 初始化Atom
|
2022-04-24 14:52:13 +08:00
|
|
|
nullptr))
|
|
|
|
std::cout << "XCBUtils: init ewmh error" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
XCBUtils::~XCBUtils()
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
if (m_connect) {
|
|
|
|
xcb_disconnect(m_connect); // 关闭连接并释放
|
|
|
|
m_connect = nullptr;
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
XWindow XCBUtils::allocId()
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
return xcb_generate_id(m_connect);
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::killClientChecked(XWindow xid)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_kill_client_checked(m_connect, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
xcb_get_property_reply_t *XCBUtils::getPropertyValueReply(XWindow xid, XCBAtom property, XCBAtom type)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_get_property(m_connect,
|
2022-04-24 14:52:13 +08:00
|
|
|
0,
|
|
|
|
xid,
|
|
|
|
property,
|
|
|
|
type,
|
|
|
|
0,
|
|
|
|
MAXLEN);
|
2022-05-15 12:10:42 +08:00
|
|
|
return xcb_get_property_reply(m_connect, cookie, nullptr);
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void *XCBUtils::getPropertyValue(XWindow xid, XCBAtom property, XCBAtom type)
|
|
|
|
{
|
|
|
|
void *value = nullptr;
|
|
|
|
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, property, type);
|
|
|
|
if (reply) {
|
|
|
|
if (xcb_get_property_value_length(reply) > 0) {
|
|
|
|
value = xcb_get_property_value(reply);
|
|
|
|
}
|
|
|
|
free(reply);
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string XCBUtils::getUTF8PropertyStr(XWindow xid, XCBAtom property)
|
|
|
|
{
|
|
|
|
std::string ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, property, m_ewmh.UTF8_STRING);
|
2022-04-24 14:52:13 +08:00
|
|
|
if (reply) {
|
|
|
|
ret = getUTF8StrFromReply(reply);
|
|
|
|
|
|
|
|
free(reply);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
XCBAtom XCBUtils::getAtom(const char *name)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
XCBAtom ret = m_atomCache.getVal(name);
|
2022-04-24 14:52:13 +08:00
|
|
|
if (ret == ATOMNONE) {
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_connect, false, strlen(name), name);
|
|
|
|
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply (m_connect,
|
2022-04-24 14:52:13 +08:00
|
|
|
cookie,
|
|
|
|
nullptr);
|
|
|
|
if (reply) {
|
2022-05-15 12:10:42 +08:00
|
|
|
m_atomCache.store(name, reply->atom);
|
2022-04-24 14:52:13 +08:00
|
|
|
ret = reply->atom;
|
|
|
|
|
|
|
|
free(reply);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string XCBUtils::getAtomName(XCBAtom atom)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
std::string ret = m_atomCache.getName(atom);
|
2022-04-24 14:52:13 +08:00
|
|
|
if (ret.empty()) {
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(m_connect, atom);
|
|
|
|
xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(m_connect,
|
2022-04-24 14:52:13 +08:00
|
|
|
cookie,
|
|
|
|
nullptr);
|
|
|
|
if (reply) {
|
|
|
|
char *name = xcb_get_atom_name_name(reply);
|
|
|
|
if (name) {
|
2022-05-15 12:10:42 +08:00
|
|
|
m_atomCache.store(name, atom);
|
2022-04-24 14:52:13 +08:00
|
|
|
ret = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(reply);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
Geometry XCBUtils::getWindowGeometry(XWindow xid)
|
|
|
|
{
|
|
|
|
Geometry ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(m_connect, xid);
|
|
|
|
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(m_connect, cookie, nullptr);
|
2022-04-24 14:52:13 +08:00
|
|
|
if (reply) {
|
|
|
|
ret.x = reply->x;
|
|
|
|
ret.y = reply->y;
|
|
|
|
ret.width = reply->width;
|
|
|
|
ret.height = reply->height;
|
|
|
|
|
|
|
|
free(reply);
|
|
|
|
} else {
|
|
|
|
std::cout << xid << " getWindowGeometry err" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
XWindow XCBUtils::getActiveWindow()
|
|
|
|
{
|
|
|
|
XWindow ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_active_window(&m_ewmh, m_screenNum);
|
|
|
|
if (!xcb_ewmh_get_active_window_reply(&m_ewmh, cookie, &ret, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << "getActiveWindow error" << std::endl;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::setActiveWindow(XWindow xid)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_ewmh_set_active_window(&m_ewmh, m_screenNum, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
|
2022-05-24 21:49:47 +08:00
|
|
|
void XCBUtils::changeActiveWindow(XWindow newActiveXid)
|
|
|
|
{
|
|
|
|
xcb_ewmh_request_change_active_window(&m_ewmh, m_screenNum, newActiveXid, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::restackWindow(XWindow xid)
|
|
|
|
{
|
|
|
|
xcb_ewmh_request_restack_window(&m_ewmh, m_screenNum, xid, 0, XCB_STACK_MODE_ABOVE);
|
|
|
|
}
|
|
|
|
|
2022-04-24 14:52:13 +08:00
|
|
|
std::list<XWindow> XCBUtils::getClientList()
|
|
|
|
{
|
|
|
|
std::list<XWindow> ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list(&m_ewmh, m_screenNum);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_ewmh_get_windows_reply_t reply;
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!xcb_ewmh_get_client_list_reply(&m_ewmh, cookie, &reply, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << "getClientList error" << std::endl;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < reply.windows_len; i++)
|
|
|
|
ret.push_back(reply.windows[i]);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::list<XWindow> XCBUtils::getClientListStacking()
|
|
|
|
{
|
|
|
|
std::list<XWindow> ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list_stacking(&m_ewmh, m_screenNum);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_ewmh_get_windows_reply_t reply;
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!xcb_ewmh_get_client_list_stacking_reply(&m_ewmh, cookie, &reply, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << "getClientListStacking error" << std::endl;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < reply.windows_len; i++)
|
|
|
|
ret.push_back(reply.windows[i]);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<XCBAtom> XCBUtils::getWMState(XWindow xid)
|
|
|
|
{
|
|
|
|
std::vector<XCBAtom> ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_state(&m_ewmh, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_ewmh_get_atoms_reply_t reply; // a list of Atom
|
2022-05-15 12:10:42 +08:00
|
|
|
if (xcb_ewmh_get_wm_state_reply(&m_ewmh, cookie, &reply, nullptr)) {
|
2022-04-24 14:52:13 +08:00
|
|
|
for (uint32_t i = 0; i < reply.atoms_len; i++) {
|
|
|
|
ret.push_back(reply.atoms[i]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
std::cout << xid << " getWMState error" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<XCBAtom> XCBUtils::getWMWindoType(XWindow xid)
|
|
|
|
{
|
|
|
|
std::vector<XCBAtom> ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type(&m_ewmh, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_ewmh_get_atoms_reply_t reply; // a list of Atom
|
2022-05-24 21:49:47 +08:00
|
|
|
if (xcb_ewmh_get_wm_window_type_reply(&m_ewmh, cookie, &reply, nullptr)) {
|
|
|
|
for (uint32_t i = 0; i < reply.atoms_len; i++) {
|
|
|
|
ret.push_back(reply.atoms[i]);
|
|
|
|
}
|
|
|
|
} else {
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMWindoType error" << std::endl;
|
2022-05-24 21:49:47 +08:00
|
|
|
}
|
2022-04-24 14:52:13 +08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<XCBAtom> XCBUtils::getWMAllowedActions(XWindow xid)
|
|
|
|
{
|
|
|
|
std::vector<XCBAtom> ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_allowed_actions(&m_ewmh, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_ewmh_get_atoms_reply_t reply; // a list of Atoms
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!xcb_ewmh_get_wm_allowed_actions_reply(&m_ewmh, cookie, &reply, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMAllowedActions error" << std::endl;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < reply.atoms_len; i++) {
|
|
|
|
ret.push_back(reply.atoms[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::setWMAllowedActions(XWindow xid, std::vector<XCBAtom> actions)
|
|
|
|
{
|
|
|
|
XCBAtom list[MAXALLOWEDACTIONLEN] {0};
|
|
|
|
for (size_t i = 0; i < actions.size(); i++)
|
|
|
|
list[i] = actions[i];
|
|
|
|
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_ewmh_set_wm_allowed_actions(&m_ewmh, xid, actions.size(), list);
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string XCBUtils::getWMName(XWindow xid)
|
|
|
|
{
|
|
|
|
std::string ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name(&m_ewmh, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_ewmh_get_utf8_strings_reply_t reply1;
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!xcb_ewmh_get_wm_name_reply(&m_ewmh, cookie, &reply1, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMName error" << std::endl;
|
|
|
|
|
|
|
|
ret.assign(reply1.strings);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XCBUtils::getWMPid(XWindow xid)
|
|
|
|
{
|
|
|
|
uint32_t ret = 0;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_pid(&m_ewmh, xid);
|
|
|
|
if (!xcb_ewmh_get_wm_pid_reply(&m_ewmh, cookie, &ret, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMPid error" << std::endl;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string XCBUtils::getWMIconName(XWindow xid)
|
|
|
|
{
|
|
|
|
std::string ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_name(&m_ewmh, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_ewmh_get_utf8_strings_reply_t reply;
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!xcb_ewmh_get_wm_icon_name_reply(&m_ewmh, cookie, &reply, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMIconName error" << std::endl;
|
|
|
|
|
|
|
|
ret.assign(reply.strings);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<WMIcon> XCBUtils::getWMIcon(XWindow xid)
|
|
|
|
{
|
|
|
|
std::vector<WMIcon> ret;
|
|
|
|
/*
|
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon(&ewmh, xid);
|
|
|
|
xcb_ewmh_get_wm_icon_reply_t reply;
|
|
|
|
if (xcb_ewmh_get_wm_icon_reply(&ewmh, cookie, &reply, nullptr)) {
|
|
|
|
xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&reply);
|
|
|
|
auto fcn = [](xcb_ewmh_wm_icon_iterator_t it) {
|
|
|
|
std::vector<BYTE> data;
|
|
|
|
uint32_t *dat = it.data;
|
|
|
|
int area = it.width * it.height;
|
|
|
|
for (int i = 0; i < (2 + area) * 4; i++, dat++) { // TODO check data accuracy
|
|
|
|
data.push_back(*dat);
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
};
|
|
|
|
|
|
|
|
ret.push_back({iter.width, iter.height, fcn(iter)});
|
|
|
|
|
|
|
|
while (iter.rem >= 1) {
|
|
|
|
xcb_ewmh_get_wm_icon_next(&iter);
|
|
|
|
ret.push_back({iter.width, iter.height, fcn(iter)});
|
|
|
|
}
|
|
|
|
|
|
|
|
xcb_ewmh_get_wm_icon_reply_wipe(&reply); // clear
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
XWindow XCBUtils::getWMClientLeader(XWindow xid)
|
|
|
|
{
|
|
|
|
XWindow ret;
|
|
|
|
XCBAtom atom = getAtom("WM_CLIENT_LEADER");
|
|
|
|
void *value = getPropertyValue(xid, atom, XCB_ATOM_INTEGER);
|
|
|
|
std::cout << "getWMClientLeader:" << (char*)value << std::endl;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::requestCloseWindow(XWindow xid, uint32_t timestamp)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_ewmh_request_close_window(&m_ewmh, m_screenNum, xid, timestamp, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER);
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XCBUtils::getWMDesktop(XWindow xid)
|
|
|
|
{
|
|
|
|
uint32_t ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop(&m_ewmh, xid);
|
|
|
|
if (!xcb_ewmh_get_wm_desktop_reply(&m_ewmh, cookie, &ret, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMDesktop error" << std::endl;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::setWMDesktop(XWindow xid, uint32_t desktop)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_ewmh_set_wm_desktop(&m_ewmh, xid, desktop);
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::setCurrentWMDesktop(uint32_t desktop)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_ewmh_set_current_desktop(&m_ewmh, m_screenNum, desktop);
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XCBUtils::getCurrentWMDesktop()
|
|
|
|
{
|
|
|
|
uint32_t ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop(&m_ewmh, m_screenNum);
|
|
|
|
if (!xcb_ewmh_get_current_desktop_reply(&m_ewmh, cookie, &ret, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << "getCurrentWMDesktop error" << std::endl;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XCBUtils::isGoodWindow(XWindow xid)
|
|
|
|
{
|
|
|
|
bool ret = false;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(m_connect, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_generic_error_t **errStore = nullptr;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(m_connect, cookie, errStore);
|
2022-04-24 14:52:13 +08:00
|
|
|
if (reply) {
|
|
|
|
if (!errStore) // 正常获取窗口geometry则判定为good
|
|
|
|
ret = true;
|
|
|
|
|
|
|
|
free(reply);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO XCB下无_MOTIF_WM_HINTS属性
|
|
|
|
MotifWMHints XCBUtils::getWindowMotifWMHints(XWindow xid)
|
|
|
|
{
|
|
|
|
MotifWMHints ret;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XCBUtils::hasXEmbedInfo(XWindow xid)
|
|
|
|
{
|
|
|
|
//XCBAtom atom = getAtom("_XEMBED_INFO");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
XWindow XCBUtils::getWMTransientFor(XWindow xid)
|
|
|
|
{
|
|
|
|
XWindow ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_transient_for(m_connect, xid);
|
|
|
|
if (!xcb_icccm_get_wm_transient_for_reply(m_connect, cookie, &ret, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMTransientFor error" << std::endl;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XCBUtils::getWMUserTime(XWindow xid)
|
|
|
|
{
|
|
|
|
uint32_t ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_user_time(&m_ewmh, xid);
|
|
|
|
if (!xcb_ewmh_get_wm_user_time_reply(&m_ewmh, cookie, &ret, nullptr))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMUserTime error" << std::endl;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int XCBUtils::getWMUserTimeWindow(XWindow xid)
|
|
|
|
{
|
|
|
|
XCBAtom ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_user_time_window(&m_ewmh, xid);
|
|
|
|
if (!xcb_ewmh_get_wm_user_time_window_reply(&m_ewmh, cookie, &ret, NULL))
|
2022-04-24 14:52:13 +08:00
|
|
|
std::cout << xid << " getWMUserTimeWindow error" << std::endl;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
WMClass XCBUtils::getWMClass(XWindow xid)
|
|
|
|
{
|
|
|
|
WMClass ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class(m_connect, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_icccm_get_wm_class_reply_t reply;
|
2022-05-24 21:49:47 +08:00
|
|
|
reply.instance_name = nullptr;
|
|
|
|
reply.class_name = nullptr;
|
2022-05-15 12:10:42 +08:00
|
|
|
if (!xcb_icccm_get_wm_class_reply(m_connect, cookie, &reply, nullptr)) {
|
2022-04-24 14:52:13 +08:00
|
|
|
if (reply.class_name)
|
|
|
|
ret.className.assign(reply.class_name);
|
|
|
|
|
|
|
|
if (reply.instance_name)
|
|
|
|
ret.instanceName.assign(reply.instance_name);
|
|
|
|
|
|
|
|
//xcb_icccm_get_wm_class_reply_wipe(&reply);
|
|
|
|
} else {
|
|
|
|
std::cout << xid << " getWMClass error" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
void XCBUtils::minimizeWindow(XWindow xid)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints(m_connect, xid);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_icccm_wm_hints_t *hints = new xcb_icccm_wm_hints_t; // 分配堆空间
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_icccm_get_wm_hints_reply(m_connect, cookie, hints, nullptr);
|
2022-04-24 14:52:13 +08:00
|
|
|
xcb_icccm_wm_hints_set_iconic(hints);
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_icccm_set_wm_hints(m_connect, xid, hints);
|
2022-04-24 14:52:13 +08:00
|
|
|
free(hints);
|
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::maxmizeWindow(XWindow xid)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_ewmh_request_change_wm_state(&m_ewmh
|
|
|
|
, m_screenNum
|
2022-04-24 14:52:13 +08:00
|
|
|
, xid
|
|
|
|
, XCB_EWMH_WM_STATE_ADD
|
|
|
|
, getAtom("_NET_WM_STATE_MAXIMIZED_VERT")
|
|
|
|
, getAtom("_NET_WM_STATE_MAXIMIZED_HORZ")
|
|
|
|
, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
std::vector<std::string> XCBUtils::getWMCommand(XWindow xid)
|
|
|
|
{
|
|
|
|
std::vector<std::string> ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, XCB_ATOM_WM_COMMAND, m_ewmh.UTF8_STRING);
|
2022-04-24 14:52:13 +08:00
|
|
|
if (reply) {
|
|
|
|
ret = getUTF8StrsFromReply(reply);
|
|
|
|
free(reply);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string XCBUtils::getUTF8StrFromReply(xcb_get_property_reply_t *reply)
|
|
|
|
{
|
|
|
|
std::string ret;
|
|
|
|
if (!reply || reply->format != 8)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
char data[12] = {0};
|
|
|
|
for (uint32_t i=0; i < reply->value_len; i++) {
|
|
|
|
data[i] = char(reply->pad0[i]);
|
|
|
|
}
|
|
|
|
ret.assign(data);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> XCBUtils::getUTF8StrsFromReply(xcb_get_property_reply_t *reply)
|
|
|
|
{
|
|
|
|
std::vector<std::string> ret;
|
|
|
|
if (!reply)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (reply->format != 8)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
|
|
// 字符串拆分
|
|
|
|
uint32_t start = 0;
|
|
|
|
for (uint32_t i=0; i < reply->value_len; i++) {
|
|
|
|
if (reply->pad0[i] == 0) {
|
|
|
|
char data[12] = {0};
|
|
|
|
int count = 0;
|
|
|
|
for (uint32_t j=start; j < i; j++)
|
|
|
|
data[count++] = char(reply->pad0[j]);
|
|
|
|
|
|
|
|
data[count] = 0;
|
|
|
|
ret.push_back(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
XWindow XCBUtils::getRootWindow()
|
|
|
|
{
|
|
|
|
XWindow rootWindow = 0;
|
|
|
|
/* Get the first screen */
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(m_connect)).data;
|
2022-04-24 14:52:13 +08:00
|
|
|
if (screen)
|
|
|
|
rootWindow = screen->root;
|
|
|
|
|
|
|
|
std::cout << "getRootWinodw: " << rootWindow << std::endl;
|
|
|
|
return rootWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XCBUtils::registerEvents(XWindow xid, uint32_t eventMask)
|
|
|
|
{
|
|
|
|
uint32_t value[1] = {eventMask};
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_void_cookie_t cookie = xcb_change_window_attributes_checked(m_connect,
|
2022-04-24 14:52:13 +08:00
|
|
|
xid,
|
|
|
|
XCB_CW_EVENT_MASK,
|
|
|
|
&value);
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_flush(m_connect);
|
2022-04-24 14:52:13 +08:00
|
|
|
|
2022-05-15 12:10:42 +08:00
|
|
|
xcb_generic_error_t *error = xcb_request_check(m_connect, cookie);
|
2022-04-24 14:52:13 +08:00
|
|
|
if (error != nullptr) {
|
|
|
|
std::cout << "window " << xid << "registerEvents error" << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AtomCache::AtomCache()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
XCBAtom AtomCache::getVal(std::string name)
|
|
|
|
{
|
|
|
|
XCBAtom atom = ATOMNONE;
|
2022-05-15 12:10:42 +08:00
|
|
|
auto search = m_atoms.find(name);
|
|
|
|
if (search != m_atoms.end())
|
2022-04-24 14:52:13 +08:00
|
|
|
atom = search->second;
|
|
|
|
|
|
|
|
return atom;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string AtomCache::getName(XCBAtom atom)
|
|
|
|
{
|
|
|
|
std::string ret;
|
2022-05-15 12:10:42 +08:00
|
|
|
auto search = m_atomNames.find(atom);
|
|
|
|
if (search != m_atomNames.end())
|
2022-04-24 14:52:13 +08:00
|
|
|
ret = search->second;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AtomCache::store(std::string name, XCBAtom value)
|
|
|
|
{
|
2022-05-15 12:10:42 +08:00
|
|
|
m_atoms[name] = value;
|
|
|
|
m_atomNames[value] = name;
|
2022-04-24 14:52:13 +08:00
|
|
|
}
|