Re: Reminder: shared library applets deskguide and tasklist.
- From: jacob berkman <jacob ximian com>
- To: Miguel de Icaza <miguel ximian com>
- Cc: gnome-hackers gnome org, andersca gnu org, jirka 5z com
- Subject: Re: Reminder: shared library applets deskguide and tasklist.
- Date: 22 Jan 2001 23:00:21 -0500
On 22 Jan 2001 19:09:48 -0500, jacob berkman wrote:
> On 11 Jan 2001 21:48:43 -0500, Miguel de Icaza wrote:
> >
> > I have patches to make the tasklist and the deskguide shared
> > libraries. They are a bit outdated now, but I think we should get
> > them into CVS.
>
>
> So here is my super hacked up version. It is against HEAD gnome-core.
Crap. Forgot to attach. Not used to evo yet.
jacob
--
"The people who made the Macintosh produced a miracle, but that
doesn't mean their code was wonderful." -- Bob Cringely
? tasklist.diff
? tasklist_properties.lo
? libtasklist_applet.la
? to-1.80.patch
? to-1.81.patch
? to-1.82.patch
? tasklist_config.lo
? gwmh.lo
? gstc.lo
? tasklist-shlib-grouping.patch
? tasklist_icon.lo
? tasklist_menu.lo
? tasklist_applet.lo
? to-1.79.patch
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/tasklist/Makefile.am,v
retrieving revision 1.14
diff -u -r1.14 Makefile.am
--- Makefile.am 2000/04/15 17:11:38 1.14
+++ Makefile.am 2001/01/23 04:00:11
@@ -7,29 +7,41 @@
-I$(top_builddir)/panel \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
-I$(includedir) $(GNOME_INCLUDEDIR) \
- -DVERSION=\""$(VERSION)"\" \
@PIXBUF_CFLAGS@
-bin_PROGRAMS = tasklist_applet
+#bin_PROGRAMS = tasklist_applet
+lib_LTLIBRARIES = libtasklist_applet.la
-tasklist_applet_SOURCES = tasklist_applet.c \
- tasklist_config.c \
- tasklist_icon.c \
- tasklist_menu.c \
- tasklist_properties.c \
- gstc.c \
- gwmh.c
+#tasklist_applet_SOURCES = \
+# tasklist_applet.c \
+# tasklist_config.c \
+# tasklist_icon.c \
+# tasklist_menu.c \
+# tasklist_properties.c \
+# gstc.c \
+# gwmh.c
+#
-tasklist_applet_LDADD = ../../panel/libpanel_applet.la \
- $(GNOME_LIBDIR) $(ORB_LIBS) \
- $(GNOMEUI_LIBS) $(GNORBA_LIBS) \
- $(INTLLIBS) @PIXBUF_LIBS@
+libtasklist_applet_la_SOURCES =\
+ pixmaps.h \
+ tasklist_applet.h \
+ tasklist_applet.c \
+ tasklist_config.c \
+ tasklist_icon.c \
+ tasklist_menu.c \
+ tasklist_properties.c \
+ gstc.c \
+ gwmh.c
-EXTRA_DIST = \
- pixmaps.h \
- tasklist_applet.h \
- tasklist_applet.gnorba \
- tasklist_applet.desktop \
+#libtasklist_applet_la_LIBADD = \
+# ../../panel/libpanel_applet.la \
+# $(GNOME_LIBDIR) $(ORB_LIBS) \
+# $(GNOMEUI_LIBS) $(GNORBA_LIBS) \
+# $(INTLLIBS) @PIXBUF_LIBS@
+
+EXTRA_DIST = \
+ tasklist_applet.gnorba \
+ tasklist_applet.desktop \
unknown.xpm \
gnome-tasklist.png
Index: tasklist_applet.c
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/tasklist/tasklist_applet.c,v
retrieving revision 1.82
diff -u -r1.82 tasklist_applet.c
--- tasklist_applet.c 2000/12/21 07:11:35 1.82
+++ tasklist_applet.c 2001/01/23 04:00:11
@@ -5,122 +5,93 @@
#include "gstc.h"
#include "gwmh.h"
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "tasklist_applet.h"
#include "unknown.xpm"
-
-/* Prototypes */
-static void cb_properties (void);
-static void cb_about (void);
-gchar *fixup_task_label (TasklistTask *task);
-gboolean is_task_visible (TasklistTask *task);
-void draw_task (TasklistTask *task, GdkRectangle *rect);
-TasklistTask *find_gwmh_task (GwmhTask *gwmh_task);
-gboolean desk_notifier (gpointer func_data, GwmhDesk *desk, GwmhDeskInfoMask change_mask);
-gboolean task_notifier (gpointer func_data, GwmhTask *gwmh_task, GwmhTaskNotifyType ntype, GwmhTaskInfoMask imask);
-gboolean cb_button_press_event (GtkWidget *widget, GdkEventButton *event);
-gboolean cb_drag_motion (GtkWidget *widget, GdkDragContext *context, int x, int y, guint time);
-void cb_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time);
-gboolean cb_motion_timeout (gpointer data);
-gboolean cb_expose_event (GtkWidget *widget, GdkEventExpose *event);
-void create_applet (void);
-TasklistTask *task_get_xy (gint x, gint y);
-GList *get_visible_tasks (void);
-gint get_horz_rows(void);
-gboolean show_task (TasklistTask *task);
-
-GNOME_Panel_OrientType tasklist_orient; /* Tasklist orient */
-GtkWidget *handle; /* The handle box */
-GtkWidget *applet; /* The applet */
-GtkWidget *area; /* The drawing area used to display tasks */
-GList *tasks = NULL; /* The list of tasks used */
-
-#define MOTION_TIMEOUT 500 /* Show task motion_task if cursor over task for ... msec */
-int motion_timeout = 0; /* Show task motion_task after MOTION_TIMEOUT in drag_motion */
-TasklistTask *motion_task = NULL; /* Task to show after motion_timeout */
-
-TasklistIcon *unknown_icon = NULL; /* The unknown icon */
-gint vert_height=0; /* Vertical height, used for resizing */
-gint horz_width=0; /* Horizontal width, used for resizing */
-
-gint panel_size = 48;
+/* from gtkhandlebox.c */
+#define DRAG_HANDLE_SIZE 10
-extern TasklistConfig Config;
+/* define to x for debugging output */
+#define d(x)
/* sorting the list... */
static gint
-lexographic_compare_func (gconstpointer a, gconstpointer b)
+tlsort (TasklistTask *la, TasklistTask *lb)
{
- const TasklistTask *la = (const TasklistTask*)a;
- const TasklistTask *lb = (const TasklistTask*)b;
+ char *sa, *sb;
- if (la->gwmh_task->name == NULL && lb->gwmh_task->name == NULL)
- return 0;
- else if (la->gwmh_task->name == NULL)
+ d(g_print ("la: %p\tlb: %p\n", la, lb));
+
+ sa = la->task_group ? la->group_name : (la->group ? la->group->group_name : la->gwmh_task->name);
+ sb = lb->task_group ? lb->group_name : (lb->group ? lb->group->group_name : lb->gwmh_task->name);
+
+ if (sa && sb)
+ return strcasecmp (sa, sb);
+ else if (sa)
return 1;
- else if (lb->gwmh_task->name == NULL)
+ else if (sb)
return -1;
-
- return strcasecmp (la->gwmh_task->name, lb->gwmh_task->name);
+ else
+ return 0;
}
-static gint
-creation_compare_func (gconstpointer a, gconstpointer b)
+static void
+clamp_size (Tasklist *tasklist, int *size)
{
- const TasklistTask *la = (const TasklistTask*)a;
- const TasklistTask *lb = (const TasklistTask*)b;
+ int free_space;
- return lb->serial_number - la->serial_number;
-}
+ free_space = applet_widget_get_free_space (APPLET_WIDGET (tasklist->applet));
-static gint
-tasklist_sorting_compare_func (gconstpointer a, gconstpointer b)
-{
- /*
- * This is dumb, but here's why:
- * the intent is that there be lots of compare functions
- * (maybe putting the icons at the top, or by desktop,
- * or whatever. Right now there are just two: the old
- * one and the one I like. BUT, I don't know enough about
- * how to make gnome_config_xxx map a list of things into
- * functions, so for now I just have a boolean that controls
- * which. Hopefully the next person who adds sorting functions
- * will know more about gnome than I do and will fix this hack.
- * - johnh isi edu, 24-Nov-00
- */
- return Config.sort_tasklist ?
- lexographic_compare_func (a, b) :
- creation_compare_func (a, b);
+ if (free_space > 0 && free_space < *size)
+ *size = free_space;
}
-static void
-clamp_size_if_never_push (int *size)
+void
+tasklist_clean_menu (TasklistTask *task)
{
- if (Config.vert_never_push) {
- int free_space = applet_widget_get_free_space
- (APPLET_WIDGET (applet));
- if (free_space > 0 &&
- free_space < *size)
- *size = free_space;
+ if(task->menu) {
+ d(g_print ("group had a menu: %p\t", task->menu));
+ gtk_widget_unref (task->menu);
+ d(g_print ("%p\n", task->menu));
}
}
+static char *
+get_task_class (GwmhTask *task)
+{
+ XClassHint hint;
+ char *retval;
-/* from gtkhandlebox.c */
-#define DRAG_HANDLE_SIZE 10
+ if (!XGetClassHint (GDK_DISPLAY (), task->xwin, &hint))
+ return NULL;
+
+ d(g_print ("name: %s\tclass: %s\n", hint.res_name, hint.res_class));
+ retval = g_strdup (hint.res_class);
+
+ XFree (hint.res_name);
+ XFree (hint.res_class);
+
+ return retval;
+}
/* get the horz_rows depending on the configuration settings */
-gint
-get_horz_rows(void)
+static gint
+get_horz_rows(Tasklist *tasklist)
{
int result;
- if (Config.follow_panel_size)
- result = panel_size/ROW_HEIGHT;
+ g_return_val_if_fail (tasklist != NULL, 1);
+
+ if (tasklist->config.follow_panel_size)
+ result = tasklist->panel_size/ROW_HEIGHT;
else
- result = Config.horz_rows;
+ result = tasklist->config.horz_rows;
if (result < 1)
result = 1;
@@ -130,141 +101,122 @@
/* Shorten a label that is too long */
gchar *
-fixup_task_label (TasklistTask *task)
-{
- gchar *str, *tempstr;
- gint len, label_len;
-
- label_len = gdk_string_width (area->style->font,
- task->gwmh_task->name);
+tasklist_task_get_label (TasklistTask *task, int width, gboolean add_groupcount)
+{
+ Tasklist *tasklist = task->tasklist;
+ gchar *das_string;
+ gchar *str, *tempstr, *groupcount = NULL;
+ gint len, label_len, overhead, allowed_width;
+
+ das_string = task->gwmh_task->name;
+
+ label_len = gdk_string_width (tasklist->area->style->font, das_string);
+
+ overhead = tasklist->config.show_mini_icons ? 30 : 6;
+
+ if (add_groupcount) {
+ groupcount = g_strdup_printf ("(%d) ", g_slist_length (task->vtasks
+ ? task->vtasks
+ : task->group->vtasks));
+
+ overhead += 10 + gdk_string_width (tasklist->area->style->font,
+ groupcount);
+ }
if (GWMH_TASK_ICONIFIED (task->gwmh_task))
- label_len += gdk_string_width (area->style->font,
- "[]");
+ overhead += gdk_string_width (tasklist->area->style->font, "[]");
- if (label_len > task->width - ROW_HEIGHT) {
+ allowed_width = width - overhead;
+
+ if ( (width > 0) && (label_len > allowed_width) ) {
GdkWChar *wstr;
+
+ g_assert (width > 0);
- len = strlen (task->gwmh_task->name);
+ len = strlen (das_string);
wstr = g_new (GdkWChar, len + 3);
- len = gdk_mbstowcs (wstr, task->gwmh_task->name, len);
+ len = gdk_mbstowcs (wstr, das_string, len);
+ /* ok, the below thing is broken */
if ( len < 0 ) { /* if the conversion is failed */
wstr[0] = wstr[1] = wstr[2] = '?';
wstr[3] = '\0'; /* wcscpy(wstr,"???");*/
len = 3;
- label_len = gdk_text_width_wc(area->style->font,
+ label_len = gdk_text_width_wc(tasklist->area->style->font,
wstr, len);
- if (label_len <= task->width
- - (Config.show_mini_icons ? 24:6)) {
+ if (label_len <= allowed_width) {
str = gdk_wcstombs(wstr);
g_free(wstr);
return str;
- }
+ }
}
wstr[len] = wstr[len+1] = '.';
wstr[len+2] = '\0'; /*wcscat(wstr,"..");*/
len--;
-
+
for (; len > 0; len--) {
wstr[len] = '.';
wstr[len + 3] = '\0';
- label_len = gdk_text_width_wc (area->style->font,
+ label_len = gdk_text_width_wc (tasklist->area->style->font,
wstr, len + 3);
- if (GWMH_TASK_ICONIFIED (task->gwmh_task))
- label_len += gdk_string_width (area->style->font,
- "[]");
- if (label_len <= task->width - (Config.show_mini_icons ? 24:6))
+ if (label_len <= allowed_width)
break;
}
str = gdk_wcstombs (wstr);
g_free (wstr);
+ } else {
+ str = g_strdup (das_string);
}
- else
- str = g_strdup (task->gwmh_task->name);
- if (GWMH_TASK_ICONIFIED (task->gwmh_task)) {
- tempstr = g_strdup_printf ("[%s]", str);
+ if (task->gwmh_task && GWMH_TASK_ICONIFIED (task->gwmh_task)) {
+ tempstr = g_strdup_printf ("[%s]", str);
g_free(str);
str = tempstr;
}
-
- return str;
-}
-
-/* Check what task (if any) is at position x,y on the tasklist */
-TasklistTask *
-task_get_xy (gint x, gint y)
-{
- GList *temp_tasks, *temp;
- TasklistTask *task;
-
- temp_tasks = get_visible_tasks ();
-
- for (temp = temp_tasks; temp != NULL; temp = temp->next) {
- task = (TasklistTask *)temp->data;
- if (x > task->x &&
- x < task->x + task->width &&
- y > task->y &&
- y < task->y + task->height) {
- g_list_free (temp_tasks);
- return task;
- }
+
+ if (groupcount) {
+ tempstr = g_strconcat (groupcount, str, NULL);
+ g_free (str);
+ str = tempstr;
}
-
- if (temp_tasks != NULL)
- g_list_free (temp_tasks);
-
- return NULL;
-}
-
-
-/* Check which tasks are "visible",
- if they should be drawn onto the tasklist */
-GList *
-get_visible_tasks (void)
-{
- GList *temp_tasks;
- GList *visible_tasks = NULL;
- temp_tasks = tasks;
- while (temp_tasks) {
- if (is_task_visible ((TasklistTask *) temp_tasks->data))
- visible_tasks = g_list_insert_sorted (visible_tasks, temp_tasks->data, tasklist_sorting_compare_func);
- temp_tasks = temp_tasks->next;
- }
- return visible_tasks;
+ return str;
}
/* Check if a task is "visible",
if it should be drawn onto the tasklist */
-gboolean
+static gboolean
is_task_visible (TasklistTask *task)
{
+ Tasklist *tasklist;
GwmhDesk *desk_info;
+ if (!task || task->destroyed || task->task_group)
+ return FALSE;
+
+ tasklist = task->tasklist;
+
desk_info = gwmh_desk_get_config ();
if (GWMH_TASK_SKIP_TASKBAR (task->gwmh_task))
return FALSE;
-
if (task->gwmh_task->desktop != desk_info->current_desktop ||
task->gwmh_task->harea != desk_info->current_harea ||
task->gwmh_task->varea != desk_info->current_varea) {
if (!GWMH_TASK_STICKY (task->gwmh_task)) {
- if (!Config.all_desks_minimized &&
- !Config.all_desks_normal)
+ if (!tasklist->config.all_desks_minimized &&
+ !tasklist->config.all_desks_normal)
return FALSE;
- else if (Config.all_desks_minimized &&
- !Config.all_desks_normal) {
+ else if (tasklist->config.all_desks_minimized &&
+ !tasklist->config.all_desks_normal) {
if (!GWMH_TASK_ICONIFIED (task->gwmh_task))
return FALSE;
}
- else if (Config.all_desks_normal &&
- !Config.all_desks_minimized) {
+ else if (tasklist->config.all_desks_normal &&
+ !tasklist->config.all_desks_minimized) {
if (GWMH_TASK_ICONIFIED (task->gwmh_task))
return FALSE;
}
@@ -272,148 +224,381 @@
}
if (GWMH_TASK_ICONIFIED (task->gwmh_task)) {
- if (!Config.show_minimized)
+ if (!tasklist->config.show_minimized)
return FALSE;
} else {
- if (!Config.show_normal)
+ if (!tasklist->config.show_normal)
return FALSE;
}
return TRUE;
}
+static gboolean
+is_task_really_visible (TasklistTask *task)
+{
+ g_return_val_if_fail (task != NULL, FALSE);
+
+ if (!task->tasklist->config.enable_grouping)
+ return is_task_visible (task);
+
+ /* we can probably unroll the length test */
+ if (task->group && g_slist_length (task->group->vtasks) > task->tasklist->config.grouping_min)
+ return FALSE;
+ else if (task->task_group)
+ return g_slist_length (task->vtasks) > task->tasklist->config.grouping_min;;
+ return is_task_visible (task);
+}
+
+static void
+print_task (TasklistTask *task, gpointer null)
+{
+ return;
+
+ if (!task)
+ g_print (" * * NULL TASK * *\n");
+ else if (task->group)
+ g_print ("task: %p (%p) [%d, %d]: %s\n",
+ task, task->gwmh_task,
+ is_task_visible (task),
+ is_task_really_visible (task),
+ task->gwmh_task->name);
+ else if (task->task_group) {
+ g_print ("group: %p [%d]: %s\n", task, is_task_really_visible (task), task->group_name);
+ g_slist_foreach (task->tasks, (GFunc)print_task, NULL);
+ g_print ("/\n");
+ } else {
+ g_print ("Unknown task: %p\n", task);
+ g_assert_not_reached ();
+ }
+}
+
+static void
+fixup_group (TasklistTask *group)
+{
+ TasklistTask *task;
+ GSList *item;
+
+ g_return_if_fail (group != NULL);
+
+ group->focused_task = NULL;
+ group->gwmh_task->iconified = TRUE;
+
+ g_slist_free (group->vtasks);
+ group->vtasks = NULL;
+
+ for (item = group->tasks; item; item = item->next) {
+ task = (TasklistTask *)item->data;
+ if (is_task_visible (task)) {
+ group->vtasks = g_slist_prepend (group->vtasks, task);
+ if (!task->gwmh_task->iconified)
+ group->gwmh_task->iconified = FALSE;
+ if (task->gwmh_task->focused)
+ group->focused_task = task;
+ }
+ }
+}
+
+static gboolean
+fixup_vtask (TasklistTask *task, gpointer forcep)
+{
+ gint force = GPOINTER_TO_INT (forcep);
+ gboolean visible;
+
+ /* why not layout if we are confused */
+ g_return_val_if_fail (task, TRUE);
+
+ if (task->task_group)
+ fixup_group (task);
+
+ visible = is_task_really_visible (task);
+
+ if (visible == task->visible)
+ return FALSE;
+
+ task->visible = visible;
+ task->tasklist->vtasks = visible
+ ? g_slist_insert_sorted (task->tasklist->vtasks, task, tlsort)
+ : g_slist_remove (task->tasklist->vtasks, task);
+
+ if (task->tasklist->config.enable_grouping) {
+ if (task->task_group) {
+ g_slist_foreach (task->tasks, (GFunc)fixup_vtask, forcep);
+ } else if (task->group) {
+ fixup_vtask (task->group, GINT_TO_POINTER (FALSE));
+ }
+ }
+
+ d(g_print (">>>>>\tfixup_vtask "));
+ d(print_task (task, NULL));
+ d(g_slist_foreach (task->tasklist->vtasks, (GFunc)print_task, NULL));
+ d(g_print ("<<<<<\n"));
+
+ return TRUE;
+}
+
+static void
+redo_groups (gchar *groupname, TasklistTask *task, Tasklist *tasklist)
+{
+ print_task (task, NULL);
+
+ fixup_group (task);
+ task->visible = is_task_really_visible (task);
+ if (task->visible)
+ tasklist->vtasks = g_slist_insert_sorted (tasklist->vtasks, task, tlsort);
+}
+
+void
+tasklist_redo_vtasks (Tasklist *tasklist)
+{
+ TasklistTask *task;
+ GList *item;
+
+ if (tasklist->vtasks) {
+ g_slist_free (tasklist->vtasks);
+ tasklist->vtasks = NULL;
+ }
+
+ d(g_print ("\n\n\n\n\n\n\n\n\n\nredo_vtasks\n\n\n\n\n\n\n\n\n\n"));
+
+ if (tasklist->config.enable_grouping)
+ g_hash_table_foreach (tasklist->groups, (GHFunc)redo_groups, tasklist);
+
+ for (item = gwmh_task_list_get (); item; item = item->next) {
+ task = g_hash_table_lookup (tasklist->tasks, item->data);
+
+ /* this should never actually happen */
+ if (!task) continue;
+
+ task->visible = is_task_really_visible (task);
+
+ if (task->visible)
+ tasklist->vtasks = g_slist_insert_sorted (tasklist->vtasks, task, tlsort);
+ }
+
+#if 0
+ if (!tasklist->config.sort_tasklist)
+ tasklist->vtasks = g_slist_reverse (tasklist->vtasks);
+#endif
+ d(g_print ("\n\n\n\n\n\n\n\n\n\nvtasks: %d\n", g_slist_length (tasklist->vtasks)));
+
+ d(g_print (">>>>>\tredo_vtasks:\n"));
+ d(g_slist_foreach (tasklist->vtasks, (GFunc)print_task, NULL));
+ d(g_print ("<<<<<\n"));
+}
+
+/* Check what task (if any) is at position x,y on the tasklist */
+static TasklistTask *
+task_get_xy (Tasklist *tasklist, gint x, gint y)
+{
+ GSList *temp_tasks, *temp;
+ TasklistTask *task;
+
+ temp_tasks = tasklist->vtasks;
+
+ for (temp = temp_tasks; temp != NULL; temp = temp->next) {
+ task = (TasklistTask *)temp->data;
+ if (x > task->x &&
+ x < task->x + task->width &&
+ y > task->y &&
+ y < task->y + task->height)
+ return task;
+ }
+
+ return NULL;
+}
+
+static void
+draw_dot (GdkWindow *window, GdkGC *lgc, GdkGC *dgc, int x, int y)
+{
+ gdk_draw_point (window, dgc, x, y);
+ gdk_draw_point (window, lgc, x+1, y+1);
+}
+
/* Draw a single task */
void
-draw_task (TasklistTask *task, GdkRectangle *rect)
+tasklist_draw_task (TasklistTask *task, GdkRectangle *rect)
{
+ TasklistTask *real_task;
gchar *tempstr;
gint text_height, text_width;
+ gboolean focused;
/* For mini icons */
TasklistIcon *icon;
GdkPixbuf *pixbuf;
+
+ Tasklist *tasklist;
- if (!is_task_visible (task))
+ if (!is_task_really_visible (task))
return;
- gtk_paint_box (area->style, area->window,
- GWMH_TASK_FOCUSED (task->gwmh_task) ?
- GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
- GWMH_TASK_FOCUSED (task->gwmh_task) ?
- GTK_SHADOW_IN : GTK_SHADOW_OUT,
- rect, area, "button",
- task->x, task->y,
- task->width, task->height);
-
- if (task->gwmh_task->name) {
- tempstr = fixup_task_label (task);
- text_height = gdk_string_height (area->style->font, "1");
- text_width = gdk_string_width (area->style->font, tempstr);
- gdk_draw_string (area->window,
- area->style->font,
- GWMH_TASK_FOCUSED (task->gwmh_task) ?
- area->style->fg_gc[GTK_STATE_ACTIVE] :
- area->style->fg_gc[GTK_STATE_NORMAL],
- task->x +
- (Config.show_mini_icons ? 10 : 0) +
- ((task->width - text_width) / 2),
- task->y + ((task->height - text_height) / 2) + text_height,
+ /* is_task_visible should return FALSE for task == NULL */
+ g_assert (task != NULL);
+
+ tasklist = task->tasklist;
+
+ real_task = task;
+ if (is_task_visible (task->focused_task) && GWMH_TASK_FOCUSED (task->focused_task->gwmh_task))
+ task = task->focused_task;
+
+ focused = GWMH_TASK_FOCUSED (task->gwmh_task) || real_task->menu != NULL;
+
+ gtk_paint_box (tasklist->area->style, tasklist->area->window,
+ focused ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
+ focused ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
+ rect, tasklist->area, "button",
+ real_task->x, real_task->y,
+ real_task->width, real_task->height);
+
+ tempstr = tasklist_task_get_label (task, real_task->width, real_task->task_group);
+ if (tempstr) {
+ text_height = gdk_string_height (tasklist->area->style->font, "1");
+ text_width = gdk_string_width (tasklist->area->style->font, tempstr);
+ gdk_draw_string (tasklist->area->window,
+ tasklist->area->style->font,
+ focused ?
+ tasklist->area->style->fg_gc[GTK_STATE_ACTIVE] :
+ tasklist->area->style->fg_gc[GTK_STATE_NORMAL],
+ real_task->x +
+ (tasklist->config.show_mini_icons ? 10 : 0) +
+ ((real_task->width - text_width) / 2),
+ real_task->y + ((real_task->height - text_height) / 2) + text_height,
tempstr);
g_free (tempstr);
}
- if (Config.show_mini_icons) {
+ if (tasklist->config.show_mini_icons) {
icon = task->icon;
- if (GWMH_TASK_ICONIFIED (task->gwmh_task))
+ if ( GWMH_TASK_ICONIFIED (task->gwmh_task))
pixbuf = icon->minimized;
else
pixbuf = icon->normal;
+
+ gdk_pixbuf_render_to_drawable_alpha (
+ pixbuf,
+ tasklist->area->window,
+ 0, 0,
+ real_task->x + 3 + (16 - gdk_pixbuf_get_width (pixbuf)) / 2,
+ real_task->y + (real_task->height - gdk_pixbuf_get_height (pixbuf)) / 2,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf),
+ GDK_PIXBUF_ALPHA_BILEVEL,
+ 127,
+ GDK_RGB_DITHER_NORMAL,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+
+ }
+
+ if (real_task->task_group) {
+ GtkStyle *style;
+ GdkWindow *window;
+ GdkGC *lgc, *dgc;
+ int x, y, i, j;
+
+ style = tasklist->area->style;
+
+ lgc = style->light_gc[focused ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL];
+ dgc = style->dark_gc[focused ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL];
+
+ window = tasklist->area->window;
+
+ x = real_task->x + real_task->width - style->klass->ythickness - 10;
+ y = real_task->y + style->klass->xthickness + 2;
+
+ for (i = 0; i < 3; i++) {
+ for (j = i; j < 3; j++) {
+ draw_dot (window, lgc, dgc, x + j*3, y + i*3);
+ }
+ }
- gdk_pixbuf_render_to_drawable_alpha (pixbuf,
- area->window,
- 0, 0,
- task->x + 3 + (16 - gdk_pixbuf_get_width (pixbuf)) / 2,
- task->y + (task->height - gdk_pixbuf_get_height (pixbuf)) / 2,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- GDK_PIXBUF_ALPHA_BILEVEL,
- 127,
- GDK_RGB_DITHER_NORMAL,
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
+
+#if 0
+ gtk_draw_arrow (tasklist->area->style, tasklist->area->window,
+ focused ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
+ GTK_SHADOW_ETCHED_IN,
+ GTK_ARROW_DOWN, TRUE,
+ real_task->x + real_task->width - 12,
+ real_task->y + (real_task->height - 8) / 2,
+ 9, 8);
+#endif
}
+
}
+
static int
-max_width (GList *temp_tasks)
+max_width (GSList *tasks)
{
- GList *li;
+ TasklistTask *task;
+ GSList *li;
int maxwidth = 0;
+ char *s;
- for (li = temp_tasks; li != NULL; li = li->next) {
- int width;
- TasklistTask *task = li->data;
- const char *name = task->gwmh_task->name != NULL ?
- task->gwmh_task->name : "";
+ for (li = tasks; li; li = li->next) {
+ task = li->data;
if (task->fullwidth < 0) {
- width = gdk_string_width (area->style->font, name);
-
- if (GWMH_TASK_ICONIFIED (task->gwmh_task))
- width += gdk_string_width (area->style->font,
- "[]");
-
- task->fullwidth = width;
- } else {
- width = task->fullwidth;
+ s = tasklist_task_get_label (task, -1, task->task_group);
+ task->fullwidth = gdk_string_width (
+ task->tasklist->area->style->font, s);
+ g_free (s);
}
- if (Config.show_mini_icons)
- width += 10;
-
- width += ROW_HEIGHT;
-
- if (width > maxwidth)
- maxwidth = width;
+ maxwidth = MAX (maxwidth,
+ task->fullwidth +
+ (task->tasklist->config.show_mini_icons
+ ? ROW_HEIGHT + 10 : 0));
}
-
- return maxwidth;
+ return MIN (maxwidth, 512);
}
/* Layout the tasklist */
-void
-layout_tasklist (gboolean call_change_size)
+static int
+real_layout_tasklist (Tasklist *tasklist, gboolean call_change_size)
{
gint j = 0, k = 0, num = 0, p = 0;
- GList *temp_tasks, *temp;
TasklistTask *task;
+ GSList *temp = NULL;
/* gint extra_space; */
gint num_rows = 0, num_cols = 0;
gint curx = 0, cury = 0, curwidth = 0, curheight = 0;
+
+ tasklist->layout_timeout = 0;
+ d(g_message ("Layout!"));
+
+ /*gdk_beep ();*/
- temp_tasks = get_visible_tasks ();
- num = g_list_length (temp_tasks);
+ if (!tasklist->vtasks) {
+ d(g_message ("no tasks :(\n"));
+ gtk_widget_draw (tasklist->area, NULL);
+ return FALSE;
+ }
+
+ num = g_slist_length (tasklist->vtasks);
- switch (applet_widget_get_panel_orient (APPLET_WIDGET (applet))) {
+ switch (applet_widget_get_panel_orient (APPLET_WIDGET (tasklist->applet))) {
case ORIENT_UP:
case ORIENT_DOWN:
if (num == 0) {
- if (Config.horz_fixed)
- horz_width = Config.horz_width;
+ if (tasklist->config.horz_fixed)
+ tasklist->horz_width = tasklist->config.horz_width;
else
- horz_width = 4;
+ tasklist->horz_width = 4;
- change_size (FALSE, -1);
+ if (call_change_size)
+ tasklist_change_size (tasklist, FALSE, -1);
- gtk_widget_draw (area, NULL);
- return;
+ gtk_widget_draw (tasklist->area, NULL);
+ return FALSE;
}
while (p < num) {
- if (num < get_horz_rows())
+ if (num < get_horz_rows(tasklist))
num_rows = num;
j++;
@@ -422,33 +607,34 @@
if (num_rows < k + 1)
num_rows = k + 1;
- if (get_horz_rows () == 0 || j >= ((num + get_horz_rows() - 1) / get_horz_rows())) {
+ if (get_horz_rows (tasklist) == 0 || j >= ((num + get_horz_rows(tasklist) - 1) / get_horz_rows(tasklist))) {
j = 0;
k++;
}
p++;
}
- if (Config.horz_fixed) {
- curheight = (ROW_HEIGHT * get_horz_rows() - 0) / num_rows;
- curwidth = (Config.horz_width - 0) / num_cols;
+ if (tasklist->config.horz_fixed) {
+ curheight = (ROW_HEIGHT * get_horz_rows(tasklist)) / num_rows;
+ curwidth = (tasklist->config.horz_width) / num_cols;
} else {
int width;
- width = Config.horz_taskwidth * num_cols + DRAG_HANDLE_SIZE;
+ width = tasklist->config.horz_taskwidth * num_cols + DRAG_HANDLE_SIZE;
+ if (tasklist->config.horz_never_push)
+ clamp_size (tasklist, &width);
- clamp_size_if_never_push (&width);
-
width -= DRAG_HANDLE_SIZE;
-
- curheight = (ROW_HEIGHT * get_horz_rows() - 0) / num_rows;
- curwidth = width / num_cols;
+ curheight = (ROW_HEIGHT * get_horz_rows(tasklist)) / num_rows;
+#if 0
/* If the total width is higher than allowed,
we use the "fixed" way instead */
- if ((curwidth * num_cols) > Config.horz_width)
- curwidth = (Config.horz_width - 0) / num_cols;
+ if ((curwidth * num_cols) > tasklist->config.horz_width)
+ curwidth = (tasklist->config.horz_width - 0) / num_cols;
+#endif
+ curwidth = width / num_cols;
}
@@ -456,7 +642,7 @@
cury = 0;
- for (temp = temp_tasks; temp != NULL; temp = temp->next) {
+ for (temp = tasklist->vtasks; temp != NULL; temp = temp->next) {
task = (TasklistTask *) temp->data;
task->x = curx;
@@ -464,11 +650,11 @@
task->width = curwidth;
task->height = curheight;
- if (Config.horz_fixed) {
+ if (tasklist->config.horz_fixed) {
curx += curwidth;
- if (curx >= Config.horz_width ||
- curx + curwidth > Config.horz_width) {
+ if (curx >= tasklist->config.horz_width ||
+ curx + curwidth > tasklist->config.horz_width) {
cury += curheight;
curx = 0;
}
@@ -483,13 +669,13 @@
}
}
- if (Config.horz_fixed)
- horz_width = Config.horz_width;
+ if (tasklist->config.horz_fixed)
+ tasklist->horz_width = tasklist->config.horz_width;
else
- horz_width = num_cols * curwidth + 4;
+ tasklist->horz_width = num_cols * curwidth + 4;
if (call_change_size)
- change_size (FALSE, -1);
+ tasklist_change_size (tasklist, FALSE, -1);
break;
@@ -497,49 +683,46 @@
case ORIENT_RIGHT:
if (num == 0) {
- if (Config.vert_fixed)
- vert_height = Config.vert_height;
+ if (tasklist->config.vert_fixed)
+ tasklist->vert_height = tasklist->config.vert_height;
else
- vert_height = 4;
+ tasklist->vert_height = 4;
if (call_change_size)
- change_size (FALSE, -1);
+ tasklist_change_size (tasklist, FALSE, -1);
- gtk_widget_draw (area, NULL);
- return;
+ gtk_widget_draw (tasklist->area, NULL);
+ return FALSE;
}
curheight = ROW_HEIGHT;
- if (Config.follow_panel_size)
- curwidth = panel_size - 0;
+ if (tasklist->config.follow_panel_size)
+ curwidth = tasklist->panel_size;
else
- curwidth = Config.vert_width - 0;
-
- if (Config.vert_width_full) {
- int fullwidth = max_width (temp_tasks);
-
- if (fullwidth > curwidth)
- curwidth = fullwidth;
- }
+ curwidth = tasklist->config.vert_width;
+ if (tasklist->config.vert_width_full)
+ curwidth = MAX (curwidth, max_width (tasklist->vtasks));
+
num_cols = 1;
num_rows = num;
curx = 0;
cury = 0;
- if (Config.vert_fixed) {
- vert_height = Config.vert_height;
+ if (tasklist->config.vert_fixed) {
+ tasklist->vert_height = tasklist->config.vert_height;
} else {
- vert_height = curheight * num_rows + 4 + DRAG_HANDLE_SIZE;
- clamp_size_if_never_push (&vert_height);
- vert_height -= DRAG_HANDLE_SIZE;
+ tasklist->vert_height = curheight * num_rows + 4 + DRAG_HANDLE_SIZE;
+ if (tasklist->config.vert_never_push)
+ clamp_size (tasklist, &tasklist->vert_height);
+ tasklist->vert_height -= DRAG_HANDLE_SIZE;
}
if (call_change_size)
- change_size (FALSE, curwidth);
+ tasklist_change_size (tasklist, FALSE, curwidth);
- for (temp = temp_tasks; temp != NULL; temp = temp->next) {
+ for (temp = tasklist->vtasks; temp != NULL; temp = temp->next) {
task = (TasklistTask *) temp->data;
task->x = curx;
@@ -549,9 +732,9 @@
curx += curwidth;
- if (curx >= (Config.follow_panel_size?
- panel_size:
- Config.vert_width) - 0) {
+ if (curx >= (tasklist->config.follow_panel_size?
+ tasklist->panel_size:
+ tasklist->config.vert_width) - 0) {
cury += curheight;
curx = 0;
}
@@ -559,22 +742,37 @@
break;
}
+
+ gtk_widget_draw (tasklist->area, NULL);
+
+ return FALSE;
+}
- if (temp_tasks != NULL)
- g_list_free (temp_tasks);
+/* this now actually just queues a relayout */
+void
+tasklist_layout_tasklist (Tasklist *tasklist)
+{
+ g_return_if_fail (tasklist);
+ /* don't queue another timeout */
+ if (tasklist->layout_timeout) {
+ d(g_message ("Skipped layout!"));
+ return;
+ }
- gtk_widget_draw (area, NULL);
+ d(g_message ("Adding layout callback..."));
+ tasklist->layout_timeout = g_idle_add ((GSourceFunc)real_layout_tasklist, tasklist);
}
+#if 0
/* Get a task from the list that has got the given gwmh_task */
-TasklistTask *
-find_gwmh_task (GwmhTask *gwmh_task)
+static TasklistTask *
+find_gwmh_task (Tasklist *tasklist, GwmhTask *gwmh_task)
{
GList *temp_tasks;
TasklistTask *task;
- temp_tasks = tasks;
+ temp_tasks = tasklist->tasks;
while (temp_tasks) {
task = (TasklistTask *)temp_tasks->data;
@@ -585,234 +783,389 @@
return NULL;
}
+#endif
/* This routine gets called when desktops are switched etc */
-gboolean
+static gboolean
desk_notifier (gpointer func_data, GwmhDesk *desk,
GwmhDeskInfoMask change_mask)
{
- if (Config.all_desks_minimized &&
- Config.all_desks_normal)
+ Tasklist *tasklist = (Tasklist *) func_data;
+
+ if (tasklist->config.all_desks_minimized &&
+ tasklist->config.all_desks_normal)
return TRUE;
- layout_tasklist (TRUE);
+ tasklist_redo_vtasks (tasklist);
+ tasklist_layout_tasklist (tasklist);
return TRUE;
}
+static void
+tasklist_group_destroy (TasklistTask *group)
+{
+ d(g_print (" *** destroying group: %s\n", group->group_name));
+
+ tasklist_icon_destroy (group);
+
+ g_hash_table_remove (group->tasklist->groups, group->group_name);
+
+ g_free (group->gwmh_task);
+ g_free (group->group_name);
+
+ tasklist_clean_menu (group);
+
+ g_free (group);
+}
+
+static void
+tasklist_task_destroy (GwmhTask *gtask, Tasklist *tasklist)
+{
+ TasklistTask *ttask;
+
+ g_return_if_fail (gtask != NULL);
+ g_return_if_fail (tasklist != NULL);
+
+ ttask = g_hash_table_lookup (tasklist->tasks, gtask);
+
+ if (!ttask) {
+ g_warning ("Task not found in tasklist: %p; not destroying", gtask);
+ return;
+ }
+
+ d(g_print (" *** removing: %p (%s)\n", ttask, gtask->name));
+
+ ttask->destroyed = TRUE;
+
+ g_hash_table_remove (tasklist->tasks, gtask);
+
+ if (ttask == tasklist->motion_task)
+ tasklist->motion_task = NULL;
+
+ /* this is broken */
+#if 0
+ if (ttask->menuitem)
+ gtk_widget_destroy (ttask->menuitem);
+#endif
+ tasklist_icon_destroy (ttask);
+ tasklist_clean_menu (ttask);
+
+ if (ttask->group) {
+ if (ttask->group->focused_task == ttask)
+ ttask->group->focused_task = NULL;
+
+ ttask->group->tasks = g_slist_remove (ttask->group->tasks, ttask);
+
+ if (!ttask->group->tasks)
+ tasklist_group_destroy (ttask->group);
+ else
+ fixup_vtask (ttask->group, GINT_TO_POINTER (FALSE));
+ }
+
+ tasklist->vtasks = g_slist_remove (tasklist->vtasks, ttask);
+
+ g_free (ttask);
+
+ tasklist_layout_tasklist (tasklist);
+}
+
+static TasklistTask *
+tasklist_group_new (TasklistTask *first_task, char *group_name)
+{
+ TasklistTask *group;
+
+ g_return_val_if_fail (first_task != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ group = g_new0 (TasklistTask, 1);
+ group->tasklist = first_task->tasklist;
+ group->task_group = TRUE;
+ group->group_name = group_name;
+ group->fullwidth = -1;
+ g_hash_table_insert (group->tasklist->groups, group_name, group);
+
+ gdk_pixbuf_ref (first_task->icon->normal);
+ gdk_pixbuf_ref (first_task->icon->minimized);
+
+ group->icon = g_new (TasklistIcon, 1);
+ group->icon->normal = first_task->icon->normal;
+ group->icon->minimized = first_task->icon->minimized;
+
+ group->tasks = g_slist_prepend (group->tasks, first_task);
+
+ group->gwmh_task = g_new0 (GwmhTask, 1);
+ group->gwmh_task->name = group_name;
+
+ return group;
+}
+
+/*
+ * this is void since we don't need to get the return value when a
+ * task is created and we can just create a lot of tasks from the gwmh
+ * task glist
+ */
+
+static void
+tasklist_task_new (GwmhTask *gtask, Tasklist *tasklist)
+{
+ TasklistTask *ttask;
+ char *class;
+
+ g_return_if_fail (gtask != NULL);
+ g_return_if_fail (tasklist != NULL);
+ g_return_if_fail (tasklist->tasks != NULL);
+
+ d(g_print ("Adding task: %s\n", gtask->name));
+
+ ttask = g_new0 (TasklistTask, 1);
+
+ ttask->tasklist = tasklist;
+ ttask->gwmh_task = gtask;
+
+ g_hash_table_insert (tasklist->tasks, gtask, ttask);
+
+ ttask->wmhints_icon = tasklist_icon_get_pixmap (ttask);
+
+ tasklist_icon_set (ttask);
+ ttask->fullwidth = -1;
+
+ class = get_task_class (gtask);
+ if (!class)
+ return;
+
+ ttask->group = g_hash_table_lookup (tasklist->groups, class);
+
+ if (!ttask->group)
+ ttask->group = tasklist_group_new (ttask, class);
+ else {
+ ttask->group->tasks = g_slist_prepend (ttask->group->tasks, ttask);
+ g_free (class);
+ fixup_vtask (ttask->group, GINT_TO_POINTER (TRUE));
+ }
+}
+
+
/* This routine gets called when tasks are created/destroyed etc */
-gboolean
+static gboolean
task_notifier (gpointer func_data, GwmhTask *gwmh_task,
GwmhTaskNotifyType ntype,
GwmhTaskInfoMask imask)
{
- gboolean que_draw, que_layout;
- static gint master_serial_number = 0;
+ Tasklist *tasklist = (Tasklist *) func_data;
TasklistTask *task;
-
+ gboolean resize = FALSE;
+
switch (ntype)
{
case GWMH_NOTIFY_INFO_CHANGED:
- que_draw = FALSE;
- que_layout = FALSE;
- task = find_gwmh_task (gwmh_task);
+ task = g_hash_table_lookup (tasklist->tasks, gwmh_task);
+ if (!task) {
+ g_warning ("Getting info about task we don't know about: %p", gwmh_task);
+ break;
+ }
+
+ if (imask & GWMH_TASK_INFO_FOCUSED && task->gwmh_task->focused && task->group)
+ task->group->focused_task = task;
+
+ /* we only need to re-layout if the task has changed
+ * visibility status. If it has, its group will also get fixed up
+ */
+
+ /* this probably should be optimized and only done when the title changes */
+ resize = (tasklist->config.vert_width_full &&
+ (tasklist->orient == ORIENT_LEFT || tasklist->orient == ORIENT_RIGHT));
+ task->fullwidth = -1;
+
+ if (fixup_vtask (task, GINT_TO_POINTER (FALSE))) {
+ if (resize)
+ tasklist_change_size (tasklist, TRUE, -1);
+ else
+ tasklist_layout_tasklist (tasklist);
+ } else {
+ if (resize)
+ tasklist_change_size (tasklist, TRUE, -1);
+ else
+ tasklist_draw_task (task->group && is_task_really_visible (task->group)
+ ? task->group : task, NULL);
+ }
+#if 0
if (imask & GWMH_TASK_INFO_WM_HINTS) {
- task->fullwidth = -1;
- if (tasklist_icon_get_pixmap (task) !=
- task->wmhints_icon) {
- tasklist_icon_destroy (task);
- tasklist_icon_set (task);
- que_draw = TRUE;
+ if (tasklist_icon_get_pixmap (task) != task->wmhints_icon) {
+ tasklist_icon_destroy (tasklist, task);
+ tasklist_icon_set (tasklist, task);
+ tasklist_draw_task (tasklist, task, NULL);
}
}
if (imask & GWMH_TASK_INFO_GSTATE)
- que_layout = TRUE;
- if (imask & GWMH_TASK_INFO_ICONIFIED) {
- task->fullwidth = -1;
- que_layout = TRUE;
- }
+ tasklist_layout_tasklist (tasklist);
+ if (imask & GWMH_TASK_INFO_ICONIFIED)
+ tasklist_layout_tasklist (tasklist);
+
if (imask & GWMH_TASK_INFO_FOCUSED)
- que_draw = TRUE;
- if (imask & GWMH_TASK_INFO_MISC) {
- task->fullwidth = -1;
- que_draw = TRUE;
-
- /* this might change the size,
- * if width full is on. */
- if (Config.vert_width_full &&
- (tasklist_orient == ORIENT_LEFT ||
- tasklist_orient == ORIENT_RIGHT))
- que_layout = TRUE;
- }
+ tasklist_draw_task (tasklist, task, NULL);
+ if (imask & GWMH_TASK_INFO_MISC)
+ tasklist_draw_task (tasklist, task, NULL);
if (imask & GWMH_TASK_INFO_DESKTOP) {
- if ( ! Config.all_desks_minimized ||
- ! Config.all_desks_normal)
- que_layout = TRUE;
- }
+ if (tasklist->config.all_desks_minimized &&
+ tasklist->config.all_desks_normal)
+ break;
if (que_layout)
/* Redraw entire tasklist */
- layout_tasklist (TRUE);
- else if (que_draw)
- /* We can get away with redrawing the task only */
- draw_task (task, NULL);
+ tasklist_layout_tasklist (tasklist);
+ }
+#endif
break;
case GWMH_NOTIFY_NEW:
- task = g_malloc0 (sizeof (TasklistTask));
- task->gwmh_task = gwmh_task;
- task->wmhints_icon = tasklist_icon_get_pixmap (task);
- tasklist_icon_set (task);
- task->serial_number = master_serial_number++; /* wrapping seems unlikely :-) */
- tasks = g_list_insert_sorted (tasks, task, tasklist_sorting_compare_func);
- layout_tasklist (TRUE);
+ tasklist_task_new (gwmh_task, tasklist);
+ tasklist_layout_tasklist (tasklist);
break;
case GWMH_NOTIFY_DESTROY:
- task = find_gwmh_task (gwmh_task);
- if(task) {
- tasks = g_list_remove (tasks, task);
- if (task == motion_task) {
- motion_task = NULL;
- }
- tasklist_icon_destroy (task);
- if(task->menu)
- gtk_widget_destroy(task->menu);
- g_free (task);
- layout_tasklist (TRUE);
- }
+ tasklist_task_destroy (gwmh_task, tasklist);
break;
default:
- g_print ("Unknown ntype: %d\n", ntype);
+ d(g_print ("Unknown ntype: %d\n", ntype));
}
return TRUE;
}
/* Show the task if need. Return TRUE if so */
-gboolean
-show_task (TasklistTask *task)
+static gboolean
+show_task (Tasklist *tasklist, TasklistTask *task)
{
- if (GWMH_TASK_ICONIFIED (task->gwmh_task) || !GWMH_TASK_FOCUSED (task->gwmh_task)) {
-
- if (!(Config.move_to_current && GWMH_TASK_ICONIFIED (task->gwmh_task))) {
- GwmhDesk *desk_info;
- desk_info = gwmh_desk_get_config ();
-
- if (task->gwmh_task->desktop != desk_info->current_desktop ||
- task->gwmh_task->harea != desk_info->current_harea ||
- task->gwmh_task->varea != desk_info->current_varea) {
- gwmh_desk_set_current_area (task->gwmh_task->desktop,
- task->gwmh_task->harea,
- task->gwmh_task->varea);
- }
- }
+ if (!GWMH_TASK_ICONIFIED (task->gwmh_task) && GWMH_TASK_FOCUSED (task->gwmh_task))
+ return FALSE;
+
- gwmh_task_show (task->gwmh_task);
- /* Why is a focus needed here?
- gwmh_task_show is supposed to give focus */
- gwmh_task_focus (task->gwmh_task);
- gwmh_task_focus (task->gwmh_task);
-
+ if (!(tasklist->config.move_to_current && GWMH_TASK_ICONIFIED (task->gwmh_task))) {
+ GwmhDesk *desk_info;
+ desk_info = gwmh_desk_get_config ();
- return TRUE;
+ if (task->gwmh_task->desktop != desk_info->current_desktop ||
+ task->gwmh_task->harea != desk_info->current_harea ||
+ task->gwmh_task->varea != desk_info->current_varea) {
+ gwmh_desk_set_current_area (task->gwmh_task->desktop,
+ task->gwmh_task->harea,
+ task->gwmh_task->varea);
+ }
}
- return FALSE;
+ gwmh_task_show (task->gwmh_task);
+#if 0
+ /* Why is a focus needed here?
+ gwmh_task_show is supposed to give focus */
+
+ /*
+ * i think this is a sawfish bug: when "give
+ * uniconised windows focused" is unchecked it
+ * probably doesn't reassign focus. -- jacob
+ */
+
+ gwmh_task_focus (task->gwmh_task);
+ gwmh_task_focus (task->gwmh_task);
+
+#endif
+ return TRUE;
}
/* This routine gets called when the mouse is pressed */
-gboolean
-cb_button_press_event (GtkWidget *widget, GdkEventButton *event)
+static gboolean
+cb_button_press_event (GtkWidget *widget, GdkEventButton *event, Tasklist *tasklist)
{
TasklistTask *task;
- task = task_get_xy ((gint)event->x, (gint)event->y);
+ task = task_get_xy (tasklist, (gint)event->x, (gint)event->y);
if (!task)
return FALSE;
if (event->button == 1) {
-
- if (! show_task (task)) {
+ if (task->task_group)
+ tasklist_group_popup (task, event->button, event->time);
+ else if (! show_task (tasklist, task))
gwmh_task_iconify (task->gwmh_task);
- }
-
+
return TRUE;
}
-
+
if (event->button == 3) {
gtk_signal_emit_stop_by_name (GTK_OBJECT (widget),
"button_press_event");
- menu_popup (task, event->button, event->time);
+ tasklist_menu_popup (task, event->button, event->time);
return TRUE;
}
return FALSE;
}
-void
-cb_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time)
+static void
+cb_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, Tasklist *tasklist)
+{
+ if (tasklist->motion_timeout) {
+ gtk_timeout_remove (tasklist->motion_timeout);
+ tasklist->motion_timeout = 0;
+ tasklist->motion_task = NULL;
+ }
+}
+
+static gboolean
+cb_motion_timeout (gpointer user_data)
{
- if (motion_timeout) {
- gtk_timeout_remove (motion_timeout);
- motion_timeout = 0;
- motion_task = NULL;
+ Tasklist *tasklist = user_data;
+
+ if (tasklist->motion_task) {
+ show_task (tasklist, tasklist->motion_task);
}
+
+ tasklist->motion_timeout = 0;
+ tasklist->motion_task = NULL;
+
+ return FALSE;
}
/* This routine gets called when user drag something over the tasklist */
-gboolean
-cb_drag_motion (GtkWidget *widget, GdkDragContext *context, int x, int y, guint time)
+static gboolean
+cb_drag_motion (GtkWidget *widget, GdkDragContext *context, int x, int y, guint time, Tasklist *tasklist)
{
TasklistTask *task;
gdk_drag_status (context, 0, time);
- task = task_get_xy (x, y);
+ task = task_get_xy (tasklist, x, y);
- if (task != motion_task) {
+ if (task != tasklist->motion_task) {
- if (motion_timeout) {
- gtk_timeout_remove (motion_timeout);
+ if (tasklist->motion_timeout) {
+ gtk_timeout_remove (tasklist->motion_timeout);
}
- motion_task = task;
+ tasklist->motion_task = task;
if (task) {
- motion_timeout = gtk_timeout_add (MOTION_TIMEOUT, cb_motion_timeout, widget);
+ tasklist->motion_timeout = gtk_timeout_add (MOTION_TIMEOUT, cb_motion_timeout, tasklist);
} else {
- motion_timeout = 0;
+ tasklist->motion_timeout = 0;
}
}
return TRUE;
}
-gboolean
-cb_motion_timeout (gpointer data)
-{
- if (motion_task) {
- show_task (motion_task);
- }
-
- motion_timeout = 0;
- motion_task = NULL;
-
- return FALSE;
-}
-
/* This routine gets called when the tasklist is exposed */
-gboolean
-cb_expose_event (GtkWidget *widget, GdkEventExpose *event)
+static gboolean
+cb_expose_event (GtkWidget *widget, GdkEventExpose *event, Tasklist *tasklist)
{
- GList *temp_tasks, *temp;
+ GSList *temp_tasks, *temp;
TasklistTask *task;
- temp_tasks = get_visible_tasks ();
+ temp_tasks = tasklist->vtasks;
- gtk_paint_flat_box (area->style, area->window,
- area->state, GTK_SHADOW_NONE,
- &event->area, area, "button",
+ gtk_paint_flat_box (tasklist->area->style, tasklist->area->window,
+ tasklist->area->state, GTK_SHADOW_NONE,
+ &event->area, tasklist->area, "button",
0, 0, -1, -1);
for (temp = temp_tasks; temp != NULL; temp = temp->next) {
@@ -825,30 +1178,29 @@
rect.height = task->height;
if(gdk_rectangle_intersect(&event->area, &rect, &dest))
- draw_task (task, &dest);
+ tasklist_draw_task (task, &dest);
}
- if (temp_tasks != NULL)
- g_list_free (temp_tasks);
-
return FALSE;
}
/* This routine gets called when the user selects "properties" */
static void
-cb_properties (void)
+cb_properties (AppletWidget *applet, Tasklist *tasklist)
{
- display_properties ();
+ tasklist_display_properties (tasklist);
}
/* This routine gets called when the user selects "about" */
static void
-cb_about (void)
+cb_about (AppletWidget *applet, Tasklist *tasklist)
{
static GtkWidget *dialog = NULL;
const char *authors[] = {
"Anders Carlsson (andersca gnu org)",
+ "Miguel de Icaza (miguel ximian com)",
+ "Jacob Berkman (jacob ximian com)",
NULL
};
@@ -860,12 +1212,13 @@
return;
}
- dialog = gnome_about_new ("Gnome Tasklist",
- VERSION,
- "Copyright (C) 1999 Anders Carlsson",
- authors,
- "A tasklist for the GNOME desktop environment.\nIcons by Tuomas Kuosmanen (tigert gimp org).",
- NULL);
+ dialog = gnome_about_new (
+ "Gnome Tasklist",
+ VERSION,
+ _("Copyright (C) 1999 Anders Carlsson"),
+ authors,
+ _("A tasklist for the GNOME desktop environment.\nIcons by Tuomas Kuosmanen (tigert gimp org)."),
+ NULL);
gtk_signal_connect (GTK_OBJECT(dialog), "destroy",
GTK_SIGNAL_FUNC(gtk_widget_destroyed), &dialog);
@@ -875,223 +1228,264 @@
/* Ignore mouse button 1 clicks */
static gboolean
-ignore_1st_click (GtkWidget *widget, GdkEvent *event)
+ignore_1st_click (GtkWidget *widget, GdkEvent *event, Tasklist *tasklist)
{
GdkEventButton *buttonevent = (GdkEventButton *)event;
if (event->type == GDK_BUTTON_PRESS &&
buttonevent->button == 1) {
- if (buttonevent->window != area->window)
+ if (buttonevent->window != tasklist->area->window)
buttonevent->button = 2;
}
if (event->type == GDK_BUTTON_RELEASE &&
buttonevent->button == 1) {
- if (buttonevent->window != area->window)
+ if (buttonevent->window != tasklist->area->window)
buttonevent->button = 2;
}
return FALSE;
}
-
+
/*
* Resort the task list.
* (This is only here because tasks and tasklist_sorting_compare_func
* are not globally defined.)
*/
void
-resort_tasklist (void)
+resort_tasklist (Tasklist *tasklist)
{
- tasks = g_list_sort (tasks, tasklist_sorting_compare_func);
+ tasklist->vtasks = g_slist_sort (tasklist->vtasks, tlsort);
}
/* Changes size of the applet */
void
-change_size (gboolean layout, int fullwidth)
+tasklist_change_size (Tasklist *tasklist, gboolean layout, int fullwidth)
{
gboolean force_change = FALSE;
- static int old_handle_width = -1;
- static int old_handle_height = -1;
- static int old_width = -1;
- static int old_height = -1;
int handle_width = 0;
int handle_height = 0;
int width = 0;
int height = 0;
+
- switch (applet_widget_get_panel_orient (APPLET_WIDGET (applet))) {
+ switch (applet_widget_get_panel_orient (APPLET_WIDGET (tasklist->applet))) {
case ORIENT_UP:
case ORIENT_DOWN:
-/* if (Config.horz_fixed)
- horz_width = Config.horz_width;
- else
- horz_width = 4;*/
+ width = tasklist->horz_width;
+ handle_width = tasklist->horz_width + DRAG_HANDLE_SIZE;
+ height = handle_height = get_horz_rows (tasklist) * ROW_HEIGHT;
- width = horz_width;
- handle_width = DRAG_HANDLE_SIZE + horz_width;
- height = handle_height = get_horz_rows() * ROW_HEIGHT;
-
- if (GTK_HANDLE_BOX (handle)->handle_position != GTK_POS_LEFT) {
- GTK_HANDLE_BOX (handle)->handle_position = GTK_POS_LEFT;
- force_change = TRUE;
- }
+ GTK_HANDLE_BOX (tasklist->handle)->handle_position = GTK_POS_LEFT;
break;
case ORIENT_LEFT:
case ORIENT_RIGHT:
-/* if (Config.vert_fixed)
- vert_height = Config.vert_height;
- else
- vert_height = 4;*/
-
- if (Config.follow_panel_size)
- width = panel_size;
- else
- width = Config.vert_width;
-
- if (Config.vert_width_full) {
- if (fullwidth < 0) {
- GList *temp_tasks = get_visible_tasks ();
+ width = tasklist->config.follow_panel_size
+ ? tasklist->panel_size
+ : tasklist->config.vert_width;
+
+ if (tasklist->config.vert_width_full) {
+ if (fullwidth < 0)
+ fullwidth = max_width (tasklist->vtasks);
- fullwidth = max_width (temp_tasks);
-
- g_list_free (temp_tasks);
- }
-
- if (fullwidth > width)
- width = fullwidth;
+ width = MAX (width, fullwidth);
}
- if (GTK_HANDLE_BOX (handle)->handle_position != GTK_POS_TOP) {
- GTK_HANDLE_BOX (handle)->handle_position = GTK_POS_TOP;
- force_change = TRUE;
- }
-
handle_width = width;
- handle_height = vert_height + DRAG_HANDLE_SIZE;
- height = vert_height;
- }
-
- if (force_change ||
- old_width != width ||
- old_height != height ||
- old_handle_width != handle_width ||
- old_handle_height != handle_height) {
- gtk_widget_set_usize (handle,
- handle_width,
- handle_height);
- gtk_drawing_area_size (GTK_DRAWING_AREA (area),
- width, height);
- old_width = width;
- old_height = height;
- old_handle_width = handle_width;
- old_handle_height = handle_height;
+ handle_height = tasklist->vert_height + DRAG_HANDLE_SIZE;
+ height = tasklist->vert_height;
+
+ GTK_HANDLE_BOX (tasklist->handle)->handle_position = GTK_POS_TOP;
}
+ gtk_widget_set_usize (tasklist->handle, handle_width, handle_height);
+ gtk_drawing_area_size (GTK_DRAWING_AREA (tasklist->area), width, height);
+
if (layout)
- layout_tasklist (FALSE);
+ tasklist_layout_tasklist (tasklist);
}
/* Called when the panel's orient changes */
static void
-cb_change_orient (GtkWidget *widget, GNOME_Panel_OrientType orient)
+cb_change_orient (GtkWidget *widget, GNOME_Panel_OrientType orient, Tasklist *tasklist)
{
-
- tasklist_orient = orient;
+ tasklist->orient = orient;
/* Change size accordingly */
- change_size (TRUE, -1);
+ tasklist_change_size (tasklist, TRUE, -1);
}
static void
-cb_change_pixel_size (GtkWidget *widget, int size)
+cb_change_pixel_size (GtkWidget *widget, int size, Tasklist *tasklist)
{
- panel_size = size;
+ tasklist->panel_size = size;
/* Change size accordingly */
- if(Config.follow_panel_size)
- change_size (TRUE, -1);
+ if(tasklist->config.follow_panel_size)
+ tasklist_change_size (tasklist, TRUE, -1);
}
static void
-cb_help (GtkWidget *w, gpointer data)
+cb_help (AppletWidget *w, Tasklist *tasklist)
{
GnomeHelpMenuEntry help_entry = { "tasklist_applet",
"index.html" };
gnome_help_display(NULL, &help_entry);
}
+static void
+tasklist_destroy (GtkObject *applet_widget, Tasklist *tasklist)
+{
+ gwmh_task_notifier_remove (tasklist->task_notifier_id);
+ gwmh_desk_notifier_remove (tasklist->desk_notifier_id);
+
+ tasklist->task_notifier_id = -1;
+ tasklist->desk_notifier_id = -1;
+}
+
/* Create the applet */
-void
-create_applet (void)
+static Tasklist *
+tasklist_new (void)
{
+ Tasklist *tasklist;
GtkWidget *hbox;
+
+ tasklist = g_new0 (Tasklist, 1);
+ tasklist->panel_size = 48;
+ tasklist->horz_width = 0;
+ tasklist->vert_height = 0;
+
+ tasklist->applet = applet_widget_new ("tasklist_applet");
+ if (!tasklist->applet) {
+ g_warning (_("Tasklist: Unable to create applet widget"));
+ g_free (tasklist);
+ return NULL;
+ }
- applet = applet_widget_new ("tasklist_applet");
+#warning should we be doing this?
+ /* gtk_widget_ref (tasklist->applet); */
hbox = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox);
+
+ tasklist->handle = gtk_handle_box_new ();
+ gtk_signal_connect (GTK_OBJECT (tasklist->handle), "event",
+ GTK_SIGNAL_FUNC (ignore_1st_click), tasklist);
+
+ tasklist->area = gtk_drawing_area_new ();
+
+ gtk_widget_ensure_style (tasklist->area);
+ tasklist->unknown_icon = g_new (TasklistIcon, 1);
+ tasklist->unknown_icon->normal = gdk_pixbuf_new_from_xpm_data (unknown_xpm);
+ tasklist->unknown_icon->minimized = tasklist_icon_create_minimized_icon (tasklist, tasklist->unknown_icon->normal);
+
+#if 0
+ gtk_container_add (GTK_CONTAINER (tasklist->handle), tasklist->area);
+#endif
+
/* we must bind signals BEFORE applet_widget_add to avoid
* a race */
- gtk_signal_connect (GTK_OBJECT (applet), "change-orient",
- GTK_SIGNAL_FUNC (cb_change_orient), NULL);
- gtk_signal_connect (GTK_OBJECT (applet), "save-session",
- GTK_SIGNAL_FUNC (write_config), NULL);
- gtk_signal_connect (GTK_OBJECT (applet), "change-pixel-size",
- GTK_SIGNAL_FUNC (cb_change_pixel_size), NULL);
-
- applet_widget_add (APPLET_WIDGET (applet), hbox);
-
- handle = gtk_handle_box_new ();
- gtk_signal_connect (GTK_OBJECT (handle), "event",
- GTK_SIGNAL_FUNC (ignore_1st_click), NULL);
-
- area = gtk_drawing_area_new ();
-
- gtk_widget_show (area);
- gtk_widget_show (handle);
- gtk_container_add (GTK_CONTAINER (handle), area);
- gtk_container_add (GTK_CONTAINER (hbox), handle);
+ gtk_signal_connect (GTK_OBJECT (tasklist->applet), "change-orient",
+ GTK_SIGNAL_FUNC (cb_change_orient), tasklist);
+ gtk_signal_connect (GTK_OBJECT (tasklist->applet), "save-session",
+ GTK_SIGNAL_FUNC (tasklist_write_config), tasklist);
+ gtk_signal_connect (GTK_OBJECT (tasklist->applet), "change-pixel-size",
+ GTK_SIGNAL_FUNC (cb_change_pixel_size), tasklist);
- gtk_widget_set_events (area, GDK_EXPOSURE_MASK |
+ gtk_widget_set_events (tasklist->area, GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK);
- gtk_signal_connect (GTK_OBJECT (area), "expose_event",
- GTK_SIGNAL_FUNC (cb_expose_event), NULL);
- gtk_signal_connect (GTK_OBJECT (area), "button_press_event",
- GTK_SIGNAL_FUNC (cb_button_press_event), NULL);
- gtk_signal_connect (GTK_OBJECT (area), "drag_motion",
- GTK_SIGNAL_FUNC (cb_drag_motion), NULL);
- gtk_signal_connect (GTK_OBJECT (area), "drag_leave",
- GTK_SIGNAL_FUNC (cb_drag_leave), NULL);
-
-
- gtk_drag_dest_set (GTK_WIDGET (area), 0,
- NULL, 0, GDK_ACTION_COPY);
-
- applet_widget_register_stock_callback (APPLET_WIDGET (applet),
- "properties",
- GNOME_STOCK_MENU_PROP,
- _("Properties..."),
- (AppletCallbackFunc) cb_properties,
- NULL);
- applet_widget_register_stock_callback (APPLET_WIDGET (applet),
- "help",
- GNOME_STOCK_PIXMAP_HELP,
- _("Help"),
- (AppletCallbackFunc) cb_help,
- NULL);
-
- applet_widget_register_stock_callback (APPLET_WIDGET (applet),
- "about",
- GNOME_STOCK_MENU_ABOUT,
- _("About..."),
- (AppletCallbackFunc) cb_about,
- NULL);
+ gtk_signal_connect (GTK_OBJECT (tasklist->area), "expose_event",
+ GTK_SIGNAL_FUNC (cb_expose_event), tasklist);
+ gtk_signal_connect (GTK_OBJECT (tasklist->area), "button_press_event",
+ GTK_SIGNAL_FUNC (cb_button_press_event), tasklist);
+ gtk_signal_connect (GTK_OBJECT (tasklist->area), "drag_motion",
+ GTK_SIGNAL_FUNC (cb_drag_motion), tasklist);
+ gtk_signal_connect (GTK_OBJECT (tasklist->area), "drag_leave",
+ GTK_SIGNAL_FUNC (cb_drag_leave), tasklist);
+
+ gtk_drag_dest_set (GTK_WIDGET (tasklist->area), 0,
+ NULL, 0, GDK_ACTION_COPY);
+
+ /*
+ * we add the area *after* the widget so that we get events on it
+ */
+ gtk_container_add (GTK_CONTAINER (hbox), tasklist->handle);
+ applet_widget_add (APPLET_WIDGET (tasklist->applet), hbox);
+ gtk_container_add (GTK_CONTAINER (tasklist->handle), tasklist->area);
+
+ tasklist_read_config (tasklist);
+
+ applet_widget_register_stock_callback (
+ APPLET_WIDGET (tasklist->applet),
+ "properties",
+ GNOME_STOCK_MENU_PROP,
+ _("Properties..."),
+ (AppletCallbackFunc) cb_properties,
+ tasklist);
+
+ applet_widget_register_stock_callback (
+ APPLET_WIDGET (tasklist->applet),
+ "help",
+ GNOME_STOCK_PIXMAP_HELP,
+ _("Help"),
+ (AppletCallbackFunc) cb_help,
+ tasklist);
+
+ applet_widget_register_stock_callback (
+ APPLET_WIDGET (tasklist->applet),
+ "about",
+ GNOME_STOCK_MENU_ABOUT,
+ _("About..."),
+ (AppletCallbackFunc) cb_about,
+ tasklist);
+
+ tasklist->panel_size = applet_widget_get_panel_pixel_size(APPLET_WIDGET(tasklist->applet));
+ tasklist->orient = applet_widget_get_panel_orient(APPLET_WIDGET(tasklist->applet));
+
+ tasklist->task_notifier_id = gwmh_task_notifier_add (task_notifier, tasklist);
+ tasklist->desk_notifier_id = gwmh_desk_notifier_add (desk_notifier, tasklist);
+
+ gtk_signal_connect (GTK_OBJECT (tasklist->applet), "destroy",
+ GTK_SIGNAL_FUNC (tasklist_destroy), tasklist);
+
+ gtk_widget_show_all (tasklist->area);
+ gtk_widget_show_all (tasklist->handle);
+
+ tasklist_change_size (tasklist, TRUE, -1);
+
+ tasklist->tasks = g_hash_table_new (g_direct_hash, g_direct_equal);
+ tasklist->groups = g_hash_table_new (g_str_hash, g_str_equal);
+
+ g_list_foreach (gwmh_task_list_get (), (GFunc)tasklist_task_new, tasklist);
+
+ return tasklist;
+}
+
+static void
+tasklist_init (void)
+{
+ gwmh_init ();
+}
+
+static void
+tasklist_freeze (Tasklist *tasklist)
+{
+ tasklist->frozen = TRUE;
}
+static void
+tasklist_thaw (Tasklist *tasklist)
+{
+ tasklist->frozen = FALSE;
+}
+
+#ifdef APPLET_COMPILE_AS_PROCESS
gint
main (gint argc, gchar *argv[])
{
+ Tasklist *tasklist;
+
/* Initialize i18n */
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
textdomain (PACKAGE);
@@ -1108,25 +1502,76 @@
gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
gtk_widget_set_default_visual (gdk_rgb_get_visual ());
- gwmh_init ();
- gwmh_task_notifier_add (task_notifier, NULL);
- gwmh_desk_notifier_add (desk_notifier, NULL);
+ tasklist_init ();
- create_applet ();
+ tasklist = create_applet ();
- read_config ();
- panel_size = applet_widget_get_panel_pixel_size(APPLET_WIDGET(applet));
- tasklist_orient = applet_widget_get_panel_orient(APPLET_WIDGET(applet));
+ tasklist_change_size (tasklist, TRUE);
- change_size (TRUE, -1);
-
gtk_widget_show (applet);
- unknown_icon = g_new (TasklistIcon, 1);
- unknown_icon->normal = gdk_pixbuf_new_from_xpm_data (unknown_xpm);
- unknown_icon->minimized = tasklist_icon_create_minimized_icon (unknown_icon->normal);
-
applet_widget_gtk_main ();
return 0;
}
+#else
+static GtkWidget *
+make_new_applet (const char *goad_id)
+{
+ static int inited = 0;
+ Tasklist *tasklist;
+
+ if (!inited){
+ tasklist_init ();
+ inited = 1;
+ }
+ tasklist = tasklist_new ();
+
+ if (!tasklist)
+ return NULL;
+
+ gtk_widget_show_all (tasklist->applet);
+
+ return tasklist->applet;
+}
+
+static CORBA_Object
+activator (PortableServer_POA poa,
+ const char *goad_id,
+ const char **params,
+ gpointer *impl_ptr,
+ CORBA_Environment *ev)
+{
+ GtkWidget *widget;
+
+ widget = make_new_applet (goad_id);
+ if (widget == NULL) {
+ g_warning (_("Don't know how to activate `%s'\n"), goad_id);
+ return CORBA_OBJECT_NIL;
+ }
+
+ return applet_widget_corba_activate (widget, poa, goad_id,
+ params, impl_ptr, ev);
+}
+static void
+deactivator (PortableServer_POA poa,
+ const char *goad_id,
+ gpointer impl_ptr,
+ CORBA_Environment *ev)
+{
+ applet_widget_corba_deactivate (poa, goad_id, impl_ptr, ev);
+}
+
+static const char *repo_id[]={ "IDL:GNOME/Applet:1.0", NULL };
+static GnomePluginObject applets_list[] = {
+ { repo_id, "tasklist_applet", NULL, "Task list applet",
+ &activator, &deactivator },
+ { NULL }
+};
+
+GnomePlugin GNOME_Plugin_info = {
+ applets_list,
+ NULL
+};
+
+#endif
Index: tasklist_applet.gnorba
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/tasklist/tasklist_applet.gnorba,v
retrieving revision 1.1
diff -u -r1.1 tasklist_applet.gnorba
--- tasklist_applet.gnorba 1999/07/05 22:11:39 1.1
+++ tasklist_applet.gnorba 2001/01/23 04:00:11
@@ -1,5 +1,5 @@
[tasklist_applet]
-type=exe
+type=shlib
repo_id=IDL:GNOME/Applet:1.0
description=GNOME Tasklist
-location_info=tasklist_applet
+location_info=libtasklist_applet.so
Index: tasklist_applet.h
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/tasklist/tasklist_applet.h,v
retrieving revision 1.28
diff -u -r1.28 tasklist_applet.h
--- tasklist_applet.h 2000/12/20 23:31:30 1.28
+++ tasklist_applet.h 2001/01/23 04:00:11
@@ -1,14 +1,15 @@
+#ifndef _TASKLIST_APPLET_H_
+#define _TASKLIST_APPLET_H_
+
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "applet-widget.h"
#include "gwmh.h"
-#ifndef TASKLIST_APPLET_H
-#define TASKLIST_APPLET_H
-
/* The row height of a task */
#define ROW_HEIGHT 24
+typedef struct _Tasklist Tasklist;
typedef struct _TasklistTask TasklistTask;
typedef struct _TasklistConfig TasklistConfig;
typedef struct _TasklistIcon TasklistIcon;
@@ -24,22 +25,52 @@
typedef enum
{
MENU_ACTION_CLOSE,
+ MENU_ACTION_SHOW,
+ MENU_ACTION_HIDE,
MENU_ACTION_SHOW_HIDE,
+ MENU_ACTION_SHADE,
+ MENU_ACTION_UNSHADE,
MENU_ACTION_SHADE_UNSHADE,
+ MENU_ACTION_STICK,
+ MENU_ACTION_UNSTICK,
MENU_ACTION_STICK_UNSTICK,
MENU_ACTION_KILL,
MENU_ACTION_LAST
} MenuAction;
struct _TasklistTask {
+ Tasklist *tasklist;
gint x, y;
gint width, height;
gint fullwidth;
TasklistIcon *icon;
Pixmap wmhints_icon;
- GwmhTask *gwmh_task;
GtkWidget *menu;
- gint serial_number; /* for sorting */
+
+ /*
+ * if we are a group, this is not a real task but a false one
+ * filled in with what the task group should be like
+ */
+ GwmhTask *gwmh_task;
+
+ /* this could be a union */
+ /* for real tasks */
+ TasklistTask *group;
+ GtkWidget *menuitem; /* the menuitem in the groups menu */
+
+ /* for task groups */
+ char *group_name;
+ GSList *tasks; /* all tasks in group */
+ GSList *vtasks; /* visible tasks in group */
+ TasklistTask *focused_task; /* the task in our group last focused */
+
+ /* whether we are in the vtasks list */
+ gboolean visible;
+ /* whether we are a task group */
+ gboolean task_group;
+
+ /* set when we get a notify that the gwmh window is destroyed */
+ gboolean destroyed;
};
struct _TasklistConfig {
@@ -51,46 +82,133 @@
gboolean all_desks_minimized; /* Show minimized tasks on all desktops */
gboolean confirm_before_kill; /* Confirm before killing windows */
gboolean move_to_current; /* Move iconified tasks to current workspace */
- gboolean sort_tasklist; /* show the task list in sorted order? */
/* Follow the panel sizes */
gboolean follow_panel_size;
+
+ /*
+ * Stuff for horizontal mode
+ */
+
+ /* The width of the tasklist */
+ gint horz_width;
+
+ /* Number of rows */
+ gint horz_rows;
+
+ /* Fixed or dynamic sizing */
+ gboolean horz_fixed;
+
+ /* Width of a single task (for dynamic sizing) */
+ gint horz_taskwidth;
+
+ /* in dynamic mode, never push applets */
+ gboolean horz_never_push;
+
+ /*
+ * Stuff for vertical mode
+ */
+ /* The height of the tasklist */
+ gint vert_height;
+
+ /* The width of the tasklist */
+ gint vert_width;
+
+ /* Fixed or dynamic sizing */
+ gboolean vert_fixed;
- /* Stuff for horizontal mode */
- gint horz_width; /* The width of the tasklist */
- gint horz_rows; /* Number of rows */
- gboolean horz_fixed; /* Fixed or dynamic sizing */
- gint horz_taskwidth; /* Width of a single task (for dynamic sizing) */
- gboolean horz_never_push; /* In dynamic mode, never push applets */
-
- /* Stuff for vertical mode */
- gint vert_height; /* The height of the tasklist */
- gint vert_width; /* The width of the tasklist */
- gboolean vert_fixed; /* Fixed or dynamic sizing */
- gboolean vert_width_full; /* a mode where th width is the maximum width */
- /* of any window title. */
- gboolean vert_never_push; /* In dynamic mode, never push applets */
+ /* a mode where the width is the max width of any window title */
+ gboolean vert_width_full;
+ /* in dynamic mode, never push applets */
+ gboolean vert_never_push;
+
+ /* grouping options */
+ gboolean enable_grouping;
+ gint grouping_min;
};
struct _TasklistIcon {
GdkPixbuf *normal;
GdkPixbuf *minimized;
};
+
+struct _Tasklist {
+ GNOME_Panel_OrientType orient; /* Tasklist orient */
+ GtkWidget *handle; /* The handle box */
+ GtkWidget *applet; /* The applet */
+ GtkWidget *area; /* The drawing area used to display tasks */
+
+ /* The list of tasks used */
+ GHashTable *tasks;
+
+ /* our task groups, grouped by WM_CLASS */
+ GHashTable *groups;
+
+ /*
+ * list of visible tasks. this should be set by the gwmh
+ * listner
+ */
+ GSList *vtasks;
+
+ /* idle timeout for re-laying out */
+ guint layout_timeout;
+#define MOTION_TIMEOUT 500 /* Show task motion_task if cursor over task for ... msec */
+
+ /* Show task motion_task after MOTION_TIMEOUT in drag_motion */
+ int motion_timeout;
+
+ /* Task to show after motion_timeout */
+ TasklistTask *motion_task;
+
+ /* Vertical height, used for resizing */
+ gint vert_height;
+
+ /* Horizontal width, used for resizing */
+ gint horz_width;
+
+ gint panel_size;
+
+ /* The configuration */
+ TasklistConfig config;
+ TasklistIcon *unknown_icon; /* The unknown icon */
+
+ /*
+ * Used during configuration editing
+ */
+ /* The tasklist properties configuration */
+ TasklistConfig PropsConfig;
+
+ /* The Property box */
+ GtkWidget *prop;
+
+ guint task_notifier_id;
+ guint desk_notifier_id;
+
+ gboolean frozen;
+};
-void menu_popup (TasklistTask *task, guint button, guint32 activate_time);
-void display_properties (void);
-void read_config (void);
-gboolean write_config (gpointer data,
- const gchar *privcfgpath,
- const gchar *globcfgpath);
-void resort_tasklist (void);
-/* fullwidth can be -1 so if it's to be recomputed (only if needed */
-void change_size (gboolean layout, int fullwidth);
-void layout_tasklist (gboolean call_change_size);
-GdkPixbuf *tasklist_icon_create_minimized_icon (GdkPixbuf *pixbuf);
-void tasklist_icon_set (TasklistTask *task);
-void tasklist_icon_destroy (TasklistTask *task);
-Pixmap tasklist_icon_get_pixmap (TasklistTask *task);
+void tasklist_menu_popup (TasklistTask *task, guint button,
+ guint32 activate_time);
+void tasklist_group_popup (TasklistTask *task, guint button,
+ guint32 activate_time);
+void tasklist_freeze (Tasklist *tasklist);
+void tasklist_thaw (Tasklist *tasklist);
+void tasklist_draw_task (TasklistTask *task, GdkRectangle *rect);
+void tasklist_display_properties (Tasklist *);
+void tasklist_read_config (Tasklist *);
+void tasklist_clean_menu (TasklistTask *);
+gboolean tasklist_write_config (GtkWidget *w,
+ const gchar *privcfgpath,
+ const gchar *globcfgpath,
+ gpointer data);
+gchar *tasklist_task_get_label (TasklistTask *, int, gboolean add_groupcount);
+void tasklist_change_size (Tasklist *, gboolean layout, int fullwidth);
+void tasklist_redo_vtasks (Tasklist *);
+void tasklist_layout_tasklist (Tasklist *tasklist);
+GdkPixbuf *tasklist_icon_create_minimized_icon (Tasklist *, GdkPixbuf *pixbuf);
+void tasklist_icon_set (TasklistTask *task);
+void tasklist_icon_destroy (TasklistTask *task);
+Pixmap tasklist_icon_get_pixmap (TasklistTask *task);
-#endif /* TASKLIST_APPLET_H */
+#endif /* _TASKLIST_APPLET_H_ */
Index: tasklist_config.c
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/tasklist/tasklist_config.c,v
retrieving revision 1.23
diff -u -r1.23 tasklist_config.c
--- tasklist_config.c 2000/12/20 23:31:30 1.23
+++ tasklist_config.c 2001/01/23 04:00:11
@@ -1,104 +1,75 @@
#include "tasklist_applet.h"
-/* The applet */
-extern GtkWidget *applet;
-
-/* The configuration */
-TasklistConfig Config;
-
-gboolean write_config (gpointer data,
- const gchar *privcfgpath,
- const gchar *globcfgpath)
+gboolean
+tasklist_write_config (GtkWidget *w, const gchar *privcfgpath, const gchar *globcfgpath, gpointer data)
{
+ Tasklist *tasklist = (Tasklist *) data;
+
gnome_config_push_prefix (privcfgpath
? privcfgpath
- : APPLET_WIDGET (applet)->privcfgpath);
-
- gnome_config_set_bool ("tasklist/follow_panel_size",
- Config.follow_panel_size);
+ : APPLET_WIDGET (tasklist->applet)->privcfgpath);
- gnome_config_set_bool ("tasklist/horz_fixed",
- Config.horz_fixed);
- gnome_config_set_int ("tasklist/horz_width",
- Config.horz_width);
- gnome_config_set_int ("tasklist/horz_rows",
- Config.horz_rows);
- gnome_config_set_int ("tasklist/horz_taskwidth",
- Config.horz_taskwidth);
- gnome_config_set_bool ("tasklist/horz_never_push",
- Config.horz_never_push);
-
- gnome_config_set_bool ("tasklist/vert_fixed",
- Config.vert_fixed);
- gnome_config_set_int ("tasklist/vert_height",
- Config.vert_height);
- gnome_config_set_int ("tasklist/vert_width",
- Config.vert_width);
- gnome_config_set_bool ("tasklist/vert_width_full",
- Config.vert_width_full);
- gnome_config_set_bool ("tasklist/vert_never_push",
- Config.vert_never_push);
-
-
- gnome_config_set_bool ("tasklist/show_mini_icons",
- Config.show_mini_icons);
- gnome_config_set_bool ("tasklist/show_normal",
- Config.show_normal);
- gnome_config_set_bool ("tasklist/show_minimized",
- Config.show_minimized);
-
- gnome_config_set_bool ("tasklist/all_desks_normal",
- Config.all_desks_normal);
- gnome_config_set_bool ("tasklist/all_desks_minimized",
- Config.all_desks_minimized);
-
- gnome_config_set_bool ("tasklist/confirm_before_kill",
- Config.confirm_before_kill);
- gnome_config_set_bool ("tasklist/move_to_current",
- Config.move_to_current);
- gnome_config_set_bool ("tasklist/sort_tasklist",
- /* XXX: see comment in
- * tasklist_applet.c:bool_compare_func for
- * what's wrong here */
- Config.sort_tasklist);
+ gnome_config_set_bool ("tasklist/follow_panel_size", tasklist->config.follow_panel_size);
+ gnome_config_set_bool ("tasklist/horz_fixed", tasklist->config.horz_fixed);
+ gnome_config_set_bool ("tasklist/horz_never_push", tasklist->config.horz_never_push);
+ gnome_config_set_int ("tasklist/horz_width", tasklist->config.horz_width);
+ gnome_config_set_int ("tasklist/horz_rows", tasklist->config.horz_rows);
+ gnome_config_set_int ("tasklist/horz_taskwidth", tasklist->config.horz_taskwidth);
+ gnome_config_set_bool ("tasklist/vert_fixed", tasklist->config.vert_fixed);
+ gnome_config_set_int ("tasklist/vert_height", tasklist->config.vert_height);
+ gnome_config_set_bool ("tasklist/vert_never_push", tasklist->config.vert_never_push);
+ gnome_config_set_int ("tasklist/vert_width", tasklist->config.vert_width);
+ gnome_config_set_int ("tasklist/vert_width_full", tasklist->config.vert_width_full);
+ gnome_config_set_bool ("tasklist/show_mini_icons", tasklist->config.show_mini_icons);
+ gnome_config_set_bool ("tasklist/show_normal", tasklist->config.show_normal);
+ gnome_config_set_bool ("tasklist/show_minimized", tasklist->config.show_minimized);
+ gnome_config_set_bool ("tasklist/all_desks_normal", tasklist->config.all_desks_normal);
+ gnome_config_set_bool ("tasklist/all_desks_minimized", tasklist->config.all_desks_minimized);
+ gnome_config_set_bool ("tasklist/confirm_before_kill", tasklist->config.confirm_before_kill);
+ gnome_config_set_bool ("tasklist/move_to_current", tasklist->config.move_to_current);
+ gnome_config_set_bool ("tasklist/enable_grouping", tasklist->config.enable_grouping);
+ gnome_config_set_int ("tasklist/grouping_min", tasklist->config.grouping_min);
+
gnome_config_sync ();
gnome_config_pop_prefix ();
return FALSE;
}
-void read_config (void)
+void
+tasklist_read_config (Tasklist *tasklist)
{
- gnome_config_push_prefix (APPLET_WIDGET (applet)->privcfgpath);
+ gnome_config_push_prefix (APPLET_WIDGET (tasklist->applet)->privcfgpath);
- Config.follow_panel_size = gnome_config_get_bool ("tasklist/follow_panel_size=true");
+ tasklist->config.follow_panel_size = gnome_config_get_bool ("tasklist/follow_panel_size=true");
- Config.horz_fixed = gnome_config_get_bool ("tasklist/horz_fixed=true");
+ tasklist->config.horz_fixed = gnome_config_get_bool ("tasklist/horz_fixed=true");
/* if the screen is not too wide, make it default to 300 */
if (gdk_screen_width () <= 800)
- Config.horz_width = gnome_config_get_int ("tasklist/horz_width=300");
+ tasklist->config.horz_width = gnome_config_get_int ("tasklist/horz_width=300");
else
- Config.horz_width = gnome_config_get_int ("tasklist/horz_width=450");
- Config.horz_rows = gnome_config_get_int ("tasklist/horz_rows=2");
- Config.horz_taskwidth = gnome_config_get_int ("tasklist/horz_taskwidth=150");
- Config.horz_never_push = gnome_config_get_bool ("tasklist/horz_never_push=true");
-
- Config.vert_fixed = gnome_config_get_bool ("tasklist/vert_fixed=true");
- Config.vert_width = gnome_config_get_int ("tasklist/vert_width=48");
- Config.vert_height = gnome_config_get_int ("tasklist/vert_height=300");
- Config.vert_width_full = gnome_config_get_bool ("tasklist/vert_width_full=false");
- Config.vert_never_push = gnome_config_get_bool ("tasklist/vert_never_push=true");
+ tasklist->config.horz_width = gnome_config_get_int ("tasklist/horz_width=450");
+ tasklist->config.horz_never_push = gnome_config_get_bool ("tasklist/horz_never_push=false");
+ tasklist->config.horz_rows = gnome_config_get_int ("tasklist/horz_rows=2");
+ tasklist->config.horz_taskwidth = gnome_config_get_int ("tasklist/horz_taskwidth=150");
+ tasklist->config.vert_fixed = gnome_config_get_bool ("tasklist/vert_fixed=true");
+ tasklist->config.vert_never_push = gnome_config_get_bool ("tasklist/vert_never_push=false");
+ tasklist->config.vert_width = gnome_config_get_int ("tasklist/vert_width=48");
+ tasklist->config.vert_width_full = gnome_config_get_bool ("tasklist/vert_width_full=false");
+ tasklist->config.vert_height = gnome_config_get_int ("tasklist/vert_height=300");
- Config.confirm_before_kill = gnome_config_get_bool ("tasklist/confirm_before_kill=true");
+ tasklist->config.confirm_before_kill = gnome_config_get_bool ("tasklist/confirm_before_kill=true");
- Config.show_mini_icons = gnome_config_get_bool ("tasklist/show_mini_icons=true");
- Config.show_normal = gnome_config_get_bool ("tasklist/show_normal=true");
- Config.show_minimized = gnome_config_get_bool ("tasklist/show_minimized=true");
- Config.all_desks_normal = gnome_config_get_bool ("tasklist/all_desks_normal=false");
- Config.all_desks_minimized = gnome_config_get_bool ("tasklist/all_desks_minimized=false");
- Config.move_to_current = gnome_config_get_bool ("tasklist/move_to_current=false");
- Config.sort_tasklist = gnome_config_get_bool ("tasklist/sort_tasklist=true");
+ tasklist->config.show_mini_icons = gnome_config_get_bool ("tasklist/show_mini_icons=true");
+ tasklist->config.show_normal = gnome_config_get_bool ("tasklist/show_normal=true");
+ tasklist->config.show_minimized = gnome_config_get_bool ("tasklist/show_minimized=true");
+ tasklist->config.all_desks_normal = gnome_config_get_bool ("tasklist/all_desks_normal=false");
+ tasklist->config.all_desks_minimized = gnome_config_get_bool ("tasklist/all_desks_minimized=false");
+ tasklist->config.move_to_current = gnome_config_get_bool ("tasklist/move_to_current=false");
+ tasklist->config.enable_grouping = gnome_config_get_bool ("tasklist/enable_grouping=true");
+ tasklist->config.grouping_min = gnome_config_get_int ("tasklist/grouping_min=3");
+
gnome_config_pop_prefix ();
}
Index: tasklist_icon.c
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/tasklist/tasklist_icon.c,v
retrieving revision 1.6
diff -u -r1.6 tasklist_icon.c
--- tasklist_icon.c 2000/11/15 05:13:08 1.6
+++ tasklist_icon.c 2001/01/23 04:00:11
@@ -10,9 +10,6 @@
static gboolean tasklist_icon_check_x (TasklistTask *task);
static void tasklist_icon_set_minimized (TasklistTask *task);
-extern GtkWidget *area; /* The drawing area used to display tasks */
-extern TasklistIcon *unknown_icon; /* The unknown icon */
-
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
/* Shamelessly stolen from gwmh.c by Tim Janik */
@@ -22,6 +19,9 @@
{
XWMHints *wmhints;
Pixmap pixmap;
+
+ if (task == NULL)
+ return 0;
wmhints = XGetWMHints (GDK_DISPLAY (), task->gwmh_task->xwin);
@@ -133,7 +133,8 @@
tasklist_icon_check_mini (TasklistTask *task)
{
GdkGC *gc;
- int x, y, b, width, height, depth;
+ int x, y;
+ guint b, width, height, depth;
guint32 *atomdata;
Window root;
GdkImage *image;
@@ -180,7 +181,7 @@
pixbuf = gdk_pixbuf_get_from_drawable (NULL,
pixmap,
- gtk_widget_get_colormap (area),
+ gtk_widget_get_colormap (task->tasklist->area),
0, 0,
0, 0,
width, height);
@@ -189,8 +190,8 @@
if (size > 1 && atomdata[1]) {
mask = gdk_pixmap_new (NULL, width, height, depth);
gc = gdk_gc_new (mask);
- gdk_gc_set_background (gc, &area->style->black);
- gdk_gc_set_foreground (gc, &area->style->white);
+ gdk_gc_set_background (gc, &task->tasklist->area->style->black);
+ gdk_gc_set_foreground (gc, &task->tasklist->area->style->white);
XCopyPlane (GDK_DISPLAY (), atomdata[1], GDK_WINDOW_XWINDOW (mask),
GDK_GC_XGC (gc), 0, 0, width, height, 0, 0, 1);
gdk_gc_unref (gc);
@@ -263,12 +264,12 @@
return FALSE;
}
- pixmap = gdk_pixmap_new (area->window, width, height, -1);
+ pixmap = gdk_pixmap_new (task->tasklist->area->window, width, height, -1);
gc = gdk_gc_new (pixmap);
if (depth == 1) {
- gdk_gc_set_background (gc, &area->style->white);
- gdk_gc_set_foreground (gc, &area->style->black);
+ gdk_gc_set_background (gc, &task->tasklist->area->style->white);
+ gdk_gc_set_foreground (gc, &task->tasklist->area->style->black);
XCopyPlane (GDK_DISPLAY (), wmhints->icon_pixmap, GDK_WINDOW_XWINDOW (pixmap),
GDK_GC_XGC (gc), 0, 0, width, height, 0, 0, 1);
}
@@ -276,7 +277,7 @@
XCopyArea (GDK_DISPLAY (), wmhints->icon_pixmap, GDK_WINDOW_XWINDOW (pixmap),
GDK_GC_XGC (gc), 0, 0, width, height, 0, 0);
}
- pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, gtk_widget_get_colormap (area),
+ pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, gtk_widget_get_colormap (task->tasklist->area),
0, 0,
0, 0, width, height);
gdk_gc_destroy (gc);
@@ -288,8 +289,8 @@
if (wmhints->flags & IconMaskHint) {
mask = gdk_pixmap_new (NULL, width, height, depth);
gc = gdk_gc_new (mask);
- gdk_gc_set_background (gc, &area->style->black);
- gdk_gc_set_foreground (gc, &area->style->white);
+ gdk_gc_set_background (gc, &task->tasklist->area->style->black);
+ gdk_gc_set_foreground (gc, &task->tasklist->area->style->white);
XCopyPlane (GDK_DISPLAY (), wmhints->icon_mask, GDK_WINDOW_XWINDOW (mask),
GDK_GC_XGC (gc), 0, 0, width, height, 0, 0, 1);
gdk_gc_unref (gc);
@@ -333,10 +334,13 @@
void
tasklist_icon_set (TasklistTask *task)
{
- task->icon = g_new (TasklistIcon, 1);
+ if (task == NULL)
+ return;
+
+ task->icon = g_new0 (TasklistIcon, 1);
- task->icon->normal = unknown_icon->normal;
- task->icon->minimized = unknown_icon->minimized;
+ task->icon->normal = task->tasklist->unknown_icon->normal;
+ task->icon->minimized = task->tasklist->unknown_icon->minimized;
if (!tasklist_icon_check_x (task))
tasklist_icon_check_mini (task);
@@ -349,19 +353,22 @@
tasklist_icon_set_minimized (TasklistTask *task)
{
if (task->icon->minimized &&
- task->icon->minimized != unknown_icon->minimized)
+ task->icon->minimized != task->tasklist->unknown_icon->minimized)
gdk_pixbuf_unref (task->icon->minimized);
- task->icon->minimized = tasklist_icon_create_minimized_icon (task->icon->normal);
+ task->icon->minimized = tasklist_icon_create_minimized_icon (task->tasklist, task->icon->normal);
}
void
tasklist_icon_destroy (TasklistTask *task)
{
- if (task->icon->normal != unknown_icon->normal)
+ if (task == NULL)
+ return;
+
+ if (task->icon->normal != task->tasklist->unknown_icon->normal)
gdk_pixbuf_unref (task->icon->normal);
- if (task->icon->minimized != unknown_icon->minimized)
+ if (task->icon->minimized != task->tasklist->unknown_icon->minimized)
gdk_pixbuf_unref (task->icon->minimized);
g_free (task->icon);
@@ -369,7 +376,7 @@
/* Stolen from gnome-pixmap.c */
GdkPixbuf *
-tasklist_icon_create_minimized_icon (GdkPixbuf *pixbuf)
+tasklist_icon_create_minimized_icon (Tasklist *tasklist, GdkPixbuf *pixbuf)
{
GdkPixbuf *target;
gint i, j;
@@ -380,7 +387,7 @@
gint32 red, green, blue;
GdkColor color;
- color = area->style->bg[GTK_STATE_NORMAL];
+ color = tasklist->area->style->bg[GTK_STATE_NORMAL];
red = color.red / 255;
blue = color.blue / 255;
green = color.green / 255;
Index: tasklist_menu.c
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/tasklist/tasklist_menu.c,v
retrieving revision 1.18
diff -u -r1.18 tasklist_menu.c
--- tasklist_menu.c 2000/12/20 22:34:23 1.18
+++ tasklist_menu.c 2001/01/23 04:00:11
@@ -4,31 +4,23 @@
#include "tasklist_applet.h"
#include "pixmaps.h"
-GtkWidget *get_popup_menu (TasklistTask *task);
-void add_menu_item (gchar *name, GtkWidget *menu, MenuAction action, gchar **xpm);
-gboolean cb_menu (GtkWidget *widget, gpointer data);
-void cb_to_desktop (GtkWidget *widget, gpointer data);
-void cb_menu_position (GtkMenu *menu, gint *x, gint *y, gpointer user_data);
-
-extern TasklistConfig Config;
-extern GtkWidget *area;
-extern GtkWidget *applet;
-TasklistTask *current_task;
+/* define to x for debug output */
+#define d(x)
/* Callback for menu positioning */
-void
+static void
cb_menu_position (GtkMenu *menu, gint *x, gint *y, gpointer user_data)
{
GtkRequisition mreq;
gint wx, wy;
- TasklistTask *task;
+ TasklistTask *task = gtk_object_get_data (GTK_OBJECT (menu), "task");
- current_task = task = (TasklistTask *)user_data;
+ g_return_if_fail (task != NULL);
gtk_widget_get_child_requisition (GTK_WIDGET (menu), &mreq);
- gdk_window_get_origin (area->window, &wx, &wy);
+ gdk_window_get_origin (task->tasklist->area->window, &wx, &wy);
- switch (applet_widget_get_panel_orient (APPLET_WIDGET (applet))) {
+ switch (applet_widget_get_panel_orient (APPLET_WIDGET (task->tasklist->applet))) {
case ORIENT_UP:
*x = wx + task->x;
*y = wy - mreq.height + task->y;
@@ -50,89 +42,132 @@
}
-/* Callback for menus */
-gboolean
-cb_menu (GtkWidget *widget, gpointer data)
+static gboolean
+do_action (TasklistTask *task, gpointer data)
{
- switch (GPOINTER_TO_INT (data)) {
+ MenuAction action = GPOINTER_TO_INT (data);
+ Tasklist *tasklist = task->tasklist;
+ GtkWidget *dialog;
+ gint retval;
+
+ switch (action) {
case MENU_ACTION_SHADE_UNSHADE:
- if (GWMH_TASK_SHADED (current_task->gwmh_task))
- gwmh_task_unset_gstate_flags (current_task->gwmh_task,
- GWMH_STATE_SHADED);
- else
- gwmh_task_set_gstate_flags (current_task->gwmh_task,
- GWMH_STATE_SHADED);
+ action = GWMH_TASK_SHADED (task->gwmh_task) ? MENU_ACTION_UNSHADE : MENU_ACTION_SHADE;
break;
case MENU_ACTION_STICK_UNSTICK:
- if (GWMH_TASK_STICKY (current_task->gwmh_task))
- gwmh_task_unset_gstate_flags (current_task->gwmh_task,
- GWMH_STATE_STICKY);
- else
- gwmh_task_set_gstate_flags (current_task->gwmh_task,
- GWMH_STATE_STICKY);
+ action = GWMH_TASK_STICKY (task->gwmh_task) ? MENU_ACTION_UNSTICK : MENU_ACTION_STICK;
break;
- case MENU_ACTION_KILL:
- if (Config.confirm_before_kill) {
- GtkWidget *dialog;
- gint retval;
-
- dialog = gnome_message_box_new(_("Warning! Unsaved changes will be lost!\nProceed?"),
- GNOME_MESSAGE_BOX_WARNING,
- GNOME_STOCK_BUTTON_YES,
- GNOME_STOCK_BUTTON_NO,
- NULL);
- gtk_widget_show(dialog);
- retval = gnome_dialog_run(GNOME_DIALOG(dialog));
-
- if (retval)
- return TRUE;
+ case MENU_ACTION_SHOW_HIDE:
+ action = GWMH_TASK_ICONIFIED (task->gwmh_task) ? MENU_ACTION_SHOW : MENU_ACTION_HIDE;
+ break;
+ default:
+ break;
+ }
- gwmh_task_kill(current_task->gwmh_task);
- }
- else
- gwmh_task_kill (current_task->gwmh_task);
+ switch (action) {
+ case MENU_ACTION_UNSHADE:
+ gwmh_task_unset_gstate_flags (task->gwmh_task,
+ GWMH_STATE_SHADED);
break;
- case MENU_ACTION_SHOW_HIDE:
- if (GWMH_TASK_ICONIFIED (current_task->gwmh_task)) {
- gwmh_desk_set_current_area (current_task->gwmh_task->desktop,
- current_task->gwmh_task->harea,
- current_task->gwmh_task->varea);
- gwmh_task_show (current_task->gwmh_task);
+ case MENU_ACTION_SHADE:
+ gwmh_task_set_gstate_flags (task->gwmh_task,
+ GWMH_STATE_SHADED);
+ break;
+ case MENU_ACTION_UNSTICK:
+ gwmh_task_unset_gstate_flags (task->gwmh_task,
+ GWMH_STATE_STICKY);
+ break;
+ case MENU_ACTION_STICK:
+ gwmh_task_set_gstate_flags (task->gwmh_task,
+ GWMH_STATE_STICKY);
+ break;
+ case MENU_ACTION_KILL:
+ if (!tasklist->config.confirm_before_kill) {
+ gwmh_task_kill (task->gwmh_task);
+ break;
}
- else
- gwmh_task_iconify (current_task->gwmh_task);
+ dialog = gnome_message_box_new(_("Warning! Unsaved changes will be lost!\nProceed?"),
+ GNOME_MESSAGE_BOX_WARNING,
+ GNOME_STOCK_BUTTON_YES,
+ GNOME_STOCK_BUTTON_NO,
+ NULL);
+ gtk_widget_show(dialog);
+ retval = gnome_dialog_run(GNOME_DIALOG(dialog));
+
+ if (retval)
+ return TRUE;
+
+ gwmh_task_kill(task->gwmh_task);
+ break;
+ case MENU_ACTION_SHOW:
+ gwmh_desk_set_current_area (task->gwmh_task->desktop,
+ task->gwmh_task->harea,
+ task->gwmh_task->varea);
+ gwmh_task_show (task->gwmh_task);
+ gwmh_task_raise (task->gwmh_task);
+ gwmh_task_focus (task->gwmh_task);
break;
+ case MENU_ACTION_HIDE:
+ gwmh_task_iconify (task->gwmh_task);
+ break;
case MENU_ACTION_CLOSE:
- gwmh_task_close (current_task->gwmh_task);
+ gwmh_task_close (task->gwmh_task);
break;
default:
- g_print ("Menu Callback: %d\n", GPOINTER_TO_INT (data));
+ d(g_print ("Menu Callback: %d\n", GPOINTER_TO_INT (data)));
}
return FALSE;
+
}
-/* Open a popup menu with window operations */
-void
-menu_popup (TasklistTask *task, guint button, guint32 activate_time)
+/* Callback for menus */
+static gboolean
+cb_menu (GtkWidget *widget, gpointer data)
{
- if(task->menu)
- gtk_widget_destroy(task->menu);
+ MenuAction action = GPOINTER_TO_INT (data);
+ GtkWidget *dialog;
+ gint retval;
+ int config_save = 0;
- task->menu = get_popup_menu (task);
+ TasklistTask *task = gtk_object_get_data (GTK_OBJECT (widget), "task");
- gtk_signal_connect(GTK_OBJECT(task->menu), "destroy",
- GTK_SIGNAL_FUNC(gtk_widget_destroyed),
- &task->menu);
+ g_return_val_if_fail (task != NULL, FALSE);
- gtk_menu_popup (GTK_MENU (task->menu), NULL, NULL,
- cb_menu_position, task,
- button, activate_time);
+ if (!task->task_group)
+ return do_action (task, data);
+
+ if (!task->vtasks)
+ return FALSE;
+
+ if (action == MENU_ACTION_KILL) {
+ config_save = task->tasklist->config.confirm_before_kill;
+ if (config_save) {
+ dialog = gnome_message_box_new(_("Warning! Unsaved changes will be lost!\nProceed?"),
+ GNOME_MESSAGE_BOX_WARNING,
+ GNOME_STOCK_BUTTON_YES,
+ GNOME_STOCK_BUTTON_NO,
+ NULL);
+ gtk_widget_show(dialog);
+ retval = gnome_dialog_run(GNOME_DIALOG(dialog));
+
+ if (retval)
+ return TRUE;
+
+ task->tasklist->config.confirm_before_kill = FALSE;
+ }
+ }
+ g_slist_foreach (task->vtasks, (GFunc)do_action, data);
+
+ if (action == MENU_ACTION_KILL)
+ task->tasklist->config.confirm_before_kill = config_save;
+
+ return FALSE;
}
/* Add a menu item to the popup menu */
-void
-add_menu_item (gchar *name, GtkWidget *menu, MenuAction action, gchar **xpm)
+static void
+add_menu_item (TasklistTask *task, gchar *name, GtkWidget *menu, MenuAction action, gchar **xpm)
{
GtkWidget *menuitem;
GdkPixmap *pixmap;
@@ -145,33 +180,49 @@
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_container_add (GTK_CONTAINER (menuitem), label);
if (xpm) {
- pixmap = gdk_pixmap_create_from_xpm_d (area->window, &mask, NULL, xpm);
+ pixmap = gdk_pixmap_create_from_xpm_d (task->tasklist->area->window, &mask, NULL, xpm);
gtkpixmap = gtk_pixmap_new (pixmap, mask);
gtk_pixmap_menu_item_set_pixmap (GTK_PIXMAP_MENU_ITEM (menuitem), gtkpixmap);
}
-
+
+ gtk_object_set_data (GTK_OBJECT (menuitem), "task", task);
+
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (cb_menu), GINT_TO_POINTER (action));
+ if (task->group && task->group->menu)
+ gtk_signal_connect_object (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (gtk_menu_shell_deactivate),
+ GTK_OBJECT (task->group->menu));
+
gtk_widget_show_all (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
}
/* Called when "Send to desktop" is used */
-void
+static void
cb_to_desktop (GtkWidget *widget, gpointer data)
{
- gwmh_task_set_desktop (current_task->gwmh_task,
+ TasklistTask *task = gtk_object_get_data (GTK_OBJECT (widget), "task");
+
+ gwmh_task_set_desktop (task->gwmh_task,
GPOINTER_TO_INT (data));
- gwmh_task_set_desktop (current_task->gwmh_task,
+ gwmh_task_set_desktop (task->gwmh_task,
GPOINTER_TO_INT (data));
- layout_tasklist (TRUE);
+ tasklist_layout_tasklist (task->tasklist);
+}
+
+static void
+destroy_menu (GtkWidget *w, gpointer null)
+{
+ d(g_print ("Destroying menu\n"));
+ gtk_widget_unref (w);
}
/* Create a popup menu */
-GtkWidget
-*get_popup_menu (TasklistTask *task)
+static GtkWidget *
+get_popup_menu (TasklistTask *task)
{
GtkWidget *menu, *menuitem; /*, *desktop, *label, *gtkpixmap;*/
/*GdkPixmap *pixmap;*/
@@ -182,21 +233,27 @@
/*int i, curworkspace;*/
menu = gtk_menu_new ();
+ gtk_signal_connect (GTK_OBJECT (menu), "deactivate",
+ GTK_SIGNAL_FUNC (destroy_menu),
+ NULL);
+
gtk_widget_show (menu);
+
+ gtk_object_set_data (GTK_OBJECT (menu), "task", task);
- add_menu_item (GWMH_TASK_ICONIFIED (task->gwmh_task)
+ add_menu_item (task, GWMH_TASK_ICONIFIED (task->gwmh_task)
? _("Restore") : _("Iconify"),
menu, MENU_ACTION_SHOW_HIDE,
GWMH_TASK_ICONIFIED (task->gwmh_task)
? tasklist_restore_xpm : tasklist_iconify_xpm);
- add_menu_item (GWMH_TASK_SHADED (task->gwmh_task)
+ add_menu_item (task, GWMH_TASK_SHADED (task->gwmh_task)
? _("Unshade") : _("Shade"),
menu, MENU_ACTION_SHADE_UNSHADE,
GWMH_TASK_SHADED (task->gwmh_task)
? tasklist_unshade_xpm: tasklist_shade_xpm);
- add_menu_item (GWMH_TASK_STICKY (task->gwmh_task)
+ add_menu_item (task, GWMH_TASK_STICKY (task->gwmh_task)
? _("Unstick") : _("Stick"),
menu, MENU_ACTION_STICK_UNSTICK,
GWMH_TASK_STICKY (task->gwmh_task)
@@ -206,7 +263,7 @@
label = gtk_label_new (_("To desktop"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_container_add (GTK_CONTAINER (menuitem), label);
- pixmap = gdk_pixmap_create_from_xpm_d (area->window, &mask, NULL,
+ pixmap = gdk_pixmap_create_from_xpm_d (tasklist->area->window, &mask, NULL,
tasklist_send_to_desktop_xpm);
gtkpixmap = gtk_pixmap_new (pixmap, mask);
gtk_pixmap_menu_item_set_pixmap (GTK_PIXMAP_MENU_ITEM (menuitem), gtkpixmap);
@@ -229,6 +286,7 @@
menuitem = gtk_menu_item_new_with_label (wsname);
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (cb_to_desktop), i);
+ gtk_object_set_user_data (GTK_OBJECT (menuitem), tasklist);
if (i == curworkspace)
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
@@ -242,14 +300,295 @@
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
#endif
- add_menu_item (_("Close window"), menu, MENU_ACTION_CLOSE,
+ add_menu_item (task, _("Close window"), menu, MENU_ACTION_CLOSE,
tasklist_close_xpm);
menuitem = gtk_menu_item_new ();
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
+
+ add_menu_item (task, _("Kill app"), menu, MENU_ACTION_KILL, tasklist_kill_xpm);
+
+ return menu;
+}
+
+/* Create a popup menu */
+static GtkWidget *
+get_group_popup_menu (TasklistTask *task)
+{
+ GtkWidget *menu, *menuitem; /*, *desktop, *label, *gtkpixmap;*/
+ /*GdkPixmap *pixmap;*/
+ /*GdkBitmap *mask;*/
+ /*GwmhDesk *desk_info;*/
+
+ /*gchar *wsname;*/
+ /*int i, curworkspace;*/
+
+ menu = gtk_menu_new ();
+ gtk_signal_connect (GTK_OBJECT (menu), "deactivate",
+ GTK_SIGNAL_FUNC (destroy_menu),
+ NULL);
+ gtk_widget_show (menu);
+
+ gtk_object_set_data (GTK_OBJECT (menu), "task", task);
+
+ /* if (iconified window in group) */
+ add_menu_item (task, _("Restore All"), menu,
+ MENU_ACTION_SHOW, tasklist_restore_xpm);
+
+ add_menu_item (task, _("Iconify All"), menu,
+ MENU_ACTION_HIDE, tasklist_iconify_xpm);
+
+ add_menu_item (task, _("Unshade All"), menu,
+ MENU_ACTION_UNSHADE, tasklist_unshade_xpm);
+
+ add_menu_item (task, _("Shade All"), menu,
+ MENU_ACTION_SHADE, tasklist_shade_xpm);
+
+ add_menu_item (task, _("Unstick All"), menu,
+ MENU_ACTION_UNSTICK, tasklist_unstick_xpm);
+
+ add_menu_item (task, _("Stick All"), menu,
+ MENU_ACTION_STICK, tasklist_stick_xpm);
+
+#if 0
+ menuitem = gtk_pixmap_menu_item_new ();
+ label = gtk_label_new (_("To desktop"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_container_add (GTK_CONTAINER (menuitem), label);
+ pixmap = gdk_pixmap_create_from_xpm_d (tasklist->area->window, &mask, NULL,
+ tasklist_send_to_desktop_xpm);
+ gtkpixmap = gtk_pixmap_new (pixmap, mask);
+ gtk_pixmap_menu_item_set_pixmap (GTK_PIXMAP_MENU_ITEM (menuitem), gtkpixmap);
+ gtk_widget_show_all (menuitem);
+ gtk_menu_append (GTK_MENU (menu), menuitem);
+
+ if (!GWMH_TASK_STICKY (task->gwmh_task)) {
+ desktop = gtk_menu_new ();
+ gtk_widget_show (desktop);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), desktop);
+
+ desk_info = gwmh_desk_get_config ();
+ curworkspace = desk_info->current_desktop;
+
+ for (i=0; i<desk_info->n_desktops;i++) {
+ if (desk_info->desktop_names[i])
+ wsname = g_strdup_printf ("%s", desk_info->desktop_names[i]);
+ else
+ wsname = g_strdup_printf ("%d", i);
+ menuitem = gtk_menu_item_new_with_label (wsname);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ GTK_SIGNAL_FUNC (cb_to_desktop), i);
+ gtk_object_set_user_data (GTK_OBJECT (menuitem), tasklist);
+ if (i == curworkspace)
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (desktop), menuitem);
+ g_free (wsname);
+ }
+ } else
+ gtk_widget_set_sensitive (menuitem, FALSE);
+
+ menuitem = gtk_menu_item_new ();
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (menu), menuitem);
+#endif
+ add_menu_item (task, _("Close All"), menu,
+ MENU_ACTION_CLOSE, tasklist_close_xpm);
+
+
+ menuitem = gtk_menu_item_new ();
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (menu), menuitem);
- add_menu_item (_("Kill app"), menu, MENU_ACTION_KILL, tasklist_kill_xpm);
+ add_menu_item (task, _("Kill All"), menu, MENU_ACTION_KILL, tasklist_kill_xpm);
return menu;
+}
+
+static void
+redraw_task (GtkWidget *w, TasklistTask *task)
+{
+ tasklist_draw_task (task, NULL);
+}
+
+/* Open a popup menu with window operations */
+void
+tasklist_menu_popup (TasklistTask *task, guint button, guint32 activate_time)
+{
+ tasklist_clean_menu (task);
+
+ task->menu = task->task_group
+ ? get_group_popup_menu (task)
+ : get_popup_menu (task);
+
+ gtk_signal_connect(GTK_OBJECT(task->menu), "destroy",
+ GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+ &task->menu);
+
+ tasklist_draw_task (task, NULL);
+ gtk_signal_connect (GTK_OBJECT (task->menu), "destroy",
+ GTK_SIGNAL_FUNC (redraw_task), task);
+
+ gtk_menu_popup (GTK_MENU (task->menu), NULL, NULL,
+ cb_menu_position, task,
+ button, activate_time);
+}
+
+/*most of this function stolen from the real gtk_menu_popup*/
+static void
+restore_grabs(GtkWidget *w, gpointer data)
+{
+ GtkWidget *menu_item = data;
+ GtkMenu *menu = GTK_MENU(menu_item->parent);
+ GtkWidget *xgrab_shell;
+ GtkWidget *parent;
+
+ d(g_print ("restore_grabs\n"));
+ /* Find the last viewable ancestor, and make an X grab on it
+ */
+ parent = GTK_WIDGET (menu);
+ xgrab_shell = NULL;
+ while (parent) {
+ gboolean viewable = TRUE;
+ GtkWidget *tmp = parent;
+
+ while (tmp) {
+ if (!GTK_WIDGET_MAPPED (tmp)) {
+ viewable = FALSE;
+ break;
+ }
+ tmp = tmp->parent;
+ }
+
+ if (viewable)
+ xgrab_shell = parent;
+
+ parent = GTK_MENU_SHELL (parent)->parent_menu_shell;
+ }
+
+ /*only grab if this HAD a grab before*/
+ if (xgrab_shell && (GTK_MENU_SHELL (xgrab_shell)->have_xgrab)) {
+ GdkCursor *cursor = gdk_cursor_new (GDK_ARROW);
+
+ GTK_MENU_SHELL (xgrab_shell)->have_xgrab =
+ (gdk_pointer_grab (xgrab_shell->window, TRUE,
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK,
+ NULL, cursor, 0) == 0);
+ gdk_cursor_destroy (cursor);
+ }
+
+ gtk_grab_add (GTK_WIDGET (menu));
+}
+
+static gboolean
+cb_show_popup (GtkWidget *w, GdkEventButton *event, TasklistTask *task)
+{
+ if (event->type != GDK_BUTTON_PRESS) return FALSE;
+
+ if (event->button == 1) {
+ d(g_print ("click!\n"));
+ gwmh_desk_set_current_area (task->gwmh_task->desktop,
+ task->gwmh_task->harea,
+ task->gwmh_task->varea);
+ gwmh_task_show (task->gwmh_task);
+ gwmh_task_raise (task->gwmh_task);
+ gwmh_task_focus (task->gwmh_task);
+ return TRUE;
+ }
+
+ if (event->button == 3) {
+ /*gtk_signal_emit_stop_by_name (GTK_OBJECT (w), "button_press_event");*/
+ tasklist_clean_menu (task);
+
+ task->menu = get_popup_menu (task);
+
+ gtk_signal_connect (GTK_OBJECT(task->menu), "destroy",
+ GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+ &task->menu);
+
+ gtk_signal_connect(GTK_OBJECT(task->menu),"deactivate",
+ GTK_SIGNAL_FUNC(restore_grabs), w);
+
+ gtk_menu_popup (GTK_MENU (task->menu), NULL, NULL,
+ NULL, NULL, event->button, event->time);
+
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static void
+create_task_item (TasklistTask *task, TasklistTask *group)
+{
+ GtkWidget *pixmap, *label;
+ GdkPixmap *pix;
+ GdkBitmap *bit;
+ gchar *s;
+
+ gdk_pixbuf_render_pixmap_and_mask (
+ task->gwmh_task->iconified
+ ? task->icon->minimized
+ : task->icon->normal, &pix, &bit, 128);
+
+ pixmap = gtk_pixmap_new (pix, bit);
+
+ /* are we leaking the pixmap and bitmap? */
+
+ task->menuitem = gtk_pixmap_menu_item_new ();
+ gtk_pixmap_menu_item_set_pixmap (GTK_PIXMAP_MENU_ITEM (task->menuitem), pixmap);
+
+ s = tasklist_task_get_label (task, group->width, FALSE);
+ label = gtk_label_new (s);
+ g_free (s);
+ gtk_container_add (GTK_CONTAINER (task->menuitem), label);
+
+ gtk_menu_append (GTK_MENU (group->menu), task->menuitem);
+
+ gtk_object_set_data (GTK_OBJECT (task->menuitem), "task", task);
+
+ gtk_signal_connect (GTK_OBJECT (task->menuitem), "button_press_event",
+ GTK_SIGNAL_FUNC (cb_show_popup), task);
+ /* this is broken */
+#if 0
+ gtk_signal_connect (GTK_OBJECT (task->menuitem), "destroy",
+ GTK_SIGNAL_FUNC (gtk_widget_destroyed), &task->menuitem);
+#endif
+}
+
+/* Open a popup menu with windows in a group */
+void
+tasklist_group_popup (TasklistTask *task, guint button, guint32 activate_time)
+{
+ TasklistTask *subtask;
+ GSList *item;
+
+ tasklist_clean_menu (task);
+
+ task->menu = gtk_menu_new ();
+ gtk_signal_connect (GTK_OBJECT (task->menu), "deactivate",
+ GTK_SIGNAL_FUNC (destroy_menu),
+ NULL);
+
+ g_slist_foreach (task->vtasks, (GFunc)create_task_item, task);
+
+ gtk_widget_show_all (task->menu);
+ gtk_signal_connect (GTK_OBJECT (task->menu), "destroy",
+ GTK_SIGNAL_FUNC (gtk_widget_destroyed),
+ &task->menu);
+
+ tasklist_draw_task (task, NULL);
+ gtk_signal_connect (GTK_OBJECT (task->menu), "destroy",
+ GTK_SIGNAL_FUNC (redraw_task), task);
+
+ gtk_object_set_data (GTK_OBJECT (task->menu), "task", task);
+
+ tasklist_draw_task (task, NULL);
+
+ gtk_menu_popup (GTK_MENU (task->menu), NULL, NULL,
+ cb_menu_position, task,
+ button, activate_time);
}
Index: tasklist_properties.c
===================================================================
RCS file: /cvs/gnome/gnome-core/applets/tasklist/tasklist_properties.c,v
retrieving revision 1.31
diff -u -r1.31 tasklist_properties.c
--- tasklist_properties.c 2000/12/20 23:31:30 1.31
+++ tasklist_properties.c 2001/01/23 04:00:11
@@ -1,37 +1,30 @@
#include <config.h>
#include "tasklist_applet.h"
-/* The tasklist configuration */
-extern TasklistConfig Config;
-
-/* The tasklist properties configuration */
-TasklistConfig PropsConfig;
-
-/* The Property box */
-GtkWidget *prop = NULL;
-
/* Callback for apply */
static void
cb_apply (GtkWidget *widget, gint page, gpointer data)
{
-
+ Tasklist *tasklist = data;
+
/* Copy the Property struct back to the Config struct */
- memcpy (&Config, &PropsConfig, sizeof (TasklistConfig));
+ memcpy (&tasklist->config, &tasklist->PropsConfig, sizeof (TasklistConfig));
- /* Resort and redraw everything */
- resort_tasklist ();
- change_size (TRUE, -1);
+ /* Redraw everything */
+ tasklist_redo_vtasks (tasklist);
+ tasklist_change_size (tasklist, TRUE, -1);
}
/* Callback for radio buttons */
static void
cb_radio_button (GtkWidget *widget, gint *data)
{
-
+ Tasklist *tasklist = gtk_object_get_user_data (GTK_OBJECT (widget));
+
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
*data = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
"number"));
- gnome_property_box_changed (GNOME_PROPERTY_BOX (prop));
+ gnome_property_box_changed (GNOME_PROPERTY_BOX (tasklist->prop));
}
}
@@ -39,7 +32,9 @@
static void
cb_spin_button (GtkWidget *widget, gint *data)
{
- gnome_property_box_changed (GNOME_PROPERTY_BOX (prop));
+ Tasklist *tasklist = gtk_object_get_user_data (GTK_OBJECT (widget));
+
+ gnome_property_box_changed (GNOME_PROPERTY_BOX (tasklist->prop));
*data = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
}
@@ -48,7 +43,9 @@
static void
cb_check_button (GtkWidget *widget, gboolean *data)
{
- gnome_property_box_changed (GNOME_PROPERTY_BOX (prop));
+ Tasklist *tasklist = gtk_object_get_user_data (GTK_OBJECT (widget));
+
+ gnome_property_box_changed (GNOME_PROPERTY_BOX (tasklist->prop));
*data = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
}
@@ -64,7 +61,8 @@
/* Create a spin button */
static GtkWidget *
-create_spin_button (gchar *name,
+create_spin_button (Tasklist *tasklist,
+ gchar *name,
gint *init_value,
gfloat min_value,
gfloat max_value,
@@ -85,6 +83,7 @@
hbox = gtk_hbox_new (TRUE, GNOME_PAD_SMALL);
spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
+ gtk_object_set_user_data (GTK_OBJECT (spin), tasklist);
gtk_signal_connect (GTK_OBJECT (spin), "changed",
GTK_SIGNAL_FUNC (cb_spin_button), init_value);
@@ -101,7 +100,7 @@
/* Create a radio button */
static GtkWidget *
-create_radio_button (gchar *name, GSList **group,
+create_radio_button (Tasklist *tasklist, gchar *name, GSList **group,
gint number, gint *change_value)
{
GtkWidget *radiobutton;
@@ -116,19 +115,20 @@
GTK_SIGNAL_FUNC (cb_radio_button), change_value);
gtk_object_set_data (GTK_OBJECT (radiobutton), "number",
GINT_TO_POINTER (number));
+ gtk_object_set_user_data (GTK_OBJECT (radiobutton), tasklist);
-
return radiobutton;
}
/* Create a check button */
static GtkWidget *
-create_check_button (gchar *name, gboolean *change_value)
+create_check_button (Tasklist *tasklist, gchar *name, gboolean *change_value)
{
GtkWidget *checkbutton;
checkbutton = gtk_check_button_new_with_label (name);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), *change_value);
+ gtk_object_set_user_data (GTK_OBJECT (checkbutton), tasklist);
gtk_signal_connect (GTK_OBJECT (checkbutton), "toggled",
GTK_SIGNAL_FUNC (cb_check_button), change_value);
return checkbutton;
@@ -136,7 +136,7 @@
/* Create the size page */
static void
-create_size_page (void)
+create_size_page (Tasklist *tasklist)
{
GtkWidget *hbox,/* *table,*/ *frame, *vbox, *topbox;
GSList *vertgroup = NULL, *horzgroup = NULL;
@@ -145,8 +145,9 @@
topbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
gtk_container_border_width (GTK_CONTAINER (topbox), GNOME_PAD_SMALL);
- autobutton = create_check_button (_("Follow panel size"),
- &PropsConfig.follow_panel_size);
+ autobutton = create_check_button (
+ tasklist, _("Follow panel size"),
+ &tasklist->PropsConfig.follow_panel_size);
gtk_box_pack_start (GTK_BOX (topbox),
autobutton,
FALSE, TRUE, 0);
@@ -161,47 +162,54 @@
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
gtk_container_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL);
- gtk_box_pack_start (GTK_BOX (vbox),
- create_spin_button (_("Tasklist width:"),
- &PropsConfig.horz_width,
- 48,
- 8192,
- 10),
- FALSE, TRUE, 0);
- w = create_spin_button (_("Rows of tasks:"),
- &PropsConfig.horz_rows,
- 1,
- 8,
- 1);
+ gtk_box_pack_start (
+ GTK_BOX (vbox),
+ create_spin_button (
+ tasklist, _("Tasklist width:"),
+ &tasklist->PropsConfig.horz_width,
+ 48,
+ 8192,
+ 10),
+ FALSE, TRUE, 0);
+ w = create_spin_button (
+ tasklist, _("Rows of tasks:"),
+ &tasklist->PropsConfig.horz_rows,
+ 1,
+ 8,
+ 1);
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (autobutton), "toggled",
- GTK_SIGNAL_FUNC (cb_check_button_disable),
- w);
+ GTK_SIGNAL_FUNC (cb_check_button_disable),
+ w);
cb_check_button_disable (autobutton, w);
- gtk_box_pack_start (GTK_BOX (vbox),
- create_spin_button (_("Default task size:"),
- &PropsConfig.horz_taskwidth,
- 48,
- 350,
- 10),
- FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (vbox),
+ create_spin_button (
+ tasklist, _("Default task size:"),
+ &tasklist->PropsConfig.horz_taskwidth,
+ 48,
+ 350,
+ 10),
+ FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox),
- create_radio_button (_("Tasklist width is fixed"),
- &horzgroup, TRUE, &PropsConfig.horz_fixed),
+ create_radio_button (
+ tasklist, _("Tasklist width is fixed"),
+ &horzgroup, TRUE, &tasklist->PropsConfig.horz_fixed),
FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox),
- create_radio_button (_("Tasklist width is dynamic"),
- &horzgroup, FALSE, &PropsConfig.horz_fixed),
+ create_radio_button (
+ tasklist, _("Tasklist width is dynamic"),
+ &horzgroup, FALSE, &tasklist->PropsConfig.horz_fixed),
FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox),
- create_check_button (_("Only use empty space"),
- &PropsConfig.horz_never_push),
+ create_check_button (tasklist, _("Only use empty space"),
+ &tasklist->PropsConfig.horz_never_push),
FALSE, TRUE, 0);
-
+
gtk_container_add (GTK_CONTAINER (frame), vbox);
frame = gtk_frame_new (_("Vertical"));
@@ -210,16 +218,17 @@
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
gtk_container_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL);
- gtk_box_pack_start (GTK_BOX (vbox),
- create_spin_button (_("Tasklist height:"),
- &PropsConfig.vert_height,
- 48,
- 1024*8,
- 10),
- FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (vbox),
+ create_spin_button (tasklist, _("Tasklist height:"),
+ &tasklist->PropsConfig.vert_height,
+ 48,
+ 1024*8,
+ 10),
+ FALSE, TRUE, 0);
- w = create_spin_button (_("Tasklist width:"),
- &PropsConfig.vert_width,
+ w = create_spin_button (tasklist, _("Tasklist width:"),
+ &tasklist->PropsConfig.vert_width,
48,
512,
10);
@@ -229,34 +238,39 @@
w);
cb_check_button_disable (autobutton, w);
- gtk_box_pack_start (GTK_BOX (vbox),
- create_radio_button (_("Tasklist height is fixed"),
- &vertgroup, TRUE, &PropsConfig.vert_fixed),
- FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox),
- create_radio_button (_("Tasklist height is dynamic"),
- &vertgroup, FALSE, &PropsConfig.vert_fixed),
- FALSE, TRUE, 0);
+ create_radio_button (
+ tasklist,_("Tasklist height is fixed"),
+ &vertgroup, TRUE, &tasklist->PropsConfig.vert_fixed),
+ FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (vbox),
+ create_radio_button (
+ tasklist, _("Tasklist height is dynamic"),
+ &vertgroup, FALSE, &tasklist->PropsConfig.vert_fixed),
+ FALSE, TRUE, 0);
+
gtk_box_pack_start (GTK_BOX (vbox),
- create_check_button (_("Only use empty space"),
- &PropsConfig.vert_never_push),
+ create_check_button (tasklist, _("Only use empty space"),
+ &tasklist->PropsConfig.vert_never_push),
FALSE, TRUE, 0);
-
gtk_box_pack_start (GTK_BOX (vbox),
- create_check_button (_("Tasklist width is that of longest title"),
- &PropsConfig.vert_width_full),
+ create_check_button (tasklist,
+ _("Tasklist width is that of longest title"),
+ &tasklist->PropsConfig.vert_width_full),
FALSE, TRUE, 0);
-
+
gtk_container_add (GTK_CONTAINER (frame), vbox);
- gnome_property_box_append_page (GNOME_PROPERTY_BOX (prop), topbox,
- gtk_label_new (_("Size")));
+ gnome_property_box_append_page (
+ GNOME_PROPERTY_BOX (tasklist->prop), topbox,
+ gtk_label_new (_("Size")));
}
static void
-create_display_page (void)
+create_display_page (Tasklist *tasklist)
{
GtkWidget *vbox, *frame;
GtkWidget *miscbox, *taskbox;
@@ -270,44 +284,82 @@
gtk_box_pack_start_defaults (GTK_BOX (vbox), frame);
taskbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_container_border_width (GTK_CONTAINER (taskbox), GNOME_PAD_SMALL);
gtk_container_add (GTK_CONTAINER (frame), taskbox);
- gtk_box_pack_start (GTK_BOX (taskbox),
- create_check_button (_("Show normal applications"), &PropsConfig.show_normal),
- FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (taskbox),
- create_check_button (_("Show iconified (minimized) applications"), &PropsConfig.show_minimized),
- FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (taskbox),
+ create_check_button (
+ tasklist, _("Show normal applications"),
+ &tasklist->PropsConfig.show_normal),
+ FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (taskbox),
+ create_check_button (
+ tasklist, _("Show iconified (minimized) applications"),
+ &tasklist->PropsConfig.show_minimized),
+ FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (taskbox),
- create_check_button (_("Show normal applications on all desktops"), &PropsConfig.all_desks_normal),
- FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (taskbox),
- create_check_button (_("Show iconified (minimized) applications on all desktops"), &PropsConfig.all_desks_minimized),
- FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (taskbox),
+ create_check_button (
+ tasklist, _("Show normal applications on all desktops"),
+ &tasklist->PropsConfig.all_desks_normal),
+ FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (taskbox),
+ create_check_button (tasklist,
+ _("Show iconified (minimized) applications on all desktops"),
+ &tasklist->PropsConfig.all_desks_minimized),
+ FALSE, TRUE, 0);
frame = gtk_frame_new (_("Miscellaneous"));
gtk_container_border_width (GTK_CONTAINER (frame), GNOME_PAD_SMALL);
gtk_box_pack_start_defaults (GTK_BOX (vbox), frame);
miscbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ gtk_container_border_width (GTK_CONTAINER (miscbox), GNOME_PAD_SMALL);
gtk_container_add (GTK_CONTAINER (frame), miscbox);
- gtk_box_pack_start (GTK_BOX (miscbox),
- create_check_button (_("Show mini icons"), &PropsConfig.show_mini_icons),
- FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (miscbox),
- create_check_button (_("Confirm before killing windows"), &PropsConfig.confirm_before_kill),
- FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (miscbox),
- create_check_button (_("Move iconified tasks to current workspace when restoring"), &PropsConfig.move_to_current),
- FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (miscbox),
- create_check_button (_("Keep tasks sorted"),
- &PropsConfig.sort_tasklist),
- FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (miscbox),
+ create_check_button (
+ tasklist, _("Show mini icons"),
+ &tasklist->PropsConfig.show_mini_icons),
+ FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (miscbox),
+ create_check_button (
+ tasklist,
+ _("Confirm before killing windows"),
+ &tasklist->PropsConfig.confirm_before_kill),
+ FALSE, TRUE, 0);
+ gtk_box_pack_start (
+ GTK_BOX (miscbox),
+ create_check_button (
+ tasklist,
+ _("Move iconified tasks to current workspace when restoring"),
+ &tasklist->PropsConfig.move_to_current),
+ FALSE, TRUE, 0);
+
+ gtk_box_pack_start (
+ GTK_BOX (miscbox),
+ create_check_button (
+ tasklist,
+ _("Enable task grouping"),
+ &tasklist->PropsConfig.enable_grouping),
+ FALSE, TRUE, 0);
+
+ gtk_box_pack_start (
+ GTK_BOX (miscbox),
+ create_spin_button (
+ tasklist,
+ _("Number of tasks before grouping occurs"),
+ &tasklist->PropsConfig.grouping_min,
+ 1, 10, 3),
+ FALSE, TRUE, 0);
- gnome_property_box_append_page (GNOME_PROPERTY_BOX (prop), vbox,
+ gnome_property_box_append_page (GNOME_PROPERTY_BOX (tasklist->prop), vbox,
gtk_label_new (_("Display")));
}
@@ -321,37 +373,33 @@
/* Display property dialog */
void
-display_properties (void)
+tasklist_display_properties (Tasklist *tasklist)
{
- if (prop != NULL)
+ if (tasklist->prop != NULL)
{
- gdk_window_show (prop->window);
- gdk_window_raise (prop->window);
+ gdk_window_show (tasklist->prop->window);
+ gdk_window_raise (tasklist->prop->window);
return;
}
- /* Copy memory from the tasklist config
- to the tasklist properties config. */
- memcpy (&PropsConfig, &Config, sizeof (TasklistConfig));
-
- prop = gnome_property_box_new ();
- gtk_window_set_title (GTK_WINDOW (prop), _("Tasklist properties"));
- gtk_signal_connect (GTK_OBJECT (prop), "apply",
- GTK_SIGNAL_FUNC (cb_apply), NULL);
- gtk_signal_connect (GTK_OBJECT (prop), "destroy",
+ /*
+ * Copy memory from the tasklist config
+ * to the tasklist properties config.
+ */
+ memcpy (&tasklist->PropsConfig, &tasklist->config, sizeof (TasklistConfig));
+
+ tasklist->prop = gnome_property_box_new ();
+ gtk_window_set_title (GTK_WINDOW (tasklist->prop), _("Tasklist properties"));
+ gtk_window_set_wmclass (GTK_WINDOW (tasklist->prop), "tasklist", "Tasklist");
+ gtk_signal_connect (GTK_OBJECT (tasklist->prop), "apply",
+ GTK_SIGNAL_FUNC (cb_apply), tasklist);
+ gtk_signal_connect (GTK_OBJECT (tasklist->prop), "destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
- &prop);
- gtk_signal_connect (GTK_OBJECT (prop), "help",
+ &tasklist->prop);
+ gtk_signal_connect (GTK_OBJECT (tasklist->prop), "help",
GTK_SIGNAL_FUNC (phelp_cb), NULL);
- create_display_page ();
- create_size_page ();
+ create_display_page (tasklist);
+ create_size_page (tasklist);
- gtk_widget_show_all (prop);
+ gtk_widget_show_all (tasklist->prop);
}
-
-
-
-
-
-
-
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]