78
/* Register the display to receive startup notifications */
79
Display *xdisplay = QX11Info::display();
80
m_snDisplay = sn_display_new(xdisplay, NULL, NULL);
81
m_snContext = sn_monitor_context_new(m_snDisplay, QX11Info::appScreen(),
82
LauncherApplicationsList::snEventHandler,
84
Unity2dApplication::instance()->installX11EventFilter(this);
90
LauncherApplicationsList::snEventHandler(SnMonitorEvent *event, void *user_data)
92
/* This method is static and only forwards the event to a non static method. */
93
((LauncherApplicationsList*)user_data)->onSnMonitorEventReceived(event);
97
LauncherApplicationsList::onSnMonitorEventReceived(SnMonitorEvent *event)
99
SnStartupSequence *sequence = sn_monitor_event_get_startup_sequence(event);
101
switch (sn_monitor_event_get_type (event)) {
102
case SN_MONITOR_EVENT_INITIATED:
103
insertSnStartupSequence(sequence);
105
case SN_MONITOR_EVENT_CHANGED:
106
case SN_MONITOR_EVENT_COMPLETED:
107
case SN_MONITOR_EVENT_CANCELED:
108
/* These events are ignored for now. This is acceptable since the
109
case of a failed application startup is handled by
110
LauncherApplication::launching being automatically reset to
111
false after a timeout. */
118
LauncherApplicationsList::x11EventFilter(XEvent* xevent)
120
/* libsn specifies that all events need to be forwarded to
121
sn_display_process_event but it is not actually necessary.
122
Forwarding only the events of type ClientMessage.
124
if (xevent->type == ClientMessage) {
125
sn_display_process_event(m_snDisplay, xevent);
76
131
LauncherApplicationsList::onRemoteEntryUpdated(QString applicationURI, QMap<QString, QVariant> properties)
78
133
QString desktopFile;
96
151
LauncherApplicationsList::~LauncherApplicationsList()
153
Unity2dApplication::instance()->removeX11EventFilter(this);
154
sn_monitor_context_unref(m_snContext);
155
sn_display_unref(m_snDisplay);
98
157
qDeleteAll(m_applications);
99
158
delete m_favorites_list;
117
176
if (!application->desktop_file().isEmpty()) {
118
177
m_applicationForDesktopFile.insert(application->desktop_file(), application);
179
if (!application->executable().isEmpty()) {
180
m_applicationForExecutable.insert(application->executable(), application);
122
184
QObject::connect(application, SIGNAL(closed()), this, SLOT(onApplicationClosed()));
123
185
QObject::connect(application, SIGNAL(stickyChanged(bool)), this, SLOT(onApplicationStickyChanged(bool)));
186
QObject::connect(application, SIGNAL(launchingChanged(bool)), this, SLOT(onApplicationLaunchingChanged(bool)));
129
192
int index = m_applications.indexOf(application);
195
/* application is not present in m_applications */
131
199
beginRemoveRows(QModelIndex(), index, index);
132
200
m_applications.removeAt(index);
133
201
m_applicationForDesktopFile.remove(application->desktop_file());
202
m_applicationForExecutable.remove(application->executable());
205
/* LauncherApplicationsList::removeApplication might have been called in
206
response to a signal emitted by application itself. Do not delete
207
immediately to cater for this case.
209
application->deleteLater();
139
212
void LauncherApplicationsList::insertBamfApplication(BamfApplication* bamf_application)
145
LauncherApplication* application;
218
LauncherApplication* matchingApplication = NULL;
219
LauncherApplication* newApplication = new LauncherApplication;
220
newApplication->setBamfApplication(bamf_application);
147
QString desktop_file = bamf_application->desktop_file();
222
QString executable = newApplication->executable();
223
QString desktop_file = newApplication->desktop_file();
148
224
if (m_applicationForDesktopFile.contains(desktop_file)) {
149
225
/* A LauncherApplication with the same desktop file already exists */
150
application = m_applicationForDesktopFile[desktop_file];
151
application->setBamfApplication(bamf_application);
226
matchingApplication = m_applicationForDesktopFile[desktop_file];
227
} else if (m_applicationForExecutable.contains(executable)) {
228
/* A LauncherApplication with the same executable already exists */
229
matchingApplication = m_applicationForExecutable[executable];
232
if (matchingApplication != NULL) {
233
/* A LauncherApplication that corresponds to bamf_application already exists */
234
/* FIXME: this deletion blocks for a long time (around 100ms here) and
235
leads to a visual glitch in the launcher when an application finished
236
starting up. This is due to the deletion of the QFileSystemWatcher
237
belonging to the LauncherApplication. */
238
delete newApplication;
239
matchingApplication->setBamfApplication(bamf_application);
153
/* Create a new LauncherApplication and append it to the list */
154
application = new LauncherApplication;
155
application->setBamfApplication(bamf_application);
156
insertApplication(application);
241
insertApplication(newApplication);
285
LauncherApplicationsList::insertSnStartupSequence(SnStartupSequence* sequence)
287
if (sequence == NULL) {
291
QString executable = sn_startup_sequence_get_binary_name(sequence);
293
if (m_applicationForExecutable.contains(executable)) {
294
/* A LauncherApplication with the same executable already exists */
295
m_applicationForExecutable[executable]->setSnStartupSequence(sequence);
297
/* Create a new LauncherApplication and append it to the list */
298
LauncherApplication* newApplication = new LauncherApplication;
299
newApplication->setSnStartupSequence(sequence);
300
insertApplication(newApplication);
200
305
LauncherApplicationsList::load()
202
307
/* Insert favorites */
365
LauncherApplicationsList::onApplicationLaunchingChanged(bool launching)
367
LauncherApplication* application = static_cast<LauncherApplication*>(sender());
369
if (!application->sticky() && !application->running() && !application->launching()) {
370
removeApplication(application);
260
375
LauncherApplicationsList::writeFavoritesToGConf()
262
377
QStringList favorites;