mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 416771 - Allow window.focus() to switch tabs. r=NeilDeakin,dao CLOSED TREE
Differential Revision: https://phabricator.services.mozilla.com/D31643 --HG-- extra : source : 5acccb49a66840b5c2266edfb7a8953878a2a040 extra : histedit_source : 33a19d54114ef5eda00aefb1c997d6dbcfb40501
This commit is contained in:
parent
e34a09a25c
commit
300ed443b9
@ -30,6 +30,7 @@ window._gBrowser = {
|
||||
}
|
||||
window.addEventListener("sizemodechange", this);
|
||||
window.addEventListener("occlusionstatechange", this);
|
||||
window.addEventListener("framefocusrequested", this);
|
||||
|
||||
this._setupInitialBrowserAndTab();
|
||||
|
||||
@ -4298,6 +4299,18 @@ window._gBrowser = {
|
||||
case "keypress":
|
||||
this._handleKeyPressEventMac(aEvent);
|
||||
break;
|
||||
case "framefocusrequested": {
|
||||
let tab = this.getTabForBrowser(aEvent.target);
|
||||
if (!tab || tab == this.selectedTab) {
|
||||
// Let the focus manager try to do its thing by not calling
|
||||
// preventDefault(). It will still raise the window if appropriate.
|
||||
break;
|
||||
}
|
||||
this.selectedTab = tab;
|
||||
window.focus();
|
||||
aEvent.preventDefault();
|
||||
break;
|
||||
}
|
||||
case "sizemodechange":
|
||||
case "occlusionstatechange":
|
||||
if (aEvent.target == window && !this._switcher) {
|
||||
@ -4508,6 +4521,7 @@ window._gBrowser = {
|
||||
}
|
||||
window.removeEventListener("sizemodechange", this);
|
||||
window.removeEventListener("occlusionstatechange", this);
|
||||
window.removeEventListener("framefocusrequested", this);
|
||||
|
||||
if (gMultiProcessBrowser) {
|
||||
let messageManager = window.getGroupMessageManager("browsers");
|
||||
|
@ -4176,6 +4176,32 @@ nsresult nsContentUtils::DispatchFocusChromeEvent(nsPIDOMWindowOuter* aWindow) {
|
||||
CanBubble::eYes, Cancelable::eYes);
|
||||
}
|
||||
|
||||
void nsContentUtils::RequestFrameFocus(Element& aFrameElement, bool aCanRaise) {
|
||||
RefPtr<Element> target = &aFrameElement;
|
||||
bool defaultAction = true;
|
||||
if (aCanRaise) {
|
||||
DispatchEventOnlyToChrome(target->OwnerDoc(), target,
|
||||
NS_LITERAL_STRING("framefocusrequested"),
|
||||
CanBubble::eYes, Cancelable::eYes,
|
||||
&defaultAction);
|
||||
}
|
||||
if (!defaultAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
|
||||
if (!fm) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t flags = nsIFocusManager::FLAG_NOSCROLL;
|
||||
if (aCanRaise) {
|
||||
flags |= nsIFocusManager::FLAG_RAISE;
|
||||
}
|
||||
|
||||
fm->SetFocus(target, flags);
|
||||
}
|
||||
|
||||
nsresult nsContentUtils::DispatchEventOnlyToChrome(
|
||||
Document* aDoc, nsISupports* aTarget, const nsAString& aEventName,
|
||||
CanBubble aCanBubble, Cancelable aCancelable, bool* aDefaultAction) {
|
||||
|
@ -1520,6 +1520,12 @@ class nsContentUtils {
|
||||
*/
|
||||
static nsresult DispatchFocusChromeEvent(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
/**
|
||||
* Helper to dispatch a "framefocusrequested" event to chrome, which will only
|
||||
* bring the window to the foreground and switch tabs if aCanRaise is true.
|
||||
*/
|
||||
static void RequestFrameFocus(Element& aFrameElement, bool aCanRaise);
|
||||
|
||||
/**
|
||||
* This method creates and dispatches a trusted event.
|
||||
* If aTarget is not a chrome object, the nearest chrome object in the
|
||||
|
@ -4866,14 +4866,7 @@ void nsGlobalWindowOuter::FocusOuter() {
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mDocShell);
|
||||
|
||||
bool isVisible = false;
|
||||
if (baseWin) {
|
||||
baseWin->GetVisibility(&isVisible);
|
||||
}
|
||||
|
||||
if (!isVisible) {
|
||||
// A hidden tab is being focused, ignore this call.
|
||||
if (!baseWin) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4932,14 +4925,8 @@ void nsGlobalWindowOuter::FocusOuter() {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Element> frame = parentdoc->FindContentForSubDocument(mDoc);
|
||||
if (frame) {
|
||||
uint32_t flags = nsIFocusManager::FLAG_NOSCROLL;
|
||||
if (canFocus) flags |= nsIFocusManager::FLAG_RAISE;
|
||||
DebugOnly<nsresult> rv = fm->SetFocus(frame, flags);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv),
|
||||
"SetFocus only fails if the first argument is null, "
|
||||
"but we pass an element");
|
||||
if (Element* frame = parentdoc->FindContentForSubDocument(mDoc)) {
|
||||
nsContentUtils::RequestFrameFocus(*frame, canFocus);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -159,22 +159,11 @@ IPCResult BrowserBridgeChild::RecvSetLayersId(
|
||||
mozilla::ipc::IPCResult BrowserBridgeChild::RecvRequestFocus(
|
||||
const bool& aCanRaise) {
|
||||
// Adapted from BrowserParent
|
||||
nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
|
||||
if (!fm) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
|
||||
if (!owner) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
uint32_t flags = nsIFocusManager::FLAG_NOSCROLL;
|
||||
if (aCanRaise) {
|
||||
flags |= nsIFocusManager::FLAG_RAISE;
|
||||
}
|
||||
|
||||
fm->SetFocus(owner, flags);
|
||||
nsContentUtils::RequestFrameFocus(*owner, aCanRaise);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -187,8 +176,7 @@ mozilla::ipc::IPCResult BrowserBridgeChild::RecvMoveFocus(
|
||||
}
|
||||
|
||||
RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
|
||||
|
||||
if (!owner || !owner->OwnerDoc()) {
|
||||
if (!owner) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -2121,26 +2121,16 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnWindowedPluginKeyEvent(
|
||||
|
||||
mozilla::ipc::IPCResult BrowserParent::RecvRequestFocus(const bool& aCanRaise) {
|
||||
LOGBROWSERFOCUS(("RecvRequestFocus %p, aCanRaise: %d", this, aCanRaise));
|
||||
BrowserBridgeParent* bridgeParent = GetBrowserBridgeParent();
|
||||
if (bridgeParent) {
|
||||
if (BrowserBridgeParent* bridgeParent = GetBrowserBridgeParent()) {
|
||||
mozilla::Unused << bridgeParent->SendRequestFocus(aCanRaise);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
|
||||
if (!fm) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (!mFrameElement) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
uint32_t flags = nsIFocusManager::FLAG_NOSCROLL;
|
||||
if (aCanRaise) flags |= nsIFocusManager::FLAG_RAISE;
|
||||
|
||||
RefPtr<Element> element = mFrameElement;
|
||||
fm->SetFocus(element, flags);
|
||||
nsContentUtils::RequestFrameFocus(*mFrameElement, aCanRaise);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user