3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
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, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 Metacity - (c) 2003 Havoc Pennington
18 xfwm4 - (c) 2002-2007 Olivier Fourdan
26 #ifdef HAVE_LIBSTARTUP_NOTIFICATION
27 #define SN_API_NOT_YET_FROZEN
30 #include <X11/Xatom.h>
39 #include <libxfce4util/libxfce4util.h>
45 #define STARTUP_TIMEOUT (30 /* seconds */ * 1000)
47 static SnDisplay
*sn_display
= NULL
;
56 static gboolean
sn_startup_sequence_timeout (void *data
);
59 sn_error_trap_push (SnDisplay
* sn_display
, Display
* dpy
)
61 gdk_error_trap_push ();
65 sn_error_trap_pop (SnDisplay
* sn_display
, Display
* dpy
)
67 gdk_error_trap_pop ();
71 sn_update_feedback (ScreenInfo
*screen_info
)
73 g_return_if_fail (screen_info
!= NULL
);
75 if (screen_info
->startup_sequences
!= NULL
)
77 XDefineCursor (myScreenGetXDisplay (screen_info
), screen_info
->xroot
,
78 myDisplayGetCursorBusy(screen_info
->display_info
));
82 XDefineCursor (myScreenGetXDisplay (screen_info
), screen_info
->xroot
,
83 myDisplayGetCursorRoot(screen_info
->display_info
));
88 sn_add_sequence (ScreenInfo
*screen_info
, SnStartupSequence
* sequence
)
90 g_return_if_fail (screen_info
!= NULL
);
91 g_return_if_fail (sequence
!= NULL
);
93 sn_startup_sequence_ref (sequence
);
94 screen_info
->startup_sequences
= g_slist_prepend (screen_info
->startup_sequences
, sequence
);
96 if (screen_info
->startup_sequence_timeout
== 0)
98 screen_info
->startup_sequence_timeout
=
99 g_timeout_add (1000, sn_startup_sequence_timeout
, screen_info
);
101 sn_update_feedback (screen_info
);
105 sn_remove_sequence (ScreenInfo
*screen_info
, SnStartupSequence
* sequence
)
107 g_return_if_fail (screen_info
!= NULL
);
108 g_return_if_fail (sequence
!= NULL
);
110 screen_info
->startup_sequences
= g_slist_remove (screen_info
->startup_sequences
, sequence
);
111 sn_startup_sequence_unref (sequence
);
113 if ((screen_info
->startup_sequences
== NULL
) && (screen_info
->startup_sequence_timeout
!= 0))
115 g_source_remove (screen_info
->startup_sequence_timeout
);
116 screen_info
->startup_sequence_timeout
= 0;
118 sn_update_feedback (screen_info
);
122 sn_collect_timed_out_foreach (void *element
, void *data
)
124 CollectTimedOutData
*ctod
;
125 SnStartupSequence
*sequence
;
126 long tv_sec
, tv_usec
;
129 g_return_if_fail (data
!= NULL
);
130 g_return_if_fail (element
!= NULL
);
133 ctod
= (CollectTimedOutData
*) data
;
134 sn_startup_sequence_get_last_active_time (sequence
, &tv_sec
, &tv_usec
);
137 ((((double) ctod
->now
.tv_sec
- tv_sec
) * G_USEC_PER_SEC
+
138 (ctod
->now
.tv_usec
- tv_usec
))) / 1000.0;
140 if (elapsed
> STARTUP_TIMEOUT
)
142 ctod
->list
= g_slist_prepend (ctod
->list
, sequence
);
147 sn_startup_sequence_timeout (void *data
)
149 ScreenInfo
* screen_info
;
150 CollectTimedOutData ctod
;
153 screen_info
= (ScreenInfo
*) data
;
154 g_return_val_if_fail (screen_info
!= NULL
, FALSE
);
157 g_get_current_time (&ctod
.now
);
158 g_slist_foreach (screen_info
->startup_sequences
, sn_collect_timed_out_foreach
, &ctod
);
163 SnStartupSequence
*sequence
= tmp
->data
;
165 sn_startup_sequence_complete (sequence
);
170 g_slist_free (ctod
.list
);
172 if (screen_info
->startup_sequences
!= NULL
)
179 screen_info
->startup_sequence_timeout
= 0;
185 sn_screen_event (SnMonitorEvent
* event
, void *user_data
)
188 ScreenInfo
*screen_info
;
189 SnStartupSequence
*sequence
;
191 g_return_if_fail (event
!= NULL
);
192 sequence
= sn_monitor_event_get_startup_sequence (event
);
194 screen_info
= (ScreenInfo
*) user_data
;
195 g_return_if_fail (screen_info
!= NULL
);
197 switch (sn_monitor_event_get_type (event
))
199 case SN_MONITOR_EVENT_INITIATED
:
200 wmclass
= sn_startup_sequence_get_wmclass (sequence
);
201 sn_add_sequence (screen_info
, sequence
);
204 case SN_MONITOR_EVENT_COMPLETED
:
205 sn_remove_sequence (screen_info
, sn_monitor_event_get_startup_sequence (event
));
208 case SN_MONITOR_EVENT_CHANGED
:
211 case SN_MONITOR_EVENT_CANCELED
:
218 sn_client_startup_properties (Client
* c
)
220 ScreenInfo
*screen_info
;
222 SnStartupSequence
*sequence
;
225 g_return_if_fail (c
!= NULL
);
227 startup_id
= clientGetStartupId (c
);
228 screen_info
= c
->screen_info
;
230 if (startup_id
== NULL
)
232 tmp
= screen_info
->startup_sequences
;
237 wmclass
= sn_startup_sequence_get_wmclass (tmp
->data
);
239 if ((wmclass
!= NULL
) && ((c
->class.res_class
&& !strcmp (wmclass
, c
->class.res_class
))
240 || (c
->class.res_name
&& !strcmp (wmclass
, c
->class.res_name
))))
242 sequence
= tmp
->data
;
244 free (c
->startup_id
);
245 c
->startup_id
= strdup (sn_startup_sequence_get_id (sequence
));
246 startup_id
= c
->startup_id
;
248 sn_startup_sequence_complete (sequence
);
256 if (startup_id
== NULL
)
261 if (sequence
== NULL
)
263 tmp
= screen_info
->startup_sequences
;
268 id
= sn_startup_sequence_get_id (tmp
->data
);
270 if (!strcmp (id
, startup_id
))
272 sequence
= tmp
->data
;
280 if (sequence
!= NULL
)
285 /* Set initial time */
286 timestamp
= sn_startup_sequence_get_timestamp (sequence
);
287 TRACE ("Given startup time: %u", (unsigned int) timestamp
);
288 if ((c
->user_time
== (Time
) 0) || TIMESTAMP_IS_BEFORE(c
->user_time
, timestamp
))
290 c
->user_time
= timestamp
;
291 myDisplaySetLastUserTime (screen_info
->display_info
, c
->user_time
);
293 FLAG_SET (c
->flags
, CLIENT_FLAG_HAS_STARTUP_TIME
);
295 /* Set initial workspace */
296 if (!FLAG_TEST (c
->xfwm_flags
, XFWM_FLAG_WORKSPACE_SET
))
298 workspace
= sn_startup_sequence_get_workspace (sequence
);
301 FLAG_SET (c
->xfwm_flags
, XFWM_FLAG_WORKSPACE_SET
);
302 c
->win_workspace
= workspace
;
309 sn_init_display (ScreenInfo
*screen_info
)
311 g_return_if_fail (screen_info
!= NULL
);
312 g_return_if_fail (myScreenGetXDisplay (screen_info
) != NULL
);
316 sn_display
= sn_display_new (myScreenGetXDisplay (screen_info
), sn_error_trap_push
, sn_error_trap_pop
);
318 screen_info
->sn_context
= NULL
;
319 if (sn_display
!= NULL
)
321 screen_info
->sn_context
=
322 sn_monitor_context_new (sn_display
, screen_info
->screen
, sn_screen_event
, screen_info
, NULL
);
324 screen_info
->startup_sequences
= NULL
;
325 screen_info
->startup_sequence_timeout
= 0;
329 sn_close_display (void)
333 sn_display_unref (sn_display
);
339 sn_process_event (XEvent
* event
)
341 g_return_if_fail (sn_display
!= NULL
);
342 sn_display_process_event (sn_display
, event
);