If a window places itself at (0,0) and there are struts there, assume it is a bug...
authorDana Jansens <danakj@orodu.net>
Thu, 14 Jan 2010 23:38:40 +0000 (18:38 -0500)
committerDana Jansens <danakj@orodu.net>
Thu, 14 Jan 2010 23:41:25 +0000 (18:41 -0500)
Added a test 'oldfullscreen' that makes a oldschool fullscreen window

.gitignore
openbox/client.c
openbox/place.c
tests/oldfullscreen.c [new file with mode: 0644]

index f4b627b..d48a7c3 100644 (file)
@@ -81,6 +81,7 @@ tests/modal
 tests/modal2
 tests/modal3
 tests/noresize
 tests/modal2
 tests/modal3
 tests/noresize
+tests/oldfullscreen
 tests/override
 tests/overrideinputonly
 tests/positioned
 tests/override
 tests/overrideinputonly
 tests/positioned
index f91a783..6d934bd 100644 (file)
@@ -202,9 +202,10 @@ void client_manage(Window window, ObPrompt *prompt)
     gboolean activate = FALSE;
     ObAppSettings *settings;
     gboolean transient = FALSE;
     gboolean activate = FALSE;
     ObAppSettings *settings;
     gboolean transient = FALSE;
-    Rect place, *monitor;
+    Rect place, *monitor, *allmonitors;
     Time launch_time, map_time;
     guint32 user_time;
     Time launch_time, map_time;
     guint32 user_time;
+    gboolean obplaced;
 
     ob_debug("Managing window: 0x%lx", window);
 
 
     ob_debug("Managing window: 0x%lx", window);
 
@@ -311,6 +312,7 @@ void client_manage(Window window, ObPrompt *prompt)
     /* where the frame was placed is where the window was originally */
     place = self->area;
     monitor = screen_physical_area_monitor(screen_find_monitor(&place));
     /* where the frame was placed is where the window was originally */
     place = self->area;
     monitor = screen_physical_area_monitor(screen_find_monitor(&place));
+    allmonitors = screen_physical_area_all_monitors();
 
     /* figure out placement for the window if the window is new */
     if (ob_state() == OB_STATE_RUNNING) {
 
     /* figure out placement for the window if the window is new */
     if (ob_state() == OB_STATE_RUNNING) {
@@ -330,7 +332,23 @@ void client_manage(Window window, ObPrompt *prompt)
                      "program + user specified" :
                      "BADNESS !?")))), place.width, place.height);
 
                      "program + user specified" :
                      "BADNESS !?")))), place.width, place.height);
 
-        place_client(self, &place.x, &place.y, settings);
+        obplaced = place_client(self, &place.x, &place.y, settings);
+
+        /* watch for buggy apps that ask to be placed at (0,0) when there is
+           a strut there */
+        if (!obplaced && place.x == 0 && place.y == 0 &&
+            /* oldschool fullscreen windows are allowed */
+            !(self->decorations == 0 && (RECT_EQUAL(place, *monitor) ||
+                                         RECT_EQUAL(place, *allmonitors))))
+        {
+            Rect *r;
+
+            r = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS, NULL);
+            place.x = r->x;
+            place.y = r->y;
+            ob_debug("Moving buggy app from (0,0) to (%d,%d)", r->x, r->y);
+            g_free(r);
+        }
 
         /* make sure the window is visible. */
         client_find_onscreen(self, &place.x, &place.y,
 
         /* make sure the window is visible. */
         client_find_onscreen(self, &place.x, &place.y,
@@ -362,7 +380,8 @@ void client_manage(Window window, ObPrompt *prompt)
                                   makes its fullscreen window fit the screen
                                   but it is not USSize'd or USPosition'd) */
                                !(self->decorations == 0 &&
                                   makes its fullscreen window fit the screen
                                   but it is not USSize'd or USPosition'd) */
                                !(self->decorations == 0 &&
-                                 RECT_EQUAL(place, *monitor)))));
+                                 (RECT_EQUAL(place, *monitor) ||
+                                  RECT_EQUAL(place, *allmonitors))))));
     }
 
     /* if the window isn't user-sized, then make it fit inside
     }
 
     /* if the window isn't user-sized, then make it fit inside
@@ -382,7 +401,8 @@ void client_manage(Window window, ObPrompt *prompt)
           /* don't shrink oldschool fullscreen windows to fit inside the
              struts (fixes Acroread, which makes its fullscreen window
              fit the screen but it is not USSize'd or USPosition'd) */
           /* don't shrink oldschool fullscreen windows to fit inside the
              struts (fixes Acroread, which makes its fullscreen window
              fit the screen but it is not USSize'd or USPosition'd) */
-          !(self->decorations == 0 && RECT_EQUAL(place, *monitor)))))
+          !(self->decorations == 0 && (RECT_EQUAL(place, *monitor) ||
+                                       RECT_EQUAL(place, *allmonitors))))))
     {
         Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &place);
 
     {
         Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &place);
 
@@ -422,6 +442,8 @@ void client_manage(Window window, ObPrompt *prompt)
 
     g_free(monitor);
     monitor = NULL;
 
     g_free(monitor);
     monitor = NULL;
+    g_free(allmonitors);
+    allmonitors = NULL;
 
     ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s",
                   activate ? "yes" : "no");
 
     ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s",
                   activate ? "yes" : "no");
@@ -2456,9 +2478,10 @@ gboolean client_has_parent(ObClient *self)
 static ObStackingLayer calc_layer(ObClient *self)
 {
     ObStackingLayer l;
 static ObStackingLayer calc_layer(ObClient *self)
 {
     ObStackingLayer l;
-    Rect *monitor;
+    Rect *monitor, *allmonitors;
 
     monitor = screen_physical_area_monitor(client_monitor(self));
 
     monitor = screen_physical_area_monitor(client_monitor(self));
+    allmonitors = screen_physical_area_all_monitors();
 
     if (self->type == OB_CLIENT_TYPE_DESKTOP)
         l = OB_STACKING_LAYER_DESKTOP;
 
     if (self->type == OB_CLIENT_TYPE_DESKTOP)
         l = OB_STACKING_LAYER_DESKTOP;
@@ -2472,7 +2495,8 @@ static ObStackingLayer calc_layer(ObClient *self)
               */
               (self->decorations == 0 &&
                !(self->max_horz && self->max_vert) &&
               */
               (self->decorations == 0 &&
                !(self->max_horz && self->max_vert) &&
-               RECT_EQUAL(self->area, *monitor))) &&
+               (RECT_EQUAL(self->area, *monitor) ||
+                RECT_EQUAL(self->area, *allmonitors)))) &&
              /* you are fullscreen while you or your children are focused.. */
              (client_focused(self) || client_search_focus_tree(self) ||
               /* you can be fullscreen if you're on another desktop */
              /* you are fullscreen while you or your children are focused.. */
              (client_focused(self) || client_search_focus_tree(self) ||
               /* you can be fullscreen if you're on another desktop */
@@ -2488,6 +2512,7 @@ static ObStackingLayer calc_layer(ObClient *self)
     else l = OB_STACKING_LAYER_NORMAL;
 
     g_free(monitor);
     else l = OB_STACKING_LAYER_NORMAL;
 
     g_free(monitor);
+    g_free(allmonitors);
 
     return l;
 }
 
     return l;
 }
index 36e977d..c396e8f 100644 (file)
@@ -468,12 +468,12 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y)
     return FALSE;
 }
 
     return FALSE;
 }
 
-/* Return TRUE if we want client.c to enforce on-screen-keeping */
+/*! Return TRUE if openbox chose the position for the window, and FALSE if
+  the application chose it */
 gboolean place_client(ObClient *client, gint *x, gint *y,
                       ObAppSettings *settings)
 {
     gboolean ret;
 gboolean place_client(ObClient *client, gint *x, gint *y,
                       ObAppSettings *settings)
 {
     gboolean ret;
-    gboolean userplaced = FALSE;
 
     /* per-app settings override program specified position
      * but not user specified, unless pos_force is enabled */
 
     /* per-app settings override program specified position
      * but not user specified, unless pos_force is enabled */
@@ -484,7 +484,7 @@ gboolean place_client(ObClient *client, gint *x, gint *y,
         return FALSE;
 
     /* try a number of methods */
         return FALSE;
 
     /* try a number of methods */
-    ret = (userplaced = place_per_app_setting(client, x, y, settings)) ||
+    ret = place_per_app_setting(client, x, y, settings) ||
         place_transient_splash(client, x, y) ||
         (config_place_policy == OB_PLACE_POLICY_MOUSE &&
          place_under_mouse(client, x, y)) ||
         place_transient_splash(client, x, y) ||
         (config_place_policy == OB_PLACE_POLICY_MOUSE &&
          place_under_mouse(client, x, y)) ||
@@ -494,5 +494,5 @@ gboolean place_client(ObClient *client, gint *x, gint *y,
 
     /* get where the client should be */
     frame_frame_gravity(client->frame, x, y);
 
     /* get where the client should be */
     frame_frame_gravity(client->frame, x, y);
-    return !userplaced;
+    return TRUE;
 }
 }
diff --git a/tests/oldfullscreen.c b/tests/oldfullscreen.c
new file mode 100644 (file)
index 0000000..543e960
--- /dev/null
@@ -0,0 +1,94 @@
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+   oldfullscreen.c for the Openbox window manager
+   Copyright (c) 2010        Dana Jansens
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   See the COPYING file for a copy of the GNU General Public License.
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+typedef struct
+{
+    unsigned long   flags;
+    unsigned long   functions;
+    unsigned long   decorations;
+    long            inputMode;
+    unsigned long   status;
+} Hints;
+
+int main (int argc, char **argv) {
+    Display    *display;
+    Window      win;
+    Window      r;
+    XEvent      report;
+    int         x=200,y=200,h=100,w=400,s;
+    XSizeHints *size;
+    Hints       hints;
+    Atom        prop;
+
+    display = XOpenDisplay(NULL);
+
+    if (display == NULL) {
+        fprintf(stderr, "couldn't connect to X server :0\n");
+        return 0;
+    }
+
+    XGetGeometry(display, RootWindow(display, DefaultScreen(display)), &r,
+                 &x, &y, &w, &h, &s, &s);
+
+    win = XCreateWindow(display, RootWindow(display, 0),
+                        x, y, w, h, 0, CopyFromParent, CopyFromParent,
+                        CopyFromParent, 0, NULL);
+    XSetWindowBackground(display,win,WhitePixel(display,0));
+
+    size = XAllocSizeHints();
+    size->flags = PPosition;
+    XSetWMNormalHints(display,win,size);
+    XFree(size);
+
+    hints.flags = 2;
+    hints.decorations = 0;
+    prop = XInternAtom(display, "_MOTIF_WM_HINTS", False);
+    XChangeProperty(display, win, prop, prop, 32, PropModeReplace,
+                    (unsigned char *)&hints, 5);
+
+    XFlush(display);
+    XMapWindow(display, win);
+
+    XSelectInput(display, win, StructureNotifyMask | ButtonPressMask);
+
+    while (1) {
+        XNextEvent(display, &report);
+
+        switch (report.type) {
+        case ButtonPress:
+            XUnmapWindow(display, win);
+            break;
+        case ConfigureNotify:
+            x = report.xconfigure.x;
+            y = report.xconfigure.y;
+            w = report.xconfigure.width;
+            h = report.xconfigure.height;
+            s = report.xconfigure.send_event;
+            printf("confignotify %i,%i-%ix%i (send: %d)\n",x,y,w,h,s);
+            break;
+        }
+
+    }
+
+    return 1;
+}