mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
bug 794038 pt 2.0 - respond to changes to backing-store resolution when a window moves between HiDPI and non-HiDPI displays. r=smichaud
This commit is contained in:
parent
1d9d7aca0e
commit
171fa34718
@ -5007,6 +5007,13 @@ NS_IMETHODIMP
|
||||
nsDocShell::GetPositionAndSize(int32_t * x, int32_t * y, int32_t * cx,
|
||||
int32_t * cy)
|
||||
{
|
||||
if (mParentWidget) {
|
||||
// ensure size is up-to-date if window has changed resolution
|
||||
nsIntRect r;
|
||||
mParentWidget->GetClientBounds(r);
|
||||
SetPositionAndSize(mBounds.x, mBounds.y, r.width, r.height, false);
|
||||
}
|
||||
|
||||
// We should really consider just getting this information from
|
||||
// our window instead of duplicating the storage and code...
|
||||
if (cx || cy) {
|
||||
|
@ -1353,6 +1353,7 @@ public:
|
||||
virtual void WindowSizeMoveDone() = 0;
|
||||
virtual void SysColorChanged() = 0;
|
||||
virtual void ThemeChanged() = 0;
|
||||
virtual void BackingScaleFactorChanged() = 0;
|
||||
|
||||
nscoord MaxLineBoxWidth() {
|
||||
return mMaxLineBoxWidth;
|
||||
|
@ -1604,6 +1604,45 @@ nsPresContext::SysColorChangedInternal()
|
||||
RebuildAllStyleData(nsChangeHint(0));
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::UIResolutionChanged()
|
||||
{
|
||||
if (!mPendingUIResolutionChanged) {
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
NS_NewRunnableMethod(this, &nsPresContext::UIResolutionChangedInternal);
|
||||
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(ev))) {
|
||||
mPendingUIResolutionChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
nsPresContext::UIResolutionChangedSubdocumentCallback(nsIDocument* aDocument,
|
||||
void* aData)
|
||||
{
|
||||
nsIPresShell* shell = aDocument->GetShell();
|
||||
if (shell) {
|
||||
nsPresContext* pc = shell->GetPresContext();
|
||||
if (pc) {
|
||||
pc->UIResolutionChangedInternal();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::UIResolutionChangedInternal()
|
||||
{
|
||||
mPendingUIResolutionChanged = false;
|
||||
|
||||
if (mDeviceContext->CheckDPIChange()) {
|
||||
AppUnitsPerDevPixelChanged();
|
||||
}
|
||||
|
||||
mDocument->EnumerateSubDocuments(UIResolutionChangedSubdocumentCallback,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::RebuildAllStyleData(nsChangeHint aExtraHint)
|
||||
{
|
||||
|
@ -722,6 +722,13 @@ public:
|
||||
*/
|
||||
NS_HIDDEN_(void) ThemeChanged();
|
||||
|
||||
/*
|
||||
* Notify the pres context that the resolution of the user interface has
|
||||
* changed. This happens if a window is moved between HiDPI and non-HiDPI
|
||||
* displays, so that the ratio of points to device pixels changes.
|
||||
*/
|
||||
NS_HIDDEN_(void) UIResolutionChanged();
|
||||
|
||||
/*
|
||||
* Notify the pres context that a system color has changed
|
||||
*/
|
||||
@ -930,6 +937,10 @@ protected:
|
||||
friend class nsRunnableMethod<nsPresContext>;
|
||||
NS_HIDDEN_(void) ThemeChangedInternal();
|
||||
NS_HIDDEN_(void) SysColorChangedInternal();
|
||||
NS_HIDDEN_(void) UIResolutionChangedInternal();
|
||||
|
||||
static NS_HIDDEN_(bool)
|
||||
UIResolutionChangedSubdocumentCallback(nsIDocument* aDocument, void* aData);
|
||||
|
||||
NS_HIDDEN_(void) SetImgAnimations(nsIContent *aParent, uint16_t aMode);
|
||||
NS_HIDDEN_(void) SetSMILAnimations(nsIDocument *aDoc, uint16_t aNewMode,
|
||||
@ -1165,6 +1176,7 @@ protected:
|
||||
unsigned mPrefScrollbarSide : 2;
|
||||
unsigned mPendingSysColorChanged : 1;
|
||||
unsigned mPendingThemeChanged : 1;
|
||||
unsigned mPendingUIResolutionChanged : 1;
|
||||
unsigned mPendingMediaFeatureValuesChanged : 1;
|
||||
unsigned mPrefChangePendingNeedsReflow : 1;
|
||||
unsigned mMayHaveFixedBackgroundFrames : 1;
|
||||
|
@ -697,6 +697,7 @@ protected:
|
||||
virtual void WindowSizeMoveDone();
|
||||
virtual void SysColorChanged() { mPresContext->SysColorChanged(); }
|
||||
virtual void ThemeChanged() { mPresContext->ThemeChanged(); }
|
||||
virtual void BackingScaleFactorChanged() { mPresContext->UIResolutionChanged(); }
|
||||
|
||||
#ifdef DEBUG
|
||||
// The reflow root under which we're currently reflowing. Null when
|
||||
|
@ -195,8 +195,8 @@ pref("media.video-queue.default-size", 10);
|
||||
// Whether to run in native HiDPI mode on machines with "Retina"/HiDPI display;
|
||||
// <= 0 : hidpi mode disabled, display will just use pixel-based upscaling
|
||||
// == 1 : hidpi supported if all screens share the same backingScaleFactor
|
||||
// >= 2 : hidpi supported even with mixed backingScaleFactors (currently broken)
|
||||
pref("gfx.hidpi.enabled", 1);
|
||||
// >= 2 : hidpi supported even with mixed backingScaleFactors (somewhat broken)
|
||||
pref("gfx.hidpi.enabled", 2);
|
||||
#endif
|
||||
|
||||
// 0 = Off, 1 = Full, 2 = Tagged Images Only.
|
||||
|
@ -396,6 +396,10 @@ public:
|
||||
// pixels" and the Cocoa "points" coordinate system.
|
||||
CGFloat BackingScaleFactor();
|
||||
|
||||
// Call if the window's backing scale factor changes - i.e., it is moved
|
||||
// between HiDPI and non-HiDPI screens
|
||||
void BackingScaleFactorChanged();
|
||||
|
||||
virtual double GetDefaultScale();
|
||||
|
||||
NS_IMETHOD Invalidate(const nsIntRect &aRect);
|
||||
|
@ -765,6 +765,29 @@ nsChildView::BackingScaleFactor()
|
||||
return mBackingScaleFactor;
|
||||
}
|
||||
|
||||
void
|
||||
nsChildView::BackingScaleFactorChanged()
|
||||
{
|
||||
CGFloat newScale = nsCocoaUtils::GetBackingScaleFactor(mView);
|
||||
|
||||
// ignore notification if it hasn't really changed (or maybe we have
|
||||
// disabled HiDPI mode via prefs)
|
||||
if (mBackingScaleFactor == newScale) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBackingScaleFactor = newScale;
|
||||
|
||||
if (!mWidgetListener || mWidgetListener->GetXULWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = mWidgetListener->GetPresShell();
|
||||
if (presShell) {
|
||||
presShell->BackingScaleFactorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsChildView::ConstrainPosition(bool aAllowSlop,
|
||||
int32_t *aX, int32_t *aY)
|
||||
{
|
||||
@ -2347,6 +2370,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
return nsCocoaUtils::HiDPIEnabled() ? YES : NO;
|
||||
}
|
||||
|
||||
- (void)viewDidChangeBackingProperties
|
||||
{
|
||||
[super viewDidChangeBackingProperties];
|
||||
if (mGeckoChild) {
|
||||
// actually, it could be the color space that's changed,
|
||||
// but we can't tell the difference here except by retrieving
|
||||
// the backing scale factor and comparing to the old value
|
||||
mGeckoChild->BackingScaleFactorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// The display system has told us that a portion of our view is dirty. Tell
|
||||
// gecko to paint it
|
||||
- (void)drawRect:(NSRect)aRect
|
||||
|
@ -243,6 +243,7 @@ public:
|
||||
NS_IMETHOD SetCursor(imgIContainer* aCursor, uint32_t aHotspotX, uint32_t aHotspotY);
|
||||
|
||||
CGFloat BackingScaleFactor();
|
||||
void BackingScaleFactorChanged();
|
||||
virtual double GetDefaultScale();
|
||||
|
||||
NS_IMETHOD SetTitle(const nsAString& aTitle);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "nsCocoaFeatures.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsIWidgetListener.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "qcms.h"
|
||||
@ -425,6 +426,10 @@ nsresult nsCocoaWindow::CreateNativeWindow(const NSRect &aRect,
|
||||
mWindow = [[windowClass alloc] initWithContentRect:contentRect styleMask:features
|
||||
backing:NSBackingStoreBuffered defer:YES];
|
||||
|
||||
// setup our notification delegate. Note that setDelegate: does NOT retain.
|
||||
mDelegate = [[WindowDelegate alloc] initWithGeckoWindow:this];
|
||||
[mWindow setDelegate:mDelegate];
|
||||
|
||||
// Make sure that the content rect we gave has been honored.
|
||||
NSRect wantedFrame = [mWindow frameRectForContentRect:contentRect];
|
||||
if (!NSEqualRects([mWindow frame], wantedFrame)) {
|
||||
@ -445,10 +450,6 @@ nsresult nsCocoaWindow::CreateNativeWindow(const NSRect &aRect,
|
||||
[mWindow setContentMinSize:NSMakeSize(60, 60)];
|
||||
[mWindow disableCursorRects];
|
||||
|
||||
// setup our notification delegate. Note that setDelegate: does NOT retain.
|
||||
mDelegate = [[WindowDelegate alloc] initWithGeckoWindow:this];
|
||||
[mWindow setDelegate:mDelegate];
|
||||
|
||||
[[WindowDataMap sharedWindowDataMap] ensureDataForWindow:mWindow];
|
||||
mWindowMadeHere = true;
|
||||
|
||||
@ -1415,6 +1416,29 @@ nsCocoaWindow::BackingScaleFactor()
|
||||
return mBackingScaleFactor;
|
||||
}
|
||||
|
||||
void
|
||||
nsCocoaWindow::BackingScaleFactorChanged()
|
||||
{
|
||||
CGFloat newScale = nsCocoaUtils::GetBackingScaleFactor(mWindow);
|
||||
|
||||
// ignore notification if it hasn't really changed (or maybe we have
|
||||
// disabled HiDPI mode via prefs)
|
||||
if (mBackingScaleFactor == newScale) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBackingScaleFactor = newScale;
|
||||
|
||||
if (!mWidgetListener || mWidgetListener->GetXULWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = mWidgetListener->GetPresShell();
|
||||
if (presShell) {
|
||||
presShell->BackingScaleFactorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCocoaWindow::SetCursor(nsCursor aCursor)
|
||||
{
|
||||
if (mPopupContentView)
|
||||
@ -2240,6 +2264,24 @@ bool nsCocoaWindow::ShouldFocusPlugin()
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)windowDidChangeBackingProperties:(NSNotification *)aNotification
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NSWindow *window = (NSWindow *)[aNotification object];
|
||||
|
||||
if ([window respondsToSelector:@selector(backingScaleFactor)]) {
|
||||
CGFloat oldFactor =
|
||||
[[[aNotification userInfo]
|
||||
objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
|
||||
if ([window backingScaleFactor] != oldFactor) {
|
||||
mGeckoWindow->BackingScaleFactorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (nsCocoaWindow*)geckoWidget
|
||||
{
|
||||
return mGeckoWindow;
|
||||
|
Loading…
x
Reference in New Issue
Block a user