From: Dana Jansens Date: Thu, 14 Jan 2010 23:38:40 +0000 (-0500) Subject: If a window places itself at (0,0) and there are struts there, assume it is a bug... X-Git-Tag: xkb~23 X-Git-Url: http://git.openbox.org/?p=dana%2Fopenbox.git;a=commitdiff_plain;h=54e04a520bd04ef7bc97c1fc2eef3495daa8a18f 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 --- diff --git a/.gitignore b/.gitignore index f4b627b..d48a7c3 100644 --- a/.gitignore +++ b/.gitignore @@ -81,6 +81,7 @@ tests/modal tests/modal2 tests/modal3 tests/noresize +tests/oldfullscreen tests/override tests/overrideinputonly tests/positioned diff --git a/openbox/client.c b/openbox/client.c index f91a783..6d934bd 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -202,9 +202,10 @@ void client_manage(Window window, ObPrompt *prompt) gboolean activate = FALSE; ObAppSettings *settings; gboolean transient = FALSE; - Rect place, *monitor; + Rect place, *monitor, *allmonitors; Time launch_time, map_time; guint32 user_time; + gboolean obplaced; 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)); + allmonitors = screen_physical_area_all_monitors(); /* 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); - 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, @@ -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 && - RECT_EQUAL(place, *monitor))))); + (RECT_EQUAL(place, *monitor) || + RECT_EQUAL(place, *allmonitors)))))); } /* 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) */ - !(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); @@ -422,6 +442,8 @@ void client_manage(Window window, ObPrompt *prompt) 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"); @@ -2456,9 +2478,10 @@ gboolean client_has_parent(ObClient *self) static ObStackingLayer calc_layer(ObClient *self) { ObStackingLayer l; - Rect *monitor; + Rect *monitor, *allmonitors; 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; @@ -2472,7 +2495,8 @@ static ObStackingLayer calc_layer(ObClient *self) */ (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 */ @@ -2488,6 +2512,7 @@ static ObStackingLayer calc_layer(ObClient *self) else l = OB_STACKING_LAYER_NORMAL; g_free(monitor); + g_free(allmonitors); return l; } diff --git a/openbox/place.c b/openbox/place.c index 36e977d..c396e8f 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -468,12 +468,12 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y) 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 userplaced = FALSE; /* 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 */ - 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)) || @@ -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); - return !userplaced; + return TRUE; } diff --git a/tests/oldfullscreen.c b/tests/oldfullscreen.c new file mode 100644 index 0000000..543e960 --- /dev/null +++ b/tests/oldfullscreen.c @@ -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 +#include +#include +#include + +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; +}