2
* Copyright (C) 2010 Canonical Ltd
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 3 as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
19
#include "IndicatorObjectFactoryRemote.h"
21
#include "IndicatorObjectProxyRemote.h"
22
#include "IndicatorObjectEntryProxyRemote.h"
23
#include "IndicatorObjectEntryProxy.h"
25
#define S_NAME "com.canonical.Unity.Panel.Service"
26
#define S_PATH "/com/canonical/Unity/Panel/Service"
27
#define S_IFACE "com.canonical.Unity.Panel.Service"
28
#define D_NAME "com.canonical.Unity.Panel.Service.Indicators"
40
static void on_proxy_ready_cb (GObject *source,
44
static void on_row_added (DeeModel *model,
46
IndicatorObjectFactoryRemote *remote);
48
static void on_row_changed (DeeModel *model,
50
IndicatorObjectFactoryRemote *remote);
52
static void on_row_removed (DeeModel *model,
54
IndicatorObjectFactoryRemote *remote);
56
static void on_proxy_signal_received (GDBusProxy *proxy,
60
IndicatorObjectFactoryRemote *remote);
63
IndicatorObjectFactoryRemote::IndicatorObjectFactoryRemote ()
65
// We want to grab the Panel Service object. This is async, which is fine
66
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
67
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
76
// Connect to the main DeeSharedModel, which gives us info about the
77
// indicators that the service has
78
_model = dee_shared_model_new_with_name (D_NAME);
79
g_signal_connect (_model, "row-added",
80
G_CALLBACK (on_row_added), this);
81
g_signal_connect (_model, "row-changed",
82
G_CALLBACK (on_row_changed), this);
83
g_signal_connect (_model, "row-removed",
84
G_CALLBACK (on_row_removed), this);
86
dee_shared_model_connect (DEE_SHARED_MODEL (_model));
89
IndicatorObjectFactoryRemote::~IndicatorObjectFactoryRemote ()
91
if (G_IS_OBJECT (_proxy))
92
g_object_unref (_proxy);
95
if (DEE_IS_SHARED_MODEL (_model))
96
g_object_unref (_model);
99
std::vector<IndicatorObjectProxy*>::iterator it;
101
for (it = _indicators.begin(); it != _indicators.end(); it++)
103
IndicatorObjectProxyRemote *remote = static_cast<IndicatorObjectProxyRemote *> (*it);
107
_indicators.erase (_indicators.begin (), _indicators.end ());
110
std::vector<IndicatorObjectProxy *>&
111
IndicatorObjectFactoryRemote::GetIndicatorObjects ()
117
IndicatorObjectFactoryRemote::ForceRefresh ()
122
IndicatorObjectFactoryRemote::OnRemoteProxyReady (GDBusProxy *proxy)
126
// Connect to interesting signals
127
// FIXME: Add autorestarting bits here
128
g_signal_connect (_proxy, "g-signal",
129
G_CALLBACK (on_proxy_signal_received), this);
133
IndicatorObjectFactoryRemote::OnShowMenuRequestReceived (const char *id, int x, int y, guint timestamp)
135
// FIXME: Why doesn't this work if timestamp is valid?
138
g_dbus_proxy_call (_proxy,
140
g_variant_new ("(suii)",
145
G_DBUS_CALL_FLAGS_NONE,
153
IndicatorObjectFactoryRemote::OnRowAdded (DeeModelIter *iter)
155
IndicatorObjectProxyRemote *remote;
157
const gchar *model_name;
159
name = dee_model_get_string (_model, iter, COL_NAME);
160
model_name = dee_model_get_string (_model, iter, COL_MODEL_NAME);
162
remote = new IndicatorObjectProxyRemote (name, model_name);
163
remote->OnShowMenuRequest.connect (sigc::mem_fun (this, &IndicatorObjectFactoryRemote::OnShowMenuRequestReceived));
165
_indicators.push_back (remote);
167
OnObjectAdded.emit (remote);
171
IndicatorObjectFactoryRemote::OnRowChanged (DeeModelIter *iter)
173
printf ("HELLO %s\n", G_STRFUNC);
177
IndicatorObjectFactoryRemote::OnRowRemoved (DeeModelIter *iter)
179
printf ("HELLO%s\n", G_STRFUNC);
182
// We need to unset the last active entry and set the new one as active
184
IndicatorObjectFactoryRemote::OnEntryActivated (const char *entry_id)
186
std::vector<IndicatorObjectProxy*>::iterator it;
188
for (it = _indicators.begin(); it != _indicators.end(); it++)
190
IndicatorObjectProxyRemote *object = static_cast<IndicatorObjectProxyRemote *> (*it);
191
std::vector<IndicatorObjectEntryProxy*>::iterator it;
193
for (it = object->GetEntries ().begin(); it != object->GetEntries ().end(); it++)
195
IndicatorObjectEntryProxyRemote *entry = static_cast<IndicatorObjectEntryProxyRemote *> (*it);
197
entry->SetActive (g_strcmp0 (entry_id, entry->GetId ()) == 0);
203
// C callbacks, they just link to class methods and aren't interesting
207
reconnect_to_service (gpointer data)
209
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
210
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
223
on_proxy_ready_cb (GObject *source,
227
IndicatorObjectFactoryRemote *remote = static_cast<IndicatorObjectFactoryRemote *> (data);
229
GError *error = NULL;
230
static bool force_tried = false;
233
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
234
name_owner = g_dbus_proxy_get_name_owner (proxy);
236
if (G_IS_DBUS_PROXY (proxy) && name_owner)
238
remote->OnRemoteProxyReady (G_DBUS_PROXY (proxy));
246
printf ("\nWARNING: Unable to connect to the unity-panel-service %s\n",
247
error ? error->message : "Unknown");
249
g_error_free (error);
254
GError *error = NULL;
256
// Let's attempt to run it from where we expect it to be
257
char *cmd = g_strdup_printf ("%s/lib/unity/unity-panel-service", PREFIX);
258
printf ("\nWARNING: Couldn't load panel from installed services, so trying to load panel from known location: %s\n", cmd);
260
g_spawn_command_line_async (cmd, &error);
263
printf ("\nWARNING: Unable to launch remote service manually: %s\n", error->message);
264
g_error_free (error);
268
// This is obviously hackish, but this part of the code is mostly hackish...
269
g_timeout_add_seconds (2, (GSourceFunc)reconnect_to_service, remote);
274
g_object_unref (proxy);
278
on_row_added (DeeModel *model, DeeModelIter *iter, IndicatorObjectFactoryRemote *remote)
280
remote->OnRowAdded (iter);
284
on_row_changed (DeeModel *model, DeeModelIter *iter, IndicatorObjectFactoryRemote *remote)
286
remote->OnRowChanged (iter);
290
on_row_removed (DeeModel *model, DeeModelIter *iter, IndicatorObjectFactoryRemote *remote)
292
remote->OnRowRemoved (iter);
296
on_proxy_signal_received (GDBusProxy *proxy,
299
GVariant *parameters,
300
IndicatorObjectFactoryRemote *remote)
302
if (g_strcmp0 (signal_name, "EntryActivated") == 0)
304
remote->OnEntryActivated (g_variant_get_string (g_variant_get_child_value (parameters, 0), NULL));