throw out some old code from manage.c, cleanups

This commit is contained in:
Michael Stapelberg 2010-04-17 18:26:46 +02:00
parent 42bed06b9a
commit b0f47b25a0
3 changed files with 58 additions and 194 deletions

View File

@ -172,4 +172,7 @@ int predict_text_width(xcb_connection_t *conn, const char *font_pattern, char *t
*/ */
void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r); void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r);
bool xcb_reply_contains_atom(xcb_get_property_reply_t *prop, xcb_atom_t atom);
#endif #endif

View File

@ -169,33 +169,31 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
if (xcb_request_check(conn, rcookie) != NULL) { if (xcb_request_check(conn, rcookie) != NULL) {
LOG("Could not reparent the window, aborting\n"); LOG("Could not reparent the window, aborting\n");
goto out; goto out;
//xcb_destroy_window(conn, nc->frame);
} }
xcb_atom_t *state; xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, state_cookie, NULL);
xcb_get_property_reply_t *preply; if (xcb_reply_contains_atom(reply, atoms[_NET_WM_STATE_FULLSCREEN]))
if ((preply = xcb_get_property_reply(conn, state_cookie, NULL)) != NULL && con_toggle_fullscreen(nc);
(state = xcb_get_property_value(preply)) != NULL) {
/* Check all set _NET_WM_STATEs */
for (int i = 0; i < xcb_get_property_value_length(preply); i++) {
if (state[i] != atoms[_NET_WM_STATE_FULLSCREEN])
continue;
con_toggle_fullscreen(nc);
break;
}
}
reply = xcb_get_property_reply(conn, wm_type_cookie, NULL);
if (xcb_reply_contains_atom(reply, atoms[_NET_WM_WINDOW_TYPE_DOCK]))
LOG("this window is a dock\n");
if (xcb_reply_contains_atom(reply, atoms[_NET_WM_WINDOW_TYPE_DIALOG]) ||
xcb_reply_contains_atom(reply, atoms[_NET_WM_WINDOW_TYPE_UTILITY]) ||
xcb_reply_contains_atom(reply, atoms[_NET_WM_WINDOW_TYPE_TOOLBAR]) ||
xcb_reply_contains_atom(reply, atoms[_NET_WM_WINDOW_TYPE_SPLASH]))
LOG("This window is a dialog window\n");
/* Put the client inside the save set. Upon termination (whether killed or
* normal exit does not matter) of the window manager, these clients will
* be correctly reparented to their most closest living ancestor (=
* cleanup) */
xcb_change_save_set(conn, XCB_SET_MODE_INSERT, window); xcb_change_save_set(conn, XCB_SET_MODE_INSERT, window);
tree_render(); tree_render();
#if 0
/* Reparent the window and add it to our list of managed windows */
reparent_window(conn, window, attr->visual, geom->root, geom->depth,
geom->x, geom->y, geom->width, geom->height,
geom->border_width);
#endif
free(geom); free(geom);
out: out:
free(attr); free(attr);
@ -203,119 +201,18 @@ out:
} }
#if 0 #if 0
/*
* reparent_window() gets called when a new window was opened and becomes a child of the root
* window, or it gets called by us when we manage the already existing windows at startup.
*
* Essentially, this is the point where we take over control.
*
*/
void reparent_window(xcb_connection_t *conn, xcb_window_t child, void reparent_window(xcb_connection_t *conn, xcb_window_t child,
xcb_visualid_t visual, xcb_window_t root, uint8_t depth, xcb_visualid_t visual, xcb_window_t root, uint8_t depth,
int16_t x, int16_t y, uint16_t width, uint16_t height, int16_t x, int16_t y, uint16_t width, uint16_t height,
uint32_t border_width) { uint32_t border_width) {
xcb_get_property_cookie_t wm_type_cookie, strut_cookie, state_cookie, /* Minimum useful size for managed windows is 75x50 (primarily affects floating) */
utf8_title_cookie, title_cookie,
class_cookie, leader_cookie;
uint32_t mask = 0;
uint32_t values[3];
uint16_t original_height = height;
bool map_frame = true;
/* We are interested in property changes */
mask = XCB_CW_EVENT_MASK;
values[0] = CHILD_EVENT_MASK;
xcb_change_window_attributes(conn, child, mask, values);
/* Place requests for properties ASAP */
wm_type_cookie = xcb_get_any_property_unchecked(conn, false, child, atoms[_NET_WM_WINDOW_TYPE], UINT32_MAX);
strut_cookie = xcb_get_any_property_unchecked(conn, false, child, atoms[_NET_WM_STRUT_PARTIAL], UINT32_MAX);
state_cookie = xcb_get_any_property_unchecked(conn, false, child, atoms[_NET_WM_STATE], UINT32_MAX);
utf8_title_cookie = xcb_get_any_property_unchecked(conn, false, child, atoms[_NET_WM_NAME], 128);
leader_cookie = xcb_get_any_property_unchecked(conn, false, child, atoms[WM_CLIENT_LEADER], UINT32_MAX);
title_cookie = xcb_get_any_property_unchecked(conn, false, child, WM_NAME, 128);
class_cookie = xcb_get_any_property_unchecked(conn, false, child, WM_CLASS, 128);
Client *new = table_get(&by_child, child);
/* Events for already managed windows should already be filtered in manage_window() */
assert(new == NULL);
LOG("Managing window 0x%08x\n", child);
DLOG("x = %d, y = %d, width = %d, height = %d\n", x, y, width, height);
new = scalloc(sizeof(Client));
new->force_reconfigure = true;
/* Update the data structures */
Client *old_focused = CUR_CELL->currently_focused;
new->container = CUR_CELL;
new->workspace = new->container->workspace;
/* Minimum useful size for managed windows is 75x50 (primarily affects floating) */
width = max(width, 75); width = max(width, 75);
height = max(height, 50); height = max(height, 50);
new->frame = xcb_generate_id(conn);
new->child = child;
new->rect.width = width;
new->rect.height = height;
new->width_increment = 1;
new->height_increment = 1;
new->border_width = border_width;
/* Pre-initialize the values for floating */
new->floating_rect.x = -1;
new->floating_rect.width = width;
new->floating_rect.height = height;
if (config.default_border != NULL) if (config.default_border != NULL)
client_init_border(conn, new, config.default_border[1]); client_init_border(conn, new, config.default_border[1]);
mask = 0;
/* Dont generate events for our new window, it should *not* be managed */
mask |= XCB_CW_OVERRIDE_REDIRECT;
values[0] = 1;
/* We want to know when… */
mask |= XCB_CW_EVENT_MASK;
values[1] = FRAME_EVENT_MASK;
i3Font *font = load_font(conn, config.font);
width = min(width, c_ws->rect.x + c_ws->rect.width);
height = min(height, c_ws->rect.y + c_ws->rect.height);
Rect framerect = {x, y,
width + 2 + 2, /* 2 px border at each side */
height + 2 + 2 + font->height}; /* 2 px border plus fonts height */
/* Yo dawg, I heard you like windows, so I create a window around your window… */
new->frame = create_window(conn, framerect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, false, mask, values);
/* Put the client inside the save set. Upon termination (whether killed or normal exit
does not matter) of the window manager, these clients will be correctly reparented
to their most closest living ancestor (= cleanup) */
xcb_change_save_set(conn, XCB_SET_MODE_INSERT, child);
/* Generate a graphics context for the titlebar */
new->titlegc = xcb_generate_id(conn);
xcb_create_gc(conn, new->titlegc, new->frame, 0, 0);
/* Moves the original window into the new frame we've created for it */
new->awaiting_useless_unmap = true;
xcb_void_cookie_t cookie = xcb_reparent_window_checked(conn, child, new->frame, 0, font->height);
if (xcb_request_check(conn, cookie) != NULL) {
DLOG("Could not reparent the window, aborting\n");
xcb_destroy_window(conn, new->frame);
free(new);
return;
}
/* Put our data structure (Client) into the table */
table_put(&by_parent, new->frame, new);
table_put(&by_child, child, new);
/* We need to grab the mouse buttons for click to focus */ /* We need to grab the mouse buttons for click to focus */
xcb_grab_button(conn, false, child, XCB_EVENT_MASK_BUTTON_PRESS, xcb_grab_button(conn, false, child, XCB_EVENT_MASK_BUTTON_PRESS,
XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
@ -327,36 +224,22 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
3 /* right mouse button */, 3 /* right mouse button */,
XCB_BUTTON_MASK_ANY /* dont filter for any modifiers */); XCB_BUTTON_MASK_ANY /* dont filter for any modifiers */);
/* Get _NET_WM_WINDOW_TYPE (to see if its a dock) */ if (dock) {
xcb_atom_t *atom; DLOG("Window is a dock.\n");
xcb_get_property_reply_t *preply = xcb_get_property_reply(conn, wm_type_cookie, NULL); Output *t_out = get_output_containing(x, y);
if (preply != NULL && preply->value_len > 0 && (atom = xcb_get_property_value(preply))) { if (t_out != c_ws->output) {
for (int i = 0; i < xcb_get_property_value_length(preply); i++) DLOG("Dock client requested to be on output %s by geometry (%d, %d)\n",
if (atom[i] == atoms[_NET_WM_WINDOW_TYPE_DOCK]) { t_out->name, x, y);
DLOG("Window is a dock.\n"); new->workspace = t_out->current_workspace;
Output *t_out = get_output_containing(x, y); }
if (t_out != c_ws->output) { new->dock = true;
DLOG("Dock client requested to be on output %s by geometry (%d, %d)\n", new->borderless = true;
t_out->name, x, y); new->titlebar_position = TITLEBAR_OFF;
new->workspace = t_out->current_workspace; new->force_reconfigure = true;
} new->container = NULL;
new->dock = true; SLIST_INSERT_HEAD(&(t_out->dock_clients), new, dock_clients);
new->borderless = true; /* If its a dock we cant make it float, so we break */
new->titlebar_position = TITLEBAR_OFF; new->floating = FLOATING_AUTO_OFF;
new->force_reconfigure = true;
new->container = NULL;
SLIST_INSERT_HEAD(&(t_out->dock_clients), new, dock_clients);
/* If its a dock we cant make it float, so we break */
new->floating = FLOATING_AUTO_OFF;
break;
} else if (atom[i] == atoms[_NET_WM_WINDOW_TYPE_DIALOG] ||
atom[i] == atoms[_NET_WM_WINDOW_TYPE_UTILITY] ||
atom[i] == atoms[_NET_WM_WINDOW_TYPE_TOOLBAR] ||
atom[i] == atoms[_NET_WM_WINDOW_TYPE_SPLASH]) {
/* Set the dialog window to automatically floating, will be used below */
new->floating = FLOATING_AUTO_ON;
DLOG("dialog/utility/toolbar/splash window, automatically floating\n");
}
} }
/* All clients which have a leader should be floating */ /* All clients which have a leader should be floating */
@ -465,34 +348,6 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
} }
} }
if (new->workspace->fullscreen_client != NULL) {
DLOG("Setting below fullscreen window\n");
/* If we are in fullscreen, we should place the window below
* the fullscreen window to not be annoying */
uint32_t values[] = {
new->workspace->fullscreen_client->frame,
XCB_STACK_MODE_BELOW
};
xcb_configure_window(conn, new->frame,
XCB_CONFIG_WINDOW_SIBLING |
XCB_CONFIG_WINDOW_STACK_MODE, values);
}
/* Insert into the currently active container, if its not a dock window */
if (!new->dock && !client_is_floating(new)) {
/* Insert after the old active client, if existing. If it does not exist, the
container is empty and it does not matter, where we insert it */
if (old_focused != NULL && !old_focused->dock)
CIRCLEQ_INSERT_AFTER(&(new->container->clients), old_focused, new, clients);
else CIRCLEQ_INSERT_TAIL(&(new->container->clients), new, clients);
if (new->container->workspace->fullscreen_client != NULL)
SLIST_INSERT_AFTER(new->container->workspace->fullscreen_client, new, focus_clients);
else SLIST_INSERT_HEAD(&(new->container->workspace->focus_stack), new, focus_clients);
client_set_below_floating(conn, new);
}
if (client_is_floating(new)) { if (client_is_floating(new)) {
SLIST_INSERT_HEAD(&(new->workspace->focus_stack), new, focus_clients); SLIST_INSERT_HEAD(&(new->workspace->focus_stack), new, focus_clients);
@ -539,20 +394,6 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
new->initialized = true; new->initialized = true;
/* Check if the window already got the fullscreen hint set */
xcb_atom_t *state;
if ((preply = xcb_get_property_reply(conn, state_cookie, NULL)) != NULL &&
(state = xcb_get_property_value(preply)) != NULL)
/* Check all set _NET_WM_STATEs */
for (int i = 0; i < xcb_get_property_value_length(preply); i++) {
if (state[i] != atoms[_NET_WM_STATE_FULLSCREEN])
continue;
/* If the window got the fullscreen state, we just toggle fullscreen
and dont event bother to redraw the layout that would not change
anything anyways */
client_toggle_fullscreen(conn, new);
goto map;
}
render_layout(conn); render_layout(conn);

View File

@ -328,3 +328,23 @@ void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r) {
/* ignore events which are generated because we configured a window */ /* ignore events which are generated because we configured a window */
add_ignore_event(cookie.sequence); add_ignore_event(cookie.sequence);
} }
/*
* Returns true if the given reply contains the given atom.
*
*/
bool xcb_reply_contains_atom(xcb_get_property_reply_t *prop, xcb_atom_t atom) {
if (prop == NULL || xcb_get_property_value_length(prop) == 0)
return false;
xcb_atom_t *atoms;
if ((atoms = xcb_get_property_value(prop)) == NULL)
return false;
for (int i = 0; i < xcb_get_property_value_length(prop); i++)
if (atoms[i] == atom)
return true;
return false;
}