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

Side by Side Diff: ui/views/widget/desktop_aura/desktop_screen_x11.cc

Issue 2963033002: Linux UI: Dynamically respond to changes in the scale factor (Closed)
Patch Set: LinuxUI may not exist in test scenarios Created 3 years, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/widget/desktop_aura/desktop_screen_x11.h" 5 #include "ui/views/widget/desktop_aura/desktop_screen_x11.h"
6 6
7 #include <X11/extensions/Xrandr.h> 7 #include <X11/extensions/Xrandr.h>
8 #include <X11/Xlib.h> 8 #include <X11/Xlib.h>
9 9
10 // It clashes with out RootWindow. 10 // It clashes with out RootWindow.
11 #undef RootWindow 11 #undef RootWindow
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/threading/thread_task_runner_handle.h"
14 #include "base/trace_event/trace_event.h" 15 #include "base/trace_event/trace_event.h"
15 #include "ui/aura/window.h" 16 #include "ui/aura/window.h"
16 #include "ui/aura/window_event_dispatcher.h" 17 #include "ui/aura/window_event_dispatcher.h"
17 #include "ui/aura/window_tree_host.h" 18 #include "ui/aura/window_tree_host.h"
18 #include "ui/base/layout.h" 19 #include "ui/base/layout.h"
19 #include "ui/display/display.h" 20 #include "ui/display/display.h"
20 #include "ui/display/display_finder.h" 21 #include "ui/display/display_finder.h"
21 #include "ui/display/screen.h" 22 #include "ui/display/screen.h"
22 #include "ui/display/util/display_util.h" 23 #include "ui/display/util/display_util.h"
23 #include "ui/display/util/x11/edid_parser_x11.h" 24 #include "ui/display/util/x11/edid_parser_x11.h"
24 #include "ui/events/platform/platform_event_source.h" 25 #include "ui/events/platform/platform_event_source.h"
25 #include "ui/events/platform/x11/x11_event_source.h" 26 #include "ui/events/platform/x11/x11_event_source.h"
26 #include "ui/gfx/font_render_params.h" 27 #include "ui/gfx/font_render_params.h"
27 #include "ui/gfx/geometry/point_conversions.h" 28 #include "ui/gfx/geometry/point_conversions.h"
28 #include "ui/gfx/geometry/size_conversions.h" 29 #include "ui/gfx/geometry/size_conversions.h"
29 #include "ui/gfx/icc_profile.h" 30 #include "ui/gfx/icc_profile.h"
30 #include "ui/gfx/native_widget_types.h" 31 #include "ui/gfx/native_widget_types.h"
31 #include "ui/gfx/x/x11_atom_cache.h" 32 #include "ui/gfx/x/x11_atom_cache.h"
32 #include "ui/gfx/x/x11_types.h" 33 #include "ui/gfx/x/x11_types.h"
33 #include "ui/views/linux_ui/linux_ui.h" 34 #include "ui/views/linux_ui/linux_ui.h"
34 #include "ui/views/widget/desktop_aura/desktop_screen.h" 35 #include "ui/views/widget/desktop_aura/desktop_screen.h"
35 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" 36 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
36 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h" 37 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
37 38
38 namespace { 39 namespace {
39 40
40 // The delay to perform configuration after RRNotify. See the comment
41 // in |Dispatch()|.
42 const int64_t kConfigureDelayMs = 500;
43
44 double GetDeviceScaleFactor() { 41 double GetDeviceScaleFactor() {
45 float device_scale_factor = 1.0f; 42 float device_scale_factor = 1.0f;
46 if (views::LinuxUI::instance()) { 43 if (views::LinuxUI::instance()) {
47 device_scale_factor = 44 device_scale_factor =
48 views::LinuxUI::instance()->GetDeviceScaleFactor(); 45 views::LinuxUI::instance()->GetDeviceScaleFactor();
49 } else if (display::Display::HasForceDeviceScaleFactor()) { 46 } else if (display::Display::HasForceDeviceScaleFactor()) {
50 device_scale_factor = display::Display::GetForcedDeviceScaleFactor(); 47 device_scale_factor = display::Display::GetForcedDeviceScaleFactor();
51 } 48 }
52 return device_scale_factor; 49 return device_scale_factor;
53 } 50 }
(...skipping 30 matching lines...) Expand all
84 namespace views { 81 namespace views {
85 82
86 //////////////////////////////////////////////////////////////////////////////// 83 ////////////////////////////////////////////////////////////////////////////////
87 // DesktopScreenX11, public: 84 // DesktopScreenX11, public:
88 85
89 DesktopScreenX11::DesktopScreenX11() 86 DesktopScreenX11::DesktopScreenX11()
90 : xdisplay_(gfx::GetXDisplay()), 87 : xdisplay_(gfx::GetXDisplay()),
91 x_root_window_(DefaultRootWindow(xdisplay_)), 88 x_root_window_(DefaultRootWindow(xdisplay_)),
92 has_xrandr_(false), 89 has_xrandr_(false),
93 xrandr_event_base_(0), 90 xrandr_event_base_(0),
94 primary_display_index_(0) { 91 primary_display_index_(0),
92 weak_factory_(this) {
93 if (views::LinuxUI::instance())
94 views::LinuxUI::instance()->AddDeviceScaleFactorObserver(this);
95 // We only support 1.3+. There were library changes before this and we should 95 // We only support 1.3+. There were library changes before this and we should
96 // use the new interface instead of the 1.2 one. 96 // use the new interface instead of the 1.2 one.
97 int randr_version_major = 0; 97 int randr_version_major = 0;
98 int randr_version_minor = 0; 98 int randr_version_minor = 0;
99 has_xrandr_ = XRRQueryVersion( 99 has_xrandr_ = XRRQueryVersion(
100 xdisplay_, &randr_version_major, &randr_version_minor) && 100 xdisplay_, &randr_version_major, &randr_version_minor) &&
101 randr_version_major == 1 && 101 randr_version_major == 1 &&
102 randr_version_minor >= 3; 102 randr_version_minor >= 3;
103 103
104 if (has_xrandr_) { 104 if (has_xrandr_) {
105 int error_base_ignored = 0; 105 int error_base_ignored = 0;
106 XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored); 106 XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored);
107 107
108 if (ui::PlatformEventSource::GetInstance()) 108 if (ui::PlatformEventSource::GetInstance())
109 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); 109 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
110 XRRSelectInput(xdisplay_, 110 XRRSelectInput(xdisplay_,
111 x_root_window_, 111 x_root_window_,
112 RRScreenChangeNotifyMask | 112 RRScreenChangeNotifyMask |
113 RROutputChangeNotifyMask | 113 RROutputChangeNotifyMask |
114 RRCrtcChangeNotifyMask); 114 RRCrtcChangeNotifyMask);
115 115
116 SetDisplaysInternal(BuildDisplaysFromXRandRInfo()); 116 SetDisplaysInternal(BuildDisplaysFromXRandRInfo());
117 } else { 117 } else {
118 SetDisplaysInternal(GetFallbackDisplayList()); 118 SetDisplaysInternal(GetFallbackDisplayList());
119 } 119 }
120 } 120 }
121 121
122 DesktopScreenX11::~DesktopScreenX11() { 122 DesktopScreenX11::~DesktopScreenX11() {
123 if (views::LinuxUI::instance())
124 views::LinuxUI::instance()->AddDeviceScaleFactorObserver(this);
123 if (has_xrandr_ && ui::PlatformEventSource::GetInstance()) 125 if (has_xrandr_ && ui::PlatformEventSource::GetInstance())
124 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); 126 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
125 } 127 }
126 128
127 //////////////////////////////////////////////////////////////////////////////// 129 ////////////////////////////////////////////////////////////////////////////////
128 // DesktopScreenX11, display::Screen implementation: 130 // DesktopScreenX11, display::Screen implementation:
129 131
130 gfx::Point DesktopScreenX11::GetCursorScreenPoint() { 132 gfx::Point DesktopScreenX11::GetCursorScreenPoint() {
131 TRACE_EVENT0("views", "DesktopScreenX11::GetCursorScreenPoint()"); 133 TRACE_EVENT0("views", "DesktopScreenX11::GetCursorScreenPoint()");
132 134
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA")); 242 event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA"));
241 } 243 }
242 244
243 uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) { 245 uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) {
244 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) { 246 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) {
245 // Pass the event through to xlib. 247 // Pass the event through to xlib.
246 XRRUpdateConfiguration(event); 248 XRRUpdateConfiguration(event);
247 } else if (event->type - xrandr_event_base_ == RRNotify || 249 } else if (event->type - xrandr_event_base_ == RRNotify ||
248 (event->type == PropertyNotify && 250 (event->type == PropertyNotify &&
249 event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA"))) { 251 event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA"))) {
250 // There's some sort of observer dispatch going on here, but I don't think 252 RestartDelayedConfigurationTask();
251 // it's the screen's?
252 if (configure_timer_.get() && configure_timer_->IsRunning()) {
253 configure_timer_->Reset();
254 } else {
255 configure_timer_.reset(new base::OneShotTimer());
256 configure_timer_->Start(
257 FROM_HERE,
258 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
259 this,
260 &DesktopScreenX11::ConfigureTimerFired);
261 }
262 } else { 253 } else {
263 NOTREACHED(); 254 NOTREACHED();
264 } 255 }
265 256
266 return ui::POST_DISPATCH_NONE; 257 return ui::POST_DISPATCH_NONE;
267 } 258 }
268 259
260 void DesktopScreenX11::OnDeviceScaleFactorChanged() {
261 RestartDelayedConfigurationTask();
262 }
263
269 // static 264 // static
270 void DesktopScreenX11::UpdateDeviceScaleFactorForTest() { 265 void DesktopScreenX11::UpdateDeviceScaleFactorForTest() {
271 DesktopScreenX11* screen = 266 DesktopScreenX11* screen =
272 static_cast<DesktopScreenX11*>(display::Screen::GetScreen()); 267 static_cast<DesktopScreenX11*>(display::Screen::GetScreen());
273 screen->ConfigureTimerFired(); 268 screen->UpdateDisplays();
274 } 269 }
275 270
276 //////////////////////////////////////////////////////////////////////////////// 271 ////////////////////////////////////////////////////////////////////////////////
277 // DesktopScreenX11, private: 272 // DesktopScreenX11, private:
278 273
279 DesktopScreenX11::DesktopScreenX11( 274 DesktopScreenX11::DesktopScreenX11(
280 const std::vector<display::Display>& test_displays) 275 const std::vector<display::Display>& test_displays)
281 : xdisplay_(gfx::GetXDisplay()), 276 : xdisplay_(gfx::GetXDisplay()),
282 x_root_window_(DefaultRootWindow(xdisplay_)), 277 x_root_window_(DefaultRootWindow(xdisplay_)),
283 has_xrandr_(false), 278 has_xrandr_(false),
284 xrandr_event_base_(0), 279 xrandr_event_base_(0),
285 displays_(test_displays), 280 displays_(test_displays),
286 primary_display_index_(0) {} 281 primary_display_index_(0),
282 weak_factory_(this) {
283 if (views::LinuxUI::instance())
284 views::LinuxUI::instance()->AddDeviceScaleFactorObserver(this);
285 }
287 286
288 std::vector<display::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() { 287 std::vector<display::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
289 std::vector<display::Display> displays; 288 std::vector<display::Display> displays;
290 gfx::XScopedPtr< 289 gfx::XScopedPtr<
291 XRRScreenResources, 290 XRRScreenResources,
292 gfx::XObjectDeleter<XRRScreenResources, void, XRRFreeScreenResources>> 291 gfx::XObjectDeleter<XRRScreenResources, void, XRRFreeScreenResources>>
293 resources(XRRGetScreenResourcesCurrent(xdisplay_, x_root_window_)); 292 resources(XRRGetScreenResourcesCurrent(xdisplay_, x_root_window_));
294 if (!resources) { 293 if (!resources) {
295 LOG(ERROR) << "XRandR returned no displays. Falling back to Root Window."; 294 LOG(ERROR) << "XRandR returned no displays. Falling back to Root Window.";
296 return GetFallbackDisplayList(); 295 return GetFallbackDisplayList();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 displays.push_back(display); 382 displays.push_back(display);
384 } 383 }
385 } 384 }
386 385
387 if (displays.empty()) 386 if (displays.empty())
388 return GetFallbackDisplayList(); 387 return GetFallbackDisplayList();
389 388
390 return displays; 389 return displays;
391 } 390 }
392 391
393 void DesktopScreenX11::ConfigureTimerFired() { 392 void DesktopScreenX11::RestartDelayedConfigurationTask() {
393 delayed_configuration_task_.Reset(base::Bind(
394 &DesktopScreenX11::UpdateDisplays, weak_factory_.GetWeakPtr()));
395 base::ThreadTaskRunnerHandle::Get()->PostTask(
396 FROM_HERE, delayed_configuration_task_.callback());
397 }
398
399 void DesktopScreenX11::UpdateDisplays() {
394 std::vector<display::Display> old_displays = displays_; 400 std::vector<display::Display> old_displays = displays_;
395 SetDisplaysInternal(BuildDisplaysFromXRandRInfo()); 401 SetDisplaysInternal(BuildDisplaysFromXRandRInfo());
396 change_notifier_.NotifyDisplaysChanged(old_displays, displays_); 402 change_notifier_.NotifyDisplaysChanged(old_displays, displays_);
397 } 403 }
398 404
399 void DesktopScreenX11::SetDisplaysInternal( 405 void DesktopScreenX11::SetDisplaysInternal(
400 const std::vector<display::Display>& displays) { 406 const std::vector<display::Display>& displays) {
401 displays_ = displays; 407 displays_ = displays;
402 gfx::SetFontRenderParamsDeviceScaleFactor( 408 gfx::SetFontRenderParamsDeviceScaleFactor(
403 GetPrimaryDisplay().device_scale_factor()); 409 GetPrimaryDisplay().device_scale_factor());
404 } 410 }
405 411
406 //////////////////////////////////////////////////////////////////////////////// 412 ////////////////////////////////////////////////////////////////////////////////
407 413
408 display::Screen* CreateDesktopScreen() { 414 display::Screen* CreateDesktopScreen() {
409 return new DesktopScreenX11; 415 return new DesktopScreenX11;
410 } 416 }
411 417
412 } // namespace views 418 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_screen_x11.h ('k') | ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698