GNOME Bugzilla – Bug 327543
XSetWMNormalHints/PMaxSize: maximal bounds are not used optimally
Last modified: 2007-04-09 17:03:49 UTC
Please describe the problem: I use XSetWMNormalHints with flag PMaxSize to specify maximize size of the window for Normal state. But if the window is maximized (e.g. using 'Maximized' button) specified size are not taken into account. Default size is used in spite of the fact that the current state of the window is NormalState. SOURCE CODE ========================= // gcc test.c -L /usr/X11R6/lib -l X11 #include<X11/Xlib.h> #include<X11/Xutil.h> #include<stdio.h> #define BORDER_WIDTH 2 /* Program wide globals */ Display *theDisplay; int theScreen; int theDepth; Window OpenWindow(int x, int y, int width, int height, int flag){ XSetWindowAttributes theWindowAttributes; unsigned long theWindowMask; XSizeHints normal, zoom; XWMHints theWMHints; Window theNewWindow; /*Setting the attributes*/ theWindowAttributes.border_pixel =BlackPixel(theDisplay,theScreen); theWindowAttributes.background_pixel = WhitePixel(theDisplay,theScreen); theWindowAttributes.override_redirect = False; theWindowMask = CWBackPixel|CWBorderPixel|CWOverrideRedirect; theNewWindow = XCreateWindow( theDisplay, RootWindow(theDisplay,theScreen), x,y,width,height, BORDER_WIDTH,theDepth, InputOutput, CopyFromParent, theWindowMask, &theWindowAttributes); theWMHints.initial_state = NormalState; theWMHints.flags = StateHint; XSetWMHints(theDisplay,theNewWindow,&theWMHints); /* * XSizeHints */ normal.flags = PSize | PMinSize | PMaxSize | PResizeInc | PBaseSize | PWinGravity; normal.x = 100; normal.y = 100; normal.width = 100; normal.height = 100; normal.min_width = 50; normal.min_height = 50; normal.max_width = 200; normal.max_height = 200; normal.width_inc = 2; normal.height_inc = 2; normal.base_width = 10; normal.base_height = 10; normal.win_gravity = CenterGravity; XSetWMNormalHints(theDisplay, theNewWindow, &normal); XMapWindow(theDisplay,theNewWindow); XFlush(theDisplay); return theNewWindow; } int main(void){ Window theWindow; theDisplay = XOpenDisplay(NULL); theScreen = DefaultScreen(theDisplay); theDepth = DefaultDepth(theDisplay,theScreen); theWindow = OpenWindow(50,50,100,100,0); XFlush(theDisplay); sleep(100); XDestroyWindow(theDisplay,theWindow); } Steps to reproduce: 1. Run the attached testcase 2. You will see the window 3. Maximize the window using 'Maximize' button 4. You will see that maximized size (width=200,height=200) are not honored and default maximized bounds (screen bounds) is used Actual results: Expected results: Does this happen every time? Other information: There is no suitable way to workaround this problem. This functionality works correctly on some window managers (e.g. wmaker, xfwm)
This bug has been basically been fixed by the constraints rewrite -- but there's a new interesting little bug now: constraints.c:constrain_maximization() just basically drops out if it notices the two constraints (maximizations & max size constraints) can't be simultaneously satisfied. This means that hitting the maximize button does nothing (well, other than changing the little button icon and possibly changing the frame size since it's now 'maximized'). It would seem to make more sense that if the maximum size is bigger than the current window size and the maximized size is also bigger than the current window size, to increase it as much as possible without violating either constraint.
Created attachment 59898 [details] [review] Resize to maximum extent if window max size is smaller than maximisation would be How's this? It might be cleaner to get rid of the four booleans and just use the expressions for them. OTOH, maybe it makes their purpose clearer.
We do ignore the size increment ("grid") hint on maximization, so ignoring the PMaxSize might make sense too. They are after all just hints, and it looks bad/broken to the user if maximization doesn't work. If an app can't deal with adding some empty space in its window, it's a pretty darn lame app.
Another alternative would be to disallow maximization altogether, so if the maximum size hints are smaller than the workarea then we would desensitize or remove any UI for the user to maximize it (i.e. treat the window as if the MWM has maximize func setting was false). So, I guess we have four options that I can see: 1) (Current behavior) Ignore maximization requests altogether if maximum size hints are less than workarea; seems lame that a UI option is provided that has no effect 2) (Thomas' patch) Increase window size as much as possible up to the maximum size hints when the user requests the window be maximized; possible downside of the user being surprised that the window wasn't actually "maximized" (made to fill the entire workarea) as per their request 3) (Old behavior) Ignore maximum size hints when maximizing; i.e. restore the behavior this bug report was complaining about 4) (New choice) Desensitize or remove the UI options to allow the window to be maximized if the maximum size hints aren't as large as the workarea; this removes the ability to easily make-the-window-as-big-as-possible and might make the window look inconsistent with others but does explain that the window is different to the user. I don't care what is chosen. Havoc, should we ask the UI review folk for suggestions, or did you prefer #3 (since you suggested it)? Thomas: The patch looks fine, _if_ we decide #2 is the route we want to take.
IMO, 3) is the way to go
*** Bug 338073 has been marked as a duplicate of this bug. ***
Matthias' opinion is good enough for me. Thomas: Do you want to update the patch to implement option #3?
Sure, I'll work on it on the train tonight.
There's a test case to add to src/wm-tester at: http://bugzilla.gnome.org/show_bug.cgi?id=338073#c1
Created attachment 63401 [details] [review] Allow even windows with a max size to maximise to the whole screen Sorry it took longer than I thought, but work got in the way a bit. I wanted to make this so that vertical maximisation meant that vertical max size was ignored, and similarly for horizontal. But you can't really do that with the existing constraints mechanism: either you constrain the window or you don't. There's no way of saying that a constraint should only apply in one direction. So this patch disables the size limits constraint if a window is maximised in either direction.
> I wanted to make this so that vertical maximisation meant that vertical max > size was ignored, and similarly for horizontal. But you can't really do that > with the existing constraints mechanism: either you constrain the window or > you don't. There's no way of saying that a constraint should only apply in one > direction. Why is that? Wouldn't something like /* We ignore max-size limits for maximized windows; see #327543 */ if (window->maximized_horizontally) max_size.width = MAX (max_size.width, info->current.width) if (window->maximized_vertically) max_size.height = MAX (max_size.height, info->current.height) right after the get_size_limits() call work?
When I tried this it had the side-effect of constraining the X and Y coords of the window too, so the window maximised but its top left-hand corner stayed in place.
I'm unable to duplicate any problem; for what I've tried the constrain-max-size-in-direction-only-if-not-maximized-in-that-direction seems to work. Could you provide more details on how to duplicate the problem?
Created attachment 73002 [details] [review] My suggestion
(In reply to comment #13) > I'm unable to duplicate any problem; for what I've tried the > constrain-max-size-in-direction-only-if-not-maximized-in-that-direction seems > to work. Could you provide more details on how to duplicate the problem? I'll take the lack of response as a 'no', and use an alternative way to find out the details of how to duplicate any such problem... ;-) 2006-09-18 Elijah Newren <newren gmail com> * src/constraints.c (constrain_maximization): Ignore maximum size hints when maximizing. Should fix #327543.
No response/complaints, assuming fixed.
*** Bug 426335 has been marked as a duplicate of this bug. ***