启动时扫描已有窗口并管理
This commit is contained in:
@@ -84,8 +84,10 @@ rect_size_t *get_screen_size(void);
|
||||
void set_wallpaper(uint32_t *wallpaper_data);
|
||||
|
||||
typedef struct window_list_t {
|
||||
uint32_t count;
|
||||
xcb_window_t *list;
|
||||
xcb_window_t *normal_list;
|
||||
xcb_window_t *transient_list;
|
||||
uint32_t normal_count;
|
||||
uint32_t transient_count;
|
||||
} window_list_t;
|
||||
window_list_t *scan_window_list(void);
|
||||
void free_window_list(window_list_t *window_list);
|
||||
@@ -103,5 +105,12 @@ typedef enum atom_t {
|
||||
atom_wm_take_focus,
|
||||
} atom_t;
|
||||
bool send_event(xcb_window_t window, atom_t atom);
|
||||
typedef enum wm_state_t {
|
||||
wm_state_withdrawn = 0,
|
||||
wm_state_normal = 1,
|
||||
wm_state_iconic = 3
|
||||
} wm_state_t;
|
||||
int32_t get_window_state(xcb_window_t window);
|
||||
void set_window_state(xcb_window_t window, wm_state_t state);
|
||||
|
||||
bool get_pointer_position(int32_t *x, int32_t *y);
|
||||
|
||||
16
src/main.c
16
src/main.c
@@ -146,8 +146,11 @@ static void print_window_list(window_list_t *window_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < window_list->count; i++) {
|
||||
logger("window[%u]: 0x%x\n", i, window_list->list[i]);
|
||||
for (uint32_t i = 0; i < window_list->normal_count; i++) {
|
||||
logger("normal window[%u]: 0x%x\n", i, window_list->normal_list[i]);
|
||||
}
|
||||
for (uint32_t i = 0; i < window_list->transient_count; i++) {
|
||||
logger("transient window[%u]: 0x%x\n", i, window_list->transient_list[i]);
|
||||
}
|
||||
}
|
||||
static char *bool2string(bool b) { return b ? "true" : "false"; }
|
||||
@@ -877,6 +880,15 @@ int main(int argc, char *argv[]) {
|
||||
print_wallpaper_config(wallpaper_config);
|
||||
print_window_list(window_list);
|
||||
|
||||
if (window_list) {
|
||||
for (uint32_t i = 0; i < window_list->normal_count; i++) {
|
||||
manage_window(window_list->normal_list[i]);
|
||||
}
|
||||
for (uint32_t i = 0; i < window_list->transient_count; i++) {
|
||||
manage_window(window_list->transient_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free_window_list(window_list);
|
||||
|
||||
grab_keybindings(keys, LENGTH(keys));
|
||||
|
||||
@@ -218,11 +218,14 @@ bool get_window_visible(xcb_window_t window) {
|
||||
}
|
||||
|
||||
xcb_window_t get_transient_window_for(xcb_window_t window) {
|
||||
xcb_window_t transient_for = XCB_NONE;
|
||||
xcb_window_t transient_for = WINDOW_NONE;
|
||||
xcb_get_property_cookie_t cookie =
|
||||
xcb_icccm_get_wm_transient_for(conn, window);
|
||||
xcb_icccm_get_wm_transient_for_reply(conn, cookie, &transient_for, NULL);
|
||||
return transient_for;
|
||||
if (xcb_icccm_get_wm_transient_for_reply(conn, cookie, &transient_for,
|
||||
NULL)) {
|
||||
return transient_for;
|
||||
}
|
||||
return WINDOW_NONE;
|
||||
}
|
||||
|
||||
window_geometry_t *get_window_geometry(xcb_window_t window) {
|
||||
|
||||
@@ -125,3 +125,27 @@ bool send_event(xcb_window_t window, atom_t atom) {
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
int32_t get_window_state(xcb_window_t window) {
|
||||
xcb_icccm_wm_hints_t hints;
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints(conn, window);
|
||||
if (!xcb_icccm_get_wm_hints_reply(conn, cookie, &hints, NULL)) return -1;
|
||||
return hints.initial_state;
|
||||
}
|
||||
|
||||
void set_window_state(xcb_window_t window, wm_state_t state) {
|
||||
xcb_icccm_wm_hints_t hints;
|
||||
xcb_icccm_wm_hints_set_none(&hints);
|
||||
switch (state) {
|
||||
case wm_state_withdrawn:
|
||||
xcb_icccm_wm_hints_set_withdrawn(&hints);
|
||||
break;
|
||||
case wm_state_normal:
|
||||
xcb_icccm_wm_hints_set_normal(&hints);
|
||||
break;
|
||||
case wm_state_iconic:
|
||||
xcb_icccm_wm_hints_set_iconic(&hints);
|
||||
break;
|
||||
}
|
||||
xcb_icccm_set_wm_hints(conn, window, &hints);
|
||||
}
|
||||
|
||||
@@ -185,8 +185,9 @@ window_list_t *scan_window_list(void) {
|
||||
xcb_window_t *list = xcb_query_tree_children(tree_reply);
|
||||
int len = xcb_query_tree_children_length(tree_reply);
|
||||
|
||||
uint32_t count = 0;
|
||||
xcb_window_t temp_window_array[len];
|
||||
uint32_t normal_count = 0, transient_count = 0;
|
||||
xcb_window_t normal_window_array[len];
|
||||
xcb_window_t transient_window_array[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
xcb_window_t window = list[i];
|
||||
|
||||
@@ -199,34 +200,47 @@ window_list_t *scan_window_list(void) {
|
||||
uint8_t override_redirect = attribute_reply->override_redirect;
|
||||
uint8_t map_state = attribute_reply->map_state;
|
||||
free(attribute_reply);
|
||||
if (override_redirect || map_state != XCB_MAP_STATE_VIEWABLE) continue;
|
||||
if (!(map_state == XCB_MAP_STATE_VIEWABLE ||
|
||||
get_window_state(window) == wm_state_iconic)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
xcb_window_t transient_for = XCB_NONE;
|
||||
xcb_get_property_cookie_t p_cookie =
|
||||
xcb_icccm_get_wm_transient_for(conn, window);
|
||||
xcb_icccm_get_wm_transient_for_reply(conn, p_cookie, &transient_for, NULL);
|
||||
if (transient_for != XCB_NONE) continue;
|
||||
|
||||
temp_window_array[count] = window;
|
||||
count++;
|
||||
xcb_window_t transient_for = get_transient_window_for(window);
|
||||
if (transient_for) {
|
||||
transient_window_array[transient_count++] = window;
|
||||
} else if (!override_redirect) {
|
||||
normal_window_array[normal_count++] = window;
|
||||
}
|
||||
}
|
||||
free(tree_reply);
|
||||
|
||||
if (!count) return NULL;
|
||||
|
||||
xcb_window_t *window_list = ecalloc(count, sizeof(xcb_window_t));
|
||||
for (uint32_t i = 0; i < count; i++) window_list[i] = temp_window_array[i];
|
||||
if ((!normal_count) && (!transient_count)) return NULL;
|
||||
|
||||
window_list_t *r = ecalloc(1, sizeof(window_list_t));
|
||||
r->count = count;
|
||||
r->list = window_list;
|
||||
r->normal_count = normal_count;
|
||||
r->transient_count = transient_count;
|
||||
|
||||
if (normal_count) {
|
||||
r->normal_list = ecalloc(normal_count, sizeof(xcb_window_t));
|
||||
for (uint32_t i = 0; i < normal_count; i++) {
|
||||
r->normal_list[i] = normal_window_array[i];
|
||||
}
|
||||
}
|
||||
if (transient_count) {
|
||||
r->transient_list = ecalloc(transient_count, sizeof(xcb_window_t));
|
||||
for (uint32_t i = 0; i < transient_count; i++) {
|
||||
r->transient_list[i] = transient_window_array[i];
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void free_window_list(window_list_t *window_list) {
|
||||
if (window_list == NULL) return;
|
||||
free(window_list->list);
|
||||
|
||||
if (window_list->normal_list) free(window_list->normal_list);
|
||||
if (window_list->transient_list) free(window_list->transient_list);
|
||||
free(window_list);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user