x11_workspace_handler.cc 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright 2020 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. #include "ui/base/x/x11_workspace_handler.h"
  5. #include "base/strings/string_number_conversions.h"
  6. #include "ui/base/x/x11_util.h"
  7. #include "ui/gfx/x/x11_atom_cache.h"
  8. #include "ui/gfx/x/x11_window_event_manager.h"
  9. #include "ui/gfx/x/xproto.h"
  10. namespace ui {
  11. namespace {
  12. x11::Future<x11::GetPropertyReply> GetWorkspace() {
  13. auto* connection = x11::Connection::Get();
  14. return connection->GetProperty(x11::GetPropertyRequest{
  15. .window = connection->default_screen().root,
  16. .property = static_cast<x11::Atom>(x11::GetAtom("_NET_CURRENT_DESKTOP")),
  17. .type = static_cast<x11::Atom>(x11::Atom::CARDINAL),
  18. .long_length = 1,
  19. });
  20. }
  21. } // namespace
  22. X11WorkspaceHandler::X11WorkspaceHandler(Delegate* delegate)
  23. : x_root_window_(ui::GetX11RootWindow()), delegate_(delegate) {
  24. DCHECK(delegate_);
  25. x11::Connection::Get()->AddEventObserver(this);
  26. x_root_window_events_ = std::make_unique<x11::XScopedEventSelector>(
  27. x_root_window_, x11::EventMask::PropertyChange);
  28. }
  29. X11WorkspaceHandler::~X11WorkspaceHandler() {
  30. x11::Connection::Get()->RemoveEventObserver(this);
  31. }
  32. std::string X11WorkspaceHandler::GetCurrentWorkspace() {
  33. if (workspace_.empty())
  34. OnWorkspaceResponse(GetWorkspace().Sync());
  35. return workspace_;
  36. }
  37. void X11WorkspaceHandler::OnEvent(const x11::Event& xev) {
  38. auto* prop = xev.As<x11::PropertyNotifyEvent>();
  39. if (prop && prop->window == x_root_window_ &&
  40. prop->atom == x11::GetAtom("_NET_CURRENT_DESKTOP")) {
  41. GetWorkspace().OnResponse(base::BindOnce(
  42. &X11WorkspaceHandler::OnWorkspaceResponse, weak_factory_.GetWeakPtr()));
  43. }
  44. }
  45. void X11WorkspaceHandler::OnWorkspaceResponse(
  46. x11::GetPropertyResponse response) {
  47. if (!response || response->format != 32 || response->value->size() < 4)
  48. return;
  49. DCHECK_EQ(response->bytes_after, 0U);
  50. DCHECK_EQ(response->type, static_cast<x11::Atom>(x11::Atom::CARDINAL));
  51. uint32_t workspace;
  52. memcpy(&workspace, response->value->data(), 4);
  53. workspace_ = base::NumberToString(workspace);
  54. delegate_->OnCurrentWorkspaceChanged(workspace_);
  55. }
  56. } // namespace ui