diff options
author | MC <mc@hack.org> | 2010-07-07 15:09:00 +0200 |
---|---|---|
committer | MC <mc@hack.org> | 2010-07-07 15:09:00 +0200 |
commit | a74a68bfc13dee191855221e04d62ef8f5e86b68 (patch) | |
tree | b35914544a1ad527c5a0623385a3f65ab5e63e03 /mcwm.c | |
parent | a8241b27a795c16cf6a91f47bc3663fde845d175 (diff) | |
download | mcwm-a74a68bfc13dee191855221e04d62ef8f5e86b68.zip |
First, perhaps naive, implementation to rearrange windows when screen
size changes, that is when the user removed a physical screen or
tilted her screen.
Diffstat (limited to 'mcwm.c')
-rw-r--r-- | mcwm.c | 141 |
1 files changed, 128 insertions, 13 deletions
@@ -177,6 +177,7 @@ xcb_atom_t atom_desktop; /* Functions declerations. */ +void arrangewindows(int32_t rootwidth, int32_t rootheight); void setwmdesktop(xcb_drawable_t win, uint32_t ws); int32_t getwmdesktop(xcb_drawable_t win); void addtoworkspace(struct client *client, uint32_t ws); @@ -203,6 +204,7 @@ void resizestep(struct client *client, char direction); void mousemove(xcb_drawable_t win, int rel_x, int rel_y); void mouseresize(xcb_drawable_t win, int rel_x, int rel_y); void movestep(struct client *client, char direction); +void unmax(struct client *client); void maximize(struct client *client); void maxvert(struct client *client); void handle_keypress(xcb_key_press_event_t *ev); @@ -211,6 +213,119 @@ void printhelp(void); /* Function bodies. */ +/* + * + * Rearrange windows to fit new screen size rootwidth x rootheight. + */ +void arrangewindows(int32_t rootwidth, int32_t rootheight) +{ + xcb_query_tree_reply_t *reply; + int i; + int len; + xcb_window_t *children; + xcb_get_window_attributes_reply_t *attr; + xcb_get_geometry_reply_t *geom; + uint32_t mask = 0; + uint32_t values[4]; + bool changed; + + PDEBUG("Rearranging all windows to fit new screen size %d x %d.\n", + rootwidth, rootheight); + + /* Get all children of the root window */ + reply = xcb_query_tree_reply(conn, + xcb_query_tree(conn, screen->root), 0); + if (NULL == reply) + { + return; + } + + len = xcb_query_tree_children_length(reply); + children = xcb_query_tree_children(reply); + + /* + * Go through all children and look at their coordinates and + * geometry. If they don't fit on the new screen, move them around + * and resize them as necessary. + */ + for (i = 0; i < len; i ++) + { + changed = false; + + attr = xcb_get_window_attributes_reply( + conn, xcb_get_window_attributes(conn, children[i]), NULL); + + if (!attr) + { + fprintf(stderr, "Couldn't get attributes for window %d.", + children[i]); + continue; + } + + /* + * Don't bother with windows in override redirect mode. + */ + if (!attr->override_redirect) + { + geom = xcb_get_geometry_reply(conn, + xcb_get_geometry(conn, children[i]), + NULL); + if (NULL == geom) + { + fprintf(stderr, "mcwm: Couldn't get geometry for win %d.\n", + children[i]); + return; + } + + PDEBUG("Win %d at %d,%d %d x %d\n", children[i], + geom->x, geom->y, geom->width, + geom->height); + + if (geom->width > rootwidth) + { + geom->width = rootwidth - BORDERWIDTH * 2; + changed = true; + } + + if (geom->height > rootheight) + { + geom->height = rootheight - BORDERWIDTH * 2; + changed = true; + } + + /* If x or y + geometry is outside of screen, move window. */ + + if (geom->x + geom->width > rootwidth) + { + geom->x = rootwidth - (geom->width + BORDERWIDTH * 2); + changed = true; + } + + if (geom->y + geom->height > rootheight) + { + geom->y = rootheight - (geom->height + BORDERWIDTH * 2);; + changed = true; + } + + if (changed) + { + PDEBUG("--- Win %d going to %d,%d %d x %d\n", children[i], + geom->x, geom->y, geom->width, geom->height); + + mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y + | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + values[0] = geom->x; + values[1] = geom->y; + values[2] = geom->width; + values[3] = geom->height; + + xcb_configure_window(conn, children[i], mask, values); + xcb_flush(conn); + } + } /* if not override_direct */ + } /* for */ +} + void setwmdesktop(xcb_drawable_t win, uint32_t ws) { PDEBUG("Changing _NET_WM_DESKTOP on window %d to %d\n", win, ws); @@ -2002,25 +2117,23 @@ void events(void) if (e->window == screen->root) { /* - * When using RANDR, the root can suddenly change - * geometry when the user adds a new screen, tilts - * their screen 90 degrees or whatnot. - * - * Since mcwm cares about the root edges, we need to - * update our view if this happens. + * When using RANDR, the root can change geometry when + * the user adds a new screen, tilts their screen 90 + * degrees or whatnot. We might need to rearrange + * windows to be visible. */ PDEBUG("Notify event for root!\n"); + if (e->width < screen->width_in_pixels + || e->height < screen->height_in_pixels) + { + arrangewindows(e->width, e->height); + } + screen->width_in_pixels = e->width; screen->height_in_pixels = e->height; PDEBUG("New root geometry: %dx%d\n", e->width, e->height); - - /* - * FIXME: If the root suddenly got a lot smaller and - * some windows are outside of the root window, we - * need to rearrange them to fit the new geometry. - */ } } break; @@ -2071,6 +2184,7 @@ void events(void) values[i] = e->height; } +#if 0 /* We handle a request to change the border width, but * only change it to what we think is right. */ @@ -2082,7 +2196,8 @@ void events(void) i ++; values[i] = BORDERWIDTH; } - +#endif + if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) { mask |= XCB_CONFIG_WINDOW_SIBLING; |