Bug 1137229 - Keyboard input can stop working in a window. r=smaug

This commit is contained in:
Steven Michaud 2015-03-24 11:41:32 -05:00
parent 79493e5ce3
commit f38180eace
3 changed files with 67 additions and 11 deletions

View File

@ -45,6 +45,9 @@ HTMLObjectElement::HTMLObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& a
HTMLObjectElement::~HTMLObjectElement()
{
#ifdef XP_MACOSX
OnFocusBlurPlugin(this, false);
#endif
UnregisterActivityObserver();
DestroyImageLoadingContent();
}
@ -113,20 +116,50 @@ NS_IMPL_NSICONSTRAINTVALIDATION(HTMLObjectElement)
static nsIWidget* GetWidget(Element* aElement)
{
nsIWidget* retval = NULL;
nsIFrame* frame = aElement->GetPrimaryFrame();
if (frame) {
retval = frame->GetNearestWidget();
}
return retval;
return nsContentUtils::WidgetForDocument(aElement->OwnerDoc());
}
static void OnFocusBlurPlugin(Element* aElement, bool aFocus)
Element* HTMLObjectElement::sLastFocused = nullptr; // Weak
class PluginFocusSetter : public nsRunnable
{
nsIWidget* widget = GetWidget(aElement);
if (widget) {
bool value = aFocus;
widget->SetPluginFocused(value);
public:
PluginFocusSetter(nsIWidget* aWidget, Element* aElement)
: mWidget(aWidget), mElement(aElement)
{
}
NS_IMETHOD Run()
{
if (mElement) {
HTMLObjectElement::sLastFocused = mElement;
bool value = true;
mWidget->SetPluginFocused(value);
} else if (!HTMLObjectElement::sLastFocused) {
bool value = false;
mWidget->SetPluginFocused(value);
}
return NS_OK;
}
private:
nsCOMPtr<Element> mElement;
nsCOMPtr<nsIWidget> mWidget;
};
void
HTMLObjectElement::OnFocusBlurPlugin(Element* aElement, bool aFocus)
{
if (aFocus || aElement == sLastFocused) {
if (!aFocus) {
sLastFocused = nullptr;
}
nsIWidget* widget = GetWidget(aElement);
if (widget) {
nsContentUtils::AddScriptRunner(
new PluginFocusSetter(widget, aFocus ? aElement : nullptr));
}
}
}
@ -210,6 +243,14 @@ void
HTMLObjectElement::UnbindFromTree(bool aDeep,
bool aNullParent)
{
#ifdef XP_MACOSX
// When a page is reloaded (when an nsIDocument's content is removed), the
// focused element isn't necessarily sent an NS_BLUR_CONTENT event. See
// nsFocusManager::ContentRemoved(). This means that a widget may think it
// still contains a focused plugin when it doesn't -- which in turn can
// disable text input in the browser window. See bug 1137229.
OnFocusBlurPlugin(this, false);
#endif
nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
}

View File

@ -33,7 +33,11 @@ public:
#ifdef XP_MACOSX
// nsIDOMEventTarget
NS_IMETHOD PostHandleEvent(EventChainPostVisitor& aVisitor) override;
// Helper methods
static void OnFocusBlurPlugin(Element* aElement, bool aFocus);
static void HandleFocusBlurPlugin(Element* aElement, WidgetEvent* aEvent);
// Weak pointer. Null if last action was blur.
static Element* sLastFocused;
#endif
// Element

View File

@ -62,6 +62,9 @@ HTMLSharedObjectElement::SetItemValueText(const nsAString& aValue)
HTMLSharedObjectElement::~HTMLSharedObjectElement()
{
#ifdef XP_MACOSX
HTMLObjectElement::OnFocusBlurPlugin(this, false);
#endif
UnregisterActivityObserver();
DestroyImageLoadingContent();
}
@ -159,6 +162,14 @@ void
HTMLSharedObjectElement::UnbindFromTree(bool aDeep,
bool aNullParent)
{
#ifdef XP_MACOSX
// When a page is reloaded (when an nsIDocument's content is removed), the
// focused element isn't necessarily sent an NS_BLUR_CONTENT event. See
// nsFocusManager::ContentRemoved(). This means that a widget may think it
// still contains a focused plugin when it doesn't -- which in turn can
// disable text input in the browser window. See bug 1137229.
HTMLObjectElement::OnFocusBlurPlugin(this, false);
#endif
nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}