Я записываю список окон в свое приложение C, в котором отображаются все окна верхнего уровня, включая затененные, свернутые и другие рабочие столы.Я хотел бы восстановить не отображенные (свернутые) окна, поднять окно и переключиться на рабочий стол / рабочее пространство окна, когда оно выбрано.
В прошлом я писал что-то для достижения этой цели с помощью Xlib.Я использовал XSendEvent () для отправки события ClientMessage типа _NET_ACTIVE_WINDOW с последующим XMapRaised () ранее, и оно работало довольно хорошо, но не идеально.
Сейчас я переписываю приложение и решил использовать XCB для окнаперечислите код, а не Xlib и надеетесь создать лучшую и более эффективную реализацию.XCB не имеет эквивалента XMapRaised (), и xcb_map_window (), похоже, не работает для меня.Я нашел достаточное количество документации по созданию и настройке новых окон, но очень мало полезного для реализации оконного менеджера или служебных программ, таких как пейджеры, значки, панели задач и т. Д. Сгенерированная документация для XCB довольно расплывчата в отношении того, чтонекоторые функции на самом деле делают так же.Если кто-нибудь знает о дополнительной документации, которая может быть полезна для этого, это тоже было бы здорово.
РЕДАКТИРОВАТЬ:
Я продублировал часть старого кода, который использует Xlib, в небольшойутилита, и она на самом деле делает большую часть того, что я хочу, и, кажется, работает согласованно:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
int main(int argc, char **argv) {
Display *display = XOpenDisplay("");
Window rootwin = XDefaultRootWindow(display);
if (argc < 2)
{
printf("usage: %s windowid\n", argv[0]);
return 0;
}
Window window = (Window)strtoul(argv[1], NULL, 0);
printf("switch to window: 0x%lx\n", window);
Atom ActiveWindowAtom = XInternAtom(display, "_NET_ACTIVE_WINDOW", False);
XEvent xev;
xev.xclient.type = ClientMessage;
xev.xclient.window = window;
xev.xclient.message_type = ActiveWindowAtom;
xev.xclient.format = 32;
xev.xclient.data.l[0] = 1U;
xev.xclient.data.l[1] = 1U;
xev.xclient.data.l[2] = 0U;
xev.xclient.data.l[3] = 0U;
xev.xclient.data.l[4] = 0U;
XSendEvent(display, rootwin, False, SubstructureRedirectMask, &xev);
XMapRaised(display, window);
XCloseDisplay(display);
return 0;
}
... и затем я распаковал исходники libX11 и подтвердил, что она просто оборачивает функции XCB, ноОболочки используют некоторые структуры данных libX11 вместо тех, которые определены в XCB, и используется так много макросов, что трудно точно понять, что происходит.Это эквивалент XCB, который я придумал, и он не работает:
#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
#include "atom_cache.h"
int main(int argc, char **argv) {
xcb_connection_t *connection;
const xcb_setup_t *setup;
xcb_screen_iterator_t screen_iter;
xcb_screen_t *screen;
xcb_window_t rootwin, window;
xcb_void_cookie_t void_cookie;
xcb_client_message_event_t client_message_event;
if (argc < 2)
{
printf("usage: %s windowid\n", argv[0]);
return 0;
}
window = (xcb_window_t)strtoul(argv[1], NULL, 0);
printf("switch to window: 0x%x\n", window);
connection = xcb_connect(NULL, NULL);
setup = xcb_get_setup(connection);
screen_iter = xcb_setup_roots_iterator(setup);
screen = screen_iter.data;
rootwin = screen->root;
// send _net_active_window request
client_message_event.response_type = XCB_CLIENT_MESSAGE;
client_message_event.format = 32;
client_message_event.sequence = 0;
client_message_event.window = window;
client_message_event.type = get_atom(connection, "_NET_ACTIVE_WINDOW");
client_message_event.data.data32[0] = 1UL; // source: 1=application 2=pager
client_message_event.data.data32[1] = 1UL; // timestamp
client_message_event.data.data32[2] = 0UL; // my currently active window?
client_message_event.data.data32[3] = 0UL;
client_message_event.data.data32[4] = 0UL;
void_cookie = xcb_send_event(connection, 1, rootwin, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&client_message_event);
uint32_t values[] = { XCB_STACK_MODE_ABOVE };
xcb_configure_window(connection, window, XCB_CONFIG_WINDOW_STACK_MODE, values);
xcb_map_window(connection, window);
xcb_flush(connection);
xcb_disconnect(connection);
return 0;
}
Я все еще пытаюсь выяснить это.