Bug 1282003 - (Part 3) Add screen ID to nsWindow and GeckoView to get the correct nsScreen and density. r?snorp
MozReview-Commit-ID: Cd9MS2I1RRQ
--- a/gfx/src/nsDeviceContext.cpp
+++ b/gfx/src/nsDeviceContext.cpp
@@ -1,9 +1,10 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=4 expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsDeviceContext.h"
#include <algorithm> // for max
#include "gfxASurface.h" // for gfxASurface, etc
#include "gfxContext.h"
@@ -606,17 +607,25 @@ nsDeviceContext::FindScreen(nsIScreen**
if (mWidget->GetOwningTabChild()) {
mScreenManager->ScreenForNativeWidget((void *)mWidget->GetOwningTabChild(),
outScreen);
}
else if (mWidget->GetNativeData(NS_NATIVE_WINDOW)) {
mScreenManager->ScreenForNativeWidget(mWidget->GetNativeData(NS_NATIVE_WINDOW),
outScreen);
}
- else {
+
+#ifdef MOZ_WIDGET_ANDROID
+ if (!(*outScreen)) {
+ nsCOMPtr<nsIScreen> screen = mWidget->GetWidgetScreen();
+ screen.forget(outScreen);
+ }
+#endif
+
+ if (!(*outScreen)) {
mScreenManager->GetPrimaryScreen(outScreen);
}
}
bool
nsDeviceContext::CalcPrintingSize()
{
if (!mPrintTarget) {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
@@ -1,9 +1,10 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: ts=4 sw=4 expandtab:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import java.util.Set;
@@ -43,16 +44,17 @@ public class GeckoView extends LayerView
private static final String LOGTAG = "GeckoView";
private ChromeDelegate mChromeDelegate;
private ContentDelegate mContentDelegate;
private InputConnectionListener mInputConnectionListener;
private boolean onAttachedToWindowCalled;
+ private int screenId = 0; // default to the primary screen
@Override
public void handleMessage(final String event, final JSONObject message) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
try {
if (event.equals("Gecko:Ready")) {
@@ -109,17 +111,17 @@ public class GeckoView extends LayerView
}
@WrapForJNI(dispatchTo = "proxy")
private static final class Window extends JNIObject {
@WrapForJNI(skip = true)
/* package */ Window() {}
static native void open(Window instance, GeckoView view, Object compositor,
- String chromeURI);
+ String chromeURI, int screenId);
@Override protected native void disposeNative();
native void close();
native void reattach(GeckoView view, Object compositor);
native void loadUri(String uri, int flags);
}
// Object to hold onto our nsWindow connection when GeckoView gets destroyed.
@@ -224,21 +226,21 @@ public class GeckoView extends LayerView
super.onRestoreInstanceState(stateBinder.superState);
}
private void openWindow() {
final String chromeURI = getGeckoInterface().getDefaultChromeURI();
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
Window.open(window, this, getCompositor(),
- chromeURI);
+ chromeURI, screenId);
} else {
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY, Window.class,
"open", window, GeckoView.class, this, Object.class, getCompositor(),
- String.class, chromeURI);
+ String.class, chromeURI, screenId);
}
}
private void reattachWindow() {
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
window.reattach(this, getCompositor());
} else {
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -3269,20 +3269,21 @@ public:
struct Open_t {
typedef Window Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
Window::Param,
GeckoView::Param,
mozilla::jni::Object::Param,
- mozilla::jni::String::Param> Args;
+ mozilla::jni::String::Param,
+ int32_t> Args;
static constexpr char name[] = "open";
static constexpr char signature[] =
- "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Ljava/lang/String;)V";
+ "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Ljava/lang/String;I)V";
static const bool isStatic = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;
static const mozilla::jni::DispatchTarget dispatchTarget =
mozilla::jni::DispatchTarget::PROXY;
};
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1,9 +1,10 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * vim: set sw=4 ts=4 expandtab:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <android/log.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <math.h>
@@ -340,17 +341,18 @@ public:
private:
nsCOMPtr<nsPIDOMWindowOuter> mDOMWindow;
public:
// Create and attach a window.
static void Open(const jni::Class::LocalRef& aCls,
GeckoView::Window::Param aWindow,
GeckoView::Param aView, jni::Object::Param aCompositor,
- jni::String::Param aChromeURI);
+ jni::String::Param aChromeURI,
+ int32_t screenId);
// Close and destroy the nsWindow.
void Close();
// Reattach this nsWindow to a new GeckoView.
void Reattach(const GeckoView::Window::LocalRef& inst,
GeckoView::Param aView, jni::Object::Param aCompositor);
@@ -1314,17 +1316,18 @@ nsWindow::GeckoViewSupport::~GeckoViewSu
}
}
/* static */ void
nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
GeckoView::Window::Param aWindow,
GeckoView::Param aView,
jni::Object::Param aCompositor,
- jni::String::Param aChromeURI)
+ jni::String::Param aChromeURI,
+ int32_t aScreenId)
{
MOZ_ASSERT(NS_IsMainThread());
PROFILER_LABEL("nsWindow", "GeckoViewSupport::Open",
js::ProfileEntry::Category::OTHER);
nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
MOZ_RELEASE_ASSERT(ww);
@@ -1345,16 +1348,17 @@ nsWindow::GeckoViewSupport::Open(const j
MOZ_RELEASE_ASSERT(domWindow);
nsCOMPtr<nsPIDOMWindowOuter> pdomWindow =
nsPIDOMWindowOuter::From(domWindow);
nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(pdomWindow);
MOZ_ASSERT(widget);
const auto window = static_cast<nsWindow*>(widget.get());
+ window->SetScreenId(aScreenId);
// Attach a new GeckoView support object to the new window.
window->mGeckoViewSupport = mozilla::MakeUnique<GeckoViewSupport>(
window, GeckoView::Window::LocalRef(aCls.Env(), aWindow), aView);
window->mGeckoViewSupport->mDOMWindow = pdomWindow;
// Attach the Compositor to the new window.
@@ -1487,16 +1491,17 @@ nsWindow::DumpWindows(const nsTArray<nsW
for (uint32_t i = 0; i < wins.Length(); ++i) {
nsWindow *w = wins[i];
LogWindow(w, i, indent);
DumpWindows(w->mChildren, indent+1);
}
}
nsWindow::nsWindow() :
+ mScreenId(0), // Use 0 (primary screen) as the default value.
mIsVisible(false),
mParent(nullptr),
mAwaitingFullScreen(false),
mIsFullScreen(false)
{
}
nsWindow::~nsWindow()
@@ -1648,29 +1653,21 @@ nsWindow::GetDPI()
if (AndroidBridge::Bridge())
return AndroidBridge::Bridge()->GetDPI();
return 160.0f;
}
double
nsWindow::GetDefaultScaleInternal()
{
- static double density = 0.0;
-
- if (density != 0.0) {
- return density;
- }
-
- density = GeckoAppShell::GetDensity();
-
- if (!density) {
- density = 1.0;
- }
-
- return density;
+
+ nsCOMPtr<nsIScreen> screen = GetWidgetScreen();
+ MOZ_ASSERT(screen);
+ RefPtr<nsScreenAndroid> screenAndroid = (nsScreenAndroid*) screen.get();
+ return screenAndroid->GetDensity();
}
NS_IMETHODIMP
nsWindow::Show(bool aState)
{
ALOG("nsWindow[%p]::Show %d", (void*)this, aState);
if (mWindowType == eWindowType_invisible) {
@@ -3592,17 +3589,30 @@ nsWindow::UpdateZoomConstraints(const ui
const mozilla::Maybe<ZoomConstraints>& aConstraints)
{
nsBaseWidget::UpdateZoomConstraints(aPresShellId, aViewId, aConstraints);
}
CompositorBridgeParent*
nsWindow::GetCompositorBridgeParent() const
{
- return mCompositorSession ? mCompositorSession->GetInProcessBridge() : nullptr;
+ return mCompositorSession ? mCompositorSession->GetInProcessBridge() : nullptr;
+}
+
+already_AddRefed<nsIScreen>
+nsWindow::GetWidgetScreen()
+{
+ nsCOMPtr<nsIScreenManager> screenMgr =
+ do_GetService("@mozilla.org/gfx/screenmanager;1");
+ MOZ_ASSERT(screenMgr, "Failed to get nsIScreenManager");
+
+ nsCOMPtr<nsIScreen> screen;
+ screenMgr->ScreenForId(mScreenId, getter_AddRefs(screen));
+
+ return screen.forget();
}
jni::DependentRef<java::GeckoLayerClient>
nsWindow::GetLayerClient()
{
if (NativePtr<LayerViewSupport>::Locked lvs{mLayerViewSupport}) {
return lvs->GetLayerClient().Get();
}
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -1,9 +1,10 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: set sw=4 ts=4 expandtab:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef NSWINDOW_H_
#define NSWINDOW_H_
#include "nsBaseWidget.h"
@@ -40,18 +41,21 @@ private:
public:
using nsBaseWidget::GetLayerManager;
nsWindow();
NS_DECL_ISUPPORTS_INHERITED
static void InitNatives();
+ void SetScreenId(uint32_t aScreenId) { mScreenId = aScreenId; }
private:
+ uint32_t mScreenId;
+
// An Event subclass that guards against stale events.
template<typename Lambda,
bool IsStatic = Lambda::isStatic,
typename InstanceType = typename Lambda::ThisArgType,
class Impl = typename Lambda::TargetClass>
class WindowEvent;
// Smart pointer for holding a pointer back to the nsWindow inside a native
@@ -160,16 +164,17 @@ public:
virtual bool IsEnabled() const override;
NS_IMETHOD Invalidate(const LayoutDeviceIntRect& aRect) override;
NS_IMETHOD SetFocus(bool aRaise = false) override;
virtual LayoutDeviceIntRect GetScreenBounds() override;
virtual LayoutDeviceIntPoint WidgetToScreenOffset() override;
NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
nsEventStatus& aStatus) override;
nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent);
+ virtual already_AddRefed<nsIScreen> GetWidgetScreen() override;
virtual nsresult MakeFullScreen(bool aFullScreen,
nsIScreen* aTargetScreen = nullptr)
override;
NS_IMETHOD SetCursor(nsCursor aCursor) override { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD SetCursor(imgIContainer* aCursor,
uint32_t aHotspotX,
uint32_t aHotspotY) override { return NS_ERROR_NOT_IMPLEMENTED; }
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -178,16 +178,17 @@ public:
virtual void SetShowsFullScreenButton(bool aShow) override {}
virtual void SetWindowAnimationType(WindowAnimationType aType) override {}
NS_IMETHOD HideWindowChrome(bool aShouldHide) override;
virtual bool PrepareForFullscreenTransition(nsISupports** aData) override { return false; }
virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage,
uint16_t aDuration,
nsISupports* aData,
nsIRunnable* aCallback) override;
+ virtual already_AddRefed<nsIScreen> GetWidgetScreen() override;
virtual nsresult MakeFullScreen(bool aFullScreen,
nsIScreen* aScreen = nullptr) override;
void InfallibleMakeFullScreen(bool aFullScreen,
nsIScreen* aScreen = nullptr);
virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;
@@ -334,19 +335,16 @@ public:
nsPopupLevel PopupLevel() { return mPopupLevel; }
virtual LayoutDeviceIntSize
ClientToWindowSize(const LayoutDeviceIntSize& aClientSize) override
{
return aClientSize;
}
- // return the screen the widget is in.
- already_AddRefed<nsIScreen> GetWidgetScreen();
-
// return true if this is a popup widget with a native titlebar
bool IsPopupWithTitleBar() const
{
return (mWindowType == eWindowType_popup &&
mBorderStyle != eBorderStyle_default &&
mBorderStyle & eBorderStyle_title);
}
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -1187,16 +1187,21 @@ class nsIWidget : public nsISupports
* finishes.
*/
virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage,
uint16_t aDuration,
nsISupports* aData,
nsIRunnable* aCallback) = 0;
/**
+ * Return the screen the widget is in, or null if we don't know.
+ */
+ virtual already_AddRefed<nsIScreen> GetWidgetScreen() = 0;
+
+ /**
* Put the toplevel window into or out of fullscreen mode.
* If aTargetScreen is given, attempt to go fullscreen on that screen,
* if possible. (If not, it behaves as if aTargetScreen is null.)
* If !aFullScreen, aTargetScreen is ignored.
* aTargetScreen support is currently only implemented on Windows.
*
* @return NS_OK if the widget is setup properly for fullscreen and
* FullscreenChanged callback has been or will be called. If other