X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Fscreen.c;h=707d0b6b29fb649c9a4e897af168e4c38bdc14cb;hb=4b73574406e24df84e909014926e56ab1e5c7934;hp=720fc049c423bfcb4ce104b4e21070ea7adb4fca;hpb=de2ba8f28b85422e645c94cfdf5791cce3321264;p=chaz%2Fopenbox diff --git a/openbox/screen.c b/openbox/screen.c index 720fc049..707d0b6b 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -48,7 +48,7 @@ #define ROOT_EVENTMASK (StructureNotifyMask | PropertyChangeMask | \ EnterWindowMask | LeaveWindowMask | \ SubstructureRedirectMask | FocusChangeMask | \ - ButtonPressMask | ButtonReleaseMask | ButtonMotionMask) + ButtonPressMask | ButtonReleaseMask) static gboolean screen_validate_layout(ObDesktopLayout *l); static gboolean replace_wm(); @@ -526,9 +526,10 @@ void screen_set_num_desktops(guint num) client_set_desktop(c, num - 1, FALSE, TRUE); /* raise all the windows that are on the current desktop which is being merged */ - else if (c->desktop == DESKTOP_ALL || - c->desktop == num - 1) - stacking_raise(WINDOW_AS_CLIENT(c)); + else if (screen_desktop == num - 1 && + (c->desktop == DESKTOP_ALL || + c->desktop == screen_desktop)) + stacking_raise(CLIENT_AS_WINDOW(c)); } } @@ -630,6 +631,72 @@ void screen_set_desktop(guint num, gboolean dofocus) screen_desktop_user_time = event_curtime; } +void screen_add_desktop(gboolean current) +{ + screen_set_num_desktops(screen_num_desktops+1); + + /* move all the clients over */ + if (current) { + GList *it; + + for (it = client_list; it; it = g_list_next(it)) { + ObClient *c = it->data; + if (c->desktop != DESKTOP_ALL && c->desktop >= screen_desktop) + client_set_desktop(c, c->desktop+1, FALSE, TRUE); + } + } +} + +void screen_remove_desktop(gboolean current) +{ + guint rmdesktop, movedesktop; + GList *it, *stacking_copy; + + if (screen_num_desktops <= 1) return; + + /* what desktop are we removing and moving to? */ + if (current) + rmdesktop = screen_desktop; + else + rmdesktop = screen_num_desktops - 1; + if (rmdesktop < screen_num_desktops - 1) + movedesktop = rmdesktop + 1; + else + movedesktop = rmdesktop; + + /* make a copy of the list cuz we're changing it */ + stacking_copy = g_list_copy(stacking_list); + for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) { + if (WINDOW_IS_CLIENT(it->data)) { + ObClient *c = it->data; + guint d = c->desktop; + if (d != DESKTOP_ALL && d >= movedesktop) { + client_set_desktop(c, c->desktop - 1, TRUE, TRUE); + ob_debug("moving window %s\n", c->title); + } + /* raise all the windows that are on the current desktop which + is being merged */ + if ((screen_desktop == rmdesktop - 1 || + screen_desktop == rmdesktop) && + (d == DESKTOP_ALL || d == screen_desktop)) + { + stacking_raise(CLIENT_AS_WINDOW(c)); + ob_debug("raising window %s\n", c->title); + } + } + } + + /* act like we're changing desktops */ + if (screen_desktop < screen_num_desktops - 1) { + gint d = screen_desktop; + screen_desktop = screen_last_desktop; + screen_set_desktop(d, TRUE); + ob_debug("fake desktop change\n"); + } + + screen_set_num_desktops(screen_num_desktops-1); +} + static void get_row_col(guint d, guint *r, guint *c) { switch (screen_desktop_layout.orientation) { @@ -759,22 +826,14 @@ void screen_desktop_popup(guint d, gboolean show) } } -guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, - gboolean dialog, gboolean done, gboolean cancel) +guint screen_find_desktop(guint from, ObDirection dir, + gboolean wrap, gboolean linear) { guint r, c; - static guint d = (guint)-1; - guint ret, oldd; - - if (d == (guint)-1) - d = screen_desktop; - - if ((cancel || done) && dialog) - goto show_cycle_dialog; + guint d; - oldd = d; + d = from; get_row_col(d, &r, &c); - if (linear) { switch (dir) { case OB_DIRECTION_EAST: @@ -782,16 +841,20 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, ++d; else if (wrap) d = 0; + else + return from; break; case OB_DIRECTION_WEST: if (d > 0) --d; else if (wrap) d = screen_num_desktops - 1; + else + return from; break; default: - assert(0); - return screen_desktop; + g_assert_not_reached(); + return from; } } else { switch (dir) { @@ -801,16 +864,14 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, if (wrap) c = 0; else - goto show_cycle_dialog; + return from; } d = translate_row_col(r, c); if (d >= screen_num_desktops) { - if (wrap) { + if (wrap) ++c; - } else { - d = oldd; - goto show_cycle_dialog; - } + else + return from; } break; case OB_DIRECTION_WEST: @@ -819,16 +880,14 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, if (wrap) c = screen_desktop_layout.columns - 1; else - goto show_cycle_dialog; + return from; } d = translate_row_col(r, c); if (d >= screen_num_desktops) { - if (wrap) { + if (wrap) --c; - } else { - d = oldd; - goto show_cycle_dialog; - } + else + return from; } break; case OB_DIRECTION_SOUTH: @@ -837,16 +896,14 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, if (wrap) r = 0; else - goto show_cycle_dialog; + return from; } d = translate_row_col(r, c); if (d >= screen_num_desktops) { - if (wrap) { + if (wrap) ++r; - } else { - d = oldd; - goto show_cycle_dialog; - } + else + return from; } break; case OB_DIRECTION_NORTH: @@ -855,30 +912,41 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, if (wrap) r = screen_desktop_layout.rows - 1; else - goto show_cycle_dialog; + return from; } d = translate_row_col(r, c); if (d >= screen_num_desktops) { - if (wrap) { + if (wrap) --r; - } else { - d = oldd; - goto show_cycle_dialog; - } + else + return from; } break; default: - assert(0); - return d = screen_desktop; + g_assert_not_reached(); + return from; } d = translate_row_col(r, c); } + return d; +} + +guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, + gboolean dialog, gboolean done, gboolean cancel) +{ + static guint d = (guint)-1; + guint ret; + + if (d == (guint)-1) + d = screen_desktop; -show_cycle_dialog: - if (dialog && !cancel && !done) { + if ((!cancel && !done) || !dialog) + d = screen_find_desktop(d, dir, wrap, linear); + + if (dialog && !cancel && !done) screen_desktop_popup(d, TRUE); - } else + else screen_desktop_popup(0, FALSE); ret = d; @@ -1127,6 +1195,15 @@ typedef struct { sl = g_slist_prepend(sl, ss); \ } +#define VALIDATE_STRUTS(sl, side, max) \ +{ \ + GSList *it; \ + for (it = sl; it; it = g_slist_next(it)) { \ + ObScreenStrut *ss = it->data; \ + ss->strut->side = MIN(max, ss->strut->side); \ + } \ +} + void screen_update_areas() { guint i, j; @@ -1134,11 +1211,19 @@ void screen_update_areas() GList *it; GSList *sit; - ob_debug("updating screen areas\n"); - g_free(monitor_area); extensions_xinerama_screens(&monitor_area, &screen_num_monitors); + /* set up the user-specified margins */ + config_margins.top_start = RECT_LEFT(monitor_area[screen_num_monitors]); + config_margins.top_end = RECT_RIGHT(monitor_area[screen_num_monitors]); + config_margins.bottom_start = RECT_LEFT(monitor_area[screen_num_monitors]); + config_margins.bottom_end = RECT_RIGHT(monitor_area[screen_num_monitors]); + config_margins.left_start = RECT_TOP(monitor_area[screen_num_monitors]); + config_margins.left_end = RECT_BOTTOM(monitor_area[screen_num_monitors]); + config_margins.right_start = RECT_TOP(monitor_area[screen_num_monitors]); + config_margins.right_end = RECT_BOTTOM(monitor_area[screen_num_monitors]); + dims = g_new(gulong, 4 * screen_num_desktops * screen_num_monitors); RESET_STRUT_LIST(struts_left); @@ -1167,6 +1252,24 @@ void screen_update_areas() if (dock_strut.bottom) ADD_STRUT_TO_LIST(struts_bottom, DESKTOP_ALL, &dock_strut); + if (config_margins.left) + ADD_STRUT_TO_LIST(struts_left, DESKTOP_ALL, &config_margins); + if (config_margins.top) + ADD_STRUT_TO_LIST(struts_top, DESKTOP_ALL, &config_margins); + if (config_margins.right) + ADD_STRUT_TO_LIST(struts_right, DESKTOP_ALL, &config_margins); + if (config_margins.bottom) + ADD_STRUT_TO_LIST(struts_bottom, DESKTOP_ALL, &config_margins); + + VALIDATE_STRUTS(struts_left, left, + monitor_area[screen_num_monitors].width / 2); + VALIDATE_STRUTS(struts_right, right, + monitor_area[screen_num_monitors].width / 2); + VALIDATE_STRUTS(struts_top, top, + monitor_area[screen_num_monitors].height / 2); + VALIDATE_STRUTS(struts_bottom, bottom, + monitor_area[screen_num_monitors].height / 2); + /* set up the work areas to be full screen */ for (i = 0; i < screen_num_monitors; ++i) for (j = 0; j < screen_num_desktops; ++j) { @@ -1216,8 +1319,10 @@ void screen_update_areas() dims[(i * screen_num_desktops + j) * 4 + 3] -= t + b; } + /* all the work areas are not used here, only the ones for the first + monitor are */ PROP_SETA32(RootWindow(ob_display, ob_screen), net_workarea, cardinal, - dims, 4 * screen_num_desktops * screen_num_monitors); + dims, 4 * screen_num_desktops); /* the area has changed, adjust all the windows if they need it */ for (it = client_list; it; it = g_list_next(it))