1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/390223051): Remove C-library calls to fix the errors.
#pragma allow_unsafe_libc_calls
#endif
#include "ui/base/x/x11_workspace_handler.h"
#include "base/strings/string_number_conversions.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/x/atom_cache.h"
#include "ui/gfx/x/window_event_manager.h"
#include "ui/gfx/x/xproto.h"
namespace ui {
namespace {
x11::Future<x11::GetPropertyReply> GetWorkspace() {
auto* connection = x11::Connection::Get();
return connection->GetProperty({
.window = connection->default_screen().root,
.property = static_cast<x11::Atom>(x11::GetAtom("_NET_CURRENT_DESKTOP")),
.type = static_cast<x11::Atom>(x11::Atom::CARDINAL),
.long_length = 1,
});
}
} // namespace
X11WorkspaceHandler::X11WorkspaceHandler(Delegate* delegate)
: x_root_window_(ui::GetX11RootWindow()), delegate_(delegate) {
DCHECK(delegate_);
auto* connection = x11::Connection::Get();
connection->AddEventObserver(this);
x_root_window_events_ = connection->ScopedSelectEvent(
x_root_window_, x11::EventMask::PropertyChange);
}
X11WorkspaceHandler::~X11WorkspaceHandler() {
x11::Connection::Get()->RemoveEventObserver(this);
}
std::string X11WorkspaceHandler::GetCurrentWorkspace() {
if (workspace_.empty()) {
OnWorkspaceResponse(GetWorkspace().Sync());
}
return workspace_;
}
void X11WorkspaceHandler::OnEvent(const x11::Event& xev) {
auto* prop = xev.As<x11::PropertyNotifyEvent>();
if (prop && prop->window == x_root_window_ &&
prop->atom == x11::GetAtom("_NET_CURRENT_DESKTOP")) {
GetWorkspace().OnResponse(base::BindOnce(
&X11WorkspaceHandler::OnWorkspaceResponse, weak_factory_.GetWeakPtr()));
}
}
void X11WorkspaceHandler::OnWorkspaceResponse(
x11::GetPropertyResponse response) {
if (!response || response->format != 32 || response->value_len < 1) {
return;
}
DCHECK_EQ(response->bytes_after, 0U);
DCHECK_EQ(response->type, static_cast<x11::Atom>(x11::Atom::CARDINAL));
uint32_t workspace;
memcpy(&workspace, response->value->bytes(), 4);
workspace_ = base::NumberToString(workspace);
delegate_->OnCurrentWorkspaceChanged(workspace_);
}
} // namespace ui
|