Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Unified Diff: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc

Issue 924853002: linux/x11: Fix setting window bounds in High DPI. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 3874e6705ac6083def2012a9dfbaa61fa28ffe65..4a2b0855580d986dd6772d611055455b0fad488d 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -32,6 +32,7 @@
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/display.h"
#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/path.h"
@@ -190,11 +191,11 @@ std::vector<aura::Window*> DesktopWindowTreeHostX11::GetAllOpenWindows() {
}
gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowBounds() const {
- return bounds_;
+ return bounds_in_pixels_;
}
gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const {
- gfx::Rect outer_bounds(bounds_);
+ gfx::Rect outer_bounds(bounds_in_pixels_);
outer_bounds.Inset(-native_window_frame_borders_);
return outer_bounds;
}
@@ -382,7 +383,7 @@ void DesktopWindowTreeHostX11::ShowMaximizedWithBounds(
const gfx::Rect& restored_bounds) {
ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED);
// Enforce |restored_bounds_| since calling Maximize() could have reset it.
- restored_bounds_ = restored_bounds;
+ restored_bounds_ = ToPixelRect(restored_bounds);
}
bool DesktopWindowTreeHostX11::IsVisible() const {
@@ -390,12 +391,14 @@ bool DesktopWindowTreeHostX11::IsVisible() const {
}
void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) {
- gfx::Size size = AdjustSize(requested_size);
- bool size_changed = bounds_.size() != size;
- XResizeWindow(xdisplay_, xwindow_, size.width(), size.height());
- bounds_.set_size(size);
+ gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size();
+ size_in_pixels = AdjustSize(size_in_pixels);
+ bool size_changed = bounds_in_pixels_.size() != size_in_pixels;
+ XResizeWindow(xdisplay_, xwindow_, size_in_pixels.width(),
+ size_in_pixels.height());
+ bounds_in_pixels_.set_size(size_in_pixels);
if (size_changed) {
- OnHostResized(size);
+ OnHostResized(size_in_pixels);
ResetWindowRegion();
}
}
@@ -405,27 +408,29 @@ void DesktopWindowTreeHostX11::StackAtTop() {
}
void DesktopWindowTreeHostX11::CenterWindow(const gfx::Size& size) {
- gfx::Rect parent_bounds = GetWorkAreaBoundsInScreen();
+ gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(size)).size();
+ gfx::Rect parent_bounds_in_pixels = GetWorkAreaBoundsInPixels();
- // If |window_|'s transient parent bounds are big enough to contain |size|,
- // use them instead.
+ // If |window_|'s transient parent bounds are big enough to contain
+ // |size_in_pixels|, use them instead.
if (wm::GetTransientParent(content_window_)) {
gfx::Rect transient_parent_rect =
wm::GetTransientParent(content_window_)->GetBoundsInScreen();
- if (transient_parent_rect.height() >= size.height() &&
- transient_parent_rect.width() >= size.width()) {
- parent_bounds = transient_parent_rect;
+ if (transient_parent_rect.height() >= size_in_pixels.height() &&
+ transient_parent_rect.width() >= size_in_pixels.width()) {
+ parent_bounds_in_pixels = ToPixelRect(transient_parent_rect);
}
}
gfx::Rect window_bounds(
- parent_bounds.x() + (parent_bounds.width() - size.width()) / 2,
- parent_bounds.y() + (parent_bounds.height() - size.height()) / 2,
- size.width(),
- size.height());
+ parent_bounds_in_pixels.x() +
+ (parent_bounds_in_pixels.width() - size_in_pixels.width()) / 2,
+ parent_bounds_in_pixels.y() +
+ (parent_bounds_in_pixels.height() - size_in_pixels.height()) / 2,
+ size_in_pixels.width(), size_in_pixels.height());
// Don't size the window bigger than the parent, otherwise the user may not be
// able to close or move it.
- window_bounds.AdjustToFit(parent_bounds);
+ window_bounds.AdjustToFit(parent_bounds_in_pixels);
SetBounds(window_bounds);
}
@@ -449,19 +454,19 @@ void DesktopWindowTreeHostX11::GetWindowPlacement(
}
gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const {
- return bounds_;
+ return ToDIPRect(bounds_in_pixels_);
}
gfx::Rect DesktopWindowTreeHostX11::GetClientAreaBoundsInScreen() const {
- // TODO(erg): The NativeWidgetAura version returns |bounds_|, claiming its
- // needed for View::ConvertPointToScreen() to work
- // correctly. DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just
- // asks windows what it thinks the client rect is.
+ // TODO(erg): The NativeWidgetAura version returns |bounds_in_pixels_|,
+ // claiming it's needed for View::ConvertPointToScreen() to work correctly.
+ // DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() just asks windows
+ // what it thinks the client rect is.
//
// Attempts to calculate the rect by asking the NonClientFrameView what it
// thought its GetBoundsForClientView() were broke combobox drop down
// placement.
- return bounds_;
+ return GetWindowBoundsInScreen();
}
gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const {
@@ -470,30 +475,13 @@ gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const {
// or restoring bounds, we can record the current bounds before we request
// maximization, and clear it when we detect a state change.
if (!restored_bounds_.IsEmpty())
- return restored_bounds_;
+ return ToDIPRect(restored_bounds_);
return GetWindowBoundsInScreen();
}
gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const {
- std::vector<int> value;
- if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) &&
- value.size() >= 4) {
- return gfx::Rect(value[0], value[1], value[2], value[3]);
- }
-
- // Fetch the geometry of the root window.
- Window root;
- int x, y;
- unsigned int width, height;
- unsigned int border_width, depth;
- if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y,
- &width, &height, &border_width, &depth)) {
- NOTIMPLEMENTED();
- return gfx::Rect(0, 0, 10, 10);
- }
-
- return gfx::Rect(x, y, width, height);
+ return ToDIPRect(GetWorkAreaBoundsInPixels());
}
void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) {
@@ -539,8 +527,9 @@ void DesktopWindowTreeHostX11::Maximize() {
// Resize the window so that it does not have the same size as a monitor.
// (Otherwise, some window managers immediately put the window back in
// fullscreen mode).
- gfx::Rect adjusted_bounds(bounds_.origin(), AdjustSize(bounds_.size()));
- if (adjusted_bounds != bounds_)
+ gfx::Rect adjusted_bounds(bounds_in_pixels_.origin(),
+ AdjustSize(bounds_in_pixels_.size()));
+ if (adjusted_bounds != bounds_in_pixels_)
SetBounds(adjusted_bounds);
}
@@ -551,7 +540,7 @@ void DesktopWindowTreeHostX11::Maximize() {
// When we are in the process of requesting to maximize a window, we can
// accurately keep track of our restored bounds instead of relying on the
// heuristics that are in the PropertyNotify and ConfigureNotify handlers.
- restored_bounds_ = bounds_;
+ restored_bounds_ = bounds_in_pixels_;
SetWMSpecState(true,
atom_cache_.GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
@@ -737,15 +726,15 @@ void DesktopWindowTreeHostX11::SetFullscreen(bool fullscreen) {
// synchronously.
// See https://crbug.com/361408
if (fullscreen) {
- restored_bounds_ = bounds_;
+ restored_bounds_ = bounds_in_pixels_;
const gfx::Display display =
gfx::Screen::GetScreenFor(NULL)->GetDisplayNearestWindow(window());
- bounds_ = display.bounds();
+ bounds_in_pixels_ = ToPixelRect(display.bounds());
} else {
- bounds_ = restored_bounds_;
+ bounds_in_pixels_ = restored_bounds_;
}
- OnHostMoved(bounds_.origin());
- OnHostResized(bounds_.size());
+ OnHostMoved(bounds_in_pixels_.origin());
+ OnHostResized(bounds_in_pixels_.size());
if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN") == fullscreen) {
Relayout();
@@ -862,6 +851,20 @@ void DesktopWindowTreeHostX11::SizeConstraintsChanged() {
////////////////////////////////////////////////////////////////////////////////
// DesktopWindowTreeHostX11, aura::WindowTreeHost implementation:
+gfx::Transform DesktopWindowTreeHostX11::GetRootTransform() const {
pkotwicz 2015/02/18 22:58:50 Nit: I would be tempted to query the device scale
sadrul 2015/02/18 23:33:58 Done.
+ float scale = gfx::Display::GetForcedDeviceScaleFactor();
+ if (window_mapped_) {
+ const gfx::Display display =
+ gfx::Screen::GetNativeScreen()->GetDisplayNearestPoint(
+ bounds_in_pixels_.origin());
pkotwicz 2015/02/18 22:58:50 tldr: If you plan on making ToPixelRect() / ToDIPR
sadrul 2015/02/18 23:33:58 Changed to use DisplayNearestWindow() instead.
+ scale = display.device_scale_factor();
+ }
+
+ gfx::Transform transform;
+ transform.Scale(scale, scale);
+ return transform;
+}
+
ui::EventSource* DesktopWindowTreeHostX11::GetEventSource() {
return this;
}
@@ -884,14 +887,15 @@ void DesktopWindowTreeHostX11::Hide() {
}
gfx::Rect DesktopWindowTreeHostX11::GetBounds() const {
- return bounds_;
+ return bounds_in_pixels_;
}
-void DesktopWindowTreeHostX11::SetBounds(const gfx::Rect& requested_bounds) {
- gfx::Rect bounds(requested_bounds.origin(),
- AdjustSize(requested_bounds.size()));
- bool origin_changed = bounds_.origin() != bounds.origin();
- bool size_changed = bounds_.size() != bounds.size();
+void DesktopWindowTreeHostX11::SetBounds(
+ const gfx::Rect& requested_bounds_in_pixel) {
+ gfx::Rect bounds(requested_bounds_in_pixel.origin(),
+ AdjustSize(requested_bounds_in_pixel.size()));
+ bool origin_changed = bounds_in_pixels_.origin() != bounds.origin();
+ bool size_changed = bounds_in_pixels_.size() != bounds.size();
XWindowChanges changes = {0};
unsigned value_mask = 0;
@@ -927,8 +931,8 @@ void DesktopWindowTreeHostX11::SetBounds(const gfx::Rect& requested_bounds) {
// case if we're running without a window manager. If there's a window
// manager, it can modify or ignore the request, but (per ICCCM) we'll get a
// (possibly synthetic) ConfigureNotify about the actual size and correct
- // |bounds_| later.
- bounds_ = bounds;
+ // |bounds_in_pixels_| later.
+ bounds_in_pixels_ = bounds;
if (origin_changed)
native_widget_delegate_->AsWidget()->OnNativeWidgetMove();
@@ -939,7 +943,7 @@ void DesktopWindowTreeHostX11::SetBounds(const gfx::Rect& requested_bounds) {
}
gfx::Point DesktopWindowTreeHostX11::GetLocationOnNativeScreen() const {
- return bounds_.origin();
+ return bounds_in_pixels_.origin();
}
void DesktopWindowTreeHostX11::SetCapture() {
@@ -982,7 +986,8 @@ void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) {
void DesktopWindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) {
XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0,
- bounds_.x() + location.x(), bounds_.y() + location.y());
+ bounds_in_pixels_.x() + location.x(),
+ bounds_in_pixels_.y() + location.y());
}
void DesktopWindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) {
@@ -1058,18 +1063,14 @@ void DesktopWindowTreeHostX11::InitX11Window(
}
}
- bounds_ = gfx::Rect(params.bounds.origin(),
- AdjustSize(params.bounds.size()));
- xwindow_ = XCreateWindow(
- xdisplay_, x_root_window_,
- bounds_.x(), bounds_.y(),
- bounds_.width(), bounds_.height(),
- 0, // border width
- depth,
- InputOutput,
- visual,
- attribute_mask,
- &swa);
+ bounds_in_pixels_ = ToPixelRect(params.bounds);
+ bounds_in_pixels_ = gfx::Rect(bounds_in_pixels_.origin(),
+ AdjustSize(bounds_in_pixels_.size()));
+ xwindow_ = XCreateWindow(xdisplay_, x_root_window_, bounds_in_pixels_.x(),
+ bounds_in_pixels_.y(), bounds_in_pixels_.width(),
+ bounds_in_pixels_.height(),
+ 0, // border width
+ depth, InputOutput, visual, attribute_mask, &swa);
if (ui::PlatformEventSource::GetInstance())
ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
open_windows().push_back(xwindow_);
@@ -1208,20 +1209,20 @@ void DesktopWindowTreeHostX11::InitX11Window(
}
gfx::Size DesktopWindowTreeHostX11::AdjustSize(
- const gfx::Size& requested_size) {
+ const gfx::Size& requested_size_in_pixels) {
std::vector<gfx::Display> displays =
gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)->GetAllDisplays();
// Compare against all monitor sizes. The window manager can move the window
// to whichever monitor it wants.
for (size_t i = 0; i < displays.size(); ++i) {
- if (requested_size == displays[i].size()) {
- return gfx::Size(requested_size.width() - 1,
- requested_size.height() - 1);
+ if (requested_size_in_pixels == displays[i].GetSizeInPixel()) {
+ return gfx::Size(requested_size_in_pixels.width() - 1,
+ requested_size_in_pixels.height() - 1);
}
}
// Do not request a 0x0 window size. It causes an XError.
- gfx::Size size = requested_size;
+ gfx::Size size = requested_size_in_pixels;
size.SetToMax(gfx::Size(1,1));
return size;
}
@@ -1265,10 +1266,10 @@ void DesktopWindowTreeHostX11::OnWMStateUpdated() {
DCHECK(!IsFullscreen());
if (IsMaximized()) {
// The request that we become maximized originated from a different
- // process. |bounds_| already contains our maximized bounds. Do a best
- // effort attempt to get restored bounds by setting it to our previously
- // set bounds (and if we get this wrong, we aren't any worse off since
- // we'd otherwise be returning our maximized bounds).
+ // process. |bounds_in_pixels_| already contains our maximized bounds. Do
+ // a best effort attempt to get restored bounds by setting it to our
+ // previously set bounds (and if we get this wrong, we aren't any worse
+ // off since we'd otherwise be returning our maximized bounds).
restored_bounds_ = previous_bounds_;
}
} else if (!IsMaximized() && !IsFullscreen()) {
@@ -1481,7 +1482,8 @@ void DesktopWindowTreeHostX11::ResetWindowRegion() {
if (widget->non_client_view()) {
// Some frame views define a custom (non-rectangular) window mask. If
// so, use it to define the window shape. If not, fall through.
- widget->non_client_view()->GetWindowMask(bounds_.size(), &window_mask);
+ widget->non_client_view()->GetWindowMask(bounds_in_pixels_.size(),
+ &window_mask);
if (window_mask.countPoints() > 0) {
window_shape_ = gfx::CreateRegionFromSkPath(window_mask);
XShapeCombineRegion(xdisplay_, xwindow_, ShapeBounding,
@@ -1505,8 +1507,10 @@ void DesktopWindowTreeHostX11::ResetWindowRegion() {
// is due to a bug in KWin <= 4.11.5 (KDE bug #330573) where setting a null
// shape causes the hint to disable system borders to be ignored (resulting
// in a double border).
- XRectangle r = {0, 0, static_cast<unsigned short>(bounds_.width()),
- static_cast<unsigned short>(bounds_.height())};
+ XRectangle r = {0,
+ 0,
+ static_cast<unsigned short>(bounds_in_pixels_.width()),
+ static_cast<unsigned short>(bounds_in_pixels_.height())};
XShapeCombineRectangles(
xdisplay_, xwindow_, ShapeBounding, 0, 0, &r, 1, ShapeSet, YXBanded);
}
@@ -1581,8 +1585,8 @@ void DesktopWindowTreeHostX11::MapWindow(ui::WindowShowState show_state) {
// will ignore toplevel XMoveWindow commands.
XSizeHints size_hints;
size_hints.flags = PPosition;
- size_hints.x = bounds_.x();
- size_hints.y = bounds_.y();
+ size_hints.x = bounds_in_pixels_.x();
+ size_hints.y = bounds_in_pixels_.y();
XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
// If SHOW_STATE_INACTIVE, tell the window manager not to focus the window
@@ -1742,13 +1746,13 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
}
gfx::Rect bounds(translated_x, translated_y,
xev->xconfigure.width, xev->xconfigure.height);
- bool size_changed = bounds_.size() != bounds.size();
- bool origin_changed = bounds_.origin() != bounds.origin();
- previous_bounds_ = bounds_;
- bounds_ = bounds;
+ bool size_changed = bounds_in_pixels_.size() != bounds.size();
+ bool origin_changed = bounds_in_pixels_.origin() != bounds.origin();
+ previous_bounds_ = bounds_in_pixels_;
+ bounds_in_pixels_ = bounds;
if (origin_changed)
- OnHostMoved(bounds_.origin());
+ OnHostMoved(bounds_in_pixels_.origin());
if (size_changed) {
delayed_resize_task_.Reset(base::Bind(
@@ -1930,6 +1934,41 @@ void DesktopWindowTreeHostX11::DelayedResize(const gfx::Size& size) {
delayed_resize_task_.Cancel();
}
+gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInPixels() const {
+ std::vector<int> value;
+ if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) &&
+ value.size() >= 4) {
+ return gfx::Rect(value[0], value[1], value[2], value[3]);
+ }
+
+ // Fetch the geometry of the root window.
+ Window root;
+ int x, y;
+ unsigned int width, height;
+ unsigned int border_width, depth;
+ if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, &width, &height,
+ &border_width, &depth)) {
+ NOTIMPLEMENTED();
+ return gfx::Rect(0, 0, 10, 10);
+ }
+
+ return gfx::Rect(x, y, width, height);
+}
+
+gfx::Rect DesktopWindowTreeHostX11::ToDIPRect(
+ const gfx::Rect& rect_in_pixels) const {
+ gfx::RectF rect_in_dip = rect_in_pixels;
+ GetRootTransform().TransformRectReverse(&rect_in_dip);
+ return gfx::ToEnclosingRect(rect_in_dip);
+}
+
+gfx::Rect DesktopWindowTreeHostX11::ToPixelRect(
+ const gfx::Rect& rect_in_dip) const {
+ gfx::RectF rect_in_pixels = rect_in_dip;
+ GetRootTransform().TransformRect(&rect_in_pixels);
+ return gfx::ToEnclosingRect(rect_in_pixels);
+}
+
////////////////////////////////////////////////////////////////////////////////
// DesktopWindowTreeHost, public:
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698