diff --git a/cef_paths2.gypi b/cef_paths2.gypi index bac6d9197..fbbd83fe9 100644 --- a/cef_paths2.gypi +++ b/cef_paths2.gypi @@ -158,6 +158,8 @@ 'tests/cefclient/browser/client_types.h', 'tests/cefclient/browser/dialog_test.cc', 'tests/cefclient/browser/dialog_test.h', + 'tests/cefclient/browser/geometry_util.cc', + 'tests/cefclient/browser/geometry_util.h', 'tests/cefclient/browser/main_context.cc', 'tests/cefclient/browser/main_context.h', 'tests/cefclient/browser/main_context_impl.cc', diff --git a/tests/cefclient/browser/browser_window.cc b/tests/cefclient/browser/browser_window.cc index 0d62e2719..5f29ac2dc 100644 --- a/tests/cefclient/browser/browser_window.cc +++ b/tests/cefclient/browser/browser_window.cc @@ -15,6 +15,13 @@ BrowserWindow::BrowserWindow(Delegate* delegate) DCHECK(delegate_); } +void BrowserWindow::SetDeviceScaleFactor(float device_scale_factor) { +} + +float BrowserWindow::GetDeviceScaleFactor() const { + return 1.0f; +} + CefRefPtr BrowserWindow::GetBrowser() const { REQUIRE_MAIN_THREAD(); return browser_; diff --git a/tests/cefclient/browser/browser_window.h b/tests/cefclient/browser/browser_window.h index 9c1aca9ff..4d9fd8c70 100644 --- a/tests/cefclient/browser/browser_window.h +++ b/tests/cefclient/browser/browser_window.h @@ -82,6 +82,14 @@ class BrowserWindow : public ClientHandler::Delegate { // Set focus to the window. virtual void SetFocus(bool focus) = 0; + // Set the device scale factor. Only used in combination with off-screen + // rendering. + virtual void SetDeviceScaleFactor(float device_scale_factor); + + // Returns the device scale factor. Only used in combination with off-screen + // rendering. + virtual float GetDeviceScaleFactor() const; + // Returns the window handle. virtual ClientWindowHandle GetWindowHandle() const = 0; diff --git a/tests/cefclient/browser/browser_window_osr_gtk.cc b/tests/cefclient/browser/browser_window_osr_gtk.cc index bedda3c91..b2d43d6ff 100644 --- a/tests/cefclient/browser/browser_window_osr_gtk.cc +++ b/tests/cefclient/browser/browser_window_osr_gtk.cc @@ -19,6 +19,7 @@ #include "include/base/cef_logging.h" #include "include/wrapper/cef_closure_task.h" +#include "cefclient/browser/geometry_util.h" #include "cefclient/browser/main_message_loop.h" namespace client { @@ -919,7 +920,8 @@ BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate, glarea_(NULL), hidden_(false), gl_enabled_(false), - painting_popup_(false) { + painting_popup_(false), + device_scale_factor_(1.0f) { client_handler_ = new ClientHandlerOsr(this, this, startup_url); } @@ -1012,6 +1014,28 @@ void BrowserWindowOsrGtk::SetFocus(bool focus) { gtk_widget_grab_focus(glarea_); } +void BrowserWindowOsrGtk::SetDeviceScaleFactor(float device_scale_factor) { + REQUIRE_MAIN_THREAD(); + if (device_scale_factor == device_scale_factor_) + return; + + // Apply some sanity checks. + if (device_scale_factor < 1.0f || device_scale_factor > 4.0f) + return; + + device_scale_factor_ = device_scale_factor; + + if (browser_) { + browser_->GetHost()->NotifyScreenInfoChanged(); + browser_->GetHost()->WasResized(); + } +} + +float BrowserWindowOsrGtk::GetDeviceScaleFactor() const { + REQUIRE_MAIN_THREAD(); + return device_scale_factor_; +} + ClientWindowHandle BrowserWindowOsrGtk::GetWindowHandle() const { REQUIRE_MAIN_THREAD(); return glarea_; @@ -1052,8 +1076,9 @@ bool BrowserWindowOsrGtk::GetViewRect(CefRefPtr browser, // The simulated screen and view rectangle are the same. This is necessary // for popup menus to be located and sized inside the view. rect.x = rect.y = 0; - rect.width = glarea_->allocation.width; - rect.height = glarea_->allocation.height; + rect.width = DeviceToLogical(glarea_->allocation.width, device_scale_factor_); + rect.height = DeviceToLogical(glarea_->allocation.height, + device_scale_factor_); return true; } @@ -1067,15 +1092,25 @@ bool BrowserWindowOsrGtk::GetScreenPoint(CefRefPtr browser, GdkRectangle screen_rect; GetWidgetRectInScreen(glarea_, &screen_rect); - screenX = screen_rect.x + viewX; - screenY = screen_rect.y + viewY; + screenX = screen_rect.x + LogicalToDevice(viewX, device_scale_factor_); + screenY = screen_rect.y + LogicalToDevice(viewY, device_scale_factor_); return true; } bool BrowserWindowOsrGtk::GetScreenInfo(CefRefPtr browser, CefScreenInfo& screen_info) { CEF_REQUIRE_UI_THREAD(); - return false; + + CefRect view_rect; + GetViewRect(browser, view_rect); + + screen_info.device_scale_factor = device_scale_factor_; + + // The screen info rectangles are used by the renderer to create and position + // popups. Keep popups inside the view rectangle. + screen_info.rect = view_rect; + screen_info.available_rect = view_rect; + return true; } void BrowserWindowOsrGtk::OnPopupShow(CefRefPtr browser, @@ -1095,7 +1130,7 @@ void BrowserWindowOsrGtk::OnPopupSize(CefRefPtr browser, CEF_REQUIRE_UI_THREAD(); REQUIRE_MAIN_THREAD(); - renderer_.OnPopupSize(browser, rect); + renderer_.OnPopupSize(browser, LogicalToDevice(rect, device_scale_factor_)); } void BrowserWindowOsrGtk::OnPaint( @@ -1270,6 +1305,7 @@ gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget, mouse_event.x = event->x; mouse_event.y = event->y; self->ApplyPopupOffset(mouse_event.x, mouse_event.y); + DeviceToLogical(mouse_event, self->device_scale_factor_); mouse_event.modifiers = GetCefStateModifiers(event->state); bool mouse_up = (event->type == GDK_BUTTON_RELEASE); @@ -1376,6 +1412,7 @@ gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget, mouse_event.x = x; mouse_event.y = y; self->ApplyPopupOffset(mouse_event.x, mouse_event.y); + DeviceToLogical(mouse_event, self->device_scale_factor_); mouse_event.modifiers = GetCefStateModifiers(state); bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY); @@ -1399,6 +1436,7 @@ gint BrowserWindowOsrGtk::ScrollEvent(GtkWidget* widget, mouse_event.x = event->x; mouse_event.y = event->y; self->ApplyPopupOffset(mouse_event.x, mouse_event.y); + DeviceToLogical(mouse_event, self->device_scale_factor_); mouse_event.modifiers = GetCefStateModifiers(event->state); static const int scrollbarPixelsPerGtkTick = 40; diff --git a/tests/cefclient/browser/browser_window_osr_gtk.h b/tests/cefclient/browser/browser_window_osr_gtk.h index 20b7f9394..c6a2d491e 100644 --- a/tests/cefclient/browser/browser_window_osr_gtk.h +++ b/tests/cefclient/browser/browser_window_osr_gtk.h @@ -39,6 +39,8 @@ class BrowserWindowOsrGtk : public BrowserWindow, void Hide() OVERRIDE; void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE; void SetFocus(bool focus) OVERRIDE; + void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE; + float GetDeviceScaleFactor() const OVERRIDE; ClientWindowHandle GetWindowHandle() const OVERRIDE; // ClientHandlerOsr::OsrDelegate methods. @@ -115,6 +117,8 @@ class BrowserWindowOsrGtk : public BrowserWindow, bool gl_enabled_; bool painting_popup_; + float device_scale_factor_; + DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrGtk); }; diff --git a/tests/cefclient/browser/browser_window_osr_mac.h b/tests/cefclient/browser/browser_window_osr_mac.h index 876c5fa51..52f4e514c 100644 --- a/tests/cefclient/browser/browser_window_osr_mac.h +++ b/tests/cefclient/browser/browser_window_osr_mac.h @@ -40,6 +40,8 @@ class BrowserWindowOsrMac : public BrowserWindow, void Hide() OVERRIDE; void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE; void SetFocus(bool focus) OVERRIDE; + void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE; + float GetDeviceScaleFactor() const OVERRIDE; ClientWindowHandle GetWindowHandle() const OVERRIDE; // ClientHandlerOsr::OsrDelegate methods. diff --git a/tests/cefclient/browser/browser_window_osr_mac.mm b/tests/cefclient/browser/browser_window_osr_mac.mm index bfb4d7ac5..22e0a84e5 100644 --- a/tests/cefclient/browser/browser_window_osr_mac.mm +++ b/tests/cefclient/browser/browser_window_osr_mac.mm @@ -12,6 +12,7 @@ #include "include/cef_parser.h" #include "include/wrapper/cef_closure_task.h" #include "cefclient/browser/bytes_write_handler.h" +#include "cefclient/browser/geometry_util.h" #include "cefclient/browser/main_message_loop.h" // Forward declare methods and constants that are only available with newer SDK @@ -25,6 +26,8 @@ @end @interface NSView (LionSDK) +- (NSPoint)convertPointFromBacking:(NSPoint)aPoint; +- (NSPoint)convertPointToBacking:(NSPoint)aPoint; - (NSRect)convertRectFromBacking:(NSRect)aRect; - (NSRect)convertRectToBacking:(NSRect)aRect; - (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag; @@ -53,6 +56,8 @@ extern NSString* const NSWindowDidChangeBackingPropertiesNotification; bool was_last_mouse_down_on_view_; + float device_scale_factor_; + // Drag and drop CefRefPtr current_drag_data_; NSDragOperation current_drag_op_; @@ -73,6 +78,8 @@ extern NSString* const NSWindowDidChangeBackingPropertiesNotification; - (NSPoint)getClickPointForEvent:(NSEvent*)event; - (void)getKeyEvent:(CefKeyEvent&)keyEvent forEvent:(NSEvent*)event; - (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event; +- (void)getMouseEvent:(CefMouseEvent&)mouseEvent + forDragInfo:(id)info; - (int)getModifiersForEvent:(NSEvent*)event; - (BOOL)isKeyUpEvent:(NSEvent*)event; - (BOOL)isKeyPadEvent:(NSEvent*)event; @@ -85,6 +92,8 @@ extern NSString* const NSWindowDidChangeBackingPropertiesNotification; - (void)populateDropData:(CefRefPtr)data fromPasteboard:(NSPasteboard*)pboard; - (NSPoint)flipWindowPointToView:(const NSPoint&)windowPoint; +- (void)resetDeviceScaleFactor; +- (void)setDeviceScaleFactor:(float)device_scale_factor; - (float)getDeviceScaleFactor; - (void)windowDidChangeBackingProperties:(NSNotification*)notification; @@ -97,8 +106,10 @@ extern NSString* const NSWindowDidChangeBackingPropertiesNotification; button:(CefBrowserHost::MouseButtonType)type isUp:(bool)isUp; -- (CefRect)convertRectToBackingInternal:(const CefRect&)rect; -- (CefRect)convertRectFromBackingInternal:(const CefRect&)rect; +- (NSPoint)convertPointFromBackingInternal:(NSPoint)aPoint; +- (NSPoint)convertPointToBackingInternal:(NSPoint)aPoint; +- (NSRect)convertRectFromBackingInternal:(NSRect)aRect; +- (NSRect)convertRectToBackingInternal:(NSRect)aRect; @end @@ -128,15 +139,6 @@ BOOL SupportsBackingPropertiesChangedNotification() { return methodDescription.name != NULL || methodDescription.types != NULL; } -CefRect convertRect(const NSRect& target, const NSRect& frame) { - NSRect rect = target; - rect.origin.y = NSMaxY(frame) - NSMaxY(target); - return CefRect(rect.origin.x, - rect.origin.y, - rect.size.width, - rect.size.height); -} - NSString* const kCEFDragDummyPboardType = @"org.CEF.drag-dummy-type"; NSString* const kNSURLTitlePboardType = @"public.url-name"; @@ -184,6 +186,7 @@ BrowserOpenGLView* GLView(NSView* view) { renderer_ = renderer; rotating_ = false; endWheelMonitor_ = nil; + device_scale_factor_ = 1.0f; tracking_area_ = [[NSTrackingArea alloc] initWithRect:frame @@ -255,14 +258,20 @@ BrowserOpenGLView* GLView(NSView* view) { return; CefMouseEvent mouseEvent; - [self getMouseEvent: mouseEvent forEvent: event]; + [self getMouseEvent:mouseEvent forEvent:event]; + + // |point| is in OS X view coordinates. NSPoint point = [self getClickPointForEvent:event]; - if (!isUp) - was_last_mouse_down_on_view_ = ![self isOverPopupWidgetX: point.x - andY: point.y]; - else if (was_last_mouse_down_on_view_ && - [self isOverPopupWidgetX:point.x andY: point.y] && - ([self getPopupXOffset] || [self getPopupYOffset])) { + + // Convert to device coordinates. + point = [self convertPointToBackingInternal:point]; + + if (!isUp) { + was_last_mouse_down_on_view_ = ![self isOverPopupWidgetX:point.x + andY:point.y]; + } else if (was_last_mouse_down_on_view_ && + [self isOverPopupWidgetX:point.x andY:point.y] && + ([self getPopupXOffset] || [self getPopupYOffset])) { return; } @@ -326,7 +335,8 @@ BrowserOpenGLView* GLView(NSView* view) { } CefMouseEvent mouseEvent; - [self getMouseEvent: mouseEvent forEvent: event]; + [self getMouseEvent:mouseEvent forEvent:event]; + browser->GetHost()->SendMouseMoveEvent(mouseEvent, false); } @@ -352,7 +362,8 @@ BrowserOpenGLView* GLView(NSView* view) { return; CefMouseEvent mouseEvent; - [self getMouseEvent: mouseEvent forEvent: event]; + [self getMouseEvent:mouseEvent forEvent:event]; + browser->GetHost()->SendMouseMoveEvent(mouseEvent, true); } @@ -439,7 +450,8 @@ BrowserOpenGLView* GLView(NSView* view) { CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1); CefMouseEvent mouseEvent; - [self getMouseEvent: mouseEvent forEvent: event]; + [self getMouseEvent:mouseEvent forEvent:event]; + browser->GetHost()->SendMouseWheelEvent(mouseEvent, deltaX, deltaY); } @@ -554,17 +566,44 @@ BrowserOpenGLView* GLView(NSView* view) { } - (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event { - NSPoint point = [self getClickPointForEvent:event]; - mouseEvent.x = point.x; - mouseEvent.y = point.y; + const float device_scale_factor = [self getDeviceScaleFactor]; - if ([self isOverPopupWidgetX:mouseEvent.x andY: mouseEvent.y]) { - [self applyPopupOffsetToX:mouseEvent.x andY: mouseEvent.y]; - } + // |point| is in OS X view coordinates. + NSPoint point = [self getClickPointForEvent:event]; + + // Convert to device coordinates. + point = [self convertPointToBackingInternal:point]; + + int device_x = point.x; + int device_y = point.y; + if ([self isOverPopupWidgetX:device_x andY:device_y]) + [self applyPopupOffsetToX:device_x andY:device_y]; + + // Convert to browser view coordinates. + mouseEvent.x = client::DeviceToLogical(device_x, device_scale_factor); + mouseEvent.y = client::DeviceToLogical(device_y, device_scale_factor); mouseEvent.modifiers = [self getModifiersForEvent:event]; } +- (void)getMouseEvent:(CefMouseEvent&)mouseEvent + forDragInfo:(id)info { + const float device_scale_factor = [self getDeviceScaleFactor]; + + // |point| is in OS X view coordinates. + NSPoint windowPoint = [info draggingLocation]; + NSPoint point = [self flipWindowPointToView:windowPoint]; + + // Convert to device coordinates. + point = [self convertPointToBackingInternal:point]; + + // Convert to browser view coordinates. + mouseEvent.x = client::DeviceToLogical(point.x, device_scale_factor); + mouseEvent.y = client::DeviceToLogical(point.y, device_scale_factor); + + mouseEvent.modifiers = [NSEvent modifierFlags]; +} + - (int)getModifiersForEvent:(NSEvent*)event { int modifiers = 0; @@ -678,16 +717,7 @@ BrowserOpenGLView* GLView(NSView* view) { - (void)windowDidChangeBackingProperties:(NSNotification*)notification { // This delegate method is only called on 10.7 and later, so don't worry about // other backing changes calling it on 10.6 or earlier - CGFloat newBackingScaleFactor = [self getDeviceScaleFactor]; - CGFloat oldBackingScaleFactor = (CGFloat)[ - [notification.userInfo objectForKey:@"NSBackingPropertyOldScaleFactorKey"] - doubleValue - ]; - if (newBackingScaleFactor != oldBackingScaleFactor) { - CefRefPtr browser = [self getBrowser]; - if (browser.get()) - browser->GetHost()->NotifyScreenInfoChanged(); - } + [self resetDeviceScaleFactor]; } - (void)drawRect: (NSRect) dirtyRect { @@ -814,7 +844,7 @@ BrowserOpenGLView* GLView(NSView* view) { // NSDraggingDestination Protocol -- (NSDragOperation)draggingEntered:(id )info { +- (NSDragOperation)draggingEntered:(id)info { CefRefPtr browser = [self getBrowser]; if (!browser.get()) return NSDragOperationNone; @@ -829,44 +859,39 @@ BrowserOpenGLView* GLView(NSView* view) { drag_data->ResetFileContents(); } - NSPoint windowPoint = [info draggingLocation]; - NSPoint viewPoint = [self flipWindowPointToView:windowPoint]; + CefMouseEvent mouseEvent; + [self getMouseEvent:mouseEvent forDragInfo:info]; + NSDragOperation mask = [info draggingSourceOperationMask]; - CefMouseEvent ev; - ev.x = viewPoint.x; - ev.y = viewPoint.y; - ev.modifiers = [NSEvent modifierFlags]; CefBrowserHost::DragOperationsMask allowed_ops = static_cast(mask); - browser->GetHost()->DragTargetDragEnter(drag_data, ev, allowed_ops); - browser->GetHost()->DragTargetDragOver(ev, allowed_ops); + + browser->GetHost()->DragTargetDragEnter(drag_data, mouseEvent, allowed_ops); + browser->GetHost()->DragTargetDragOver(mouseEvent, allowed_ops); current_drag_op_ = NSDragOperationCopy; return current_drag_op_; } -- (void)draggingExited:(id )sender { +- (void)draggingExited:(id)sender { CefRefPtr browser = [self getBrowser]; if (browser.get()) browser->GetHost()->DragTargetDragLeave(); } -- (BOOL)prepareForDragOperation:(id )info { +- (BOOL)prepareForDragOperation:(id)info { return YES; } -- (BOOL)performDragOperation:(id )info { +- (BOOL)performDragOperation:(id)info { CefRefPtr browser = [self getBrowser]; if (!browser.get()) return NO; - NSPoint windowPoint = [info draggingLocation]; - NSPoint viewPoint = [self flipWindowPointToView:windowPoint]; - CefMouseEvent ev; - ev.x = viewPoint.x; - ev.y = viewPoint.y; - ev.modifiers = [NSEvent modifierFlags]; - browser->GetHost()->DragTargetDrop(ev); + CefMouseEvent mouseEvent; + [self getMouseEvent:mouseEvent forDragInfo:info]; + + browser->GetHost()->DragTargetDrop(mouseEvent); return YES; } @@ -876,16 +901,14 @@ BrowserOpenGLView* GLView(NSView* view) { if (!browser.get()) return NSDragOperationNone; - NSPoint windowPoint = [info draggingLocation]; - NSPoint viewPoint = [self flipWindowPointToView:windowPoint]; + CefMouseEvent mouseEvent; + [self getMouseEvent:mouseEvent forDragInfo:info]; + NSDragOperation mask = [info draggingSourceOperationMask]; - CefMouseEvent ev; - ev.x = viewPoint.x; - ev.y = viewPoint.y; - ev.modifiers = [NSEvent modifierFlags]; CefBrowserHost::DragOperationsMask allowed_ops = - static_cast(mask); - browser->GetHost()->DragTargetDragOver(ev, allowed_ops); + static_cast(mask); + + browser->GetHost()->DragTargetDragOver(mouseEvent, allowed_ops); return current_drag_op_; } @@ -1041,22 +1064,41 @@ BrowserOpenGLView* GLView(NSView* view) { return viewPoint; } -- (float)getDeviceScaleFactor { - float deviceScaleFactor = 1; +- (void)resetDeviceScaleFactor { + float device_scale_factor = 1.0f; NSWindow* window = [self window]; - if (!window) - return deviceScaleFactor; + if (window) { + if ([window respondsToSelector:@selector(backingScaleFactor)]) + device_scale_factor = [window backingScaleFactor]; + else + device_scale_factor = [window userSpaceScaleFactor]; + } + [self setDeviceScaleFactor:device_scale_factor]; +} - if ([window respondsToSelector:@selector(backingScaleFactor)]) - deviceScaleFactor = [window backingScaleFactor]; - else - deviceScaleFactor = [window userSpaceScaleFactor]; +- (void)setDeviceScaleFactor:(float)device_scale_factor { + if (device_scale_factor == device_scale_factor_) + return; - return deviceScaleFactor; + // Apply some sanity checks. + if (device_scale_factor < 1.0f || device_scale_factor > 4.0f) + return; + + device_scale_factor_ = device_scale_factor; + + CefRefPtr browser = [self getBrowser]; + if (browser) { + browser->GetHost()->NotifyScreenInfoChanged(); + browser->GetHost()->WasResized(); + } +} + +- (float)getDeviceScaleFactor { + return device_scale_factor_; } - (bool)isOverPopupWidgetX:(int)x andY:(int)y { - CefRect rc = [self convertRectFromBackingInternal:renderer_->popup_rect()]; + CefRect rc = renderer_->popup_rect(); int popup_right = rc.x + rc.width; int popup_bottom = rc.y + rc.height; return (x >= rc.x) && (x < popup_right) && @@ -1064,21 +1106,11 @@ BrowserOpenGLView* GLView(NSView* view) { } - (int)getPopupXOffset { - int original_x = - [self convertRectFromBackingInternal:renderer_->original_popup_rect()].x; - int popup_x = - [self convertRectFromBackingInternal:renderer_->popup_rect()].x; - - return original_x - popup_x; + return renderer_->original_popup_rect().x - renderer_->popup_rect().x; } - (int)getPopupYOffset { - int original_y = - [self convertRectFromBackingInternal:renderer_->original_popup_rect()].y; - int popup_y = - [self convertRectFromBackingInternal:renderer_->popup_rect()].y; - - return original_y - popup_y; + return renderer_->original_popup_rect().y - renderer_->popup_rect().y; } - (void)applyPopupOffsetToX:(int&)x andY:(int&)y { @@ -1088,32 +1120,32 @@ BrowserOpenGLView* GLView(NSView* view) { } } -// Convert the rect from view coordinates to scaled coordinates. -- (CefRect) convertRectToBackingInternal:(const CefRect&)rect { - if ([self respondsToSelector:@selector(convertRectToBacking:)]) { - NSRect view_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); - NSRect scaled_rect = [self convertRectToBacking:view_rect]; - return CefRect((int)scaled_rect.origin.x, - (int)scaled_rect.origin.y, - (int)scaled_rect.size.width, - (int)scaled_rect.size.height); - } - - return rect; +// Convert from scaled coordinates to view coordinates. +- (NSPoint)convertPointFromBackingInternal:(NSPoint)aPoint { + if ([self respondsToSelector:@selector(convertPointFromBacking:)]) + return [self convertPointFromBacking:aPoint]; + return aPoint; } -// Convert the rect from scaled coordinates to view coordinates. -- (CefRect) convertRectFromBackingInternal: (const CefRect&) rect { - if ([self respondsToSelector:@selector(convertRectFromBacking:)]) { - NSRect scaled_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); - NSRect view_rect = [self convertRectFromBacking:scaled_rect]; - return CefRect((int)view_rect.origin.x, - (int)view_rect.origin.y, - (int)view_rect.size.width, - (int)view_rect.size.height); - } +// Convert from view coordinates to scaled coordinates. +- (NSPoint)convertPointToBackingInternal:(NSPoint)aPoint { + if ([self respondsToSelector:@selector(convertPointToBacking:)]) + return [self convertPointToBacking:aPoint]; + return aPoint; +} - return rect; +// Convert from scaled coordinates to view coordinates. +- (NSRect)convertRectFromBackingInternal:(NSRect)aRect { + if ([self respondsToSelector:@selector(convertRectFromBacking:)]) + return [self convertRectFromBacking:aRect]; + return aRect; +} + +// Convert from view coordinates to scaled coordinates. +- (NSRect)convertRectToBackingInternal:(NSRect)aRect { + if ([self respondsToSelector:@selector(convertRectToBacking:)]) + return [self convertRectToBacking:aRect]; + return aRect; } @end @@ -1223,6 +1255,19 @@ void BrowserWindowOsrMac::SetFocus(bool focus) { [[nsview_ window] makeFirstResponder:nsview_]; } +void BrowserWindowOsrMac::SetDeviceScaleFactor(float device_scale_factor) { + REQUIRE_MAIN_THREAD(); + if (nsview_) + [GLView(nsview_) setDeviceScaleFactor:device_scale_factor]; +} + +float BrowserWindowOsrMac::GetDeviceScaleFactor() const { + REQUIRE_MAIN_THREAD(); + if (nsview_) + return [GLView(nsview_) getDeviceScaleFactor]; + return 1.0f; +} + ClientWindowHandle BrowserWindowOsrMac::GetWindowHandle() const { REQUIRE_MAIN_THREAD(); return nsview_; @@ -1254,12 +1299,19 @@ bool BrowserWindowOsrMac::GetViewRect(CefRefPtr browser, if (!nsview_) return false; - // The simulated screen and view rectangle are the same. This is necessary - // for popup menus to be located and sized inside the view. - const NSRect bounds = [nsview_ bounds]; + const float device_scale_factor = [GLView(nsview_) getDeviceScaleFactor]; + + // |bounds| is in OS X view coordinates. + NSRect bounds = [nsview_ bounds]; + + // Convert to device coordinates. + bounds = [GLView(nsview_) convertRectToBackingInternal:bounds]; + + // Convert to browser view coordinates. rect.x = rect.y = 0; - rect.width = bounds.size.width; - rect.height = bounds.size.height; + rect.width = DeviceToLogical(bounds.size.width, device_scale_factor); + rect.height = DeviceToLogical(bounds.size.height, device_scale_factor); + return true; } @@ -1274,11 +1326,25 @@ bool BrowserWindowOsrMac::GetScreenPoint(CefRefPtr browser, if (!nsview_) return false; - // Convert the point from view coordinates to actual screen coordinates. - NSRect bounds = [nsview_ bounds]; - NSPoint view_pt = NSMakePoint(viewX, bounds.size.height - viewY); + const float device_scale_factor = [GLView(nsview_) getDeviceScaleFactor]; + + // (viewX, viewX) is in browser view coordinates. + // Convert to device coordinates. + NSPoint view_pt = NSMakePoint( + LogicalToDevice(viewX, device_scale_factor), + LogicalToDevice(viewY, device_scale_factor)); + + // Convert to OS X view coordinates. + view_pt = [GLView(nsview_) convertPointFromBackingInternal:view_pt]; + + // Reverse the Y component. + const NSRect bounds = [nsview_ bounds]; + view_pt.y = bounds.size.height - view_pt.y; + + // Convert to screen coordinates. NSPoint window_pt = [nsview_ convertPoint:view_pt toView:nil]; NSPoint screen_pt = [[nsview_ window] convertBaseToScreen:window_pt]; + screenX = screen_pt.x; screenY = screen_pt.y; return true; @@ -1292,23 +1358,15 @@ bool BrowserWindowOsrMac::GetScreenInfo(CefRefPtr browser, if (!nsview_) return false; - NSWindow* window = [nsview_ window]; - if (!window) - return false; + CefRect view_rect; + GetViewRect(browser, view_rect); screen_info.device_scale_factor = [GLView(nsview_) getDeviceScaleFactor]; - NSScreen* screen = [window screen]; - if (!screen) - screen = [NSScreen deepestScreen]; - - screen_info.depth = NSBitsPerPixelFromDepth([screen depth]); - screen_info.depth_per_component = NSBitsPerSampleFromDepth([screen depth]); - screen_info.is_monochrome = - [[screen colorSpace] colorSpaceModel] == NSGrayColorSpaceModel; - screen_info.rect = convertRect([screen frame], [screen frame]); - screen_info.available_rect = - convertRect([screen visibleFrame], [screen frame]); + // The screen info rectangles are used by the renderer to create and position + // popups. Keep popups inside the view rectangle. + screen_info.rect = view_rect; + screen_info.available_rect = view_rect; return true; } @@ -1336,8 +1394,12 @@ void BrowserWindowOsrMac::OnPopupSize(CefRefPtr browser, if (!nsview_) return; - renderer_.OnPopupSize(browser, - [GLView(nsview_) convertRectToBackingInternal:rect]); + const float device_scale_factor = [GLView(nsview_) getDeviceScaleFactor]; + + // |rect| is in browser view coordinates. Convert to device coordinates. + CefRect device_rect = LogicalToDevice(rect, device_scale_factor); + + renderer_.OnPopupSize(browser, device_rect); } void BrowserWindowOsrMac::OnPaint( @@ -1396,10 +1458,22 @@ bool BrowserWindowOsrMac::StartDragging( if (!nsview_) return false; + static float device_scale_factor = [GLView(nsview_) getDeviceScaleFactor]; + + // |point| is in browser view coordinates. + NSPoint point = NSMakePoint(x, y); + + // Convert to device coordinates. + point.x = LogicalToDevice(point.x, device_scale_factor); + point.y = LogicalToDevice(point.y, device_scale_factor); + + // Convert to OS X view coordinates. + point = [GLView(nsview_) convertPointFromBackingInternal:point]; + return [GLView(nsview_) startDragging:drag_data allowedOps:static_cast(allowed_ops) - point:NSMakePoint(x, y)]; + point:point]; } void BrowserWindowOsrMac::UpdateDragCursor( @@ -1426,6 +1500,9 @@ void BrowserWindowOsrMac::Create(ClientWindowHandle parent_handle, [nsview_ setAutoresizesSubviews: true]; [parent_handle addSubview:nsview_]; + // Determine the default scale factor. + [GLView(nsview_) resetDeviceScaleFactor]; + // Backing property notifications crash on 10.6 when building with the 10.7 // SDK, see http://crbug.com/260595. static BOOL supportsBackingPropertiesNotification = diff --git a/tests/cefclient/browser/browser_window_osr_win.cc b/tests/cefclient/browser/browser_window_osr_win.cc index e4ee5d500..019a27629 100644 --- a/tests/cefclient/browser/browser_window_osr_win.cc +++ b/tests/cefclient/browser/browser_window_osr_win.cc @@ -5,6 +5,7 @@ #include "cefclient/browser/browser_window_osr_win.h" #include "cefclient/browser/main_message_loop.h" +#include "cefclient/browser/util_win.h" namespace client { @@ -13,7 +14,8 @@ BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindow::Delegate* delegate, const OsrRenderer::Settings& settings) : BrowserWindow(delegate), transparent_(settings.transparent), - osr_hwnd_(NULL) { + osr_hwnd_(NULL), + device_scale_factor_(client::GetDeviceScaleFactor()) { osr_window_ = new OsrWindowWin(this, settings); client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url); } @@ -71,6 +73,25 @@ void BrowserWindowOsrWin::SetFocus(bool focus) { osr_window_->SetFocus(); } +void BrowserWindowOsrWin::SetDeviceScaleFactor(float device_scale_factor) { + REQUIRE_MAIN_THREAD(); + if (device_scale_factor == device_scale_factor_) + return; + + // Apply some sanity checks. + if (device_scale_factor < 1.0f || device_scale_factor > 4.0f) + return; + + device_scale_factor_ = device_scale_factor; + if (osr_window_) + osr_window_->SetDeviceScaleFactor(device_scale_factor); +} + +float BrowserWindowOsrWin::GetDeviceScaleFactor() const { + REQUIRE_MAIN_THREAD(); + return device_scale_factor_; +} + ClientWindowHandle BrowserWindowOsrWin::GetWindowHandle() const { REQUIRE_MAIN_THREAD(); return osr_hwnd_; diff --git a/tests/cefclient/browser/browser_window_osr_win.h b/tests/cefclient/browser/browser_window_osr_win.h index 9abe17ea8..7d561ade8 100644 --- a/tests/cefclient/browser/browser_window_osr_win.h +++ b/tests/cefclient/browser/browser_window_osr_win.h @@ -38,6 +38,8 @@ class BrowserWindowOsrWin : public BrowserWindow, void Hide() OVERRIDE; void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE; void SetFocus(bool focus) OVERRIDE; + void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE; + float GetDeviceScaleFactor() const OVERRIDE; ClientWindowHandle GetWindowHandle() const OVERRIDE; private: @@ -53,6 +55,8 @@ class BrowserWindowOsrWin : public BrowserWindow, scoped_refptr osr_window_; HWND osr_hwnd_; + float device_scale_factor_; + DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrWin); }; diff --git a/tests/cefclient/browser/geometry_util.cc b/tests/cefclient/browser/geometry_util.cc new file mode 100644 index 000000000..3c20cf27c --- /dev/null +++ b/tests/cefclient/browser/geometry_util.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#include "cefclient/browser/geometry_util.h" + +#include + +namespace client { + +int LogicalToDevice(int value, float device_scale_factor) { + float scaled_val = static_cast(value) * device_scale_factor; + return static_cast(std::floor(scaled_val)); +} + +CefRect LogicalToDevice(const CefRect& value, float device_scale_factor) { + return CefRect(LogicalToDevice(value.x, device_scale_factor), + LogicalToDevice(value.y, device_scale_factor), + LogicalToDevice(value.width, device_scale_factor), + LogicalToDevice(value.height, device_scale_factor)); +} + +int DeviceToLogical(int value, float device_scale_factor) { + float scaled_val = static_cast(value) / device_scale_factor; + return static_cast(std::floor(scaled_val)); +} + +void DeviceToLogical(CefMouseEvent& value, float device_scale_factor) { + value.x = DeviceToLogical(value.x, device_scale_factor); + value.y = DeviceToLogical(value.y, device_scale_factor); +} + +} // namespace client diff --git a/tests/cefclient/browser/geometry_util.h b/tests/cefclient/browser/geometry_util.h new file mode 100644 index 000000000..64cf9e8f5 --- /dev/null +++ b/tests/cefclient/browser/geometry_util.h @@ -0,0 +1,23 @@ +// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef CEF_TESTS_CEFCLIENT_BROWSER_GEOMETRY_UTIL_H_ +#define CEF_TESTS_CEFCLIENT_BROWSER_GEOMETRY_UTIL_H_ +#pragma once + +#include "include/internal/cef_types_wrappers.h" + +namespace client { + +// Convert |value| from logical coordinates to device coordinates. +int LogicalToDevice(int value, float device_scale_factor); +CefRect LogicalToDevice(const CefRect& value, float device_scale_factor); + +// Convert |value| from device coordinates to logical coordinates. +int DeviceToLogical(int value, float device_scale_factor); +void DeviceToLogical(CefMouseEvent& value, float device_scale_factor); + +} // namespace client + +#endif // CEF_TESTS_CEFCLIENT_BROWSER_GEOMETRY_UTIL_H_ diff --git a/tests/cefclient/browser/osr_window_win.cc b/tests/cefclient/browser/osr_window_win.cc index 7b9571014..a5f6205e2 100644 --- a/tests/cefclient/browser/osr_window_win.cc +++ b/tests/cefclient/browser/osr_window_win.cc @@ -7,6 +7,7 @@ #include #include "include/base/cef_build.h" +#include "cefclient/browser/geometry_util.h" #include "cefclient/browser/main_message_loop.h" #include "cefclient/browser/resource.h" #include "cefclient/browser/util_win.h" @@ -55,6 +56,7 @@ OsrWindowWin::OsrWindowWin(Delegate* delegate, hdc_(NULL), hrc_(NULL), client_rect_(), + device_scale_factor_(client::GetDeviceScaleFactor()), painting_popup_(false), render_task_pending_(false), hidden_(false), @@ -199,6 +201,24 @@ void OsrWindowWin::SetFocus() { } } +void OsrWindowWin::SetDeviceScaleFactor(float device_scale_factor) { + if (!CefCurrentlyOn(TID_UI)) { + // Execute this method on the UI thread. + CefPostTask(TID_UI, base::Bind(&OsrWindowWin::SetDeviceScaleFactor, this, + device_scale_factor)); + return; + } + + if (device_scale_factor == device_scale_factor_) + return; + + device_scale_factor_ = device_scale_factor; + if (browser_) { + browser_->GetHost()->NotifyScreenInfoChanged(); + browser_->GetHost()->WasResized(); + } +} + void OsrWindowWin::Create(HWND parent_hwnd, const RECT& rect) { CEF_REQUIRE_UI_THREAD(); DCHECK(!hwnd_ && !hdc_ && !hrc_); @@ -443,8 +463,6 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { LONG currentTime = 0; bool cancelPreviousClick = false; - const float device_scale_factor = GetDeviceScaleFactor(); - if (message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_MOUSEMOVE || message == WM_MOUSELEAVE) { @@ -498,7 +516,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { mouse_event.y = y; last_mouse_down_on_view_ = !IsOverPopupWidget(x, y); ApplyPopupOffset(mouse_event.x, mouse_event.y); - DeviceToLogical(mouse_event, device_scale_factor); + DeviceToLogical(mouse_event, device_scale_factor_); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseClickEvent(mouse_event, btnType, false, last_click_count_); @@ -532,7 +550,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { break; } ApplyPopupOffset(mouse_event.x, mouse_event.y); - DeviceToLogical(mouse_event, device_scale_factor); + DeviceToLogical(mouse_event, device_scale_factor_); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseClickEvent(mouse_event, btnType, true, last_click_count_); @@ -570,7 +588,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { mouse_event.x = x; mouse_event.y = y; ApplyPopupOffset(mouse_event.x, mouse_event.y); - DeviceToLogical(mouse_event, device_scale_factor); + DeviceToLogical(mouse_event, device_scale_factor_); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseMoveEvent(mouse_event, false); } @@ -598,7 +616,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { CefMouseEvent mouse_event; mouse_event.x = p.x; mouse_event.y = p.y; - DeviceToLogical(mouse_event, device_scale_factor); + DeviceToLogical(mouse_event, device_scale_factor_); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseMoveEvent(mouse_event, true); } @@ -618,7 +636,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { mouse_event.x = screen_point.x; mouse_event.y = screen_point.y; ApplyPopupOffset(mouse_event.x, mouse_event.y); - DeviceToLogical(mouse_event, device_scale_factor); + DeviceToLogical(mouse_event, device_scale_factor_); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseWheelEvent(mouse_event, IsKeyDown(VK_SHIFT) ? delta : 0, @@ -744,13 +762,11 @@ bool OsrWindowWin::GetViewRect(CefRefPtr browser, CefRect& rect) { CEF_REQUIRE_UI_THREAD(); - const float device_scale_factor = GetDeviceScaleFactor(); - rect.x = rect.y = 0; rect.width = DeviceToLogical(client_rect_.right - client_rect_.left, - device_scale_factor); + device_scale_factor_); rect.height = DeviceToLogical(client_rect_.bottom - client_rect_.top, - device_scale_factor); + device_scale_factor_); return true; } @@ -764,12 +780,10 @@ bool OsrWindowWin::GetScreenPoint(CefRefPtr browser, if (!::IsWindow(hwnd_)) return false; - const float device_scale_factor = GetDeviceScaleFactor(); - // Convert the point from view coordinates to actual screen coordinates. POINT screen_pt = { - LogicalToDevice(viewX, device_scale_factor), - LogicalToDevice(viewY, device_scale_factor) + LogicalToDevice(viewX, device_scale_factor_), + LogicalToDevice(viewY, device_scale_factor_) }; ClientToScreen(hwnd_, &screen_pt); screenX = screen_pt.x; @@ -787,7 +801,7 @@ bool OsrWindowWin::GetScreenInfo(CefRefPtr browser, CefRect view_rect; GetViewRect(browser, view_rect); - screen_info.device_scale_factor = GetDeviceScaleFactor(); + screen_info.device_scale_factor = device_scale_factor_; // The screen info rectangles are used by the renderer to create and position // popups. Keep popups inside the view rectangle. @@ -811,7 +825,7 @@ void OsrWindowWin::OnPopupSize(CefRefPtr browser, const CefRect& rect) { CEF_REQUIRE_UI_THREAD(); - renderer_.OnPopupSize(browser, LogicalToDevice(rect, GetDeviceScaleFactor())); + renderer_.OnPopupSize(browser, LogicalToDevice(rect, device_scale_factor_)); } void OsrWindowWin::OnPaint(CefRefPtr browser, @@ -874,11 +888,9 @@ bool OsrWindowWin::StartDragging( GetCursorPos(&pt); ScreenToClient(hwnd_, &pt); - const float device_scale_factor = GetDeviceScaleFactor(); - browser->GetHost()->DragSourceEndedAt( - DeviceToLogical(pt.x, device_scale_factor), - DeviceToLogical(pt.y, device_scale_factor), + DeviceToLogical(pt.x, device_scale_factor_), + DeviceToLogical(pt.y, device_scale_factor_), result); browser->GetHost()->DragSourceSystemDragEnded(); return true; @@ -905,7 +917,7 @@ OsrWindowWin::OnDragEnter(CefRefPtr drag_data, CefMouseEvent ev, CefBrowserHost::DragOperationsMask effect) { if (browser_) { - DeviceToLogical(ev, GetDeviceScaleFactor()); + DeviceToLogical(ev, device_scale_factor_); browser_->GetHost()->DragTargetDragEnter(drag_data, ev, effect); browser_->GetHost()->DragTargetDragOver(ev, effect); } @@ -916,7 +928,7 @@ CefBrowserHost::DragOperationsMask OsrWindowWin::OnDragOver(CefMouseEvent ev, CefBrowserHost::DragOperationsMask effect) { if (browser_) { - DeviceToLogical(ev, GetDeviceScaleFactor()); + DeviceToLogical(ev, device_scale_factor_); browser_->GetHost()->DragTargetDragOver(ev, effect); } return current_drag_op_; @@ -931,7 +943,7 @@ CefBrowserHost::DragOperationsMask OsrWindowWin::OnDrop(CefMouseEvent ev, CefBrowserHost::DragOperationsMask effect) { if (browser_) { - DeviceToLogical(ev, GetDeviceScaleFactor()); + DeviceToLogical(ev, device_scale_factor_); browser_->GetHost()->DragTargetDragOver(ev, effect); browser_->GetHost()->DragTargetDrop(ev); } diff --git a/tests/cefclient/browser/osr_window_win.h b/tests/cefclient/browser/osr_window_win.h index 4006f958c..398846783 100644 --- a/tests/cefclient/browser/osr_window_win.h +++ b/tests/cefclient/browser/osr_window_win.h @@ -57,6 +57,7 @@ class OsrWindowWin : void Hide(); void SetBounds(int x, int y, size_t width, size_t height); void SetFocus(); + void SetDeviceScaleFactor(float device_scale_factor); private: // Only allow deletion via scoped_refptr. @@ -156,6 +157,7 @@ class OsrWindowWin : HGLRC hrc_; RECT client_rect_; + float device_scale_factor_; CefRefPtr browser_; diff --git a/tests/cefclient/browser/resource.h b/tests/cefclient/browser/resource.h index c39129480..5f4c79cf6 100644 --- a/tests/cefclient/browser/resource.h +++ b/tests/cefclient/browser/resource.h @@ -38,11 +38,10 @@ #define ID_TESTS_ZOOM_IN 32710 #define ID_TESTS_ZOOM_OUT 32711 #define ID_TESTS_ZOOM_RESET 32712 -#define ID_TESTS_FPS_INCREASE 32713 -#define ID_TESTS_FPS_DECREASE 32714 -#define ID_TESTS_FPS_RESET 32715 -#define ID_TESTS_PRINT_TO_PDF 32716 -#define ID_TESTS_LAST 32716 +#define ID_TESTS_OSR_FPS 32713 +#define ID_TESTS_OSR_DSF 32714 +#define ID_TESTS_PRINT_TO_PDF 32715 +#define ID_TESTS_LAST 32715 #define IDC_STATIC -1 #define IDS_BINDING_HTML 1000 #define IDS_DIALOGS_HTML 1001 diff --git a/tests/cefclient/browser/root_window.h b/tests/cefclient/browser/root_window.h index 8acff89df..74e96cb35 100644 --- a/tests/cefclient/browser/root_window.h +++ b/tests/cefclient/browser/root_window.h @@ -103,6 +103,14 @@ class RootWindow : // executed. virtual void Close(bool force) = 0; + // Set the device scale factor. Only used in combination with off-screen + // rendering. + virtual void SetDeviceScaleFactor(float device_scale_factor) = 0; + + // Returns the device scale factor. Only used in combination with off-screen + // rendering. + virtual float GetDeviceScaleFactor() const = 0; + // Returns the browser that this window contains, if any. virtual CefRefPtr GetBrowser() const = 0; diff --git a/tests/cefclient/browser/root_window_gtk.cc b/tests/cefclient/browser/root_window_gtk.cc index 686c2d683..ee85f9d35 100644 --- a/tests/cefclient/browser/root_window_gtk.cc +++ b/tests/cefclient/browser/root_window_gtk.cc @@ -192,6 +192,21 @@ void RootWindowGtk::Close(bool force) { } } +void RootWindowGtk::SetDeviceScaleFactor(float device_scale_factor) { + REQUIRE_MAIN_THREAD(); + + if (browser_window_) + browser_window_->SetDeviceScaleFactor(device_scale_factor); +} + +float RootWindowGtk::GetDeviceScaleFactor() const { + REQUIRE_MAIN_THREAD(); + + if (browser_window_) + return browser_window_->GetDeviceScaleFactor(); + return 1.0f; +} + CefRefPtr RootWindowGtk::GetBrowser() const { REQUIRE_MAIN_THREAD(); @@ -608,9 +623,8 @@ GtkWidget* RootWindowGtk::CreateMenuBar() { AddMenuEntry(test_menu, "Zoom Out", ID_TESTS_ZOOM_OUT); AddMenuEntry(test_menu, "Zoom Reset", ID_TESTS_ZOOM_RESET); if (with_osr_) { - AddMenuEntry(test_menu, "FPS Increase", ID_TESTS_FPS_INCREASE); - AddMenuEntry(test_menu, "FPS Decrease", ID_TESTS_FPS_DECREASE); - AddMenuEntry(test_menu, "FPS Reset", ID_TESTS_FPS_RESET); + AddMenuEntry(test_menu, "Set FPS", ID_TESTS_OSR_FPS); + AddMenuEntry(test_menu, "Set Scale Factor", ID_TESTS_OSR_DSF); } AddMenuEntry(test_menu, "Begin Tracing", ID_TESTS_TRACING_BEGIN); AddMenuEntry(test_menu, "End Tracing", ID_TESTS_TRACING_END); diff --git a/tests/cefclient/browser/root_window_gtk.h b/tests/cefclient/browser/root_window_gtk.h index 8bb20bac6..f446c3663 100644 --- a/tests/cefclient/browser/root_window_gtk.h +++ b/tests/cefclient/browser/root_window_gtk.h @@ -43,6 +43,8 @@ class RootWindowGtk : public RootWindow, void Hide() OVERRIDE; void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE; void Close(bool force) OVERRIDE; + void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE; + float GetDeviceScaleFactor() const OVERRIDE; CefRefPtr GetBrowser() const OVERRIDE; ClientWindowHandle GetWindowHandle() const OVERRIDE; diff --git a/tests/cefclient/browser/root_window_mac.h b/tests/cefclient/browser/root_window_mac.h index 601b16005..33399f066 100644 --- a/tests/cefclient/browser/root_window_mac.h +++ b/tests/cefclient/browser/root_window_mac.h @@ -43,6 +43,8 @@ class RootWindowMac : public RootWindow, void Hide() OVERRIDE; void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE; void Close(bool force) OVERRIDE; + void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE; + float GetDeviceScaleFactor() const OVERRIDE; CefRefPtr GetBrowser() const OVERRIDE; ClientWindowHandle GetWindowHandle() const OVERRIDE; diff --git a/tests/cefclient/browser/root_window_mac.mm b/tests/cefclient/browser/root_window_mac.mm index 146d2ff52..458a90b52 100644 --- a/tests/cefclient/browser/root_window_mac.mm +++ b/tests/cefclient/browser/root_window_mac.mm @@ -395,6 +395,21 @@ void RootWindowMac::Close(bool force) { } } +void RootWindowMac::SetDeviceScaleFactor(float device_scale_factor) { + REQUIRE_MAIN_THREAD(); + + if (browser_window_) + browser_window_->SetDeviceScaleFactor(device_scale_factor); +} + +float RootWindowMac::GetDeviceScaleFactor() const { + REQUIRE_MAIN_THREAD(); + + if (browser_window_) + return browser_window_->GetDeviceScaleFactor(); + return 1.0f; +} + CefRefPtr RootWindowMac::GetBrowser() const { REQUIRE_MAIN_THREAD(); diff --git a/tests/cefclient/browser/root_window_win.cc b/tests/cefclient/browser/root_window_win.cc index 0591d6e90..2458d984d 100644 --- a/tests/cefclient/browser/root_window_win.cc +++ b/tests/cefclient/browser/root_window_win.cc @@ -9,6 +9,7 @@ #include "include/cef_app.h" #include "cefclient/browser/browser_window_osr_win.h" #include "cefclient/browser/browser_window_std_win.h" +#include "cefclient/browser/geometry_util.h" #include "cefclient/browser/main_context.h" #include "cefclient/browser/main_message_loop.h" #include "cefclient/browser/resource.h" @@ -209,7 +210,7 @@ void RootWindowWin::SetBounds(int x, int y, size_t width, size_t height) { REQUIRE_MAIN_THREAD(); if (hwnd_) - SetWindowPos(hwnd_, NULL, 0, 0, 0, 0, SWP_NOZORDER); + SetWindowPos(hwnd_, NULL, x, y, width, height, SWP_NOZORDER); } void RootWindowWin::Close(bool force) { @@ -223,6 +224,21 @@ void RootWindowWin::Close(bool force) { } } +void RootWindowWin::SetDeviceScaleFactor(float device_scale_factor) { + REQUIRE_MAIN_THREAD(); + + if (browser_window_) + browser_window_->SetDeviceScaleFactor(device_scale_factor); +} + +float RootWindowWin::GetDeviceScaleFactor() const { + REQUIRE_MAIN_THREAD(); + + if (browser_window_) + return browser_window_->GetDeviceScaleFactor(); + return client::GetDeviceScaleFactor(); +} + CefRefPtr RootWindowWin::GetBrowser() const { REQUIRE_MAIN_THREAD(); @@ -307,7 +323,8 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) { static int button_width = GetButtonWidth(); static int urlbar_height = GetURLBarHeight(); - static int font_height = LogicalToDevice(14, GetDeviceScaleFactor()); + static int font_height = + LogicalToDevice(14, client::GetDeviceScaleFactor()); // Create a scaled font. font_ = ::CreateFont( @@ -376,9 +393,8 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) { if (hMenu) { HMENU hTestMenu = ::GetSubMenu(hMenu, 2); if (hTestMenu) { - ::RemoveMenu(hTestMenu, ID_TESTS_FPS_INCREASE, MF_BYCOMMAND); - ::RemoveMenu(hTestMenu, ID_TESTS_FPS_DECREASE, MF_BYCOMMAND); - ::RemoveMenu(hTestMenu, ID_TESTS_FPS_RESET, MF_BYCOMMAND); + ::RemoveMenu(hTestMenu, ID_TESTS_OSR_FPS, MF_BYCOMMAND); + ::RemoveMenu(hTestMenu, ID_TESTS_OSR_DSF, MF_BYCOMMAND); } } } diff --git a/tests/cefclient/browser/root_window_win.h b/tests/cefclient/browser/root_window_win.h index 7bf114344..833373c30 100644 --- a/tests/cefclient/browser/root_window_win.h +++ b/tests/cefclient/browser/root_window_win.h @@ -45,6 +45,8 @@ class RootWindowWin : public RootWindow, void Hide() OVERRIDE; void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE; void Close(bool force) OVERRIDE; + void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE; + float GetDeviceScaleFactor() const OVERRIDE; CefRefPtr GetBrowser() const OVERRIDE; ClientWindowHandle GetWindowHandle() const OVERRIDE; diff --git a/tests/cefclient/browser/test_runner.cc b/tests/cefclient/browser/test_runner.cc index bc0184184..579fc952c 100644 --- a/tests/cefclient/browser/test_runner.cc +++ b/tests/cefclient/browser/test_runner.cc @@ -171,27 +171,113 @@ void ModifyZoom(CefRefPtr browser, double delta) { browser->GetHost()->GetZoomLevel() + delta); } -void ModifyFPS(CefRefPtr browser, int fps_delta) { +const char kPrompt[] = "Prompt."; +const char kPromptFPS[] = "FPS"; +const char kPromptDSF[] = "DSF"; + +// Handles execution of prompt results. +class PromptHandler : public CefMessageRouterBrowserSide::Handler { + public: + PromptHandler() {} + + // Called due to cefQuery execution. + virtual bool OnQuery(CefRefPtr browser, + CefRefPtr frame, + int64 query_id, + const CefString& request, + bool persistent, + CefRefPtr callback) OVERRIDE { + // Parse |request| which takes the form "Prompt.[type]:[value]". + const std::string& request_str = request; + if (request_str.find(kPrompt) != 0) + return false; + + std::string type = request_str.substr(sizeof(kPrompt) - 1); + size_t delim = type.find(':'); + if (delim == std::string::npos) + return false; + + const std::string& value = type.substr(delim + 1); + type = type.substr(0, delim); + + // Canceling the prompt dialog returns a value of "null". + if (value != "null") { + if (type == kPromptFPS) + SetFPS(browser, atoi(value.c_str())); + else if (type == kPromptDSF) + SetDSF(browser, static_cast(atof(value.c_str()))); + } + + // Nothing is done with the response. + callback->Success(CefString()); + return true; + } + + private: + void SetFPS(CefRefPtr browser, int fps) { + if (fps <= 0) { + // Reset to the default value. + CefBrowserSettings settings; + MainContext::Get()->PopulateBrowserSettings(&settings); + fps = settings.windowless_frame_rate; + } + + browser->GetHost()->SetWindowlessFrameRate(fps); + } + + void SetDSF(CefRefPtr browser, float dsf) { + MainMessageLoop::Get()->PostClosure( + base::Bind(&PromptHandler::SetDSFOnMainThread, browser, dsf)); + } + + static void SetDSFOnMainThread(CefRefPtr browser, float dsf) { + RootWindow::GetForBrowser(browser->GetIdentifier())-> + SetDeviceScaleFactor(dsf); + } +}; + +void Prompt(CefRefPtr browser, + const std::string& type, + const std::string& label, + const std::string& default_value) { + // Prompt the user for a new value. Works as follows: + // 1. Show a prompt() dialog via JavaScript. + // 2. Pass the result to window.cefQuery(). + // 3. Handle the result in PromptHandler::OnQuery. + const std::string& code = + "window.cefQuery({'request': '" + std::string(kPrompt) + type + + ":' + prompt('" + label + "', '" + default_value + "')});"; + browser->GetMainFrame()->ExecuteJavaScript( + code, browser->GetMainFrame()->GetURL(), 0); +} + +void PromptFPS(CefRefPtr browser) { if (!CefCurrentlyOn(TID_UI)) { // Execute on the UI thread. - CefPostTask(TID_UI, base::Bind(&ModifyFPS, browser, fps_delta)); + CefPostTask(TID_UI, base::Bind(&PromptFPS, browser)); return; } - int fps; - if (fps_delta == 0) { - // Reset to the default value. - CefBrowserSettings settings; - MainContext::Get()->PopulateBrowserSettings(&settings); - fps = settings.windowless_frame_rate; - } else { - // Modify the existing value. - fps = browser->GetHost()->GetWindowlessFrameRate() + fps_delta; - if (fps <= 0) - fps = 1; + // Format the default value string. + std::stringstream ss; + ss << browser->GetHost()->GetWindowlessFrameRate(); + + Prompt(browser, kPromptFPS, "Enter FPS", ss.str()); +} + +void PromptDSF(CefRefPtr browser) { + if (!MainMessageLoop::Get()->RunsTasksOnCurrentThread()) { + // Execute on the main thread. + MainMessageLoop::Get()->PostClosure(base::Bind(&PromptDSF, browser)); + return; } - browser->GetHost()->SetWindowlessFrameRate(fps); + // Format the default value string. + std::stringstream ss; + ss << RootWindow::GetForBrowser(browser->GetIdentifier())-> + GetDeviceScaleFactor(); + + Prompt(browser, kPromptDSF, "Enter Device Scale Factor", ss.str()); } void BeginTracing() { @@ -437,14 +523,11 @@ void RunTest(CefRefPtr browser, int id) { case ID_TESTS_ZOOM_RESET: browser->GetHost()->SetZoomLevel(0.0); break; - case ID_TESTS_FPS_INCREASE: - ModifyFPS(browser, 10); + case ID_TESTS_OSR_FPS: + PromptFPS(browser); break; - case ID_TESTS_FPS_DECREASE: - ModifyFPS(browser, -10); - break; - case ID_TESTS_FPS_RESET: - ModifyFPS(browser, 0); + case ID_TESTS_OSR_DSF: + PromptDSF(browser); break; case ID_TESTS_TRACING_BEGIN: BeginTracing(); @@ -616,6 +699,8 @@ void Alert(CefRefPtr browser, const std::string& message) { } void CreateMessageHandlers(MessageHandlerSet& handlers) { + handlers.insert(new PromptHandler); + // Create the dialog test handlers. dialog_test::CreateMessageHandlers(handlers); diff --git a/tests/cefclient/browser/util_win.cc b/tests/cefclient/browser/util_win.cc index fb14d4a1b..3e7ebb2b9 100644 --- a/tests/cefclient/browser/util_win.cc +++ b/tests/cefclient/browser/util_win.cc @@ -157,33 +157,4 @@ float GetDeviceScaleFactor() { return scale_factor; } -int LogicalToDevice(int value, float device_scale_factor) { - float scaled_val = static_cast(value) * device_scale_factor; - return static_cast(std::floor(scaled_val)); -} - -CefRect LogicalToDevice(const CefRect& value, float device_scale_factor) { - return CefRect(LogicalToDevice(value.x, device_scale_factor), - LogicalToDevice(value.y, device_scale_factor), - LogicalToDevice(value.width, device_scale_factor), - LogicalToDevice(value.height, device_scale_factor)); -} - -int DeviceToLogical(int value, float device_scale_factor) { - float scaled_val = static_cast(value) / device_scale_factor; - return static_cast(std::floor(scaled_val)); -} - -CefRect DeviceToLogical(const CefRect& value, float device_scale_factor) { - return CefRect(DeviceToLogical(value.x, device_scale_factor), - DeviceToLogical(value.y, device_scale_factor), - DeviceToLogical(value.width, device_scale_factor), - DeviceToLogical(value.height, device_scale_factor)); -} - -void DeviceToLogical(CefMouseEvent& value, float device_scale_factor) { - value.x = DeviceToLogical(value.x, device_scale_factor); - value.y = DeviceToLogical(value.y, device_scale_factor); -} - } // namespace client diff --git a/tests/cefclient/browser/util_win.h b/tests/cefclient/browser/util_win.h index c7b37d387..ea01bde26 100644 --- a/tests/cefclient/browser/util_win.h +++ b/tests/cefclient/browser/util_win.h @@ -36,15 +36,6 @@ bool IsKeyDown(WPARAM wparam); // return 2.0. float GetDeviceScaleFactor(); -// Convert |value| from logical coordinates to device coordinates. -int LogicalToDevice(int value, float device_scale_factor); -CefRect LogicalToDevice(const CefRect& value, float device_scale_factor); - -// Convert |value| from device coordinates to logical coordinates. -int DeviceToLogical(int value, float device_scale_factor); -CefRect DeviceToLogical(const CefRect& value, float device_scale_factor); -void DeviceToLogical(CefMouseEvent& value, float device_scale_factor); - } // namespace client #endif // CEF_TESTS_CEFCLIENT_BROWSER_UTIL_WIN_H_ diff --git a/tests/cefclient/cefclient_mac.mm b/tests/cefclient/cefclient_mac.mm index 907dedd76..1d2cf7785 100644 --- a/tests/cefclient/cefclient_mac.mm +++ b/tests/cefclient/cefclient_mac.mm @@ -136,9 +136,8 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) { AddMenuItem(testMenu, @"Zoom Out", ID_TESTS_ZOOM_OUT); AddMenuItem(testMenu, @"Zoom Reset", ID_TESTS_ZOOM_RESET); if (with_osr_) { - AddMenuItem(testMenu, @"FPS Increase", ID_TESTS_FPS_INCREASE); - AddMenuItem(testMenu, @"FPS Decrease", ID_TESTS_FPS_DECREASE); - AddMenuItem(testMenu, @"FPS Reset", ID_TESTS_FPS_RESET); + AddMenuItem(testMenu, @"Set FPS", ID_TESTS_OSR_FPS); + AddMenuItem(testMenu, @"Set Scale Factor", ID_TESTS_OSR_DSF); } AddMenuItem(testMenu, @"Begin Tracing", ID_TESTS_TRACING_BEGIN); AddMenuItem(testMenu, @"End Tracing", ID_TESTS_TRACING_END); diff --git a/tests/cefclient/resources/win/cefclient.rc b/tests/cefclient/resources/win/cefclient.rc index 8a1997a1d..1c50aad03 100644 --- a/tests/cefclient/resources/win/cefclient.rc +++ b/tests/cefclient/resources/win/cefclient.rc @@ -82,9 +82,8 @@ BEGIN MENUITEM "Zoom In", ID_TESTS_ZOOM_IN MENUITEM "Zoom Out", ID_TESTS_ZOOM_OUT MENUITEM "Zoom Reset", ID_TESTS_ZOOM_RESET - MENUITEM "FPS Increase", ID_TESTS_FPS_INCREASE - MENUITEM "FPS Decrease", ID_TESTS_FPS_DECREASE - MENUITEM "FPS Reset", ID_TESTS_FPS_RESET + MENUITEM "Set FPS", ID_TESTS_OSR_FPS + MENUITEM "Set Scale Factor", ID_TESTS_OSR_DSF MENUITEM "Begin Tracing", ID_TESTS_TRACING_BEGIN MENUITEM "End Tracing", ID_TESTS_TRACING_END MENUITEM "Print", ID_TESTS_PRINT