1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/ozone/platform/x11/x11_screen_ozone.h" 6 7 #include "ui/base/x/x11_idle_query.h" 8 #include "ui/base/x/x11_screensaver_window_finder.h" 9 #include "ui/base/x/x11_util.h" 10 #include "ui/display/display_finder.h" 11 #include "ui/display/util/display_util.h" 12 #include "ui/events/platform/x11/x11_event_source.h" 13 #include "ui/gfx/font_render_params.h" 14 #include "ui/gfx/geometry/dip_util.h" 15 #include "ui/gfx/geometry/point_conversions.h" 16 #include "ui/gfx/geometry/rect_conversions.h" 17 #include "ui/gfx/native_widget_types.h" 18 #include "ui/platform_window/x11/x11_topmost_window_finder.h" 19 #include "ui/platform_window/x11/x11_window.h" 20 #include "ui/platform_window/x11/x11_window_manager.h" 21 22 namespace ui { 23 24 namespace { 25 GetDeviceScaleFactor()26float GetDeviceScaleFactor() { 27 float device_scale_factor = 1.0f; 28 // TODO(crbug.com/891175): Implement PlatformScreen for X11 29 // Get device scale factor using scale factor and resolution like 30 // 'GtkUi::GetRawDeviceScaleFactor'. 31 if (display::Display::HasForceDeviceScaleFactor()) 32 device_scale_factor = display::Display::GetForcedDeviceScaleFactor(); 33 return device_scale_factor; 34 } 35 36 } // namespace 37 X11ScreenOzone()38X11ScreenOzone::X11ScreenOzone() 39 : window_manager_(X11WindowManager::GetInstance()), 40 x11_display_manager_(std::make_unique<XDisplayManager>(this)) { 41 DCHECK(window_manager_); 42 } 43 ~X11ScreenOzone()44X11ScreenOzone::~X11ScreenOzone() { 45 if (x11_display_manager_->IsXrandrAvailable() && 46 X11EventSource::HasInstance()) { 47 X11EventSource::GetInstance()->RemoveXEventDispatcher(this); 48 } 49 } 50 Init()51void X11ScreenOzone::Init() { 52 if (x11_display_manager_->IsXrandrAvailable() && 53 X11EventSource::HasInstance()) { 54 X11EventSource::GetInstance()->AddXEventDispatcher(this); 55 } 56 x11_display_manager_->Init(); 57 } 58 GetAllDisplays() const59const std::vector<display::Display>& X11ScreenOzone::GetAllDisplays() const { 60 return x11_display_manager_->displays(); 61 } 62 GetPrimaryDisplay() const63display::Display X11ScreenOzone::GetPrimaryDisplay() const { 64 return x11_display_manager_->GetPrimaryDisplay(); 65 } 66 GetDisplayForAcceleratedWidget(gfx::AcceleratedWidget widget) const67display::Display X11ScreenOzone::GetDisplayForAcceleratedWidget( 68 gfx::AcceleratedWidget widget) const { 69 if (widget == gfx::kNullAcceleratedWidget) 70 return GetPrimaryDisplay(); 71 72 X11Window* window = window_manager_->GetWindow(widget); 73 return window ? GetDisplayMatching(window->GetBounds()) : GetPrimaryDisplay(); 74 } 75 GetCursorScreenPoint() const76gfx::Point X11ScreenOzone::GetCursorScreenPoint() const { 77 base::Optional<gfx::Point> point_in_pixels; 78 if (ui::X11EventSource::HasInstance()) { 79 point_in_pixels = ui::X11EventSource::GetInstance() 80 ->GetRootCursorLocationFromCurrentEvent(); 81 } 82 if (!point_in_pixels) { 83 // This call is expensive so we explicitly only call it when 84 // |point_in_pixels| is not set. We note that base::Optional::value_or() 85 // would cause it to be called regardless. 86 point_in_pixels = GetCursorLocation(); 87 } 88 // TODO(danakj): Should this be rounded? Or kept as a floating point? 89 return gfx::ToFlooredPoint( 90 gfx::ConvertPointToDips(*point_in_pixels, GetDeviceScaleFactor())); 91 } 92 GetAcceleratedWidgetAtScreenPoint(const gfx::Point & point) const93gfx::AcceleratedWidget X11ScreenOzone::GetAcceleratedWidgetAtScreenPoint( 94 const gfx::Point& point) const { 95 X11TopmostWindowFinder finder; 96 return static_cast<gfx::AcceleratedWidget>(finder.FindWindowAt(point)); 97 } 98 GetLocalProcessWidgetAtPoint(const gfx::Point & point,const std::set<gfx::AcceleratedWidget> & ignore) const99gfx::AcceleratedWidget X11ScreenOzone::GetLocalProcessWidgetAtPoint( 100 const gfx::Point& point, 101 const std::set<gfx::AcceleratedWidget>& ignore) const { 102 X11TopmostWindowFinder finder; 103 return static_cast<gfx::AcceleratedWidget>( 104 finder.FindLocalProcessWindowAt(point, ignore)); 105 } 106 GetDisplayNearestPoint(const gfx::Point & point) const107display::Display X11ScreenOzone::GetDisplayNearestPoint( 108 const gfx::Point& point) const { 109 auto displays = GetAllDisplays(); 110 if (displays.size() <= 1) 111 return GetPrimaryDisplay(); 112 return *display::FindDisplayNearestPoint(displays, point); 113 } 114 GetDisplayMatching(const gfx::Rect & match_rect_in_pixels) const115display::Display X11ScreenOzone::GetDisplayMatching( 116 const gfx::Rect& match_rect_in_pixels) const { 117 gfx::Rect match_rect = gfx::ToEnclosingRect( 118 gfx::ConvertRectToDips(match_rect_in_pixels, GetDeviceScaleFactor())); 119 const display::Display* matching_display = 120 display::FindDisplayWithBiggestIntersection( 121 x11_display_manager_->displays(), match_rect); 122 return matching_display ? *matching_display : GetPrimaryDisplay(); 123 } 124 SetScreenSaverSuspended(bool suspend)125void X11ScreenOzone::SetScreenSaverSuspended(bool suspend) { 126 SuspendX11ScreenSaver(suspend); 127 } 128 IsScreenSaverActive() const129bool X11ScreenOzone::IsScreenSaverActive() const { 130 // Usually the screensaver is used to lock the screen. 131 return ScreensaverWindowFinder::ScreensaverWindowExists(); 132 } 133 CalculateIdleTime() const134base::TimeDelta X11ScreenOzone::CalculateIdleTime() const { 135 IdleQueryX11 idle_query; 136 return base::TimeDelta::FromSeconds(idle_query.IdleTime()); 137 } 138 AddObserver(display::DisplayObserver * observer)139void X11ScreenOzone::AddObserver(display::DisplayObserver* observer) { 140 x11_display_manager_->AddObserver(observer); 141 } 142 RemoveObserver(display::DisplayObserver * observer)143void X11ScreenOzone::RemoveObserver(display::DisplayObserver* observer) { 144 x11_display_manager_->RemoveObserver(observer); 145 } 146 GetCurrentWorkspace()147std::string X11ScreenOzone::GetCurrentWorkspace() { 148 return x11_display_manager_->GetCurrentWorkspace(); 149 } 150 GetGpuExtraInfoAsListValue(const gfx::GpuExtraInfo & gpu_extra_info)151base::Value X11ScreenOzone::GetGpuExtraInfoAsListValue( 152 const gfx::GpuExtraInfo& gpu_extra_info) { 153 return ui::GpuExtraInfoAsListValue(gpu_extra_info.system_visual, 154 gpu_extra_info.rgba_visual); 155 } 156 DispatchXEvent(x11::Event * xev)157bool X11ScreenOzone::DispatchXEvent(x11::Event* xev) { 158 return x11_display_manager_->ProcessEvent(xev); 159 } 160 GetCursorLocation() const161gfx::Point X11ScreenOzone::GetCursorLocation() const { 162 return x11_display_manager_->GetCursorLocation(); 163 } 164 OnXDisplayListUpdated()165void X11ScreenOzone::OnXDisplayListUpdated() { 166 float scale_factor = 167 x11_display_manager_->GetPrimaryDisplay().device_scale_factor(); 168 gfx::SetFontRenderParamsDeviceScaleFactor(scale_factor); 169 } 170 GetXDisplayScaleFactor() const171float X11ScreenOzone::GetXDisplayScaleFactor() const { 172 return GetDeviceScaleFactor(); 173 } 174 175 } // namespace ui 176