1
+ // Copyright 2013 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
+
5
+ #include " content/nw/src/browser/global_menu_bar_registrar_x11.h"
6
+
7
+ #include " base/bind.h"
8
+ #include " base/debug/leak_annotations.h"
9
+ #include " base/logging.h"
10
+ #include " content/nw/src/browser/global_menu_bar_x11.h"
11
+
12
+ namespace nw {
13
+
14
+ namespace {
15
+
16
+ const char kAppMenuRegistrarName [] = " com.canonical.AppMenu.Registrar" ;
17
+ const char kAppMenuRegistrarPath [] = " /com/canonical/AppMenu/Registrar" ;
18
+
19
+ } // namespace
20
+
21
+ // static
22
+ GlobalMenuBarRegistrarX11* GlobalMenuBarRegistrarX11::GetInstance () {
23
+ return base::Singleton<GlobalMenuBarRegistrarX11>::get ();
24
+ }
25
+
26
+ void GlobalMenuBarRegistrarX11::OnWindowMapped (unsigned long xid) {
27
+ live_xids_.insert (xid);
28
+
29
+ if (registrar_proxy_)
30
+ RegisterXID (xid);
31
+ }
32
+
33
+ void GlobalMenuBarRegistrarX11::OnWindowUnmapped (unsigned long xid) {
34
+ if (registrar_proxy_)
35
+ UnregisterXID (xid);
36
+
37
+ live_xids_.erase (xid);
38
+ }
39
+
40
+ GlobalMenuBarRegistrarX11::GlobalMenuBarRegistrarX11 ()
41
+ : registrar_proxy_(nullptr ) {
42
+ // libdbusmenu uses the gio version of dbus; I tried using the code in dbus/,
43
+ // but it looks like that's isn't sharing the bus name with the gio version,
44
+ // even when |connection_type| is set to SHARED.
45
+ g_dbus_proxy_new_for_bus (
46
+ G_BUS_TYPE_SESSION,
47
+ static_cast <GDBusProxyFlags>(
48
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
49
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
50
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
51
+ nullptr ,
52
+ kAppMenuRegistrarName ,
53
+ kAppMenuRegistrarPath ,
54
+ kAppMenuRegistrarName ,
55
+ nullptr , // TODO: Probalby want a real cancelable.
56
+ static_cast <GAsyncReadyCallback>(OnProxyCreatedThunk),
57
+ this );
58
+ }
59
+
60
+ GlobalMenuBarRegistrarX11::~GlobalMenuBarRegistrarX11 () {
61
+ if (registrar_proxy_) {
62
+ g_signal_handlers_disconnect_by_func (
63
+ registrar_proxy_,
64
+ reinterpret_cast <void *>(OnNameOwnerChangedThunk),
65
+ this );
66
+ g_object_unref (registrar_proxy_);
67
+ }
68
+ }
69
+
70
+ void GlobalMenuBarRegistrarX11::RegisterXID (unsigned long xid) {
71
+ DCHECK (registrar_proxy_);
72
+ std::string path = GlobalMenuBarX11::GetPathForWindow (xid);
73
+
74
+ ANNOTATE_SCOPED_MEMORY_LEAK; // http://crbug.com/314087
75
+ // TODO(erg): The mozilla implementation goes to a lot of callback trouble
76
+ // just to make sure that they react to make sure there's some sort of
77
+ // cancelable object; including making a whole callback just to handle the
78
+ // cancelable.
79
+ //
80
+ // I don't see any reason why we should care if "RegisterWindow" completes or
81
+ // not.
82
+ g_dbus_proxy_call (registrar_proxy_,
83
+ " RegisterWindow" ,
84
+ g_variant_new (" (uo)" , xid, path.c_str ()),
85
+ G_DBUS_CALL_FLAGS_NONE, -1 ,
86
+ nullptr ,
87
+ nullptr ,
88
+ nullptr );
89
+ }
90
+
91
+ void GlobalMenuBarRegistrarX11::UnregisterXID (unsigned long xid) {
92
+ DCHECK (registrar_proxy_);
93
+ std::string path = GlobalMenuBarX11::GetPathForWindow (xid);
94
+
95
+ ANNOTATE_SCOPED_MEMORY_LEAK; // http://crbug.com/314087
96
+ // TODO(erg): The mozilla implementation goes to a lot of callback trouble
97
+ // just to make sure that they react to make sure there's some sort of
98
+ // cancelable object; including making a whole callback just to handle the
99
+ // cancelable.
100
+ //
101
+ // I don't see any reason why we should care if "UnregisterWindow" completes
102
+ // or not.
103
+ g_dbus_proxy_call (registrar_proxy_,
104
+ " UnregisterWindow" ,
105
+ g_variant_new (" (u)" , xid),
106
+ G_DBUS_CALL_FLAGS_NONE, -1 ,
107
+ nullptr ,
108
+ nullptr ,
109
+ nullptr );
110
+ }
111
+
112
+ void GlobalMenuBarRegistrarX11::OnProxyCreated (GObject* source,
113
+ GAsyncResult* result) {
114
+ GError* error = nullptr ;
115
+ GDBusProxy* proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
116
+ if (error) {
117
+ g_error_free (error);
118
+ return ;
119
+ }
120
+
121
+ // TODO(erg): Mozilla's implementation has a workaround for GDBus
122
+ // cancellation here. However, it's marked as fixed. If there's weird
123
+ // problems with cancelation, look at how they fixed their issues.
124
+
125
+ registrar_proxy_ = proxy;
126
+
127
+ g_signal_connect (registrar_proxy_, " notify::g-name-owner" ,
128
+ G_CALLBACK (OnNameOwnerChangedThunk), this );
129
+
130
+ OnNameOwnerChanged (nullptr , nullptr );
131
+ }
132
+
133
+ void GlobalMenuBarRegistrarX11::OnNameOwnerChanged (GObject* /* ignored */ ,
134
+ GParamSpec* /* ignored */ ) {
135
+ // If the name owner changed, we need to reregister all the live xids with
136
+ // the system.
137
+ for (std::set<unsigned long >::const_iterator it = live_xids_.begin ();
138
+ it != live_xids_.end (); ++it) {
139
+ RegisterXID (*it);
140
+ }
141
+ }
142
+
143
+ } // namespace nw
0 commit comments