File: status_icon_linux_dbus.h

package info (click to toggle)
chromium 139.0.7258.138-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,120,676 kB
  • sloc: cpp: 35,100,869; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (142 lines) | stat: -rw-r--r-- 5,341 bytes parent folder | download | duplicates (6)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_ICON_LINUX_DBUS_H_
#define CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_ICON_LINUX_DBUS_H_

#include <string>

#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "chrome/browser/ui/views/status_icons/concat_menu_model.h"
#include "dbus/bus.h"
#include "dbus/exported_object.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "ui/linux/status_icon_linux.h"
#include "ui/menus/simple_menu_model.h"
#include "ui/views/controls/menu/menu_runner.h"

namespace gfx {
class ImageSkia;
}  // namespace gfx

class DbusMenu;
class DbusProperties;

// A status icon following the StatusNotifierItem specification.
// https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/
class StatusIconLinuxDbus : public ui::StatusIconLinux,
                            public ui::SimpleMenuModel::Delegate,
                            public base::RefCounted<StatusIconLinuxDbus> {
 public:
  StatusIconLinuxDbus();

  StatusIconLinuxDbus(const StatusIconLinuxDbus&) = delete;
  StatusIconLinuxDbus& operator=(const StatusIconLinuxDbus&) = delete;

  // StatusIcon:
  void SetImage(const gfx::ImageSkia& image) override;
  void SetIcon(const gfx::VectorIcon& icon) override;
  void SetToolTip(const std::u16string& tool_tip) override;
  void UpdatePlatformContextMenu(ui::MenuModel* model) override;
  void RefreshPlatformContextMenu() override;

  // ui::SimpleMenuModel::Delegate:
  void ExecuteCommand(int command_id, int event_flags) override;

 private:
  friend class base::RefCounted<StatusIconLinuxDbus>;

  ~StatusIconLinuxDbus() override;

  // Step 0: send the request to verify that the StatusNotifierWatcher service
  // is owned.
  void CheckStatusNotifierWatcherHasOwner();

  // Step 1: verify that the StatusNotifierWatcher service is owned.
  void OnNameHasOwnerResponse(dbus::Response* response);

  // Step 2: verify with the StatusNotifierWatcher that a StatusNotifierHost is
  // registered.
  void OnHostRegisteredResponse(dbus::Response* response);

  // Step 3: export methods for the StatusNotifierItem and the properties
  // interface.
  void OnExported(const std::string& interface_name,
                  const std::string& method_name,
                  bool success);
  void OnInitialized(bool success);
  void RegisterStatusNotifierItem();

  // Step 5: register the StatusNotifierItem with the StatusNotifierWatcher.
  void OnRegistered(dbus::Response* response);

  // Called when the name owner of StatusNotifierWatcher has changed, which
  // can happen when lock/unlock screen.
  void OnNameOwnerChangedReceived(const std::string& old_owner,
                                  const std::string& new_owner);

  // DBus methods.
  // Action       -> KDE behavior:
  // Left-click   -> Activate
  // Right-click  -> ContextMenu
  // Scroll       -> Scroll
  // Middle-click -> SecondaryActivate
  void OnActivate(dbus::MethodCall* method_call,
                  dbus::ExportedObject::ResponseSender sender);
  void OnContextMenu(dbus::MethodCall* method_call,
                     dbus::ExportedObject::ResponseSender sender);
  void OnScroll(dbus::MethodCall* method_call,
                dbus::ExportedObject::ResponseSender sender);
  void OnSecondaryActivate(dbus::MethodCall* method_call,
                           dbus::ExportedObject::ResponseSender sender);

  void UpdateMenuImpl(ui::MenuModel* model, bool send_signal);

  void SetImageImpl(const gfx::ImageSkia& image, bool send_signals);

  void OnIconFileWritten(const base::FilePath& icon_file);

  void CleanupIconFile();

  scoped_refptr<dbus::Bus> bus_;

  int service_id_ = 0;
  raw_ptr<dbus::ObjectProxy, DanglingUntriaged> watcher_ = nullptr;
  raw_ptr<dbus::ExportedObject, DanglingUntriaged> item_ = nullptr;

  base::RepeatingCallback<void(bool)> barrier_;

  std::unique_ptr<DbusProperties> properties_;

  std::unique_ptr<DbusMenu> menu_;
  // A menu that contains the click action (if there is a click action) and a
  // separator (if there's a click action and delegate_->GetMenuModel() is
  // non-empty).
  std::unique_ptr<ui::SimpleMenuModel> click_action_menu_;
  // An empty menu for use in |concat_menu_| if delegate_->GetMenuModel() is
  // null.
  std::unique_ptr<ui::SimpleMenuModel> empty_menu_;
  // A concatenation of |click_action_menu_| and either
  // delegate_->GetMenuModel() or |empty_menu_| if the delegate's menu is null.
  // Appears after the other menus so that it gets destroyed first.
  std::unique_ptr<ConcatMenuModel> concat_menu_;
  // Used when the server doesn't support DBus menus and requests for us to use
  // our own menu.
  std::unique_ptr<views::MenuRunner> menu_runner_;

  const bool should_write_icon_to_file_;
  const scoped_refptr<base::SequencedTaskRunner> icon_task_runner_;
  size_t icon_file_id_ = 0;
  base::FilePath icon_file_;

  base::WeakPtrFactory<StatusIconLinuxDbus> weak_factory_{this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_ICON_LINUX_DBUS_H_