Closed Bug 465186 Opened 16 years ago Closed 13 years ago

Detaching a tab does not open the new window at the drop location (dragging tab to an empty second monitor opens window on the wrong monitor)

Categories

(Firefox :: Tabbed Browser, defect)

defect
Not set
normal

Tracking

()

VERIFIED FIXED
Firefox 7

People

(Reporter: sylvain.pasche, Assigned: int3)

References

(Depends on 1 open bug, Blocks 1 open bug)

Details

(Keywords: polish, Whiteboard: [parity-safari][polish-hard][polish-interactive][polish-p2])

Attachments

(2 files, 9 obsolete files)

If a tab is detached and dropped at a given point, the new window that is opened will be located near the window that contained the tab but not where the tab was dropped. This is most visible if you have two monitors. If you drag a tab to the other monitor, the window will open on the wrong one. Safari does the right thing in this case.
Whiteboard: [parity-safari]
Depends on: 466379
Confirmed - this is a real pain if you have more than one monitor.
Flags: blocking-firefox3.1?
Keywords: dogfood
Really really wanted, but not blocking. Let's hope that the core bug this relies on can be fixed in a timely manner.
Flags: wanted-firefox3.1+
Flags: blocking-firefox3.1?
Flags: blocking-firefox3.1-
Keywords: polish
Whiteboard: [parity-safari] → [parity-safari][polish-hard]
OS: Mac OS X → All
Hardware: x86 → All
Mano: any idea why this is happening?
Keywords: dogfood
So I took a look at this yesterday, and we can get the mouse coords. However when changing the window features string to ww.openWindow to include top= & left=, it's not changing the position of the window... I'll do some more investigating.
(In reply to comment #6) > I'll do some more investigating. We'd like that solution for SessionStore's _openWindowWithState as well, BTW.
Attached file Guilty Stack Trace (obsolete) —
An update on the investigation - it looks like it's getting the right initial position, but then something else positions the window afterward. So I'm pretty sure this is the guilty stack trace. I'm working on going through this now to see if I can track it down more specifically. One thing I've noticed is that nsXULWindow::GetPositionAndSize gives the correct coords, but windowElement->GetAttribute("screenX") (and screenY) result in incorrect positioning. The window then gets repositioned based on these incorrect positions. Why? I don't know... It might be that we need to go one step up and never even call LoadPositionFromXUL... I'll talk to a window specialist ASAP
I see you are testing on Mac. I also noticed some strange behaviors with window positioning there (see bug 461285 comment 2). Basically, setting screenX/screenY on the window had no effect when set just after the window is opened. It worked if I waited a few hundred milliseconds and set the screenX/screenY at that moment.
Attached patch Patch v0.1 (WIP) (obsolete) — Splinter Review
I had a patch in progress in my patch queue, so I thought I'd throw it up here. In theory, this should be all we need, but as mentioned previously, there appears to be a problem with positioning a window. Also, we'll want to do more than just position the window where the use drops is. For real [parity-safari] we'll need to do smart positioning to keep windows on screen (maybe make that a pref - surely somebody would want dumb positioning).
This bug's priority relative to the set of other polish bugs is: P2 - Polish issue that is in a secondary interface, occasionally encountered, and is easily identifiable. This bug is super obvious when you tear off a tab, I'm just not sure how many users are tearing their tabs off yet (or even know that now they can). Might need to switch to a P1 if the feature becomes more widely known.
Whiteboard: [parity-safari][polish-hard] → [parity-safari][polish-hard][polish-interactive][polish-p2]
Paul: did you file any Core bugs about the positioning issues you encountered? That should get done sooner than later if this is to make 3.next.
(In reply to comment #13) > Paul: did you file any Core bugs about the positioning issues you encountered? > That should get done sooner than later if this is to make 3.next. I didn't get much further than what I said in comment #8, so no other bugs got filed. Hopefully I'll have a chance to get back at it soon, though I'm a bit swamped with other stuff. If anybody wants to poke around at it, feel free. I can't speak for drivers, but I would imagine a fix for this would go into 3.5.1 if found in time.
Attached patch patch (obsolete) — Splinter Review
Here's another idea. The reason (I think) the other approach wasn't working is because the screenX and screenY attributes are defined and persisted on the window. That was overriding the position setting from the openWindow call. This does its thing in BrowserStartUp, after a timeout so that the window is ready to be moved (without the timeout it wouldn't work). I've also made sure to clamp the values to reasonable numbers, as well as a small initial change to get it just right.
Assignee: nobody → highmind63
Attachment #393878 - Flags: review?(mano)
Depends on: 509828
Attached patch patch ver. 2 (obsolete) — Splinter Review
Make it actually work... windowState isn't available to _after_ unload, so we have to check for it then. The clamping also needed some tweaking to make sure the window is always accessible. No need to check for the existence of the attributes, as we always set them.
Attachment #393878 - Attachment is obsolete: true
Attachment #393914 - Flags: review?(mano)
Attachment #393878 - Flags: review?(mano)
Flags: wanted-firefox3.6?
Status: NEW → ASSIGNED
Comment on attachment 393914 [details] [diff] [review] patch ver. 2 Thanks to Neil Rushbrook, I found this out: http://hg.mozilla.org/mozilla-central/annotate/bc5324d3f8fc/embedding/components/windowwatcher/src/nsWindowWatcher.cpp#l745 So, if you specify either the height or the width of the new window, the persisted values would be left off. Let's go back to the previous approach then.
Attachment #393914 - Flags: review?(mano) → review-
(In reply to comment #17) > Thanks to Neil Rushbrook, I found this out: > http://hg.mozilla.org/mozilla-central/annotate/bc5324d3f8fc/embedding/components/windowwatcher/src/nsWindowWatcher.cpp#l745 > > So, if you specify either the height or the width of the new window, the > persisted values would be left off. Let's go back to the previous approach > then. The first WIP patch already tried that (specifying a "width=" in the features) and it didn't work. In my testing it didn't work either, so I'm not sure what exactly you mean...
As mentioned on IRC, you'd probably have to use "classic" js window.open/window.openDialog to get this effect working. It might be worth filing a bug on that.
Adding keywords to the summary to make this bug easier to find...
Summary: Detaching a tab does not open the new window at the drop location → Detaching a tab does not open the new window at the drop location (dragging tab to an empty second monitor opens window on the wrong monitor)
Not going to be able to get to this.
Assignee: highmind63 → nobody
Status: ASSIGNED → NEW
Paul your patch should be good to go, bug 509828 is fixed on trunk.
(In reply to comment #25) > Paul your patch should be good to go, bug 509828 is fixed on trunk. Thanks for the reminder and filing & fixing that bug. I'll take a look at it this week. It would definitely be nice to have for 3.6. I'll probably add in the logic you had to keep the window on screen, though long-term I think something more advanced would be nice (re comment #10).
Beltzner says this has a good chance of landing for 3.6 but it needs to bake on trunk & happen soon. Getting some UX help on how we should behave around the edges.
Adding uiwanted; Paul do you have specific questions about those edges? Like, what edge behaviours do you want to get feedback on?
Keywords: uiwanted
(In reply to comment #28) > Adding uiwanted; Paul do you have specific questions about those edges? Like, > what edge behaviours do you want to get feedback on? I briefly talked to Boriss yesterday about this. Specifically I'm looking for feedback on what we do when a window overflows the available size of the screen. The patch I have right now just builds in a buffer around the edges so you can't lose a window. It's naive but works. Things to consider: should we resize/move the window so that upon dropping, the new window is always completely visible? Or do we trust that the user meant to have it partially offscreen. Do we size the new window the same as the previous? or just keep doing what we're doing? Do we put a pref in to switch back to current behavior (because people might have gotten used to it)? Other thoughts, since the cursor holds onto the top left of the "preview", we should position the top left of the window there (easy & working). But that's not really ideal. I like how Safari does it. Maybe here we keep it simple & naive. Then for the tab animation project we really think about what should be happening and redo the experience.
Attached patch Patch v0.3 (obsolete) — Splinter Review
Current patch. Only does protection along the right & bottom because it's ok if the window gets positioned at (0,0). Problem: This doesn't work with multiple monitors (screen.availWidth is only the current/default? monitor).
(In reply to comment #30) > Problem: This doesn't work with multiple monitors (screen.availWidth is only > the current/default? monitor). I think you need to look at screen.availLeft and screen.availTop.
Comment on attachment 407415 [details] [diff] [review] Patch v0.3 >+ if (aLeft !== null) { // explicit null check because could be == 0 The second "=" is unnecessary. In fact, it's incorrect, because undefined !== null.
Flags: wanted-firefox3.6? → wanted-firefox3.6+
(In reply to comment #31) > (In reply to comment #30) > > Problem: This doesn't work with multiple monitors (screen.availWidth is only > > the current/default? monitor). > > I think you need to look at screen.availLeft and screen.availTop. Those help with top/left (eg on OS X, availTop is 22, not 0) but that doesn't help the multiple monitor situation. screen only picks up attributes from the monitor the window is on. Do we have something that will give us a better breakdown on available screen real estate?
nsIScreenManager lets you get the screen for a given rectangle with screenForRect. I think you should be able to get the screen object for all the relevant screens using that. Your current patch is also assuming that screenX/Y are between 0 and the width/height of the current screen. This is not always true. For example, if you have two identical screens, and set your primary screen to be to the right of the other one, then all of the screenX coordinates on the left screen will be negative.
(In reply to comment #34) > nsIScreenManager lets you get the screen for a given rectangle with > screenForRect. I think you should be able to get the screen object for all the > relevant screens using that. Thanks. Looks perfect. I can use screenForRect with the drop location & window size. > Your current patch is also assuming that screenX/Y are between 0 and the > width/height of the current screen. This is not always true. For example, if > you have two identical screens, and set your primary screen to be to the right > of the other one, then all of the screenX coordinates on the left screen will > be negative. I'm using availTop & availLeft locally, so that should be ok now. You're right though.
Blocks: 566509
Blocks: multimon-win
Any work still being done on this? Would be nice to have in 4.0
(In reply to comment #42) > Any work still being done on this? Would be nice to have in 4.0 Agreed. Especially with the proliferation of ATI Eyefinity & NVIDIA Surround setups over the last year, multi-monitor configurations are becoming a lot more common. I find this issue annoying, but I have a friend who switched to Chrome (and I'm hoping to convince him to switch back for FF4) because of speed, tabs on top (something I don't like but am glad it's a preference choice in FF4) & this issue, all of which will be addressed for Firefox 4 except for this issue and he won't switch back until it is. I'm sure there must be quite a few other multi-monitor setup users who've done the same or at least find quite annoying. Doesn't seem like this issue *should* be that hard to fix, with a little time from a few more higher up eyes (I say *should* because I did read what Paul said and it sounds like this is an issue being made unnecessarily cumbersome by Firefox's massive legacy codebase design causing unexpected conflicts for an unexpected issue).
This really is the main reason I keep using chrome over FF, it sounds so small but the silly task of dragging off a tab, having it maximize on the wrong screen, so I have to double click to shrink, then drag, and then double click the bar again to maximize. Its a small pain that makes browsing annoying.
It's a shame this still hasn't been fixed.
I honestly thought that this was a new bug with Firefox 4. At least from 3.4 (i think) onwards for definite, in all honesty i hadn't tried before, I'd been able to do this no problem, first on XP then on Win 7. I only lost the ability to do so as I updated to 4 RC today
Did a bit more poking around and it seems that the new window is being created at the default position to create new windows. Example 1: Opened window A (full screen on monitor 1) Dragged tab to monitor 2 Result: Full screen window on monitor 1 Example 2: Opened window A (full screen on monitor 1) Moved window A to monitor 2, to center of the screen State: Window A is windowed on monitor 2 dragged new tab to monitor 1 Result: Window B is the same size as window A, aligned slightly down and . to the right, i.e. default new window behavior Example 3: Opened window A (windowed on monitor 1) Moved window A to monitor 2, dropping it on the top of the screen, . using Windows 7 to make the window full screen (this does not change the default screen of the window) State: Window A is full screen on monitor 2 Dragged new tab to monitor 1 Result: Window B is full screen on monitor 1 I then repeated all the tests using the opposite screens and got the opposite results as expected. As you can see the windowed/full screen is retained correctly but otherwise it is simply using the default position of the window. I plan to look into this more but I'm afraid that I haven't seriously coded in a long time so doubt I'll get very far beyond doing tests to try and work out the exact behavior of this bug.
(In reply to comment #48) > I plan to look into this more but I'm afraid that I haven't seriously coded in > a long time so doubt I'll get very far beyond doing tests to try and work out > the exact behavior of this bug. I appreciate you looking into this, but the behavior is pretty well known. Windows are opened based on previous state and positioning indicated in localstore.rdf
(In reply to comment #30) > Created attachment 407415 [details] [diff] [review] > Patch v0.3 > > Current patch. Only does protection along the right & bottom because it's ok if > the window gets positioned at (0,0). > > Problem: This doesn't work with multiple monitors (screen.availWidth is only > the current/default? monitor). This still makes the problem less annoying. Paul, could we recycle this patch, land it, and handle the monitor issue separately?
I've had a patch that fixed this for a while now. Didn't realize it was its own bug.
Assignee: nobody → fryn
Status: NEW → ASSIGNED
Ack. Wrong bug. Bugzilla, why you so confusing! Paul, do you have a basic patch for this? It'll be even more obvious that we're doing it wrong after we get bug 455694. A basic patch is better than nothing.
Assignee: fryn → nobody
Status: ASSIGNED → NEW
Attached patch Patch v0.4 (WIP)Splinter Review
I looked at this again not too long ago and it's using the screen manager to get the right screen size. On OS X (either our window opening code or OS X itself) seem to handle keeping a window on screen (no resizing unless between monitors) so that's ifdef'd out. Frank said he might put in support to resize the window down to keep the window as close to drop coordinates as possible.
Attachment #373882 - Attachment is obsolete: true
Attachment #383029 - Attachment is obsolete: true
Attachment #393914 - Attachment is obsolete: true
Attachment #407415 - Attachment is obsolete: true
Not exactly sure yet, if uiwanted is still necessary but cc'ing Limi. Also it would be great if we could get this issue fixed for Fx7.
Attached patch Patch v0.5 (obsolete) — Splinter Review
This is an improvement upon zpao's patch. This fixes some errors in the positioning and drops tabs based on the positioning of the cursor instead of the area of the window that overlaps with the various screens. Additionally, it handles the case where the tab being dragged is the only one in its window. This patch has been tested on OS X and Windows. On Windows, specifying the size of a detached tab via options passed to openDialog() seems problematic -- the webpage in the resulting window does not extend to the bottom of the window. To reproduce this problem: 1. Remove the #ifndef XP_WIN section in the patch 2. Create a browser session with at least two tabs in one window 3. Detach one tab via drag & drop Result: The rendered page in the new window does not extend to the bottom of the window. I haven't quite figured out what happens when we do not specify the size of the new window. Sometimes it takes the size of the window that the tab was dragged from and sometimes it takes the size of a different window. However, in all cases, the resulting window fits within the monitor that it is dropped into, so it doesn't seem _too_ big a deal.
Jezreel, what's the purpose of the nsGlobalWindow.cpp part of your patch?
When there's only one tab in the window being dragged, I call window.moveTo() instead of destroying and recreating the window, as the latter is slower. However, I ran into a problem with the mSuppressLevel lock in nsGlobalWindow. This lock is acquired whenever moveTo() is called and nsGlobalWindow thinks the mouse button is being held down. Of course, the mouse button has been released by the time we receive the 'dragend' event, but currently the window doesn't know this because it looks for the mouseUp event, and since the mouseUp happens when the mouse is outside the global window, the event does not get sent to the window. The change to nsGlobalWindow.cpp fixes that. This mSuppressLevel lock was actually introduced in bug 329385 by smaug as part of a security fix. The change to nsGlobalWindow.cpp was made after discussing the above problem with him.
Comment on attachment 539431 [details] [diff] [review] Patch v0.5 smaug should probably review this part, then.
Attachment #539431 - Flags: review?(Olli.Pettay)
Assignee: nobody → jezreel
gg
Oops, I guess I left some random characters in the textbox when I clicked 'Save Changes'. Anyway, cc'ing smaug...
Comment on attachment 539431 [details] [diff] [review] Patch v0.5 >+++ b/dom/base/nsGlobalWindow.cpp >@@ -2536,17 +2536,18 @@ > gEntropyCollector->RandomUpdate((void*)&(aVisitor.mEvent->time), > sizeof(PRUint32)); > } > } else if (msg == NS_RESIZE_EVENT) { > mIsHandlingResizeEvent = PR_TRUE; > } else if (msg == NS_MOUSE_BUTTON_DOWN && > NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) { > gMouseDown = PR_TRUE; >- } else if (msg == NS_MOUSE_BUTTON_UP && >+ } else if ((msg == NS_MOUSE_BUTTON_UP || >+ msg == NS_DRAGDROP_END) && add one space before the latter msg. Reviewing only this part, r=me.
Attachment #539431 - Flags: review?(Olli.Pettay) → review+
Attached patch Patch v0.6 (obsolete) — Splinter Review
Added in the space as per smaug's review.
Attachment #539431 - Attachment is obsolete: true
Attachment #539661 - Flags: review?(dao)
Attached patch Patch v0.7 (obsolete) — Splinter Review
Previously, the new window created when a tab gets dropped is positioned with the corner of the window next to the mouse cursor. I've modified the patch slightly to drop the window such that the position of the mouse relative to the corner of the dragged tab stays the same before and after the drag. With this change, after the user drops a tab and a new window is created, he can start a new drag session by clicking on the same spot. Thanks fryn for the suggestion!
Attachment #539661 - Attachment is obsolete: true
Attachment #539661 - Flags: review?(dao)
Attachment #540215 - Flags: review?(dao)
(In reply to comment #65) > Created attachment 540215 [details] [diff] [review] [review] > Patch v0.7 Nit: I'd prefix dragOffset[X|Y] with an underscore. I'm surprised that there is a scrollboxPaddingStart property :P Also, it's good that you freed dragOffset[X|Y] in the drop handler :)
I was surprised too -- I chanced upon it while searching for stuff in the file. Apparently the pinned tabs code uses it. (:
Attached patch Patch v0.8 (obsolete) — Splinter Review
Added in underscores as per fryn's suggestion.
Attachment #540215 - Attachment is obsolete: true
Attachment #540275 - Flags: review?(dao)
Attachment #540215 - Flags: review?(dao)
Blocks: 597989
Attached patch Patch v0.9Splinter Review
So I noticed that by moving / resizing a dragged window with only one tab we could end up with it placed behind existing browser windows. I've fixed it up so that our dragged window retains the focus.
Attachment #540275 - Attachment is obsolete: true
Attachment #543342 - Flags: review?(dao)
Attachment #540275 - Flags: review?(dao)
No longer blocks: 597989
Depends on: 668711
Comment on attachment 543342 [details] [diff] [review] Patch v0.9 >+ let bo = this.mTabstrip.boxObject; >+ let paddingStart = this.mTabstrip.scrollboxPaddingStart; >+ // _dragOffset[X|Y] give the coordinates that the mouse should be >+ // positioned relative to the corner of the new window created upon >+ // dragend such that the mouse appears to have the same position >+ // relative to the corner of the dragged tab. >+ tab._dragOffsetX = event.screenX - tab.boxObject.screenX + paddingStart + bo.screenX - window.screenX; >+ tab._dragOffsetY = event.screenY - tab.boxObject.screenY + bo.screenY - window.screenY; - The horizontal calculation doesn't take pinned tabs into account. - The scrollboxPaddingStart usage is fragile, as it may be different depending on whether the tab strip is overflowing. - "+ bo.screenY - window.screenY" seems redundant, it should always be 0. >+ var sm = Cc["@mozilla.org/gfx/screenmanager;1"]. >+ getService(Ci.nsIScreenManager); >+ var whichScreen = sm.screenForRect(eX, eY, 1, 1); >+ var sX = {}, sY = {}, sW = {}, sH = {}; >+ whichScreen.GetAvailRect(sX, sY, sW, sH); >+ // ensure new window entirely within screen >+ var winWidth = Math.min(window.outerWidth, sW.value); >+ var winHeight = Math.min(window.outerHeight, sH.value); >+ var aLeft = Math.min(Math.max(eX - draggedTab._dragOffsetX, sX.value), sX.value + sW.value - winWidth); >+ var aTop = Math.min(Math.max(eY - draggedTab._dragOffsetY, sY.value), sY.value + sH.value - winHeight); - The amount of two-letter variable names is slightly overwhelming. sW and sH can be sWidth and sHeight, at least. - The "a" prefix should be used arguments from the outside, not for variables that you intend to pass to other functions. I'll address these comments and land it.
Attachment #543342 - Flags: review?(dao) → review+
Status: NEW → RESOLVED
Closed: 13 years ago
Keywords: uiwanted
Resolution: --- → FIXED
Target Milestone: --- → Firefox 7
Setting resolution to Verified Fixed on Mozilla/5.0 (Windows NT 6.1; rv:7.0a2) Gecko/20110707 Firefox/7.0a2
Status: RESOLVED → VERIFIED
THANK YOU. Finally, this bug has been resolved and was included in the Firefox 7 release as targeted. To everyone who contributed to this bug fix, thank you so much. In my opinion, after the memory handling fixes, this is the most significant feature/update introduced in Firefox 7 (certainly as far as usability improvements go) and yet it went completely unmentioned in the main list of the Firefox 7 "what's new" improvements? Who's running Mozilla? This was an important (and long overdue) feature that should have been advertised (catching Firefox 7 up to Chrome) and should be added there now (better late than never). - JS
Depends on: 851928
Why does this problem still exist in 2013...?
Flags: needinfo?
Who knows. It still exists in Firefox Nightly (28.0a1 (2013-11-17)) on Ubuntu 12.10.
Flags: needinfo?
Firefox 25.0.1 on Windows 7 here. Glad I'm not the only one.
Flags: needinfo?(jezreel)
This still works for me in the single monitor case on Windows 7 and OS X 10.9 but not in the multi-monitor case for 10.7 and 10.9 so I filed bug 949320. When bugs have been fixed for a long time, you should always file new bugs about regressions rather than commenting in ones many years old.
Flags: needinfo?(jezreel)
Depends on: 675401

Firefox 84.0.2 and the bug is still there in 2021.. this drives me crazy

Yes I think it has resurfaced.

https://www.youtube.com/watch?v=ngMwYX0fJYo

I have further information

This is only a problem for me, when using RDP.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: