File: x11_workspace_handler.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (78 lines) | stat: -rw-r--r-- 2,371 bytes parent folder | download | duplicates (5)
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