cefclient: Support dynamic configuration of the device scale factor with off-screen rendering (issue #1674)

This commit is contained in:
Marshall Greenblatt 2015-08-10 16:49:45 -04:00
parent 41669141eb
commit a08686e6a6
26 changed files with 580 additions and 244 deletions

View File

@ -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',

View File

@ -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<CefBrowser> BrowserWindow::GetBrowser() const {
REQUIRE_MAIN_THREAD();
return browser_;

View File

@ -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;

View File

@ -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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> browser,
@ -1095,7 +1130,7 @@ void BrowserWindowOsrGtk::OnPopupSize(CefRefPtr<CefBrowser> 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;

View File

@ -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);
};

View File

@ -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.

View File

@ -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<CefDragData> 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<NSDraggingInfo>)info;
- (int)getModifiersForEvent:(NSEvent*)event;
- (BOOL)isKeyUpEvent:(NSEvent*)event;
- (BOOL)isKeyPadEvent:(NSEvent*)event;
@ -85,6 +92,8 @@ extern NSString* const NSWindowDidChangeBackingPropertiesNotification;
- (void)populateDropData:(CefRefPtr<CefDragData>)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<NSDraggingInfo>)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<CefBrowser> 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 <NSDraggingInfo>)info {
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
CefRefPtr<CefBrowser> 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<CefBrowserHost::DragOperationsMask>(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 <NSDraggingInfo>)sender {
- (void)draggingExited:(id<NSDraggingInfo>)sender {
CefRefPtr<CefBrowser> browser = [self getBrowser];
if (browser.get())
browser->GetHost()->DragTargetDragLeave();
}
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)info {
- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)info {
return YES;
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)info {
- (BOOL)performDragOperation:(id<NSDraggingInfo>)info {
CefRefPtr<CefBrowser> 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<CefBrowserHost::DragOperationsMask>(mask);
browser->GetHost()->DragTargetDragOver(ev, allowed_ops);
static_cast<CefBrowserHost::DragOperationsMask>(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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<NSDragOperation>(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 =

View File

@ -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_;

View File

@ -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<OsrWindowWin> osr_window_;
HWND osr_hwnd_;
float device_scale_factor_;
DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrWin);
};

View File

@ -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 <cmath>
namespace client {
int LogicalToDevice(int value, float device_scale_factor) {
float scaled_val = static_cast<float>(value) * device_scale_factor;
return static_cast<int>(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<float>(value) / device_scale_factor;
return static_cast<int>(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

View File

@ -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_

View File

@ -7,6 +7,7 @@
#include <windowsx.h>
#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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefDragData> 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);
}

View File

@ -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<CefBrowser> browser_;

View File

@ -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

View File

@ -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<CefBrowser> GetBrowser() const = 0;

View File

@ -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<CefBrowser> 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);

View File

@ -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<CefBrowser> GetBrowser() const OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;

View File

@ -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<CefBrowser> GetBrowser() const OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;

View File

@ -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<CefBrowser> RootWindowMac::GetBrowser() const {
REQUIRE_MAIN_THREAD();

View File

@ -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<CefBrowser> 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);
}
}
}

View File

@ -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<CefBrowser> GetBrowser() const OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;

View File

@ -171,27 +171,113 @@ void ModifyZoom(CefRefPtr<CefBrowser> browser, double delta) {
browser->GetHost()->GetZoomLevel() + delta);
}
void ModifyFPS(CefRefPtr<CefBrowser> 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<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> 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<float>(atof(value.c_str())));
}
// Nothing is done with the response.
callback->Success(CefString());
return true;
}
private:
void SetFPS(CefRefPtr<CefBrowser> 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<CefBrowser> browser, float dsf) {
MainMessageLoop::Get()->PostClosure(
base::Bind(&PromptHandler::SetDSFOnMainThread, browser, dsf));
}
static void SetDSFOnMainThread(CefRefPtr<CefBrowser> browser, float dsf) {
RootWindow::GetForBrowser(browser->GetIdentifier())->
SetDeviceScaleFactor(dsf);
}
};
void Prompt(CefRefPtr<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> browser, const std::string& message) {
}
void CreateMessageHandlers(MessageHandlerSet& handlers) {
handlers.insert(new PromptHandler);
// Create the dialog test handlers.
dialog_test::CreateMessageHandlers(handlers);

View File

@ -157,33 +157,4 @@ float GetDeviceScaleFactor() {
return scale_factor;
}
int LogicalToDevice(int value, float device_scale_factor) {
float scaled_val = static_cast<float>(value) * device_scale_factor;
return static_cast<int>(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<float>(value) / device_scale_factor;
return static_cast<int>(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

View File

@ -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_

View File

@ -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);

View File

@ -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