If a window places itself at (0,0) and there are struts there, assume it is a bug. Also allow oldschool fullscreen windows that cover all monitors on a multihead setup to work properly

Added a test 'oldfullscreen' that makes a oldschool fullscreen window
This commit is contained in:
Dana Jansens 2010-01-14 18:38:40 -05:00
parent 6cf3357036
commit 54e04a520b
4 changed files with 130 additions and 10 deletions

1
.gitignore vendored
View file

@ -81,6 +81,7 @@ tests/modal
tests/modal2 tests/modal2
tests/modal3 tests/modal3
tests/noresize tests/noresize
tests/oldfullscreen
tests/override tests/override
tests/overrideinputonly tests/overrideinputonly
tests/positioned tests/positioned

View file

@ -202,9 +202,10 @@ void client_manage(Window window, ObPrompt *prompt)
gboolean activate = FALSE; gboolean activate = FALSE;
ObAppSettings *settings; ObAppSettings *settings;
gboolean transient = FALSE; gboolean transient = FALSE;
Rect place, *monitor; Rect place, *monitor, *allmonitors;
Time launch_time, map_time; Time launch_time, map_time;
guint32 user_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 */ /* where the frame was placed is where the window was originally */
place = self->area; place = self->area;
monitor = screen_physical_area_monitor(screen_find_monitor(&place)); 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 */ /* figure out placement for the window if the window is new */
if (ob_state() == OB_STATE_RUNNING) { if (ob_state() == OB_STATE_RUNNING) {
@ -330,7 +332,23 @@ void client_manage(Window window, ObPrompt *prompt)
"program + user specified" : "program + user specified" :
"BADNESS !?")))), place.width, place.height); "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. */ /* make sure the window is visible. */
client_find_onscreen(self, &place.x, &place.y, 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 makes its fullscreen window fit the screen
but it is not USSize'd or USPosition'd) */ but it is not USSize'd or USPosition'd) */
!(self->decorations == 0 && !(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 /* don't shrink oldschool fullscreen windows to fit inside the
struts (fixes Acroread, which makes its fullscreen window struts (fixes Acroread, which makes its fullscreen window
fit the screen but it is not USSize'd or USPosition'd) */ 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); g_free(monitor);
monitor = NULL; monitor = NULL;
g_free(allmonitors);
allmonitors = NULL;
ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s", ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s",
activate ? "yes" : "no"); activate ? "yes" : "no");
@ -2456,9 +2478,10 @@ gboolean client_has_parent(ObClient *self)
static ObStackingLayer calc_layer(ObClient *self) static ObStackingLayer calc_layer(ObClient *self)
{ {
ObStackingLayer l; 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) if (self->type == OB_CLIENT_TYPE_DESKTOP)
l = OB_STACKING_LAYER_DESKTOP; l = OB_STACKING_LAYER_DESKTOP;
@ -2472,7 +2495,8 @@ static ObStackingLayer calc_layer(ObClient *self)
*/ */
(self->decorations == 0 && (self->decorations == 0 &&
!(self->max_horz && self->max_vert) && !(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.. */ /* you are fullscreen while you or your children are focused.. */
(client_focused(self) || client_search_focus_tree(self) || (client_focused(self) || client_search_focus_tree(self) ||
/* you can be fullscreen if you're on another desktop */ /* 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; else l = OB_STACKING_LAYER_NORMAL;
g_free(monitor); g_free(monitor);
g_free(allmonitors);
return l; return l;
} }

View 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, gboolean place_client(ObClient *client, gint *x, gint *y,
ObAppSettings *settings) ObAppSettings *settings)
{ {
gboolean ret; gboolean ret;
gboolean userplaced = FALSE;
/* per-app settings override program specified position /* per-app settings override program specified position
* but not user specified, unless pos_force is enabled */ * but not user specified, unless pos_force is enabled */
@ -484,7 +484,7 @@ gboolean place_client(ObClient *client, gint *x, gint *y,
return FALSE; return FALSE;
/* try a number of methods */ /* 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) || place_transient_splash(client, x, y) ||
(config_place_policy == OB_PLACE_POLICY_MOUSE && (config_place_policy == OB_PLACE_POLICY_MOUSE &&
place_under_mouse(client, x, y)) || 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 */ /* get where the client should be */
frame_frame_gravity(client->frame, x, y); frame_frame_gravity(client->frame, x, y);
return !userplaced; return TRUE;
} }

94
tests/oldfullscreen.c Normal file
View file

@ -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;
}