Stop moving stuff onscreen when the screen size changes
[mikachu/openbox.git] / openbox / screen.c
index 33acb4a..a6551cf 100644 (file)
 
 static gboolean screen_validate_layout(ObDesktopLayout *l);
 static gboolean replace_wm(void);
-static void     screen_tell_ksplash(void);
+//static void     screen_tell_ksplash(void);
 static void     screen_fallback_focus(void);
 
-guint           screen_num_desktops;
-guint           screen_num_monitors;
-guint           screen_desktop;
-guint           screen_last_desktop;
-gboolean        screen_showing_desktop;
-ObDesktopLayout screen_desktop_layout;
-gchar         **screen_desktop_names;
-Window          screen_support_win;
-Time            screen_desktop_user_time = CurrentTime;
+guint                  screen_num_desktops;
+guint                  screen_num_monitors;
+guint                  screen_desktop;
+guint                  screen_last_desktop;
+ObScreenShowDestopMode screen_show_desktop_mode;
+ObDesktopLayout        screen_desktop_layout;
+gchar                **screen_desktop_names;
+Window                 screen_support_win;
+Time                   screen_desktop_user_time = CurrentTime;
 
 static Size     screen_physical_size;
 static guint    screen_old_desktop;
@@ -169,7 +169,7 @@ gboolean screen_annex(void)
 
     /* create the netwm support window */
     attrib.override_redirect = TRUE;
-    attrib.event_mask = PropertyChangeMask;
+    attrib.event_mask = PropertyChangeMask | KeyPressMask | KeyReleaseMask;
     screen_support_win = XCreateWindow(obt_display, obt_root(ob_screen),
                                        -100, -100, 1, 1, 0,
                                        CopyFromParent, InputOutput,
@@ -294,11 +294,13 @@ gboolean screen_annex(void)
     supported[i++] = OBT_PROP_ATOM(KDE_NET_WM_FRAME_STRUT);
     supported[i++] = OBT_PROP_ATOM(KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
 
+    supported[i++] = OBT_PROP_ATOM(OB_FOCUS);
     supported[i++] = OBT_PROP_ATOM(OB_WM_ACTION_UNDECORATE);
     supported[i++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
     supported[i++] = OBT_PROP_ATOM(OPENBOX_PID);
     supported[i++] = OBT_PROP_ATOM(OB_THEME);
     supported[i++] = OBT_PROP_ATOM(OB_CONFIG_FILE);
+    supported[i++] = OBT_PROP_ATOM(OB_LAST_DESKTOP);
     supported[i++] = OBT_PROP_ATOM(OB_CONTROL);
     supported[i++] = OBT_PROP_ATOM(OB_VERSION);
     supported[i++] = OBT_PROP_ATOM(OB_APP_ROLE);
@@ -317,11 +319,11 @@ gboolean screen_annex(void)
     OBT_PROP_SETS(RootWindow(obt_display, ob_screen), OB_VERSION,
                   OPENBOX_VERSION);
 
-    screen_tell_ksplash();
+    //screen_tell_ksplash();
 
     return TRUE;
 }
-
+#if 0
 static void screen_tell_ksplash(void)
 {
     XEvent e;
@@ -355,7 +357,7 @@ static void screen_tell_ksplash(void)
     XSendEvent(obt_display, obt_root(ob_screen),
                False, SubstructureNotifyMask, &e);
 }
-
+#endif
 void screen_startup(gboolean reconfig)
 {
     gchar **names = NULL;
@@ -442,12 +444,16 @@ void screen_startup(gboolean reconfig)
     else
         screen_set_desktop(MIN(config_screen_firstdesk,
                                screen_num_desktops) - 1, FALSE);
-    screen_last_desktop = screen_desktop;
+    OBT_PROP_GET32(obt_root(ob_screen), OB_LAST_DESKTOP, CARDINAL, &screen_last_desktop);
+    if (screen_last_desktop < 0 || screen_last_desktop >= screen_num_desktops) {
+        screen_last_desktop = screen_desktop;
+        OBT_PROP_SET32(obt_root(ob_screen), OB_LAST_DESKTOP, CARDINAL, screen_last_desktop);
+    }
 
     /* don't start in showing-desktop mode */
-    screen_showing_desktop = FALSE;
+    screen_show_desktop_mode = SCREEN_SHOW_DESKTOP_NO;
     OBT_PROP_SET32(obt_root(ob_screen),
-                   NET_SHOWING_DESKTOP, CARDINAL, screen_showing_desktop);
+                   NET_SHOWING_DESKTOP, CARDINAL, screen_showing_desktop());
 
     if (session_desktop_layout_present &&
         screen_validate_layout(&session_desktop_layout))
@@ -501,10 +507,11 @@ void screen_resize(void)
     /* this calls screen_update_areas(), which we need ! */
     dock_configure();
 
-    for (it = client_list; it; it = g_list_next(it)) {
-        client_move_onscreen(it->data, FALSE);
-        client_reconfigure(it->data, FALSE);
-    }
+    // bug: this is done in screen_update_areas() already
+//    for (it = client_list; it; it = g_list_next(it)) {
+//        client_move_onscreen(it->data, FALSE);
+//        client_reconfigure(it->data, FALSE);
+//    }
 }
 
 void screen_set_num_desktops(guint num)
@@ -602,6 +609,7 @@ static void screen_fallback_focus(void)
 static gboolean last_desktop_func(gpointer data)
 {
     screen_desktop_timeout = TRUE;
+    OBT_PROP_SET32(obt_root(ob_screen), OB_LAST_DESKTOP, CARDINAL, screen_last_desktop);
     screen_desktop_timer = 0;
     return FALSE; /* don't repeat */
 }
@@ -1218,15 +1226,33 @@ void screen_update_desktop_names(void)
                                       screen_num_desktops);
 }
 
-void screen_show_desktop(gboolean show, ObClient *show_only)
+void screen_show_desktop(ObScreenShowDestopMode show_mode, ObClient *show_only)
 {
     GList *it;
 
-    if (show == screen_showing_desktop) return; /* no change */
+    ObScreenShowDestopMode before_mode = screen_show_desktop_mode;
 
-    screen_showing_desktop = show;
+    gboolean showing_before = screen_showing_desktop();
+    screen_show_desktop_mode = show_mode;
+    gboolean showing_after = screen_showing_desktop();
 
-    if (show) {
+    if (showing_before == showing_after) {
+        /* No change. */
+        screen_show_desktop_mode = before_mode;
+        return;
+    }
+
+    if (screen_show_desktop_mode == SCREEN_SHOW_DESKTOP_UNTIL_TOGGLE &&
+        show_only != NULL)
+    {
+        /* If we're showing the desktop until the show-mode is toggled, we
+           don't allow breaking out of showing-desktop mode unless we're
+           showing all the windows again. */
+        screen_show_desktop_mode = before_mode;
+        return;
+    }
+
+    if (showing_after) {
         /* hide windows bottom to top */
         for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) {
             if (WINDOW_IS_CLIENT(it->data)) {
@@ -1250,7 +1276,7 @@ void screen_show_desktop(gboolean show, ObClient *show_only)
         }
     }
 
-    if (show) {
+    if (showing_after) {
         /* focus the desktop */
         for (it = focus_order; it; it = g_list_next(it)) {
             ObClient *c = it->data;
@@ -1275,8 +1301,23 @@ void screen_show_desktop(gboolean show, ObClient *show_only)
         }
     }
 
-    show = !!show; /* make it boolean */
-    OBT_PROP_SET32(obt_root(ob_screen), NET_SHOWING_DESKTOP, CARDINAL, show);
+    OBT_PROP_SET32(obt_root(ob_screen),
+                   NET_SHOWING_DESKTOP,
+                   CARDINAL,
+                   !!showing_after);
+}
+
+gboolean screen_showing_desktop()
+{
+    switch (screen_show_desktop_mode) {
+    case SCREEN_SHOW_DESKTOP_NO:
+        return FALSE;
+    case SCREEN_SHOW_DESKTOP_UNTIL_WINDOW:
+    case SCREEN_SHOW_DESKTOP_UNTIL_TOGGLE:
+        return TRUE;
+    }
+    g_assert_not_reached();
+    return FALSE;
 }
 
 void screen_install_colormap(ObClient *client, gboolean install)
@@ -1327,8 +1368,9 @@ typedef struct {
 static void get_xinerama_screens(Rect **xin_areas, guint *nxin)
 {
     guint i;
-    gint n, l, r, t, b;
+    gint l, r, t, b;
 #ifdef XINERAMA
+    gint n;
     XineramaScreenInfo *info;
 #endif
 
@@ -1647,7 +1689,7 @@ guint screen_find_monitor(const Rect *search)
 {
     guint i;
     guint mostpx_index = screen_num_monitors;
-    guint mostpx = 0;
+    glong mostpx = 0;
     guint closest_distance_index = screen_num_monitors;
     guint closest_distance = G_MAXUINT;
     GSList *counted = NULL;
@@ -1846,7 +1888,7 @@ void screen_set_root_cursor(void)
 {
     if (sn_app_starting())
         XDefineCursor(obt_display, obt_root(ob_screen),
-                      ob_cursor(OB_CURSOR_BUSYPOINTER));
+                      ob_cursor(OB_CURSOR_BUSY));
     else
         XDefineCursor(obt_display, obt_root(ob_screen),
                       ob_cursor(OB_CURSOR_POINTER));
@@ -1894,3 +1936,30 @@ gboolean screen_compare_desktops(guint a, guint b)
         b = screen_desktop;
     return a == b;
 }
+
+void screen_apply_gravity_point(gint *x, gint *y, gint width, gint height,
+                                const GravityPoint *position, const Rect *area)
+{
+    if (position->x.center)
+        *x = area->width / 2 - width / 2;
+    else {
+        *x = position->x.pos;
+        if (position->x.denom)
+            *x = (*x * area->width) / position->x.denom;
+        if (position->x.opposite)
+            *x = area->width - width - *x;
+    }
+
+    if (position->y.center)
+        *y = area->height / 2 - height / 2;
+    else {
+        *y = position->y.pos;
+        if (position->y.denom)
+            *y = (*y * area->height) / position->y.denom;
+        if (position->y.opposite)
+            *y = area->height - height - *y;
+    }
+
+    *x += area->x;
+    *y += area->y;
+}