From: Dana Jansens Date: Tue, 13 Mar 2007 02:29:08 +0000 (+0000) Subject: save and restore pre-maximized/fullscreen sizes properly X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=7f58bd9eaaa8285a743be4b7b210568cfe588e3e;p=chaz%2Fopenbox save and restore pre-maximized/fullscreen sizes properly much cleanup on how per-app settings are applied to new mapping windows. maybe i broke it? but it'll be much quicker now, and it's consistant with the rest of the code, so hooray for that. pls let me know if i broke any of it :( hee.. --- diff --git a/openbox/action.c b/openbox/action.c index 73eadf8d..eca4707a 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -1359,14 +1359,14 @@ void action_resize_relative(union ActionData *data) void action_maximize_full(union ActionData *data) { client_action_start(data); - client_maximize(data->client.any.c, TRUE, 0, TRUE); + client_maximize(data->client.any.c, TRUE, 0); client_action_end(data); } void action_unmaximize_full(union ActionData *data) { client_action_start(data); - client_maximize(data->client.any.c, FALSE, 0, TRUE); + client_maximize(data->client.any.c, FALSE, 0); client_action_end(data); } @@ -1376,21 +1376,21 @@ void action_toggle_maximize_full(union ActionData *data) client_maximize(data->client.any.c, !(data->client.any.c->max_horz || data->client.any.c->max_vert), - 0, TRUE); + 0); client_action_end(data); } void action_maximize_horz(union ActionData *data) { client_action_start(data); - client_maximize(data->client.any.c, TRUE, 1, TRUE); + client_maximize(data->client.any.c, TRUE, 1); client_action_end(data); } void action_unmaximize_horz(union ActionData *data) { client_action_start(data); - client_maximize(data->client.any.c, FALSE, 1, TRUE); + client_maximize(data->client.any.c, FALSE, 1); client_action_end(data); } @@ -1398,21 +1398,21 @@ void action_toggle_maximize_horz(union ActionData *data) { client_action_start(data); client_maximize(data->client.any.c, - !data->client.any.c->max_horz, 1, TRUE); + !data->client.any.c->max_horz, 1); client_action_end(data); } void action_maximize_vert(union ActionData *data) { client_action_start(data); - client_maximize(data->client.any.c, TRUE, 2, TRUE); + client_maximize(data->client.any.c, TRUE, 2); client_action_end(data); } void action_unmaximize_vert(union ActionData *data) { client_action_start(data); - client_maximize(data->client.any.c, FALSE, 2, TRUE); + client_maximize(data->client.any.c, FALSE, 2); client_action_end(data); } @@ -1420,15 +1420,14 @@ void action_toggle_maximize_vert(union ActionData *data) { client_action_start(data); client_maximize(data->client.any.c, - !data->client.any.c->max_vert, 2, TRUE); + !data->client.any.c->max_vert, 2); client_action_end(data); } void action_toggle_fullscreen(union ActionData *data) { client_action_start(data); - client_fullscreen(data->client.any.c, - !(data->client.any.c->fullscreen), TRUE); + client_fullscreen(data->client.any.c, !(data->client.any.c->fullscreen)); client_action_end(data); } diff --git a/openbox/client.c b/openbox/client.c index b561f4e2..f07f2dfe 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -74,9 +74,10 @@ static void client_get_gravity(ObClient *self); static void client_showhide(ObClient *self); static void client_change_allowed_actions(ObClient *self); static void client_change_state(ObClient *self); -static void client_apply_startup_state(ObClient *self); +static void client_apply_startup_state(ObClient *self, gint x, gint y); static void client_restore_session_state(ObClient *self); static void client_restore_session_stacking(ObClient *self); +static ObAppSettings *client_get_settings_state(ObClient *self); void client_startup(gboolean reconfig) { @@ -205,33 +206,6 @@ void client_manage_all() XFree(children); } -static ObAppSettings *get_settings(ObClient *client) -{ - GSList *a = config_per_app_settings; - - while (a) { - ObAppSettings *app = (ObAppSettings *) a->data; - - if ( - (app->name && !app->class && !strcmp(app->name, client->name)) - || (app->class && !app->name && !strcmp(app->class, client->class)) - || (app->class && app->name && !strcmp(app->class, client->class) - && !strcmp(app->name, client->name)) - ) { - ob_debug("Window matching: %s\n", app->name); - /* Match if no role was specified in the per app setting, or if the - * string matches the beginning of the role, since apps like to set - * the role to things like browser-window-23c4b2f */ - if (!app->role - || !strncmp(app->role, client->role, strlen(app->role))) - return app; - } - - a = a->next; - } - return NULL; -} - void client_manage(Window window) { ObClient *self; @@ -241,6 +215,7 @@ void client_manage(Window window) XWMHints *wmhint; gboolean activate = FALSE; ObAppSettings *settings; + gint newx, newy; grab_server(TRUE); @@ -300,6 +275,9 @@ void client_manage(Window window) client_get_all(self); client_restore_session_state(self); + /* per-app settings override stuff, and return the settings for other + uses too */ + settings = client_get_settings_state(self); client_calc_layer(self); @@ -328,57 +306,9 @@ void client_manage(Window window) grab_server(FALSE); - client_apply_startup_state(self); - - /* get and set application level settings */ - settings = get_settings(self); - stacking_add_nonintrusive(CLIENT_AS_WINDOW(self)); client_restore_session_stacking(self); - if (settings) { - /* Don't worry, we won't actually both shade and undecorate the - * window when push comes to shove. */ - if (settings->shade != -1) - client_shade(self, !!settings->shade); - if (settings->decor != -1) - client_set_undecorated(self, !settings->decor); - if (settings->iconic != -1) - client_iconify(self, !!settings->iconic, FALSE); - if (settings->skip_pager != -1) { - self->skip_pager = !!settings->skip_pager; - client_change_state(self); - } - if (settings->skip_taskbar != -1) { - self->skip_taskbar = !!settings->skip_taskbar; - client_change_state(self); - } - - /* 1 && -1 shouldn't be possible by the code in config.c */ - if (settings->max_vert == 1 && settings->max_horz == 1) - client_maximize(self, TRUE, 0, TRUE); - else if (settings->max_vert == 0 && settings->max_horz == 0) - client_maximize(self, FALSE, 0, TRUE); - else if (settings->max_vert == 1 && settings->max_horz == 0) { - client_maximize(self, TRUE, 2, TRUE); - client_maximize(self, FALSE, 1, TRUE); - } else if (settings->max_vert == 0 && settings->max_horz == 1) { - client_maximize(self, TRUE, 1, TRUE); - client_maximize(self, FALSE, 2, TRUE); - } - - if (settings->fullscreen != -1) - client_fullscreen(self, !!settings->fullscreen, TRUE); - - if (settings->desktop < screen_num_desktops - || settings->desktop == DESKTOP_ALL) - client_set_desktop(self, settings->desktop, TRUE); - - if (settings->layer > -2 && settings->layer < 2) - client_set_layer(self, settings->layer); - - } - /* focus the new window? */ if (ob_state() != OB_STATE_STARTING && /* this means focus=true for window is same as config_focus_new=true */ @@ -426,15 +356,18 @@ void client_manage(Window window) #endif } + /* get the current position */ + newx = self->area.x; + newy = self->area.y; + + /* figure out placement for the window */ if (ob_state() == OB_STATE_RUNNING) { - gint x = self->area.x, ox = x; - gint y = self->area.y, oy = y; gboolean transient; - transient = place_client(self, &x, &y, settings); + transient = place_client(self, &newx, &newy, settings); /* make sure the window is visible. */ - client_find_onscreen(self, &x, &y, + client_find_onscreen(self, &newx, &newy, self->frame->area.width, self->frame->area.height, /* non-normal clients has less rules, and @@ -452,10 +385,14 @@ void client_manage(Window window) !(self->positioned & USPosition)) && client_normal(self) && !self->session)); - if (x != ox || y != oy) - client_move(self, x, y); } + /* do this after the window is placed, so the premax/prefullscreen numbers + won't be all wacko!! + also, this moves the window to the position where it has been placed + */ + client_apply_startup_state(self, newx, newy); + keyboard_grab_for_client(self, TRUE); mouse_grab_for_client(self, TRUE); @@ -636,6 +573,27 @@ void client_unmanage(ObClient *self) /* reparent the window out of the frame, and free the frame */ frame_release_client(self->frame, self); self->frame = NULL; + + /* restore the window's original geometry so it is not lost */ + if (self->fullscreen) + XMoveResizeWindow(ob_display, self->window, + self->pre_fullscreen_area.x, + self->pre_fullscreen_area.y, + self->pre_fullscreen_area.width, + self->pre_fullscreen_area.height); + else if (self->max_horz || self->max_vert) { + Rect a = self->area; + if (self->max_horz) { + a.x = self->pre_max_area.x; + a.width = self->pre_max_area.width; + } + if (self->max_vert) { + a.y = self->pre_max_area.y; + a.height = self->pre_max_area.height; + } + XMoveResizeWindow(ob_display, self->window, + a.x, a.y, a.width, a.height); + } if (ob_state() != OB_STATE_EXITING) { /* these values should not be persisted across a window @@ -673,6 +631,73 @@ void client_unmanage(ObClient *self) grab_pointer(FALSE, OB_CURSOR_NONE); } +static ObAppSettings *client_get_settings_state(ObClient *self) +{ + ObAppSettings *settings = NULL; + GSList *it; + + for (it = config_per_app_settings; it; it = g_slist_next(it)) { + ObAppSettings *app; + + if ((app->name && !app->class && !strcmp(app->name, self->name)) + || (app->class && !app->name && !strcmp(app->class, self->class)) + || (app->class && app->name && !strcmp(app->class, self->class) + && !strcmp(app->name, self->name))) + { + ob_debug("Window matching: %s\n", app->name); + /* Match if no role was specified in the per app setting, or if the + * string matches the beginning of the role, since apps like to set + * the role to things like browser-window-23c4b2f */ + if (!app->role + || !strncmp(app->role, self->role, strlen(app->role))) + { + /* use this one */ + settings = app; + break; + } + } + } + + if (settings) { + if (settings->shade != -1) + self->shaded = !!settings->shade; + if (settings->decor != -1) + self->undecorated = !settings->decor; + if (settings->iconic != -1) + self->iconic = !!settings->iconic; + if (settings->skip_pager != -1) + self->skip_pager = !!settings->skip_pager; + if (settings->skip_taskbar != -1) + self->skip_taskbar = !!settings->skip_taskbar; + + if (settings->max_vert != -1) + self->max_vert = !!settings->max_vert; + if (settings->max_horz != -1) + self->max_vert = !!settings->max_horz; + + if (settings->fullscreen != -1) + self->fullscreen = !!settings->fullscreen; + + if (settings->desktop < screen_num_desktops + || settings->desktop == DESKTOP_ALL) + client_set_desktop(self, settings->desktop, TRUE); + + if (settings->layer == -1) { + self->below = TRUE; + self->above = FALSE; + } + else if (settings->layer == 0) { + self->below = FALSE; + self->above = FALSE; + } + else if (settings->layer == 1) { + self->below = FALSE; + self->above = TRUE; + } + } + return settings; +} + static void client_restore_session_state(ObClient *self) { GList *it; @@ -935,6 +960,9 @@ static void client_get_area(ObClient *self) RECT_SET(self->area, wattrib.x, wattrib.y, wattrib.width, wattrib.height); self->border_width = wattrib.border_width; + + ob_debug("client area: %d %d %d %d\n", wattrib.x, wattrib.y, + wattrib.width, wattrib.height); } static void client_get_desktop(ObClient *self) @@ -1511,12 +1539,12 @@ static void client_change_allowed_actions(ObClient *self) else self->iconic = FALSE; } if (!(self->functions & OB_CLIENT_FUNC_FULLSCREEN) && self->fullscreen) { - if (self->frame) client_fullscreen(self, FALSE, TRUE); + if (self->frame) client_fullscreen(self, FALSE); else self->fullscreen = FALSE; } if (!(self->functions & OB_CLIENT_FUNC_MAXIMIZE) && (self->max_horz || self->max_vert)) { - if (self->frame) client_maximize(self, FALSE, 0, TRUE); + if (self->frame) client_maximize(self, FALSE, 0); else self->max_vert = self->max_horz = FALSE; } } @@ -2080,8 +2108,17 @@ gboolean client_normal(ObClient *self) { self->type == OB_CLIENT_TYPE_SPLASH); } -static void client_apply_startup_state(ObClient *self) +static void client_apply_startup_state(ObClient *self, gint x, gint y) { + gboolean pos = FALSE; /* has the window's position been configured? */ + gint ox, oy; + + /* save the position, and set self->area for these to use */ + ox = self->area.x; + oy = self->area.y; + self->area.x = x; + self->area.y = y; + /* these are in a carefully crafted order.. */ if (self->iconic) { @@ -2090,7 +2127,8 @@ static void client_apply_startup_state(ObClient *self) } if (self->fullscreen) { self->fullscreen = FALSE; - client_fullscreen(self, TRUE, FALSE); + client_fullscreen(self, TRUE); + pos = TRUE; } if (self->undecorated) { self->undecorated = FALSE; @@ -2107,13 +2145,24 @@ static void client_apply_startup_state(ObClient *self) if (self->max_vert && self->max_horz) { self->max_vert = self->max_horz = FALSE; - client_maximize(self, TRUE, 0, FALSE); + client_maximize(self, TRUE, 0); + pos = TRUE; } else if (self->max_vert) { self->max_vert = FALSE; - client_maximize(self, TRUE, 2, FALSE); + client_maximize(self, TRUE, 2); + pos = TRUE; } else if (self->max_horz) { self->max_horz = FALSE; - client_maximize(self, TRUE, 1, FALSE); + client_maximize(self, TRUE, 1); + pos = TRUE; + } + + /* if the client didn't get positioned yet, then do so now */ + if (!pos && (ox != x || oy != y)) { + /* use the saved position */ + self->area.x = ox; + self->area.y = oy; + client_move(self, x, y); } /* nothing to do for the other states: @@ -2351,7 +2400,7 @@ void client_configure_full(ObClient *self, ObCorner anchor, XFlush(ob_display); } -void client_fullscreen(ObClient *self, gboolean fs, gboolean savearea) +void client_fullscreen(ObClient *self, gboolean fs) { gint x, y, w, h; @@ -2363,8 +2412,17 @@ void client_fullscreen(ObClient *self, gboolean fs, gboolean savearea) client_calc_layer(self); /* and adjust out layer/stacking */ if (fs) { - if (savearea) - self->pre_fullscreen_area = self->area; + self->pre_fullscreen_area = self->area; + /* if the window is maximized, its area isn't all that meaningful. + save it's premax area instead. */ + if (self->max_horz) { + self->pre_fullscreen_area.x = self->pre_max_area.x; + self->pre_fullscreen_area.width = self->pre_max_area.width; + } + if (self->max_vert) { + self->pre_fullscreen_area.y = self->pre_max_area.y; + self->pre_fullscreen_area.height = self->pre_max_area.height; + } /* these are not actually used cuz client_configure will set them as appropriate when the window is fullscreened */ @@ -2473,7 +2531,7 @@ void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk) client_iconify_recursive(self, iconic, curdesk); } -void client_maximize(ObClient *self, gboolean max, gint dir, gboolean savearea) +void client_maximize(ObClient *self, gboolean max, gint dir) { gint x, y, w, h; @@ -2499,17 +2557,15 @@ void client_maximize(ObClient *self, gboolean max, gint dir, gboolean savearea) h = self->area.height; if (max) { - if (savearea) { - if ((dir == 0 || dir == 1) && !self->max_horz) { /* horz */ - RECT_SET(self->pre_max_area, - self->area.x, self->pre_max_area.y, - self->area.width, self->pre_max_area.height); - } - if ((dir == 0 || dir == 2) && !self->max_vert) { /* vert */ - RECT_SET(self->pre_max_area, - self->pre_max_area.x, self->area.y, - self->pre_max_area.width, self->area.height); - } + if ((dir == 0 || dir == 1) && !self->max_horz) { /* horz */ + RECT_SET(self->pre_max_area, + self->area.x, self->pre_max_area.y, + self->area.width, self->pre_max_area.height); + } + if ((dir == 0 || dir == 2) && !self->max_vert) { /* vert */ + RECT_SET(self->pre_max_area, + self->pre_max_area.x, self->area.y, + self->pre_max_area.width, self->area.height); } } else { Rect *a; @@ -2857,23 +2913,23 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) if (max_horz != self->max_horz && max_vert != self->max_vert) { /* toggling both */ if (max_horz == max_vert) { /* both going the same way */ - client_maximize(self, max_horz, 0, TRUE); + client_maximize(self, max_horz, 0); } else { - client_maximize(self, max_horz, 1, TRUE); - client_maximize(self, max_vert, 2, TRUE); + client_maximize(self, max_horz, 1); + client_maximize(self, max_vert, 2); } } else { /* toggling one */ if (max_horz != self->max_horz) - client_maximize(self, max_horz, 1, TRUE); + client_maximize(self, max_horz, 1); else - client_maximize(self, max_vert, 2, TRUE); + client_maximize(self, max_vert, 2); } } /* change fullscreen state before shading, as it will affect if the window can shade or not */ if (fullscreen != self->fullscreen) - client_fullscreen(self, fullscreen, TRUE); + client_fullscreen(self, fullscreen); if (shaded != self->shaded) client_shade(self, shaded); if (undecorated != self->undecorated) diff --git a/openbox/client.h b/openbox/client.h index 845d9ad2..2e5766e2 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -397,12 +397,8 @@ void client_move_onscreen(ObClient *self, gboolean rude); /*! Fullscreen's or unfullscreen's the client window @param fs true if the window should be made fullscreen; false if it should be returned to normal state. - @param savearea true to have the client's current size and position saved; - otherwise, they are not. You should not save when mapping a - new window that is set to fullscreen. This has no effect - when restoring a window from fullscreen. */ -void client_fullscreen(ObClient *self, gboolean fs, gboolean savearea); +void client_fullscreen(ObClient *self, gboolean fs); /*! Iconifies or uniconifies the client window @param iconic true if the window should be iconified; false if it should be @@ -417,13 +413,8 @@ void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk); @param max true if the window should be maximized; false if it should be returned to normal size. @param dir 0 to set both horz and vert, 1 to set horz, 2 to set vert. - @param savearea true to have the client's current size and position saved; - otherwise, they are not. You should not save when mapping a - new window that is set to fullscreen. This has no effect - when unmaximizing a window. */ -void client_maximize(ObClient *self, gboolean max, gint dir, - gboolean savearea); +void client_maximize(ObClient *self, gboolean max, gint dir); /*! Shades or unshades the client window @param shade true if the window should be shaded; false if it should be