"Jonas Sundström" <jonas@xxxxxxxxxxx> wrote: > Are you guys maybe over-engineering this a little? > > It may be that I haven't grasped the full contents > of your discussion, but I believe that the BWindow > Zoom code I posted shows that there's no need to > change anything about the app_server to make Zoom > not overlap Deskbar. Well, I'm a big fan of keeping things as simple as they possibly can be, from the user's point of view, the application programmer's point of view, and the API designer's point of view. But adding some kind of special-case specifically for the Deskbar doesn't really seem to solve the core issue here -- which is windows overlapping into "forbidden" areas of the screen. There are already quite a few launcher-type applications on Bebits, and several users have multi-monitor configurations, potentially with unequal sized monitors. Something that can handle forbidden areas of the screen in a general sense as easily as possible would be pretty desirable, I think! From a more immediate standpoint, I've been thinking about implementing an application for R5 and Haiku which sits in the background watching for new windows being opened and zoomed. Upon detecting either condition, the window will be moved/clipped to avoid forbidden areas of the screen. The original motive for writing it is to make things more convenient right now on a multi-monitor system, but as the topic of windows overlapping the Deskbar was also brought up, it seems like this would also solve that problem simultaneously. > If people want to add other Deskbar-ish components > and want other apps to not overlap these, there's > scripting support in BWindow, which any application > is free to use to tell another overlapping application > not to do so. ("hey, don't cover me") Hmm, could you provide some examples of how this might be used? Specifically, could it solve the overlapping problem for multiple forbidden rectangles without any changes to applications, aside from Deskbar and other launcher apps? "André Braga" <meianoite@xxxxxxxxx> wrote: > And it would solve my main grip against Mac OS and OSs using the > concept of a zoom button in general. It makes sense to *maximise* > the browser window, g'dammit :) Heh, I never run browsers maximized, even on a single monitor! A lot of sites use fixed-width designs which leaves lots of white space at the edges if you're above their "recommended resolution", plus there's no room for extra windows then. I know a lot of people do though, so solving the overlap problem would be beneficial there. It would be nice to have a choice between fit-to-document and zoom-to-largest-possible-size, especially in the case of a browser; some users will expect the latter, but personally I'd always use the former. Neither Firefox nor NetPositive support fit-to-document, which means I spend a lot of time twiddling the width of the window from site to site. I'm not sure it should be a three-state mechanism like you described though -- the main reason is this: When you perform a fit-to-document, the window always expands rightwards and downwards (which is good), leaving the zoom button in exactly the same place -- below the mouse. If the zoom wasn't desired, the user can simply click it again without performing any mouse movement. When performing a zoom-to-largest-possible-size, the window may expand leftwards and upwards as well, moving the tab and thus the zoom button. Therefore the mouse needs to travel -- possibly many thousands of pixels -- in order to reach the zoom button again. I find this a *huge* problem under Windows where the tiny maximize button is crammed within just a couple of pixels of the close button: attempt to close the window, and it suddenly expands to exceed your field of vision, leaving the mouse stranded somewhere in the middle and the user in a state of panic. =P (Mac OS- or GEM-style "zoom animations" could help with easing the shock, but still, zooming a window to the maximum possible size can be a highly surprising operation). One solution might be to move the mouse along with the window tab, so it retains its relative position. However I think that'd really violate the principle of least surprise for some users. And there'd still be an element of surprise in that it's difficult to tell what state you've left a window in (e.g., click zoom, it expands slightly, click it again, it restores, make a cup of tea, come back and click zoom again and it's suddenly full-screen -- and the tea is on the floor). How about using the secondary mouse button (aka ctrl+click) on the zoom button for performing zoom-to-largest-possible-size, and defaulting to fit-to-document? We already use the secondary button for sending a window to the background, so it might not be that surprising? Alternatively perhaps a double-click could work? That's also already familiar (from hiding a window), and the first click could perform fit-to-document without rendering the second click uncatchable (because the tab doesn't move). > Because your definition forbids that the legal areas overlap. Mine > basically mandates it :) Aah, okay, that's the key difference here. Using legal rectangles requires a different algorithm to the one I had in mind, which was simply this: 1) Expand the window leftwards until it hits an illegal area, 2) Expand the window upwards until it hits an illegal area, 3) Expand the window rightwards until it hits an illegal area, 4) Expand the window downwards until it hits an illegal area. A priority setting -- B_MAXIMUM_HORIZONTAL or B_MAXIMUM_VERTICAL -- is passed to the expansion function (or if not provided, defaults to a system-wide value) to decide whether to flip stages 1<->2 and 3<->4, perhaps also B_MAXIMUM_BOTH to make horizontal and vertical expansion happen simultaneously. The purpose being to give the application a choice of which axis is more important to maximise, if any. Using overlapping legal areas, here's a proposed alternative algorithm: 1) Scan through the list of legal rectangles, picking the one which has the largest overlapping area with the window. In the (likely) event of there being several equal candidates (usually rectangles which contain the window in its entirety), return all of those rectangles. 2) Out of those, choose the rectangle which provides either the most: a) Increase in total area, b) Horizontal expansion in pixels, c) Vertical expansion in pixels, depending on the setting supplied to the expansion function -- B_MAXIMUM_AREA, B_MAXIMUM_HORIZONTAL, B_MAXIMUM_VERTICAL, or B_USE_SYSTEM_DEFAULT. Additionally, these constants could form a bitfield, where more than one is permitted, e.g.: B_MAXIMUM_AREA | B_MAXIMUM_HORIZONTAL would favour the area and horizontal expansion roughly equally. 3) If multiple results qualify equally, pick the top-left-most rectangle, which could be calculated as: BRect.top + BRect.left. (2) gets a bit confusing with regard to how to sort the rectangles in terms of desirability regarding area vs. horizontal/vertical expansion figures. Here's a proposed algorithm for doing that, but I've not tested it and it's probably far from perfect: float calculate_desirability( float current_x_size, float current_y_size, float target_rect_x_size, float target_rect_y_size, uint8 mode ) { float total, old_area, new_area; float area_gained, x_gained, y_gained; old_area = current_x_size * current_y_size; new_area = target_rect_x_size * target_rect_y_size; area_gained = new_area - old_area; x_gained = target_rect_x_size - current_x_size; y_gained = target_rect_y_size - current_y_size; x_gained *= x_gained; y_gained *= y_gained; total = 0; if( mode & B_USE_SYSTEM_DEFAULT ) mode = get_system_default(); if( mode & B_MAXIMUM_HORIZONTAL ) total += x_gained; else if( mode & B_MAXIMUM_VERTICAL ) total += y_gained; else if( mode & B_MAXIMUM_AREA ) total += area_gained; else return(0); return(total); } The target rectangle is therefore the one which yields the most positive return value from this function (out of those rectangles selected by criteria #1). Zooming-to-fit (as opposed to zooming-to-fill-total-area) would be much the same algorithm, except the rectangles are clipped to the window's current top-left position before passing to the above function (to account for the fact that we're only expanding rightwards and downwards). > I have grown used to it already, but people are often surprised by > the lack of a maximise button. In some ways this can be an advantage -- it forces the user to think in a less destructive manner! ("apps belong full-screen") Though I think this can be provided non-destructively as long as it's treated as a secondary feature; e.g. double-click the zoom button... > Right; but users should never have to pay this price. This > algorithm should only kick in for events that result in automatic > window placement, like a new window being spawned or the zoom > button being activated on an existing one. Under no circumnstances > it shall kick in as a result of explicit window placement or > resizing done by the user. Agreed. The only area of confusion is what happens when the user moves the Deskbar -- users of MS Windows might expect windows to be relocated to adhere to that platform's rule of never allowing windows to overlap the start bar. But then again if we're allowing the users to explicitly overlap windows with the Deskbar (as we should), then I suppose it makes sense not to perform any automatic clipping when they move the Deskbar. One question though: what happens when the user has "stay on top" selected for the Deskbar, and they drag the Deskbar so it overlaps some windows? Should the now-partially-obscured windows remain in their existing locations? > I'm still not sure what would the POLA-friendly behaviour of moving > a window to a screen with smaller legal areas than the window > currently occupies be. Or any other action that modify the > available areas, actually. Hmm, I would think something like this: - Moving a window onto a monitor which can't accommodate it should just cause the window to become overscanned: the user will notice this, move the window back and perform the adjustments automatically for the programmer. ;) This is pretty much what happens already with workspaces under BeOS, and it's in-keeping with the principles of spatial orientation -- if the user has a large monitor next to a small monitor (lined up at the bottom edge), then it behaves simply like a massive monitor with duct tape stuck across the top-right of the screen, and therefore shouldn't interact with the window during dragging (though the mouse shouldn't be allowed to enter that area). - Changing the monitor settings so that the resolution is lowered, or a previously-visible area of the desktop becomes invisible should force the windows to be moved/resized to avoid them becoming lost or unresizable. That's pretty much all I have to add at the moment; I'll get around to writing that app at some point, which can serve as a test platform if anyone has any other ideas for zoom algorithms. Thanks for the input, as always!