123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- // Copyright 2019 The Chromium 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 "ui/base/x/x11_display_manager.h"
- #include <utility>
- #include "base/bind.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "ui/base/x/x11_display_util.h"
- #include "ui/gfx/x/future.h"
- #include "ui/gfx/x/randr.h"
- #include "ui/gfx/x/x11_atom_cache.h"
- #include "ui/gfx/x/xproto.h"
- namespace ui {
- namespace {
- constexpr int kMinXrandrVersion = 103; // Need at least xrandr version 1.3
- } // namespace
- XDisplayManager::XDisplayManager(Delegate* delegate)
- : delegate_(delegate),
- connection_(x11::Connection::Get()),
- x_root_window_(connection_->default_screen().root),
- xrandr_version_(GetXrandrVersion()),
- workspace_handler_(this) {}
- XDisplayManager::~XDisplayManager() = default;
- void XDisplayManager::Init() {
- if (IsXrandrAvailable()) {
- auto& randr = connection_->randr();
- randr.SelectInput(
- {x_root_window_, x11::RandR::NotifyMask::ScreenChange |
- x11::RandR::NotifyMask::OutputChange |
- x11::RandR::NotifyMask::CrtcChange});
- }
- FetchDisplayList();
- }
- // Need at least xrandr version 1.3
- bool XDisplayManager::IsXrandrAvailable() const {
- return xrandr_version_ >= kMinXrandrVersion;
- }
- display::Display XDisplayManager::GetPrimaryDisplay() const {
- DCHECK(!displays_.empty());
- return displays_[primary_display_index_];
- }
- void XDisplayManager::AddObserver(display::DisplayObserver* observer) {
- change_notifier_.AddObserver(observer);
- }
- void XDisplayManager::RemoveObserver(display::DisplayObserver* observer) {
- change_notifier_.RemoveObserver(observer);
- }
- void XDisplayManager::OnEvent(const x11::Event& xev) {
- auto* prop = xev.As<x11::PropertyNotifyEvent>();
- if (xev.As<x11::RandR::NotifyEvent>() ||
- (prop && prop->atom == x11::GetAtom("_NET_WORKAREA"))) {
- DispatchDelayedDisplayListUpdate();
- }
- }
- void XDisplayManager::SetDisplayList(std::vector<display::Display> displays) {
- displays_ = std::move(displays);
- delegate_->OnXDisplayListUpdated();
- }
- // Talks to xrandr to get the information of the outputs for a screen and
- // updates display::Display list. The minimum required version of xrandr is
- // 1.3.
- void XDisplayManager::FetchDisplayList() {
- std::vector<display::Display> displays;
- float scale = delegate_->GetXDisplayScaleFactor();
- if (IsXrandrAvailable()) {
- displays = BuildDisplaysFromXRandRInfo(xrandr_version_, scale,
- &primary_display_index_);
- } else {
- displays = GetFallbackDisplayList(scale);
- }
- SetDisplayList(std::move(displays));
- }
- void XDisplayManager::OnCurrentWorkspaceChanged(
- const std::string& new_workspace) {
- change_notifier_.NotifyCurrentWorkspaceChanged(new_workspace);
- }
- void XDisplayManager::UpdateDisplayList() {
- std::vector<display::Display> old_displays = displays_;
- FetchDisplayList();
- change_notifier_.NotifyDisplaysChanged(old_displays, displays_);
- }
- void XDisplayManager::DispatchDelayedDisplayListUpdate() {
- update_task_.Reset(base::BindOnce(&XDisplayManager::UpdateDisplayList,
- base::Unretained(this)));
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- update_task_.callback());
- }
- gfx::Point XDisplayManager::GetCursorLocation() const {
- if (auto response = connection_->QueryPointer({x_root_window_}).Sync())
- return {response->root_x, response->root_y};
- return {};
- }
- std::string XDisplayManager::GetCurrentWorkspace() {
- return workspace_handler_.GetCurrentWorkspace();
- }
- } // namespace ui
|