1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 startupnotify.c for the Openbox window manager
4 Copyright (c) 2003 Ben Jansens
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 See the COPYING file for a copy of the GNU General Public License.
19 #include "startupnotify.h"
23 void sn_startup(gboolean reconfig
) {}
24 void sn_shutdown(gboolean reconfig
) {}
25 gboolean
sn_app_starting() { return FALSE
; }
26 void sn_app_started(gchar
*wmclass
) {}
27 gboolean
sn_get_desktop(gchar
*id
, guint
*desktop
) { return FALSE
; }
35 #define SN_API_NOT_YET_FROZEN
39 SnStartupSequence
*seq
;
43 static SnDisplay
*sn_display
;
44 static SnMonitorContext
*sn_context
;
45 static GSList
*sn_waits
; /* list of ObWaitDatas */
47 static ObWaitData
* wait_data_new(SnStartupSequence
*seq
);
48 static void wait_data_free(ObWaitData
*d
);
49 static ObWaitData
* wait_find(const gchar
*id
);
51 static void sn_handler(const XEvent
*e
, gpointer data
);
52 static void sn_event_func(SnMonitorEvent
*event
, gpointer data
);
54 void sn_startup(gboolean reconfig
)
58 sn_display
= sn_display_new(ob_display
, NULL
, NULL
);
59 sn_context
= sn_monitor_context_new(sn_display
, ob_screen
,
60 sn_event_func
, NULL
, NULL
);
62 ob_main_loop_x_add(ob_main_loop
, sn_handler
, NULL
, NULL
, NULL
);
65 void sn_shutdown(gboolean reconfig
)
71 ob_main_loop_x_remove(ob_main_loop
, sn_handler
);
73 for (it
= sn_waits
; it
; it
= g_slist_next(it
))
74 wait_data_free(it
->data
);
75 g_slist_free(sn_waits
);
78 screen_set_root_cursor();
80 sn_monitor_context_unref(sn_context
);
81 sn_display_unref(sn_display
);
84 static ObWaitData
* wait_data_new(SnStartupSequence
*seq
)
86 ObWaitData
*d
= g_new(ObWaitData
, 1);
90 sn_startup_sequence_ref(d
->seq
);
95 static void wait_data_free(ObWaitData
*d
)
98 sn_startup_sequence_unref(d
->seq
);
104 static ObWaitData
* wait_find(const gchar
*id
)
106 ObWaitData
*ret
= NULL
;
109 for (it
= sn_waits
; it
; it
= g_slist_next(it
)) {
110 ObWaitData
*d
= it
->data
;
111 if (!strcmp(id
, sn_startup_sequence_get_id(d
->seq
))) {
119 gboolean
sn_app_starting()
123 for (it
= sn_waits
; it
; it
= g_slist_next(it
)) {
124 ObWaitData
*d
= it
->data
;
131 static gboolean
sn_wait_timeout(gpointer data
)
133 ObWaitData
*d
= data
;
135 screen_set_root_cursor();
136 return FALSE
; /* don't repeat */
139 static void sn_wait_destroy(gpointer data
)
141 ObWaitData
*d
= data
;
142 sn_waits
= g_slist_remove(sn_waits
, d
);
146 static void sn_handler(const XEvent
*e
, gpointer data
)
150 sn_display_process_event(sn_display
, &ec
);
153 static void sn_event_func(SnMonitorEvent
*ev
, gpointer data
)
155 SnStartupSequence
*seq
;
156 gboolean change
= FALSE
;
159 if (!(seq
= sn_monitor_event_get_startup_sequence(ev
)))
162 switch (sn_monitor_event_get_type(ev
)) {
163 case SN_MONITOR_EVENT_INITIATED
:
164 d
= wait_data_new(seq
);
165 sn_waits
= g_slist_prepend(sn_waits
, d
);
166 /* 30 second timeout for apps to start */
167 ob_main_loop_timeout_add(ob_main_loop
, 30 * G_USEC_PER_SEC
,
168 sn_wait_timeout
, d
, sn_wait_destroy
);
171 case SN_MONITOR_EVENT_CHANGED
:
172 /* XXX feedback changed? */
175 case SN_MONITOR_EVENT_COMPLETED
:
176 case SN_MONITOR_EVENT_CANCELED
:
177 if ((d
= wait_find(sn_startup_sequence_get_id(seq
)))) {
179 ob_main_loop_timeout_remove_data(ob_main_loop
, sn_wait_timeout
, d
);
186 screen_set_root_cursor();
189 void sn_app_started(gchar
*wmclass
)
193 for (it
= sn_waits
; it
; it
= g_slist_next(it
)) {
194 ObWaitData
*d
= it
->data
;
195 if (sn_startup_sequence_get_wmclass(d
->seq
) &&
196 !strcmp(sn_startup_sequence_get_wmclass(d
->seq
), wmclass
))
198 sn_startup_sequence_complete(d
->seq
);
204 gboolean
sn_get_desktop(gchar
*id
, guint
*desktop
)
208 if (id
&& (d
= wait_find(id
))) {
209 gint desk
= sn_startup_sequence_get_workspace(d
->seq
);