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
=== 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 @@
17 task-drag-indicator.h \17 task-drag-indicator.h \
18 task-icon.c \18 task-icon.c \
19 task-icon.h \19 task-icon.h \
20 task-item.c \
21 task-item.h \
22 task-window.c \
23 task-window.h \
20 task-launcher.c \24 task-launcher.c \
21 task-launcher.h \25 task-launcher.h \
22 task-manager.c \26 task-manager.c \
23 task-manager.h \27 task-manager.h \
28 task-manager-api-wrapper.c \
29 task-manager-api-wrapper.h \
24 task-settings.c \30 task-settings.c \
25 task-settings.h \31 task-settings.h \
26 task-window.c \
27 task-window.h \
28 $(builddir)/taskmanager-marshal.c \32 $(builddir)/taskmanager-marshal.c \
29 $(builddir)/taskmanager-marshal.h \33 $(builddir)/taskmanager-marshal.h \
30 xutils.c \34 xutils.c \
3135
=== 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 @@
13 * You should have received a copy of the GNU General Public License13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>16 * Authored by Hannes Verschore <hv1989@gmail.com>
17 *17 *
18 */18 */
1919
@@ -151,6 +151,12 @@
151 GtkWidget *drag_indicator = NULL;151 GtkWidget *drag_indicator = NULL;
152152
153 drag_indicator = g_object_new (TASK_TYPE_DRAG_INDICATOR, NULL);153 drag_indicator = g_object_new (TASK_TYPE_DRAG_INDICATOR, NULL);
154 gtk_widget_hide (drag_indicator);
155
156 //BUG: AwnApplet calls upon start gtk_widget_show_all. So even when gtk_widget_hide
157 // gets called, it will get shown. So I'm forcing it to not listen to
158 // 'gtk_widget_show_all' with this function. FIXME: improve AwnApplet
159 gtk_widget_set_no_show_all (drag_indicator, TRUE);
154160
155 return drag_indicator;161 return drag_indicator;
156}162}
157163
=== modified file 'applets/taskmanager/task-drag-indicator.h'
--- applets/taskmanager/task-drag-indicator.h 2009-05-27 15:57:06 +0000
+++ applets/taskmanager/task-drag-indicator.h 2009-06-20 14:17:54 +0000
@@ -13,7 +13,7 @@
13 * You should have received a copy of the GNU General Public License13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>16 * Authored by Hannes Verschore <hv1989@gmail.com>
17 *17 *
18 */18 */
1919
2020
=== modified file 'applets/taskmanager/task-icon.c'
--- applets/taskmanager/task-icon.c 2009-06-19 09:35:43 +0000
+++ applets/taskmanager/task-icon.c 2009-06-26 11:00:10 +0000
@@ -14,6 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
17 * Hannes Verschore <hv1989@gmail.com>
17 *18 *
18 */19 */
1920
@@ -33,7 +34,7 @@
33#include "task-launcher.h"34#include "task-launcher.h"
34#include "task-settings.h"35#include "task-settings.h"
3536
36G_DEFINE_TYPE (TaskIcon, task_icon, AWN_TYPE_ICON)37G_DEFINE_TYPE (TaskIcon, task_icon, AWN_TYPE_THEMED_ICON)
3738
38#define TASK_ICON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\39#define TASK_ICON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
39 TASK_TYPE_ICON, \40 TASK_TYPE_ICON, \
@@ -41,7 +42,27 @@
4142
42struct _TaskIconPrivate43struct _TaskIconPrivate
43{44{
44 GSList *windows;45 //List containing the TaskItems
46 GSList *items;
47
48 //The number of TaskItems that get shown
49 guint shown_items;
50
51 //The number of TaskWindows (subclass of TaskItem) that needs attention
52 guint needs_attention;
53
54 //The number of TaskWindows (subclass of TaskItem) that have the active state.
55 guint is_active;
56
57 //The main item being used for the icon (and if alone for the text)
58 TaskItem *main_item;
59
60 //Whetever this icon is visible or not
61 gboolean visible;
62
63 //An overlay for showing number of items
64 AwnOverlayText *overlay_text;
65
45 GdkPixbuf *icon;66 GdkPixbuf *icon;
46 GtkWidget *dialog;67 GtkWidget *dialog;
4768
@@ -64,13 +85,12 @@
64{85{
65 PROP_0,86 PROP_0,
6687
67 PROP_WINDOW,
68 PROP_DRAGGABLE88 PROP_DRAGGABLE
69};89};
7090
71enum91enum
72{92{
73 ENSURE_LAYOUT,93 VISIBLE_CHANGED,
7494
75 SOURCE_DRAG_FAIL,95 SOURCE_DRAG_FAIL,
76 SOURCE_DRAG_BEGIN,96 SOURCE_DRAG_BEGIN,
@@ -113,7 +133,7 @@
113static gboolean task_icon_dialog_unfocus (GtkWidget *widget,133static gboolean task_icon_dialog_unfocus (GtkWidget *widget,
114 GdkEventFocus *event,134 GdkEventFocus *event,
115 gpointer null);135 gpointer null);
116/* Dnd 'source' forwards */136/* Dnd forwards */
117static void task_icon_drag_data_get (GtkWidget *widget, 137static void task_icon_drag_data_get (GtkWidget *widget,
118 GdkDragContext *context, 138 GdkDragContext *context,
119 GtkSelectionData *selection_data,139 GtkSelectionData *selection_data,
@@ -148,6 +168,9 @@
148 guint time);168 guint time);
149169
150static gboolean _update_geometry(GtkWidget *widget);170static gboolean _update_geometry(GtkWidget *widget);
171static gboolean task_icon_refresh_geometry (TaskIcon *icon);
172static void task_icon_refresh_visible (TaskIcon *icon);
173static void task_icon_search_main_item (TaskIcon *icon);
151174
152/* GObject stuff */175/* GObject stuff */
153static void176static void
@@ -161,11 +184,6 @@
161184
162 switch (prop_id)185 switch (prop_id)
163 {186 {
164 case PROP_WINDOW:
165 g_value_set_object (value,
166 priv->windows ? priv->windows->data : NULL);
167 break;
168
169 case PROP_DRAGGABLE:187 case PROP_DRAGGABLE:
170 g_value_set_boolean (value, priv->draggable); 188 g_value_set_boolean (value, priv->draggable);
171 break;189 break;
@@ -185,10 +203,6 @@
185203
186 switch (prop_id)204 switch (prop_id)
187 {205 {
188 case PROP_WINDOW:
189 task_icon_append_window (icon, g_value_get_object (value));
190 break;
191
192 case PROP_DRAGGABLE:206 case PROP_DRAGGABLE:
193 task_icon_set_draggable (icon, g_value_get_boolean (value));207 task_icon_set_draggable (icon, g_value_get_boolean (value));
194 break;208 break;
@@ -198,10 +212,15 @@
198 }212 }
199}213}
200214
215/**
216 * Finalize the object and remove the list of windows,
217 * the list of launchers and the timer of update_geometry.
218 */
201static void219static void
202task_icon_dispose (GObject *object)220task_icon_dispose (GObject *object)
203{221{
204 TaskIconPrivate *priv = TASK_ICON_GET_PRIVATE (object);222 TaskIconPrivate *priv = TASK_ICON_GET_PRIVATE (object);
223
205 /*this needs to be done in dispose, not finalize, due to idiosyncracies of 224 /*this needs to be done in dispose, not finalize, due to idiosyncracies of
206 AwnDialog*/225 AwnDialog*/
207 if (priv->dialog)226 if (priv->dialog)
@@ -209,6 +228,7 @@
209 gtk_widget_destroy (priv->dialog);228 gtk_widget_destroy (priv->dialog);
210 priv->dialog = NULL;229 priv->dialog = NULL;
211 }230 }
231
212 G_OBJECT_CLASS (task_icon_parent_class)->dispose (object); 232 G_OBJECT_CLASS (task_icon_parent_class)->dispose (object);
213}233}
214234
@@ -218,13 +238,15 @@
218 TaskIconPrivate *priv = TASK_ICON_GET_PRIVATE (object);238 TaskIconPrivate *priv = TASK_ICON_GET_PRIVATE (object);
219239
220 /* FIXME Check to see if icon needs to be unreffed */240 /* FIXME Check to see if icon needs to be unreffed */
221 if (priv->windows)241 if (priv->items)
222 {242 {
223 g_slist_free (priv->windows);243 g_slist_free (priv->items);
224 priv->windows = NULL;244 priv->items = NULL;
225 }245 }
226 if(priv->update_geometry_id)246 if(priv->update_geometry_id)
247 {
227 g_source_remove(priv->update_geometry_id);248 g_source_remove(priv->update_geometry_id);
249 }
228250
229 G_OBJECT_CLASS (task_icon_parent_class)->finalize (object);251 G_OBJECT_CLASS (task_icon_parent_class)->finalize (object);
230}252}
@@ -234,13 +256,27 @@
234{256{
235 TaskIconPrivate *priv = TASK_ICON (object)->priv;257 TaskIconPrivate *priv = TASK_ICON (object)->priv;
236 GtkWidget *widget = GTK_WIDGET(object);258 GtkWidget *widget = GTK_WIDGET(object);
237 259
260 if ( G_OBJECT_CLASS (task_icon_parent_class)->constructed)
261 {
262 G_OBJECT_CLASS (task_icon_parent_class)->constructed (object);
263 }
264
265 //update geometry of icon every second.
238 priv->update_geometry_id = g_timeout_add_seconds (1, (GSourceFunc)_update_geometry, widget);266 priv->update_geometry_id = g_timeout_add_seconds (1, (GSourceFunc)_update_geometry, widget);
239}267}
240 268
269/**
270 * Checks if the position of the widget has changed.
271 * Upon change it asks the icon to refresh.
272 * returns: TRUE when succeeds
273 * FALSE when widget isn't an icon
274 */
241static gboolean 275static gboolean
242_update_geometry(GtkWidget *widget)276_update_geometry(GtkWidget *widget)
243{277{
278 return TRUE; //TODO solve
279
244 gint x,y;280 gint x,y;
245 TaskIconPrivate *priv;281 TaskIconPrivate *priv;
246 GdkWindow *win;282 GdkWindow *win;
@@ -251,6 +287,7 @@
251287
252 win = gtk_widget_get_window (widget);288 win = gtk_widget_get_window (widget);
253 gdk_window_get_origin (win, &x, &y);289 gdk_window_get_origin (win, &x, &y);
290
254 if(priv->old_x != x || priv->old_y != y)291 if(priv->old_x != x || priv->old_y != y)
255 {292 {
256 priv->old_x = x;293 priv->old_x = x;
@@ -260,7 +297,86 @@
260297
261 return TRUE;298 return TRUE;
262}299}
263 300
301/**
302 * Set the icon geometry of the windows in a task-icon.
303 * This equals to the minimize position of the window.
304 * TODO: not done (part2)
305 */
306static gboolean
307task_icon_refresh_geometry (TaskIcon *icon)
308{
309 TaskSettings *settings;
310 TaskIconPrivate *priv;
311 GtkWidget *widget;
312 GdkWindow *win;
313 GSList *w;
314 gint x, y, ww, width, height;
315 gint i = 0, len = 0;
316
317 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
318
319 priv = icon->priv;
320 widget = GTK_WIDGET (icon);
321
322 //get the position of the widget
323 win = gtk_widget_get_window (widget);
324 gdk_window_get_origin (win, &x, &y);
325
326 settings = task_settings_get_default ();
327
328 switch (settings->orient)
329 {
330 case AWN_ORIENTATION_RIGHT:
331 case AWN_ORIENTATION_LEFT:
332 ww = GTK_WIDGET (icon)->allocation.height;
333 break;
334 case AWN_ORIENTATION_TOP:
335 case AWN_ORIENTATION_BOTTOM:
336 ww = GTK_WIDGET (icon)->allocation.width;
337 break;
338 default:
339 g_error ("Orientation isn't right, left, top, bottom ??");
340 break;
341 }
342
343 /* FIXME: Do something clever here to allow the user to "scrub" the icon
344 * for the windows.
345 */
346 len = g_slist_length (priv->items);
347 ww = ww/len;
348 for (w = priv->items; w; w = w->next)
349 {
350 if (!TASK_IS_WINDOW (w->data)) continue;
351
352 TaskWindow *window = TASK_WINDOW (w->data);
353
354 switch (settings->orient)
355 {
356 case AWN_ORIENTATION_RIGHT:
357 width = settings->panel_size+settings->offset;
358 height = ww + (i*ww);
359 break;
360 case AWN_ORIENTATION_LEFT:
361 width = settings->panel_size+settings->offset;
362 height = ww + (i*ww);
363 break;
364 case AWN_ORIENTATION_TOP:
365 width = ww + (i*ww);
366 height = settings->panel_size+settings->offset;
367 break;
368 default:
369 width = ww + (i*ww);
370 height = settings->panel_size+settings->offset;
371 break;
372 }
373 task_window_set_icon_geometry (window, x, y,
374 width,
375 height);
376 i++;
377 }
378 return FALSE;
379}
264380
265static void381static void
266task_icon_class_init (TaskIconClass *klass)382task_icon_class_init (TaskIconClass *klass)
@@ -272,7 +388,7 @@
272 obj_class->constructed = task_icon_constructed;388 obj_class->constructed = task_icon_constructed;
273 obj_class->set_property = task_icon_set_property;389 obj_class->set_property = task_icon_set_property;
274 obj_class->get_property = task_icon_get_property;390 obj_class->get_property = task_icon_get_property;
275 obj_class->dispose = task_icon_dispose;391 obj_class->dispose = task_icon_dispose;
276 obj_class->finalize = task_icon_finalize;392 obj_class->finalize = task_icon_finalize;
277393
278 wid_class->configure_event = task_icon_configure_event;394 wid_class->configure_event = task_icon_configure_event;
@@ -285,15 +401,7 @@
285 wid_class->drag_leave = task_icon_dest_drag_leave;401 wid_class->drag_leave = task_icon_dest_drag_leave;
286 wid_class->drag_data_received = task_icon_dest_drag_data_received;402 wid_class->drag_data_received = task_icon_dest_drag_data_received;
287403
288
289 /* Install properties first */404 /* Install properties first */
290 pspec = g_param_spec_object ("taskwindow",
291 "TaskWindow",
292 "TaskWindow",
293 TASK_TYPE_WINDOW,
294 G_PARAM_READWRITE);
295 g_object_class_install_property (obj_class, PROP_WINDOW, pspec);
296
297 pspec = g_param_spec_boolean ("draggable",405 pspec = g_param_spec_boolean ("draggable",
298 "Draggable",406 "Draggable",
299 "TaskIcon is draggable?",407 "TaskIcon is draggable?",
@@ -302,11 +410,11 @@
302 g_object_class_install_property (obj_class, PROP_DRAGGABLE, pspec);410 g_object_class_install_property (obj_class, PROP_DRAGGABLE, pspec);
303411
304 /* Install signals */412 /* Install signals */
305 _icon_signals[ENSURE_LAYOUT] =413 _icon_signals[VISIBLE_CHANGED] =
306 g_signal_new ("ensure-layout",414 g_signal_new ("visible_changed",
307 G_OBJECT_CLASS_TYPE (obj_class),415 G_OBJECT_CLASS_TYPE (obj_class),
308 G_SIGNAL_RUN_LAST,416 G_SIGNAL_RUN_LAST,
309 G_STRUCT_OFFSET (TaskIconClass, ensure_layout),417 G_STRUCT_OFFSET (TaskIconClass, visible_changed),
310 NULL, NULL,418 NULL, NULL,
311 g_cclosure_marshal_VOID__VOID, 419 g_cclosure_marshal_VOID__VOID,
312 G_TYPE_NONE, 0);420 G_TYPE_NONE, 0);
@@ -368,11 +476,17 @@
368 g_signal_connect (G_OBJECT (priv->dialog),"focus-out-event",476 g_signal_connect (G_OBJECT (priv->dialog),"focus-out-event",
369 G_CALLBACK (task_icon_dialog_unfocus),NULL); 477 G_CALLBACK (task_icon_dialog_unfocus),NULL);
370 priv->icon = NULL;478 priv->icon = NULL;
371 priv->windows = NULL;479 priv->items = NULL;
372 priv->drag_tag = 0;480 priv->drag_tag = 0;
373 priv->drag_motion = FALSE;481 priv->drag_motion = FALSE;
374 priv->gets_dragged = FALSE;482 priv->gets_dragged = FALSE;
375 priv->update_geometry_id = 0;483 priv->update_geometry_id = 0;
484 priv->shown_items = 0;
485 priv->needs_attention = 0;
486 priv->is_active = 0;
487 priv->main_item = NULL;
488 priv->visible = FALSE;
489 priv->overlay_text = NULL;
376490
377 awn_icon_set_orientation (AWN_ICON (icon), AWN_ORIENTATION_BOTTOM);491 awn_icon_set_orientation (AWN_ICON (icon), AWN_ORIENTATION_BOTTOM);
378492
@@ -394,88 +508,46 @@
394 GDK_ACTION_MOVE);508 GDK_ACTION_MOVE);
395}509}
396510
511/**
512 * Creates a new TaskIcon, hides it and returns it.
513 * (Hiding is because there are no visible TaskItems yet in the TaskIcon)
514 */
397GtkWidget *515GtkWidget *
398task_icon_new_for_window (TaskWindow *window)516task_icon_new ()
399{517{
400 GtkWidget *icon = NULL;518 GtkWidget *icon = g_object_new (TASK_TYPE_ICON, NULL);
401519 gtk_widget_hide (icon);
402 g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);520
403521 //BUG: AwnApplet calls upon start gtk_widget_show_all. So even when gtk_widget_hide
404 icon = g_object_new (TASK_TYPE_ICON,522 // gets called, it will get shown. So I'm forcing it to not listen to
405 "taskwindow", window,523 // 'gtk_widget_show_all' with this function. FIXME: improve AwnApplet
406 NULL);524 gtk_widget_set_no_show_all (icon, TRUE);
525
407 return icon;526 return icon;
408}527}
409528
410/*529/**
411 * Public Functions530 * The name of the main TaskItem in this TaskIcon changed.
531 * So update the tooltip text.
412 */532 */
413gboolean 533static void
414task_icon_is_skip_taskbar (TaskIcon *icon)534on_main_item_name_changed (TaskItem *item,
415{535 const gchar *name,
416 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);536 TaskIcon *icon)
417
418 /*if (TASK_IS_LAUNCHER_WINDOW (icon->priv->windows->data))
419 return FALSE;*/
420
421 if (icon->priv->windows)
422 return task_window_is_hidden (icon->priv->windows->data);
423
424 return FALSE;
425}
426
427gboolean
428task_icon_is_in_viewport (TaskIcon *icon, WnckWorkspace *space)
429{
430 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
431
432 /*if (TASK_IS_LAUNCHER_WINDOW (icon->priv->windows->data))
433 return TRUE;*/
434
435 if (icon->priv->windows)
436 return task_window_is_on_workspace (icon->priv->windows->data, space);
437
438 return TRUE;
439}
440
441static void
442window_closed (TaskIcon *icon, TaskWindow *old_window)
443{
444 TaskIconPrivate *priv;
445
446 g_return_if_fail (TASK_IS_ICON (icon));
447 g_return_if_fail (TASK_IS_WINDOW (old_window));
448 priv = icon->priv;
449
450 if (! TASK_IS_LAUNCHER(old_window))
451 {
452 priv->windows = g_slist_remove (priv->windows, old_window);
453 }
454
455 if (g_slist_length (priv->windows) == 0)
456 {
457 gtk_widget_destroy (GTK_WIDGET (icon));
458 }
459 else
460 {
461 /* Load up with new icon etc */
462 }
463}
464
465static void
466on_window_name_changed (TaskWindow *window,
467 const gchar *name,
468 TaskIcon *icon)
469{537{
470 g_return_if_fail (TASK_IS_ICON (icon));538 g_return_if_fail (TASK_IS_ICON (icon));
471539
472 awn_icon_set_tooltip_text (AWN_ICON (icon), name);540 awn_icon_set_tooltip_text (AWN_ICON (icon), name);
473}541}
474542
543/**
544 * The icon of the main TaskItem in this TaskIcon changed.
545 * So update the icon of the TaskIcon (AwnIcon).
546 */
475static void547static void
476on_window_icon_changed (TaskWindow *window, 548on_main_item_icon_changed (TaskItem *item,
477 GdkPixbuf *pixbuf, 549 GdkPixbuf *pixbuf,
478 TaskIcon *icon)550 TaskIcon *icon)
479{551{
480 TaskIconPrivate *priv;552 TaskIconPrivate *priv;
481553
@@ -490,263 +562,460 @@
490 awn_icon_set_from_pixbuf (AWN_ICON (icon), priv->icon);562 awn_icon_set_from_pixbuf (AWN_ICON (icon), priv->icon);
491}563}
492564
565/**
566 * The visibility of the main TaskItem in this TaskIcon changed.
567 * Because normally the main TaskItem should always be visible,
568 * it searches after a new main TaskItem.
569 */
570static void
571on_main_item_visible_changed (TaskItem *item,
572 gboolean visible,
573 TaskIcon *icon)
574{
575 g_return_if_fail (TASK_IS_ICON (icon));
576
577 /* the main TaskItem should have been visible, so if
578 the main TaskItem becomes visible only now,
579 it indicates a bug.
580 FIXME: this is possible atm in TaskWindow */
581 if (visible) return;
582
583 task_icon_search_main_item (icon);
584}
585
586/**
587 * Notify that the icon that a window is closed. The window gets
588 * removed from the list and when this icon doesn't has any
589 * launchers and no windows it will get destroyed.
590 */
591static void
592_destroyed_task_item (TaskIcon *icon, TaskItem *old_item)
593{
594 TaskIconPrivate *priv;
595
596 g_return_if_fail (TASK_IS_ICON (icon));
597 g_return_if_fail (TASK_IS_ITEM (old_item));
598
599 priv = icon->priv;
600 priv->items = g_slist_remove (priv->items, old_item);
601
602 if (old_item == priv->main_item)
603 {
604 task_icon_search_main_item (icon);
605 }
606
607 task_icon_refresh_visible (icon);
608
609 if (g_slist_length (priv->items) == 0)
610 {
611 gtk_widget_destroy (GTK_WIDGET (icon));
612 }
613 else
614 {
615 /* TODO: Load up with new icon etc */
616 }
617}
618
619/**
620 * Searches for a new main item.
621 * A main item is used for displaying its icon and also the text (if there is only one item)
622 * Attention: this function doesn't check if it is needed to switch to a new main item.
623 */
624static void
625task_icon_search_main_item (TaskIcon *icon)
626{
627 TaskIconPrivate *priv;
628 GSList *i;
629 TaskItem *main_item = NULL;
630
631 g_return_if_fail (TASK_IS_ICON (icon));
632
633 priv = icon->priv;
634
635 for (i = priv->items; i; i = i->next)
636 {
637 TaskItem *item = i->data;
638
639 if (!task_item_is_visible (item)) continue;
640
641 main_item = item;
642 break;
643 }
644
645 //remove signals of old main_item
646 if (priv->main_item)
647 {
648 g_signal_handlers_disconnect_by_func(priv->main_item,
649 G_CALLBACK (on_main_item_name_changed), icon);
650 g_signal_handlers_disconnect_by_func(priv->main_item,
651 G_CALLBACK (on_main_item_icon_changed), icon);
652 g_signal_handlers_disconnect_by_func(priv->main_item,
653 G_CALLBACK (on_main_item_visible_changed), icon);
654 priv->main_item = NULL;
655 }
656
657 if (main_item)
658 {
659 priv->main_item = main_item;
660 priv->icon = task_item_get_icon (priv->main_item);
661 awn_icon_set_from_pixbuf (AWN_ICON (icon), priv->icon);
662 awn_icon_set_tooltip_text (AWN_ICON (icon),
663 task_item_get_name (priv->main_item));
664 g_signal_connect (priv->main_item, "name-changed",
665 G_CALLBACK (on_main_item_name_changed), icon);
666 g_signal_connect (priv->main_item, "icon-changed",
667 G_CALLBACK (on_main_item_icon_changed), icon);
668 g_signal_connect (priv->main_item, "visible-changed",
669 G_CALLBACK (on_main_item_visible_changed), icon);
670 }
671}
672
673/**
674 *
675 */
676static void
677task_icon_refresh_visible (TaskIcon *icon)
678{
679 TaskIconPrivate *priv;
680 GSList *w;
681 guint count = 0;
682 guint count_windows = 0;
683
684 g_return_if_fail (TASK_IS_ICON (icon));
685
686 priv = icon->priv;
687
688 for (w = priv->items; w; w = w->next)
689 {
690 TaskItem *item = w->data;
691
692 if (!task_item_is_visible (item)) continue;
693 count++;
694
695 if (!TASK_IS_WINDOW (item)) continue;
696 count_windows++;
697 }
698
699 awn_icon_set_indicator_count (AWN_ICON (icon), (count_windows>0) ? 1 : 0);
700
701 if (count != priv->shown_items)
702 {
703 g_debug("shown items changed: %i", count);
704
705 if (count > 1)
706 {
707 if (!priv->overlay_text)
708 {
709 priv->overlay_text = awn_overlay_text_new ();
710 awn_overlayable_add_overlay (AWN_OVERLAYABLE (icon),
711 AWN_OVERLAY (priv->overlay_text));
712 g_object_set (G_OBJECT (priv->overlay_text),
713 "gravity", GDK_GRAVITY_SOUTH_EAST,
714 "font-sizing", AWN_FONT_SIZE_LARGE,
715 "text_color_astr", "#FFFFFFFF",
716 "apply-effects", TRUE,
717 NULL);
718 }
719 gchar* count_str = g_strdup_printf ("%i",count);
720 g_object_set (G_OBJECT (priv->overlay_text),
721 "text", count_str,
722 NULL);
723 g_free (count_str);
724 }
725 else
726 {
727 if (priv->overlay_text)
728 {
729 awn_overlayable_remove_overlay (AWN_OVERLAYABLE (icon),
730 AWN_OVERLAY (priv->overlay_text));
731 g_object_unref (priv->overlay_text);
732 priv->overlay_text = NULL;
733 }
734 }
735
736 if (count == 0)
737 {
738 priv->visible = FALSE;
739 }
740 else
741 {
742 if (!priv->main_item)
743 task_icon_search_main_item (icon);
744
745 priv->visible = TRUE;
746 }
747
748 g_signal_emit (icon, _icon_signals[VISIBLE_CHANGED], 0);
749 }
750
751 priv->shown_items = count;
752}
753
754/**
755 * The 'active' state of a TaskWindow changed.
756 * If this is the only TaskWindow that's active,
757 * the TaskIcon will get an active state.
758 * If it the last TaskWindow that isn't active anymore
759 * the TaskIcon will get an inactive state too.
760 * STATE: adjusted
761 * PROBLEM: It shouldn't get called when the state didn't change.
762 Else the count of windows that need have the active state will be off.
763 */
493static void764static void
494on_window_active_changed (TaskWindow *window, 765on_window_active_changed (TaskWindow *window,
495 gboolean is_active, 766 gboolean is_active,
496 TaskIcon *icon)767 TaskIcon *icon)
497{768{
769 TaskIconPrivate *priv;
770 GSList *w;
771 guint count = 0;
772
498 g_return_if_fail (TASK_IS_ICON (icon));773 g_return_if_fail (TASK_IS_ICON (icon));
499774
500 awn_icon_set_is_active (AWN_ICON (icon), is_active);775 priv = icon->priv;
776
777 for (w = priv->items; w; w = w->next)
778 {
779 TaskItem *item = w->data;
780
781 if (!TASK_IS_WINDOW (item)) continue;
782 if (!task_item_is_visible (item)) continue;
783 if (!task_window_is_active (TASK_WINDOW (item))) continue;
784
785 count++;
786 }
787
788 if (priv->is_active == 0 && count == 1)
789 {
790 awn_icon_set_is_active (AWN_ICON (icon), TRUE);
791 }
792 else if (priv->is_active == 1 && count == 0)
793 {
794 awn_icon_set_is_active (AWN_ICON (icon), FALSE);
795 }
796
797 priv->is_active = count;
501}798}
502799
800/**
801 * The 'needs attention' state of a window changed.
802 * If a window needs attention and there isn't one yet, it will
803 * start the animation. When every window don't need attention anymore
804 * it will stop the animation.
805 * STATE: adjusted
806 * TODO: h4writer - check if it is possible to interupt animation mid-air,
807 * and let it start again, if there is a 2nd/3rd window that needs attention.
808 * BUG: when icon becomes visible again it needs to be checked if it needs attention again.
809 */
503static void810static void
504on_window_needs_attention_changed (TaskWindow *window,811on_window_needs_attention_changed (TaskWindow *window,
505 gboolean needs_attention,812 gboolean needs_attention,
506 TaskIcon *icon)813 TaskIcon *icon)
507{814{
815 TaskIconPrivate *priv;
816 GSList *w;
817 guint count = 0;
818
508 g_return_if_fail (TASK_IS_ICON (icon));819 g_return_if_fail (TASK_IS_ICON (icon));
509820
510 if (needs_attention)821 priv = icon->priv;
822
823 for (w = priv->items; w; w = w->next)
824 {
825 TaskItem *item = w->data;
826
827 if (!TASK_IS_WINDOW (item)) continue;
828 if (!task_item_is_visible (item)) continue;
829 if (!task_window_needs_attention (TASK_WINDOW (item))) continue;
830
831 count++;
832 }
833
834 if (priv->needs_attention == 0 && count == 1)
835 {
511 awn_icon_set_effect (AWN_ICON (icon),AWN_EFFECT_ATTENTION);836 awn_icon_set_effect (AWN_ICON (icon),AWN_EFFECT_ATTENTION);
512 else837 }
513 awn_effects_stop (awn_overlayable_get_effects (AWN_OVERLAYABLE (icon)),838 else if (priv->needs_attention == 1 && count == 0)
839 {
840 awn_effects_stop (awn_overlayable_get_effects (AWN_OVERLAYABLE (icon)),
514 AWN_EFFECT_ATTENTION);841 AWN_EFFECT_ATTENTION);
515}842 }
516
517static void
518on_window_workspace_changed (TaskWindow *window,
519 WnckWorkspace *space,
520 TaskIcon *icon)
521{
522 g_return_if_fail (TASK_IS_ICON (icon));
523 843
524 g_signal_emit (icon, _icon_signals[ENSURE_LAYOUT], 0);844 priv->needs_attention = count;
525}845}
526846
527static void847/**
528on_window_message_changed (TaskWindow *window, 848 * When the progress of a TaskWindow has changed,
529 const gchar *message,849 * it will recalculate the process of all the
530 TaskIcon *icon)850 * TaskWindows this TaskIcon contains.
531{851 * STATE: adjusted
532 g_return_if_fail (TASK_IS_ICON (icon));852 */
533853static void
534 awn_icon_set_message (AWN_ICON (icon), message);854on_window_progress_changed (TaskWindow *window,
535}855 gfloat adjusted_progress,
536
537static void
538on_window_progress_changed (TaskWindow *window,
539 gfloat progress,
540 TaskIcon *icon)856 TaskIcon *icon)
541{857{
542 g_return_if_fail (TASK_IS_ICON (icon));858 TaskIconPrivate *priv;
543859 GSList *w;
544 awn_icon_set_progress (AWN_ICON (icon), progress);860 gfloat progress = 0;
545}861 guint len = 0;
546862
547static void863 g_return_if_fail (TASK_IS_ICON (icon));
548on_window_hidden_changed (TaskWindow *window,864
549 gboolean is_hidden,865 priv = icon->priv;
550 TaskIcon *icon)866
551{867 for (w = priv->items; w; w = w->next)
552 g_return_if_fail (TASK_IS_ICON (icon));868 {
553869 TaskItem *item = w->data;
554 g_signal_emit (icon, _icon_signals[ENSURE_LAYOUT], 0);870
555}871 if (!TASK_IS_WINDOW (item)) continue;
556872 if (!task_item_is_visible (item)) continue;
557static void873
558on_window_running_changed (TaskWindow *window, 874 if (progress != -1)
559 gboolean is_running,875 {
560 TaskIcon *icon)876 progress += task_window_get_progress (TASK_WINDOW (item));
561{877 len++;
562 g_return_if_fail (TASK_IS_ICON (icon));878 }
563 awn_icon_set_indicator_count (AWN_ICON (icon), is_running ? 1 : 0);879 }
564}880
565881 awn_icon_set_progress (AWN_ICON (icon), progress/len);
566void882}
567task_icon_remove_window (TaskIcon *icon,883
568 WnckWindow *window)884/**
569{885 * When a TaskWindow becomes visible or invisible,
570 GSList * w;886 * update the number of shown windows.
571 TaskIconPrivate *priv;887 * If because of that the icon has no shown TaskWindows
572888 * anymore it will get hidden. If there was no shown
573 g_return_if_fail (TASK_IS_ICON (icon));889 * TaskWindow and now the first one gets visible,
574 g_return_if_fail (WNCK_IS_WINDOW (window));890 * then show TaskIcon.
575 priv = icon->priv;891 * STATE: adjusted
576 for (w = priv->windows;w;w=w->next)892 */
577 {893static void
578 TaskWindow * task_win = w->data;894on_item_visible_changed (TaskItem *item,
579 if (! TASK_IS_WINDOW(task_win) )895 gfloat visible,
580 {896 TaskIcon *icon)
581 continue;897{
582 }898 g_return_if_fail (TASK_IS_ICON (icon));
583 if (task_win->priv->window == window)899 g_return_if_fail (TASK_IS_ITEM (item));
584 {900
585 g_assert (TASK_IS_WINDOW(task_win));901 task_icon_refresh_visible (icon);
586 if (! TASK_IS_LAUNCHER(task_win) )902}
587 {903
588 priv->windows = g_slist_remove (priv->windows, task_win);904/**
589 }905 * Public Functions
590 }906 */
591 }907
592}908/**
593909 * Returns whetever this icon should be visible.
594/*910 * (That means it should contain atleast 1 visible item)
595 FIXME 2nd arg isn't the WnckWindow911 */
596 */912gboolean
597static void913task_icon_is_visible (TaskIcon *icon)
598_task_icon_launcher_change (TaskLauncher * launcher,914{
599 WnckWindow * wnck_win,915 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
600 TaskIcon * icon)916
601{917 return icon->priv->visible;
602 GtkWidget * grouped_icon = NULL; 918}
603 if (wnck_win)919
604 {920/**
605 TaskWindow * taskwin = task_window_new (TASK_WINDOW(launcher)->priv->window); 921 * Returns whetever this icon contains atleast one (visible?) launcher.
606 grouped_icon = task_icon_new_for_window (taskwin);922 * TODO: adapt TaskIcon so it has a guint with the numbers of TaskLaunchers/TaskWindows
607 gtk_widget_show (grouped_icon); 923 */
608 gtk_container_add (GTK_CONTAINER(icon->priv->dialog),grouped_icon);924gboolean
609 }925task_icon_contains_launcher (TaskIcon *icon)
610 926{
611}927 TaskIconPrivate *priv;
612928 GSList *w;
613void929
614task_icon_append_window (TaskIcon *icon,930 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
615 TaskWindow *window)931
616{932 priv = icon->priv;
617 TaskIconPrivate *priv;933
618 gboolean first_window = FALSE;934 for (w = priv->items; w; w = w->next)
619 static gboolean recursing = FALSE;935 {
620 936 TaskItem *item = w->data;
621 g_assert (window);937
938 if (!task_item_is_visible (item)) continue;
939
940 if (TASK_IS_LAUNCHER (item))
941 return TRUE;
942 }
943 return FALSE;
944}
945
946guint
947task_icon_match_item (TaskIcon *icon,
948 TaskItem *item_to_match)
949{
950 TaskIconPrivate *priv;
951 GSList *w;
952 guint max_score = 0;
953
954 g_return_val_if_fail (TASK_IS_ICON (icon), 0);
955 g_return_val_if_fail (TASK_IS_ITEM (item_to_match), 0);
956
957 priv = icon->priv;
958
959 for (w = priv->items; w; w = w->next)
960 {
961 TaskItem *item = w->data;
962 guint score;
963
964 if (!task_item_is_visible (item)) continue;
965
966 score = task_item_match (item, item_to_match);
967 if (score > max_score)
968 max_score = score;
969 }
970
971 return max_score;
972}
973
974/**
975 * Adds a TaskWindow to this task-icon
976 */
977void
978task_icon_append_item (TaskIcon *icon,
979 TaskItem *item)
980{
981 TaskIconPrivate *priv;
982
983 g_assert (item);
622 g_assert (icon);984 g_assert (icon);
623 g_return_if_fail (TASK_IS_ICON (icon));985 g_return_if_fail (TASK_IS_ICON (icon));
624 g_return_if_fail (TASK_IS_WINDOW (window));986 g_return_if_fail (TASK_IS_ITEM (item));
987
625 priv = icon->priv;988 priv = icon->priv;
626989
627 /* Is this the first, main, window of this icon? */990 priv->items = g_slist_append (priv->items, item);
628 if (priv->windows == NULL)991 gtk_widget_show_all (GTK_WIDGET (item));
629 first_window = TRUE;992 gtk_container_add (GTK_CONTAINER (priv->dialog), GTK_WIDGET (item));
630993
631 priv->windows = g_slist_append (priv->windows, window);994 g_object_weak_ref (G_OBJECT (item), (GWeakNotify)_destroyed_task_item, icon);
632 g_object_weak_ref (G_OBJECT (window), (GWeakNotify)window_closed, icon);995
633996 task_icon_refresh_visible (icon);
634 /* If it's the first window, let's set-up our icon accordingly */997
635 if (first_window)998 /* Connect item signals */
999 g_signal_connect (item, "visible-changed",
1000 G_CALLBACK (on_item_visible_changed), icon);
1001
1002 /* Connect window signals */
1003 if (TASK_IS_WINDOW (item))
636 {1004 {
637 priv->icon = task_window_get_icon (window);1005 TaskWindow *window = TASK_WINDOW (item);
638 awn_icon_set_from_pixbuf (AWN_ICON (icon), priv->icon);
639
640 awn_icon_set_tooltip_text (AWN_ICON (icon), task_window_get_name (window));
641 on_window_needs_attention_changed (window,
642 task_window_needs_attention (window),
643 icon);
644
645 awn_icon_set_indicator_count (AWN_ICON (icon),
646 task_window_get_is_running (window) ? 1 : 0);
647
648 g_signal_connect (window, "name-changed",
649 G_CALLBACK (on_window_name_changed), icon);
650 g_signal_connect (window, "icon-changed",
651 G_CALLBACK (on_window_icon_changed), icon);
652 g_signal_connect (window, "active-changed",1006 g_signal_connect (window, "active-changed",
653 G_CALLBACK (on_window_active_changed), icon);1007 G_CALLBACK (on_window_active_changed), icon);
654 g_signal_connect (window, "needs-attention",1008 g_signal_connect (window, "needs-attention",
655 G_CALLBACK (on_window_needs_attention_changed), icon);1009 G_CALLBACK (on_window_needs_attention_changed), icon);
656 g_signal_connect (window, "workspace-changed",
657 G_CALLBACK (on_window_workspace_changed), icon);
658 g_signal_connect (window, "message-changed",
659 G_CALLBACK (on_window_message_changed), icon);
660 g_signal_connect (window, "progress-changed",1010 g_signal_connect (window, "progress-changed",
661 G_CALLBACK (on_window_progress_changed), icon);1011 G_CALLBACK (on_window_progress_changed), icon);
662 g_signal_connect (window, "hidden-changed",1012 }
663 G_CALLBACK (on_window_hidden_changed), icon);1013}
664 g_signal_connect (window, "running-changed",1014
665 G_CALLBACK (on_window_running_changed), icon);1015/**
666 }1016 *
6671017 * TODO: h4writer - adjust 2nd round
668 if (!recursing)1018 */
669 {
670 recursing = TRUE;
671 GtkWidget * grouped_icon = NULL;
672 if (!TASK_IS_LAUNCHER(window))
673 {
674 g_assert (window->priv->window);
675 grouped_icon = task_icon_new_for_window (window);
676 }
677 else if (TASK_IS_LAUNCHER(window) )
678 {
679 TaskWindowPrivate *win_priv = window->priv;
680 g_signal_connect (G_OBJECT(window),"notify::taskwindow",
681 G_CALLBACK(_task_icon_launcher_change),icon);
682 if (win_priv->window)
683 {
684 TaskWindow * taskwin = task_window_new (win_priv->window);
685 grouped_icon = task_icon_new_for_window (taskwin);
686 }
687 }
688 if (grouped_icon)
689 {
690 gtk_container_add (GTK_CONTAINER(priv->dialog),grouped_icon);
691// g_object_weak_ref (G_OBJECT (window), (GWeakNotify)window_closed, grouped_icon);
692 gtk_widget_show (grouped_icon);
693 }
694 }
695 recursing = FALSE;
696}
697
698gboolean
699task_icon_is_launcher (TaskIcon *icon)
700{
701 TaskIconPrivate *priv;
702
703 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
704 priv = icon->priv;
705
706 if (priv->windows)
707 {
708 /* For now do it this way ?! */
709 if (TASK_IS_LAUNCHER (priv->windows->data))
710 return TRUE;
711 }
712 return FALSE;
713}
714
715TaskLauncher*
716task_icon_get_launcher (TaskIcon *icon)
717{
718 TaskIconPrivate *priv;
719
720 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
721 priv = icon->priv;
722
723 if (priv->windows)
724 {
725 /* For now do it this way ?! */
726 if (TASK_IS_LAUNCHER (priv->windows->data))
727 return TASK_LAUNCHER(priv->windows->data);
728 }
729 return NULL;
730}
731
732TaskWindow*
733task_icon_get_window (TaskIcon *icon)
734{
735 TaskIconPrivate *priv;
736
737 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
738 priv = icon->priv;
739
740 if (priv->windows)
741 {
742 /* For now do it this way ?! */
743// if (TASK_IS_WINDOW (priv->windows->data))
744 return TASK_WINDOW(priv->windows->data);
745 }
746 return NULL;
747}
748
749
750void1019void
751task_icon_refresh_icon (TaskIcon *icon)1020task_icon_refresh_icon (TaskIcon *icon)
752{1021{
@@ -755,87 +1024,9 @@
755 g_return_if_fail (TASK_IS_ICON (icon));1024 g_return_if_fail (TASK_IS_ICON (icon));
756 priv = icon->priv;1025 priv = icon->priv;
7571026
758 if (priv->windows && priv->windows->data)1027 if (priv->items && priv->items->data)
759 awn_icon_set_from_pixbuf (AWN_ICON (icon), 1028 awn_icon_set_from_pixbuf (AWN_ICON (icon),
760 task_window_get_icon (priv->windows->data));1029 task_item_get_icon (priv->items->data));
761}
762
763gboolean
764task_icon_refresh_geometry (TaskIcon *icon)
765{
766 TaskSettings *settings;
767 TaskIconPrivate *priv;
768 GtkWidget *widget;
769 GdkWindow *win;
770 GSList *w;
771 gint x, y, ww, width, height;
772 gint i = 0, len = 0;
773
774 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
775 priv = icon->priv;
776
777 widget = GTK_WIDGET (icon);
778
779 //get the position of the widget
780 win = gtk_widget_get_window (widget);
781 gdk_window_get_origin (win, &x, &y);
782
783 settings = task_settings_get_default ();
784
785 switch (settings->orient)
786 {
787 case AWN_ORIENTATION_RIGHT:
788 //x += settings->panel_size;
789 ww = GTK_WIDGET (icon)->allocation.height;
790 break;
791 case AWN_ORIENTATION_LEFT:
792 //x += settings->offset;
793 ww = GTK_WIDGET (icon)->allocation.height;
794 break;
795 case AWN_ORIENTATION_TOP:
796 //y += settings->offset;
797 ww = GTK_WIDGET (icon)->allocation.width;
798 break;
799 default:
800 //y += settings->panel_size;
801 ww = GTK_WIDGET (icon)->allocation.width;
802 break;
803 }
804
805 /* FIXME: Do something clever here to allow the user to "scrub" the icon
806 * for the windows.
807 */
808 len = g_slist_length (priv->windows);
809 ww = ww/len;
810 for (w = priv->windows; w; w = w->next)
811 {
812 TaskWindow *window = w->data;
813 switch (settings->orient)
814 {
815 case AWN_ORIENTATION_RIGHT:
816 width = settings->panel_size+settings->offset;
817 height = ww + (i*ww);
818 break;
819 case AWN_ORIENTATION_LEFT:
820 width = settings->panel_size+settings->offset;
821 height = ww + (i*ww);
822 break;
823 case AWN_ORIENTATION_TOP:
824 width = ww + (i*ww);
825 height = settings->panel_size+settings->offset;
826 break;
827 default:
828 width = ww + (i*ww);
829 height = settings->panel_size+settings->offset;
830 break;
831 }
832 task_window_set_icon_geometry (window, x, y,
833 width,
834 height);
835 i++;
836 }
837
838 return FALSE;
839}1030}
8401031
841/*1032/*
@@ -861,78 +1052,146 @@
861 return TRUE;1052 return TRUE;
862}1053}
8631054
1055/**
1056 * Whenever there is a release event on the TaskIcon it will do the proper actions.
1057 * left click: - start launcher = has no (visible) windows
1058 * - activate window = when there is only one (visible) window
1059 * - show dialog = when there are multiple (visible) windows
1060 * middle click: - start launcher
1061 * Returns: TRUE to stop other handlers from being invoked for the event.
1062 * FALSE to propagate the event further.
1063 * TODO: h4writer - adjust
1064 */
864static gboolean1065static gboolean
865task_icon_button_release_event (GtkWidget *widget,1066task_icon_button_release_event (GtkWidget *widget,
866 GdkEventButton *event)1067 GdkEventButton *event)
867{1068{
868 TaskIconPrivate *priv;1069 TaskIconPrivate *priv;
869 gint len;1070 TaskIcon *icon;
8701071
871 g_return_val_if_fail (TASK_IS_ICON (widget), FALSE);1072 g_return_val_if_fail (TASK_IS_ICON (widget), FALSE);
872 priv = TASK_ICON (widget)->priv;1073
8731074 icon = TASK_ICON (widget);
874 len = g_slist_length (priv->windows);1075 priv = icon->priv;
8751076
876 if (event->button == 1)1077 switch (event->button)
877 {1078 {
878 if(priv->gets_dragged)1079 case 1: // left click: (start launcher || activate window || show dialog)
879 {1080
880 return FALSE;1081 if(priv->gets_dragged) return FALSE;
881 }1082
882 if (len == 1)1083 if (priv->shown_items == 0)
883 {1084 {
884 task_window_activate (priv->windows->data, event->time);1085 g_critical ("TaskIcon: The icons shouldn't contain a visible (and clickable) icon");
885 return TRUE;1086 return FALSE;
886 }1087 }
887 else if (len > 1)1088 else if (priv->shown_items == 1)
888 {1089 {
889 if (GTK_WIDGET_VISIBLE(priv->dialog) )1090 GSList *w;
890 {1091 /* Find the window/launcher that is shown */
891 gtk_widget_hide (priv->dialog);1092 for (w = priv->items; w; w = w->next)
1093 {
1094 TaskItem *item = w->data;
1095
1096 if (!task_item_is_visible (item)) continue;
1097
1098 task_item_left_click (item, event);
1099
1100 break;
1101 }
1102 return TRUE;
892 }1103 }
893 else1104 else
894 {1105 {
895 gtk_widget_show_all (priv->dialog); 1106 GSList *w;
1107 for (w = priv->items; w; w = w->next)
1108 {
1109 TaskItem *item = w->data;
1110
1111 if (!task_item_is_visible (item)) continue;
1112
1113 g_debug ("clicked on: %s", task_item_get_name (item));
1114 }
1115
1116 //TODO: move to hover?
1117 if (GTK_WIDGET_VISIBLE (priv->dialog) )
1118 {
1119 gtk_widget_hide (priv->dialog);
1120 }
1121 else
1122 {
1123 gtk_widget_show (priv->dialog);
1124 }
896 }1125 }
897 }1126 break;
898 }1127
899 else if (event->button == 2)1128 case 2: // middle click: start launcher
900 {1129
901 if (len >= 1 && TASK_IS_LAUNCHER (priv->windows->data))1130 g_warning ("TaskIcon: FIXME: No support for starting launcher on middle click");
902 {1131
903 task_launcher_middle_click (priv->windows->data, event);1132 //TODO: start launcher
904 return TRUE;1133 /*if (len >= 1 && TASK_IS_LAUNCHER (priv->windows->data))
905 }1134 {
906 }1135 task_launcher_middle_click (priv->windows->data, event);
1136 return TRUE;
1137 }*/
1138
1139 break;
1140
1141 default:
1142 break;
1143 }
1144
907 return FALSE;1145 return FALSE;
908}1146}
9091147
1148/**
1149 * Whenever there is a press event on the TaskIcon it will do the proper actions.
1150 * right click: - show the context menu if there is only one (visible) window
1151 * Returns: TRUE to stop other handlers from being invoked for the event.
1152 * FALSE to propagate the event further.
1153 */
910static gboolean 1154static gboolean
911task_icon_button_press_event (GtkWidget *widget,1155task_icon_button_press_event (GtkWidget *widget,
912 GdkEventButton *event)1156 GdkEventButton *event)
913{1157{
914 TaskIconPrivate *priv;1158 TaskIconPrivate *priv;
915 guint len;1159 TaskIcon *icon;
9161160
917 g_return_val_if_fail (TASK_IS_ICON (widget), FALSE);1161 g_return_val_if_fail (TASK_IS_ICON (widget), FALSE);
918 priv = TASK_ICON (widget)->priv;1162
9191163 icon = TASK_ICON (widget);
920 if (event->button != 3)1164 priv = icon->priv;
1165
1166 if (event->button != 3) return FALSE;
1167
1168 if (priv->shown_items == 0)
1169 {
1170 g_critical ("TaskIcon: The icons shouldn't contain a visible (and clickable) icon");
921 return FALSE;1171 return FALSE;
9221172 }
923 len = g_slist_length (priv->windows);1173 else if (priv->shown_items == 1)
924
925 if (len == 1)
926 {1174 {
927 /* We can just ask the window to popup as normal */1175 GSList *w;
928 task_window_popup_context_menu (priv->windows->data, event);1176
1177 /* Find the window/launcher that is shown */
1178 for (w = priv->items; w; w = w->next)
1179 {
1180 TaskItem *item = w->data;
1181
1182 if (!task_item_is_visible (item)) continue;
1183
1184 task_item_right_click (item, event);
1185
1186 break;
1187 }
929 return TRUE;1188 return TRUE;
930 }1189 }
931 else1190 else
932 {1191 {
933 g_warning ("TaskIcon: FIXME: No support for multiple windows right-click");1192 g_warning ("TaskIcon: FIXME: No support for multiple windows right-click");
1193 return FALSE;
934 }1194 }
935 return FALSE;
936}1195}
9371196
938static gboolean 1197static gboolean
@@ -976,6 +1235,9 @@
976 //g_debug("draggable:%d", draggable);1235 //g_debug("draggable:%d", draggable);
977}1236}
9781237
1238/**
1239 * TODO: h4writer - second stage
1240 */
979static gboolean1241static gboolean
980drag_timeout (TaskIcon *icon)1242drag_timeout (TaskIcon *icon)
981{1243{
@@ -984,12 +1246,12 @@
984 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);1246 g_return_val_if_fail (TASK_IS_ICON (icon), FALSE);
985 priv = icon->priv;1247 priv = icon->priv;
9861248
987 if (priv->drag_motion == FALSE)1249/* if (priv->drag_motion == FALSE)
988 return FALSE;1250 return FALSE;
989 else if (priv->windows->data)1251 else if (priv->windows->data)
990 if (!task_window_is_active(priv->windows->data))1252 if (!task_window_is_active(priv->windows->data))
991 task_window_activate (priv->windows->data, priv->drag_time);1253 task_window_activate (priv->windows->data, priv->drag_time);
9921254*/
993 return FALSE;1255 return FALSE;
994}1256}
9951257
@@ -1104,9 +1366,11 @@
1104 {1366 {
1105 /* If it is a launcher it should show that it accepts the drag.1367 /* If it is a launcher it should show that it accepts the drag.
1106 Else only the the timeout should get set to activate the window. */1368 Else only the the timeout should get set to activate the window. */
1107 if (!priv->windows || !TASK_IS_LAUNCHER (priv->windows->data))1369
1108 gdk_drag_status (context, GDK_ACTION_DEFAULT, t);1370 //TODO: h4writer - 2nd round
1109 else1371 //if (!priv->items || !TASK_IS_LAUNCHER (priv->items->data))
1372 // gdk_drag_status (context, GDK_ACTION_DEFAULT, t);
1373 //else
1110 gdk_drag_status (context, GDK_ACTION_COPY, t);1374 gdk_drag_status (context, GDK_ACTION_COPY, t);
1111 return TRUE;1375 return TRUE;
1112 }1376 }
@@ -1151,7 +1415,7 @@
1151 TaskIconPrivate *priv;1415 TaskIconPrivate *priv;
1152 GSList *list;1416 GSList *list;
1153 GError *error;1417 GError *error;
1154 TaskLauncher *launcher;1418 //TaskLauncher *launcher;
1155 GdkAtom target;1419 GdkAtom target;
1156 gchar *target_name;1420 gchar *target_name;
1157 gchar *sdata_data;1421 gchar *sdata_data;
@@ -1170,13 +1434,14 @@
1170 }1434 }
11711435
1172 /* If we are not a launcher, we don't care about this */1436 /* If we are not a launcher, we don't care about this */
1173 if (!priv->windows || !TASK_IS_LAUNCHER (priv->windows->data))1437 //TODO: h4writer - 2nd round
1174 {1438 //if (!priv->windows || !TASK_IS_LAUNCHER (priv->windows->data))
1175 gtk_drag_finish (context, FALSE, FALSE, time_);1439 //{
1176 return;1440 // gtk_drag_finish (context, FALSE, FALSE, time_);
1177 }1441 // return;
11781442 //}
1179 launcher = priv->windows->data;1443 //
1444 //launcher = priv->windows->data;
11801445
1181 sdata_data = (gchar*)gtk_selection_data_get_data (sdata);1446 sdata_data = (gchar*)gtk_selection_data_get_data (sdata);
1182 1447
@@ -1197,10 +1462,10 @@
1197 //FIXME: I think this function returns always FALSE (haytjes)1462 //FIXME: I think this function returns always FALSE (haytjes)
1198 // and I also think this isn't a bad idea to allow too.1463 // and I also think this isn't a bad idea to allow too.
1199 // I often drop a url on firefox, even when it is already open.1464 // I often drop a url on firefox, even when it is already open.
1200 if (task_launcher_has_window (launcher))1465 //if (task_launcher_has_windows (launcher))
1201 {1466 //{
1202 gtk_drag_finish (context, FALSE, FALSE, time_);1467 // gtk_drag_finish (context, FALSE, FALSE, time_);
1203 }1468 //}
1204 1469
1205 error = NULL;1470 error = NULL;
1206 list = awn_vfs_get_pathlist_from_string (sdata_data, &error);1471 list = awn_vfs_get_pathlist_from_string (sdata_data, &error);
@@ -1212,7 +1477,7 @@
1212 return;1477 return;
1213 }1478 }
12141479
1215 task_launcher_launch_with_data (launcher, list);1480 //task_launcher_launch_with_data (launcher, list);
12161481
1217 g_slist_foreach (list, (GFunc)g_free, NULL);1482 g_slist_foreach (list, (GFunc)g_free, NULL);
1218 g_slist_free (list);1483 g_slist_free (list);
12191484
=== modified file 'applets/taskmanager/task-icon.h'
--- applets/taskmanager/task-icon.h 2009-05-27 15:57:06 +0000
+++ applets/taskmanager/task-icon.h 2009-06-22 13:16:54 +0000
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
17 *17 * Hannes Verschore <hv1989@gmail.com>
18 */18 */
1919
20#ifndef _TASK_ICON_H_20#ifndef _TASK_ICON_H_
@@ -24,6 +24,7 @@
24#include <gtk/gtk.h>24#include <gtk/gtk.h>
25#include <libawn/libawn.h>25#include <libawn/libawn.h>
2626
27#include "task-item.h"
27#include "task-window.h"28#include "task-window.h"
28#include "task-launcher.h"29#include "task-launcher.h"
2930
@@ -50,19 +51,19 @@
50 51
51struct _TaskIcon52struct _TaskIcon
52{53{
53 AwnIcon parent; 54 AwnThemedIcon parent;
5455
55 TaskIconPrivate *priv;56 TaskIconPrivate *priv;
56};57};
5758
58struct _TaskIconClass59struct _TaskIconClass
59{60{
60 AwnIconClass parent_class;61 AwnThemedIconClass parent_class;
6162
62 /*< vtable, not signals >*/63 /*< vtable, not signals >*/
63 64
64 /*< signals >*/65 /*< signals >*/
65 void (*ensure_layout) (TaskIcon *icon);66 void (*visible_changed) (TaskIcon *icon);
66 void (*source_drag_fail) (TaskIcon *icon);67 void (*source_drag_fail) (TaskIcon *icon);
67 void (*source_drag_begin) (TaskIcon *icon);68 void (*source_drag_begin) (TaskIcon *icon);
68 void (*source_drag_end) (TaskIcon *icon);69 void (*source_drag_end) (TaskIcon *icon);
@@ -72,27 +73,24 @@
7273
73GType task_icon_get_type (void) G_GNUC_CONST;74GType task_icon_get_type (void) G_GNUC_CONST;
7475
75GtkWidget* task_icon_new_for_window (TaskWindow *window);76GtkWidget* task_icon_new ();
7677
77gboolean task_icon_is_skip_taskbar (TaskIcon *icon);78gboolean task_icon_is_visible (TaskIcon *icon);
7879gboolean task_icon_contains_launcher (TaskIcon *icon);
79gboolean task_icon_is_in_viewport (TaskIcon *icon,80
80 WnckWorkspace *space);81void task_icon_append_item (TaskIcon *icon,
8182 TaskItem *item);
82void task_icon_append_window (TaskIcon *icon,83void task_icon_remove_item (TaskIcon *icon,
83 TaskWindow *window);84 TaskItem *item);
84void task_icon_remove_window (TaskIcon *icon,85guint task_icon_match_item (TaskIcon *icon,
85 WnckWindow *window);86 TaskItem *item);
86gboolean task_icon_is_launcher (TaskIcon *icon);87
87TaskLauncher* task_icon_get_launcher (TaskIcon *icon);88//void task_icon_remove_windows (TaskIcon *icon);
88TaskWindow* task_icon_get_window (TaskIcon *icon);89
8990void task_icon_refresh_icon (TaskIcon *icon);
90void task_icon_refresh_icon (TaskIcon *icon);91
9192void task_icon_set_draggable (TaskIcon *icon,
92gboolean task_icon_refresh_geometry (TaskIcon *icon);93 gboolean draggable);
93
94void task_icon_set_draggable (TaskIcon *icon,
95 gboolean draggable);
9694
97#endif /* _TASK_ICON_H_ */95#endif /* _TASK_ICON_H_ */
9896
9997
=== added file 'applets/taskmanager/task-item.c'
--- applets/taskmanager/task-item.c 1970-01-01 00:00:00 +0000
+++ applets/taskmanager/task-item.c 2009-06-28 01:53:46 +0000
@@ -0,0 +1,301 @@
1/*
2 * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by Hannes Verschore <hv1989@gmail.com>
17 *
18 */
19
20#include "task-item.h"
21
22#include <libawn/libawn.h>
23
24G_DEFINE_ABSTRACT_TYPE (TaskItem, task_item, GTK_TYPE_EVENT_BOX)
25
26#define TASK_ITEM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
27 TASK_TYPE_ITEM, \
28 TaskItemPrivate))
29
30struct _TaskItemPrivate
31{
32 GtkWidget *box;
33 GtkWidget *name;
34 GtkWidget *icon;
35};
36
37enum
38{
39 PROP_0
40};
41
42enum
43{
44 NAME_CHANGED,
45 ICON_CHANGED,
46 VISIBLE_CHANGED,
47
48 LAST_SIGNAL
49};
50static guint32 _item_signals[LAST_SIGNAL] = { 0 };
51
52/* Forwards */
53static void task_item_name_changed (TaskItem *item, const gchar *name);
54static void task_item_icon_changed (TaskItem *item, GdkPixbuf *icon);
55static void task_item_visible_changed (TaskItem *item, gboolean visible);
56
57static gboolean task_item_button_release_event (GtkWidget *widget,
58 GdkEventButton *event);
59static gboolean task_item_button_press_event (GtkWidget *widget,
60 GdkEventButton *event);
61
62/* GObject stuff */
63static void
64task_item_class_init (TaskItemClass *klass)
65{
66 //GParamSpec *pspec;
67 GObjectClass *obj_class = G_OBJECT_CLASS (klass);
68 GtkWidgetClass *wid_class = GTK_WIDGET_CLASS (klass);
69
70 wid_class->button_release_event = task_item_button_release_event;
71 wid_class->button_press_event = task_item_button_press_event;
72
73 /* We implement the necessary funtions for a normal item */
74 klass->get_name = NULL;
75 klass->get_icon = NULL;
76 klass->is_visible = NULL;
77 klass->match = NULL;
78
79 /* Install signals */
80 _item_signals[NAME_CHANGED] =
81 g_signal_new ("name-changed",
82 G_OBJECT_CLASS_TYPE (obj_class),
83 G_SIGNAL_RUN_LAST,
84 G_STRUCT_OFFSET (TaskItemClass, name_changed),
85 NULL, NULL,
86 g_cclosure_marshal_VOID__STRING,
87 G_TYPE_NONE,
88 1, G_TYPE_STRING);
89
90 _item_signals[ICON_CHANGED] =
91 g_signal_new ("icon-changed",
92 G_OBJECT_CLASS_TYPE (obj_class),
93 G_SIGNAL_RUN_LAST,
94 G_STRUCT_OFFSET (TaskItemClass, icon_changed),
95 NULL, NULL,
96 g_cclosure_marshal_VOID__OBJECT,
97 G_TYPE_NONE,
98 1, GDK_TYPE_PIXBUF);
99
100 _item_signals[VISIBLE_CHANGED] =
101 g_signal_new ("visible-changed",
102 G_OBJECT_CLASS_TYPE (obj_class),
103 G_SIGNAL_RUN_LAST,
104 G_STRUCT_OFFSET (TaskItemClass, visible_changed),
105 NULL, NULL,
106 g_cclosure_marshal_VOID__BOOLEAN,
107 G_TYPE_NONE,
108 1, G_TYPE_BOOLEAN);
109
110 g_type_class_add_private (obj_class, sizeof (TaskItemPrivate));
111}
112
113static void
114task_item_init (TaskItem *item)
115{
116 TaskItemPrivate *priv;
117
118 /* get and save private struct */
119 priv = item->priv = TASK_ITEM_GET_PRIVATE (item);
120
121 /* let this eventbox listen to every events */
122 gtk_event_box_set_above_child (GTK_EVENT_BOX (item), TRUE);
123
124 /* create content */
125 priv->box = gtk_hbox_new (FALSE, 10);
126 gtk_container_add (GTK_CONTAINER (item), priv->box);
127
128 priv->icon = awn_icon_new ();
129 gtk_box_pack_start (GTK_BOX (priv->box), priv->icon, FALSE, FALSE, 0);
130
131 priv->name = gtk_label_new ("");
132 gtk_box_pack_start (GTK_BOX (priv->box), priv->name, TRUE, FALSE, 10);
133
134 /* connect to signals */
135 g_signal_connect (G_OBJECT (item), "name-changed",
136 G_CALLBACK (task_item_name_changed), NULL);
137 g_signal_connect (G_OBJECT (item), "icon-changed",
138 G_CALLBACK (task_item_icon_changed), NULL);
139 g_signal_connect (G_OBJECT (item), "visible-changed",
140 G_CALLBACK (task_item_visible_changed), NULL);
141}
142
143static gboolean
144task_item_button_release_event (GtkWidget *widget,
145 GdkEventButton *event)
146{
147 g_return_val_if_fail (TASK_IS_ITEM (widget), FALSE);
148
149 task_item_left_click (TASK_ITEM (widget), event);
150
151 return TRUE;
152}
153
154static gboolean
155task_item_button_press_event (GtkWidget *widget,
156 GdkEventButton *event)
157{
158 g_return_val_if_fail (TASK_IS_ITEM (widget), FALSE);
159
160 if (event->button != 3) return FALSE;
161
162 task_item_right_click (TASK_ITEM (widget), event);
163
164 return TRUE;
165}
166
167static void
168task_item_name_changed (TaskItem *item, const gchar *name)
169{
170 TaskItemPrivate *priv = TASK_ITEM_GET_PRIVATE (item);
171
172 gtk_label_set_text (GTK_LABEL (priv->name), name);
173}
174
175
176static void
177task_item_icon_changed (TaskItem *item, GdkPixbuf *icon)
178{
179 TaskItemPrivate *priv = TASK_ITEM_GET_PRIVATE (item);
180
181 awn_icon_set_from_pixbuf (AWN_ICON (priv->icon), icon);
182}
183
184static void
185task_item_visible_changed (TaskItem *item, gboolean visible)
186{
187 if (visible)
188 gtk_widget_show (GTK_WIDGET (item));
189 else
190 gtk_widget_hide (GTK_WIDGET (item));
191}
192
193/**
194 * Public functions
195 */
196
197const gchar *
198task_item_get_name (TaskItem *item)
199{
200 TaskItemClass *klass;
201
202 g_return_val_if_fail (TASK_IS_ITEM (item), NULL);
203
204 klass = TASK_ITEM_GET_CLASS (item);
205 g_return_val_if_fail (klass->get_name, NULL);
206
207 return klass->get_name (item);
208}
209
210GdkPixbuf *
211task_item_get_icon (TaskItem *item)
212{
213 TaskItemClass *klass;
214
215 g_return_val_if_fail (TASK_IS_ITEM (item), NULL);
216
217 klass = TASK_ITEM_GET_CLASS (item);
218 g_return_val_if_fail (klass->get_icon, NULL);
219
220 return klass->get_icon (item);
221}
222
223gboolean
224task_item_is_visible (TaskItem *item)
225{
226 TaskItemClass *klass;
227
228 g_return_val_if_fail (TASK_IS_ITEM (item), FALSE);
229
230 klass = TASK_ITEM_GET_CLASS (item);
231 g_return_val_if_fail (klass->is_visible, FALSE);
232
233 return klass->is_visible (item);
234}
235
236void
237task_item_left_click (TaskItem *item, GdkEventButton *event)
238{
239 TaskItemClass *klass;
240
241 g_return_if_fail (TASK_IS_ITEM (item));
242
243 klass = TASK_ITEM_GET_CLASS (item);
244 g_return_if_fail (klass->left_click);
245
246 klass->left_click (item, event);
247}
248
249void
250task_item_right_click (TaskItem *item, GdkEventButton *event)
251{
252 TaskItemClass *klass;
253
254 g_return_if_fail (TASK_IS_ITEM (item));
255
256 klass = TASK_ITEM_GET_CLASS (item);
257 g_return_if_fail (klass->right_click);
258
259 klass->right_click (item, event);
260}
261
262guint
263task_item_match (TaskItem *item, TaskItem *item_to_match)
264{
265 TaskItemClass *klass;
266
267 g_return_val_if_fail (TASK_IS_ITEM (item), 0);
268
269 klass = TASK_ITEM_GET_CLASS (item);
270 g_return_val_if_fail (klass->match, 0);
271
272 return klass->match (item, item_to_match);
273}
274
275/**
276 * Protected functions (used only by derived classes)
277 */
278
279void
280task_item_emit_name_changed (TaskItem *item, const gchar *name)
281{
282 g_return_if_fail (TASK_IS_ITEM (item));
283
284 g_signal_emit (item, _item_signals[NAME_CHANGED], 0, name);
285}
286
287void
288task_item_emit_icon_changed (TaskItem *item, GdkPixbuf *icon)
289{
290 g_return_if_fail (TASK_IS_ITEM (item));
291
292 g_signal_emit (item, _item_signals[ICON_CHANGED], 0, icon);
293}
294
295void
296task_item_emit_visible_changed (TaskItem *item, gboolean visible)
297{
298 g_return_if_fail (TASK_IS_ITEM (item));
299
300 g_signal_emit (item, _item_signals[VISIBLE_CHANGED], 0, visible);
301}
0\ No newline at end of file302\ No newline at end of file
1303
=== added file 'applets/taskmanager/task-item.h'
--- applets/taskmanager/task-item.h 1970-01-01 00:00:00 +0000
+++ applets/taskmanager/task-item.h 2009-06-20 10:58:03 +0000
@@ -0,0 +1,98 @@
1/*
2 * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by Hannes Verschore <hv1989@gmail.com>
17 *
18 */
19
20#ifndef _TASK_ITEM_H_
21#define _TASK_ITEM_H_
22
23#include <glib-object.h>
24#include <gtk/gtk.h>
25
26G_BEGIN_DECLS
27
28#define TASK_TYPE_ITEM (task_item_get_type ())
29
30#define TASK_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
31 TASK_TYPE_ITEM, TaskItem))
32
33#define TASK_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
34 TASK_TYPE_ITEM, TaskItemClass))
35
36#define TASK_IS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
37 TASK_TYPE_ITEM))
38
39#define TASK_IS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
40 TASK_TYPE_ITEM))
41
42#define TASK_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
43 TASK_TYPE_ITEM, TaskItemClass))
44
45typedef struct _TaskItem TaskItem;
46typedef struct _TaskItemClass TaskItemClass;
47typedef struct _TaskItemPrivate TaskItemPrivate;
48
49struct _TaskItem
50{
51 GtkBox parent;
52
53 TaskItemPrivate *priv;
54};
55
56struct _TaskItemClass
57{
58 GtkBoxClass parent_class;
59
60 /*< vtable, not signals >*/
61 const gchar * (*get_name) (TaskItem *item);
62 GdkPixbuf * (*get_icon) (TaskItem *item);
63 gboolean (*is_visible) (TaskItem *item);
64 void (*left_click) (TaskItem *item, GdkEventButton *event);
65 void (*right_click) (TaskItem *item, GdkEventButton *event);
66 guint (*match) (TaskItem *item, TaskItem *item_to_match);
67
68 /*< signals >*/
69 void (*name_changed) (TaskItem *item, const gchar *name);
70 void (*icon_changed) (TaskItem *item, GdkPixbuf *icon);
71 void (*visible_changed) (TaskItem *item, gboolean visible);
72};
73
74GType task_item_get_type (void) G_GNUC_CONST;
75
76const gchar * task_item_get_name (TaskItem *item);
77GdkPixbuf * task_item_get_icon (TaskItem *item);
78gboolean task_item_is_visible (TaskItem *item);
79void task_item_left_click (TaskItem *item, GdkEventButton *event);
80void task_item_right_click (TaskItem *item, GdkEventButton *event);
81guint task_item_match (TaskItem *item, TaskItem *item_to_match);
82
83//TODO: 2nd round: implement
84//const gchar * task_item_get_name (TaskItem *item);
85//void task_item_set_name (TaskItem *item,
86// const gchar *name);
87//GdkPixbuf * task_item_get_icon (TaskItem *item);
88//void task_item_update_icon (TaskItem *item,
89// GdkPixbuf *pixbuf);
90
91/* These should be "protected" (used only by derived classes) */
92void task_item_emit_name_changed (TaskItem *item, const gchar *name);
93void task_item_emit_icon_changed (TaskItem *item, GdkPixbuf *icon);
94void task_item_emit_visible_changed (TaskItem *item, gboolean visible);
95
96G_END_DECLS
97
98#endif /* _TASK_ITEM_H_ */
099
=== modified file 'applets/taskmanager/task-launcher.c'
--- applets/taskmanager/task-launcher.c 2009-04-18 00:36:20 +0000
+++ applets/taskmanager/task-launcher.c 2009-06-20 14:17:54 +0000
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
17 *17 * Hannes Verschore <hv1989@gmail.com>
18 */18 */
1919
20#include <stdio.h>20#include <stdio.h>
@@ -28,19 +28,18 @@
28#include <libawn/libawn.h>28#include <libawn/libawn.h>
2929
30#include "task-launcher.h"30#include "task-launcher.h"
31#include "task-item.h"
31#include "task-window.h"32#include "task-window.h"
3233
33#include "task-settings.h"34#include "task-settings.h"
34#include "xutils.h"35#include "xutils.h"
3536
36G_DEFINE_TYPE (TaskLauncher, task_launcher, TASK_TYPE_WINDOW)37G_DEFINE_TYPE (TaskLauncher, task_launcher, TASK_TYPE_ITEM)
3738
38#define TASK_LAUNCHER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\39#define TASK_LAUNCHER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
39 TASK_TYPE_LAUNCHER, \40 TASK_TYPE_LAUNCHER, \
40 TaskLauncherPrivate))41 TaskLauncherPrivate))
4142
42#define GET_WINDOW_PRIVATE(obj) (TASK_WINDOW(obj)->priv)
43
44struct _TaskLauncherPrivate43struct _TaskLauncherPrivate
45{44{
46 gchar *path;45 gchar *path;
@@ -59,15 +58,15 @@
59};58};
6059
61/* Forwards */60/* Forwards */
62static gint _get_pid (TaskWindow *window);61static const gchar * _get_name (TaskItem *item);
63static const gchar * _get_name (TaskWindow *window);62static GdkPixbuf * _get_icon (TaskItem *item);
64static GdkPixbuf * _get_icon (TaskWindow *window);63static gboolean _is_visible (TaskItem *item);
65static gboolean _is_on_workspace (TaskWindow *window,64static void _left_click (TaskItem *item,
66 WnckWorkspace *space);65 GdkEventButton *event);
67static void _activate (TaskWindow *window,66static void _right_click (TaskItem *item,
68 guint32 timestamp);67 GdkEventButton *event);
69static void _popup_menu (TaskWindow *window,68static guint _match (TaskItem *item,
70 GtkMenu *menu);69 TaskItem *item_to_match);
7170
72static void task_launcher_set_desktop_file (TaskLauncher *launcher,71static void task_launcher_set_desktop_file (TaskLauncher *launcher,
73 const gchar *path);72 const gchar *path);
@@ -115,19 +114,19 @@
115task_launcher_class_init (TaskLauncherClass *klass)114task_launcher_class_init (TaskLauncherClass *klass)
116{115{
117 GParamSpec *pspec;116 GParamSpec *pspec;
118 GObjectClass *obj_class = G_OBJECT_CLASS (klass);117 GObjectClass *obj_class = G_OBJECT_CLASS (klass);
119 TaskWindowClass *win_class = TASK_WINDOW_CLASS (klass);118 TaskItemClass *item_class = TASK_ITEM_CLASS (klass);
120119
121 obj_class->set_property = task_launcher_set_property;120 obj_class->set_property = task_launcher_set_property;
122 obj_class->get_property = task_launcher_get_property;121 obj_class->get_property = task_launcher_get_property;
123122
124 /* We implement the necessary funtions for a normal window */123 /* We implement the necessary funtions for a normal window */
125 win_class->get_pid = _get_pid;124 item_class->get_name = _get_name;
126 win_class->get_name = _get_name;125 item_class->get_icon = _get_icon;
127 win_class->get_icon = _get_icon;126 item_class->is_visible = _is_visible;
128 win_class->is_on_workspace = _is_on_workspace;127 item_class->match = _match;
129 win_class->activate = _activate;128 item_class->left_click = _left_click;
130 win_class->popup_menu = _popup_menu;129 item_class->right_click = _right_click;
131130
132 /* Install properties */131 /* Install properties */
133 pspec = g_param_spec_string ("desktopfile",132 pspec = g_param_spec_string ("desktopfile",
@@ -151,19 +150,19 @@
151 priv->item = NULL;150 priv->item = NULL;
152}151}
153152
154TaskLauncher * 153TaskItem *
155task_launcher_new_for_desktop_file (const gchar *path)154task_launcher_new_for_desktop_file (const gchar *path)
156{155{
157 TaskLauncher *win = NULL;156 TaskItem *item = NULL;
158157
159 if (!g_file_test (path, G_FILE_TEST_EXISTS))158 if (!g_file_test (path, G_FILE_TEST_EXISTS))
160 return NULL;159 return NULL;
161160
162 win = g_object_new (TASK_TYPE_LAUNCHER,161 item = g_object_new (TASK_TYPE_LAUNCHER,
163 "desktopfile", path,162 "desktopfile", path,
164 NULL);163 NULL);
165164
166 return win;165 return item;
167}166}
168167
169const gchar * 168const gchar *
@@ -178,6 +177,8 @@
178task_launcher_set_desktop_file (TaskLauncher *launcher, const gchar *path)177task_launcher_set_desktop_file (TaskLauncher *launcher, const gchar *path)
179{178{
180 TaskLauncherPrivate *priv;179 TaskLauncherPrivate *priv;
180 TaskSettings * s = task_settings_get_default ();
181 GdkPixbuf *pixbuf;
181 gchar * exec_key = NULL;182 gchar * exec_key = NULL;
182 gchar * needle = NULL;183 gchar * needle = NULL;
183 184
@@ -210,194 +211,161 @@
210 priv->exec = exec_key;211 priv->exec = exec_key;
211 priv->icon_name = awn_desktop_item_get_icon_name (priv->item);212 priv->icon_name = awn_desktop_item_get_icon_name (priv->item);
212213
214 task_item_emit_name_changed (TASK_ITEM (launcher), priv->name);
215 pixbuf = awn_desktop_item_get_icon (priv->item, s->panel_size);
216 task_item_emit_icon_changed (TASK_ITEM (launcher), pixbuf);
217 g_object_unref (pixbuf);
218 task_item_emit_visible_changed (TASK_ITEM (launcher), TRUE);
219
213 g_debug ("LAUNCHER: %s", priv->name);220 g_debug ("LAUNCHER: %s", priv->name);
214}221}
215222
216/*223/*
217 * Implemented functions for a standard window without a launcher224 * Implemented functions for a standard window without a launcher
218 */225 */
219static gint
220_get_pid (TaskWindow *window)
221{
222 TaskLauncher *launcher = TASK_LAUNCHER (window);
223
224 if (WNCK_IS_WINDOW (window->priv->window))
225 {
226 gint value = -1;
227 value = wnck_window_get_pid (window->priv->window);
228 value = value ? value : -1;
229 return value;
230 }
231 else
232 {
233 return launcher->priv->pid;
234 }
235}
236
237static const gchar * 226static const gchar *
238_get_name (TaskWindow *window)227_get_name (TaskItem *item)
239{228{
240 TaskLauncher *launcher = TASK_LAUNCHER (window);229 return TASK_LAUNCHER (item)->priv->name;
241
242 if (WNCK_IS_WINDOW (window->priv->window))
243 {
244 return wnck_window_get_name (window->priv->window);
245 }
246 else
247 {
248 return launcher->priv->name;
249 }
250}230}
251231
252static GdkPixbuf * 232static GdkPixbuf *
253_get_icon (TaskWindow *window)233_get_icon (TaskItem *item)
254{234{
255 TaskLauncher *launcher = TASK_LAUNCHER (window);
256 TaskSettings *s = task_settings_get_default ();235 TaskSettings *s = task_settings_get_default ();
257236
258 if (WNCK_IS_WINDOW (window->priv->window))237 return awn_desktop_item_get_icon (TASK_LAUNCHER (item)->priv->item, s->panel_size);
259 {
260 return _wnck_get_icon_at_size (window->priv->window,
261 s->panel_size, s->panel_size);
262 }
263 else
264 {
265 return awn_desktop_item_get_icon (launcher->priv->item, s->panel_size);
266 }
267}238}
268239
269static gboolean 240static gboolean
270_is_on_workspace (TaskWindow *window,241_is_visible (TaskItem *item)
271 WnckWorkspace *space)
272{242{
273 return TRUE;243 return TRUE;
274}244}
275245
276static void 246/**
277_activate (TaskWindow *window,247 * Match the launcher with the provided window.
278 guint32 timestamp)248 * The higher the number it returns the more it matches the window.
279{249 * 100 = definitly matches
280 TaskLauncher *launcher = TASK_LAUNCHER (window);250 * 0 = doesn't match
281 GError *error = NULL;
282
283 launcher->priv->pid = awn_desktop_item_launch (launcher->priv->item,
284 NULL, &error);
285
286 if (error)
287 {
288 g_warning ("Unable to launch %s: %s",
289 launcher->priv->name,
290 error->message);
291 g_error_free (error);
292 }
293}
294
295/*
296 * Public functions
297 */251 */
298gboolean 252static guint
299task_launcher_has_window (TaskLauncher *launcher)253_match (TaskItem *item,
300{254 TaskItem *item_to_match)
301 g_return_val_if_fail (TASK_IS_LAUNCHER (launcher), TRUE);
302
303 if (WNCK_IS_WINDOW (TASK_WINDOW (launcher)->priv->window))
304 return TRUE;
305 return FALSE;
306}
307
308gboolean
309task_launcher_try_match (TaskLauncher *launcher,
310 gint pid,
311 const gchar *res_name,
312 const gchar *class_name)
313{255{
314 TaskLauncherPrivate *priv;256 TaskLauncherPrivate *priv;
315257 TaskLauncher *launcher;
316 g_return_val_if_fail (launcher, FALSE);258 TaskWindow *window;
259 gchar *res_name = NULL;
260 gchar *class_name = NULL;
261 gchar *temp;
262 gint pid;
263
264 g_return_val_if_fail (TASK_IS_LAUNCHER(item), 0);
265
266 if (!TASK_IS_WINDOW (item_to_match)) return 0;
267
268 launcher = TASK_LAUNCHER (item);
317 priv = launcher->priv;269 priv = launcher->priv;
270
271 window = TASK_WINDOW (item_to_match);
318272
319 /* Try simple pid-match first */273 /* Try simple pid-match first */
274 pid = task_window_get_pid(window);
320 if ( pid && (priv->pid == pid))275 if ( pid && (priv->pid == pid))
321 return TRUE;276 return 100;
322277
323 /* Now try resource name, which should (hopefully) be 99% of the cases */278 /* Now try resource name, which should (hopefully) be 99% of the cases */
324 if ( res_name && strlen(res_name) && priv->exec)279 task_window_get_wm_class(window, &res_name, &class_name);
280
281 if (res_name)
325 {282 {
326 if ( g_strstr_len (priv->exec, strlen (priv->exec), res_name) ||283 temp = res_name;
327 g_strstr_len (res_name, strlen (res_name), priv->exec))284 res_name = g_utf8_strdown (temp, -1);
285 g_free (temp);
286
287 if ( strlen(res_name) && priv->exec)
328 {288 {
329 return TRUE;289 if ( g_strstr_len (priv->exec, strlen (priv->exec), res_name) ||
290 g_strstr_len (res_name, strlen (res_name), priv->exec))
291 {
292 g_free (res_name);
293 g_free (class_name);
294 return 70;
295 }
330 }296 }
331 }297 }
332 298
333 /* Try a class_name to exec line match */299 /* Try a class_name to exec line match */
334 if ( class_name && strlen(class_name) && priv->exec)300 if (class_name)
335 {301 {
336 if (g_strstr_len (priv->exec, strlen (priv->exec), class_name))302 temp = class_name;
337 return TRUE;303 class_name = g_utf8_strdown (temp, -1);
338 }304 g_free (temp);
339305
340 return FALSE; 306 if (strlen(class_name) && priv->exec)
341}307 {
342308 if (g_strstr_len (priv->exec, strlen (priv->exec), class_name))
343static void309 {
344on_window_closed (TaskLauncher *launcher, WnckWindow *old_window)310 g_free (res_name);
345{311 g_free (class_name);
346 TaskWindowPrivate *priv;312 return 50;
347 TaskSettings *s = task_settings_get_default ();313 }
348 GdkPixbuf *pixbuf;314 }
349315 }
350 g_return_if_fail (TASK_IS_LAUNCHER (launcher));316
351 priv = TASK_WINDOW (launcher)->priv;317 g_free (res_name);
352318 g_free (class_name);
353 /* NULLify the window pointer */319 return 0;
354 priv->window = NULL;320}
355321
356 /* Reset name */322static void
357 task_window_set_name (TASK_WINDOW (launcher), launcher->priv->name); 323_left_click (TaskItem *item, GdkEventButton *event)
358324{
359 /* Reset icon */325 TaskLauncherPrivate *priv;
360 pixbuf = xutils_get_named_icon (launcher->priv->icon_name,326 TaskLauncher *launcher;
361 s->panel_size, s->panel_size);327 GError *error = NULL;
362328
363 task_window_update_icon (TASK_WINDOW (launcher), pixbuf);329 g_return_if_fail (TASK_IS_LAUNCHER (item));
364330
365 g_object_unref (pixbuf);331 launcher = TASK_LAUNCHER (item);
366}332 priv = launcher->priv;
367333
368void 334 priv->pid = awn_desktop_item_launch (priv->item, NULL, &error);
369task_launcher_set_window (TaskLauncher *launcher,335
370 WnckWindow *window)336 if (error)
371{337 {
372 g_return_if_fail (TASK_IS_LAUNCHER (launcher));338 g_warning ("Unable to launch %s: %s",
373 g_return_if_fail (WNCK_IS_WINDOW (window));339 task_item_get_name (item),
374340 error->message);
375 g_object_set (launcher, "taskwindow", window, NULL);341 g_error_free (error);
376342 }
377 task_window_set_name (TASK_WINDOW (launcher), wnck_window_get_name (window));343}
378344
379 g_object_weak_ref (G_OBJECT (window), 345static void
380 (GWeakNotify)on_window_closed,346_right_click (TaskItem *item, GdkEventButton *event)
381 launcher);347{
382}348 TaskLauncherPrivate *priv;
383349 TaskLauncher *launcher;
384static void 350 GtkWidget *menu_item,
385_popup_menu (TaskWindow *window,351 *menu;
386 GtkMenu *menu)352
387{353 g_return_if_fail (TASK_IS_LAUNCHER (item));
388 TaskWindowPrivate *priv;354
389 GtkWidget *item;355 launcher = TASK_LAUNCHER (item);
390 356 priv = launcher->priv;
391 g_return_if_fail (TASK_IS_WINDOW (window));357
392 priv = window->priv;358 menu = gtk_menu_new ();
393359 menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_EXECUTE, NULL);
394 if (!WNCK_IS_WINDOW (priv->window))360 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
395 {361 gtk_widget_show (menu_item);
396 item = gtk_image_menu_item_new_from_stock (GTK_STOCK_EXECUTE, NULL);362 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
397 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);363 NULL, NULL, event->button, event->time);
398 gtk_widget_show (item);364}
399 }365
400}366/*
367 * Public functions
368 */
401369
402void 370void
403task_launcher_launch_with_data (TaskLauncher *launcher,371task_launcher_launch_with_data (TaskLauncher *launcher,
@@ -429,10 +397,7 @@
429 g_return_if_fail (TASK_IS_LAUNCHER (launcher));397 g_return_if_fail (TASK_IS_LAUNCHER (launcher));
430 priv = launcher->priv;398 priv = launcher->priv;
431399
432 if (WNCK_IS_WINDOW (TASK_WINDOW (launcher)->priv->window))400 priv->pid = awn_desktop_item_launch (priv->item, NULL, &error);
433 awn_desktop_item_launch (priv->item, NULL, &error);
434 else
435 priv->pid = awn_desktop_item_launch (priv->item, NULL, &error);
436401
437 if (error)402 if (error)
438 {403 {
439404
=== modified file 'applets/taskmanager/task-launcher.h'
--- applets/taskmanager/task-launcher.h 2008-12-26 15:19:53 +0000
+++ applets/taskmanager/task-launcher.h 2009-06-20 14:17:54 +0000
@@ -14,6 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
17 * Hannes Verschore <hv1989@gmail.com>
17 *18 *
18 */19 */
1920
@@ -24,7 +25,7 @@
24#include <gtk/gtk.h>25#include <gtk/gtk.h>
25#include <libwnck/libwnck.h>26#include <libwnck/libwnck.h>
2627
27#include "task-window.h"28#include "task-item.h"
2829
29#define TASK_TYPE_LAUNCHER (task_launcher_get_type ())30#define TASK_TYPE_LAUNCHER (task_launcher_get_type ())
3031
@@ -49,38 +50,24 @@
49 50
50struct _TaskLauncher51struct _TaskLauncher
51{52{
52 TaskWindow parent; 53 TaskItem parent;
5354
54 TaskLauncherPrivate *priv;55 TaskLauncherPrivate *priv;
55};56};
5657
57struct _TaskLauncherClass58struct _TaskLauncherClass
58{59{
59 TaskWindowClass parent_class;60 TaskItemClass parent_class;
6061
61 /*< signals >*/62 /*< signals >*/
62 void (*launcher0) (void);
63 void (*launcher1) (void);
64 void (*launcher2) (void);
65 void (*launcher3) (void);
66};63};
6764
68GType task_launcher_get_type (void) G_GNUC_CONST;65GType task_launcher_get_type (void) G_GNUC_CONST;
6966
70TaskLauncher * task_launcher_new_for_desktop_file (const gchar *path);67TaskItem * task_launcher_new_for_desktop_file (const gchar *path);
7168
72const gchar * task_launcher_get_desktop_path (TaskLauncher *launcher);69const gchar * task_launcher_get_desktop_path (TaskLauncher *launcher);
7370
74gboolean task_launcher_has_window (TaskLauncher *launcher);
75
76gboolean task_launcher_try_match (TaskLauncher *launcher,
77 gint pid,
78 const gchar *res_name,
79 const gchar *class_name);
80
81void task_launcher_set_window (TaskLauncher *launcher,
82 WnckWindow *window);
83
84void task_launcher_launch_with_data (TaskLauncher *launcher,71void task_launcher_launch_with_data (TaskLauncher *launcher,
85 GSList *list);72 GSList *list);
8673
8774
=== added file 'applets/taskmanager/task-manager-api-wrapper.c'
--- applets/taskmanager/task-manager-api-wrapper.c 1970-01-01 00:00:00 +0000
+++ applets/taskmanager/task-manager-api-wrapper.c 2009-06-26 11:00:10 +0000
@@ -0,0 +1,509 @@
1/*
2 * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by Hannes Verschore <hv1989@gmail.com>
17 */
18
19
20#include "task-manager-api-wrapper.h"
21
22#include <libawn/libawn.h>
23
24G_DEFINE_TYPE (TaskManagerApiWrapper, task_manager_api_wrapper, G_TYPE_OBJECT)
25
26#define TASK_MANAGER_API_WRAPPER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
27 TASK_TYPE_MANAGER_API_WRAPPER, \
28 TaskManagerApiWrapperPrivate))
29
30struct _TaskManagerApiWrapperPrivate
31{
32 TaskManager *manager;
33};
34
35enum
36{
37 PROP_0,
38 PROP_MANAGER
39};
40
41/* GObject stuff */
42
43static void
44task_manager_api_wrapper_set_manager (TaskManagerApiWrapper *wrapper,
45 TaskManager *manager)
46{
47 g_return_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper));
48 g_return_if_fail (TASK_IS_MANAGER (manager));
49
50 wrapper->priv->manager = manager;
51}
52
53static void
54task_manager_api_wrapper_get_property (GObject *object,
55 guint prop_id,
56 GValue *value,
57 GParamSpec *pspec)
58{
59 TaskManagerApiWrapper *wrapper = TASK_MANAGER_API_WRAPPER (object);
60
61 switch (prop_id)
62 {
63 case PROP_MANAGER:
64 g_value_set_object (value, wrapper->priv->manager);
65 break;
66
67 default:
68 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
69 }
70}
71
72static void
73task_manager_api_wrapper_set_property (GObject *object,
74 guint prop_id,
75 const GValue *value,
76 GParamSpec *pspec)
77{
78 TaskManagerApiWrapper *wrapper = TASK_MANAGER_API_WRAPPER (object);
79
80 switch (prop_id)
81 {
82 case PROP_MANAGER:
83 task_manager_api_wrapper_set_manager (wrapper, g_value_get_object (value));
84 break;
85
86 default:
87 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
88 }
89}
90
91/* GObject stuff */
92static void
93task_manager_api_wrapper_class_init (TaskManagerApiWrapperClass *klass)
94{
95 GParamSpec *pspec;
96 GObjectClass *obj_class = G_OBJECT_CLASS (klass);
97
98 obj_class->set_property = task_manager_api_wrapper_set_property;
99 obj_class->get_property = task_manager_api_wrapper_get_property;
100
101 /* Install properties */
102 pspec = g_param_spec_object ("manager",
103 "Manager",
104 "TaskManager",
105 TASK_TYPE_MANAGER,
106 G_PARAM_READWRITE);
107 g_object_class_install_property (obj_class, PROP_MANAGER, pspec);
108
109 g_type_class_add_private (obj_class, sizeof (TaskManagerApiWrapperPrivate));
110}
111
112static void
113task_manager_api_wrapper_init (TaskManagerApiWrapper *wrapper)
114{
115 TaskManagerApiWrapperPrivate *priv;
116
117 /* get and save private struct */
118 priv = wrapper->priv = TASK_MANAGER_API_WRAPPER_GET_PRIVATE (wrapper);
119 priv->manager = NULL;
120}
121
122
123TaskManagerApiWrapper *
124task_manager_api_wrapper_new (TaskManager *manager)
125{
126 TaskManagerApiWrapper *wrapper = NULL;
127
128 wrapper = g_object_new (TASK_TYPE_MANAGER_API_WRAPPER,
129 "manager", manager,
130 NULL);
131
132 return wrapper;
133}
134
135gboolean
136task_manager_api_wrapper_set_task_icon_by_name (TaskManagerApiWrapper *wrapper,
137 gchar *name,
138 gchar *icon_path,
139 GError **error)
140{
141 TaskManagerApiWrapperPrivate *priv;
142 gboolean succeeded;
143 GValue window = {0};
144 GHashTable *hints;
145 const gchar *key = "icon-file";
146 GValue value = {0};
147
148 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
149
150 priv = wrapper->priv;
151
152 g_value_init (&window, G_TYPE_STRING);
153 g_value_set_string (&window, name);
154
155 g_value_init (&value, G_TYPE_STRING);
156 g_value_set_string (&value, icon_path);
157
158 hints = g_hash_table_new (g_str_hash, g_str_equal);
159 g_hash_table_insert (hints, (gpointer)key, &value);
160
161 succeeded = task_manager_update (priv->manager,
162 &window,
163 hints,
164 error);
165 g_value_unset (&window);
166 g_value_unset (&value);
167 g_hash_table_destroy (hints);
168
169 return succeeded;
170}
171
172gboolean
173task_manager_api_wrapper_unset_task_icon_by_name (TaskManagerApiWrapper *wrapper,
174 gchar *name,
175 GError **error)
176{
177 TaskManagerApiWrapperPrivate *priv;
178 gboolean succeeded;
179 GValue window = {0};
180 GHashTable *hints;
181 const gchar *key = "icon-file";
182 GValue value = {0};
183
184 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
185
186 priv = wrapper->priv;
187
188 g_value_init (&window, G_TYPE_STRING);
189 g_value_set_string (&window, name);
190
191 g_value_init (&value, G_TYPE_STRING);
192 g_value_set_string (&value, "");
193
194 hints = g_hash_table_new (g_str_hash, g_str_equal);
195 g_hash_table_insert (hints, (gpointer)key, &value);
196
197 succeeded = task_manager_update (priv->manager,
198 &window,
199 hints,
200 error);
201 g_value_unset (&window);
202 g_value_unset (&value);
203 g_hash_table_destroy (hints);
204
205 return succeeded;
206}
207
208gboolean
209task_manager_api_wrapper_set_info_by_name (TaskManagerApiWrapper *wrapper,
210 gchar *name,
211 gchar *info,
212 GError **error)
213{
214 TaskManagerApiWrapperPrivate *priv;
215 gboolean succeeded;
216 GValue window = {0};
217 GHashTable *hints;
218 const gchar *key = "message";
219 GValue value = {0};
220
221 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
222
223 priv = wrapper->priv;
224
225 g_value_init (&window, G_TYPE_STRING);
226 g_value_set_string (&window, name);
227
228 g_value_init (&value, G_TYPE_STRING);
229 g_value_set_string (&value, info);
230
231 hints = g_hash_table_new (g_str_hash, g_str_equal);
232 g_hash_table_insert (hints, (gpointer)key, &value);
233
234 succeeded = task_manager_update (priv->manager,
235 &window,
236 hints,
237 error);
238 g_value_unset (&window);
239 g_value_unset (&value);
240 g_hash_table_destroy (hints);
241
242 return succeeded;
243}
244
245gboolean
246task_manager_api_wrapper_unset_info_by_name (TaskManagerApiWrapper *wrapper,
247 gchar *name,
248 GError **error)
249{
250 TaskManagerApiWrapperPrivate *priv;
251 gboolean succeeded;
252 GValue window = {0};
253 GHashTable *hints;
254 const gchar *key = "message";
255 GValue value = {0};
256
257 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
258
259 priv = wrapper->priv;
260
261 g_value_init (&window, G_TYPE_STRING);
262 g_value_set_string (&window, name);
263
264 g_value_init (&value, G_TYPE_STRING);
265 g_value_set_string (&value, "");
266
267 hints = g_hash_table_new (g_str_hash, g_str_equal);
268 g_hash_table_insert (hints, (gpointer)key, &value);
269
270 succeeded = task_manager_update (priv->manager,
271 &window,
272 hints,
273 error);
274 g_value_unset (&window);
275 g_value_unset (&value);
276 g_hash_table_destroy (hints);
277
278 return succeeded;
279}
280
281gboolean
282task_manager_api_wrapper_set_progress_by_name (TaskManagerApiWrapper *wrapper,
283 gchar *name,
284 gint progress,
285 GError **error)
286{
287 TaskManagerApiWrapperPrivate *priv;
288 gboolean succeeded;
289 GValue window = {0};
290 GHashTable *hints;
291 const gchar *key = "message";
292 GValue value = {0};
293
294 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
295
296 priv = wrapper->priv;
297
298 g_value_init (&window, G_TYPE_STRING);
299 g_value_set_string (&window, name);
300
301 //difference between old and new api
302 //unsetting progress indicator by setting progress to -1;
303 if (progress == 100) progress = -1;
304
305 g_value_init (&value, G_TYPE_INT);
306 g_value_set_int (&value, progress);
307
308 hints = g_hash_table_new (g_str_hash, g_str_equal);
309 g_hash_table_insert (hints, (gpointer)key, &value);
310
311 succeeded = task_manager_update (priv->manager,
312 &window,
313 hints,
314 error);
315 g_value_unset (&window);
316 g_value_unset (&value);
317 g_hash_table_destroy (hints);
318
319 return succeeded;
320}
321
322/* XID variants */
323
324gboolean
325task_manager_api_wrapper_set_task_icon_by_xid (TaskManagerApiWrapper *wrapper,
326 gint64 xid,
327 gchar *icon_path,
328 GError **error)
329{
330 TaskManagerApiWrapperPrivate *priv;
331 gboolean succeeded;
332 GValue window = {0};
333 GHashTable *hints;
334 const gchar *key = "icon-file";
335 GValue value = {0};
336
337 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
338
339 priv = wrapper->priv;
340
341 g_value_init (&window, G_TYPE_INT64);
342 g_value_set_int64 (&window, xid);
343
344 g_value_init (&value, G_TYPE_STRING);
345 g_value_set_string (&value, icon_path);
346
347 hints = g_hash_table_new (g_str_hash, g_str_equal);
348 g_hash_table_insert (hints, (gpointer)key, &value);
349
350 succeeded = task_manager_update (priv->manager,
351 &window,
352 hints,
353 error);
354 g_value_unset (&window);
355 g_value_unset (&value);
356 g_hash_table_destroy (hints);
357
358 return succeeded;
359}
360
361gboolean
362task_manager_api_wrapper_unset_task_icon_by_xid (TaskManagerApiWrapper *wrapper,
363 gint64 xid,
364 GError **error)
365{
366 TaskManagerApiWrapperPrivate *priv;
367 gboolean succeeded;
368 GValue window = {0};
369 GHashTable *hints;
370 const gchar *key = "icon-file";
371 GValue value = {0};
372
373 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
374
375 priv = wrapper->priv;
376
377 g_value_init (&window, G_TYPE_INT64);
378 g_value_set_int64 (&window, xid);
379
380 g_value_init (&value, G_TYPE_STRING);
381 g_value_set_string (&value, "");
382
383 hints = g_hash_table_new (g_str_hash, g_str_equal);
384 g_hash_table_insert (hints, (gpointer)key, &value);
385
386 succeeded = task_manager_update (priv->manager,
387 &window,
388 hints,
389 error);
390 g_value_unset (&window);
391 g_value_unset (&value);
392 g_hash_table_destroy (hints);
393
394 return succeeded;
395}
396
397gboolean
398task_manager_api_wrapper_set_info_by_xid (TaskManagerApiWrapper *wrapper,
399 gint64 xid,
400 gchar *info,
401 GError **error)
402{
403 TaskManagerApiWrapperPrivate *priv;
404 gboolean succeeded;
405 GValue window = {0};
406 GHashTable *hints;
407 const gchar *key = "message";
408 GValue value = {0};
409
410 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
411
412 priv = wrapper->priv;
413
414 g_value_init (&window, G_TYPE_INT64);
415 g_value_set_int64 (&window, xid);
416
417 g_value_init (&value, G_TYPE_STRING);
418 g_value_set_string (&value, info);
419
420 hints = g_hash_table_new (g_str_hash, g_str_equal);
421 g_hash_table_insert (hints, (gpointer)key, &value);
422
423 succeeded = task_manager_update (priv->manager,
424 &window,
425 hints,
426 error);
427 g_value_unset (&window);
428 g_value_unset (&value);
429 g_hash_table_destroy (hints);
430
431 return succeeded;
432}
433
434gboolean
435task_manager_api_wrapper_unset_info_by_xid (TaskManagerApiWrapper *wrapper,
436 gint64 xid,
437 GError **error)
438{
439 TaskManagerApiWrapperPrivate *priv;
440 gboolean succeeded;
441 GValue window = {0};
442 GHashTable *hints;
443 const gchar *key = "message";
444 GValue value = {0};
445
446 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
447
448 priv = wrapper->priv;
449
450 g_value_init (&window, G_TYPE_INT64);
451 g_value_set_int64 (&window, xid);
452
453 g_value_init (&value, G_TYPE_STRING);
454 g_value_set_string (&value, "");
455
456 hints = g_hash_table_new (g_str_hash, g_str_equal);
457 g_hash_table_insert (hints, (gpointer)key, &value);
458
459 succeeded = task_manager_update (priv->manager,
460 &window,
461 hints,
462 error);
463 g_value_unset (&window);
464 g_value_unset (&value);
465 g_hash_table_destroy (hints);
466
467 return succeeded;
468}
469
470gboolean
471task_manager_api_wrapper_set_progress_by_xid (TaskManagerApiWrapper *wrapper,
472 gint64 xid,
473 gint progress,
474 GError **error)
475{
476 TaskManagerApiWrapperPrivate *priv;
477 gboolean succeeded;
478 GValue window = {0};
479 GHashTable *hints;
480 const gchar *key = "message";
481 GValue value = {0};
482
483 g_return_val_if_fail (TASK_IS_MANAGER_API_WRAPPER (wrapper), FALSE);
484
485 priv = wrapper->priv;
486
487 g_value_init (&window, G_TYPE_INT64);
488 g_value_set_int64 (&window, xid);
489
490 //difference between old and new api
491 //unsetting progress indicator by setting progress to -1;
492 if (progress == 100) progress = -1;
493
494 g_value_init (&value, G_TYPE_INT);
495 g_value_set_int (&value, progress);
496
497 hints = g_hash_table_new (g_str_hash, g_str_equal);
498 g_hash_table_insert (hints, (gpointer)key, &value);
499
500 succeeded = task_manager_update (priv->manager,
501 &window,
502 hints,
503 error);
504 g_value_unset (&window);
505 g_value_unset (&value);
506 g_hash_table_destroy (hints);
507
508 return succeeded;
509}
0510
=== added file 'applets/taskmanager/task-manager-api-wrapper.h'
--- applets/taskmanager/task-manager-api-wrapper.h 1970-01-01 00:00:00 +0000
+++ applets/taskmanager/task-manager-api-wrapper.h 2009-06-26 11:00:10 +0000
@@ -0,0 +1,125 @@
1/*
2 * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by Hannes Verschore <hv1989@gmail.com>
17 */
18
19#ifndef _TASK_MANAGER_API_WRAPPER_H_
20#define _TASK_MANAGER_API_WRAPPER_H_
21
22#include <glib-object.h>
23#include <libawn/libawn.h>
24
25#include "task-manager.h"
26
27#define TASK_TYPE_MANAGER_API_WRAPPER (task_manager_api_wrapper_get_type ())
28
29#define TASK_MANAGER_API_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
30 TASK_TYPE_MANAGER_API_WRAPPER, TaskManagerApiWrapper))
31
32#define TASK_MANAGER_API_WRAPPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
33 TASK_TYPE_MANAGER_API_WRAPPER, TaskManagerApiWrapperClass))
34
35#define TASK_IS_MANAGER_API_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
36 TASK_TYPE_MANAGER_API_WRAPPER))
37
38#define TASK_IS_MANAGER_API_WRAPPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
39 TASK_TYPE_MANAGER_API_WRAPPER))
40
41#define TASK_MANAGER_API_WRAPPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
42 TASK_TYPE_MANAGER_API_WRAPPER, TaskManagerApiWrapperClass))
43
44typedef struct _TaskManagerApiWrapper TaskManagerApiWrapper;
45typedef struct _TaskManagerApiWrapperClass TaskManagerApiWrapperClass;
46typedef struct _TaskManagerApiWrapperPrivate TaskManagerApiWrapperPrivate;
47
48struct _TaskManagerApiWrapper
49{
50 GObject parent;
51
52 TaskManagerApiWrapperPrivate *priv;
53};
54
55struct _TaskManagerApiWrapperClass
56{
57 GObjectClass parent_class;
58};
59
60GType task_manager_api_wrapper_get_type (void) G_GNUC_CONST;
61
62TaskManagerApiWrapper * task_manager_api_wrapper_new (TaskManager *manager);
63
64/* name variants */
65
66gboolean
67task_manager_api_wrapper_set_task_icon_by_name (TaskManagerApiWrapper *wrapper,
68 gchar *name,
69 gchar *icon_path,
70 GError **error);
71
72gboolean
73task_manager_api_wrapper_unset_task_icon_by_name (TaskManagerApiWrapper *wrapper,
74 gchar *name,
75 GError **error);
76
77gboolean
78task_manager_api_wrapper_set_info_by_name (TaskManagerApiWrapper *wrapper,
79 gchar *name,
80 gchar *info,
81 GError **error);
82
83gboolean
84task_manager_api_wrapper_unset_info_by_name (TaskManagerApiWrapper *wrapper,
85 gchar *name,
86 GError **error);
87
88gboolean
89task_manager_api_wrapper_set_progress_by_name (TaskManagerApiWrapper *wrapper,
90 gchar *name,
91 gint progress,
92 GError **error);
93
94/* XID variants */
95
96gboolean
97task_manager_api_wrapper_set_task_icon_by_xid (TaskManagerApiWrapper *wrapper,
98 gint64 xid,
99 gchar *icon_path,
100 GError **error);
101
102gboolean
103task_manager_api_wrapper_unset_task_icon_by_xid (TaskManagerApiWrapper *wrapper,
104 gint64 xid,
105 GError **error);
106
107gboolean
108task_manager_api_wrapper_set_info_by_xid (TaskManagerApiWrapper *wrapper,
109 gint64 xid,
110 gchar *info,
111 GError **error);
112
113gboolean
114task_manager_api_wrapper_unset_info_by_xid (TaskManagerApiWrapper *wrapper,
115 gint64 xid,
116 GError **error);
117
118gboolean
119task_manager_api_wrapper_set_progress_by_xid (TaskManagerApiWrapper *wrapper,
120 gint64 xid,
121 gint progress,
122 GError **error);
123
124#endif /* _TASK_MANAGER_API_WRAPPER_H_ */
125
0126
=== modified file 'applets/taskmanager/task-manager.c'
--- applets/taskmanager/task-manager.c 2009-06-11 05:04:21 +0000
+++ applets/taskmanager/task-manager.c 2009-06-28 01:53:46 +0000
@@ -14,7 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
17 *17 * Hannes Verschore <hv1989@gmail.com>
18 */18 */
1919
20#include <stdio.h>20#include <stdio.h>
@@ -29,9 +29,9 @@
2929
30#include "task-drag-indicator.h"30#include "task-drag-indicator.h"
31#include "task-icon.h"31#include "task-icon.h"
32#include "task-launcher.h"32//#include "task-launcher.h"
33//#include "task-window.h"
33#include "task-settings.h"34#include "task-settings.h"
34#include "task-window.h"
35#include "xutils.h"35#include "xutils.h"
3636
37G_DEFINE_TYPE (TaskManager, task_manager, AWN_TYPE_APPLET)37G_DEFINE_TYPE (TaskManager, task_manager, AWN_TYPE_APPLET)
@@ -48,17 +48,15 @@
48 TaskSettings *settings;48 TaskSettings *settings;
49 WnckScreen *screen;49 WnckScreen *screen;
5050
51
52 /* Dragging properties */51 /* Dragging properties */
53 TaskIcon *dragged_icon;52 TaskIcon *dragged_icon;
54 TaskDragIndicator *drag_indicator;53 TaskDragIndicator *drag_indicator;
55 gint drag_timeout;54 gint drag_timeout;
5655
57 /* This is what the icons are packed into */56 /* This is what the icons are packed into */
58 GtkWidget *box;57 GtkWidget *box;
59 GSList *icons;58 GSList *icons;
60 GSList *windows;59 GSList *windows;
61 GSList *launchers;
62 GHashTable *win_table;60 GHashTable *win_table;
6361
64 /* Properties */62 /* Properties */
@@ -66,7 +64,7 @@
66 gboolean show_all_windows;64 gboolean show_all_windows;
67 gboolean only_show_launchers;65 gboolean only_show_launchers;
68 gboolean drag_and_drop;66 gboolean drag_and_drop;
69 gint grouping_mode;67 gint match_strength;
70};68};
7169
72enum70enum
@@ -77,30 +75,20 @@
77 PROP_ONLY_SHOW_LAUNCHERS,75 PROP_ONLY_SHOW_LAUNCHERS,
78 PROP_LAUNCHER_PATHS,76 PROP_LAUNCHER_PATHS,
79 PROP_DRAG_AND_DROP,77 PROP_DRAG_AND_DROP,
80 PROP_GROUPING_MODE78 PROP_MATCH_STRENGTH
81};
82
83enum
84{
85 GROUPING_NONE,
86 GROUPING_UTIL,
87 GROUPING_PID,
88 GROUPING_WNCK_APP,
89 GROUPING_WMCLASS,
90 GROUPING_END
91};79};
9280
93/* Forwards */81/* Forwards */
94static void ensure_layout (TaskManager *manager);82static void update_icon_visible (TaskManager *manager,
83 TaskIcon *icon);
84static void on_icon_visible_changed (TaskManager *manager,
85 TaskIcon *icon);
95static void on_window_opened (WnckScreen *screen, 86static void on_window_opened (WnckScreen *screen,
96 WnckWindow *window,87 WnckWindow *window,
97 TaskManager *manager);88 TaskManager *manager);
98static void on_active_window_changed (WnckScreen *screen, 89static void on_active_window_changed (WnckScreen *screen,
99 WnckWindow *old_window,90 WnckWindow *old_window,
100 TaskManager *manager);91 TaskManager *manager);
101static void on_wnck_window_closed (WnckScreen *screen,
102 WnckWindow *window,
103 TaskManager *manager);
104static void task_manager_set_show_all_windows (TaskManager *manager,92static void task_manager_set_show_all_windows (TaskManager *manager,
105 gboolean show_all);93 gboolean show_all);
106static void task_manager_set_show_only_launchers (TaskManager *manager, 94static void task_manager_set_show_only_launchers (TaskManager *manager,
@@ -110,14 +98,15 @@
110static void task_manager_set_drag_and_drop (TaskManager *manager, 98static void task_manager_set_drag_and_drop (TaskManager *manager,
111 gboolean drag_and_drop);99 gboolean drag_and_drop);
112100
113static void task_manager_set_grouping_mode (TaskManager *manager, 101static void task_manager_set_match_strength (TaskManager *manager,
114 gint drag_and_drop);102 gint drag_and_drop);
115103
116static void task_manager_orient_changed (AwnApplet *applet, 104static void task_manager_orient_changed (AwnApplet *applet,
117 AwnOrientation orient);105 AwnOrientation orient);
118static void task_manager_size_changed (AwnApplet *applet,106static void task_manager_size_changed (AwnApplet *applet,
119 gint size);107 gint size);
120108
109
121/* D&D Forwards */110/* D&D Forwards */
122static void _drag_dest_motion (TaskManager *manager,111static void _drag_dest_motion (TaskManager *manager,
123 gint x,112 gint x,
@@ -163,9 +152,9 @@
163 case PROP_DRAG_AND_DROP:152 case PROP_DRAG_AND_DROP:
164 g_value_set_boolean (value, manager->priv->drag_and_drop);153 g_value_set_boolean (value, manager->priv->drag_and_drop);
165 break;154 break;
166 155
167 case PROP_GROUPING_MODE:156 case PROP_MATCH_STRENGTH:
168 g_value_set_int (value, manager->priv->grouping_mode);157 g_value_set_int (value, manager->priv->match_strength);
169 break;158 break;
170159
171 default:160 default:
@@ -200,11 +189,10 @@
200 case PROP_DRAG_AND_DROP:189 case PROP_DRAG_AND_DROP:
201 task_manager_set_drag_and_drop (manager, 190 task_manager_set_drag_and_drop (manager,
202 g_value_get_boolean (value));191 g_value_get_boolean (value));
203 break;192
204 193 case PROP_MATCH_STRENGTH:
205 case PROP_GROUPING_MODE:194 task_manager_set_match_strength (manager,
206 task_manager_set_grouping_mode (manager, 195 g_value_get_int (value));
207 g_value_get_int (value));
208 break;196 break;
209197
210 198
@@ -250,8 +238,8 @@
250 AWN_CONFIG_CLIENT_DEFAULT_GROUP, "drag_and_drop",238 AWN_CONFIG_CLIENT_DEFAULT_GROUP, "drag_and_drop",
251 object, "drag_and_drop");239 object, "drag_and_drop");
252 awn_config_bridge_bind (bridge, priv->client, 240 awn_config_bridge_bind (bridge, priv->client,
253 AWN_CONFIG_CLIENT_DEFAULT_GROUP, "grouping_mode",241 AWN_CONFIG_CLIENT_DEFAULT_GROUP, "match_strength",
254 object, "grouping_mode");242 object, "match_strength");
255}243}
256244
257static void245static void
@@ -296,14 +284,14 @@
296 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);284 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
297 g_object_class_install_property (obj_class, PROP_DRAG_AND_DROP, pspec);285 g_object_class_install_property (obj_class, PROP_DRAG_AND_DROP, pspec);
298286
299 pspec = g_param_spec_int ("grouping_mode",287 pspec = g_param_spec_int ("match_strength",
300 "grouping_mode",288 "match_strength",
301 "Window Grouping Mode",289 "How radical matching is applied for grouping items",
302 0,290 0,
303 GROUPING_END-1,291 99,
304 0,292 0,
305 G_PARAM_READWRITE);293 G_PARAM_READWRITE);
306 g_object_class_install_property (obj_class, PROP_GROUPING_MODE, pspec);294 g_object_class_install_property (obj_class, PROP_MATCH_STRENGTH, pspec);
307 295
308 g_type_class_add_private (obj_class, sizeof (TaskManagerPrivate));296 g_type_class_add_private (obj_class, sizeof (TaskManagerPrivate));
309}297}
@@ -342,12 +330,6 @@
342 G_CALLBACK (on_window_opened), manager);330 G_CALLBACK (on_window_opened), manager);
343 g_signal_connect (priv->screen, "active-window-changed", 331 g_signal_connect (priv->screen, "active-window-changed",
344 G_CALLBACK (on_active_window_changed), manager);332 G_CALLBACK (on_active_window_changed), manager);
345 g_signal_connect_swapped (priv->screen, "active-workspace-changed",
346 G_CALLBACK (ensure_layout), manager);
347 g_signal_connect_swapped (priv->screen, "viewports-changed",
348 G_CALLBACK (ensure_layout), manager);
349 g_signal_connect (priv->screen, "window-closed",
350 G_CALLBACK(on_wnck_window_closed),manager);
351}333}
352334
353AwnApplet *335AwnApplet *
@@ -411,80 +393,15 @@
411}393}
412394
413/*395/*
414 * The guts of the show or hide logic
415 */
416static void
417ensure_layout (TaskManager *manager)
418{
419 TaskManagerPrivate *priv = manager->priv;
420 WnckWorkspace *space;
421 GSList *i;
422
423 space = wnck_screen_get_active_workspace (priv->screen);
424
425 if (!WNCK_IS_WORKSPACE (space))
426 {
427 return;
428 }
429
430 /* Go through all the TaskIcons to make sure that they should be shown */
431 for (i = priv->icons; i; i = i->next)
432 {
433 TaskIcon *icon = i->data;
434
435 if (!TASK_IS_ICON (icon))
436 continue;
437
438 /* If the icon gets dragged, it shouldn't be shown */
439 if( icon == priv->dragged_icon )
440 {
441 gtk_widget_hide (GTK_WIDGET (icon));
442 continue;
443 }
444
445 /* Show launchers regardless of workspace */
446 if (task_icon_is_launcher (icon))
447 {
448 gtk_widget_show (GTK_WIDGET (icon));
449 continue;
450 }
451
452 /* FIXME: Add support for start-up notification icons too */
453
454 /*
455 * Only show normal window icons if a) the use wants to see them and b) if
456 * they are on the correct workspace
457 */
458 if (priv->only_show_launchers)
459 {
460 gtk_widget_hide (GTK_WIDGET (icon));
461 }
462 else if (task_icon_is_skip_taskbar (icon))
463 {
464 gtk_widget_hide (GTK_WIDGET (icon));
465 }
466 else if (task_icon_is_in_viewport (icon, space))
467 {
468 gtk_widget_show (GTK_WIDGET (icon));
469 }
470 else if (priv->show_all_windows)
471 {
472 gtk_widget_show (GTK_WIDGET (icon));
473 }
474 else
475 {
476 gtk_widget_hide (GTK_WIDGET (icon));
477 }
478 }
479
480 /* Hide drag_indicator if there is no AwnIcon currently dragged */
481 if(priv->dragged_icon == NULL)
482 gtk_widget_hide (GTK_WIDGET(priv->drag_indicator));
483}
484
485/*
486 * WNCK_SCREEN CALLBACKS396 * WNCK_SCREEN CALLBACKS
487 */397 */
398
399/**
400 * This signal is only connected for windows which were of type normal/utility
401 * and were initially "skip-tasklist". If they are not skip-tasklist anymore
402 * we treat them as newly opened windows.
403 * STATE: done
404 */
488static void405static void
489on_window_state_changed (WnckWindow *window,406on_window_state_changed (WnckWindow *window,
490 WnckWindowState changed_mask,407 WnckWindowState changed_mask,
@@ -493,10 +410,7 @@
493{410{
494 g_return_if_fail (TASK_IS_MANAGER (manager));411 g_return_if_fail (TASK_IS_MANAGER (manager));
495412
496 /* This signal is only connected for windows which were of type normal/utility413 // test if they don't skip-tasklist anymore
497 * and were initially "skip-tasklist". If they are not skip-tasklist anymore
498 * we treat them as newly opened windows
499 */
500 if (!wnck_window_is_skip_tasklist (window))414 if (!wnck_window_is_skip_tasklist (window))
501 {415 {
502 g_signal_handlers_disconnect_by_func (window, 416 g_signal_handlers_disconnect_by_func (window,
@@ -506,315 +420,145 @@
506 }420 }
507}421}
508422
423/**
424 * The active WnckWindow has changed.
425 * Retrieve the TaskWindows and update there active state
426 */
509static void 427static void
510on_wnck_window_closed (WnckScreen *screen, WnckWindow *window, TaskManager *manager)428on_active_window_changed (WnckScreen *screen,
511{429 WnckWindow *old_window,
512 GSList *i; 430 TaskManager *manager)
513 TaskManagerPrivate *priv = manager->priv; 431{
514 for (i = priv->icons; i; i = i->next)432 TaskManagerPrivate *priv;
515 {433 WnckWindow *active = NULL;
516 TaskIcon *taskicon = i->data;434 TaskWindow *taskwin = NULL;
517 if (!TASK_IS_ICON (taskicon))435 TaskWindow *old_taskwin = NULL;
518 continue;436
519 task_icon_remove_window (taskicon, window); 437 g_return_if_fail (TASK_IS_MANAGER (manager));
520 }438 priv = manager->priv;
521}439
522440 active = wnck_screen_get_active_window (priv->screen);
523static gboolean441
524check_wmclass(TaskWindow *taskwin,gchar * win_res_name, gchar *win_class_name)442 if (WNCK_IS_WINDOW (old_window))
525{443 old_taskwin = (TaskWindow *)g_object_get_qdata (G_OBJECT (old_window),
526 gboolean result;444 win_quark);
527 gchar *temp;445 if (WNCK_IS_WINDOW (active))
528 gchar *res_name = NULL;446 taskwin = (TaskWindow *)g_object_get_qdata (G_OBJECT (active), win_quark);
529 gchar *class_name = NULL;447
530448 if (TASK_IS_WINDOW (old_taskwin))
531 _wnck_get_wmclass (task_window_get_xid (taskwin), &res_name, &class_name);449 task_window_set_is_active (old_taskwin, FALSE);
532 if (res_name)450 if (TASK_IS_WINDOW (taskwin))
533 {451 task_window_set_is_active (taskwin, TRUE);
534 temp = res_name;452}
535 res_name = g_utf8_strdown (temp, -1);453
536 g_free (temp);454/**
537 }455 * When the property 'show_all_windows' is False,
538 456 * workspace switches are monitored. Whenever one happens
539 if (class_name)457 * all TaskWindows are notified.
540 {458 */
541 temp = class_name;459static void
542 class_name = g_utf8_strdown (temp, -1);460on_workspace_changed (TaskManager *manager) //... has more arguments
543 g_free (temp);461{
544 }462 TaskManagerPrivate *priv;
545 result = ( 463 GSList *w;
546 (g_strcmp0 (res_name,win_res_name)==0) 464 WnckWorkspace *space;
547 ||465
548 (g_strcmp0 (class_name,win_class_name)==0)466 g_return_if_fail (TASK_IS_MANAGER (manager));
549 );467
550 g_free (res_name);468 priv = manager->priv;
551 g_free (class_name);469 space = wnck_screen_get_active_workspace (priv->screen);
552470
553 return result;471 for (w = priv->windows; w; w = w->next)
554}472 {
555473 TaskWindow *window = w->data;
556static gboolean474
557try_to_place_window_by_wmclass (TaskManager *manager, WnckWindow *window)475 if (!TASK_IS_WINDOW (window)) continue;
558{476
559 GSList *i;477 task_window_set_active_workspace (window, space);
560 TaskManagerPrivate *priv = manager->priv;478 }
561 gchar *temp;479}
562 gchar *res_name = NULL;480
563 gchar *class_name = NULL;481/*
564482 * TASK_ICON CALLBACKS
565 /* Grab the appropriete info */483 */
566 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);484
567485static void
568 if (res_name)486update_icon_visible (TaskManager *manager, TaskIcon *icon)
569 { 487{
570 temp = res_name;488 TaskManagerPrivate *priv;
571 res_name = g_utf8_strdown (temp, -1);489
572 g_free (temp);490 g_return_if_fail (TASK_IS_MANAGER (manager));
573 }491
574 492 priv = manager->priv;
575 if (class_name)493
576 {494 if (task_icon_is_visible (icon))
577 temp = class_name;495 {
578 class_name = g_utf8_strdown (temp, -1);496 if (priv->only_show_launchers && !task_icon_contains_launcher (icon))
579 g_free (temp);497 {
580 }498 gtk_widget_hide (GTK_WIDGET (icon));
581 499 }
582 for (i = priv->icons; i; i = i->next)500 else
583 {501 {
584 TaskIcon *taskicon = i->data;502 if (!GTK_WIDGET_VISIBLE (icon))
585 TaskWindow *taskwin = NULL;503 {
586 504 awn_effects_start_ex (awn_overlayable_get_effects (AWN_OVERLAYABLE (icon)),
587 if (!TASK_IS_ICON (taskicon))505 AWN_EFFECT_OPENING, 1, FALSE, FALSE);
588 continue;506 gtk_widget_show (GTK_WIDGET (icon));
589 507 }
590 taskwin = task_icon_get_window(taskicon);508 }
591509 }
592 if ( check_wmclass (taskwin,res_name,class_name) )510 else
593 {511 {
594 task_icon_append_window (taskicon, task_window_new (window));512 gtk_widget_hide (GTK_WIDGET (icon));
595 g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);513 }
596 g_free (res_name);514}
597 g_free (class_name);515
598 return TRUE;516static void
599 }517on_icon_visible_changed (TaskManager *manager, TaskIcon *icon)
600 }518{
601519 g_return_if_fail (TASK_IS_MANAGER (manager));
602 g_free (res_name);520
603 g_free (class_name);521 update_icon_visible (manager, icon);
604 return FALSE; 522}
605}523
606524/**
607static gboolean525 * This function gets called whenever a task-window gets finalized.
608try_to_place_window_by_wnck_app (TaskManager *manager, WnckWindow *window)526 * It removes the task-window from the list.
609{527 * State: done
610 TaskManagerPrivate *priv = manager->priv;528 */
611 GSList *i;529static void
612 WnckApplication *taskwin_app;530window_closed (TaskManager *manager, GObject *old_item)
613531{
614 for (i = priv->icons; i; i = i->next)532 TaskManagerPrivate *priv;
615 {533
616 TaskIcon *taskicon = i->data;534 g_return_if_fail (TASK_IS_MANAGER (manager));
617 TaskWindow *taskwin = NULL;535
618 536 priv = manager->priv;
619 if (!TASK_IS_ICON (taskicon))537 priv->windows = g_slist_remove (priv->windows, old_item);
620 continue;538}
621 539
622 taskwin = task_icon_get_window(taskicon);540/**
623 taskwin_app = task_window_get_application (taskwin);541 * This function gets called whenever a task-icon gets finalized.
624 if ( taskwin_app && (taskwin_app == wnck_window_get_application (window)))542 * It removes the task-icon from the gslist and update layout
625 {543 * (so it gets removed from the bar)
626 task_icon_append_window (taskicon, task_window_new (window));544 * State: done
627 g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);545 */
628 return TRUE;
629 }
630 }
631
632 return FALSE;
633}
634
635static gboolean
636try_to_place_window_by_pid (TaskManager *manager, WnckWindow *window)
637{
638 TaskManagerPrivate *priv = manager->priv;
639 GSList *i;
640 gint taskwin_pid = -1;
641 gint matches = 0;
642
643 for (i = priv->icons; i; i = i->next)
644 {
645 TaskIcon *taskicon = i->data;
646 TaskWindow *taskwin = NULL;
647
648 if (!TASK_IS_ICON (taskicon))
649 continue;
650
651 taskwin = task_icon_get_window(taskicon);
652 taskwin_pid = task_window_get_pid (taskwin);
653 if ( taskwin_pid && (taskwin_pid == wnck_window_get_pid (window)))
654 {
655 if (matches)
656 {
657 task_icon_append_window (taskicon, task_window_new (window));
658 g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);
659 return TRUE;
660 }
661 matches++;
662 }
663 }
664 return FALSE;
665}
666
667static gboolean
668try_to_place_util_window (TaskManager *manager, WnckWindow *window)
669{
670 WnckWindowType type = wnck_window_get_window_type (window);
671 TaskManagerPrivate *priv = manager->priv;
672 GSList *w;
673 gint taskwin_pid = -1;
674 gint matches = 0;
675
676 if ( (type != WNCK_WINDOW_UTILITY) && (type != WNCK_WINDOW_DIALOG) )
677 {
678 return FALSE;
679 }
680
681 for (w = priv->icons; w; w = w->next)
682 {
683 TaskIcon *taskicon = w->data;
684 TaskWindow *taskwin = NULL;
685
686 if (!TASK_IS_ICON (taskicon))
687 continue;
688
689 taskwin = task_icon_get_window(taskicon);
690 taskwin_pid = task_window_get_pid (taskwin);
691 if ( taskwin_pid && (taskwin_pid == wnck_window_get_pid (window)))
692 {
693 if (matches)
694 {
695 task_icon_append_window (taskicon, task_window_new (window));
696 g_object_set_qdata (G_OBJECT (window), win_quark, taskwin);
697 return TRUE;
698 }
699 matches++;
700 }
701 }
702 return FALSE;
703}
704
705static gboolean
706try_to_place_window (TaskManager *manager, WnckWindow *window)
707{
708 TaskManagerPrivate *priv = manager->priv;
709 gboolean result = FALSE;
710 switch(priv->grouping_mode)
711 {
712 case GROUPING_WMCLASS: /*Fall through*/
713 result =result?result:try_to_place_window_by_wmclass(manager,window);
714 case GROUPING_WNCK_APP:/*Fall through*/
715 result =result?result:try_to_place_window_by_wnck_app(manager,window);
716 case GROUPING_PID: /*Don't Fall through*/
717 result =result?result:try_to_place_window_by_pid(manager,window);
718 break;
719 case GROUPING_UTIL:/*Don't Fall through*/
720 result =result?result:try_to_place_util_window(manager,window);
721 break;
722 case GROUPING_NONE:
723 break;
724 default:
725 g_assert_not_reached();
726 }
727 return result;
728}
729
730static gboolean
731try_to_match_window_to_launcher (TaskManager *manager, WnckWindow *window)
732{
733 TaskManagerPrivate *priv = manager->priv;
734 GSList *l;
735 gchar *temp;
736 gchar *res_name = NULL;
737 gchar *class_name = NULL;
738 gint pid;
739 gboolean res = FALSE;
740
741 /* Grab the appropriete info */
742 pid = wnck_window_get_pid (window);
743 _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name);
744
745 if (res_name)
746 {
747 temp = res_name;
748 res_name = g_utf8_strdown (temp, -1);
749 g_free (temp);
750 }
751
752 if (class_name)
753 {
754 temp = class_name;
755 class_name = g_utf8_strdown (temp, -1);
756 g_free (temp);
757 }
758
759 /* Try and match */
760 for (l = priv->launchers; l; l = l->next)
761 {
762 TaskLauncher *launcher = l->data;
763
764 if (!TASK_IS_LAUNCHER (launcher))
765 continue;
766
767 if (task_launcher_has_window (launcher))
768 continue;
769
770 if (!task_launcher_try_match (launcher, pid, res_name, class_name))
771 continue;
772
773 /* As it matched this launcher, we can set the window to the launcher and
774 * get on with it
775 */
776 task_launcher_set_window (launcher, window);
777 g_object_set_qdata (G_OBJECT (window), win_quark, launcher);
778 res = TRUE;
779 }
780 g_free (res_name);
781 g_free (class_name);
782
783 return res;
784}
785
786static gboolean
787try_to_match_window_to_sn_context (TaskManager *manager, WnckWindow *window)
788{
789 return FALSE;
790}
791
792static void
793window_closed (TaskManager *manager, GObject *old_window)
794{
795 TaskManagerPrivate *priv;
796
797 g_return_if_fail (TASK_IS_MANAGER (manager));
798 priv = manager->priv;
799
800 priv->windows = g_slist_remove (priv->windows, old_window);
801
802 ensure_layout (manager);
803}
804
805static void546static void
806icon_closed (TaskManager *manager, GObject *old_icon)547icon_closed (TaskManager *manager, GObject *old_icon)
807{548{
808 TaskManagerPrivate *priv;549 TaskManagerPrivate *priv;
809550
810 g_return_if_fail (TASK_IS_MANAGER (manager));551 g_return_if_fail (TASK_IS_MANAGER (manager));
552
811 priv = manager->priv;553 priv = manager->priv;
812
813 priv->icons = g_slist_remove (priv->icons, old_icon);554 priv->icons = g_slist_remove (priv->icons, old_icon);
814
815 ensure_layout (manager);
816}555}
817556
557/**
558 * Whenever a new window gets opened it will try to place it
559 * in an awn-icon or will create a new awn-icon.
560 * State: adjusted
561 */
818static void 562static void
819on_window_opened (WnckScreen *screen, 563on_window_opened (WnckScreen *screen,
820 WnckWindow *window,564 WnckWindow *window,
@@ -822,13 +566,17 @@
822{566{
823 TaskManagerPrivate *priv;567 TaskManagerPrivate *priv;
824 GtkWidget *icon;568 GtkWidget *icon;
825 TaskWindow *taskwin;569 TaskItem *item;
826 WnckWindowType type;570 WnckWindowType type;
571 GSList *w;
572 TaskIcon *match = NULL;
573 gint match_score = 0;
574 gint max_match_score = 0;
827575
828 g_return_if_fail (TASK_IS_MANAGER (manager));576 g_return_if_fail (TASK_IS_MANAGER (manager));
829 g_return_if_fail (WNCK_IS_WINDOW (window));577 g_return_if_fail (WNCK_IS_WINDOW (window));
578
830 priv = manager->priv;579 priv = manager->priv;
831
832 type = wnck_window_get_window_type (window);580 type = wnck_window_get_window_type (window);
833581
834 switch (type)582 switch (type)
@@ -855,84 +603,52 @@
855 return;603 return;
856 }604 }
857605
858 /*606 // create a new TaskWindow containing the WnckWindow
859 */607 item = task_window_new (window);
860 608 g_object_set_qdata (G_OBJECT (window), win_quark, TASK_WINDOW (item));
861 if ( priv->grouping_mode && try_to_place_window (manager,window))609
862 {610 priv->windows = g_slist_append (priv->windows, item);
863 g_debug ("WINDOW PLACED: %s", wnck_window_get_name (window));611 g_object_weak_ref (G_OBJECT (item), (GWeakNotify)window_closed, manager);
864 return;612
865 }613 // see if there is a icon that matches
866 614 for (w = priv->icons; w; w = w->next)
867 /* Okay, time to check the launchers if we can get a match */615 {
868 if (try_to_match_window_to_launcher (manager, window))616 TaskIcon *taskicon = w->data;
869 {617
870 g_debug ("WINDOW MATCHED: %s", wnck_window_get_name (window));618 if (!TASK_IS_ICON (taskicon)) continue;
871 return;619
872 }620 match_score = task_icon_match_item (taskicon, item);
873621 if (match_score > max_match_score)
874 /* Try the startup-notification windows */622 {
875 if (try_to_match_window_to_sn_context (manager, window))623 max_match_score = match_score;
876 {624 match = taskicon;
877 g_debug ("WINDOW STARTUP: %s", wnck_window_get_name (window));625 }
878 return;626 }
879 }627
880628 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);
881 /* 629
882 * We couldn't append the window to a pre-existing TaskWindow, so we'll need630 if (max_match_score > 99-priv->match_strength)
883 * to make a new one631 {
884 */632 task_icon_append_item (match, item);
885 taskwin = task_window_new (window);633 }
886 priv->windows = g_slist_append (priv->windows, taskwin);634 else
887 g_object_weak_ref (G_OBJECT (taskwin), (GWeakNotify)window_closed, manager);635 {
888 g_object_set_qdata (G_OBJECT (window), win_quark, taskwin); 636 icon = task_icon_new();
889 637 task_icon_append_item (TASK_ICON (icon), item);
890 /* If we've come this far, the window deserves a spot on the task-manager!638
891 * Time to create a TaskIcon for it639 priv->icons = g_slist_append (priv->icons, icon);
892 */640 gtk_container_add (GTK_CONTAINER (priv->box), icon);
893 icon = task_icon_new_for_window (taskwin);641
894 gtk_container_add (GTK_CONTAINER (priv->box), icon);642 /* reordening through D&D */
895 gtk_widget_show (icon);643 if(priv->drag_and_drop)
896644 _drag_add_signals(manager, icon);
897 priv->icons = g_slist_append (priv->icons, icon);645
898 g_signal_connect_swapped (icon, "ensure_layout", 646 g_object_weak_ref (G_OBJECT (icon), (GWeakNotify)icon_closed, manager);
899 G_CALLBACK (ensure_layout), manager);647 g_signal_connect_swapped (icon, "visible-changed",
900648 G_CALLBACK (on_icon_visible_changed), manager);
901 /* reordening through D&D */649
902 if(priv->drag_and_drop)650 update_icon_visible (manager, TASK_ICON (icon));
903 _drag_add_signals(manager, icon);651 }
904
905 g_object_weak_ref (G_OBJECT (icon), (GWeakNotify)icon_closed, manager);
906
907 /* Finally, make sure all is well on the taskbar */
908 ensure_layout (manager);
909}
910
911static void
912on_active_window_changed (WnckScreen *screen,
913 WnckWindow *old_window,
914 TaskManager *manager)
915{
916 TaskManagerPrivate *priv;
917 WnckWindow *active = NULL;
918 TaskWindow *taskwin = NULL;
919 TaskWindow *old_taskwin = NULL;
920
921 g_return_if_fail (TASK_IS_MANAGER (manager));
922 priv = manager->priv;
923
924 active = wnck_screen_get_active_window (priv->screen);
925
926 if (WNCK_IS_WINDOW (old_window))
927 old_taskwin = (TaskWindow *)g_object_get_qdata (G_OBJECT (old_window),
928 win_quark);
929 if (WNCK_IS_WINDOW (active))
930 taskwin = (TaskWindow *)g_object_get_qdata (G_OBJECT (active), win_quark);
931
932 if (TASK_IS_WINDOW (old_taskwin))
933 task_window_set_is_active (old_taskwin, FALSE);
934 if (TASK_IS_WINDOW (taskwin))
935 task_window_set_is_active (taskwin, TRUE);
936}652}
937653
938/*654/*
@@ -942,26 +658,86 @@
942task_manager_set_show_all_windows (TaskManager *manager,658task_manager_set_show_all_windows (TaskManager *manager,
943 gboolean show_all)659 gboolean show_all)
944{660{
661 TaskManagerPrivate *priv;
662 GSList *w;
663 WnckWorkspace *space = NULL;
664
945 g_return_if_fail (TASK_IS_MANAGER (manager));665 g_return_if_fail (TASK_IS_MANAGER (manager));
666
667 priv = manager->priv;
668
669 if (priv->show_all_windows == show_all) return;
670
946 manager->priv->show_all_windows = show_all;671 manager->priv->show_all_windows = show_all;
947672
948 ensure_layout (manager);673 if (show_all)
949674 {
675 // Remove signals of workspace changes
676 g_signal_handlers_disconnect_by_func(priv->screen,
677 G_CALLBACK (on_workspace_changed),
678 manager);
679
680 // Set workspace to NULL, so TaskWindows aren't tied to workspaces anymore
681 space = NULL;
682 }
683 else
684 {
685 // Add signals to WnckScreen for workspace changes
686 g_signal_connect_swapped (priv->screen, "viewports-changed",
687 G_CALLBACK (on_workspace_changed), manager);
688 g_signal_connect_swapped (priv->screen, "active-workspace-changed",
689 G_CALLBACK (on_workspace_changed), manager);
690
691 // Retrieve the current active workspace
692 space = wnck_screen_get_active_workspace (priv->screen);
693 }
694
695 /* Update the workspace for every TaskWindow.
696 * NULL if the windows aren't tied to a workspace anymore */
697 for (w = priv->windows; w; w = w->next)
698 {
699 TaskWindow *window = w->data;
700 if (!TASK_IS_WINDOW (window)) continue;
701 task_window_set_active_workspace (window, space);
702 }
703
950 g_debug ("%s", show_all ? "showing all windows":"not showing all windows");704 g_debug ("%s", show_all ? "showing all windows":"not showing all windows");
951}705}
952706
707/**
708 * The property 'show_only_launchers' changed.
709 * So update the property and update the visiblity of every icon.
710 */
953static void711static void
954task_manager_set_show_only_launchers (TaskManager *manager, 712task_manager_set_show_only_launchers (TaskManager *manager,
955 gboolean show_only)713 gboolean only_show_launchers)
956{714{
715 TaskManagerPrivate *priv;
716 GSList *w;
717
957 g_return_if_fail (TASK_IS_MANAGER (manager));718 g_return_if_fail (TASK_IS_MANAGER (manager));
958 manager->priv->only_show_launchers = show_only;719
959720 priv = manager->priv;
960 ensure_layout (manager);721 priv->only_show_launchers = only_show_launchers;
961722
962 g_debug ("%s", show_only ? "only show launchers":"show everything");723 for (w = priv->icons; w; w = w->next)
724 {
725 TaskIcon *icon = w->data;
726
727 if (!TASK_IS_ICON (icon)) continue;
728
729 update_icon_visible (manager, icon);
730 }
731
732 g_debug ("%s", only_show_launchers ? "only show launchers":"show everything");
963}733}
964734
735/**
736 * Checks when launchers got added/removed in the list in gconf/file.
737 * It removes the launchers from the task-icons and add those
738 * that aren't already on the bar.
739 * State: partial - TODO: refresh of a list
740 */
965static void 741static void
966task_manager_refresh_launcher_paths (TaskManager *manager,742task_manager_refresh_launcher_paths (TaskManager *manager,
967 GSList *list)743 GSList *list)
@@ -979,41 +755,23 @@
979 for (d = list; d; d = d->next)755 for (d = list; d; d = d->next)
980 {756 {
981 GtkWidget *icon;757 GtkWidget *icon;
982 TaskLauncher *launcher = NULL;758 TaskItem *launcher = NULL;
983 GSList *l;
984
985 for (l = priv->launchers; l; l = l->next)
986 {
987 TaskLauncher *launch = l->data;
988
989 if (!TASK_IS_LAUNCHER (launch))
990 continue;
991
992 if (g_strcmp0 (d->data, task_launcher_get_desktop_path (launch)) == 0)
993 {
994 launcher = launch;
995 break;
996 }
997 }
998
999 if (TASK_IS_LAUNCHER (launcher))
1000 continue;
1001759
1002 launcher = task_launcher_new_for_desktop_file (d->data);760 launcher = task_launcher_new_for_desktop_file (d->data);
1003761
1004 if (!launcher)762 if (!launcher) continue;
1005 continue;
1006763
1007 priv->launchers = g_slist_append (priv->launchers, launcher);764 icon = task_icon_new ();
1008 765 task_icon_append_item (TASK_ICON (icon), launcher);
1009 icon = task_icon_new_for_window (TASK_WINDOW (launcher));
1010 gtk_container_add (GTK_CONTAINER (priv->box), icon);766 gtk_container_add (GTK_CONTAINER (priv->box), icon);
1011 gtk_widget_show (icon);
1012767
1013 priv->icons = g_slist_append (priv->icons, icon);768 priv->icons = g_slist_append (priv->icons, icon);
1014 g_signal_connect_swapped (icon, "ensure_layout", 769
1015 G_CALLBACK (ensure_layout), manager);
1016 g_object_weak_ref (G_OBJECT (icon), (GWeakNotify)icon_closed, manager);770 g_object_weak_ref (G_OBJECT (icon), (GWeakNotify)icon_closed, manager);
771 g_signal_connect_swapped (icon, "visible-changed",
772 G_CALLBACK (on_icon_visible_changed), manager);
773
774 update_icon_visible (manager, TASK_ICON (icon));
1017775
1018 /* reordening through D&D */776 /* reordening through D&D */
1019 if(priv->drag_and_drop)777 if(priv->drag_and_drop)
@@ -1023,19 +781,14 @@
1023 for (d = list; d; d = d->next)781 for (d = list; d; d = d->next)
1024 g_free (d->data);782 g_free (d->data);
1025 g_slist_free (list);783 g_slist_free (list);
1026
1027 /* Finally, make sure all is well on the taskbar */
1028 ensure_layout (manager);
1029}784}
1030785
1031static void786static void
1032task_manager_set_grouping_mode (TaskManager *manager,787task_manager_set_match_strength (TaskManager *manager,
1033 gint grouping_mode)788 gint match_strength)
1034{789{
1035 g_return_if_fail (TASK_IS_MANAGER (manager));790 g_return_if_fail (TASK_IS_MANAGER (manager));
1036 manager->priv->grouping_mode = grouping_mode;791 manager->priv->match_strength = match_strength;
1037
1038 ensure_layout (manager);
1039}792}
1040793
1041static void794static void
@@ -1049,37 +802,189 @@
1049802
1050 priv->drag_and_drop = drag_and_drop;803 priv->drag_and_drop = drag_and_drop;
1051804
805 //connect or dissconnect the dragging signals
806 for (i = priv->icons; i; i = i->next)
807 {
808 TaskIcon *icon = i->data;
809
810 if (!TASK_IS_ICON (icon)) continue;
811
812 if(drag_and_drop)
813 {
814 _drag_add_signals (manager, GTK_WIDGET(icon));
815 }
816 else
817 {
818 //FIXME: Stop any ongoing move
819 _drag_remove_signals (manager, GTK_WIDGET(icon));
820 }
821 }
1052 if(drag_and_drop)822 if(drag_and_drop)
1053 {823 {
1054 //connect to the dragging signals
1055 for (i = priv->icons; i; i = i->next)
1056 {
1057 TaskIcon *icon = i->data;
1058
1059 if (!TASK_IS_ICON (icon)) continue;
1060
1061 _drag_add_signals (manager, GTK_WIDGET(icon));
1062 }
1063 _drag_add_signals (manager, GTK_WIDGET(priv->drag_indicator));824 _drag_add_signals (manager, GTK_WIDGET(priv->drag_indicator));
1064 }825 }
1065 else826 else
1066 {827 {
1067 //disconnect the dragging signals
1068 for (i = priv->icons; i; i = i->next)
1069 {
1070 TaskIcon *icon = i->data;
1071
1072 if (!TASK_IS_ICON (icon)) continue;
1073
1074 _drag_remove_signals (manager, GTK_WIDGET(icon));
1075 }
1076 _drag_remove_signals (manager, GTK_WIDGET(priv->drag_indicator));828 _drag_remove_signals (manager, GTK_WIDGET(priv->drag_indicator));
1077 //FIXME: Stop any ongoing move
1078 }829 }
1079830
1080 g_debug("%s", drag_and_drop?"D&D is on":"D&D is off");831 g_debug("%s", drag_and_drop?"D&D is on":"D&D is off");
1081}832}
1082833
834/**
835 * D-BUS functionality
836 */
837
838gboolean
839task_manager_get_capabilities (TaskManager *manager,
840 GStrv *supported_keys,
841 GError **error)
842{
843 const gchar *known_keys[] =
844 {
845 "icon-file",
846 "progress",
847 "message",
848 "visible",
849 NULL
850 };
851
852 *supported_keys = g_strdupv ((char **)known_keys);
853
854 return TRUE;
855}
856
857/**
858 * Find the window that corresponds to the given window name.
859 * First try to match the application name, then the normal name.
860 */
861static TaskWindow*
862_match_name (TaskManager *manager, const gchar* window)
863{
864 TaskManagerPrivate *priv;
865 WnckApplication *wnck_app = NULL;
866 const gchar *name = NULL;
867 GSList *w;
868
869 g_return_val_if_fail (TASK_IS_MANAGER (manager), FALSE);
870 priv = manager->priv;
871
872 for (w = priv->windows; w; w = w->next)
873 {
874 TaskWindow *taskwindow = w->data;
875
876 if (!TASK_IS_WINDOW (taskwindow)) continue;
877
878 wnck_app = task_window_get_application (taskwindow);
879 if (WNCK_IS_APPLICATION(wnck_app))
880 {
881 name = wnck_application_get_name(wnck_app);
882 if (name && strcmp (window, name) == 0)
883 return taskwindow;
884 }
885
886 name = task_window_get_name (taskwindow);
887 if (name && strcmp (window, name) == 0)
888 return taskwindow;
889 }
890
891 return NULL;
892}
893
894/**
895 * Find the window that corresponds to the given xid
896 */
897static TaskWindow*
898_match_xid (TaskManager *manager, gint64 window)
899{
900 TaskManagerPrivate *priv;
901 gint64 xid;
902 GSList *w;
903
904 g_return_val_if_fail (TASK_IS_MANAGER (manager), FALSE);
905 priv = manager->priv;
906
907 for (w = priv->windows; w; w = w->next)
908 {
909 TaskWindow *taskwindow = w->data;
910
911 if (!TASK_IS_WINDOW (taskwindow)) continue;
912
913 xid = task_window_get_xid (taskwindow);
914 if (xid && window == xid)
915 return taskwindow;
916 }
917
918 return NULL;
919}
920
921gboolean
922task_manager_update (TaskManager *manager,
923 GValue *window,
924 GHashTable *hints, /* mappings from string to GValue */
925 GError **error)
926{
927 TaskManagerPrivate *priv;
928 TaskWindow *matched_window = NULL;
929
930 g_return_val_if_fail (TASK_IS_MANAGER (manager), FALSE);
931
932 priv = manager->priv;
933
934 if (G_VALUE_HOLDS_STRING (window))
935 {
936 matched_window = _match_name (manager, g_value_get_string (window));
937 }
938 else if (G_VALUE_HOLDS_INT64 (window))
939 {
940 matched_window = _match_xid (manager, g_value_get_int64 (window));
941 }
942 else
943 {
944 //G_ERROR stuff
945 return FALSE;
946 }
947
948 if (matched_window)
949 {
950 GHashTableIter iter;
951 gpointer key, value;
952
953 g_hash_table_iter_init (&iter, hints);
954 while (g_hash_table_iter_next (&iter, &key, &value))
955 {
956 gchar *key_name = (gchar *)key;
957 if (strcmp ("icon-file", key_name) == 0)
958 {
959
960 }
961 else if (strcmp ("progress", key_name) == 0)
962 {
963
964 }
965 else if (strcmp ("message", key_name) == 0)
966 {
967
968 }
969 else if (strcmp ("visible", key_name) == 0)
970 {
971
972 }
973 else
974 {
975 g_debug ("Taskmanager doesn't understand the key: %s", key_name);
976 }
977 }
978
979 return TRUE;
980 }
981 else
982 {
983 return FALSE;
984 }
985}
986
987
1083/*988/*
1084 * Position Icons through dragging989 * Position Icons through dragging
1085 */990 */
@@ -1212,11 +1117,11 @@
1212 TaskManagerPrivate *priv;1117 TaskManagerPrivate *priv;
1213 gint move_to;1118 gint move_to;
1214 GList* childs;1119 GList* childs;
1215 GSList* d;1120 //GSList* d;
1216 GSList* launchers = NULL;1121 //GSList* launchers = NULL;
1217 TaskLauncher* launcher;1122 //TaskLauncher* launcher;
1218 gchar* launcher_path;1123 //gchar* launcher_path;
1219 GError *err = NULL;1124 //GError *err = NULL;
12201125
1221 g_return_if_fail (TASK_IS_MANAGER (manager));1126 g_return_if_fail (TASK_IS_MANAGER (manager));
12221127
@@ -1252,7 +1157,7 @@
1252 // Update the position in the config (Gconf) if the AwnIcon is a launcher.1157 // Update the position in the config (Gconf) if the AwnIcon is a launcher.
1253 // FIXME: support multiple launchers in one AwnIcon?1158 // FIXME: support multiple launchers in one AwnIcon?
12541159
1255 if (task_icon_is_launcher (priv->dragged_icon))1160/* if (task_icon_is_launcher (priv->dragged_icon))
1256 {1161 {
1257 // get the updated list1162 // get the updated list
1258 childs = gtk_container_get_children (GTK_CONTAINER(priv->box));1163 childs = gtk_container_get_children (GTK_CONTAINER(priv->box));
@@ -1283,6 +1188,7 @@
1283 return;1188 return;
1284 }1189 }
1285 }1190 }
1191*/
12861192
1287 priv->dragged_icon = NULL;1193 priv->dragged_icon = NULL;
1288}1194}
12891195
=== modified file 'applets/taskmanager/task-manager.h'
--- applets/taskmanager/task-manager.h 2009-03-03 00:58:39 +0000
+++ applets/taskmanager/task-manager.h 2009-06-21 23:03:17 +0000
@@ -64,5 +64,14 @@
64 gint offset,64 gint offset,
65 gint height);65 gint height);
6666
67gboolean task_manager_get_capabilities (TaskManager *manager,
68 GStrv *supported_keys,
69 GError **error);
70
71gboolean task_manager_update (TaskManager *manager,
72 GValue *window,
73 GHashTable *hints, /* mappings from string to GValue */
74 GError **error);
75
67#endif /* _TASK_MANAGER_H_ */76#endif /* _TASK_MANAGER_H_ */
6877
6978
=== removed file 'applets/taskmanager/task-window-private.h'
--- applets/taskmanager/task-window-private.h 2009-03-24 16:39:41 +0000
+++ applets/taskmanager/task-window-private.h 1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
1/*
2 * Copyright (C) 2008 Neil Jagdish Patel <njpatel@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
17 *
18 */
19
20#define TASK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
21 TASK_TYPE_WINDOW, \
22 TaskWindowPrivate))
23
24struct _TaskWindowPrivate
25{
26 WnckWindow *window;
27
28 /* Properties */
29 gchar *message;
30 gfloat progress;
31 gboolean hidden;
32 gboolean needs_attention;
33 gboolean is_active;
34};
35
360
=== modified file 'applets/taskmanager/task-window.c'
--- applets/taskmanager/task-window.c 2009-06-11 05:04:21 +0000
+++ applets/taskmanager/task-window.c 2009-06-26 11:00:10 +0000
@@ -14,6 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>16 * Authored by Neil Jagdish Patel <njpatel@gmail.com>
17 * Hannes Verschore <hv1989@gmail.com>
17 *18 *
18 */19 */
1920
@@ -26,11 +27,33 @@
26#include <libwnck/libwnck.h>27#include <libwnck/libwnck.h>
2728
28#include "task-window.h"29#include "task-window.h"
29#include "task-launcher.h"
30#include "task-settings.h"30#include "task-settings.h"
31#include "xutils.h"31#include "xutils.h"
3232
33G_DEFINE_TYPE (TaskWindow, task_window, G_TYPE_OBJECT)33G_DEFINE_TYPE (TaskWindow, task_window, TASK_TYPE_ITEM)
34
35#define TASK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
36 TASK_TYPE_WINDOW, \
37 TaskWindowPrivate))
38
39struct _TaskWindowPrivate
40{
41 WnckWindow *window;
42
43 // Workspace where the window should be in, before being visible.
44 // NULL if it isn't important
45 WnckWorkspace *workspace;
46
47 // Is this window in the workspace. If workspace is NULL, this is always TRUE;
48 gboolean in_workspace;
49
50 /* Properties */
51 gchar *message;
52 gfloat progress;
53 gboolean hidden;
54 gboolean needs_attention;
55 gboolean is_active;
56};
3457
35enum58enum
36{59{
@@ -40,27 +63,25 @@
4063
41enum64enum
42{65{
43 NAME_CHANGED,
44 ICON_CHANGED,
45 ACTIVE_CHANGED,66 ACTIVE_CHANGED,
46 NEEDS_ATTENTION,67 NEEDS_ATTENTION,
47 WORKSPACE_CHANGED,68 WORKSPACE_CHANGED,
48 MESSAGE_CHANGED,69 MESSAGE_CHANGED,
49 PROGRESS_CHANGED,70 PROGRESS_CHANGED,
50 HIDDEN_CHANGED,71 HIDDEN_CHANGED,
51 RUNNING_CHANGED,
5272
53 LAST_SIGNAL73 LAST_SIGNAL
54};74};
55static guint32 _window_signals[LAST_SIGNAL] = { 0 };75static guint32 _window_signals[LAST_SIGNAL] = { 0 };
5676
57/* Forwards */77/* Forwards */
58static WnckApplication * _get_application (TaskWindow *window);78static const gchar * _get_name (TaskItem *item);
59static gint _get_pid (TaskWindow *window);79static GdkPixbuf * _get_icon (TaskItem *item);
60static const gchar * _get_name (TaskWindow *window);80static gboolean _is_visible (TaskItem *item);
61static GdkPixbuf * _get_icon (TaskWindow *window);81static void _left_click (TaskItem *item, GdkEventButton *event);
62static gboolean _is_on_workspace (TaskWindow *window,82static void _right_click (TaskItem *item, GdkEventButton *event);
63 WnckWorkspace *space);83static guint _match (TaskItem *item, TaskItem *item_to_match);
84
64static void task_window_set_window (TaskWindow *window,85static void task_window_set_window (TaskWindow *window,
65 WnckWindow *wnckwin);86 WnckWindow *wnckwin);
6687
@@ -104,51 +125,24 @@
104}125}
105126
106static void127static void
107task_window_constructed (GObject *object)
108{
109 /*TaskWindowPrivate *priv = TASK_WINDOW (object)->priv;*/
110}
111
112static void
113task_window_class_init (TaskWindowClass *klass)128task_window_class_init (TaskWindowClass *klass)
114{129{
115 GParamSpec *pspec;130 GParamSpec *pspec;
116 GObjectClass *obj_class = G_OBJECT_CLASS (klass);131 GObjectClass *obj_class = G_OBJECT_CLASS (klass);
117132 TaskItemClass *item_class = TASK_ITEM_CLASS (klass);
118 obj_class->constructed = task_window_constructed;133
119 obj_class->set_property = task_window_set_property;134 obj_class->set_property = task_window_set_property;
120 obj_class->get_property = task_window_get_property;135 obj_class->get_property = task_window_get_property;
121136
122 /* We implement the necessary funtions for a normal window */137 /* We implement the necessary funtions for an item */
123 klass->get_application = _get_application;138 item_class->get_name = _get_name;
124 klass->get_pid = _get_pid;139 item_class->get_icon = _get_icon;
125 klass->get_name = _get_name;140 item_class->is_visible = _is_visible;
126 klass->get_icon = _get_icon;141 item_class->left_click = _left_click;
127 klass->is_on_workspace = _is_on_workspace;142 item_class->right_click = _right_click;
128 klass->activate = NULL;143 item_class->match = _match;
129 klass->popup_menu = NULL;144
130
131 /* Install signals */145 /* Install signals */
132 _window_signals[NAME_CHANGED] =
133 g_signal_new ("name-changed",
134 G_OBJECT_CLASS_TYPE (obj_class),
135 G_SIGNAL_RUN_LAST,
136 G_STRUCT_OFFSET (TaskWindowClass, name_changed),
137 NULL, NULL,
138 g_cclosure_marshal_VOID__STRING,
139 G_TYPE_NONE,
140 1, G_TYPE_STRING);
141
142 _window_signals[ICON_CHANGED] =
143 g_signal_new ("icon-changed",
144 G_OBJECT_CLASS_TYPE (obj_class),
145 G_SIGNAL_RUN_LAST,
146 G_STRUCT_OFFSET (TaskWindowClass, icon_changed),
147 NULL, NULL,
148 g_cclosure_marshal_VOID__OBJECT,
149 G_TYPE_NONE,
150 1, GDK_TYPE_PIXBUF);
151
152 _window_signals[ACTIVE_CHANGED] =146 _window_signals[ACTIVE_CHANGED] =
153 g_signal_new ("active-changed",147 g_signal_new ("active-changed",
154 G_OBJECT_CLASS_TYPE (obj_class),148 G_OBJECT_CLASS_TYPE (obj_class),
@@ -209,17 +203,6 @@
209 G_TYPE_NONE,203 G_TYPE_NONE,
210 1, G_TYPE_BOOLEAN);204 1, G_TYPE_BOOLEAN);
211205
212 _window_signals[RUNNING_CHANGED] =
213 g_signal_new ("running-changed",
214 G_OBJECT_CLASS_TYPE (obj_class),
215 G_SIGNAL_RUN_LAST,
216 G_STRUCT_OFFSET (TaskWindowClass, running_changed),
217 NULL, NULL,
218 g_cclosure_marshal_VOID__BOOLEAN,
219 G_TYPE_NONE,
220 1, G_TYPE_BOOLEAN);
221
222
223 /* Install properties */206 /* Install properties */
224 pspec = g_param_spec_object ("taskwindow",207 pspec = g_param_spec_object ("taskwindow",
225 "Window",208 "Window",
@@ -237,6 +220,8 @@
237 220
238 priv = window->priv = TASK_WINDOW_GET_PRIVATE (window);221 priv = window->priv = TASK_WINDOW_GET_PRIVATE (window);
239222
223 priv->workspace = NULL;
224 priv->in_workspace = TRUE;
240 priv->message = NULL;225 priv->message = NULL;
241 priv->progress = 0;226 priv->progress = 0;
242 priv->hidden = FALSE;227 priv->hidden = FALSE;
@@ -244,14 +229,14 @@
244 priv->is_active = FALSE;229 priv->is_active = FALSE;
245}230}
246231
247TaskWindow *232TaskItem *
248task_window_new (WnckWindow *window)233task_window_new (WnckWindow *window)
249{234{
250 TaskWindow *win = NULL;235 TaskItem *win = NULL;
251236
252 win = g_object_new (TASK_TYPE_WINDOW,237 win = g_object_new (TASK_TYPE_WINDOW,
253 "taskwindow", window,238 "taskwindow", window,
254 NULL);239 NULL);
255240
256 return win;241 return win;
257}242}
@@ -262,11 +247,8 @@
262 */247 */
263static void248static void
264window_closed (TaskWindow *window, WnckWindow *old_window)249window_closed (TaskWindow *window, WnckWindow *old_window)
265{250{
266 g_signal_emit (window, _window_signals[RUNNING_CHANGED], 0, FALSE);251 gtk_widget_destroy (GTK_WIDGET (window));
267
268 if (!TASK_IS_LAUNCHER (window))
269 g_object_unref (G_OBJECT (window));
270}252}
271253
272static void254static void
@@ -278,8 +260,7 @@
278 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));260 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));
279 priv = window->priv;261 priv = window->priv;
280262
281 g_signal_emit (window, _window_signals[NAME_CHANGED], 263 task_item_emit_name_changed (TASK_ITEM (window), wnck_window_get_name (wnckwin));
282 0, wnck_window_get_name (wnckwin));
283}264}
284265
285static void266static void
@@ -292,7 +273,7 @@
292 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));273 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));
293 274
294 pixbuf = _wnck_get_icon_at_size (wnckwin, s->panel_size, s->panel_size);275 pixbuf = _wnck_get_icon_at_size (wnckwin, s->panel_size, s->panel_size);
295 task_window_update_icon (window, pixbuf);276 task_item_emit_icon_changed (TASK_ITEM (window), pixbuf);
296 g_object_unref (pixbuf);277 g_object_unref (pixbuf);
297}278}
298279
@@ -303,7 +284,17 @@
303 284
304 g_return_if_fail (TASK_IS_WINDOW (window));285 g_return_if_fail (TASK_IS_WINDOW (window));
305 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));286 g_return_if_fail (WNCK_IS_WINDOW (wnckwin));
287
306 priv = window->priv;288 priv = window->priv;
289 if (priv->workspace==NULL)
290 priv->in_workspace = TRUE;
291 else
292 priv->in_workspace = wnck_window_is_in_viewport (priv->window, priv->workspace);
293
294 if (priv->in_workspace && !priv->hidden)
295 task_item_emit_visible_changed (TASK_ITEM (window), TRUE);
296 else
297 task_item_emit_visible_changed (TASK_ITEM (window), FALSE);
307 298
308 g_signal_emit (window, _window_signals[WORKSPACE_CHANGED], 299 g_signal_emit (window, _window_signals[WORKSPACE_CHANGED],
309 0, wnck_window_get_workspace (wnckwin));300 0, wnck_window_get_workspace (wnckwin));
@@ -329,7 +320,11 @@
329 if (priv->hidden != hidden)320 if (priv->hidden != hidden)
330 {321 {
331 priv->hidden = hidden;322 priv->hidden = hidden;
332 g_signal_emit (window, _window_signals[HIDDEN_CHANGED], 0, hidden);323
324 if (priv->in_workspace && !priv->hidden)
325 task_item_emit_visible_changed (TASK_ITEM (window), TRUE);
326 else
327 task_item_emit_visible_changed (TASK_ITEM (window), FALSE);
333 }328 }
334329
335 needs_attention = wnck_window_or_transient_needs_attention (wnckwin);330 needs_attention = wnck_window_or_transient_needs_attention (wnckwin);
@@ -342,14 +337,19 @@
342 }337 }
343}338}
344339
340/**
341 * TODO: remove old signals and weak_ref...
342 */
345static void343static void
346task_window_set_window (TaskWindow *window, WnckWindow *wnckwin)344task_window_set_window (TaskWindow *window, WnckWindow *wnckwin)
347{345{
348 TaskWindowPrivate *priv;346 TaskWindowPrivate *priv;
349347 GdkPixbuf *pixbuf;
348 TaskSettings *s = task_settings_get_default ();
349
350 g_return_if_fail (TASK_IS_WINDOW (window));350 g_return_if_fail (TASK_IS_WINDOW (window));
351
351 priv = window->priv;352 priv = window->priv;
352
353 priv->window = wnckwin;353 priv->window = wnckwin;
354354
355 g_object_weak_ref (G_OBJECT (priv->window), 355 g_object_weak_ref (G_OBJECT (priv->window),
@@ -364,14 +364,33 @@
364 g_signal_connect (wnckwin, "state-changed", 364 g_signal_connect (wnckwin, "state-changed",
365 G_CALLBACK (on_window_state_changed), window);365 G_CALLBACK (on_window_state_changed), window);
366366
367 g_signal_emit (window, _window_signals[RUNNING_CHANGED], 0, TRUE);367 task_item_emit_name_changed (TASK_ITEM (window), wnck_window_get_name (wnckwin));
368 pixbuf = _wnck_get_icon_at_size (wnckwin, s->panel_size, s->panel_size);
369 task_item_emit_icon_changed (TASK_ITEM (window), pixbuf);
370 g_object_unref (pixbuf);
371 task_item_emit_visible_changed (TASK_ITEM (window), TRUE);
368}372}
369373
370/*374/*
371 * Public functions375 * Public functions
372 */376 */
377
378/**
379 * Returns the name of the WnckWindow.
380 */
381const gchar *
382task_window_get_name (TaskWindow *window)
383{
384 g_return_val_if_fail (TASK_IS_WINDOW (window), "");
385
386 if (WNCK_IS_WINDOW (window->priv->window))
387 return wnck_window_get_name (window->priv->window);
388
389 return "";
390}
391
373WnckScreen * 392WnckScreen *
374task_window_get_screen (TaskWindow *window)393task_window_get_screen (TaskWindow *window)
375{394{
376 g_return_val_if_fail (TASK_IS_WINDOW (window), wnck_screen_get_default ());395 g_return_val_if_fail (TASK_IS_WINDOW (window), wnck_screen_get_default ());
377396
@@ -382,7 +401,7 @@
382}401}
383402
384gulong 403gulong
385task_window_get_xid (TaskWindow *window)404task_window_get_xid (TaskWindow *window)
386{405{
387 g_return_val_if_fail (TASK_IS_WINDOW (window), 0);406 g_return_val_if_fail (TASK_IS_WINDOW (window), 0);
388407
@@ -393,29 +412,29 @@
393}412}
394413
395gint 414gint
396task_window_get_pid (TaskWindow *window)415task_window_get_pid (TaskWindow *window)
397{416{
398 TaskWindowClass *klass;417 g_return_val_if_fail (TASK_IS_WINDOW (window), -1);
399418
400 g_return_val_if_fail (TASK_IS_WINDOW (window), -1);419 gint pid = -1;
401 420 if (WNCK_IS_WINDOW (window->priv->window))
402 klass = TASK_WINDOW_GET_CLASS (window);421 {
403 g_return_val_if_fail (klass->get_pid, -1);422 pid = wnck_window_get_pid (window->priv->window);
404 423 pid = pid ? pid : -1; /* if the pid is 0 return -1. Bad wnck! Bad! */
405 return klass->get_pid (window);424 }
425
426 return pid;
406}427}
407428
408WnckApplication *429WnckApplication *
409task_window_get_application (TaskWindow *window)430task_window_get_application (TaskWindow *window)
410{431{
411 TaskWindowClass *klass;432 g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);
412433
413 g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);434 if (WNCK_IS_WINDOW (window->priv->window))
414 435 return wnck_window_get_application (window->priv->window);
415 klass = TASK_WINDOW_GET_CLASS (window);436
416 g_return_val_if_fail (klass->get_application, NULL);437 return NULL;
417
418 return klass->get_application (window);
419}438}
420439
421440
@@ -424,7 +443,7 @@
424 gchar **res_name,443 gchar **res_name,
425 gchar **class_name)444 gchar **class_name)
426{445{
427 g_return_val_if_fail (TASK_IS_WINDOW (window), -1);446 g_return_val_if_fail (TASK_IS_WINDOW (window), FALSE);
428 447
429 *res_name = NULL;448 *res_name = NULL;
430 *class_name = NULL;449 *class_name = NULL;
@@ -441,51 +460,6 @@
441 return FALSE;460 return FALSE;
442}461}
443462
444const gchar *
445task_window_get_name (TaskWindow *window)
446{
447 TaskWindowClass *klass;
448
449 g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);
450
451 klass = TASK_WINDOW_GET_CLASS (window);
452 g_return_val_if_fail (klass->get_name, NULL);
453
454 return klass->get_name (window);
455}
456
457void
458task_window_set_name (TaskWindow *window,
459 const gchar *name)
460{
461 g_return_if_fail (TASK_IS_WINDOW (window));
462
463 g_signal_emit (window, _window_signals[NAME_CHANGED], 0, name);
464}
465
466GdkPixbuf *
467task_window_get_icon (TaskWindow *window)
468{
469 TaskWindowClass *klass;
470
471 g_return_val_if_fail (TASK_IS_WINDOW (window), NULL);
472
473 klass = TASK_WINDOW_GET_CLASS (window);
474 g_return_val_if_fail (klass->get_icon, NULL);
475
476 return klass->get_icon (window);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: