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

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: Call OnHostResizedInPixels() when scale factor changes 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 views::LinuxUI::instance()->AddDeviceScaleFactorObserver(this);
95 // We only support 1.3+. There were library changes before this and we should 94 // 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. 95 // use the new interface instead of the 1.2 one.
97 int randr_version_major = 0; 96 int randr_version_major = 0;
98 int randr_version_minor = 0; 97 int randr_version_minor = 0;
99 has_xrandr_ = XRRQueryVersion( 98 has_xrandr_ = XRRQueryVersion(
100 xdisplay_, &randr_version_major, &randr_version_minor) && 99 xdisplay_, &randr_version_major, &randr_version_minor) &&
101 randr_version_major == 1 && 100 randr_version_major == 1 &&
102 randr_version_minor >= 3; 101 randr_version_minor >= 3;
103 102
104 if (has_xrandr_) { 103 if (has_xrandr_) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA")); 239 event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA"));
241 } 240 }
242 241
243 uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) { 242 uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) {
244 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) { 243 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) {
245 // Pass the event through to xlib. 244 // Pass the event through to xlib.
246 XRRUpdateConfiguration(event); 245 XRRUpdateConfiguration(event);
247 } else if (event->type - xrandr_event_base_ == RRNotify || 246 } else if (event->type - xrandr_event_base_ == RRNotify ||
248 (event->type == PropertyNotify && 247 (event->type == PropertyNotify &&
249 event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA"))) { 248 event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA"))) {
250 // There's some sort of observer dispatch going on here, but I don't think 249 RestartDelayedConfigureTask();
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 { 250 } else {
263 NOTREACHED(); 251 NOTREACHED();
264 } 252 }
265 253
266 return ui::POST_DISPATCH_NONE; 254 return ui::POST_DISPATCH_NONE;
267 } 255 }
268 256
257 void DesktopScreenX11::OnDeviceScaleFactorChanged() {
258 RestartDelayedConfigureTask();
259 }
260
269 // static 261 // static
270 void DesktopScreenX11::UpdateDeviceScaleFactorForTest() { 262 void DesktopScreenX11::UpdateDeviceScaleFactorForTest() {
271 DesktopScreenX11* screen = 263 DesktopScreenX11* screen =
272 static_cast<DesktopScreenX11*>(display::Screen::GetScreen()); 264 static_cast<DesktopScreenX11*>(display::Screen::GetScreen());
273 screen->ConfigureTimerFired(); 265 screen->UpdateDisplayConfiguration();
274 } 266 }
275 267
276 //////////////////////////////////////////////////////////////////////////////// 268 ////////////////////////////////////////////////////////////////////////////////
277 // DesktopScreenX11, private: 269 // DesktopScreenX11, private:
278 270
279 DesktopScreenX11::DesktopScreenX11( 271 DesktopScreenX11::DesktopScreenX11(
280 const std::vector<display::Display>& test_displays) 272 const std::vector<display::Display>& test_displays)
281 : xdisplay_(gfx::GetXDisplay()), 273 : xdisplay_(gfx::GetXDisplay()),
282 x_root_window_(DefaultRootWindow(xdisplay_)), 274 x_root_window_(DefaultRootWindow(xdisplay_)),
283 has_xrandr_(false), 275 has_xrandr_(false),
284 xrandr_event_base_(0), 276 xrandr_event_base_(0),
285 displays_(test_displays), 277 displays_(test_displays),
286 primary_display_index_(0) {} 278 primary_display_index_(0),
279 weak_factory_(this) {}
287 280
288 std::vector<display::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() { 281 std::vector<display::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
289 std::vector<display::Display> displays; 282 std::vector<display::Display> displays;
290 gfx::XScopedPtr< 283 gfx::XScopedPtr<
291 XRRScreenResources, 284 XRRScreenResources,
292 gfx::XObjectDeleter<XRRScreenResources, void, XRRFreeScreenResources>> 285 gfx::XObjectDeleter<XRRScreenResources, void, XRRFreeScreenResources>>
293 resources(XRRGetScreenResourcesCurrent(xdisplay_, x_root_window_)); 286 resources(XRRGetScreenResourcesCurrent(xdisplay_, x_root_window_));
294 if (!resources) { 287 if (!resources) {
295 LOG(ERROR) << "XRandR returned no displays. Falling back to Root Window."; 288 LOG(ERROR) << "XRandR returned no displays. Falling back to Root Window.";
296 return GetFallbackDisplayList(); 289 return GetFallbackDisplayList();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 displays.push_back(display); 376 displays.push_back(display);
384 } 377 }
385 } 378 }
386 379
387 if (displays.empty()) 380 if (displays.empty())
388 return GetFallbackDisplayList(); 381 return GetFallbackDisplayList();
389 382
390 return displays; 383 return displays;
391 } 384 }
392 385
393 void DesktopScreenX11::ConfigureTimerFired() { 386 void DesktopScreenX11::RestartDelayedConfigureTask() {
387 delayed_configuration_task_.Reset(
388 base::Bind(&DesktopScreenX11::UpdateDisplayConfiguration,
389 weak_factory_.GetWeakPtr()));
390 base::ThreadTaskRunnerHandle::Get()->PostTask(
391 FROM_HERE, delayed_configuration_task_.callback());
392 }
393
394 void DesktopScreenX11::UpdateDisplayConfiguration() {
394 std::vector<display::Display> old_displays = displays_; 395 std::vector<display::Display> old_displays = displays_;
395 SetDisplaysInternal(BuildDisplaysFromXRandRInfo()); 396 SetDisplaysInternal(BuildDisplaysFromXRandRInfo());
396 change_notifier_.NotifyDisplaysChanged(old_displays, displays_); 397 change_notifier_.NotifyDisplaysChanged(old_displays, displays_);
397 } 398 }
398 399
399 void DesktopScreenX11::SetDisplaysInternal( 400 void DesktopScreenX11::SetDisplaysInternal(
400 const std::vector<display::Display>& displays) { 401 const std::vector<display::Display>& displays) {
401 displays_ = displays; 402 displays_ = displays;
402 gfx::SetFontRenderParamsDeviceScaleFactor( 403 gfx::SetFontRenderParamsDeviceScaleFactor(
403 GetPrimaryDisplay().device_scale_factor()); 404 GetPrimaryDisplay().device_scale_factor());
404 } 405 }
405 406
406 //////////////////////////////////////////////////////////////////////////////// 407 ////////////////////////////////////////////////////////////////////////////////
407 408
408 display::Screen* CreateDesktopScreen() { 409 display::Screen* CreateDesktopScreen() {
409 return new DesktopScreenX11; 410 return new DesktopScreenX11;
410 } 411 }
411 412
412 } // namespace views 413 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698