GNOME Bugzilla – Bug 152898
No way to move a window off the top of the screen
Last modified: 2006-04-06 00:38:26 UTC
Sometimes I like to move a window out of the way, and do this by using Alt+Click and dragging the window. I like to move windows up, off the screen, and think that it should be possible to move them off the top when using the Alt+Click method of moving a window (just as I can off the bottom, left and right). I understand the reason for not allowing them to be moved up (the user can't grab the title bar, and so can't move them back), but in the case of Alt+Click, that isn't an issue, as the user already clearly knows about this method of moving. So the constraint (in this case) should only apply to the bottom border not being moved off the top.
Okay, so there's been lots of previous discussion on this issue. For example, see bug 106740 (the main one about this issue), bug 120110, bug 124015 (about windows too large being able to be moved off the screen), bug 141411, or several others. Before someone marks this as a duplicate, though, please hear me out. Note that this has already been handled for windows that are too large to fit on the screen, so this request is only about windows that are small enough to fit. In comment 6 of bug 106740, Havoc stated that he would like a feature like this: "So what I'd like to do is drop the constraint on Alt+click or keyboard move only, as someone suggested. I would like to keep the constraint for moving via titlebar drag, for initial window placement, and for application configure requests." Unfortunately, he seems to have backtracked; in comment 39 he said he was against this feature beacause there is a trade-off between this and three other usability requirements that he felt were more important, namely: - allow slamming windows to edge - avoid accidentally getting windows under the panel (some apps for example try to hardcode a position at 0,0) - do the right thing when a new panel is added Now, I think we could probably satisfy all the above and still allow windows to be moved off the top of the screen if we: (1) implement edge resistance (bug 81704) (2) only let the titlebar-must-remain-on-screen constraint be ignored if the user is using either Alt+<left-click> and drag with the mouse to move the window or Alt+F7 with the keyboard to move the window. I'd rather ignore one more detail that occurs to me because I really want this feature, but there is one more problematic situation even if this is done: - What if someone's friend comes by and moves the windows off the screen while borrowing the machine to check something on the internet, and then that someone can't get the window back? I see a few possible solutions to this: - Why isn't there a guest account with fast user switching? - We could just rely on the user logging out and logging back in. (Meaning that on session restore, we can note that windows are off the screen and ask the user if they'd like them moved back onscreen) - The friend screwed it up. It's their fault, not Metacity's. (You may laugh, but think of it this way: We cannot realistically prevent everything that the friend could do to the system. We cannot even realistically prevent much of anything that the friend could do to the system; why is it important here?) Okay, you've put up with a lot of verboseness from me. I would _really_ like this feature. Would allowing this feature (only on manual user movement of Alt+click or Alt+F7) after bug 81704 has been implemented be reasonable? Is there anything I'm missing?
A basic problem is that by the time we're running the window constraints code, there isn't enough context to know if the app or the user moved the window. A secondary problem is that constraints.c is still uber-busted, so making it more complex is tricky. Those are the implementation problems. But why do you want to move a window small enough to be fully visible off the screen again? How about just shading or minimizing it? I'd rather see effort on one of the other 200 or so open bugs ;-) Such as fixing constraints.c...
Okay, so the complexity of constraint.c is an issue. And perhaps fixing that is a pre-requisite for this bug. As for why I want to do it, it's usability related. I always move windows via Alt+click; I can move windows off the left, right, and bottom, but not off the top. It inconsistent. Either windows shouldn't be allowed to move off the screen _at all_, or it should be allowed to move off all sides. Granted, I know that in general we don't want the titlebar going off the screen for most users (since they most likely won't know how to move windows other than clicking and dragging on the titlebar), and I know that in these cases it is better to break consistency in order to save them from a much worse fate; but for those of us that know more this is an annoying issue. (To be honest, I could argue further about why I think windows should be allowed off screen, and even why some sides are more useful to be able to move windows off than others (with the top being the most useful, followed by right then left then the bottom), but most of these arguments are clearly about an admittedly small niche usage case (i.e. "power-user" only stuff), and it always sounds weird trying to argue for niche scenarios. Let me know if you would like to hear it, though. And no, shading and minimizing doesn't help one iota for what I want--I'm not trying to hide windows) Last time I looked at constraints.c, I got a headache and since I had no real incentive to try to figure anything out, I just quit. This bug would be a great incentive for me to actually learn the details so that I can help fix any other problems in that code--just like I'm already trying to help with some of the other 200 or so open Metacity bugs. *cough* hint *cough* ;-)
Personally I'm very much against allowing the titlebar to be obscured. I think that its a major usability feature to prevent the user from accidentally losing a window off the screen with no practical way to recover it, other than knowing about keybindings or alt-dragging, both of which I don't think most people know how to do. A lot of effort was put into making sure that the constraints work the way they do, and the overriding principle behind it is: keep the titlebar visible. Frankly I don't see any reason why constraints.c needs to be rewritten; it currently works well and I don't know of any cases where it is broken. It is perhaps conceptually more complicated than it needs to be (if I were to write it, I would probably use the heuristic repair technique used for partial-width struts for all the constraints). The only conceivable difference is that no distinction is made between application movements and user movements, but 1) this could be added readily to constraints.c and 2) I don't see why this distinction is necessary or desirable. In fact I would argue that the distinction is not desirable. The best solution here involves no window state other than the "real" position and the position where the window actually ends up after constraints are solved.
Rob: I'm sorry. I really didn't mean to offend. I know you've put a lot of work into constraints.c, and I can tell because it feels like it Just Works (TM) to me. (The only reason I talk about "fixing it" is that I see you or Havoc mention it being broken occasionally in bug reports and so I /assume/ that it has some problems lurking somewhere). I totally agree with you that keeping the titlebar visible is the most important design principle for most users, because as you said, we need to make sure that they don't run into a situation that they can't recover from. That's why my proposal (or Crispin's, or whoever's) is to only allow it on Alt+Click or Alt+F7. I also understand that it sometimes it's nice to be able to quickly line up windows with the screen edge (and in fact, this is a more common use case than wanting to pull the window off the screen), but I feel that edge resistance (bug 81704) would take care of that--and as a bonus would allow this for all the other screen edges too. (Perhaps we could even increase the resistance at screen edges...).
Don't worry; I'm not offended in any way; in fact most of constraints.c was written by Havoc. The problems with trying to make that distinction are legion, and are independant of any constraints implementation. For example, so you have a window that the user has alt-dragged off the screen partially or completely, and you get a configure request on that window to move it. Do the constraints suddenly apply? What if the user has dragged a window 1 or 2 pixels off screen and then adds a top panel, thus covering the titlebar? Should the constraints suddenly apply in this case? How about if they've dragged the window so that only a little bit on the bottom is visible, then they add a top panel, completely obsuring the window? These are the sorts of problems you run into when you apply some constraints sometimes and not others. You'll find situations where the behavior breaks down. This is why the simple nearly-stateless implementation works as well as it does -- no need to resolve problems like this. And of course this doesn't even address the even more serious usability problem of allowing users to move windows to places where they can't get at them in the first place.
Try keyboard resize... e.g. Alt+F8, down arrow, it gets stuck and bounces. With keyboard move, move window to bottom of screen and hold down arrow, it will bounce. I'm not sure we get the simultaneous move/resize configure request case right... not sure if there's still an open bug on that, or if anyone ever tested it. There's also this: /* Evidence that we can't actually prove this algorithm is right */ #define MAX_ITERATIONS 10 paranoia = 0; But I don't think any of those are the actual example I had in mind of what's wrong with constraints.c, I have a fuzzy memory of some other issue. Maybe I was sensible enough to write it down somewhere. There's also the general problem that the basic design of the file (which is 100% my fault) is both wrong and complicated at the same time. Rob did a valiant job making it work as best it can in this model, but it is still the wrong model I think.
Agree with Rob's comment that it's tough to make constraints dependent on how we got to the current state; it's pretty stateless right now. Though I can imagine implementing that with a flag like "moved_offscreen" so we'd handle it similar to how you can "drag loose" a maximized window. The constraints code could then still be context-free, but when you alt+drag offscreen we'd set the magic flag, and when you got entirely onscreen again unset it. Clearly this gets complex fast if you start having many flags of that nature.
The bouncing appears to be that the keyboard resizing seems to actually use the mouse cursor in the center of the window somehow, and its keeping the cursor on the screen. I don't think that's a constraints.c problem, necessarily. Should be pretty fixable, since I don't think any changes to constaints.c would have to be made. I wish I actually had free time these days...
First, a clarification: I wasn't asking to allow any window to be dragged off the screen completely. Currently, windows can be dragged most the way but not all the way off to the left, right, or bottom. I'm not asking any more for the top. Yes, I can see that there are issues. However, I'm not sure I understand how they are any different from what we already have solved. In fact, to me it looks like we have already solved all these issues and all we need is an adjustment our idea of when the two constraints, which already exist, apply. These two constraints are: (1) Every window must at least partially be on the available screen area (I'm defining "the available screen area" as the screen minus area reserved for, e.g. the panels; this constraint is already implemented for the left, right and bottom edges) (2) Some windows (where without the feature requested in this bug, "some windows"=="all windows") must have their titlebar on the available screen area. (this is already implemented currently for all windows) I believe all the cases you listed can be solved with the following rules: (A) If a window is currently partially off the available screen (because e.g. the user manually dragged it there), then only contraint (1) applies. (B) If a window is entirely within the available screen area then constraint (2) also applies. So, now, case-by-case: - so you have a window that the user has alt-dragged off the screen partially or completely, and you get a configure request on that window to move it. Do the constraints suddenly apply? Yes, constraint (1) applies because the window was already partially off the screen. - What if the user has dragged a window 1 or 2 pixels off screen and then adds a top panel, thus covering the titlebar? Constraint (1) applies. Since the user had to use alt-click-dragging or alt+f7 plus keyboard moving to get it there, having only constraint (1) apply should be fine. (Although note that having a window only be a pixel or two off the screen would probably be unlikely, at least for my experience with how edge resistance works) - How about if they've dragged the window so that only a little bit on the bottom is visible, then they add a top panel, completely obsuring the window? Constraint (1) applies, forcing the window to move a little so that part is still visible on the screen. This is identical to what happens currently when one has a window that is almost completely off the bottom of the screen and then adds a panel there. So, I don't think we need to throw away or ignore constraints in order to get this feature. We always keep at least one constraint which can keep everything sane, and sometimes we happen to also apply a more stringent constraint when it also makes sense.
Ooops! Add the following edit above: s/(because e.g. the user manually dragged it there)/(because the user manually dragged it there)/ because we really don't want to allow other methods for it getting there, as far as I can tell.
Note that you can't use something like "the user dragged the window from one place to another" as the basis for your contraints, since this is not generally true. In fact, this assumption is what led to a number of the conteptual problems with constraints.c in the first place. Consider for example windows when they are first mapped, or when the constraints change because new panels are added, the screen is resized, the window changes its min-size or size-increment hint, or any of a number of other possiblities. This means that the constraints code needs to work simply on the position of the window independant of the constraints, and return a window position that is a feasible position "closest" to the requested position. (here, a "feasible position" is defined as a window position that meets all constraints, that is, a solution to the constraint satisfaction problem).
Right, isn't that what my suggestion in comment 10 does? It doesn't rely on the fact that the user dragged the window off the available screen or on any other past events; it merely determines whether the window is off the available screen when it's time to apply constraints, and uses the information to determine which of two constraints to apply.
the point is that in order for constraints to mean anything, they have to apply when they're violated. If you add a rule that "this contraint applies only when it's not violated" you might as well not have the constraint at all.
Ah, okay, I think I see what I was misunderstanding. I was thinking that constraints.c was given "here's a snapshot of what the system looks like" AND "here's an event that's about to happen" and is then asked what should happen. I believe you are saying that constraints.c is given a snapshot of what the system looks like and is then asked whether we need to modify it. Am I on the right page now? Okay, so I think a simple modification to what I said should work, but feel free to correct me. Currently constraints uses a lot of information stored in MetaWindows to do its work; e.g. current position, height, width, size hints, whether a window is maximized, fullscreen, placed, etc. We could add a little flag to each window ("offscreen" or something similar), which is set whenever the user manually drags the window off the screen. Then we can determine which constraint to apply by whether the flag is set for the given window--just as we do with many other constraints. Of course, we also need extra logic to differentiate between application movements and user movements in order to get the window off the screen in the first place, but you already said this was easy to do in comment 4. Does this seem sane? Am I missing anything?
and now we're back to my comment 6...
Why doesn't my answer in comment 10 solve that (i.e. "if window->offscreen, then apply constraint 1, if !window->offscreen, apply both constraints 1 and 2)? Are you thinking of a case where one of those events happens while the user is moving the window or something?
That's certainly a way to "solve" it, but it will result in poor behavior in the situations that I described, all to achieve a behavior of dubious usability at best.
Hmm... I don't see why it'd result in poor behavior, but maybe I need to get myself a clue by trying it out and seeing how things work. Even if the code doesn't get accepted (which sounds likely if things are as bad as you make them sound), that would probably be instructive for me to do anyway. Of course, focus bugs come first. :-)
Perhaps this is a naive question, but couldn't it be an option? "Allow-moving-windows-above-top" flag hidden far in the depths of gconf which only the true power users could toggle and only after answering the questions three? ;-) Is this only an implementation issue? If someone comes up with a (reasonable) patch to add this option, would it be accepted? Or is it that the issue is more philosophical? As you've probably guessed, I would very much like to see this feature. I can think of many times when I'd be interested in monitoring only the information in the lower portion of the screen and being able to move the window past the top of the screen would allow me to arrange windows on the desktop more efficiently. The main reason I see for this feature though is that not every application is well written. There are applications out there that do not set the minimum window size properly and allow the window to be freely resized without actually affecting the window contents; shrinking the size merely hides the contents of the lower portion of the window. Unfortunately buttons are usually right at the bottom and currently with metacity there is no way to push them (these kind of broken applications usually don't have a nice keyboard focus handling either).
Please see http://pobox.com/~hp/features.html . But allow me the time to answer your individual questions from my viewpoint: I really dislike a gconf option because options create N! maintainence complexity and few people benefit from their usage. That does not necessarily rule out the possibility of an option, it just means that it should be last implementational choice. (Of course, if it gets to the point of being an option, there is always the possibility that not implementing it is the better choice.) Personally, I believe that this can be implemented cleanly without an option and in a way that makes sense for the majority use case. Rob appears to disagree (and I have to admit he knows a lot more about the relevant code than I do). I will give it a try when other things have cleared off my plate (e.g. focus consistency bugs, special cases for not raising or focusing on click, focus stealing prevention, and a few other random bugs). It's definitely not just an implementation issue--patches have been submitted before to provide this behavior (but, to my knowledge, none of which tried to get the best behavior for the majority usage case as their priority; they simply added a hack that worked for them). Not having well written applications is a /really/ bad reason to provide an option in a window manager. That has been done in the past and what ends up happening is that app A requires all users to set window manager option X and Y, and app B requires all users to unset window manager option X, etc., etc. Infinitely configurable window managers have done more damage to the Unix desktop than anything else, IMO.
Basically everything Elijah said is true, except that its 2^n, not n! :-)
*** Bug 316876 has been marked as a duplicate of this bug. ***
[Cue Wizard of Oz music] Ding! Dong! The bug is dead! The wicked bug, The wicked bug, Ding! Dong! The wicked bug is dead...
*** Bug 328354 has been marked as a duplicate of this bug. ***
*** Bug 330530 has been marked as a duplicate of this bug. ***
*** Bug 337449 has been marked as a duplicate of this bug. ***