Awn

Merge lp:~h4writer/awn/taskmanager-rewrite into lp:~awn-core/awn/trunk-rewrite

Proposed by haytjes
Status: Merged
Approved by: Michal Hruby
Approved revision: 953
Merged at revision: not available
Proposed branch: lp:~h4writer/awn/taskmanager-rewrite
Merge into: lp:~awn-core/awn/trunk-rewrite
Diff against target: None lines
To merge this branch: bzr merge lp:~h4writer/awn/taskmanager-rewrite
Reviewer Review Type Date Requested Status
haytjes Approve
Michal Hruby (community) Approve
moonbeam overview Approve
Mark Lee superreview Needs Information
Review via email: mp+8033@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Mark Lee (malept) wrote :

=== modified file 'applets/taskmanager/Makefile.am'
--- applets/taskmanager/Makefile.am 2009-05-19 01:06:12 +0000
+++ applets/taskmanager/Makefile.am 2009-06-26 11:00:10 +0000
@@ -17,14 +17,18 @@
        task-drag-indicator.h \
        task-icon.c \
        task-icon.h \
+ task-item.c \
+ task-item.h \
+ task-window.c \
+ task-window.h \
        task-launcher.c \
        task-launcher.h \
        task-manager.c \
        task-manager.h \
+ task-manager-api-wrapper.c \
+ task-manager-api-wrapper.h \
        task-settings.c \
        task-settings.h \
- task-window.c \
- task-window.h \
        $(builddir)/taskmanager-marshal.c \
        $(builddir)/taskmanager-marshal.h \
        xutils.c \
====

Why did task-window.* move?

=== modified file 'applets/taskmanager/task-drag-indicator.c'
--- applets/taskmanager/task-drag-indicator.c 2009-06-19 09:35:43 +0000
+++ applets/taskmanager/task-drag-indicator.c 2009-06-20 14:17:54 +0000
@@ -13,7 +13,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  *
- * Authored by Neil Jagdish Patel <email address hidden>
+ * Authored by Hannes Verschore <email address hidden>
  *
  */

====

Any particular reason why you removed Neil as author here (and applets/taskmanager/task-drag-indicator.h)?

In general, you should make sure that all of the code that you commented out (instead of deleted) should be annotated with the reason why you're commenting it.

review: Needs Information (superreview)
Revision history for this message
moonbeam (rcryderman) wrote :

I'm not going to do a detailed review of this, purely based upon the extent of the modifications. A quick overview doesn't show anything particularly egregious, though I'm sure there are issues (but the current taskmanager code probably has even more fundamental ones). I think we are best served getting this merge, the sooner the better, get it tested and shake out the bugs (and any find design issues).

review: Approve (overview)
Revision history for this message
haytjes (h4writer) wrote :

> === modified file 'applets/taskmanager/Makefile.am'
> --- applets/taskmanager/Makefile.am 2009-05-19 01:06:12 +0000
> +++ applets/taskmanager/Makefile.am 2009-06-26 11:00:10 +0000
> @@ -17,14 +17,18 @@
> task-drag-indicator.h \
> task-icon.c \
> task-icon.h \
> + task-item.c \
> + task-item.h \
> + task-window.c \
> + task-window.h \
> task-launcher.c \
> task-launcher.h \
> task-manager.c \
> task-manager.h \
> + task-manager-api-wrapper.c \
> + task-manager-api-wrapper.h \
> task-settings.c \
> task-settings.h \
> - task-window.c \
> - task-window.h \
> $(builddir)/taskmanager-marshal.c \
> $(builddir)/taskmanager-marshal.h \
> xutils.c \
> ====
>
> Why did task-window.* move?

No particularly reason why it has moved. (I think I have removed it accidentally and then added again on the wrong place)

>
> === modified file 'applets/taskmanager/task-drag-indicator.c'
> --- applets/taskmanager/task-drag-indicator.c 2009-06-19 09:35:43 +0000
> +++ applets/taskmanager/task-drag-indicator.c 2009-06-20 14:17:54 +0000
> @@ -13,7 +13,7 @@
> * You should have received a copy of the GNU General Public License
> * along with this program. If not, see <http://www.gnu.org/licenses/>.
> *
> - * Authored by Neil Jagdish Patel <email address hidden>
> + * Authored by Hannes Verschore <email address hidden>
> *
> */
>
> ====
>
> Any particular reason why you removed Neil as author here (and
> applets/taskmanager/task-drag-indicator.h)?

Reason: I have made those files and if there are problems with them they should contact me. I copied the license when creating the file, but forgot to change the author.

>
> In general, you should make sure that all of the code that you commented out
> (instead of deleted) should be annotated with the reason why you're commenting
> it.

I think the only code that is commented out is the code for refreshing the launcher list. The code still need to get adapted so it works. I leave the code there for adapting later on.

Revision history for this message
Mark Lee (malept) wrote :

> > === modified file 'applets/taskmanager/Makefile.am'
> > --- applets/taskmanager/Makefile.am 2009-05-19 01:06:12 +0000
> > +++ applets/taskmanager/Makefile.am 2009-06-26 11:00:10 +0000
> > @@ -17,14 +17,18 @@
> > task-drag-indicator.h \
> > task-icon.c \
> > task-icon.h \
> > + task-item.c \
> > + task-item.h \
> > + task-window.c \
> > + task-window.h \
> > task-launcher.c \
> > task-launcher.h \
> > task-manager.c \
> > task-manager.h \
> > + task-manager-api-wrapper.c \
> > + task-manager-api-wrapper.h \
> > task-settings.c \
> > task-settings.h \
> > - task-window.c \
> > - task-window.h \
> > $(builddir)/taskmanager-marshal.c \
> > $(builddir)/taskmanager-marshal.h \
> > xutils.c \
> > ====
> >
> > Why did task-window.* move?
>
> No particularly reason why it has moved. (I think I have removed it
> accidentally and then added again on the wrong place)

Once the task-window.* entries are moved back (make sure you use tabs, not spaces), I have no objection to merging to rewrite.

Revision history for this message
haytjes (h4writer) wrote :

> > > === modified file 'applets/taskmanager/Makefile.am'
> > > --- applets/taskmanager/Makefile.am 2009-05-19 01:06:12 +0000
> > > +++ applets/taskmanager/Makefile.am 2009-06-26 11:00:10 +0000
> > > @@ -17,14 +17,18 @@
> > > task-drag-indicator.h \
> > > task-icon.c \
> > > task-icon.h \
> > > + task-item.c \
> > > + task-item.h \
> > > + task-window.c \
> > > + task-window.h \
> > > task-launcher.c \
> > > task-launcher.h \
> > > task-manager.c \
> > > task-manager.h \
> > > + task-manager-api-wrapper.c \
> > > + task-manager-api-wrapper.h \
> > > task-settings.c \
> > > task-settings.h \
> > > - task-window.c \
> > > - task-window.h \
> > > $(builddir)/taskmanager-marshal.c \
> > > $(builddir)/taskmanager-marshal.h \
> > > xutils.c \
> > > ====
> > >
> > > Why did task-window.* move?
> >
> > No particularly reason why it has moved. (I think I have removed it
> > accidentally and then added again on the wrong place)
>
> Once the task-window.* entries are moved back (make sure you use tabs, not
> spaces), I have no objection to merging to rewrite.

I will adjust it. But currently I'm doing a vacation job and I'm not home tonight. So it will be tomorrow evening. I will ask dolfje to do tonight, but I'm not sure if he will do it.

Revision history for this message
Michal Hruby (mhr3) wrote :

I basically agree with moonbeam, this is way too big to be reviewed into detail, so I'd also say let's merge it and solve the problems as they come up...

Anyway, I did notice one small issue:

681 + if (priv->overlay_text)
682 + {
683 + awn_overlayable_remove_overlay (AWN_OVERLAYABLE (icon),
684 + AWN_OVERLAY (priv->overlay_text));
685 + g_object_unref (priv->overlay_text);
686 + priv->overlay_text = NULL;
687 + }

Overlays are initially unowned, so you do not need to unref them (the remove_overlay method will destroy them).

review: Approve
Revision history for this message
haytjes (h4writer) wrote :

> I basically agree with moonbeam, this is way too big to be reviewed into
> detail, so I'd also say let's merge it and solve the problems as they come
> up...
>
> Anyway, I did notice one small issue:
>
> 681 + if (priv->overlay_text)
> 682 + {
> 683 + awn_overlayable_remove_overlay (AWN_OVERLAYABLE (icon),
> 684 + AWN_OVERLAY (priv->overlay_text));
> 685 + g_object_unref (priv->overlay_text);
> 686 + priv->overlay_text = NULL;
> 687 + }
>
> Overlays are initially unowned, so you do not need to unref them (the
> remove_overlay method will destroy them).

Ah, good to know. I was really doubting about it.

Revision history for this message
haytjes (h4writer) wrote :

Sorry that it takes so long. I have problems with creating time to work on it. I had 30min yesterday and I thought I could do those tiny adjustments within time, but it didn't worked :(. (A bit strange). I didn't investigate yet what the problem was, why it didn't work, but I will check tonight and commit it.

Revision history for this message
haytjes (h4writer) wrote :

Sorry that it takes so long. I have problems with creating time to work on it. I had 30min yesterday and I thought I could do those tiny adjustments within time, but it didn't worked :(. (A bit strange). I didn't investigate yet what the problem was, why it didn't work, but I will check tonight and commit it.

lp:~h4writer/awn/taskmanager-rewrite updated
953. By haytjes

- adjusted some bits before merge like suggested by malept and mhr3

Revision history for this message
haytjes (h4writer) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'applets/taskmanager/Makefile.am'
2--- applets/taskmanager/Makefile.am 2009-05-19 01:06:12 +0000
3+++ applets/taskmanager/Makefile.am 2009-06-26 11:00:10 +0000
4@@ -17,14 +17,18 @@
5 task-drag-indicator.h \
6 task-icon.c \
7 task-icon.h \
8+ task-item.c \
9+ task-item.h \
10+ task-window.c \
11+ task-window.h \
12 task-launcher.c \
13 task-launcher.h \
14 task-manager.c \
15 task-manager.h \
16+ task-manager-api-wrapper.c \
17+ task-manager-api-wrapper.h \
18 task-settings.c \
19 task-settings.h \
20- task-window.c \
21- task-window.h \
22 $(builddir)/taskmanager-marshal.c \
23 $(builddir)/taskmanager-marshal.h \
24 xutils.c \
25
26=== modified file 'applets/taskmanager/task-drag-indicator.c'
27--- applets/taskmanager/task-drag-indicator.c 2009-06-19 09:35:43 +0000
28+++ applets/taskmanager/task-drag-indicator.c 2009-06-20 14:17:54 +0000
29@@ -13,7 +13,7 @@
30 * You should have received a copy of the GNU General Public License
31 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 *
33- * Authored by Neil Jagdish Patel <njpatel@gmail.com>
34+ * Authored by Hannes Verschore <hv1989@gmail.com>
35 *
36 */
37
38@@ -151,6 +151,12 @@
39 GtkWidget *drag_indicator = NULL;
40
41 drag_indicator = g_object_new (TASK_TYPE_DRAG_INDICATOR, NULL);
42+ gtk_widget_hide (drag_indicator);
43+
44+ //BUG: AwnApplet calls upon start gtk_widget_show_all. So even when gtk_widget_hide
45+ // gets called, it will get shown. So I'm forcing it to not listen to
46+ // 'gtk_widget_show_all' with this function. FIXME: improve AwnApplet
47+ gtk_widget_set_no_show_all (drag_indicator, TRUE);
48
49 return drag_indicator;
50 }
51
52=== modified file 'applets/taskmanager/task-drag-indicator.h'
53--- applets/taskmanager/task-drag-indicator.h 2009-05-27 15:57:06 +0000
54+++ applets/taskmanager/task-drag-indicator.h 2009-06-20 14:17:54 +0000
55@@ -13,7 +13,7 @@
56 * You should have received a copy of the GNU General Public License
57 * along with this program. If not, see <http://www.gnu.org/licenses/>.
58 *
59- * Authored by Neil Jagdish Patel <njpatel@gmail.com>
60+ * Authored by Hannes Verschore <hv1989@gmail.com>
61 *
62 */
63
64
65=== modified file 'applets/taskmanager/task-icon.c'
66--- applets/taskmanager/task-icon.c 2009-06-19 09:35:43 +0000
67+++ applets/taskmanager/task-icon.c 2009-06-26 11:00:10 +0000
68@@ -14,6 +14,7 @@
69 * along with this program. If not, see <http://www.gnu.org/licenses/>.
70 *
71 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
72+ * Hannes Verschore <hv1989@gmail.com>
73 *
74 */
75
76@@ -33,7 +34,7 @@
77 #include "task-launcher.h"
78 #include "task-settings.h"
79
80-G_DEFINE_TYPE (TaskIcon, task_icon, AWN_TYPE_ICON)
81+G_DEFINE_TYPE (TaskIcon, task_icon, AWN_TYPE_THEMED_ICON)
82
83 #define TASK_ICON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
84 TASK_TYPE_ICON, \
85@@ -41,7 +42,27 @@
86
87 struct _TaskIconPrivate
88 {
89- GSList *windows;
90+ //List containing the TaskItems
91+ GSList *items;
92+
93+ //The number of TaskItems that get shown
94+ guint shown_items;
95+
96+ //The number of TaskWindows (subclass of TaskItem) that needs attention
97+ guint needs_attention;
98+
99+ //The number of TaskWindows (subclass of TaskItem) that have the active state.
100+ guint is_active;
101+
102+ //The main item being used for the icon (and if alone for the text)
103+ TaskItem *main_item;
104+
105+ //Whetever this icon is visible or not
106+ gboolean visible;
107+
108+ //An overlay for showing number of items
109+ AwnOverlayText *overlay_text;
110+
111 GdkPixbuf *icon;
112 GtkWidget *dialog;
113
114@@ -64,13 +85,12 @@
115 {
116 PROP_0,
117
118- PROP_WINDOW,
119 PROP_DRAGGABLE
120 };
121
122 enum
123 {
124- ENSURE_LAYOUT,
125+ VISIBLE_CHANGED,
126
127 SOURCE_DRAG_FAIL,
128 SOURCE_DRAG_BEGIN,
129@@ -113,7 +133,7 @@
130 static gboolean task_icon_dialog_unfocus (GtkWidget *widget,
131 GdkEventFocus *event,
132 gpointer null);
133-/* Dnd 'source' forwards */
134+/* Dnd forwards */
135 static void task_icon_drag_data_get (GtkWidget *widget,
136 GdkDragContext *context,
137 GtkSelectionData *selection_data,
138@@ -148,6 +168,9 @@
139 guint time);
140
141 static gboolean _update_geometry(GtkWidget *widget);
142+static gboolean task_icon_refresh_geometry (TaskIcon *icon);
143+static void task_icon_refresh_visible (TaskIcon *icon);
144+static void task_icon_search_main_item (TaskIcon *icon);
145
146 /* GObject stuff */
147 static void
148@@ -161,11 +184,6 @@
149
150 switch (prop_id)
151 {
152- case PROP_WINDOW:
153- g_value_set_object (value,
154- priv->windows ? priv->windows->data : NULL);
155- break;
156-
157 case PROP_DRAGGABLE:
158 g_value_set_boolean (value, priv->draggable);
159 break;
160@@ -185,10 +203,6 @@
161
162 switch (prop_id)
163 {
164- case PROP_WINDOW:
165- task_icon_append_window (icon, g_value_get_object (value));
166- break;
167-
168 case PROP_DRAGGABLE:
169 task_icon_set_draggable (icon, g_value_get_boolean (value));
170 break;
171@@ -198,10 +212,15 @@
172 }
173 }
174
175+/**
176+ * Finalize the object and remove the list of windows,
177+ * the list of launchers and the timer of update_geometry.
178+ */
179 static void
180 task_icon_dispose (GObject *object)
181 {
182 TaskIconPrivate *priv = TASK_ICON_GET_PRIVATE (object);
183+
184 /*this needs to be done in dispose, not finalize, due to idiosyncracies of
185 AwnDialog*/
186 if (priv->dialog)
187@@ -209,6 +228,7 @@
188 gtk_widget_destroy (priv->dialog);
189 priv->dialog = NULL;
190 }
191+
192 G_OBJECT_CLASS (task_icon_parent_class)->dispose (object);
193 }
194
195@@ -218,13 +238,15 @@
196 TaskIconPrivate *priv = TASK_ICON_GET_PRIVATE (object);
197
198 /* FIXME Check to see if icon needs to be unreffed */
199- if (priv->windows)
200+ if (priv->items)
201 {
202- g_slist_free (priv->windows);
203- priv->windows = NULL;
204+ g_slist_free (priv->items);
205+ priv->items = NULL;
206 }
207 if(priv->update_geometry_id)
208+ {
209 g_source_remove(priv->update_geometry_id);
210+ }
211
212 G_OBJECT_CLASS (task_icon_parent_class)->finalize (object);
213 }
214@@ -234,13 +256,27 @@
215 {
216 TaskIconPrivate *priv = TASK_ICON (object)->priv;
217 GtkWidget *widget = GTK_WIDGET(object);
218-
219+
220+ if ( G_OBJECT_CLASS (task_icon_parent_class)->constructed)
221+ {
222+ G_OBJECT_CLASS (task_icon_parent_class)->constructed (object);
223+ }
224+
225+ //update geometry of icon every second.
226 priv->update_geometry_id = g_timeout_add_seconds (1, (GSourceFunc)_update_geometry, widget);
227 }
228-
229+
230+/**
231+ * Checks if the position of the widget has changed.
232+ * Upon change it asks the icon to refresh.
233+ * returns: TRUE when succeeds
234+ * FALSE when widget isn't an icon
235+ */
236 static gboolean
237 _update_geometry(GtkWidget *widget)
238 {
239+ return TRUE; //TODO solve
240+
241 gint x,y;
242 TaskIconPrivate *priv;
243 GdkWindow *win;
244@@ -251,6 +287,7 @@
245
246 win = gtk_widget_get_window (widget);
247 gdk_window_get_origin (win, &x, &y);
248+
249 if(priv->old_x != x || priv->old_y != y)
250 {
251 priv->old_x = x;
252@@ -260,7 +297,86 @@
253
254 return TRUE;
255 }
256-
257+
258+/**
259+ * Set the icon geometry of the windows in a task-icon.
260+ * This equals to the minimize position of the window.
261+ * TODO: not done (part2)
262+ */
263+static gboolean
264+task_icon_refresh_geometry (TaskIcon *icon)
265+{
266+ TaskSettings *settings;
267+ TaskIconPrivate *priv;
268+ GtkWidget *widget;
269+ GdkWindow *win;
270+ GSList *w;
271+ gint x, y, ww, width, height;
272+ gint i = 0, len = 0;
273+
274+ g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
275+
276+ priv = icon->priv;
277+ widget = GTK_WIDGET (icon);
278+
279+ //get the position of the widget
280+ win = gtk_widget_get_window (widget);
281+ gdk_window_get_origin (win, &x, &y);
282+
283+ settings = task_settings_get_default ();
284+
285+ switch (settings->orient)
286+ {
287+ case AWN_ORIENTATION_RIGHT:
288+ case AWN_ORIENTATION_LEFT:
289+ ww = GTK_WIDGET (icon)->allocation.height;
290+ break;
291+ case AWN_ORIENTATION_TOP:
292+ case AWN_ORIENTATION_BOTTOM:
293+ ww = GTK_WIDGET (icon)->allocation.width;
294+ break;
295+ default:
296+ g_error ("Orientation isn't right, left, top, bottom ??");
297+ break;
298+ }
299+
300+ /* FIXME: Do something clever here to allow the user to "scrub" the icon
301+ * for the windows.
302+ */
303+ len = g_slist_length (priv->items);
304+ ww = ww/len;
305+ for (w = priv->items; w; w = w->next)
306+ {
307+ if (!TASK_IS_WINDOW (w->data)) continue;
308+
309+ TaskWindow *window = TASK_WINDOW (w->data);
310+
311+ switch (settings->orient)
312+ {
313+ case AWN_ORIENTATION_RIGHT:
314+ width = settings->panel_size+settings->offset;
315+ height = ww + (i*ww);
316+ break;
317+ case AWN_ORIENTATION_LEFT:
318+ width = settings->panel_size+settings->offset;
319+ height = ww + (i*ww);
320+ break;
321+ case AWN_ORIENTATION_TOP:
322+ width = ww + (i*ww);
323+ height = settings->panel_size+settings->offset;
324+ break;
325+ default:
326+ width = ww + (i*ww);
327+ height = settings->panel_size+settings->offset;
328+ break;
329+ }
330+ task_window_set_icon_geometry (window, x, y,
331+ width,
332+ height);
333+ i++;
334+ }
335+ return FALSE;
336+}
337
338 static void
339 task_icon_class_init (TaskIconClass *klass)
340@@ -272,7 +388,7 @@
341 obj_class->constructed = task_icon_constructed;
342 obj_class->set_property = task_icon_set_property;
343 obj_class->get_property = task_icon_get_property;
344- obj_class->dispose = task_icon_dispose;
345+ obj_class->dispose = task_icon_dispose;
346 obj_class->finalize = task_icon_finalize;
347
348 wid_class->configure_event = task_icon_configure_event;
349@@ -285,15 +401,7 @@
350 wid_class->drag_leave = task_icon_dest_drag_leave;
351 wid_class->drag_data_received = task_icon_dest_drag_data_received;
352
353-
354 /* Install properties first */
355- pspec = g_param_spec_object ("taskwindow",
356- "TaskWindow",
357- "TaskWindow",
358- TASK_TYPE_WINDOW,
359- G_PARAM_READWRITE);
360- g_object_class_install_property (obj_class, PROP_WINDOW, pspec);
361-
362 pspec = g_param_spec_boolean ("draggable",
363 "Draggable",
364 "TaskIcon is draggable?",
365@@ -302,11 +410,11 @@
366 g_object_class_install_property (obj_class, PROP_DRAGGABLE, pspec);
367
368 /* Install signals */
369- _icon_signals[ENSURE_LAYOUT] =
370- g_signal_new ("ensure-layout",
371+ _icon_signals[VISIBLE_CHANGED] =
372+ g_signal_new ("visible_changed",
373 G_OBJECT_CLASS_TYPE (obj_class),
374 G_SIGNAL_RUN_LAST,
375- G_STRUCT_OFFSET (TaskIconClass, ensure_layout),
376+ G_STRUCT_OFFSET (TaskIconClass, visible_changed),
377 NULL, NULL,
378 g_cclosure_marshal_VOID__VOID,
379 G_TYPE_NONE, 0);
380@@ -368,11 +476,17 @@
381 g_signal_connect (G_OBJECT (priv->dialog),"focus-out-event",
382 G_CALLBACK (task_icon_dialog_unfocus),NULL);
383 priv->icon = NULL;
384- priv->windows = NULL;
385+ priv->items = NULL;
386 priv->drag_tag = 0;
387 priv->drag_motion = FALSE;
388 priv->gets_dragged = FALSE;
389 priv->update_geometry_id = 0;
390+ priv->shown_items = 0;
391+ priv->needs_attention = 0;
392+ priv->is_active = 0;
393+ priv->main_item = NULL;
394+ priv->visible = FALSE;
395+ priv->overlay_text = NULL;
396
397 awn_icon_set_orientation (AWN_ICON (icon), AWN_ORIENTATION_BOTTOM);
398
399@@ -394,88 +508,46 @@
400 GDK_ACTION_MOVE);
401 }
402
403+/**
404+ * Creates a new TaskIcon, hides it and returns it.
405+ * (Hiding is because there are no visible TaskItems yet in the TaskIcon)
406+ */
407 GtkWidget *
408-task_icon_new_for_window (TaskWindow *window)
409+task_icon_new ()
410 {
411- GtkWidget *icon = NULL;
412-
413- g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);
414-
415- icon = g_object_new (TASK_TYPE_ICON,
416- "taskwindow", window,
417- NULL);
418+ GtkWidget *icon = g_object_new (TASK_TYPE_ICON, NULL);
419+ gtk_widget_hide (icon);
420+
421+ //BUG: AwnApplet calls upon start gtk_widget_show_all. So even when gtk_widget_hide
422+ // gets called, it will get shown. So I'm forcing it to not listen to
423+ // 'gtk_widget_show_all' with this function. FIXME: improve AwnApplet
424+ gtk_widget_set_no_show_all (icon, TRUE);
425+
426 return icon;
427 }
428
429-/*
430- * Public Functions
431+/**
432+ * The name of the main TaskItem in this TaskIcon changed.
433+ * So update the tooltip text.
434 */
435-gboolean
436-task_icon_is_skip_taskbar (TaskIcon *icon)
437-{
438- g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
439-
440- /*if (TASK_IS_LAUNCHER_WINDOW (icon->priv->windows->data))
441- return FALSE;*/
442-
443- if (icon->priv->windows)
444- return task_window_is_hidden (icon->priv->windows->data);
445-
446- return FALSE;
447-}
448-
449-gboolean
450-task_icon_is_in_viewport (TaskIcon *icon, WnckWorkspace *space)
451-{
452- g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
453-
454- /*if (TASK_IS_LAUNCHER_WINDOW (icon->priv->windows->data))
455- return TRUE;*/
456-
457- if (icon->priv->windows)
458- return task_window_is_on_workspace (icon->priv->windows->data, space);
459-
460- return TRUE;
461-}
462-
463-static void
464-window_closed (TaskIcon *icon, TaskWindow *old_window)
465-{
466- TaskIconPrivate *priv;
467-
468- g_return_if_fail (TASK_IS_ICON (icon));
469- g_return_if_fail (TASK_IS_WINDOW (old_window));
470- priv = icon->priv;
471-
472- if (! TASK_IS_LAUNCHER(old_window))
473- {
474- priv->windows = g_slist_remove (priv->windows, old_window);
475- }
476-
477- if (g_slist_length (priv->windows) == 0)
478- {
479- gtk_widget_destroy (GTK_WIDGET (icon));
480- }
481- else
482- {
483- /* Load up with new icon etc */
484- }
485-}
486-
487-static void
488-on_window_name_changed (TaskWindow *window,
489- const gchar *name,
490- TaskIcon *icon)
491+static void
492+on_main_item_name_changed (TaskItem *item,
493+ const gchar *name,
494+ TaskIcon *icon)
495 {
496 g_return_if_fail (TASK_IS_ICON (icon));
497
498 awn_icon_set_tooltip_text (AWN_ICON (icon), name);
499 }
500
501+/**
502+ * The icon of the main TaskItem in this TaskIcon changed.
503+ * So update the icon of the TaskIcon (AwnIcon).
504+ */
505 static void
506-on_window_icon_changed (TaskWindow *window,
507- GdkPixbuf *pixbuf,
508- TaskIcon *icon)
509+on_main_item_icon_changed (TaskItem *item,
510+ GdkPixbuf *pixbuf,
511+ TaskIcon *icon)
512 {
513 TaskIconPrivate *priv;
514
515@@ -490,263 +562,460 @@
516 awn_icon_set_from_pixbuf (AWN_ICON (icon), priv->icon);
517 }
518
519+/**
520+ * The visibility of the main TaskItem in this TaskIcon changed.
521+ * Because normally the main TaskItem should always be visible,
522+ * it searches after a new main TaskItem.
523+ */
524+static void
525+on_main_item_visible_changed (TaskItem *item,
526+ gboolean visible,
527+ TaskIcon *icon)
528+{
529+ g_return_if_fail (TASK_IS_ICON (icon));
530+
531+ /* the main TaskItem should have been visible, so if
532+ the main TaskItem becomes visible only now,
533+ it indicates a bug.
534+ FIXME: this is possible atm in TaskWindow */
535+ if (visible) return;
536+
537+ task_icon_search_main_item (icon);
538+}
539+
540+/**
541+ * Notify that the icon that a window is closed. The window gets
542+ * removed from the list and when this icon doesn't has any
543+ * launchers and no windows it will get destroyed.
544+ */
545+static void
546+_destroyed_task_item (TaskIcon *icon, TaskItem *old_item)
547+{
548+ TaskIconPrivate *priv;
549+
550+ g_return_if_fail (TASK_IS_ICON (icon));
551+ g_return_if_fail (TASK_IS_ITEM (old_item));
552+
553+ priv = icon->priv;
554+ priv->items = g_slist_remove (priv->items, old_item);
555+
556+ if (old_item == priv->main_item)
557+ {
558+ task_icon_search_main_item (icon);
559+ }
560+
561+ task_icon_refresh_visible (icon);
562+
563+ if (g_slist_length (priv->items) == 0)
564+ {
565+ gtk_widget_destroy (GTK_WIDGET (icon));
566+ }
567+ else
568+ {
569+ /* TODO: Load up with new icon etc */
570+ }
571+}
572+
573+/**
574+ * Searches for a new main item.
575+ * A main item is used for displaying its icon and also the text (if there is only one item)
576+ * Attention: this function doesn't check if it is needed to switch to a new main item.
577+ */
578+static void
579+task_icon_search_main_item (TaskIcon *icon)
580+{
581+ TaskIconPrivate *priv;
582+ GSList *i;
583+ TaskItem *main_item = NULL;
584+
585+ g_return_if_fail (TASK_IS_ICON (icon));
586+
587+ priv = icon->priv;
588+
589+ for (i = priv->items; i; i = i->next)
590+ {
591+ TaskItem *item = i->data;
592+
593+ if (!task_item_is_visible (item)) continue;
594+
595+ main_item = item;
596+ break;
597+ }
598+
599+ //remove signals of old main_item
600+ if (priv->main_item)
601+ {
602+ g_signal_handlers_disconnect_by_func(priv->main_item,
603+ G_CALLBACK (on_main_item_name_changed), icon);
604+ g_signal_handlers_disconnect_by_func(priv->main_item,
605+ G_CALLBACK (on_main_item_icon_changed), icon);
606+ g_signal_handlers_disconnect_by_func(priv->main_item,
607+ G_CALLBACK (on_main_item_visible_changed), icon);
608+ priv->main_item = NULL;
609+ }
610+
611+ if (main_item)
612+ {
613+ priv->main_item = main_item;
614+ priv->icon = task_item_get_icon (priv->main_item);
615+ awn_icon_set_from_pixbuf (AWN_ICON (icon), priv->icon);
616+ awn_icon_set_tooltip_text (AWN_ICON (icon),
617+ task_item_get_name (priv->main_item));
618+ g_signal_connect (priv->main_item, "name-changed",
619+ G_CALLBACK (on_main_item_name_changed), icon);
620+ g_signal_connect (priv->main_item, "icon-changed",
621+ G_CALLBACK (on_main_item_icon_changed), icon);
622+ g_signal_connect (priv->main_item, "visible-changed",
623+ G_CALLBACK (on_main_item_visible_changed), icon);
624+ }
625+}
626+
627+/**
628+ *
629+ */
630+static void
631+task_icon_refresh_visible (TaskIcon *icon)
632+{
633+ TaskIconPrivate *priv;
634+ GSList *w;
635+ guint count = 0;
636+ guint count_windows = 0;
637+
638+ g_return_if_fail (TASK_IS_ICON (icon));
639+
640+ priv = icon->priv;
641+
642+ for (w = priv->items; w; w = w->next)
643+ {
644+ TaskItem *item = w->data;
645+
646+ if (!task_item_is_visible (item)) continue;
647+ count++;
648+
649+ if (!TASK_IS_WINDOW (item)) continue;
650+ count_windows++;
651+ }
652+
653+ awn_icon_set_indicator_count (AWN_ICON (icon), (count_windows>0) ? 1 : 0);
654+
655+ if (count != priv->shown_items)
656+ {
657+ g_debug("shown items changed: %i", count);
658+
659+ if (count > 1)
660+ {
661+ if (!priv->overlay_text)
662+ {
663+ priv->overlay_text = awn_overlay_text_new ();
664+ awn_overlayable_add_overlay (AWN_OVERLAYABLE (icon),
665+ AWN_OVERLAY (priv->overlay_text));
666+ g_object_set (G_OBJECT (priv->overlay_text),
667+ "gravity", GDK_GRAVITY_SOUTH_EAST,
668+ "font-sizing", AWN_FONT_SIZE_LARGE,
669+ "text_color_astr", "#FFFFFFFF",
670+ "apply-effects", TRUE,
671+ NULL);
672+ }
673+ gchar* count_str = g_strdup_printf ("%i",count);
674+ g_object_set (G_OBJECT (priv->overlay_text),
675+ "text", count_str,
676+ NULL);
677+ g_free (count_str);
678+ }
679+ else
680+ {
681+ if (priv->overlay_text)
682+ {
683+ awn_overlayable_remove_overlay (AWN_OVERLAYABLE (icon),
684+ AWN_OVERLAY (priv->overlay_text));
685+ g_object_unref (priv->overlay_text);
686+ priv->overlay_text = NULL;
687+ }
688+ }
689+
690+ if (count == 0)
691+ {
692+ priv->visible = FALSE;
693+ }
694+ else
695+ {
696+ if (!priv->main_item)
697+ task_icon_search_main_item (icon);
698+
699+ priv->visible = TRUE;
700+ }
701+
702+ g_signal_emit (icon, _icon_signals[VISIBLE_CHANGED], 0);
703+ }
704+
705+ priv->shown_items = count;
706+}
707+
708+/**
709+ * The 'active' state of a TaskWindow changed.
710+ * If this is the only TaskWindow that's active,
711+ * the TaskIcon will get an active state.
712+ * If it the last TaskWindow that isn't active anymore
713+ * the TaskIcon will get an inactive state too.
714+ * STATE: adjusted
715+ * PROBLEM: It shouldn't get called when the state didn't change.
716+ Else the count of windows that need have the active state will be off.
717+ */
718 static void
719 on_window_active_changed (TaskWindow *window,
720 gboolean is_active,
721 TaskIcon *icon)
722 {
723+ TaskIconPrivate *priv;
724+ GSList *w;
725+ guint count = 0;
726+
727 g_return_if_fail (TASK_IS_ICON (icon));
728
729- awn_icon_set_is_active (AWN_ICON (icon), is_active);
730+ priv = icon->priv;
731+
732+ for (w = priv->items; w; w = w->next)
733+ {
734+ TaskItem *item = w->data;
735+
736+ if (!TASK_IS_WINDOW (item)) continue;
737+ if (!task_item_is_visible (item)) continue;
738+ if (!task_window_is_active (TASK_WINDOW (item))) continue;
739+
740+ count++;
741+ }
742+
743+ if (priv->is_active == 0 && count == 1)
744+ {
745+ awn_icon_set_is_active (AWN_ICON (icon), TRUE);
746+ }
747+ else if (priv->is_active == 1 && count == 0)
748+ {
749+ awn_icon_set_is_active (AWN_ICON (icon), FALSE);
750+ }
751+
752+ priv->is_active = count;
753 }
754
755+/**
756+ * The 'needs attention' state of a window changed.
757+ * If a window needs attention and there isn't one yet, it will
758+ * start the animation. When every window don't need attention anymore
759+ * it will stop the animation.
760+ * STATE: adjusted
761+ * TODO: h4writer - check if it is possible to interupt animation mid-air,
762+ * and let it start again, if there is a 2nd/3rd window that needs attention.
763+ * BUG: when icon becomes visible again it needs to be checked if it needs attention again.
764+ */
765 static void
766 on_window_needs_attention_changed (TaskWindow *window,
767 gboolean needs_attention,
768 TaskIcon *icon)
769 {
770+ TaskIconPrivate *priv;
771+ GSList *w;
772+ guint count = 0;
773+
774 g_return_if_fail (TASK_IS_ICON (icon));
775
776- if (needs_attention)
777+ priv = icon->priv;
778+
779+ for (w = priv->items; w; w = w->next)
780+ {
781+ TaskItem *item = w->data;
782+
783+ if (!TASK_IS_WINDOW (item)) continue;
784+ if (!task_item_is_visible (item)) continue;
785+ if (!task_window_needs_attention (TASK_WINDOW (item))) continue;
786+
787+ count++;
788+ }
789+
790+ if (priv->needs_attention == 0 && count == 1)
791+ {
792 awn_icon_set_effect (AWN_ICON (icon),AWN_EFFECT_ATTENTION);
793- else
794- awn_effects_stop (awn_overlayable_get_effects (AWN_OVERLAYABLE (icon)),
795+ }
796+ else if (priv->needs_attention == 1 && count == 0)
797+ {
798+ awn_effects_stop (awn_overlayable_get_effects (AWN_OVERLAYABLE (icon)),
799 AWN_EFFECT_ATTENTION);
800-}
801-
802-static void
803-on_window_workspace_changed (TaskWindow *window,
804- WnckWorkspace *space,
805- TaskIcon *icon)
806-{
807- g_return_if_fail (TASK_IS_ICON (icon));
808+ }
809
810- g_signal_emit (icon, _icon_signals[ENSURE_LAYOUT], 0);
811-}
812-
813-static void
814-on_window_message_changed (TaskWindow *window,
815- const gchar *message,
816- TaskIcon *icon)
817-{
818- g_return_if_fail (TASK_IS_ICON (icon));
819-
820- awn_icon_set_message (AWN_ICON (icon), message);
821-}
822-
823-static void
824-on_window_progress_changed (TaskWindow *window,
825- gfloat progress,
826+ priv->needs_attention = count;
827+}
828+
829+/**
830+ * When the progress of a TaskWindow has changed,
831+ * it will recalculate the process of all the
832+ * TaskWindows this TaskIcon contains.
833+ * STATE: adjusted
834+ */
835+static void
836+on_window_progress_changed (TaskWindow *window,
837+ gfloat adjusted_progress,
838 TaskIcon *icon)
839 {
840- g_return_if_fail (TASK_IS_ICON (icon));
841-
842- awn_icon_set_progress (AWN_ICON (icon), progress);
843-}
844-
845-static void
846-on_window_hidden_changed (TaskWindow *window,
847- gboolean is_hidden,
848- TaskIcon *icon)
849-{
850- g_return_if_fail (TASK_IS_ICON (icon));
851-
852- g_signal_emit (icon, _icon_signals[ENSURE_LAYOUT], 0);
853-}
854-
855-static void
856-on_window_running_changed (TaskWindow *window,
857- gboolean is_running,
858- TaskIcon *icon)
859-{
860- g_return_if_fail (TASK_IS_ICON (icon));
861- awn_icon_set_indicator_count (AWN_ICON (icon), is_running ? 1 : 0);
862-}
863-
864-void
865-task_icon_remove_window (TaskIcon *icon,
866- WnckWindow *window)
867-{
868- GSList * w;
869- TaskIconPrivate *priv;
870-
871- g_return_if_fail (TASK_IS_ICON (icon));
872- g_return_if_fail (WNCK_IS_WINDOW (window));
873- priv = icon->priv;
874- for (w = priv->windows;w;w=w->next)
875- {
876- TaskWindow * task_win = w->data;
877- if (! TASK_IS_WINDOW(task_win) )
878- {
879- continue;
880- }
881- if (task_win->priv->window == window)
882- {
883- g_assert (TASK_IS_WINDOW(task_win));
884- if (! TASK_IS_LAUNCHER(task_win) )
885- {
886- priv->windows = g_slist_remove (priv->windows, task_win);
887- }
888- }
889- }
890-}
891-
892-/*
893- FIXME 2nd arg isn't the WnckWindow
894- */
895-static void
896-_task_icon_launcher_change (TaskLauncher * launcher,
897- WnckWindow * wnck_win,
898- TaskIcon * icon)
899-{
900- GtkWidget * grouped_icon = NULL;
901- if (wnck_win)
902- {
903- TaskWindow * taskwin = task_window_new (TASK_WINDOW(launcher)->priv->window);
904- grouped_icon = task_icon_new_for_window (taskwin);
905- gtk_widget_show (grouped_icon);
906- gtk_container_add (GTK_CONTAINER(icon->priv->dialog),grouped_icon);
907- }
908-
909-}
910-
911-void
912-task_icon_append_window (TaskIcon *icon,
913- TaskWindow *window)
914-{
915- TaskIconPrivate *priv;
916- gboolean first_window = FALSE;
917- static gboolean recursing = FALSE;
918-
919- g_assert (window);
920+ TaskIconPrivate *priv;
921+ GSList *w;
922+ gfloat progress = 0;
923+ guint len = 0;
924+
925+ g_return_if_fail (TASK_IS_ICON (icon));
926+
927+ priv = icon->priv;
928+
929+ for (w = priv->items; w; w = w->next)
930+ {
931+ TaskItem *item = w->data;
932+
933+ if (!TASK_IS_WINDOW (item)) continue;
934+ if (!task_item_is_visible (item)) continue;
935+
936+ if (progress != -1)
937+ {
938+ progress += task_window_get_progress (TASK_WINDOW (item));
939+ len++;
940+ }
941+ }
942+
943+ awn_icon_set_progress (AWN_ICON (icon), progress/len);
944+}
945+
946+/**
947+ * When a TaskWindow becomes visible or invisible,
948+ * update the number of shown windows.
949+ * If because of that the icon has no shown TaskWindows
950+ * anymore it will get hidden. If there was no shown
951+ * TaskWindow and now the first one gets visible,
952+ * then show TaskIcon.
953+ * STATE: adjusted
954+ */
955+static void
956+on_item_visible_changed (TaskItem *item,
957+ gfloat visible,
958+ TaskIcon *icon)
959+{
960+ g_return_if_fail (TASK_IS_ICON (icon));
961+ g_return_if_fail (TASK_IS_ITEM (item));
962+
963+ task_icon_refresh_visible (icon);
964+}
965+
966+/**
967+ * Public Functions
968+ */
969+
970+/**
971+ * Returns whetever this icon should be visible.
972+ * (That means it should contain atleast 1 visible item)
973+ */
974+gboolean
975+task_icon_is_visible (TaskIcon *icon)
976+{
977+ g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
978+
979+ return icon->priv->visible;
980+}
981+
982+/**
983+ * Returns whetever this icon contains atleast one (visible?) launcher.
984+ * TODO: adapt TaskIcon so it has a guint with the numbers of TaskLaunchers/TaskWindows
985+ */
986+gboolean
987+task_icon_contains_launcher (TaskIcon *icon)
988+{
989+ TaskIconPrivate *priv;
990+ GSList *w;
991+
992+ g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
993+
994+ priv = icon->priv;
995+
996+ for (w = priv->items; w; w = w->next)
997+ {
998+ TaskItem *item = w->data;
999+
1000+ if (!task_item_is_visible (item)) continue;
1001+
1002+ if (TASK_IS_LAUNCHER (item))
1003+ return TRUE;
1004+ }
1005+ return FALSE;
1006+}
1007+
1008+guint
1009+task_icon_match_item (TaskIcon *icon,
1010+ TaskItem *item_to_match)
1011+{
1012+ TaskIconPrivate *priv;
1013+ GSList *w;
1014+ guint max_score = 0;
1015+
1016+ g_return_val_if_fail (TASK_IS_ICON (icon), 0);
1017+ g_return_val_if_fail (TASK_IS_ITEM (item_to_match), 0);
1018+
1019+ priv = icon->priv;
1020+
1021+ for (w = priv->items; w; w = w->next)
1022+ {
1023+ TaskItem *item = w->data;
1024+ guint score;
1025+
1026+ if (!task_item_is_visible (item)) continue;
1027+
1028+ score = task_item_match (item, item_to_match);
1029+ if (score > max_score)
1030+ max_score = score;
1031+ }
1032+
1033+ return max_score;
1034+}
1035+
1036+/**
1037+ * Adds a TaskWindow to this task-icon
1038+ */
1039+void
1040+task_icon_append_item (TaskIcon *icon,
1041+ TaskItem *item)
1042+{
1043+ TaskIconPrivate *priv;
1044+
1045+ g_assert (item);
1046 g_assert (icon);
1047 g_return_if_fail (TASK_IS_ICON (icon));
1048- g_return_if_fail (TASK_IS_WINDOW (window));
1049+ g_return_if_fail (TASK_IS_ITEM (item));
1050+
1051 priv = icon->priv;
1052
1053- /* Is this the first, main, window of this icon? */
1054- if (priv->windows == NULL)
1055- first_window = TRUE;
1056-
1057- priv->windows = g_slist_append (priv->windows, window);
1058- g_object_weak_ref (G_OBJECT (window), (GWeakNotify)window_closed, icon);
1059-
1060- /* If it's the first window, let's set-up our icon accordingly */
1061- if (first_window)
1062+ priv->items = g_slist_append (priv->items, item);
1063+ gtk_widget_show_all (GTK_WIDGET (item));
1064+ gtk_container_add (GTK_CONTAINER (priv->dialog), GTK_WIDGET (item));
1065+
1066+ g_object_weak_ref (G_OBJECT (item), (GWeakNotify)_destroyed_task_item, icon);
1067+
1068+ task_icon_refresh_visible (icon);
1069+
1070+ /* Connect item signals */
1071+ g_signal_connect (item, "visible-changed",
1072+ G_CALLBACK (on_item_visible_changed), icon);
1073+
1074+ /* Connect window signals */
1075+ if (TASK_IS_WINDOW (item))
1076 {
1077- priv->icon = task_window_get_icon (window);
1078- awn_icon_set_from_pixbuf (AWN_ICON (icon), priv->icon);
1079-
1080- awn_icon_set_tooltip_text (AWN_ICON (icon), task_window_get_name (window));
1081- on_window_needs_attention_changed (window,
1082- task_window_needs_attention (window),
1083- icon);
1084-
1085- awn_icon_set_indicator_count (AWN_ICON (icon),
1086- task_window_get_is_running (window) ? 1 : 0);
1087-
1088- g_signal_connect (window, "name-changed",
1089- G_CALLBACK (on_window_name_changed), icon);
1090- g_signal_connect (window, "icon-changed",
1091- G_CALLBACK (on_window_icon_changed), icon);
1092+ TaskWindow *window = TASK_WINDOW (item);
1093 g_signal_connect (window, "active-changed",
1094 G_CALLBACK (on_window_active_changed), icon);
1095 g_signal_connect (window, "needs-attention",
1096 G_CALLBACK (on_window_needs_attention_changed), icon);
1097- g_signal_connect (window, "workspace-changed",
1098- G_CALLBACK (on_window_workspace_changed), icon);
1099- g_signal_connect (window, "message-changed",
1100- G_CALLBACK (on_window_message_changed), icon);
1101 g_signal_connect (window, "progress-changed",
1102 G_CALLBACK (on_window_progress_changed), icon);
1103- g_signal_connect (window, "hidden-changed",
1104- G_CALLBACK (on_window_hidden_changed), icon);
1105- g_signal_connect (window, "running-changed",
1106- G_CALLBACK (on_window_running_changed), icon);
1107- }
1108-
1109- if (!recursing)
1110- {
1111- recursing = TRUE;
1112- GtkWidget * grouped_icon = NULL;
1113- if (!TASK_IS_LAUNCHER(window))
1114- {
1115- g_assert (window->priv->window);
1116- grouped_icon = task_icon_new_for_window (window);
1117- }
1118- else if (TASK_IS_LAUNCHER(window) )
1119- {
1120- TaskWindowPrivate *win_priv = window->priv;
1121- g_signal_connect (G_OBJECT(window),"notify::taskwindow",
1122- G_CALLBACK(_task_icon_launcher_change),icon);
1123- if (win_priv->window)
1124- {
1125- TaskWindow * taskwin = task_window_new (win_priv->window);
1126- grouped_icon = task_icon_new_for_window (taskwin);
1127- }
1128- }
1129- if (grouped_icon)
1130- {
1131- gtk_container_add (GTK_CONTAINER(priv->dialog),grouped_icon);
1132-// g_object_weak_ref (G_OBJECT (window), (GWeakNotify)window_closed, grouped_icon);
1133- gtk_widget_show (grouped_icon);
1134- }
1135- }
1136- recursing = FALSE;
1137-}
1138-
1139-gboolean
1140-task_icon_is_launcher (TaskIcon *icon)
1141-{
1142- TaskIconPrivate *priv;
1143-
1144- g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
1145- priv = icon->priv;
1146-
1147- if (priv->windows)
1148- {
1149- /* For now do it this way ?! */
1150- if (TASK_IS_LAUNCHER (priv->windows->data))
1151- return TRUE;
1152- }
1153- return FALSE;
1154-}
1155-
1156-TaskLauncher*
1157-task_icon_get_launcher (TaskIcon *icon)
1158-{
1159- TaskIconPrivate *priv;
1160-
1161- g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
1162- priv = icon->priv;
1163-
1164- if (priv->windows)
1165- {
1166- /* For now do it this way ?! */
1167- if (TASK_IS_LAUNCHER (priv->windows->data))
1168- return TASK_LAUNCHER(priv->windows->data);
1169- }
1170- return NULL;
1171-}
1172-
1173-TaskWindow*
1174-task_icon_get_window (TaskIcon *icon)
1175-{
1176- TaskIconPrivate *priv;
1177-
1178- g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
1179- priv = icon->priv;
1180-
1181- if (priv->windows)
1182- {
1183- /* For now do it this way ?! */
1184-// if (TASK_IS_WINDOW (priv->windows->data))
1185- return TASK_WINDOW(priv->windows->data);
1186- }
1187- return NULL;
1188-}
1189-
1190-
1191+ }
1192+}
1193+
1194+/**
1195+ *
1196+ * TODO: h4writer - adjust 2nd round
1197+ */
1198 void
1199 task_icon_refresh_icon (TaskIcon *icon)
1200 {
1201@@ -755,87 +1024,9 @@
1202 g_return_if_fail (TASK_IS_ICON (icon));
1203 priv = icon->priv;
1204
1205- if (priv->windows && priv->windows->data)
1206+ if (priv->items && priv->items->data)
1207 awn_icon_set_from_pixbuf (AWN_ICON (icon),
1208- task_window_get_icon (priv->windows->data));
1209-}
1210-
1211-gboolean
1212-task_icon_refresh_geometry (TaskIcon *icon)
1213-{
1214- TaskSettings *settings;
1215- TaskIconPrivate *priv;
1216- GtkWidget *widget;
1217- GdkWindow *win;
1218- GSList *w;
1219- gint x, y, ww, width, height;
1220- gint i = 0, len = 0;
1221-
1222- g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
1223- priv = icon->priv;
1224-
1225- widget = GTK_WIDGET (icon);
1226-
1227- //get the position of the widget
1228- win = gtk_widget_get_window (widget);
1229- gdk_window_get_origin (win, &x, &y);
1230-
1231- settings = task_settings_get_default ();
1232-
1233- switch (settings->orient)
1234- {
1235- case AWN_ORIENTATION_RIGHT:
1236- //x += settings->panel_size;
1237- ww = GTK_WIDGET (icon)->allocation.height;
1238- break;
1239- case AWN_ORIENTATION_LEFT:
1240- //x += settings->offset;
1241- ww = GTK_WIDGET (icon)->allocation.height;
1242- break;
1243- case AWN_ORIENTATION_TOP:
1244- //y += settings->offset;
1245- ww = GTK_WIDGET (icon)->allocation.width;
1246- break;
1247- default:
1248- //y += settings->panel_size;
1249- ww = GTK_WIDGET (icon)->allocation.width;
1250- break;
1251- }
1252-
1253- /* FIXME: Do something clever here to allow the user to "scrub" the icon
1254- * for the windows.
1255- */
1256- len = g_slist_length (priv->windows);
1257- ww = ww/len;
1258- for (w = priv->windows; w; w = w->next)
1259- {
1260- TaskWindow *window = w->data;
1261- switch (settings->orient)
1262- {
1263- case AWN_ORIENTATION_RIGHT:
1264- width = settings->panel_size+settings->offset;
1265- height = ww + (i*ww);
1266- break;
1267- case AWN_ORIENTATION_LEFT:
1268- width = settings->panel_size+settings->offset;
1269- height = ww + (i*ww);
1270- break;
1271- case AWN_ORIENTATION_TOP:
1272- width = ww + (i*ww);
1273- height = settings->panel_size+settings->offset;
1274- break;
1275- default:
1276- width = ww + (i*ww);
1277- height = settings->panel_size+settings->offset;
1278- break;
1279- }
1280- task_window_set_icon_geometry (window, x, y,
1281- width,
1282- height);
1283- i++;
1284- }
1285-
1286- return FALSE;
1287+ task_item_get_icon (priv->items->data));
1288 }
1289
1290 /*
1291@@ -861,78 +1052,146 @@
1292 return TRUE;
1293 }
1294
1295+/**
1296+ * Whenever there is a release event on the TaskIcon it will do the proper actions.
1297+ * left click: - start launcher = has no (visible) windows
1298+ * - activate window = when there is only one (visible) window
1299+ * - show dialog = when there are multiple (visible) windows
1300+ * middle click: - start launcher
1301+ * Returns: TRUE to stop other handlers from being invoked for the event.
1302+ * FALSE to propagate the event further.
1303+ * TODO: h4writer - adjust
1304+ */
1305 static gboolean
1306 task_icon_button_release_event (GtkWidget *widget,
1307 GdkEventButton *event)
1308 {
1309 TaskIconPrivate *priv;
1310- gint len;
1311+ TaskIcon *icon;
1312
1313 g_return_val_if_fail (TASK_IS_ICON (widget), FALSE);
1314- priv = TASK_ICON (widget)->priv;
1315-
1316- len = g_slist_length (priv->windows);
1317-
1318- if (event->button == 1)
1319+
1320+ icon = TASK_ICON (widget);
1321+ priv = icon->priv;
1322+
1323+ switch (event->button)
1324 {
1325- if(priv->gets_dragged)
1326- {
1327- return FALSE;
1328- }
1329- if (len == 1)
1330- {
1331- task_window_activate (priv->windows->data, event->time);
1332- return TRUE;
1333- }
1334- else if (len > 1)
1335- {
1336- if (GTK_WIDGET_VISIBLE(priv->dialog) )
1337- {
1338- gtk_widget_hide (priv->dialog);
1339+ case 1: // left click: (start launcher || activate window || show dialog)
1340+
1341+ if(priv->gets_dragged) return FALSE;
1342+
1343+ if (priv->shown_items == 0)
1344+ {
1345+ g_critical ("TaskIcon: The icons shouldn't contain a visible (and clickable) icon");
1346+ return FALSE;
1347+ }
1348+ else if (priv->shown_items == 1)
1349+ {
1350+ GSList *w;
1351+ /* Find the window/launcher that is shown */
1352+ for (w = priv->items; w; w = w->next)
1353+ {
1354+ TaskItem *item = w->data;
1355+
1356+ if (!task_item_is_visible (item)) continue;
1357+
1358+ task_item_left_click (item, event);
1359+
1360+ break;
1361+ }
1362+ return TRUE;
1363 }
1364 else
1365 {
1366- gtk_widget_show_all (priv->dialog);
1367+ GSList *w;
1368+ for (w = priv->items; w; w = w->next)
1369+ {
1370+ TaskItem *item = w->data;
1371+
1372+ if (!task_item_is_visible (item)) continue;
1373+
1374+ g_debug ("clicked on: %s", task_item_get_name (item));
1375+ }
1376+
1377+ //TODO: move to hover?
1378+ if (GTK_WIDGET_VISIBLE (priv->dialog) )
1379+ {
1380+ gtk_widget_hide (priv->dialog);
1381+ }
1382+ else
1383+ {
1384+ gtk_widget_show (priv->dialog);
1385+ }
1386 }
1387- }
1388- }
1389- else if (event->button == 2)
1390- {
1391- if (len >= 1 && TASK_IS_LAUNCHER (priv->windows->data))
1392- {
1393- task_launcher_middle_click (priv->windows->data, event);
1394- return TRUE;
1395- }
1396- }
1397+ break;
1398+
1399+ case 2: // middle click: start launcher
1400+
1401+ g_warning ("TaskIcon: FIXME: No support for starting launcher on middle click");
1402+
1403+ //TODO: start launcher
1404+ /*if (len >= 1 && TASK_IS_LAUNCHER (priv->windows->data))
1405+ {
1406+ task_launcher_middle_click (priv->windows->data, event);
1407+ return TRUE;
1408+ }*/
1409+
1410+ break;
1411+
1412+ default:
1413+ break;
1414+ }
1415+
1416 return FALSE;
1417 }
1418
1419+/**
1420+ * Whenever there is a press event on the TaskIcon it will do the proper actions.
1421+ * right click: - show the context menu if there is only one (visible) window
1422+ * Returns: TRUE to stop other handlers from being invoked for the event.
1423+ * FALSE to propagate the event further.
1424+ */
1425 static gboolean
1426 task_icon_button_press_event (GtkWidget *widget,
1427 GdkEventButton *event)
1428 {
1429 TaskIconPrivate *priv;
1430- guint len;
1431+ TaskIcon *icon;
1432
1433 g_return_val_if_fail (TASK_IS_ICON (widget), FALSE);
1434- priv = TASK_ICON (widget)->priv;
1435-
1436- if (event->button != 3)
1437+
1438+ icon = TASK_ICON (widget);
1439+ priv = icon->priv;
1440+
1441+ if (event->button != 3) return FALSE;
1442+
1443+ if (priv->shown_items == 0)
1444+ {
1445+ g_critical ("TaskIcon: The icons shouldn't contain a visible (and clickable) icon");
1446 return FALSE;
1447-
1448- len = g_slist_length (priv->windows);
1449-
1450- if (len == 1)
1451+ }
1452+ else if (priv->shown_items == 1)
1453 {
1454- /* We can just ask the window to popup as normal */
1455- task_window_popup_context_menu (priv->windows->data, event);
1456+ GSList *w;
1457+
1458+ /* Find the window/launcher that is shown */
1459+ for (w = priv->items; w; w = w->next)
1460+ {
1461+ TaskItem *item = w->data;
1462+
1463+ if (!task_item_is_visible (item)) continue;
1464+
1465+ task_item_right_click (item, event);
1466+
1467+ break;
1468+ }
1469 return TRUE;
1470 }
1471 else
1472 {
1473 g_warning ("TaskIcon: FIXME: No support for multiple windows right-click");
1474+ return FALSE;
1475 }
1476- return FALSE;
1477 }
1478
1479 static gboolean
1480@@ -976,6 +1235,9 @@
1481 //g_debug("draggable:%d", draggable);
1482 }
1483
1484+/**
1485+ * TODO: h4writer - second stage
1486+ */
1487 static gboolean
1488 drag_timeout (TaskIcon *icon)
1489 {
1490@@ -984,12 +1246,12 @@
1491 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
1492 priv = icon->priv;
1493
1494- if (priv->drag_motion == FALSE)
1495+/* if (priv->drag_motion == FALSE)
1496 return FALSE;
1497 else if (priv->windows->data)
1498 if (!task_window_is_active(priv->windows->data))
1499 task_window_activate (priv->windows->data, priv->drag_time);
1500-
1501+*/
1502 return FALSE;
1503 }
1504
1505@@ -1104,9 +1366,11 @@
1506 {
1507 /* If it is a launcher it should show that it accepts the drag.
1508 Else only the the timeout should get set to activate the window. */
1509- if (!priv->windows || !TASK_IS_LAUNCHER (priv->windows->data))
1510- gdk_drag_status (context, GDK_ACTION_DEFAULT, t);
1511- else
1512+
1513+ //TODO: h4writer - 2nd round
1514+ //if (!priv->items || !TASK_IS_LAUNCHER (priv->items->data))
1515+ // gdk_drag_status (context, GDK_ACTION_DEFAULT, t);
1516+ //else
1517 gdk_drag_status (context, GDK_ACTION_COPY, t);
1518 return TRUE;
1519 }
1520@@ -1151,7 +1415,7 @@
1521 TaskIconPrivate *priv;
1522 GSList *list;
1523 GError *error;
1524- TaskLauncher *launcher;
1525+ //TaskLauncher *launcher;
1526 GdkAtom target;
1527 gchar *target_name;
1528 gchar *sdata_data;
1529@@ -1170,13 +1434,14 @@
1530 }
1531
1532 /* If we are not a launcher, we don't care about this */
1533- if (!priv->windows || !TASK_IS_LAUNCHER (priv->windows->data))
1534- {
1535- gtk_drag_finish (context, FALSE, FALSE, time_);
1536- return;
1537- }
1538-
1539- launcher = priv->windows->data;
1540+ //TODO: h4writer - 2nd round
1541+ //if (!priv->windows || !TASK_IS_LAUNCHER (priv->windows->data))
1542+ //{
1543+ // gtk_drag_finish (context, FALSE, FALSE, time_);
1544+ // return;
1545+ //}
1546+ //
1547+ //launcher = priv->windows->data;
1548
1549 sdata_data = (gchar*)gtk_selection_data_get_data (sdata);
1550
1551@@ -1197,10 +1462,10 @@
1552 //FIXME: I think this function returns always FALSE (haytjes)
1553 // and I also think this isn't a bad idea to allow too.
1554 // I often drop a url on firefox, even when it is already open.
1555- if (task_launcher_has_window (launcher))
1556- {
1557- gtk_drag_finish (context, FALSE, FALSE, time_);
1558- }
1559+ //if (task_launcher_has_windows (launcher))
1560+ //{
1561+ // gtk_drag_finish (context, FALSE, FALSE, time_);
1562+ //}
1563
1564 error = NULL;
1565 list = awn_vfs_get_pathlist_from_string (sdata_data, &error);
1566@@ -1212,7 +1477,7 @@
1567 return;
1568 }
1569
1570- task_launcher_launch_with_data (launcher, list);
1571+ //task_launcher_launch_with_data (launcher, list);
1572
1573 g_slist_foreach (list, (GFunc)g_free, NULL);
1574 g_slist_free (list);
1575
1576=== modified file 'applets/taskmanager/task-icon.h'
1577--- applets/taskmanager/task-icon.h 2009-05-27 15:57:06 +0000
1578+++ applets/taskmanager/task-icon.h 2009-06-22 13:16:54 +0000
1579@@ -14,7 +14,7 @@
1580 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1581 *
1582 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
1583- *
1584+ * Hannes Verschore <hv1989@gmail.com>
1585 */
1586
1587 #ifndef _TASK_ICON_H_
1588@@ -24,6 +24,7 @@
1589 #include <gtk/gtk.h>
1590 #include <libawn/libawn.h>
1591
1592+#include "task-item.h"
1593 #include "task-window.h"
1594 #include "task-launcher.h"
1595
1596@@ -50,19 +51,19 @@
1597
1598 struct _TaskIcon
1599 {
1600- AwnIcon parent;
1601+ AwnThemedIcon parent;
1602
1603 TaskIconPrivate *priv;
1604 };
1605
1606 struct _TaskIconClass
1607 {
1608- AwnIconClass parent_class;
1609+ AwnThemedIconClass parent_class;
1610
1611 /*< vtable, not signals >*/
1612
1613 /*< signals >*/
1614- void (*ensure_layout) (TaskIcon *icon);
1615+ void (*visible_changed) (TaskIcon *icon);
1616 void (*source_drag_fail) (TaskIcon *icon);
1617 void (*source_drag_begin) (TaskIcon *icon);
1618 void (*source_drag_end) (TaskIcon *icon);
1619@@ -72,27 +73,24 @@
1620
1621 GType task_icon_get_type (void) G_GNUC_CONST;
1622
1623-GtkWidget* task_icon_new_for_window (TaskWindow *window);
1624-
1625-gboolean task_icon_is_skip_taskbar (TaskIcon *icon);
1626-
1627-gboolean task_icon_is_in_viewport (TaskIcon *icon,
1628- WnckWorkspace *space);
1629-
1630-void task_icon_append_window (TaskIcon *icon,
1631- TaskWindow *window);
1632-void task_icon_remove_window (TaskIcon *icon,
1633- WnckWindow *window);
1634-gboolean task_icon_is_launcher (TaskIcon *icon);
1635-TaskLauncher* task_icon_get_launcher (TaskIcon *icon);
1636-TaskWindow* task_icon_get_window (TaskIcon *icon);
1637-
1638-void task_icon_refresh_icon (TaskIcon *icon);
1639-
1640-gboolean task_icon_refresh_geometry (TaskIcon *icon);
1641-
1642-void task_icon_set_draggable (TaskIcon *icon,
1643- gboolean draggable);
1644+GtkWidget* task_icon_new ();
1645+
1646+gboolean task_icon_is_visible (TaskIcon *icon);
1647+gboolean task_icon_contains_launcher (TaskIcon *icon);
1648+
1649+void task_icon_append_item (TaskIcon *icon,
1650+ TaskItem *item);
1651+void task_icon_remove_item (TaskIcon *icon,
1652+ TaskItem *item);
1653+guint task_icon_match_item (TaskIcon *icon,
1654+ TaskItem *item);
1655+
1656+//void task_icon_remove_windows (TaskIcon *icon);
1657+
1658+void task_icon_refresh_icon (TaskIcon *icon);
1659+
1660+void task_icon_set_draggable (TaskIcon *icon,
1661+ gboolean draggable);
1662
1663 #endif /* _TASK_ICON_H_ */
1664
1665
1666=== added file 'applets/taskmanager/task-item.c'
1667--- applets/taskmanager/task-item.c 1970-01-01 00:00:00 +0000
1668+++ applets/taskmanager/task-item.c 2009-06-28 01:53:46 +0000
1669@@ -0,0 +1,301 @@
1670+/*
1671+ * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
1672+ *
1673+ * This program is free software: you can redistribute it and/or modify
1674+ * it under the terms of the GNU General Public License version 3 as
1675+ * published by the Free Software Foundation.
1676+ *
1677+ * This program is distributed in the hope that it will be useful,
1678+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1679+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1680+ * GNU General Public License for more details.
1681+ *
1682+ * You should have received a copy of the GNU General Public License
1683+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1684+ *
1685+ * Authored by Hannes Verschore <hv1989@gmail.com>
1686+ *
1687+ */
1688+
1689+#include "task-item.h"
1690+
1691+#include <libawn/libawn.h>
1692+
1693+G_DEFINE_ABSTRACT_TYPE (TaskItem, task_item, GTK_TYPE_EVENT_BOX)
1694+
1695+#define TASK_ITEM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
1696+ TASK_TYPE_ITEM, \
1697+ TaskItemPrivate))
1698+
1699+struct _TaskItemPrivate
1700+{
1701+ GtkWidget *box;
1702+ GtkWidget *name;
1703+ GtkWidget *icon;
1704+};
1705+
1706+enum
1707+{
1708+ PROP_0
1709+};
1710+
1711+enum
1712+{
1713+ NAME_CHANGED,
1714+ ICON_CHANGED,
1715+ VISIBLE_CHANGED,
1716+
1717+ LAST_SIGNAL
1718+};
1719+static guint32 _item_signals[LAST_SIGNAL] = { 0 };
1720+
1721+/* Forwards */
1722+static void task_item_name_changed (TaskItem *item, const gchar *name);
1723+static void task_item_icon_changed (TaskItem *item, GdkPixbuf *icon);
1724+static void task_item_visible_changed (TaskItem *item, gboolean visible);
1725+
1726+static gboolean task_item_button_release_event (GtkWidget *widget,
1727+ GdkEventButton *event);
1728+static gboolean task_item_button_press_event (GtkWidget *widget,
1729+ GdkEventButton *event);
1730+
1731+/* GObject stuff */
1732+static void
1733+task_item_class_init (TaskItemClass *klass)
1734+{
1735+ //GParamSpec *pspec;
1736+ GObjectClass *obj_class = G_OBJECT_CLASS (klass);
1737+ GtkWidgetClass *wid_class = GTK_WIDGET_CLASS (klass);
1738+
1739+ wid_class->button_release_event = task_item_button_release_event;
1740+ wid_class->button_press_event = task_item_button_press_event;
1741+
1742+ /* We implement the necessary funtions for a normal item */
1743+ klass->get_name = NULL;
1744+ klass->get_icon = NULL;
1745+ klass->is_visible = NULL;
1746+ klass->match = NULL;
1747+
1748+ /* Install signals */
1749+ _item_signals[NAME_CHANGED] =
1750+ g_signal_new ("name-changed",
1751+ G_OBJECT_CLASS_TYPE (obj_class),
1752+ G_SIGNAL_RUN_LAST,
1753+ G_STRUCT_OFFSET (TaskItemClass, name_changed),
1754+ NULL, NULL,
1755+ g_cclosure_marshal_VOID__STRING,
1756+ G_TYPE_NONE,
1757+ 1, G_TYPE_STRING);
1758+
1759+ _item_signals[ICON_CHANGED] =
1760+ g_signal_new ("icon-changed",
1761+ G_OBJECT_CLASS_TYPE (obj_class),
1762+ G_SIGNAL_RUN_LAST,
1763+ G_STRUCT_OFFSET (TaskItemClass, icon_changed),
1764+ NULL, NULL,
1765+ g_cclosure_marshal_VOID__OBJECT,
1766+ G_TYPE_NONE,
1767+ 1, GDK_TYPE_PIXBUF);
1768+
1769+ _item_signals[VISIBLE_CHANGED] =
1770+ g_signal_new ("visible-changed",
1771+ G_OBJECT_CLASS_TYPE (obj_class),
1772+ G_SIGNAL_RUN_LAST,
1773+ G_STRUCT_OFFSET (TaskItemClass, visible_changed),
1774+ NULL, NULL,
1775+ g_cclosure_marshal_VOID__BOOLEAN,
1776+ G_TYPE_NONE,
1777+ 1, G_TYPE_BOOLEAN);
1778+
1779+ g_type_class_add_private (obj_class, sizeof (TaskItemPrivate));
1780+}
1781+
1782+static void
1783+task_item_init (TaskItem *item)
1784+{
1785+ TaskItemPrivate *priv;
1786+
1787+ /* get and save private struct */
1788+ priv = item->priv = TASK_ITEM_GET_PRIVATE (item);
1789+
1790+ /* let this eventbox listen to every events */
1791+ gtk_event_box_set_above_child (GTK_EVENT_BOX (item), TRUE);
1792+
1793+ /* create content */
1794+ priv->box = gtk_hbox_new (FALSE, 10);
1795+ gtk_container_add (GTK_CONTAINER (item), priv->box);
1796+
1797+ priv->icon = awn_icon_new ();
1798+ gtk_box_pack_start (GTK_BOX (priv->box), priv->icon, FALSE, FALSE, 0);
1799+
1800+ priv->name = gtk_label_new ("");
1801+ gtk_box_pack_start (GTK_BOX (priv->box), priv->name, TRUE, FALSE, 10);
1802+
1803+ /* connect to signals */
1804+ g_signal_connect (G_OBJECT (item), "name-changed",
1805+ G_CALLBACK (task_item_name_changed), NULL);
1806+ g_signal_connect (G_OBJECT (item), "icon-changed",
1807+ G_CALLBACK (task_item_icon_changed), NULL);
1808+ g_signal_connect (G_OBJECT (item), "visible-changed",
1809+ G_CALLBACK (task_item_visible_changed), NULL);
1810+}
1811+
1812+static gboolean
1813+task_item_button_release_event (GtkWidget *widget,
1814+ GdkEventButton *event)
1815+{
1816+ g_return_val_if_fail (TASK_IS_ITEM (widget), FALSE);
1817+
1818+ task_item_left_click (TASK_ITEM (widget), event);
1819+
1820+ return TRUE;
1821+}
1822+
1823+static gboolean
1824+task_item_button_press_event (GtkWidget *widget,
1825+ GdkEventButton *event)
1826+{
1827+ g_return_val_if_fail (TASK_IS_ITEM (widget), FALSE);
1828+
1829+ if (event->button != 3) return FALSE;
1830+
1831+ task_item_right_click (TASK_ITEM (widget), event);
1832+
1833+ return TRUE;
1834+}
1835+
1836+static void
1837+task_item_name_changed (TaskItem *item, const gchar *name)
1838+{
1839+ TaskItemPrivate *priv = TASK_ITEM_GET_PRIVATE (item);
1840+
1841+ gtk_label_set_text (GTK_LABEL (priv->name), name);
1842+}
1843+
1844+
1845+static void
1846+task_item_icon_changed (TaskItem *item, GdkPixbuf *icon)
1847+{
1848+ TaskItemPrivate *priv = TASK_ITEM_GET_PRIVATE (item);
1849+
1850+ awn_icon_set_from_pixbuf (AWN_ICON (priv->icon), icon);
1851+}
1852+
1853+static void
1854+task_item_visible_changed (TaskItem *item, gboolean visible)
1855+{
1856+ if (visible)
1857+ gtk_widget_show (GTK_WIDGET (item));
1858+ else
1859+ gtk_widget_hide (GTK_WIDGET (item));
1860+}
1861+
1862+/**
1863+ * Public functions
1864+ */
1865+
1866+const gchar *
1867+task_item_get_name (TaskItem *item)
1868+{
1869+ TaskItemClass *klass;
1870+
1871+ g_return_val_if_fail (TASK_IS_ITEM (item), NULL);
1872+
1873+ klass = TASK_ITEM_GET_CLASS (item);
1874+ g_return_val_if_fail (klass->get_name, NULL);
1875+
1876+ return klass->get_name (item);
1877+}
1878+
1879+GdkPixbuf *
1880+task_item_get_icon (TaskItem *item)
1881+{
1882+ TaskItemClass *klass;
1883+
1884+ g_return_val_if_fail (TASK_IS_ITEM (item), NULL);
1885+
1886+ klass = TASK_ITEM_GET_CLASS (item);
1887+ g_return_val_if_fail (klass->get_icon, NULL);
1888+
1889+ return klass->get_icon (item);
1890+}
1891+
1892+gboolean
1893+task_item_is_visible (TaskItem *item)
1894+{
1895+ TaskItemClass *klass;
1896+
1897+ g_return_val_if_fail (TASK_IS_ITEM (item), FALSE);
1898+
1899+ klass = TASK_ITEM_GET_CLASS (item);
1900+ g_return_val_if_fail (klass->is_visible, FALSE);
1901+
1902+ return klass->is_visible (item);
1903+}
1904+
1905+void
1906+task_item_left_click (TaskItem *item, GdkEventButton *event)
1907+{
1908+ TaskItemClass *klass;
1909+
1910+ g_return_if_fail (TASK_IS_ITEM (item));
1911+
1912+ klass = TASK_ITEM_GET_CLASS (item);
1913+ g_return_if_fail (klass->left_click);
1914+
1915+ klass->left_click (item, event);
1916+}
1917+
1918+void
1919+task_item_right_click (TaskItem *item, GdkEventButton *event)
1920+{
1921+ TaskItemClass *klass;
1922+
1923+ g_return_if_fail (TASK_IS_ITEM (item));
1924+
1925+ klass = TASK_ITEM_GET_CLASS (item);
1926+ g_return_if_fail (klass->right_click);
1927+
1928+ klass->right_click (item, event);
1929+}
1930+
1931+guint
1932+task_item_match (TaskItem *item, TaskItem *item_to_match)
1933+{
1934+ TaskItemClass *klass;
1935+
1936+ g_return_val_if_fail (TASK_IS_ITEM (item), 0);
1937+
1938+ klass = TASK_ITEM_GET_CLASS (item);
1939+ g_return_val_if_fail (klass->match, 0);
1940+
1941+ return klass->match (item, item_to_match);
1942+}
1943+
1944+/**
1945+ * Protected functions (used only by derived classes)
1946+ */
1947+
1948+void
1949+task_item_emit_name_changed (TaskItem *item, const gchar *name)
1950+{
1951+ g_return_if_fail (TASK_IS_ITEM (item));
1952+
1953+ g_signal_emit (item, _item_signals[NAME_CHANGED], 0, name);
1954+}
1955+
1956+void
1957+task_item_emit_icon_changed (TaskItem *item, GdkPixbuf *icon)
1958+{
1959+ g_return_if_fail (TASK_IS_ITEM (item));
1960+
1961+ g_signal_emit (item, _item_signals[ICON_CHANGED], 0, icon);
1962+}
1963+
1964+void
1965+task_item_emit_visible_changed (TaskItem *item, gboolean visible)
1966+{
1967+ g_return_if_fail (TASK_IS_ITEM (item));
1968+
1969+ g_signal_emit (item, _item_signals[VISIBLE_CHANGED], 0, visible);
1970+}
1971\ No newline at end of file
1972
1973=== added file 'applets/taskmanager/task-item.h'
1974--- applets/taskmanager/task-item.h 1970-01-01 00:00:00 +0000
1975+++ applets/taskmanager/task-item.h 2009-06-20 10:58:03 +0000
1976@@ -0,0 +1,98 @@
1977+/*
1978+ * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
1979+ *
1980+ * This program is free software: you can redistribute it and/or modify
1981+ * it under the terms of the GNU General Public License version 3 as
1982+ * published by the Free Software Foundation.
1983+ *
1984+ * This program is distributed in the hope that it will be useful,
1985+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1986+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1987+ * GNU General Public License for more details.
1988+ *
1989+ * You should have received a copy of the GNU General Public License
1990+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1991+ *
1992+ * Authored by Hannes Verschore <hv1989@gmail.com>
1993+ *
1994+ */
1995+
1996+#ifndef _TASK_ITEM_H_
1997+#define _TASK_ITEM_H_
1998+
1999+#include <glib-object.h>
2000+#include <gtk/gtk.h>
2001+
2002+G_BEGIN_DECLS
2003+
2004+#define TASK_TYPE_ITEM (task_item_get_type ())
2005+
2006+#define TASK_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
2007+ TASK_TYPE_ITEM, TaskItem))
2008+
2009+#define TASK_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
2010+ TASK_TYPE_ITEM, TaskItemClass))
2011+
2012+#define TASK_IS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
2013+ TASK_TYPE_ITEM))
2014+
2015+#define TASK_IS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
2016+ TASK_TYPE_ITEM))
2017+
2018+#define TASK_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
2019+ TASK_TYPE_ITEM, TaskItemClass))
2020+
2021+typedef struct _TaskItem TaskItem;
2022+typedef struct _TaskItemClass TaskItemClass;
2023+typedef struct _TaskItemPrivate TaskItemPrivate;
2024+
2025+struct _TaskItem
2026+{
2027+ GtkBox parent;
2028+
2029+ TaskItemPrivate *priv;
2030+};
2031+
2032+struct _TaskItemClass
2033+{
2034+ GtkBoxClass parent_class;
2035+
2036+ /*< vtable, not signals >*/
2037+ const gchar * (*get_name) (TaskItem *item);
2038+ GdkPixbuf * (*get_icon) (TaskItem *item);
2039+ gboolean (*is_visible) (TaskItem *item);
2040+ void (*left_click) (TaskItem *item, GdkEventButton *event);
2041+ void (*right_click) (TaskItem *item, GdkEventButton *event);
2042+ guint (*match) (TaskItem *item, TaskItem *item_to_match);
2043+
2044+ /*< signals >*/
2045+ void (*name_changed) (TaskItem *item, const gchar *name);
2046+ void (*icon_changed) (TaskItem *item, GdkPixbuf *icon);
2047+ void (*visible_changed) (TaskItem *item, gboolean visible);
2048+};
2049+
2050+GType task_item_get_type (void) G_GNUC_CONST;
2051+
2052+const gchar * task_item_get_name (TaskItem *item);
2053+GdkPixbuf * task_item_get_icon (TaskItem *item);
2054+gboolean task_item_is_visible (TaskItem *item);
2055+void task_item_left_click (TaskItem *item, GdkEventButton *event);
2056+void task_item_right_click (TaskItem *item, GdkEventButton *event);
2057+guint task_item_match (TaskItem *item, TaskItem *item_to_match);
2058+
2059+//TODO: 2nd round: implement
2060+//const gchar * task_item_get_name (TaskItem *item);
2061+//void task_item_set_name (TaskItem *item,
2062+// const gchar *name);
2063+//GdkPixbuf * task_item_get_icon (TaskItem *item);
2064+//void task_item_update_icon (TaskItem *item,
2065+// GdkPixbuf *pixbuf);
2066+
2067+/* These should be "protected" (used only by derived classes) */
2068+void task_item_emit_name_changed (TaskItem *item, const gchar *name);
2069+void task_item_emit_icon_changed (TaskItem *item, GdkPixbuf *icon);
2070+void task_item_emit_visible_changed (TaskItem *item, gboolean visible);
2071+
2072+G_END_DECLS
2073+
2074+#endif /* _TASK_ITEM_H_ */
2075
2076=== modified file 'applets/taskmanager/task-launcher.c'
2077--- applets/taskmanager/task-launcher.c 2009-04-18 00:36:20 +0000
2078+++ applets/taskmanager/task-launcher.c 2009-06-20 14:17:54 +0000
2079@@ -14,7 +14,7 @@
2080 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2081 *
2082 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
2083- *
2084+ * Hannes Verschore <hv1989@gmail.com>
2085 */
2086
2087 #include <stdio.h>
2088@@ -28,19 +28,18 @@
2089 #include <libawn/libawn.h>
2090
2091 #include "task-launcher.h"
2092+#include "task-item.h"
2093 #include "task-window.h"
2094
2095 #include "task-settings.h"
2096 #include "xutils.h"
2097
2098-G_DEFINE_TYPE (TaskLauncher, task_launcher, TASK_TYPE_WINDOW)
2099+G_DEFINE_TYPE (TaskLauncher, task_launcher, TASK_TYPE_ITEM)
2100
2101 #define TASK_LAUNCHER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
2102 TASK_TYPE_LAUNCHER, \
2103 TaskLauncherPrivate))
2104
2105-#define GET_WINDOW_PRIVATE(obj) (TASK_WINDOW(obj)->priv)
2106-
2107 struct _TaskLauncherPrivate
2108 {
2109 gchar *path;
2110@@ -59,15 +58,15 @@
2111 };
2112
2113 /* Forwards */
2114-static gint _get_pid (TaskWindow *window);
2115-static const gchar * _get_name (TaskWindow *window);
2116-static GdkPixbuf * _get_icon (TaskWindow *window);
2117-static gboolean _is_on_workspace (TaskWindow *window,
2118- WnckWorkspace *space);
2119-static void _activate (TaskWindow *window,
2120- guint32 timestamp);
2121-static void _popup_menu (TaskWindow *window,
2122- GtkMenu *menu);
2123+static const gchar * _get_name (TaskItem *item);
2124+static GdkPixbuf * _get_icon (TaskItem *item);
2125+static gboolean _is_visible (TaskItem *item);
2126+static void _left_click (TaskItem *item,
2127+ GdkEventButton *event);
2128+static void _right_click (TaskItem *item,
2129+ GdkEventButton *event);
2130+static guint _match (TaskItem *item,
2131+ TaskItem *item_to_match);
2132
2133 static void task_launcher_set_desktop_file (TaskLauncher *launcher,
2134 const gchar *path);
2135@@ -115,19 +114,19 @@
2136 task_launcher_class_init (TaskLauncherClass *klass)
2137 {
2138 GParamSpec *pspec;
2139- GObjectClass *obj_class = G_OBJECT_CLASS (klass);
2140- TaskWindowClass *win_class = TASK_WINDOW_CLASS (klass);
2141+ GObjectClass *obj_class = G_OBJECT_CLASS (klass);
2142+ TaskItemClass *item_class = TASK_ITEM_CLASS (klass);
2143
2144 obj_class->set_property = task_launcher_set_property;
2145 obj_class->get_property = task_launcher_get_property;
2146
2147 /* We implement the necessary funtions for a normal window */
2148- win_class->get_pid = _get_pid;
2149- win_class->get_name = _get_name;
2150- win_class->get_icon = _get_icon;
2151- win_class->is_on_workspace = _is_on_workspace;
2152- win_class->activate = _activate;
2153- win_class->popup_menu = _popup_menu;
2154+ item_class->get_name = _get_name;
2155+ item_class->get_icon = _get_icon;
2156+ item_class->is_visible = _is_visible;
2157+ item_class->match = _match;
2158+ item_class->left_click = _left_click;
2159+ item_class->right_click = _right_click;
2160
2161 /* Install properties */
2162 pspec = g_param_spec_string ("desktopfile",
2163@@ -151,19 +150,19 @@
2164 priv->item = NULL;
2165 }
2166
2167-TaskLauncher *
2168+TaskItem *
2169 task_launcher_new_for_desktop_file (const gchar *path)
2170 {
2171- TaskLauncher *win = NULL;
2172+ TaskItem *item = NULL;
2173
2174 if (!g_file_test (path, G_FILE_TEST_EXISTS))
2175 return NULL;
2176
2177- win = g_object_new (TASK_TYPE_LAUNCHER,
2178- "desktopfile", path,
2179- NULL);
2180+ item = g_object_new (TASK_TYPE_LAUNCHER,
2181+ "desktopfile", path,
2182+ NULL);
2183
2184- return win;
2185+ return item;
2186 }
2187
2188 const gchar *
2189@@ -178,6 +177,8 @@
2190 task_launcher_set_desktop_file (TaskLauncher *launcher, const gchar *path)
2191 {
2192 TaskLauncherPrivate *priv;
2193+ TaskSettings * s = task_settings_get_default ();
2194+ GdkPixbuf *pixbuf;
2195 gchar * exec_key = NULL;
2196 gchar * needle = NULL;
2197
2198@@ -210,194 +211,161 @@
2199 priv->exec = exec_key;
2200 priv->icon_name = awn_desktop_item_get_icon_name (priv->item);
2201
2202+ task_item_emit_name_changed (TASK_ITEM (launcher), priv->name);
2203+ pixbuf = awn_desktop_item_get_icon (priv->item, s->panel_size);
2204+ task_item_emit_icon_changed (TASK_ITEM (launcher), pixbuf);
2205+ g_object_unref (pixbuf);
2206+ task_item_emit_visible_changed (TASK_ITEM (launcher), TRUE);
2207+
2208 g_debug ("LAUNCHER: %s", priv->name);
2209 }
2210
2211 /*
2212 * Implemented functions for a standard window without a launcher
2213 */
2214-static gint
2215-_get_pid (TaskWindow *window)
2216-{
2217- TaskLauncher *launcher = TASK_LAUNCHER (window);
2218-
2219- if (WNCK_IS_WINDOW (window->priv->window))
2220- {
2221- gint value = -1;
2222- value = wnck_window_get_pid (window->priv->window);
2223- value = value ? value : -1;
2224- return value;
2225- }
2226- else
2227- {
2228- return launcher->priv->pid;
2229- }
2230-}
2231-
2232 static const gchar *
2233-_get_name (TaskWindow *window)
2234+_get_name (TaskItem *item)
2235 {
2236- TaskLauncher *launcher = TASK_LAUNCHER (window);
2237-
2238- if (WNCK_IS_WINDOW (window->priv->window))
2239- {
2240- return wnck_window_get_name (window->priv->window);
2241- }
2242- else
2243- {
2244- return launcher->priv->name;
2245- }
2246+ return TASK_LAUNCHER (item)->priv->name;
2247 }
2248
2249 static GdkPixbuf *
2250-_get_icon (TaskWindow *window)
2251+_get_icon (TaskItem *item)
2252 {
2253- TaskLauncher *launcher = TASK_LAUNCHER (window);
2254 TaskSettings *s = task_settings_get_default ();
2255
2256- if (WNCK_IS_WINDOW (window->priv->window))
2257- {
2258- return _wnck_get_icon_at_size (window->priv->window,
2259- s->panel_size, s->panel_size);
2260- }
2261- else
2262- {
2263- return awn_desktop_item_get_icon (launcher->priv->item, s->panel_size);
2264- }
2265+ return awn_desktop_item_get_icon (TASK_LAUNCHER (item)->priv->item, s->panel_size);
2266 }
2267
2268-static gboolean
2269-_is_on_workspace (TaskWindow *window,
2270- WnckWorkspace *space)
2271+static gboolean
2272+_is_visible (TaskItem *item)
2273 {
2274 return TRUE;
2275 }
2276
2277-static void
2278-_activate (TaskWindow *window,
2279- guint32 timestamp)
2280-{
2281- TaskLauncher *launcher = TASK_LAUNCHER (window);
2282- GError *error = NULL;
2283-
2284- launcher->priv->pid = awn_desktop_item_launch (launcher->priv->item,
2285- NULL, &error);
2286-
2287- if (error)
2288- {
2289- g_warning ("Unable to launch %s: %s",
2290- launcher->priv->name,
2291- error->message);
2292- g_error_free (error);
2293- }
2294-}
2295-
2296-/*
2297- * Public functions
2298+/**
2299+ * Match the launcher with the provided window.
2300+ * The higher the number it returns the more it matches the window.
2301+ * 100 = definitly matches
2302+ * 0 = doesn't match
2303 */
2304-gboolean
2305-task_launcher_has_window (TaskLauncher *launcher)
2306-{
2307- g_return_val_if_fail (TASK_IS_LAUNCHER (launcher), TRUE);
2308-
2309- if (WNCK_IS_WINDOW (TASK_WINDOW (launcher)->priv->window))
2310- return TRUE;
2311- return FALSE;
2312-}
2313-
2314-gboolean
2315-task_launcher_try_match (TaskLauncher *launcher,
2316- gint pid,
2317- const gchar *res_name,
2318- const gchar *class_name)
2319+static guint
2320+_match (TaskItem *item,
2321+ TaskItem *item_to_match)
2322 {
2323 TaskLauncherPrivate *priv;
2324-
2325- g_return_val_if_fail (launcher, FALSE);
2326+ TaskLauncher *launcher;
2327+ TaskWindow *window;
2328+ gchar *res_name = NULL;
2329+ gchar *class_name = NULL;
2330+ gchar *temp;
2331+ gint pid;
2332+
2333+ g_return_val_if_fail (TASK_IS_LAUNCHER(item), 0);
2334+
2335+ if (!TASK_IS_WINDOW (item_to_match)) return 0;
2336+
2337+ launcher = TASK_LAUNCHER (item);
2338 priv = launcher->priv;
2339+
2340+ window = TASK_WINDOW (item_to_match);
2341
2342 /* Try simple pid-match first */
2343+ pid = task_window_get_pid(window);
2344 if ( pid && (priv->pid == pid))
2345- return TRUE;
2346+ return 100;
2347
2348 /* Now try resource name, which should (hopefully) be 99% of the cases */
2349- if ( res_name && strlen(res_name) && priv->exec)
2350+ task_window_get_wm_class(window, &res_name, &class_name);
2351+
2352+ if (res_name)
2353 {
2354- if ( g_strstr_len (priv->exec, strlen (priv->exec), res_name) ||
2355- g_strstr_len (res_name, strlen (res_name), priv->exec))
2356+ temp = res_name;
2357+ res_name = g_utf8_strdown (temp, -1);
2358+ g_free (temp);
2359+
2360+ if ( strlen(res_name) && priv->exec)
2361 {
2362- return TRUE;
2363+ if ( g_strstr_len (priv->exec, strlen (priv->exec), res_name) ||
2364+ g_strstr_len (res_name, strlen (res_name), priv->exec))
2365+ {
2366+ g_free (res_name);
2367+ g_free (class_name);
2368+ return 70;
2369+ }
2370 }
2371 }
2372-
2373+
2374 /* Try a class_name to exec line match */
2375- if ( class_name && strlen(class_name) && priv->exec)
2376- {
2377- if (g_strstr_len (priv->exec, strlen (priv->exec), class_name))
2378- return TRUE;
2379- }
2380-
2381- return FALSE;
2382-}
2383-
2384-static void
2385-on_window_closed (TaskLauncher *launcher, WnckWindow *old_window)
2386-{
2387- TaskWindowPrivate *priv;
2388- TaskSettings *s = task_settings_get_default ();
2389- GdkPixbuf *pixbuf;
2390-
2391- g_return_if_fail (TASK_IS_LAUNCHER (launcher));
2392- priv = TASK_WINDOW (launcher)->priv;
2393-
2394- /* NULLify the window pointer */
2395- priv->window = NULL;
2396-
2397- /* Reset name */
2398- task_window_set_name (TASK_WINDOW (launcher), launcher->priv->name);
2399-
2400- /* Reset icon */
2401- pixbuf = xutils_get_named_icon (launcher->priv->icon_name,
2402- s->panel_size, s->panel_size);
2403-
2404- task_window_update_icon (TASK_WINDOW (launcher), pixbuf);
2405-
2406- g_object_unref (pixbuf);
2407-}
2408-
2409-void
2410-task_launcher_set_window (TaskLauncher *launcher,
2411- WnckWindow *window)
2412-{
2413- g_return_if_fail (TASK_IS_LAUNCHER (launcher));
2414- g_return_if_fail (WNCK_IS_WINDOW (window));
2415-
2416- g_object_set (launcher, "taskwindow", window, NULL);
2417-
2418- task_window_set_name (TASK_WINDOW (launcher), wnck_window_get_name (window));
2419-
2420- g_object_weak_ref (G_OBJECT (window),
2421- (GWeakNotify)on_window_closed,
2422- launcher);
2423-}
2424-
2425-static void
2426-_popup_menu (TaskWindow *window,
2427- GtkMenu *menu)
2428-{
2429- TaskWindowPrivate *priv;
2430- GtkWidget *item;
2431-
2432- g_return_if_fail (TASK_IS_WINDOW (window));
2433- priv = window->priv;
2434-
2435- if (!WNCK_IS_WINDOW (priv->window))
2436- {
2437- item = gtk_image_menu_item_new_from_stock (GTK_STOCK_EXECUTE, NULL);
2438- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
2439- gtk_widget_show (item);
2440- }
2441-}
2442+ if (class_name)
2443+ {
2444+ temp = class_name;
2445+ class_name = g_utf8_strdown (temp, -1);
2446+ g_free (temp);
2447+
2448+ if (strlen(class_name) && priv->exec)
2449+ {
2450+ if (g_strstr_len (priv->exec, strlen (priv->exec), class_name))
2451+ {
2452+ g_free (res_name);
2453+ g_free (class_name);
2454+ return 50;
2455+ }
2456+ }
2457+ }
2458+
2459+ g_free (res_name);
2460+ g_free (class_name);
2461+ return 0;
2462+}
2463+
2464+static void
2465+_left_click (TaskItem *item, GdkEventButton *event)
2466+{
2467+ TaskLauncherPrivate *priv;
2468+ TaskLauncher *launcher;
2469+ GError *error = NULL;
2470+
2471+ g_return_if_fail (TASK_IS_LAUNCHER (item));
2472+
2473+ launcher = TASK_LAUNCHER (item);
2474+ priv = launcher->priv;
2475+
2476+ priv->pid = awn_desktop_item_launch (priv->item, NULL, &error);
2477+
2478+ if (error)
2479+ {
2480+ g_warning ("Unable to launch %s: %s",
2481+ task_item_get_name (item),
2482+ error->message);
2483+ g_error_free (error);
2484+ }
2485+}
2486+
2487+static void
2488+_right_click (TaskItem *item, GdkEventButton *event)
2489+{
2490+ TaskLauncherPrivate *priv;
2491+ TaskLauncher *launcher;
2492+ GtkWidget *menu_item,
2493+ *menu;
2494+
2495+ g_return_if_fail (TASK_IS_LAUNCHER (item));
2496+
2497+ launcher = TASK_LAUNCHER (item);
2498+ priv = launcher->priv;
2499+
2500+ menu = gtk_menu_new ();
2501+ menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_EXECUTE, NULL);
2502+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
2503+ gtk_widget_show (menu_item);
2504+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
2505+ NULL, NULL, event->button, event->time);
2506+}
2507+
2508+/*
2509+ * Public functions
2510+ */
2511
2512 void
2513 task_launcher_launch_with_data (TaskLauncher *launcher,
2514@@ -429,10 +397,7 @@
2515 g_return_if_fail (TASK_IS_LAUNCHER (launcher));
2516 priv = launcher->priv;
2517
2518- if (WNCK_IS_WINDOW (TASK_WINDOW (launcher)->priv->window))
2519- awn_desktop_item_launch (priv->item, NULL, &error);
2520- else
2521- priv->pid = awn_desktop_item_launch (priv->item, NULL, &error);
2522+ priv->pid = awn_desktop_item_launch (priv->item, NULL, &error);
2523
2524 if (error)
2525 {
2526
2527=== modified file 'applets/taskmanager/task-launcher.h'
2528--- applets/taskmanager/task-launcher.h 2008-12-26 15:19:53 +0000
2529+++ applets/taskmanager/task-launcher.h 2009-06-20 14:17:54 +0000
2530@@ -14,6 +14,7 @@
2531 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2532 *
2533 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
2534+ * Hannes Verschore <hv1989@gmail.com>
2535 *
2536 */
2537
2538@@ -24,7 +25,7 @@
2539 #include <gtk/gtk.h>
2540 #include <libwnck/libwnck.h>
2541
2542-#include "task-window.h"
2543+#include "task-item.h"
2544
2545 #define TASK_TYPE_LAUNCHER (task_launcher_get_type ())
2546
2547@@ -49,38 +50,24 @@
2548
2549 struct _TaskLauncher
2550 {
2551- TaskWindow parent;
2552+ TaskItem parent;
2553
2554 TaskLauncherPrivate *priv;
2555 };
2556
2557 struct _TaskLauncherClass
2558 {
2559- TaskWindowClass parent_class;
2560+ TaskItemClass parent_class;
2561
2562 /*< signals >*/
2563- void (*launcher0) (void);
2564- void (*launcher1) (void);
2565- void (*launcher2) (void);
2566- void (*launcher3) (void);
2567 };
2568
2569 GType task_launcher_get_type (void) G_GNUC_CONST;
2570
2571-TaskLauncher * task_launcher_new_for_desktop_file (const gchar *path);
2572+TaskItem * task_launcher_new_for_desktop_file (const gchar *path);
2573
2574 const gchar * task_launcher_get_desktop_path (TaskLauncher *launcher);
2575
2576-gboolean task_launcher_has_window (TaskLauncher *launcher);
2577-
2578-gboolean task_launcher_try_match (TaskLauncher *launcher,
2579- gint pid,
2580- const gchar *res_name,
2581- const gchar *class_name);
2582-
2583-void task_launcher_set_window (TaskLauncher *launcher,
2584- WnckWindow *window);
2585-
2586 void task_launcher_launch_with_data (TaskLauncher *launcher,
2587 GSList *list);
2588
2589
2590=== added file 'applets/taskmanager/task-manager-api-wrapper.c'
2591--- applets/taskmanager/task-manager-api-wrapper.c 1970-01-01 00:00:00 +0000
2592+++ applets/taskmanager/task-manager-api-wrapper.c 2009-06-26 11:00:10 +0000
2593@@ -0,0 +1,509 @@
2594+/*
2595+ * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
2596+ *
2597+ * This program is free software: you can redistribute it and/or modify
2598+ * it under the terms of the GNU General Public License version 3 as
2599+ * published by the Free Software Foundation.
2600+ *
2601+ * This program is distributed in the hope that it will be useful,
2602+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2603+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2604+ * GNU General Public License for more details.
2605+ *
2606+ * You should have received a copy of the GNU General Public License
2607+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2608+ *
2609+ * Authored by Hannes Verschore <hv1989@gmail.com>
2610+ */
2611+
2612+
2613+#include "task-manager-api-wrapper.h"
2614+
2615+#include <libawn/libawn.h>
2616+
2617+G_DEFINE_TYPE (TaskManagerApiWrapper, task_manager_api_wrapper, G_TYPE_OBJECT)
2618+
2619+#define TASK_MANAGER_API_WRAPPER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
2620+ TASK_TYPE_MANAGER_API_WRAPPER, \
2621+ TaskManagerApiWrapperPrivate))
2622+
2623+struct _TaskManagerApiWrapperPrivate
2624+{
2625+ TaskManager *manager;
2626+};
2627+
2628+enum
2629+{
2630+ PROP_0,
2631+ PROP_MANAGER
2632+};
2633+
2634+/* GObject stuff */
2635+
2636+static void
2637+task_manager_api_wrapper_set_manager (TaskManagerApiWrapper *wrapper,
2638+ TaskManager *manager)
2639+{
2640+ g_return_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper));
2641+ g_return_if_fail (TASK_IS_MANAGER (manager));
2642+
2643+ wrapper->priv->manager = manager;
2644+}
2645+
2646+static void
2647+task_manager_api_wrapper_get_property (GObject *object,
2648+ guint prop_id,
2649+ GValue *value,
2650+ GParamSpec *pspec)
2651+{
2652+ TaskManagerApiWrapper *wrapper = TASK_MANAGER_API_WRAPPER (object);
2653+
2654+ switch (prop_id)
2655+ {
2656+ case PROP_MANAGER:
2657+ g_value_set_object (value, wrapper->priv->manager);
2658+ break;
2659+
2660+ default:
2661+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2662+ }
2663+}
2664+
2665+static void
2666+task_manager_api_wrapper_set_property (GObject *object,
2667+ guint prop_id,
2668+ const GValue *value,
2669+ GParamSpec *pspec)
2670+{
2671+ TaskManagerApiWrapper *wrapper = TASK_MANAGER_API_WRAPPER (object);
2672+
2673+ switch (prop_id)
2674+ {
2675+ case PROP_MANAGER:
2676+ task_manager_api_wrapper_set_manager (wrapper, g_value_get_object (value));
2677+ break;
2678+
2679+ default:
2680+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2681+ }
2682+}
2683+
2684+/* GObject stuff */
2685+static void
2686+task_manager_api_wrapper_class_init (TaskManagerApiWrapperClass *klass)
2687+{
2688+ GParamSpec *pspec;
2689+ GObjectClass *obj_class = G_OBJECT_CLASS (klass);
2690+
2691+ obj_class->set_property = task_manager_api_wrapper_set_property;
2692+ obj_class->get_property = task_manager_api_wrapper_get_property;
2693+
2694+ /* Install properties */
2695+ pspec = g_param_spec_object ("manager",
2696+ "Manager",
2697+ "TaskManager",
2698+ TASK_TYPE_MANAGER,
2699+ G_PARAM_READWRITE);
2700+ g_object_class_install_property (obj_class, PROP_MANAGER, pspec);
2701+
2702+ g_type_class_add_private (obj_class, sizeof (TaskManagerApiWrapperPrivate));
2703+}
2704+
2705+static void
2706+task_manager_api_wrapper_init (TaskManagerApiWrapper *wrapper)
2707+{
2708+ TaskManagerApiWrapperPrivate *priv;
2709+
2710+ /* get and save private struct */
2711+ priv = wrapper->priv = TASK_MANAGER_API_WRAPPER_GET_PRIVATE (wrapper);
2712+ priv->manager = NULL;
2713+}
2714+
2715+
2716+TaskManagerApiWrapper *
2717+task_manager_api_wrapper_new (TaskManager *manager)
2718+{
2719+ TaskManagerApiWrapper *wrapper = NULL;
2720+
2721+ wrapper = g_object_new (TASK_TYPE_MANAGER_API_WRAPPER,
2722+ "manager", manager,
2723+ NULL);
2724+
2725+ return wrapper;
2726+}
2727+
2728+gboolean
2729+task_manager_api_wrapper_set_task_icon_by_name (TaskManagerApiWrapper *wrapper,
2730+ gchar *name,
2731+ gchar *icon_path,
2732+ GError **error)
2733+{
2734+ TaskManagerApiWrapperPrivate *priv;
2735+ gboolean succeeded;
2736+ GValue window = {0};
2737+ GHashTable *hints;
2738+ const gchar *key = "icon-file";
2739+ GValue value = {0};
2740+
2741+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
2742+
2743+ priv = wrapper->priv;
2744+
2745+ g_value_init (&window, G_TYPE_STRING);
2746+ g_value_set_string (&window, name);
2747+
2748+ g_value_init (&value, G_TYPE_STRING);
2749+ g_value_set_string (&value, icon_path);
2750+
2751+ hints = g_hash_table_new (g_str_hash, g_str_equal);
2752+ g_hash_table_insert (hints, (gpointer)key, &value);
2753+
2754+ succeeded = task_manager_update (priv->manager,
2755+ &window,
2756+ hints,
2757+ error);
2758+ g_value_unset (&window);
2759+ g_value_unset (&value);
2760+ g_hash_table_destroy (hints);
2761+
2762+ return succeeded;
2763+}
2764+
2765+gboolean
2766+task_manager_api_wrapper_unset_task_icon_by_name (TaskManagerApiWrapper *wrapper,
2767+ gchar *name,
2768+ GError **error)
2769+{
2770+ TaskManagerApiWrapperPrivate *priv;
2771+ gboolean succeeded;
2772+ GValue window = {0};
2773+ GHashTable *hints;
2774+ const gchar *key = "icon-file";
2775+ GValue value = {0};
2776+
2777+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
2778+
2779+ priv = wrapper->priv;
2780+
2781+ g_value_init (&window, G_TYPE_STRING);
2782+ g_value_set_string (&window, name);
2783+
2784+ g_value_init (&value, G_TYPE_STRING);
2785+ g_value_set_string (&value, "");
2786+
2787+ hints = g_hash_table_new (g_str_hash, g_str_equal);
2788+ g_hash_table_insert (hints, (gpointer)key, &value);
2789+
2790+ succeeded = task_manager_update (priv->manager,
2791+ &window,
2792+ hints,
2793+ error);
2794+ g_value_unset (&window);
2795+ g_value_unset (&value);
2796+ g_hash_table_destroy (hints);
2797+
2798+ return succeeded;
2799+}
2800+
2801+gboolean
2802+task_manager_api_wrapper_set_info_by_name (TaskManagerApiWrapper *wrapper,
2803+ gchar *name,
2804+ gchar *info,
2805+ GError **error)
2806+{
2807+ TaskManagerApiWrapperPrivate *priv;
2808+ gboolean succeeded;
2809+ GValue window = {0};
2810+ GHashTable *hints;
2811+ const gchar *key = "message";
2812+ GValue value = {0};
2813+
2814+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
2815+
2816+ priv = wrapper->priv;
2817+
2818+ g_value_init (&window, G_TYPE_STRING);
2819+ g_value_set_string (&window, name);
2820+
2821+ g_value_init (&value, G_TYPE_STRING);
2822+ g_value_set_string (&value, info);
2823+
2824+ hints = g_hash_table_new (g_str_hash, g_str_equal);
2825+ g_hash_table_insert (hints, (gpointer)key, &value);
2826+
2827+ succeeded = task_manager_update (priv->manager,
2828+ &window,
2829+ hints,
2830+ error);
2831+ g_value_unset (&window);
2832+ g_value_unset (&value);
2833+ g_hash_table_destroy (hints);
2834+
2835+ return succeeded;
2836+}
2837+
2838+gboolean
2839+task_manager_api_wrapper_unset_info_by_name (TaskManagerApiWrapper *wrapper,
2840+ gchar *name,
2841+ GError **error)
2842+{
2843+ TaskManagerApiWrapperPrivate *priv;
2844+ gboolean succeeded;
2845+ GValue window = {0};
2846+ GHashTable *hints;
2847+ const gchar *key = "message";
2848+ GValue value = {0};
2849+
2850+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
2851+
2852+ priv = wrapper->priv;
2853+
2854+ g_value_init (&window, G_TYPE_STRING);
2855+ g_value_set_string (&window, name);
2856+
2857+ g_value_init (&value, G_TYPE_STRING);
2858+ g_value_set_string (&value, "");
2859+
2860+ hints = g_hash_table_new (g_str_hash, g_str_equal);
2861+ g_hash_table_insert (hints, (gpointer)key, &value);
2862+
2863+ succeeded = task_manager_update (priv->manager,
2864+ &window,
2865+ hints,
2866+ error);
2867+ g_value_unset (&window);
2868+ g_value_unset (&value);
2869+ g_hash_table_destroy (hints);
2870+
2871+ return succeeded;
2872+}
2873+
2874+gboolean
2875+task_manager_api_wrapper_set_progress_by_name (TaskManagerApiWrapper *wrapper,
2876+ gchar *name,
2877+ gint progress,
2878+ GError **error)
2879+{
2880+ TaskManagerApiWrapperPrivate *priv;
2881+ gboolean succeeded;
2882+ GValue window = {0};
2883+ GHashTable *hints;
2884+ const gchar *key = "message";
2885+ GValue value = {0};
2886+
2887+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
2888+
2889+ priv = wrapper->priv;
2890+
2891+ g_value_init (&window, G_TYPE_STRING);
2892+ g_value_set_string (&window, name);
2893+
2894+ //difference between old and new api
2895+ //unsetting progress indicator by setting progress to -1;
2896+ if (progress == 100) progress = -1;
2897+
2898+ g_value_init (&value, G_TYPE_INT);
2899+ g_value_set_int (&value, progress);
2900+
2901+ hints = g_hash_table_new (g_str_hash, g_str_equal);
2902+ g_hash_table_insert (hints, (gpointer)key, &value);
2903+
2904+ succeeded = task_manager_update (priv->manager,
2905+ &window,
2906+ hints,
2907+ error);
2908+ g_value_unset (&window);
2909+ g_value_unset (&value);
2910+ g_hash_table_destroy (hints);
2911+
2912+ return succeeded;
2913+}
2914+
2915+/* XID variants */
2916+
2917+gboolean
2918+task_manager_api_wrapper_set_task_icon_by_xid (TaskManagerApiWrapper *wrapper,
2919+ gint64 xid,
2920+ gchar *icon_path,
2921+ GError **error)
2922+{
2923+ TaskManagerApiWrapperPrivate *priv;
2924+ gboolean succeeded;
2925+ GValue window = {0};
2926+ GHashTable *hints;
2927+ const gchar *key = "icon-file";
2928+ GValue value = {0};
2929+
2930+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
2931+
2932+ priv = wrapper->priv;
2933+
2934+ g_value_init (&window, G_TYPE_INT64);
2935+ g_value_set_int64 (&window, xid);
2936+
2937+ g_value_init (&value, G_TYPE_STRING);
2938+ g_value_set_string (&value, icon_path);
2939+
2940+ hints = g_hash_table_new (g_str_hash, g_str_equal);
2941+ g_hash_table_insert (hints, (gpointer)key, &value);
2942+
2943+ succeeded = task_manager_update (priv->manager,
2944+ &window,
2945+ hints,
2946+ error);
2947+ g_value_unset (&window);
2948+ g_value_unset (&value);
2949+ g_hash_table_destroy (hints);
2950+
2951+ return succeeded;
2952+}
2953+
2954+gboolean
2955+task_manager_api_wrapper_unset_task_icon_by_xid (TaskManagerApiWrapper *wrapper,
2956+ gint64 xid,
2957+ GError **error)
2958+{
2959+ TaskManagerApiWrapperPrivate *priv;
2960+ gboolean succeeded;
2961+ GValue window = {0};
2962+ GHashTable *hints;
2963+ const gchar *key = "icon-file";
2964+ GValue value = {0};
2965+
2966+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
2967+
2968+ priv = wrapper->priv;
2969+
2970+ g_value_init (&window, G_TYPE_INT64);
2971+ g_value_set_int64 (&window, xid);
2972+
2973+ g_value_init (&value, G_TYPE_STRING);
2974+ g_value_set_string (&value, "");
2975+
2976+ hints = g_hash_table_new (g_str_hash, g_str_equal);
2977+ g_hash_table_insert (hints, (gpointer)key, &value);
2978+
2979+ succeeded = task_manager_update (priv->manager,
2980+ &window,
2981+ hints,
2982+ error);
2983+ g_value_unset (&window);
2984+ g_value_unset (&value);
2985+ g_hash_table_destroy (hints);
2986+
2987+ return succeeded;
2988+}
2989+
2990+gboolean
2991+task_manager_api_wrapper_set_info_by_xid (TaskManagerApiWrapper *wrapper,
2992+ gint64 xid,
2993+ gchar *info,
2994+ GError **error)
2995+{
2996+ TaskManagerApiWrapperPrivate *priv;
2997+ gboolean succeeded;
2998+ GValue window = {0};
2999+ GHashTable *hints;
3000+ const gchar *key = "message";
3001+ GValue value = {0};
3002+
3003+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
3004+
3005+ priv = wrapper->priv;
3006+
3007+ g_value_init (&window, G_TYPE_INT64);
3008+ g_value_set_int64 (&window, xid);
3009+
3010+ g_value_init (&value, G_TYPE_STRING);
3011+ g_value_set_string (&value, info);
3012+
3013+ hints = g_hash_table_new (g_str_hash, g_str_equal);
3014+ g_hash_table_insert (hints, (gpointer)key, &value);
3015+
3016+ succeeded = task_manager_update (priv->manager,
3017+ &window,
3018+ hints,
3019+ error);
3020+ g_value_unset (&window);
3021+ g_value_unset (&value);
3022+ g_hash_table_destroy (hints);
3023+
3024+ return succeeded;
3025+}
3026+
3027+gboolean
3028+task_manager_api_wrapper_unset_info_by_xid (TaskManagerApiWrapper *wrapper,
3029+ gint64 xid,
3030+ GError **error)
3031+{
3032+ TaskManagerApiWrapperPrivate *priv;
3033+ gboolean succeeded;
3034+ GValue window = {0};
3035+ GHashTable *hints;
3036+ const gchar *key = "message";
3037+ GValue value = {0};
3038+
3039+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
3040+
3041+ priv = wrapper->priv;
3042+
3043+ g_value_init (&window, G_TYPE_INT64);
3044+ g_value_set_int64 (&window, xid);
3045+
3046+ g_value_init (&value, G_TYPE_STRING);
3047+ g_value_set_string (&value, "");
3048+
3049+ hints = g_hash_table_new (g_str_hash, g_str_equal);
3050+ g_hash_table_insert (hints, (gpointer)key, &value);
3051+
3052+ succeeded = task_manager_update (priv->manager,
3053+ &window,
3054+ hints,
3055+ error);
3056+ g_value_unset (&window);
3057+ g_value_unset (&value);
3058+ g_hash_table_destroy (hints);
3059+
3060+ return succeeded;
3061+}
3062+
3063+gboolean
3064+task_manager_api_wrapper_set_progress_by_xid (TaskManagerApiWrapper *wrapper,
3065+ gint64 xid,
3066+ gint progress,
3067+ GError **error)
3068+{
3069+ TaskManagerApiWrapperPrivate *priv;
3070+ gboolean succeeded;
3071+ GValue window = {0};
3072+ GHashTable *hints;
3073+ const gchar *key = "message";
3074+ GValue value = {0};
3075+
3076+ g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
3077+
3078+ priv = wrapper->priv;
3079+
3080+ g_value_init (&window, G_TYPE_INT64);
3081+ g_value_set_int64 (&window, xid);
3082+
3083+ //difference between old and new api
3084+ //unsetting progress indicator by setting progress to -1;
3085+ if (progress == 100) progress = -1;
3086+
3087+ g_value_init (&value, G_TYPE_INT);
3088+ g_value_set_int (&value, progress);
3089+
3090+ hints = g_hash_table_new (g_str_hash, g_str_equal);
3091+ g_hash_table_insert (hints, (gpointer)key, &value);
3092+
3093+ succeeded = task_manager_update (priv->manager,
3094+ &window,
3095+ hints,
3096+ error);
3097+ g_value_unset (&window);
3098+ g_value_unset (&value);
3099+ g_hash_table_destroy (hints);
3100+
3101+ return succeeded;
3102+}
3103
3104=== added file 'applets/taskmanager/task-manager-api-wrapper.h'
3105--- applets/taskmanager/task-manager-api-wrapper.h 1970-01-01 00:00:00 +0000
3106+++ applets/taskmanager/task-manager-api-wrapper.h 2009-06-26 11:00:10 +0000
3107@@ -0,0 +1,125 @@
3108+/*
3109+ * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
3110+ *
3111+ * This program is free software: you can redistribute it and/or modify
3112+ * it under the terms of the GNU General Public License version 3 as
3113+ * published by the Free Software Foundation.
3114+ *
3115+ * This program is distributed in the hope that it will be useful,
3116+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3117+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3118+ * GNU General Public License for more details.
3119+ *
3120+ * You should have received a copy of the GNU General Public License
3121+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3122+ *
3123+ * Authored by Hannes Verschore <hv1989@gmail.com>
3124+ */
3125+
3126+#ifndef _TASK_MANAGER_API_WRAPPER_H_
3127+#define _TASK_MANAGER_API_WRAPPER_H_
3128+
3129+#include <glib-object.h>
3130+#include <libawn/libawn.h>
3131+
3132+#include "task-manager.h"
3133+
3134+#define TASK_TYPE_MANAGER_API_WRAPPER (task_manager_api_wrapper_get_type ())
3135+
3136+#define TASK_MANAGER_API_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
3137+ TASK_TYPE_MANAGER_API_WRAPPER, TaskManagerApiWrapper))
3138+
3139+#define TASK_MANAGER_API_WRAPPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
3140+ TASK_TYPE_MANAGER_API_WRAPPER, TaskManagerApiWrapperClass))
3141+
3142+#define TASK_IS_MANAGER_API_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
3143+ TASK_TYPE_MANAGER_API_WRAPPER))
3144+
3145+#define TASK_IS_MANAGER_API_WRAPPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
3146+ TASK_TYPE_MANAGER_API_WRAPPER))
3147+
3148+#define TASK_MANAGER_API_WRAPPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
3149+ TASK_TYPE_MANAGER_API_WRAPPER, TaskManagerApiWrapperClass))
3150+
3151+typedef struct _TaskManagerApiWrapper TaskManagerApiWrapper;
3152+typedef struct _TaskManagerApiWrapperClass TaskManagerApiWrapperClass;
3153+typedef struct _TaskManagerApiWrapperPrivate TaskManagerApiWrapperPrivate;
3154+
3155+struct _TaskManagerApiWrapper
3156+{
3157+ GObject parent;
3158+
3159+ TaskManagerApiWrapperPrivate *priv;
3160+};
3161+
3162+struct _TaskManagerApiWrapperClass
3163+{
3164+ GObjectClass parent_class;
3165+};
3166+
3167+GType task_manager_api_wrapper_get_type (void) G_GNUC_CONST;
3168+
3169+TaskManagerApiWrapper * task_manager_api_wrapper_new (TaskManager *manager);
3170+
3171+/* name variants */
3172+
3173+gboolean
3174+task_manager_api_wrapper_set_task_icon_by_name (TaskManagerApiWrapper *wrapper,
3175+ gchar *name,
3176+ gchar *icon_path,
3177+ GError **error);
3178+
3179+gboolean
3180+task_manager_api_wrapper_unset_task_icon_by_name (TaskManagerApiWrapper *wrapper,
3181+ gchar *name,
3182+ GError **error);
3183+
3184+gboolean
3185+task_manager_api_wrapper_set_info_by_name (TaskManagerApiWrapper *wrapper,
3186+ gchar *name,
3187+ gchar *info,
3188+ GError **error);
3189+
3190+gboolean
3191+task_manager_api_wrapper_unset_info_by_name (TaskManagerApiWrapper *wrapper,
3192+ gchar *name,
3193+ GError **error);
3194+
3195+gboolean
3196+task_manager_api_wrapper_set_progress_by_name (TaskManagerApiWrapper *wrapper,
3197+ gchar *name,
3198+ gint progress,
3199+ GError **error);
3200+
3201+/* XID variants */
3202+
3203+gboolean
3204+task_manager_api_wrapper_set_task_icon_by_xid (TaskManagerApiWrapper *wrapper,
3205+ gint64 xid,
3206+ gchar *icon_path,
3207+ GError **error);
3208+
3209+gboolean
3210+task_manager_api_wrapper_unset_task_icon_by_xid (TaskManagerApiWrapper *wrapper,
3211+ gint64 xid,
3212+ GError **error);
3213+
3214+gboolean
3215+task_manager_api_wrapper_set_info_by_xid (TaskManagerApiWrapper *wrapper,
3216+ gint64 xid,
3217+ gchar *info,
3218+ GError **error);
3219+
3220+gboolean
3221+task_manager_api_wrapper_unset_info_by_xid (TaskManagerApiWrapper *wrapper,
3222+ gint64 xid,
3223+ GError **error);
3224+
3225+gboolean
3226+task_manager_api_wrapper_set_progress_by_xid (TaskManagerApiWrapper *wrapper,
3227+ gint64 xid,
3228+ gint progress,
3229+ GError **error);
3230+
3231+#endif /* _TASK_MANAGER_API_WRAPPER_H_ */
3232+
3233
3234=== modified file 'applets/taskmanager/task-manager.c'
3235--- applets/taskmanager/task-manager.c 2009-06-11 05:04:21 +0000
3236+++ applets/taskmanager/task-manager.c 2009-06-28 01:53:46 +0000
3237@@ -14,7 +14,7 @@
3238 * along with this program. If not, see <http://www.gnu.org/licenses/>.
3239 *
3240 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
3241- *
3242+ * Hannes Verschore <hv1989@gmail.com>
3243 */
3244
3245 #include <stdio.h>
3246@@ -29,9 +29,9 @@
3247
3248 #include "task-drag-indicator.h"
3249 #include "task-icon.h"
3250-#include "task-launcher.h"
3251+//#include "task-launcher.h"
3252+//#include "task-window.h"
3253 #include "task-settings.h"
3254-#include "task-window.h"
3255 #include "xutils.h"
3256
3257 G_DEFINE_TYPE (TaskManager, task_manager, AWN_TYPE_APPLET)
3258@@ -48,17 +48,15 @@
3259 TaskSettings *settings;
3260 WnckScreen *screen;
3261
3262-
3263 /* Dragging properties */
3264 TaskIcon *dragged_icon;
3265 TaskDragIndicator *drag_indicator;
3266 gint drag_timeout;
3267
3268 /* This is what the icons are packed into */
3269- GtkWidget *box;
3270+ GtkWidget *box;
3271 GSList *icons;
3272 GSList *windows;
3273- GSList *launchers;
3274 GHashTable *win_table;
3275
3276 /* Properties */
3277@@ -66,7 +64,7 @@
3278 gboolean show_all_windows;
3279 gboolean only_show_launchers;
3280 gboolean drag_and_drop;
3281- gint grouping_mode;
3282+ gint match_strength;
3283 };
3284
3285 enum
3286@@ -77,30 +75,20 @@
3287 PROP_ONLY_SHOW_LAUNCHERS,
3288 PROP_LAUNCHER_PATHS,
3289 PROP_DRAG_AND_DROP,
3290- PROP_GROUPING_MODE
3291-};
3292-
3293-enum
3294-{
3295- GROUPING_NONE,
3296- GROUPING_UTIL,
3297- GROUPING_PID,
3298- GROUPING_WNCK_APP,
3299- GROUPING_WMCLASS,
3300- GROUPING_END
3301+ PROP_MATCH_STRENGTH
3302 };
3303
3304 /* Forwards */
3305-static void ensure_layout (TaskManager *manager);
3306+static void update_icon_visible (TaskManager *manager,
3307+ TaskIcon *icon);
3308+static void on_icon_visible_changed (TaskManager *manager,
3309+ TaskIcon *icon);
3310 static void on_window_opened (WnckScreen *screen,
3311 WnckWindow *window,
3312 TaskManager *manager);
3313 static void on_active_window_changed (WnckScreen *screen,
3314 WnckWindow *old_window,
3315 TaskManager *manager);
3316-static void on_wnck_window_closed (WnckScreen *screen,
3317- WnckWindow *window,
3318- TaskManager *manager);
3319 static void task_manager_set_show_all_windows (TaskManager *manager,
3320 gboolean show_all);
3321 static void task_manager_set_show_only_launchers (TaskManager *manager,
3322@@ -110,14 +98,15 @@
3323 static void task_manager_set_drag_and_drop (TaskManager *manager,
3324 gboolean drag_and_drop);
3325
3326-static void task_manager_set_grouping_mode (TaskManager *manager,
3327- gint drag_and_drop);
3328+static void task_manager_set_match_strength (TaskManager *manager,
3329+ gint drag_and_drop);
3330
3331 static void task_manager_orient_changed (AwnApplet *applet,
3332 AwnOrientation orient);
3333 static void task_manager_size_changed (AwnApplet *applet,
3334 gint size);
3335
3336+
3337 /* D&D Forwards */
3338 static void _drag_dest_motion (TaskManager *manager,
3339 gint x,
3340@@ -163,9 +152,9 @@
3341 case PROP_DRAG_AND_DROP:
3342 g_value_set_boolean (value, manager->priv->drag_and_drop);
3343 break;
3344-
3345- case PROP_GROUPING_MODE:
3346- g_value_set_int (value, manager->priv->grouping_mode);
3347+
3348+ case PROP_MATCH_STRENGTH:
3349+ g_value_set_int (value, manager->priv->match_strength);
3350 break;
3351
3352 default:
3353@@ -200,11 +189,10 @@
3354 case PROP_DRAG_AND_DROP:
3355 task_manager_set_drag_and_drop (manager,
3356 g_value_get_boolean (value));
3357- break;
3358-
3359- case PROP_GROUPING_MODE:
3360- task_manager_set_grouping_mode (manager,
3361- g_value_get_int (value));
3362+
3363+ case PROP_MATCH_STRENGTH:
3364+ task_manager_set_match_strength (manager,
3365+ g_value_get_int (value));
3366 break;
3367
3368
3369@@ -250,8 +238,8 @@
3370 AWN_CONFIG_CLIENT_DEFAULT_GROUP, "drag_and_drop",
3371 object, "drag_and_drop");
3372 awn_config_bridge_bind (bridge, priv->client,
3373- AWN_CONFIG_CLIENT_DEFAULT_GROUP, "grouping_mode",
3374- object, "grouping_mode");
3375+ AWN_CONFIG_CLIENT_DEFAULT_GROUP, "match_strength",
3376+ object, "match_strength");
3377 }
3378
3379 static void
3380@@ -296,14 +284,14 @@
3381 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
3382 g_object_class_install_property (obj_class, PROP_DRAG_AND_DROP, pspec);
3383
3384- pspec = g_param_spec_int ("grouping_mode",
3385- "grouping_mode",
3386- "Window Grouping Mode",
3387- 0,
3388- GROUPING_END-1,
3389- 0,
3390- G_PARAM_READWRITE);
3391- g_object_class_install_property (obj_class, PROP_GROUPING_MODE, pspec);
3392+ pspec = g_param_spec_int ("match_strength",
3393+ "match_strength",
3394+ "How radical matching is applied for grouping items",
3395+ 0,
3396+ 99,
3397+ 0,
3398+ G_PARAM_READWRITE);
3399+ g_object_class_install_property (obj_class, PROP_MATCH_STRENGTH, pspec);
3400
3401 g_type_class_add_private (obj_class, sizeof (TaskManagerPrivate));
3402 }
3403@@ -342,12 +330,6 @@
3404 G_CALLBACK (on_window_opened), manager);
3405 g_signal_connect (priv->screen, "active-window-changed",
3406 G_CALLBACK (on_active_window_changed), manager);
3407- g_signal_connect_swapped (priv->screen, "active-workspace-changed",
3408- G_CALLBACK (ensure_layout), manager);
3409- g_signal_connect_swapped (priv->screen, "viewports-changed",
3410- G_CALLBACK (ensure_layout), manager);
3411- g_signal_connect (priv->screen, "window-closed",
3412- G_CALLBACK(on_wnck_window_closed),manager);
3413 }
3414
3415 AwnApplet *
3416@@ -411,80 +393,15 @@
3417 }
3418
3419 /*
3420- * The guts of the show or hide logic
3421- */
3422-static void
3423-ensure_layout (TaskManager *manager)
3424-{
3425- TaskManagerPrivate *priv = manager->priv;
3426- WnckWorkspace *space;
3427- GSList *i;
3428-
3429- space = wnck_screen_get_active_workspace (priv->screen);
3430-
3431- if (!WNCK_IS_WORKSPACE (space))
3432- {
3433- return;
3434- }
3435-
3436- /* Go through all the TaskIcons to make sure that they should be shown */
3437- for (i = priv->icons; i; i = i->next)
3438- {
3439- TaskIcon *icon = i->data;
3440-
3441- if (!TASK_IS_ICON (icon))
3442- continue;
3443-
3444- /* If the icon gets dragged, it shouldn't be shown */
3445- if( icon == priv->dragged_icon )
3446- {
3447- gtk_widget_hide (GTK_WIDGET (icon));
3448- continue;
3449- }
3450-
3451- /* Show launchers regardless of workspace */
3452- if (task_icon_is_launcher (icon))
3453- {
3454- gtk_widget_show (GTK_WIDGET (icon));
3455- continue;
3456- }
3457-
3458- /* FIXME: Add support for start-up notification icons too */
3459-
3460- /*
3461- * Only show normal window icons if a) the use wants to see them and b) if
3462- * they are on the correct workspace
3463- */
3464- if (priv->only_show_launchers)
3465- {
3466- gtk_widget_hide (GTK_WIDGET (icon));
3467- }
3468- else if (task_icon_is_skip_taskbar (icon))
3469- {
3470- gtk_widget_hide (GTK_WIDGET (icon));
3471- }
3472- else if (task_icon_is_in_viewport (icon, space))
3473- {
3474- gtk_widget_show (GTK_WIDGET (icon));
3475- }
3476- else if (priv->show_all_windows)
3477- {
3478- gtk_widget_show (GTK_WIDGET (icon));
3479- }
3480- else
3481- {
3482- gtk_widget_hide (GTK_WIDGET (icon));
3483- }
3484- }
3485-
3486- /* Hide drag_indicator if there is no AwnIcon currently dragged */
3487- if(priv->dragged_icon == NULL)
3488- gtk_widget_hide (GTK_WIDGET(priv->drag_indicator));
3489-}
3490-
3491-/*
3492 * WNCK_SCREEN CALLBACKS
3493 */
3494+
3495+/**
3496+ * This signal is only connected for windows which were of type normal/utility
3497+ * and were initially "skip-tasklist". If they are not skip-tasklist anymore
3498+ * we treat them as newly opened windows.
3499+ * STATE: done
3500+ */
3501 static void
3502 on_window_state_changed (WnckWindow *window,
3503 WnckWindowState changed_mask,
3504@@ -493,10 +410,7 @@
3505 {
3506 g_return_if_fail (TASK_IS_MANAGER (manager));
3507
3508- /* This signal is only connected for windows which were of type normal/utility
3509- * and were initially "skip-tasklist". If they are not skip-tasklist anymore
3510- * we treat them as newly opened windows
3511- */
3512+ // test if they don't skip-tasklist anymore
3513 if (!wnck_window_is_skip_tasklist (window))
3514 {
3515 g_signal_handlers_disconnect_by_func (window,
3516@@ -506,315 +420,145 @@
3517 }
3518 }
3519
3520+/**
3521+ * The active WnckWindow has changed.
3522+ * Retrieve the TaskWindows and update there active state
3523+ */
3524 static void
3525-on_wnck_window_closed (WnckScreen *screen, WnckWindow *window, TaskManager *manager)
3526-{
3527- GSList *i;
3528- TaskManagerPrivate *priv = manager->priv;
3529- for (i = priv->icons; i; i = i->next)
3530- {
3531- TaskIcon *taskicon = i->data;
3532- if (!TASK_IS_ICON (taskicon))
3533- continue;
3534- task_icon_remove_window (taskicon, window);
3535- }
3536-}
3537-
3538-static gboolean
3539-check_wmclass(TaskWindow *taskwin,gchar * win_res_name, gchar *win_class_name)
3540-{
3541- gboolean result;
3542- gchar *temp;
3543- gchar *res_name = NULL;
3544- gchar *class_name = NULL;
3545-
3546- _wnck_get_wmclass (task_window_get_xid (taskwin), &res_name, &class_name);
3547- if (res_name)
3548- {
3549- temp = res_name;
3550- res_name = g_utf8_strdown (temp, -1);
3551- g_free (temp);
3552- }
3553-
3554- if (class_name)
3555- {
3556- temp = class_name;
3557- class_name = g_utf8_strdown (temp, -1);
3558- g_free (temp);
3559- }
3560- result = (
3561- (g_strcmp0 (res_name,win_res_name)==0)
3562- ||
3563- (g_strcmp0 (class_name,win_class_name)==0)
3564- );
3565- g_free (res_name);
3566- g_free (class_name);
3567-
3568- return result;
3569-}
3570-
3571-static gboolean
3572-try_to_place_window_by_wmclass (TaskManager *manager, WnckWindow *window)
3573-{
3574- GSList *i;
3575- TaskManagerPrivate *priv = manager->priv;
3576- gchar *temp;
3577- gchar *res_name = NULL;
3578- gchar *class_name = NULL;
3579-
3580- /* Grab the appropriete info */
3581- _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
3582-
3583- if (res_name)
3584- {
3585- temp = res_name;
3586- res_name = g_utf8_strdown (temp, -1);
3587- g_free (temp);
3588- }
3589-
3590- if (class_name)
3591- {
3592- temp = class_name;
3593- class_name = g_utf8_strdown (temp, -1);
3594- g_free (temp);
3595- }
3596-
3597- for (i = priv->icons; i; i = i->next)
3598- {
3599- TaskIcon *taskicon = i->data;
3600- TaskWindow *taskwin = NULL;
3601-
3602- if (!TASK_IS_ICON (taskicon))
3603- continue;
3604-
3605- taskwin = task_icon_get_window(taskicon);
3606-
3607- if ( check_wmclass (taskwin,res_name,class_name) )
3608- {
3609- task_icon_append_window (taskicon, task_window_new (window));
3610- g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);
3611- g_free (res_name);
3612- g_free (class_name);
3613- return TRUE;
3614- }
3615- }
3616-
3617- g_free (res_name);
3618- g_free (class_name);
3619- return FALSE;
3620-}
3621-
3622-static gboolean
3623-try_to_place_window_by_wnck_app (TaskManager *manager, WnckWindow *window)
3624-{
3625- TaskManagerPrivate *priv = manager->priv;
3626- GSList *i;
3627- WnckApplication *taskwin_app;
3628-
3629- for (i = priv->icons; i; i = i->next)
3630- {
3631- TaskIcon *taskicon = i->data;
3632- TaskWindow *taskwin = NULL;
3633-
3634- if (!TASK_IS_ICON (taskicon))
3635- continue;
3636-
3637- taskwin = task_icon_get_window(taskicon);
3638- taskwin_app = task_window_get_application (taskwin);
3639- if ( taskwin_app && (taskwin_app == wnck_window_get_application (window)))
3640- {
3641- task_icon_append_window (taskicon, task_window_new (window));
3642- g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);
3643- return TRUE;
3644- }
3645- }
3646-
3647- return FALSE;
3648-}
3649-
3650-static gboolean
3651-try_to_place_window_by_pid (TaskManager *manager, WnckWindow *window)
3652-{
3653- TaskManagerPrivate *priv = manager->priv;
3654- GSList *i;
3655- gint taskwin_pid = -1;
3656- gint matches = 0;
3657-
3658- for (i = priv->icons; i; i = i->next)
3659- {
3660- TaskIcon *taskicon = i->data;
3661- TaskWindow *taskwin = NULL;
3662-
3663- if (!TASK_IS_ICON (taskicon))
3664- continue;
3665-
3666- taskwin = task_icon_get_window(taskicon);
3667- taskwin_pid = task_window_get_pid (taskwin);
3668- if ( taskwin_pid && (taskwin_pid == wnck_window_get_pid (window)))
3669- {
3670- if (matches)
3671- {
3672- task_icon_append_window (taskicon, task_window_new (window));
3673- g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);
3674- return TRUE;
3675- }
3676- matches++;
3677- }
3678- }
3679- return FALSE;
3680-}
3681-
3682-static gboolean
3683-try_to_place_util_window (TaskManager *manager, WnckWindow *window)
3684-{
3685- WnckWindowType type = wnck_window_get_window_type (window);
3686- TaskManagerPrivate *priv = manager->priv;
3687- GSList *w;
3688- gint taskwin_pid = -1;
3689- gint matches = 0;
3690-
3691- if ( (type != WNCK_WINDOW_UTILITY) && (type != WNCK_WINDOW_DIALOG) )
3692- {
3693- return FALSE;
3694- }
3695-
3696- for (w = priv->icons; w; w = w->next)
3697- {
3698- TaskIcon *taskicon = w->data;
3699- TaskWindow *taskwin = NULL;
3700-
3701- if (!TASK_IS_ICON (taskicon))
3702- continue;
3703-
3704- taskwin = task_icon_get_window(taskicon);
3705- taskwin_pid = task_window_get_pid (taskwin);
3706- if ( taskwin_pid && (taskwin_pid == wnck_window_get_pid (window)))
3707- {
3708- if (matches)
3709- {
3710- task_icon_append_window (taskicon, task_window_new (window));
3711- g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);
3712- return TRUE;
3713- }
3714- matches++;
3715- }
3716- }
3717- return FALSE;
3718-}
3719-
3720-static gboolean
3721-try_to_place_window (TaskManager *manager, WnckWindow *window)
3722-{
3723- TaskManagerPrivate *priv = manager->priv;
3724- gboolean result = FALSE;
3725- switch(priv->grouping_mode)
3726- {
3727- case GROUPING_WMCLASS: /*Fall through*/
3728- result =result?result:try_to_place_window_by_wmclass(manager,window);
3729- case GROUPING_WNCK_APP:/*Fall through*/
3730- result =result?result:try_to_place_window_by_wnck_app(manager,window);
3731- case GROUPING_PID: /*Don't Fall through*/
3732- result =result?result:try_to_place_window_by_pid(manager,window);
3733- break;
3734- case GROUPING_UTIL:/*Don't Fall through*/
3735- result =result?result:try_to_place_util_window(manager,window);
3736- break;
3737- case GROUPING_NONE:
3738- break;
3739- default:
3740- g_assert_not_reached();
3741- }
3742- return result;
3743-}
3744-
3745-static gboolean
3746-try_to_match_window_to_launcher (TaskManager *manager, WnckWindow *window)
3747-{
3748- TaskManagerPrivate *priv = manager->priv;
3749- GSList *l;
3750- gchar *temp;
3751- gchar *res_name = NULL;
3752- gchar *class_name = NULL;
3753- gint pid;
3754- gboolean res = FALSE;
3755-
3756- /* Grab the appropriete info */
3757- pid = wnck_window_get_pid (window);
3758- _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
3759-
3760- if (res_name)
3761- {
3762- temp = res_name;
3763- res_name = g_utf8_strdown (temp, -1);
3764- g_free (temp);
3765- }
3766-
3767- if (class_name)
3768- {
3769- temp = class_name;
3770- class_name = g_utf8_strdown (temp, -1);
3771- g_free (temp);
3772- }
3773-
3774- /* Try and match */
3775- for (l = priv->launchers; l; l = l->next)
3776- {
3777- TaskLauncher *launcher = l->data;
3778-
3779- if (!TASK_IS_LAUNCHER (launcher))
3780- continue;
3781-
3782- if (task_launcher_has_window (launcher))
3783- continue;
3784-
3785- if (!task_launcher_try_match (launcher, pid, res_name, class_name))
3786- continue;
3787-
3788- /* As it matched this launcher, we can set the window to the launcher and
3789- * get on with it
3790- */
3791- task_launcher_set_window (launcher, window);
3792- g_object_set_qdata (G_OBJECT (window), win_quark, launcher);
3793- res = TRUE;
3794- }
3795- g_free (res_name);
3796- g_free (class_name);
3797-
3798- return res;
3799-}
3800-
3801-static gboolean
3802-try_to_match_window_to_sn_context (TaskManager *manager, WnckWindow *window)
3803-{
3804- return FALSE;
3805-}
3806-
3807-static void
3808-window_closed (TaskManager *manager, GObject *old_window)
3809-{
3810- TaskManagerPrivate *priv;
3811-
3812- g_return_if_fail (TASK_IS_MANAGER (manager));
3813- priv = manager->priv;
3814-
3815- priv->windows = g_slist_remove (priv->windows, old_window);
3816-
3817- ensure_layout (manager);
3818-}
3819-
3820+on_active_window_changed (WnckScreen *screen,
3821+ WnckWindow *old_window,
3822+ TaskManager *manager)
3823+{
3824+ TaskManagerPrivate *priv;
3825+ WnckWindow *active = NULL;
3826+ TaskWindow *taskwin = NULL;
3827+ TaskWindow *old_taskwin = NULL;
3828+
3829+ g_return_if_fail (TASK_IS_MANAGER (manager));
3830+ priv = manager->priv;
3831+
3832+ active = wnck_screen_get_active_window (priv->screen);
3833+
3834+ if (WNCK_IS_WINDOW (old_window))
3835+ old_taskwin = (TaskWindow *)g_object_get_qdata (G_OBJECT (old_window),
3836+ win_quark);
3837+ if (WNCK_IS_WINDOW (active))
3838+ taskwin = (TaskWindow *)g_object_get_qdata (G_OBJECT (active), win_quark);
3839+
3840+ if (TASK_IS_WINDOW (old_taskwin))
3841+ task_window_set_is_active (old_taskwin, FALSE);
3842+ if (TASK_IS_WINDOW (taskwin))
3843+ task_window_set_is_active (taskwin, TRUE);
3844+}
3845+
3846+/**
3847+ * When the property 'show_all_windows' is False,
3848+ * workspace switches are monitored. Whenever one happens
3849+ * all TaskWindows are notified.
3850+ */
3851+static void
3852+on_workspace_changed (TaskManager *manager) //... has more arguments
3853+{
3854+ TaskManagerPrivate *priv;
3855+ GSList *w;
3856+ WnckWorkspace *space;
3857+
3858+ g_return_if_fail (TASK_IS_MANAGER (manager));
3859+
3860+ priv = manager->priv;
3861+ space = wnck_screen_get_active_workspace (priv->screen);
3862+
3863+ for (w = priv->windows; w; w = w->next)
3864+ {
3865+ TaskWindow *window = w->data;
3866+
3867+ if (!TASK_IS_WINDOW (window)) continue;
3868+
3869+ task_window_set_active_workspace (window, space);
3870+ }
3871+}
3872+
3873+/*
3874+ * TASK_ICON CALLBACKS
3875+ */
3876+
3877+static void
3878+update_icon_visible (TaskManager *manager, TaskIcon *icon)
3879+{
3880+ TaskManagerPrivate *priv;
3881+
3882+ g_return_if_fail (TASK_IS_MANAGER (manager));
3883+
3884+ priv = manager->priv;
3885+
3886+ if (task_icon_is_visible (icon))
3887+ {
3888+ if (priv->only_show_launchers && !task_icon_contains_launcher (icon))
3889+ {
3890+ gtk_widget_hide (GTK_WIDGET (icon));
3891+ }
3892+ else
3893+ {
3894+ if (!GTK_WIDGET_VISIBLE (icon))
3895+ {
3896+ awn_effects_start_ex (awn_overlayable_get_effects (AWN_OVERLAYABLE (icon)),
3897+ AWN_EFFECT_OPENING, 1, FALSE, FALSE);
3898+ gtk_widget_show (GTK_WIDGET (icon));
3899+ }
3900+ }
3901+ }
3902+ else
3903+ {
3904+ gtk_widget_hide (GTK_WIDGET (icon));
3905+ }
3906+}
3907+
3908+static void
3909+on_icon_visible_changed (TaskManager *manager, TaskIcon *icon)
3910+{
3911+ g_return_if_fail (TASK_IS_MANAGER (manager));
3912+
3913+ update_icon_visible (manager, icon);
3914+}
3915+
3916+/**
3917+ * This function gets called whenever a task-window gets finalized.
3918+ * It removes the task-window from the list.
3919+ * State: done
3920+ */
3921+static void
3922+window_closed (TaskManager *manager, GObject *old_item)
3923+{
3924+ TaskManagerPrivate *priv;
3925+
3926+ g_return_if_fail (TASK_IS_MANAGER (manager));
3927+
3928+ priv = manager->priv;
3929+ priv->windows = g_slist_remove (priv->windows, old_item);
3930+}
3931+
3932+/**
3933+ * This function gets called whenever a task-icon gets finalized.
3934+ * It removes the task-icon from the gslist and update layout
3935+ * (so it gets removed from the bar)
3936+ * State: done
3937+ */
3938 static void
3939 icon_closed (TaskManager *manager, GObject *old_icon)
3940 {
3941 TaskManagerPrivate *priv;
3942
3943 g_return_if_fail (TASK_IS_MANAGER (manager));
3944+
3945 priv = manager->priv;
3946-
3947 priv->icons = g_slist_remove (priv->icons, old_icon);
3948-
3949- ensure_layout (manager);
3950 }
3951
3952+/**
3953+ * Whenever a new window gets opened it will try to place it
3954+ * in an awn-icon or will create a new awn-icon.
3955+ * State: adjusted
3956+ */
3957 static void
3958 on_window_opened (WnckScreen *screen,
3959 WnckWindow *window,
3960@@ -822,13 +566,17 @@
3961 {
3962 TaskManagerPrivate *priv;
3963 GtkWidget *icon;
3964- TaskWindow *taskwin;
3965+ TaskItem *item;
3966 WnckWindowType type;
3967+ GSList *w;
3968+ TaskIcon *match = NULL;
3969+ gint match_score = 0;
3970+ gint max_match_score = 0;
3971
3972 g_return_if_fail (TASK_IS_MANAGER (manager));
3973 g_return_if_fail (WNCK_IS_WINDOW (window));
3974+
3975 priv = manager->priv;
3976-
3977 type = wnck_window_get_window_type (window);
3978
3979 switch (type)
3980@@ -855,84 +603,52 @@
3981 return;
3982 }
3983
3984- /*
3985- */
3986-
3987- if ( priv->grouping_mode && try_to_place_window (manager,window))
3988- {
3989- g_debug ("WINDOW PLACED: %s", wnck_window_get_name (window));
3990- return;
3991- }
3992-
3993- /* Okay, time to check the launchers if we can get a match */
3994- if (try_to_match_window_to_launcher (manager, window))
3995- {
3996- g_debug ("WINDOW MATCHED: %s", wnck_window_get_name (window));
3997- return;
3998- }
3999-
4000- /* Try the startup-notification windows */
4001- if (try_to_match_window_to_sn_context (manager, window))
4002- {
4003- g_debug ("WINDOW STARTUP: %s", wnck_window_get_name (window));
4004- return;
4005- }
4006-
4007- /*
4008- * We couldn't append the window to a pre-existing TaskWindow, so we'll need
4009- * to make a new one
4010- */
4011- taskwin = task_window_new (window);
4012- priv->windows = g_slist_append (priv->windows, taskwin);
4013- g_object_weak_ref (G_OBJECT (taskwin), (GWeakNotify)window_closed, manager);
4014- g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);
4015-
4016- /* If we've come this far, the window deserves a spot on the task-manager!
4017- * Time to create a TaskIcon for it
4018- */
4019- icon = task_icon_new_for_window (taskwin);
4020- gtk_container_add (GTK_CONTAINER (priv->box), icon);
4021- gtk_widget_show (icon);
4022-
4023- priv->icons = g_slist_append (priv->icons, icon);
4024- g_signal_connect_swapped (icon, "ensure_layout",
4025- G_CALLBACK (ensure_layout), manager);
4026-
4027- /* reordening through D&D */
4028- if(priv->drag_and_drop)
4029- _drag_add_signals(manager, icon);
4030-
4031- g_object_weak_ref (G_OBJECT (icon), (GWeakNotify)icon_closed, manager);
4032-
4033- /* Finally, make sure all is well on the taskbar */
4034- ensure_layout (manager);
4035-}
4036-
4037-static void
4038-on_active_window_changed (WnckScreen *screen,
4039- WnckWindow *old_window,
4040- TaskManager *manager)
4041-{
4042- TaskManagerPrivate *priv;
4043- WnckWindow *active = NULL;
4044- TaskWindow *taskwin = NULL;
4045- TaskWindow *old_taskwin = NULL;
4046-
4047- g_return_if_fail (TASK_IS_MANAGER (manager));
4048- priv = manager->priv;
4049-
4050- active = wnck_screen_get_active_window (priv->screen);
4051-
4052- if (WNCK_IS_WINDOW (old_window))
4053- old_taskwin = (TaskWindow *)g_object_get_qdata (G_OBJECT (old_window),
4054- win_quark);
4055- if (WNCK_IS_WINDOW (active))
4056- taskwin = (TaskWindow *)g_object_get_qdata (G_OBJECT (active), win_quark);
4057-
4058- if (TASK_IS_WINDOW (old_taskwin))
4059- task_window_set_is_active (old_taskwin, FALSE);
4060- if (TASK_IS_WINDOW (taskwin))
4061- task_window_set_is_active (taskwin, TRUE);
4062+ // create a new TaskWindow containing the WnckWindow
4063+ item = task_window_new (window);
4064+ g_object_set_qdata (G_OBJECT (window), win_quark, TASK_WINDOW (item));
4065+
4066+ priv->windows = g_slist_append (priv->windows, item);
4067+ g_object_weak_ref (G_OBJECT (item), (GWeakNotify)window_closed, manager);
4068+
4069+ // see if there is a icon that matches
4070+ for (w = priv->icons; w; w = w->next)
4071+ {
4072+ TaskIcon *taskicon = w->data;
4073+
4074+ if (!TASK_IS_ICON (taskicon)) continue;
4075+
4076+ match_score = task_icon_match_item (taskicon, item);
4077+ if (match_score > max_match_score)
4078+ {
4079+ max_match_score = match_score;
4080+ match = taskicon;
4081+ }
4082+ }
4083+
4084+ g_debug("Matching score: %i, must be bigger then:%i, groups: %i", max_match_score, 99-priv->match_strength, max_match_score > 99-priv->match_strength);
4085+
4086+ if (max_match_score > 99-priv->match_strength)
4087+ {
4088+ task_icon_append_item (match, item);
4089+ }
4090+ else
4091+ {
4092+ icon = task_icon_new();
4093+ task_icon_append_item (TASK_ICON (icon), item);
4094+
4095+ priv->icons = g_slist_append (priv->icons, icon);
4096+ gtk_container_add (GTK_CONTAINER (priv->box), icon);
4097+
4098+ /* reordening through D&D */
4099+ if(priv->drag_and_drop)
4100+ _drag_add_signals(manager, icon);
4101+
4102+ g_object_weak_ref (G_OBJECT (icon), (GWeakNotify)icon_closed, manager);
4103+ g_signal_connect_swapped (icon, "visible-changed",
4104+ G_CALLBACK (on_icon_visible_changed), manager);
4105+
4106+ update_icon_visible (manager, TASK_ICON (icon));
4107+ }
4108 }
4109
4110 /*
4111@@ -942,26 +658,86 @@
4112 task_manager_set_show_all_windows (TaskManager *manager,
4113 gboolean show_all)
4114 {
4115+ TaskManagerPrivate *priv;
4116+ GSList *w;
4117+ WnckWorkspace *space = NULL;
4118+
4119 g_return_if_fail (TASK_IS_MANAGER (manager));
4120+
4121+ priv = manager->priv;
4122+
4123+ if (priv->show_all_windows == show_all) return;
4124+
4125 manager->priv->show_all_windows = show_all;
4126
4127- ensure_layout (manager);
4128-
4129+ if (show_all)
4130+ {
4131+ // Remove signals of workspace changes
4132+ g_signal_handlers_disconnect_by_func(priv->screen,
4133+ G_CALLBACK (on_workspace_changed),
4134+ manager);
4135+
4136+ // Set workspace to NULL, so TaskWindows aren't tied to workspaces anymore
4137+ space = NULL;
4138+ }
4139+ else
4140+ {
4141+ // Add signals to WnckScreen for workspace changes
4142+ g_signal_connect_swapped (priv->screen, "viewports-changed",
4143+ G_CALLBACK (on_workspace_changed), manager);
4144+ g_signal_connect_swapped (priv->screen, "active-workspace-changed",
4145+ G_CALLBACK (on_workspace_changed), manager);
4146+
4147+ // Retrieve the current active workspace
4148+ space = wnck_screen_get_active_workspace (priv->screen);
4149+ }
4150+
4151+ /* Update the workspace for every TaskWindow.
4152+ * NULL if the windows aren't tied to a workspace anymore */
4153+ for (w = priv->windows; w; w = w->next)
4154+ {
4155+ TaskWindow *window = w->data;
4156+ if (!TASK_IS_WINDOW (window)) continue;
4157+ task_window_set_active_workspace (window, space);
4158+ }
4159+
4160 g_debug ("%s", show_all ? "showing all windows":"not showing all windows");
4161 }
4162
4163+/**
4164+ * The property 'show_only_launchers' changed.
4165+ * So update the property and update the visiblity of every icon.
4166+ */
4167 static void
4168 task_manager_set_show_only_launchers (TaskManager *manager,
4169- gboolean show_only)
4170+ gboolean only_show_launchers)
4171 {
4172+ TaskManagerPrivate *priv;
4173+ GSList *w;
4174+
4175 g_return_if_fail (TASK_IS_MANAGER (manager));
4176- manager->priv->only_show_launchers = show_only;
4177-
4178- ensure_layout (manager);
4179-
4180- g_debug ("%s", show_only ? "only show launchers":"show everything");
4181+
4182+ priv = manager->priv;
4183+ priv->only_show_launchers = only_show_launchers;
4184+
4185+ for (w = priv->icons; w; w = w->next)
4186+ {
4187+ TaskIcon *icon = w->data;
4188+
4189+ if (!TASK_IS_ICON (icon)) continue;
4190+
4191+ update_icon_visible (manager, icon);
4192+ }
4193+
4194+ g_debug ("%s", only_show_launchers ? "only show launchers":"show everything");
4195 }
4196
4197+/**
4198+ * Checks when launchers got added/removed in the list in gconf/file.
4199+ * It removes the launchers from the task-icons and add those
4200+ * that aren't already on the bar.
4201+ * State: partial - TODO: refresh of a list
4202+ */
4203 static void
4204 task_manager_refresh_launcher_paths (TaskManager *manager,
4205 GSList *list)
4206@@ -979,41 +755,23 @@
4207 for (d = list; d; d = d->next)
4208 {
4209 GtkWidget *icon;
4210- TaskLauncher *launcher = NULL;
4211- GSList *l;
4212-
4213- for (l = priv->launchers; l; l = l->next)
4214- {
4215- TaskLauncher *launch = l->data;
4216-
4217- if (!TASK_IS_LAUNCHER (launch))
4218- continue;
4219-
4220- if (g_strcmp0 (d->data, task_launcher_get_desktop_path (launch)) == 0)
4221- {
4222- launcher = launch;
4223- break;
4224- }
4225- }
4226-
4227- if (TASK_IS_LAUNCHER (launcher))
4228- continue;
4229+ TaskItem *launcher = NULL;
4230
4231 launcher = task_launcher_new_for_desktop_file (d->data);
4232
4233- if (!launcher)
4234- continue;
4235+ if (!launcher) continue;
4236
4237- priv->launchers = g_slist_append (priv->launchers, launcher);
4238-
4239- icon = task_icon_new_for_window (TASK_WINDOW (launcher));
4240+ icon = task_icon_new ();
4241+ task_icon_append_item (TASK_ICON (icon), launcher);
4242 gtk_container_add (GTK_CONTAINER (priv->box), icon);
4243- gtk_widget_show (icon);
4244
4245 priv->icons = g_slist_append (priv->icons, icon);
4246- g_signal_connect_swapped (icon, "ensure_layout",
4247- G_CALLBACK (ensure_layout), manager);
4248+
4249 g_object_weak_ref (G_OBJECT (icon), (GWeakNotify)icon_closed, manager);
4250+ g_signal_connect_swapped (icon, "visible-changed",
4251+ G_CALLBACK (on_icon_visible_changed), manager);
4252+
4253+ update_icon_visible (manager, TASK_ICON (icon));
4254
4255 /* reordening through D&D */
4256 if(priv->drag_and_drop)
4257@@ -1023,19 +781,14 @@
4258 for (d = list; d; d = d->next)
4259 g_free (d->data);
4260 g_slist_free (list);
4261-
4262- /* Finally, make sure all is well on the taskbar */
4263- ensure_layout (manager);
4264 }
4265
4266 static void
4267-task_manager_set_grouping_mode (TaskManager *manager,
4268- gint grouping_mode)
4269+task_manager_set_match_strength (TaskManager *manager,
4270+ gint match_strength)
4271 {
4272 g_return_if_fail (TASK_IS_MANAGER (manager));
4273- manager->priv->grouping_mode = grouping_mode;
4274-
4275- ensure_layout (manager);
4276+ manager->priv->match_strength = match_strength;
4277 }
4278
4279 static void
4280@@ -1049,37 +802,189 @@
4281
4282 priv->drag_and_drop = drag_and_drop;
4283
4284+ //connect or dissconnect the dragging signals
4285+ for (i = priv->icons; i; i = i->next)
4286+ {
4287+ TaskIcon *icon = i->data;
4288+
4289+ if (!TASK_IS_ICON (icon)) continue;
4290+
4291+ if(drag_and_drop)
4292+ {
4293+ _drag_add_signals (manager, GTK_WIDGET(icon));
4294+ }
4295+ else
4296+ {
4297+ //FIXME: Stop any ongoing move
4298+ _drag_remove_signals (manager, GTK_WIDGET(icon));
4299+ }
4300+ }
4301 if(drag_and_drop)
4302 {
4303- //connect to the dragging signals
4304- for (i = priv->icons; i; i = i->next)
4305- {
4306- TaskIcon *icon = i->data;
4307-
4308- if (!TASK_IS_ICON (icon)) continue;
4309-
4310- _drag_add_signals (manager, GTK_WIDGET(icon));
4311- }
4312 _drag_add_signals (manager, GTK_WIDGET(priv->drag_indicator));
4313 }
4314 else
4315 {
4316- //disconnect the dragging signals
4317- for (i = priv->icons; i; i = i->next)
4318- {
4319- TaskIcon *icon = i->data;
4320-
4321- if (!TASK_IS_ICON (icon)) continue;
4322-
4323- _drag_remove_signals (manager, GTK_WIDGET(icon));
4324- }
4325 _drag_remove_signals (manager, GTK_WIDGET(priv->drag_indicator));
4326- //FIXME: Stop any ongoing move
4327 }
4328
4329 g_debug("%s", drag_and_drop?"D&D is on":"D&D is off");
4330 }
4331
4332+/**
4333+ * D-BUS functionality
4334+ */
4335+
4336+gboolean
4337+task_manager_get_capabilities (TaskManager *manager,
4338+ GStrv *supported_keys,
4339+ GError **error)
4340+{
4341+ const gchar *known_keys[] =
4342+ {
4343+ "icon-file",
4344+ "progress",
4345+ "message",
4346+ "visible",
4347+ NULL
4348+ };
4349+
4350+ *supported_keys = g_strdupv ((char **)known_keys);
4351+
4352+ return TRUE;
4353+}
4354+
4355+/**
4356+ * Find the window that corresponds to the given window name.
4357+ * First try to match the application name, then the normal name.
4358+ */
4359+static TaskWindow*
4360+_match_name (TaskManager *manager, const gchar* window)
4361+{
4362+ TaskManagerPrivate *priv;
4363+ WnckApplication *wnck_app = NULL;
4364+ const gchar *name = NULL;
4365+ GSList *w;
4366+
4367+ g_return_val_if_fail (TASK_IS_MANAGER (manager), FALSE);
4368+ priv = manager->priv;
4369+
4370+ for (w = priv->windows; w; w = w->next)
4371+ {
4372+ TaskWindow *taskwindow = w->data;
4373+
4374+ if (!TASK_IS_WINDOW (taskwindow)) continue;
4375+
4376+ wnck_app = task_window_get_application (taskwindow);
4377+ if (WNCK_IS_APPLICATION(wnck_app))
4378+ {
4379+ name = wnck_application_get_name(wnck_app);
4380+ if (name && strcmp (window, name) == 0)
4381+ return taskwindow;
4382+ }
4383+
4384+ name = task_window_get_name (taskwindow);
4385+ if (name && strcmp (window, name) == 0)
4386+ return taskwindow;
4387+ }
4388+
4389+ return NULL;
4390+}
4391+
4392+/**
4393+ * Find the window that corresponds to the given xid
4394+ */
4395+static TaskWindow*
4396+_match_xid (TaskManager *manager, gint64 window)
4397+{
4398+ TaskManagerPrivate *priv;
4399+ gint64 xid;
4400+ GSList *w;
4401+
4402+ g_return_val_if_fail (TASK_IS_MANAGER (manager), FALSE);
4403+ priv = manager->priv;
4404+
4405+ for (w = priv->windows; w; w = w->next)
4406+ {
4407+ TaskWindow *taskwindow = w->data;
4408+
4409+ if (!TASK_IS_WINDOW (taskwindow)) continue;
4410+
4411+ xid = task_window_get_xid (taskwindow);
4412+ if (xid && window == xid)
4413+ return taskwindow;
4414+ }
4415+
4416+ return NULL;
4417+}
4418+
4419+gboolean
4420+task_manager_update (TaskManager *manager,
4421+ GValue *window,
4422+ GHashTable *hints, /* mappings from string to GValue */
4423+ GError **error)
4424+{
4425+ TaskManagerPrivate *priv;
4426+ TaskWindow *matched_window = NULL;
4427+
4428+ g_return_val_if_fail (TASK_IS_MANAGER (manager), FALSE);
4429+
4430+ priv = manager->priv;
4431+
4432+ if (G_VALUE_HOLDS_STRING (window))
4433+ {
4434+ matched_window = _match_name (manager, g_value_get_string (window));
4435+ }
4436+ else if (G_VALUE_HOLDS_INT64 (window))
4437+ {
4438+ matched_window = _match_xid (manager, g_value_get_int64 (window));
4439+ }
4440+ else
4441+ {
4442+ //G_ERROR stuff
4443+ return FALSE;
4444+ }
4445+
4446+ if (matched_window)
4447+ {
4448+ GHashTableIter iter;
4449+ gpointer key, value;
4450+
4451+ g_hash_table_iter_init (&iter, hints);
4452+ while (g_hash_table_iter_next (&iter, &key, &value))
4453+ {
4454+ gchar *key_name = (gchar *)key;
4455+ if (strcmp ("icon-file", key_name) == 0)
4456+ {
4457+
4458+ }
4459+ else if (strcmp ("progress", key_name) == 0)
4460+ {
4461+
4462+ }
4463+ else if (strcmp ("message", key_name) == 0)
4464+ {
4465+
4466+ }
4467+ else if (strcmp ("visible", key_name) == 0)
4468+ {
4469+
4470+ }
4471+ else
4472+ {
4473+ g_debug ("Taskmanager doesn't understand the key: %s", key_name);
4474+ }
4475+ }
4476+
4477+ return TRUE;
4478+ }
4479+ else
4480+ {
4481+ return FALSE;
4482+ }
4483+}
4484+
4485+
4486 /*
4487 * Position Icons through dragging
4488 */
4489@@ -1212,11 +1117,11 @@
4490 TaskManagerPrivate *priv;
4491 gint move_to;
4492 GList* childs;
4493- GSList* d;
4494- GSList* launchers = NULL;
4495- TaskLauncher* launcher;
4496- gchar* launcher_path;
4497- GError *err = NULL;
4498+ //GSList* d;
4499+ //GSList* launchers = NULL;
4500+ //TaskLauncher* launcher;
4501+ //gchar* launcher_path;
4502+ //GError *err = NULL;
4503
4504 g_return_if_fail (TASK_IS_MANAGER (manager));
4505
4506@@ -1252,7 +1157,7 @@
4507 // Update the position in the config (Gconf) if the AwnIcon is a launcher.
4508 // FIXME: support multiple launchers in one AwnIcon?
4509
4510- if (task_icon_is_launcher (priv->dragged_icon))
4511+/* if (task_icon_is_launcher (priv->dragged_icon))
4512 {
4513 // get the updated list
4514 childs = gtk_container_get_children (GTK_CONTAINER(priv->box));
4515@@ -1283,6 +1188,7 @@
4516 return;
4517 }
4518 }
4519+*/
4520
4521 priv->dragged_icon = NULL;
4522 }
4523
4524=== modified file 'applets/taskmanager/task-manager.h'
4525--- applets/taskmanager/task-manager.h 2009-03-03 00:58:39 +0000
4526+++ applets/taskmanager/task-manager.h 2009-06-21 23:03:17 +0000
4527@@ -64,5 +64,14 @@
4528 gint offset,
4529 gint height);
4530
4531+gboolean task_manager_get_capabilities (TaskManager *manager,
4532+ GStrv *supported_keys,
4533+ GError **error);
4534+
4535+gboolean task_manager_update (TaskManager *manager,
4536+ GValue *window,
4537+ GHashTable *hints, /* mappings from string to GValue */
4538+ GError **error);
4539+
4540 #endif /* _TASK_MANAGER_H_ */
4541
4542
4543=== removed file 'applets/taskmanager/task-window-private.h'
4544--- applets/taskmanager/task-window-private.h 2009-03-24 16:39:41 +0000
4545+++ applets/taskmanager/task-window-private.h 1970-01-01 00:00:00 +0000
4546@@ -1,35 +0,0 @@
4547-/*
4548- * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
4549- *
4550- * This program is free software: you can redistribute it and/or modify
4551- * it under the terms of the GNU General Public License version 3 as
4552- * published by the Free Software Foundation.
4553- *
4554- * This program is distributed in the hope that it will be useful,
4555- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4556- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4557- * GNU General Public License for more details.
4558- *
4559- * You should have received a copy of the GNU General Public License
4560- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4561- *
4562- * Authored by Neil Jagdish Patel <njpatel@gmail.com>
4563- *
4564- */
4565-
4566-#define TASK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
4567- TASK_TYPE_WINDOW, \
4568- TaskWindowPrivate))
4569-
4570-struct _TaskWindowPrivate
4571-{
4572- WnckWindow *window;
4573-
4574- /* Properties */
4575- gchar *message;
4576- gfloat progress;
4577- gboolean hidden;
4578- gboolean needs_attention;
4579- gboolean is_active;
4580-};
4581-
4582
4583=== modified file 'applets/taskmanager/task-window.c'
4584--- applets/taskmanager/task-window.c 2009-06-11 05:04:21 +0000
4585+++ applets/taskmanager/task-window.c 2009-06-26 11:00:10 +0000
4586@@ -14,6 +14,7 @@
4587 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4588 *
4589 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
4590+ * Hannes Verschore <hv1989@gmail.com>
4591 *
4592 */
4593
4594@@ -26,11 +27,33 @@
4595 #include <libwnck/libwnck.h>
4596
4597 #include "task-window.h"
4598-#include "task-launcher.h"
4599 #include "task-settings.h"
4600 #include "xutils.h"
4601
4602-G_DEFINE_TYPE (TaskWindow, task_window, G_TYPE_OBJECT)
4603+G_DEFINE_TYPE (TaskWindow, task_window, TASK_TYPE_ITEM)
4604+
4605+#define TASK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
4606+ TASK_TYPE_WINDOW, \
4607+ TaskWindowPrivate))
4608+
4609+struct _TaskWindowPrivate
4610+{
4611+ WnckWindow *window;
4612+
4613+ // Workspace where the window should be in, before being visible.
4614+ // NULL if it isn't important
4615+ WnckWorkspace *workspace;
4616+
4617+ // Is this window in the workspace. If workspace is NULL, this is always TRUE;
4618+ gboolean in_workspace;
4619+
4620+ /* Properties */
4621+ gchar *message;
4622+ gfloat progress;
4623+ gboolean hidden;
4624+ gboolean needs_attention;
4625+ gboolean is_active;
4626+};
4627
4628 enum
4629 {
4630@@ -40,27 +63,25 @@
4631
4632 enum
4633 {
4634- NAME_CHANGED,
4635- ICON_CHANGED,
4636 ACTIVE_CHANGED,
4637 NEEDS_ATTENTION,
4638 WORKSPACE_CHANGED,
4639 MESSAGE_CHANGED,
4640 PROGRESS_CHANGED,
4641 HIDDEN_CHANGED,
4642- RUNNING_CHANGED,
4643
4644 LAST_SIGNAL
4645 };
4646 static guint32 _window_signals[LAST_SIGNAL] = { 0 };
4647
4648 /* Forwards */
4649-static WnckApplication * _get_application (TaskWindow *window);
4650-static gint _get_pid (TaskWindow *window);
4651-static const gchar * _get_name (TaskWindow *window);
4652-static GdkPixbuf * _get_icon (TaskWindow *window);
4653-static gboolean _is_on_workspace (TaskWindow *window,
4654- WnckWorkspace *space);
4655+static const gchar * _get_name (TaskItem *item);
4656+static GdkPixbuf * _get_icon (TaskItem *item);
4657+static gboolean _is_visible (TaskItem *item);
4658+static void _left_click (TaskItem *item, GdkEventButton *event);
4659+static void _right_click (TaskItem *item, GdkEventButton *event);
4660+static guint _match (TaskItem *item, TaskItem *item_to_match);
4661+
4662 static void task_window_set_window (TaskWindow *window,
4663 WnckWindow *wnckwin);
4664
4665@@ -104,51 +125,24 @@
4666 }
4667
4668 static void
4669-task_window_constructed (GObject *object)
4670-{
4671- /*TaskWindowPrivate *priv = TASK_WINDOW (object)->priv;*/
4672-}
4673-
4674-static void
4675 task_window_class_init (TaskWindowClass *klass)
4676 {
4677- GParamSpec *pspec;
4678- GObjectClass *obj_class = G_OBJECT_CLASS (klass);
4679-
4680- obj_class->constructed = task_window_constructed;
4681+ GParamSpec *pspec;
4682+ GObjectClass *obj_class = G_OBJECT_CLASS (klass);
4683+ TaskItemClass *item_class = TASK_ITEM_CLASS (klass);
4684+
4685 obj_class->set_property = task_window_set_property;
4686 obj_class->get_property = task_window_get_property;
4687-
4688- /* We implement the necessary funtions for a normal window */
4689- klass->get_application = _get_application;
4690- klass->get_pid = _get_pid;
4691- klass->get_name = _get_name;
4692- klass->get_icon = _get_icon;
4693- klass->is_on_workspace = _is_on_workspace;
4694- klass->activate = NULL;
4695- klass->popup_menu = NULL;
4696-
4697+
4698+ /* We implement the necessary funtions for an item */
4699+ item_class->get_name = _get_name;
4700+ item_class->get_icon = _get_icon;
4701+ item_class->is_visible = _is_visible;
4702+ item_class->left_click = _left_click;
4703+ item_class->right_click = _right_click;
4704+ item_class->match = _match;
4705+
4706 /* Install signals */
4707- _window_signals[NAME_CHANGED] =
4708- g_signal_new ("name-changed",
4709- G_OBJECT_CLASS_TYPE (obj_class),
4710- G_SIGNAL_RUN_LAST,
4711- G_STRUCT_OFFSET (TaskWindowClass, name_changed),
4712- NULL, NULL,
4713- g_cclosure_marshal_VOID__STRING,
4714- G_TYPE_NONE,
4715- 1, G_TYPE_STRING);
4716-
4717- _window_signals[ICON_CHANGED] =
4718- g_signal_new ("icon-changed",
4719- G_OBJECT_CLASS_TYPE (obj_class),
4720- G_SIGNAL_RUN_LAST,
4721- G_STRUCT_OFFSET (TaskWindowClass, icon_changed),
4722- NULL, NULL,
4723- g_cclosure_marshal_VOID__OBJECT,
4724- G_TYPE_NONE,
4725- 1, GDK_TYPE_PIXBUF);
4726-
4727 _window_signals[ACTIVE_CHANGED] =
4728 g_signal_new ("active-changed",
4729 G_OBJECT_CLASS_TYPE (obj_class),
4730@@ -209,17 +203,6 @@
4731 G_TYPE_NONE,
4732 1, G_TYPE_BOOLEAN);
4733
4734- _window_signals[RUNNING_CHANGED] =
4735- g_signal_new ("running-changed",
4736- G_OBJECT_CLASS_TYPE (obj_class),
4737- G_SIGNAL_RUN_LAST,
4738- G_STRUCT_OFFSET (TaskWindowClass, running_changed),
4739- NULL, NULL,
4740- g_cclosure_marshal_VOID__BOOLEAN,
4741- G_TYPE_NONE,
4742- 1, G_TYPE_BOOLEAN);
4743-
4744-
4745 /* Install properties */
4746 pspec = g_param_spec_object ("taskwindow",
4747 "Window",
4748@@ -237,6 +220,8 @@
4749
4750 priv = window->priv = TASK_WINDOW_GET_PRIVATE (window);
4751
4752+ priv->workspace = NULL;
4753+ priv->in_workspace = TRUE;
4754 priv->message = NULL;
4755 priv->progress = 0;
4756 priv->hidden = FALSE;
4757@@ -244,14 +229,14 @@
4758 priv->is_active = FALSE;
4759 }
4760
4761-TaskWindow *
4762+TaskItem *
4763 task_window_new (WnckWindow *window)
4764 {
4765- TaskWindow *win = NULL;
4766+ TaskItem *win = NULL;
4767
4768 win = g_object_new (TASK_TYPE_WINDOW,
4769- "taskwindow", window,
4770- NULL);
4771+ "taskwindow", window,
4772+ NULL);
4773
4774 return win;
4775 }
4776@@ -262,11 +247,8 @@
4777 */
4778 static void
4779 window_closed (TaskWindow *window, WnckWindow *old_window)
4780-{
4781- g_signal_emit (window, _window_signals[RUNNING_CHANGED], 0, FALSE);
4782-
4783- if (!TASK_IS_LAUNCHER (window))
4784- g_object_unref (G_OBJECT (window));
4785+{
4786+ gtk_widget_destroy (GTK_WIDGET (window));
4787 }
4788
4789 static void
4790@@ -278,8 +260,7 @@
4791 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));
4792 priv = window->priv;
4793
4794- g_signal_emit (window, _window_signals[NAME_CHANGED],
4795- 0, wnck_window_get_name (wnckwin));
4796+ task_item_emit_name_changed (TASK_ITEM (window), wnck_window_get_name (wnckwin));
4797 }
4798
4799 static void
4800@@ -292,7 +273,7 @@
4801 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));
4802
4803 pixbuf = _wnck_get_icon_at_size (wnckwin, s->panel_size, s->panel_size);
4804- task_window_update_icon (window, pixbuf);
4805+ task_item_emit_icon_changed (TASK_ITEM (window), pixbuf);
4806 g_object_unref (pixbuf);
4807 }
4808
4809@@ -303,7 +284,17 @@
4810
4811 g_return_if_fail (TASK_IS_WINDOW (window));
4812 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));
4813+
4814 priv = window->priv;
4815+ if (priv->workspace==NULL)
4816+ priv->in_workspace = TRUE;
4817+ else
4818+ priv->in_workspace = wnck_window_is_in_viewport (priv->window, priv->workspace);
4819+
4820+ if (priv->in_workspace && !priv->hidden)
4821+ task_item_emit_visible_changed (TASK_ITEM (window), TRUE);
4822+ else
4823+ task_item_emit_visible_changed (TASK_ITEM (window), FALSE);
4824
4825 g_signal_emit (window, _window_signals[WORKSPACE_CHANGED],
4826 0, wnck_window_get_workspace (wnckwin));
4827@@ -329,7 +320,11 @@
4828 if (priv->hidden != hidden)
4829 {
4830 priv->hidden = hidden;
4831- g_signal_emit (window, _window_signals[HIDDEN_CHANGED], 0, hidden);
4832+
4833+ if (priv->in_workspace && !priv->hidden)
4834+ task_item_emit_visible_changed (TASK_ITEM (window), TRUE);
4835+ else
4836+ task_item_emit_visible_changed (TASK_ITEM (window), FALSE);
4837 }
4838
4839 needs_attention = wnck_window_or_transient_needs_attention (wnckwin);
4840@@ -342,14 +337,19 @@
4841 }
4842 }
4843
4844+/**
4845+ * TODO: remove old signals and weak_ref...
4846+ */
4847 static void
4848 task_window_set_window (TaskWindow *window, WnckWindow *wnckwin)
4849 {
4850 TaskWindowPrivate *priv;
4851-
4852+ GdkPixbuf *pixbuf;
4853+ TaskSettings *s = task_settings_get_default ();
4854+
4855 g_return_if_fail (TASK_IS_WINDOW (window));
4856+
4857 priv = window->priv;
4858-
4859 priv->window = wnckwin;
4860
4861 g_object_weak_ref (G_OBJECT (priv->window),
4862@@ -364,14 +364,33 @@
4863 g_signal_connect (wnckwin, "state-changed",
4864 G_CALLBACK (on_window_state_changed), window);
4865
4866- g_signal_emit (window, _window_signals[RUNNING_CHANGED], 0, TRUE);
4867+ task_item_emit_name_changed (TASK_ITEM (window), wnck_window_get_name (wnckwin));
4868+ pixbuf = _wnck_get_icon_at_size (wnckwin, s->panel_size, s->panel_size);
4869+ task_item_emit_icon_changed (TASK_ITEM (window), pixbuf);
4870+ g_object_unref (pixbuf);
4871+ task_item_emit_visible_changed (TASK_ITEM (window), TRUE);
4872 }
4873
4874 /*
4875 * Public functions
4876 */
4877+
4878+/**
4879+ * Returns the name of the WnckWindow.
4880+ */
4881+const gchar *
4882+task_window_get_name (TaskWindow *window)
4883+{
4884+ g_return_val_if_fail (TASK_IS_WINDOW (window), "");
4885+
4886+ if (WNCK_IS_WINDOW (window->priv->window))
4887+ return wnck_window_get_name (window->priv->window);
4888+
4889+ return "";
4890+}
4891+
4892 WnckScreen *
4893-task_window_get_screen (TaskWindow *window)
4894+task_window_get_screen (TaskWindow *window)
4895 {
4896 g_return_val_if_fail (TASK_IS_WINDOW (window), wnck_screen_get_default ());
4897
4898@@ -382,7 +401,7 @@
4899 }
4900
4901 gulong
4902-task_window_get_xid (TaskWindow *window)
4903+task_window_get_xid (TaskWindow *window)
4904 {
4905 g_return_val_if_fail (TASK_IS_WINDOW (window), 0);
4906
4907@@ -393,29 +412,29 @@
4908 }
4909
4910 gint
4911-task_window_get_pid (TaskWindow *window)
4912+task_window_get_pid (TaskWindow *window)
4913 {
4914- TaskWindowClass *klass;
4915-
4916- g_return_val_if_fail (TASK_IS_WINDOW (window), -1);
4917-
4918- klass = TASK_WINDOW_GET_CLASS (window);
4919- g_return_val_if_fail (klass->get_pid, -1);
4920-
4921- return klass->get_pid (window);
4922+ g_return_val_if_fail (TASK_IS_WINDOW (window), -1);
4923+
4924+ gint pid = -1;
4925+ if (WNCK_IS_WINDOW (window->priv->window))
4926+ {
4927+ pid = wnck_window_get_pid (window->priv->window);
4928+ pid = pid ? pid : -1; /* if the pid is 0 return -1. Bad wnck! Bad! */
4929+ }
4930+
4931+ return pid;
4932 }
4933
4934 WnckApplication *
4935-task_window_get_application (TaskWindow *window)
4936+task_window_get_application (TaskWindow *window)
4937 {
4938- TaskWindowClass *klass;
4939-
4940- g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);
4941-
4942- klass = TASK_WINDOW_GET_CLASS (window);
4943- g_return_val_if_fail (klass->get_application, NULL);
4944-
4945- return klass->get_application (window);
4946+ g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);
4947+
4948+ if (WNCK_IS_WINDOW (window->priv->window))
4949+ return wnck_window_get_application (window->priv->window);
4950+
4951+ return NULL;
4952 }
4953
4954
4955@@ -424,7 +443,7 @@
4956 gchar **res_name,
4957 gchar **class_name)
4958 {
4959- g_return_val_if_fail (TASK_IS_WINDOW (window), -1);
4960+ g_return_val_if_fail (TASK_IS_WINDOW (window), FALSE);
4961
4962 *res_name = NULL;
4963 *class_name = NULL;
4964@@ -441,51 +460,6 @@
4965 return FALSE;
4966 }
4967
4968-const gchar *
4969-task_window_get_name (TaskWindow *window)
4970-{
4971- TaskWindowClass *klass;
4972-
4973- g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);
4974-
4975- klass = TASK_WINDOW_GET_CLASS (window);
4976- g_return_val_if_fail (klass->get_name, NULL);
4977-
4978- return klass->get_name (window);
4979-}
4980-
4981-void
4982-task_window_set_name (TaskWindow *window,
4983- const gchar *name)
4984-{
4985- g_return_if_fail (TASK_IS_WINDOW (window));
4986-
4987- g_signal_emit (window, _window_signals[NAME_CHANGED], 0, name);
4988-}
4989-
4990-GdkPixbuf *
4991-task_window_get_icon (TaskWindow *window)
4992-{
4993- TaskWindowClass *klass;
4994-
4995- g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);
4996-
4997- klass = TASK_WINDOW_GET_CLASS (window);
4998- g_return_val_if_fail (klass->get_icon, NULL);
4999-
5000- return klass->get_icon (window);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: