Commit 0aa50c48 authored by ggaren's avatar ggaren

Reviewed by Maciej.

        - Fixed <rdar://problem/4559720> window sizing: make javascript window 
        and screen sizing methods and properties work @ HIDPI
        
        The general approach here is to change some ints to floats, make 
        a few key functions that scale between WebView and window/screen 
        coordinates, and change other functions that work with screen 
        coordinates to use the scaling functions for their underlying 
        implementations.

        * manual-tests/window-open-features.html: Removed.
        * manual-tests/window-sizing.html: Added. More test coverage.

        * bindings/js/kjs_window.cpp: Changed ints to floats and IntRects to
        FloatRects, because window coordinates can be fractional when scaled 
        to WebView/DOM coordinates.
        (KJS::floatFeature):
        (KJS::showModalDialog):
        (KJS::Window::getValueProperty):
        (KJS::constrainToVisible):
        (KJS::WindowFunc::callAsFunction):
        * bridge/BrowserExtension.h:
        * bridge/mac/BrowserExtensionMac.mm:
        (WebCore::BrowserExtensionMac::createNewWindow): Removed custom scaling
        code and replaced with calls to Page::windowRect and 
        Page::setWindowRect. Renamed 'page' and 'bridge' to 'pageBridge' and
        'frameBridge,' respectively.
        * bridge/mac/PageMac.mm:
        (WebCore::Page::windowRect): Changed to use scaling
        (WebCore::Page::setWindowRect): ditto
        * bridge/mac/WebCoreFrameBridge.mm:
        (globalPoint):
        * page/Page.h:
        * platform/IntRect.h:
        * platform/Screen.h:
        * platform/mac/MouseEventMac.mm:
        (WebCore::globalPositionForEvent): Changed to use flipScreenPoint
        * platform/mac/ScreenMac.mm:
        (WebCore::flipScreenRect): New key function
        (WebCore::flipScreenPoint): New key function
        (WebCore::scaleScreenRectToView): New key function
        (WebCore::scaleViewRectToScreen): New key function
        (WebCore::screenRect): Changed to use scaling
        (WebCore::usableScreenRect): ditto

        Feeble attempt to preserve Windows build:
        
        * platform/win/ScreenWin.cpp:
        (WebCore::scaleScreenRectToWidget): stub -- doesn't actually scale
        (WebCore::scaleWidgetRectToScreen): ditto
        * bridge/win/PageWin.cpp:
        (WebCore::Page::Page):
        (WebCore::Page::widget):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@14643 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 337bfd30
2006-05-30 Geoffrey Garen <ggaren@apple.com>
Reviewed by Maciej.
- Fixed <rdar://problem/4559720> window sizing: make javascript window
and screen sizing methods and properties work @ HIDPI
The general approach here is to change some ints to floats, make
a few key functions that scale between WebView and window/screen
coordinates, and change other functions that work with screen
coordinates to use the scaling functions for their underlying
implementations.
* manual-tests/window-open-features.html: Removed.
* manual-tests/window-sizing.html: Added. More test coverage.
* bindings/js/kjs_window.cpp: Changed ints to floats and IntRects to
FloatRects, because window coordinates can be fractional when scaled
to WebView/DOM coordinates.
(KJS::floatFeature):
(KJS::showModalDialog):
(KJS::Window::getValueProperty):
(KJS::constrainToVisible):
(KJS::WindowFunc::callAsFunction):
* bridge/BrowserExtension.h:
* bridge/mac/BrowserExtensionMac.mm:
(WebCore::BrowserExtensionMac::createNewWindow): Removed custom scaling
code and replaced with calls to Page::windowRect and
Page::setWindowRect. Renamed 'page' and 'bridge' to 'pageBridge' and
'frameBridge,' respectively.
* bridge/mac/PageMac.mm:
(WebCore::Page::windowRect): Changed to use scaling
(WebCore::Page::setWindowRect): ditto
* bridge/mac/WebCoreFrameBridge.mm:
(globalPoint):
* page/Page.h:
* platform/IntRect.h:
* platform/Screen.h:
* platform/mac/MouseEventMac.mm:
(WebCore::globalPositionForEvent): Changed to use flipScreenPoint
* platform/mac/ScreenMac.mm:
(WebCore::flipScreenRect): New key function
(WebCore::flipScreenPoint): New key function
(WebCore::scaleScreenRectToView): New key function
(WebCore::scaleViewRectToScreen): New key function
(WebCore::screenRect): Changed to use scaling
(WebCore::usableScreenRect): ditto
Feeble attempt to preserve Windows build:
* platform/win/ScreenWin.cpp:
(WebCore::scaleScreenRectToWidget): stub -- doesn't actually scale
(WebCore::scaleWidgetRectToScreen): ditto
* bridge/win/PageWin.cpp:
(WebCore::Page::Page):
(WebCore::Page::widget):
2006-05-30 David Hyatt <hyatt@apple.com> 2006-05-30 David Hyatt <hyatt@apple.com>
Rename RenderCanvas to RenderView. Rename canvas(), isCanvas() Rename RenderCanvas to RenderView. Rename canvas(), isCanvas()
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "DOMWindow.h" #include "DOMWindow.h"
#include "Element.h" #include "Element.h"
#include "EventNames.h" #include "EventNames.h"
#include "FloatRect.h"
#include "Frame.h" #include "Frame.h"
#include "FrameTree.h" #include "FrameTree.h"
#include "HTMLDocument.h" #include "HTMLDocument.h"
...@@ -512,7 +513,7 @@ static bool boolFeature(const HashMap<String, String>& features, const char* key ...@@ -512,7 +513,7 @@ static bool boolFeature(const HashMap<String, String>& features, const char* key
return value.isNull() || value == "1" || value == "yes" || value == "on"; return value.isNull() || value == "1" || value == "yes" || value == "on";
} }
static int intFeature(const HashMap<String, String> &features, const char *key, int min, int max, int defaultValue) static float floatFeature(const HashMap<String, String> &features, const char *key, float min, float max, float defaultValue)
{ {
HashMap<String, String>::const_iterator it = features.find(key); HashMap<String, String>::const_iterator it = features.find(key);
if (it == features.end()) if (it == features.end())
...@@ -614,16 +615,16 @@ static JSValue *showModalDialog(ExecState *exec, Window *openerWindow, const Lis ...@@ -614,16 +615,16 @@ static JSValue *showModalDialog(ExecState *exec, Window *openerWindow, const Lis
// - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?) // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?)
// - unadorned: trusted && boolFeature(features, "unadorned"); // - unadorned: trusted && boolFeature(features, "unadorned");
IntRect screenRect = usableScreenRect(openerWindow->frame()->view()); FloatRect screenRect = usableScreenRect(openerWindow->frame()->view());
wargs.width = intFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE wargs.width = floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE
wargs.widthSet = true; wargs.widthSet = true;
wargs.height = intFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE wargs.height = floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE
wargs.heightSet = true; wargs.heightSet = true;
wargs.x = intFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1); wargs.x = floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1);
wargs.xSet = wargs.x > 0; wargs.xSet = wargs.x > 0;
wargs.y = intFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1); wargs.y = floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1);
wargs.ySet = wargs.y > 0; wargs.ySet = wargs.y > 0;
if (boolFeature(features, "center", true)) { if (boolFeature(features, "center", true)) {
...@@ -669,6 +670,8 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const ...@@ -669,6 +670,8 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const
return jsUndefined(); // ### return jsUndefined(); // ###
case DefaultStatus: case DefaultStatus:
return jsString(UString(m_frame->jsDefaultStatusBarText())); return jsString(UString(m_frame->jsDefaultStatusBarText()));
case DOMException:
return getDOMExceptionConstructor(exec);
case Status: case Status:
return jsString(UString(m_frame->jsStatusBarText())); return jsString(UString(m_frame->jsStatusBarText()));
case Frames: case Frames:
...@@ -1467,7 +1470,7 @@ static void parseWindowFeatures(const String& features, WindowArgs& windowArgs) ...@@ -1467,7 +1470,7 @@ static void parseWindowFeatures(const String& features, WindowArgs& windowArgs)
} }
} }
static void constrainToVisible(const IntRect& screen, WindowArgs& windowArgs) static void constrainToVisible(const FloatRect& screen, WindowArgs& windowArgs)
{ {
windowArgs.x += screen.x(); windowArgs.x += screen.x();
if (windowArgs.x < screen.x() || windowArgs.x >= screen.right()) if (windowArgs.x < screen.x() || windowArgs.x >= screen.right())
...@@ -1617,8 +1620,8 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li ...@@ -1617,8 +1620,8 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li
return jsUndefined(); return jsUndefined();
case Window::MoveBy: case Window::MoveBy:
if (args.size() >= 2 && widget) { if (args.size() >= 2 && widget) {
IntRect r = frame->page()->windowRect(); FloatRect r = frame->page()->windowRect();
r.move(args[0]->toInt32(exec), args[1]->toInt32(exec)); r.move(args[0]->toNumber(exec), args[1]->toNumber(exec));
// Security check (the spec talks about UniversalBrowserWrite to disable this check...) // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
if (screenRect(widget).contains(r)) if (screenRect(widget).contains(r))
frame->page()->setWindowRect(r); frame->page()->setWindowRect(r);
...@@ -1626,10 +1629,10 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li ...@@ -1626,10 +1629,10 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li
return jsUndefined(); return jsUndefined();
case Window::MoveTo: case Window::MoveTo:
if (args.size() >= 2 && widget) { if (args.size() >= 2 && widget) {
IntRect r = frame->page()->windowRect(); FloatRect r = frame->page()->windowRect();
IntRect sr = screenRect(widget); FloatRect sr = screenRect(widget);
r.setLocation(sr.location()); r.setLocation(sr.location());
r.move(args[0]->toInt32(exec), args[1]->toInt32(exec)); r.move(args[0]->toNumber(exec), args[1]->toNumber(exec));
// Security check (the spec talks about UniversalBrowserWrite to disable this check...) // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
if (sr.contains(r)) if (sr.contains(r))
frame->page()->setWindowRect(r); frame->page()->setWindowRect(r);
...@@ -1637,24 +1640,24 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li ...@@ -1637,24 +1640,24 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li
return jsUndefined(); return jsUndefined();
case Window::ResizeBy: case Window::ResizeBy:
if (args.size() >= 2 && widget) { if (args.size() >= 2 && widget) {
IntRect r = frame->page()->windowRect(); FloatRect r = frame->page()->windowRect();
IntSize dest = r.size() + IntSize(args[0]->toInt32(exec), args[1]->toInt32(exec)); FloatSize dest = r.size() + FloatSize(args[0]->toNumber(exec), args[1]->toNumber(exec));
IntRect sg = screenRect(widget); FloatRect sg = screenRect(widget);
// Security check: within desktop limits and bigger than 100x100 (per spec) // Security check: within desktop limits and bigger than 100x100 (per spec)
if (r.x() + dest.width() <= sg.right() && r.y() + dest.height() <= sg.bottom() if (r.x() + dest.width() <= sg.right() && r.y() + dest.height() <= sg.bottom()
&& dest.width() >= 100 && dest.height() >= 100) && dest.width() >= 100 && dest.height() >= 100)
frame->page()->setWindowRect(IntRect(r.location(), dest)); frame->page()->setWindowRect(FloatRect(r.location(), dest));
} }
return jsUndefined(); return jsUndefined();
case Window::ResizeTo: case Window::ResizeTo:
if (args.size() >= 2 && widget) { if (args.size() >= 2 && widget) {
IntRect r = frame->page()->windowRect(); FloatRect r = frame->page()->windowRect();
IntSize dest = IntSize(args[0]->toInt32(exec), args[1]->toInt32(exec)); FloatSize dest = FloatSize(args[0]->toNumber(exec), args[1]->toNumber(exec));
IntRect sg = screenRect(widget); FloatRect sg = screenRect(widget);
// Security check: within desktop limits and bigger than 100x100 (per spec) // Security check: within desktop limits and bigger than 100x100 (per spec)
if (r.x() + dest.width() <= sg.right() && r.y() + dest.height() <= sg.bottom() && if (r.x() + dest.width() <= sg.right() && r.y() + dest.height() <= sg.bottom() &&
dest.width() >= 100 && dest.height() >= 100) dest.width() >= 100 && dest.height() >= 100)
frame->page()->setWindowRect(IntRect(r.location(), dest)); frame->page()->setWindowRect(FloatRect(r.location(), dest));
} }
return jsUndefined(); return jsUndefined();
case Window::SetTimeout: case Window::SetTimeout:
......
...@@ -33,13 +33,13 @@ namespace WebCore { ...@@ -33,13 +33,13 @@ namespace WebCore {
class Frame; class Frame;
struct WindowArgs { struct WindowArgs {
int x; float x;
bool xSet; bool xSet;
int y; float y;
bool ySet; bool ySet;
int width; float width;
bool widthSet; bool widthSet;
int height; float height;
bool heightSet; bool heightSet;
bool menuBarVisible; bool menuBarVisible;
......
...@@ -26,9 +26,12 @@ ...@@ -26,9 +26,12 @@
#import "config.h" #import "config.h"
#import "BrowserExtensionMac.h" #import "BrowserExtensionMac.h"
#import "FrameTree.h"
#import "BlockExceptions.h" #import "BlockExceptions.h"
#import "FloatRect.h"
#import "FrameMac.h" #import "FrameMac.h"
#import "FrameTree.h"
#import "Page.h"
#import "Screen.h"
#import "WebCoreFrameBridge.h" #import "WebCoreFrameBridge.h"
#import "WebCorePageBridge.h" #import "WebCorePageBridge.h"
...@@ -67,16 +70,16 @@ void BrowserExtensionMac::createNewWindow(const ResourceRequest& request, ...@@ -67,16 +70,16 @@ void BrowserExtensionMac::createNewWindow(const ResourceRequest& request,
NSString *frameName = request.frameName.isEmpty() ? nil : (NSString*)request.frameName; NSString *frameName = request.frameName.isEmpty() ? nil : (NSString*)request.frameName;
if (frameName) { if (frameName) {
// FIXME: Can't we just use m_frame->findFrame? // FIXME: Can't we just use m_frame->findFrame?
if (WebCoreFrameBridge *bridge = [m_frame->bridge() findFrameNamed:frameName]) { if (WebCoreFrameBridge *frameBridge = [m_frame->bridge() findFrameNamed:frameName]) {
if (!url.isEmpty()) { if (!url.isEmpty()) {
String argsReferrer = request.referrer(); String argsReferrer = request.referrer();
NSString *referrer; NSString *referrer;
if (!argsReferrer.isEmpty()) if (!argsReferrer.isEmpty())
referrer = argsReferrer; referrer = argsReferrer;
else else
referrer = [m_frame->bridge() referrer]; referrer = [frameBridge referrer];
[bridge loadURL:url.getNSURL() [frameBridge loadURL:url.getNSURL()
referrer:referrer referrer:referrer
reload:request.reload reload:request.reload
userGesture:true userGesture:true
...@@ -86,70 +89,52 @@ void BrowserExtensionMac::createNewWindow(const ResourceRequest& request, ...@@ -86,70 +89,52 @@ void BrowserExtensionMac::createNewWindow(const ResourceRequest& request,
formValues:nil]; formValues:nil];
} }
[bridge focusWindow]; [frameBridge focusWindow];
if (partResult) if (partResult)
*partResult = [bridge impl]; *partResult = [frameBridge impl];
return; return;
} }
} }
WebCorePageBridge *page; WebCorePageBridge *pageBridge;
if (winArgs.dialog) if (winArgs.dialog)
page = [m_frame->bridge() createModalDialogWithURL:url.getNSURL()]; pageBridge = [m_frame->bridge() createModalDialogWithURL:url.getNSURL()];
else else
page = [m_frame->bridge() createWindowWithURL:url.getNSURL()]; pageBridge = [m_frame->bridge() createWindowWithURL:url.getNSURL()];
if (!page) if (!pageBridge)
return; return;
WebCoreFrameBridge *bridge = [page mainFrame]; WebCoreFrameBridge *frameBridge = [pageBridge mainFrame];
if ([bridge impl]) if ([frameBridge impl])
[bridge impl]->tree()->setName(AtomicString(request.frameName)); [frameBridge impl]->tree()->setName(AtomicString(request.frameName));
if (partResult) if (partResult)
*partResult = [bridge impl]; *partResult = [frameBridge impl];
[bridge setToolbarsVisible:winArgs.toolBarVisible || winArgs.locationBarVisible]; [frameBridge setToolbarsVisible:winArgs.toolBarVisible || winArgs.locationBarVisible];
[bridge setStatusbarVisible:winArgs.statusBarVisible]; [frameBridge setStatusbarVisible:winArgs.statusBarVisible];
[bridge setScrollbarsVisible:winArgs.scrollBarsVisible]; [frameBridge setScrollbarsVisible:winArgs.scrollBarsVisible];
[bridge setWindowIsResizable:winArgs.resizable]; [frameBridge setWindowIsResizable:winArgs.resizable];
NSRect windowFrame = [page windowFrame]; NSRect windowRect = [pageBridge impl]->windowRect();
NSSize size = { 1, 1 }; // workaround for 4213314
NSSize scaleRect = [[page outerView] convertSize:size toView:nil];
float scaleX = scaleRect.width;
float scaleY = scaleRect.height;
// In JavaScript, the coordinate system of the window is the same as the coordinate system
// of the WebView, so we translate 'left' and 'top' from WebView coordinates to window coordinates.
// (If the screen resolution is scaled, window coordinates won't match WebView coordinates.)
if (winArgs.xSet) if (winArgs.xSet)
windowFrame.origin.x = winArgs.x * scaleX; windowRect.origin.x = winArgs.x;
if (winArgs.ySet) { if (winArgs.ySet)
// In JavaScript, (0, 0) is the top left corner of the screen. windowRect.origin.y = winArgs.y;
float screenTop = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]);
windowFrame.origin.y = screenTop - (winArgs.y * scaleY) - windowFrame.size.height;
}
// 'width' and 'height' specify the dimensions of the WebView, but we can only resize the window, // 'width' and 'height' specify the dimensions of the WebView, but we can only resize the window,
// so we compute a delta, translate it to window coordinates, and use the translated delta // so we compute a WebView delta and apply it to the window.
// to resize the window. NSRect webViewRect = [[pageBridge outerView] frame];
NSRect webViewFrame = [[page outerView] frame]; if (winArgs.widthSet)
if (winArgs.widthSet) { windowRect.size.width += winArgs.width - webViewRect.size.width;
float widthDelta = (winArgs.width - webViewFrame.size.width) * scaleX; if (winArgs.heightSet)
windowFrame.size.width += widthDelta; windowRect.size.height += winArgs.height - webViewRect.size.height;
}
if (winArgs.heightSet) {
float heightDelta = (winArgs.height - webViewFrame.size.height) * scaleY;
windowFrame.size.height += heightDelta;
windowFrame.origin.y -= heightDelta;
}
[page setWindowFrame:windowFrame]; [pageBridge impl]->setWindowRect(windowRect);
[bridge showWindow]; [frameBridge showWindow];
END_BLOCK_OBJC_EXCEPTIONS; END_BLOCK_OBJC_EXCEPTIONS;
} }
......
...@@ -22,31 +22,39 @@ ...@@ -22,31 +22,39 @@
#import "Page.h" #import "Page.h"
#import "Frame.h" #import "Frame.h"
#import "IntRect.h" #import "FloatRect.h"
#import "Screen.h"
#import "WebCorePageBridge.h" #import "WebCorePageBridge.h"
namespace WebCore { namespace WebCore {
static NSRect flipGlobalRect(NSRect rect) Page::Page(WebCorePageBridge* bridge)
: m_frameCount(0)
, m_widget(0)
, m_bridge(bridge)
{ {
rect.origin.y = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) - NSMaxY(rect); init();
return rect;
} }
Page::Page(WebCorePageBridge* bridge) Widget* Page::widget() const
: m_frameCount(0), m_bridge(bridge)
{ {
init(); if (!m_widget)
m_widget = new Widget([bridge() outerView]);
return m_widget;
} }
IntRect Page::windowRect() const // These methods scale between window and WebView coordinates because JavaScript/DOM operations
// assume that the WebView and the window share the same coordinate system.
FloatRect Page::windowRect() const
{ {
return enclosingIntRect(flipGlobalRect([bridge() windowFrame])); return scaleScreenRectToWidget(flipScreenRect([bridge() windowFrame]), widget());
} }
void Page::setWindowRect(const IntRect& r) void Page::setWindowRect(const FloatRect& r)
{ {
[bridge() setWindowFrame:flipGlobalRect(r)]; [bridge() setWindowFrame:flipScreenRect(scaleWidgetRectToScreen(r, widget()))];
} }
} }
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#import "RenderTreeAsText.h" #import "RenderTreeAsText.h"
#import "RenderWidget.h" #import "RenderWidget.h"
#import "ReplaceSelectionCommand.h" #import "ReplaceSelectionCommand.h"
#import "Screen.h"
#import "SelectionController.h" #import "SelectionController.h"
#import "TextIterator.h" #import "TextIterator.h"
#import "TypingCommand.h" #import "TypingCommand.h"
...@@ -2304,7 +2305,7 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element) ...@@ -2304,7 +2305,7 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element)
static IntPoint globalPoint(NSWindow* window, NSPoint windowPoint) static IntPoint globalPoint(NSWindow* window, NSPoint windowPoint)
{ {
NSPoint screenPoint = [window convertBaseToScreen:windowPoint]; NSPoint screenPoint = [window convertBaseToScreen:windowPoint];
return IntPoint((int)screenPoint.x, (int)(NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) - screenPoint.y)); return IntPoint((int)screenPoint.x, (int)(flipScreenPoint(screenPoint).y));
} }
static PlatformMouseEvent createMouseEventFromDraggingInfo(NSWindow* window, id <NSDraggingInfo> info) static PlatformMouseEvent createMouseEventFromDraggingInfo(NSWindow* window, id <NSDraggingInfo> info)
......
...@@ -33,7 +33,8 @@ ...@@ -33,7 +33,8 @@
namespace WebCore { namespace WebCore {
Page::Page() Page::Page()
: m_frameCount(0) : m_frameCount(0)
, m_widget(0)
{ {
init(); init();
} }
...@@ -51,6 +52,16 @@ static HWND rootWindowForFrame(const Frame* frame) ...@@ -51,6 +52,16 @@ static HWND rootWindowForFrame(const Frame* frame)
return GetAncestor(frameWnd, GA_ROOT); return GetAncestor(frameWnd, GA_ROOT);
} }
Widget* Page::widget() const
{
if (!m_widget) {
HWND windowHandle = rootWindowForFrame(mainFrame());
if (windowHandle)
m_widget = new Widget(windowHandle);
}
return m_widget;
}
IntRect Page::windowRect() const IntRect Page::windowRect() const
{ {
HWND windowHandle = rootWindowForFrame(mainFrame()); HWND windowHandle = rootWindowForFrame(mainFrame());
......
<html>
<head>
<script>
var w;
function test(sFeatures)
{
if (w && !w.closed)
w.close();
w = window.open("resources/popup200x200.html", "popup", sFeatures);
}
</script>
</head>
<body>
<p>This test checks our support for the 'features' argument to window.open.</p>
<p>Each button below will open a new window. Check to make sure that the window has the specified attributes.</p>
<p style="color:red">NOTE: Please verify that the behavior in this test is resolution independent.</p>
<p>To test a non-standard resolution:</p>
<ol>
<li>Open Quartz Debug (/Developer/Applications/Performance Tools).</li>
<li>Select Tools -> Show User Interface Resolution.</li>
<li>Set the resolution to 2.0.</li>
<li>Restart Safari.</li>
</ol>
<hr>
<p>Window size (no toolbars): You should see a red 1 pixel border along every edge of this page, and no scrollbars.</p>
<input type="button" value="open it!" onclick='test("width=200, height=200, scrollbars=yes")';
<hr>
<p>Window size (all toolbars): You should see a red 1 pixel border along every edge of this page, and no scrollbars.</p>
<input type="button" value="open it!" onclick='test("width=200, height=200, scrollbars=yes, menubar=yes, status=yes, toolbar=yes")';
<hr>
<p>Window positioning: This window should be aligned exactly to the top right corner of the screen.</p>
<p style="color:red">NOTE: This won't work with resolution 2.0 until we fix screen.width.</p>
<input type="button" value="open it!" onclick='test("width=200,height=200,left=" + (screen.width - 200) + ",screenY=0")';
<hr>
</body>
</html>
<html>
<head>
<script>
var w;
function Open(sFeatures)
{
if (w && !w.closed)
w.close();
w = window.open("resources/popup200x200.html", "popup", sFeatures);
}
function test1()
{
Open("width=200, height=200, left = 0, top = 0, scrollbars, resizable");
setConsole(document.getElementById('console1'));
clearConsole();
shouldBe("w.innerHeight", 200);
shouldBe("w.innerWidth", 200);
shouldBe("w.outerWidth", 200);
shouldBe("w.screenLeft", 0);
shouldBe("w.screenTop", 22); // empirical result of low dpi testing
shouldBe("w.outerHeight", 223); // empirical result of low dpi testing
}