Ok, here's the patch for the weighted sorting feature (renamed from
"custom", following Larry Gensch's suggestion).  This is against the
latest code in CVS.

- Derek

? FvwmIconMan.patch
Index: modules/FvwmIconMan/FvwmIconMan.1
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmIconMan/FvwmIconMan.1,v
retrieving revision 1.21
diff -u -r1.21 FvwmIconMan.1
--- modules/FvwmIconMan/FvwmIconMan.1   2002/04/07 00:35:34     1.21
+++ modules/FvwmIconMan/FvwmIconMan.1   2002/04/25 07:25:18
@@ -113,6 +113,7 @@
 show            list of windows to show
 showonlyicons   only icons visible         false
 sort            keep managers sorted       name
+sortweight      weight for sorting
 title           manager title              FvwmIconMan
 titlebutton     style for title button     raisededge black grey
 titlecolorset
@@ -285,8 +286,30 @@
 If \fIname\fP, then the manager list is sorted by name. If \fInamewithcase\fP,
 then it is sorted by name sensitive to case. If \fIid\fP, then
 the manager list is sorted by the window id, which never changes after the
-window is created. Or it can be set to \fInone\fP, which results in no sorting.
-Default is \fIname\fP.
+window is created. If \fIweighted\fP, then the manager list is sorted by
+weight (see the description of \fIsortweight\fP below). Or it can be set to
+\fInone\fP, which results in no sorting. Default is \fIname\fP.
+
+.IP "*FvwmIconMan: [id ]sortweight \fIweight\fP \fIpattern-list\fP"
+Assigns the specified \fIweight\fP to windows that match \fIpattern-list\fP.
+The list is made up of patterns of the form \fItype=pattern\fP, where type
+is one of \fIclass\fP, \fIresource\fP, \fItitle\fP, or \fIicon\fP, and pattern
+is an expression of the same format used in the fvwm style command
+(minimalistic shell pattern matching). Multiple sort weights can be given.
+Each window is matched against the list of sort weights, in order, and is
+given the weight from the first match. Lower-weighted windows are placed
+first in the manager list. For example:
+.EX
+*FvwmIconMan*sort       weighted
+*FvwmIconMan*sortweight 1 class=XTerm title=special*
+*FvwmIconMan*sortweight 10 class=XTerm
+*FvwmIconMan*sortweight 5
+.EE
+In this example, xterm windows whose titles start with "special" (weight 1)
+are listed first, followed by everything but other xterms (weight 5), and the
+other xterms (weight 10) are listed last. If no default weight (empty pattern
+list) is given, the default weight is 0. Only relevant if the sort type is
+set to \fIweighted\fP.
 
 .IP "*FvwmIconMan: [id ]title \fItitlestring\fP"
 Specifies the window title string for that manager window. \fITitlestring\fP
Index: modules/FvwmIconMan/FvwmIconMan.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmIconMan/FvwmIconMan.h,v
retrieving revision 1.39
diff -u -r1.39 FvwmIconMan.h
--- modules/FvwmIconMan/FvwmIconMan.h   2002/04/22 08:06:15     1.39
+++ modules/FvwmIconMan/FvwmIconMan.h   2002/04/25 07:25:19
@@ -266,9 +266,18 @@
   SortNone,          /* no sorting */
   SortId,            /* sort by window id */
   SortName,          /* case insensitive name sorting */
-  SortNameCase       /* case sensitive name sorting */
+  SortNameCase,      /* case sensitive name sorting */
+  SortWeighted       /* custom sort order */
 } SortType;
 
+typedef struct {
+  char *resname;
+  char *classname;
+  char *titlename;
+  char *iconname;
+  int weight;
+} WeightedSort;
+
 typedef struct win_manager {
   unsigned int magic;
   int index;
@@ -300,6 +309,8 @@
   Uchar followFocus;
   Uchar usewinlist;
   SortType sort;
+  WeightedSort *weighted_sorts;
+  int weighted_sorts_len, weighted_sorts_size;
   char *AnimCommand;
   Uchar showonlyiconic;
   rectangle managed_g;    /* dimensions of managed screen portion */
@@ -370,6 +381,7 @@
 
 extern void init_globals (void);
 extern int allocate_managers (int num);
+extern int expand_weighted_sorts (void);
 
 extern WinData *new_windata (void);
 extern void free_windata (WinData *p);
Index: modules/FvwmIconMan/globals.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmIconMan/globals.c,v
retrieving revision 1.19
diff -u -r1.19 globals.c
--- modules/FvwmIconMan/globals.c       2002/04/23 01:26:54     1.19
+++ modules/FvwmIconMan/globals.c       2002/04/25 07:25:19
@@ -72,6 +72,9 @@
   globals.managers[id].dontshow.mask = ALL_NAME;
   globals.managers[id].usewinlist = 1;
   globals.managers[id].sort = SortName;
+  globals.managers[id].weighted_sorts = NULL;
+  globals.managers[id].weighted_sorts_len = 0;
+  globals.managers[id].weighted_sorts_size = 0;
   globals.managers[id].bindings[MOUSE] = ParseMouseEntry (DEFAULT_MOUSE);
   globals.managers[id].we_are_drawing = 1;
   globals.managers[id].showonlyiconic = 0;
Index: modules/FvwmIconMan/readconfig.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmIconMan/readconfig.c,v
retrieving revision 1.43
diff -u -r1.43 readconfig.c
--- modules/FvwmIconMan/readconfig.c    2002/04/23 01:26:54     1.43
+++ modules/FvwmIconMan/readconfig.c    2002/04/25 07:25:22
@@ -1126,6 +1126,38 @@
               copy_string (&globals.managers[id].backColorName[context], p));
 }
 
+static void add_weighted_sort(WinManager *man, WeightedSort *weighted_sort) {
+  WeightedSort *p;
+  int i;
+
+  if (man->weighted_sorts_len == man->weighted_sorts_size) {
+    i = man->weighted_sorts_size;
+    man->weighted_sorts_size += 16;
+    man->weighted_sorts =
+      (WeightedSort *)saferealloc ((char *)man->weighted_sorts,
+                        man->weighted_sorts_size * sizeof (WeightedSort));
+  }
+  p = &man->weighted_sorts[man->weighted_sorts_len];
+  p->resname = NULL;
+  p->classname = NULL;
+  p->titlename = NULL;
+  p->iconname = NULL;
+  if (weighted_sort->resname) {
+    copy_string(&p->resname, weighted_sort->resname);
+  }
+  if (weighted_sort->classname) {
+    copy_string(&p->classname, weighted_sort->classname);
+  }
+  if (weighted_sort->titlename) {
+    copy_string(&p->titlename, weighted_sort->titlename);
+  }
+  if (weighted_sort->iconname) {
+    copy_string(&p->iconname, weighted_sort->iconname);
+  }
+  p->weight = weighted_sort->weight;
+  ++man->weighted_sorts_len;
+}
+
 void read_in_resources (char *file)
 {
   char *p, *q;
@@ -1629,6 +1661,9 @@
        else if (!strcasecmp (p, "none")) {
          i = SortNone;
        }
+       else if (!strcasecmp (p, "weighted")) {
+         i = SortWeighted;
+       }
        else if (!strcasecmp (p, "false") || !strcasecmp (p, "true")) {
          /* Old options */
          ConsoleMessage ("FvwmIconMan*sort option no longer takes "
@@ -1643,6 +1678,60 @@
        }
        ConsoleDebug (CONFIG, "Setting sort to: %d\n", i);
        SET_MANAGER (manager, sort, i);
+      }
+      else if (!strcasecmp (option1, "sortweight")) {
+       WeightedSort weighted_sort;
+       p = read_next_cmd (READ_ARG);
+       if (!p) {
+         ConsoleMessage ("Bad line: %s\n", current_line);
+         continue;
+       }
+       if (extract_int (p, &n) == 0) {
+         ConsoleMessage ("This is not a number: %s\n", p);
+         ConsoleMessage ("Bad line: %s\n", current_line);
+         continue;
+       }
+       weighted_sort.resname = NULL;
+       weighted_sort.classname = NULL;
+       weighted_sort.titlename = NULL;
+       weighted_sort.iconname = NULL;
+       weighted_sort.weight = n;
+       p = read_next_cmd (READ_ARG);
+       while (p) {
+         if (!strncasecmp(p, "resource=", 9)) {
+           copy_string(&weighted_sort.resname, p + 9);
+         } else if (!strncasecmp(p, "class=", 6)) {
+           copy_string(&weighted_sort.classname, p + 6);
+         } else if (!strncasecmp(p, "title=", 6)) {
+           copy_string(&weighted_sort.titlename, p + 6);
+         } else if (!strncasecmp(p, "icon=", 5)) {
+           copy_string(&weighted_sort.iconname, p + 5);
+         } else {
+           ConsoleMessage ("Unknown sortweight field: %s\n", p);
+           ConsoleMessage ("Bad line: %s\n", current_line);
+         }
+         p = read_next_cmd (READ_ARG);
+       }
+       if (manager == -1) {
+         for (i = 0; i < globals.num_managers; i++) {
+           add_weighted_sort (&globals.managers[i], &weighted_sort);
+         }
+       }
+       else {
+         add_weighted_sort (&globals.managers[manager], &weighted_sort);
+       }
+       if (weighted_sort.resname) {
+         Free(weighted_sort.resname);
+       }
+       if (weighted_sort.resname) {
+         Free(weighted_sort.classname);
+       }
+       if (weighted_sort.resname) {
+         Free(weighted_sort.titlename);
+       }
+       if (weighted_sort.resname) {
+         Free(weighted_sort.iconname);
+       }
       }
       else if (!strcasecmp (option1, "NoIconAction")) {
        char *token;
Index: modules/FvwmIconMan/xmanager.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmIconMan/xmanager.c,v
retrieving revision 1.62
diff -u -r1.62 xmanager.c
--- modules/FvwmIconMan/xmanager.c      2002/04/23 01:26:54     1.62
+++ modules/FvwmIconMan/xmanager.c      2002/04/25 07:25:26
@@ -1571,8 +1571,36 @@
 }
 
 
+static int compute_weight(WinData *win)
+{
+  WinManager *man;
+  WeightedSort *sort;
+  int i;
+
+  man = win->manager;
+  for (i = 0; i < man->weighted_sorts_len; i++) {
+    sort = &man->weighted_sorts[i];
+    if (sort->resname && !matchWildcards(sort->resname, win->resname)) {
+      continue;
+    }
+    if (sort->classname && !matchWildcards(sort->classname, win->classname)) {
+      continue;
+    }
+    if (sort->titlename && !matchWildcards(sort->titlename, win->titlename)) {
+      continue;
+    }
+    if (sort->iconname && !matchWildcards(sort->iconname, win->iconname)) {
+      continue;
+    }
+    return sort->weight;
+  }
+  return 0;
+}
+
 static int compare_windows(SortType type, WinData *a, WinData *b)
 {
+  int wa, wb;
+
   if (type == SortId) {
     return a->app_id - b->app_id;
   }
@@ -1581,6 +1609,14 @@
   }
   else if (type == SortNameCase) {
     return strcmp (a->display_string, b->display_string);
+  }
+  else if (type == SortWeighted) {
+    wa = compute_weight(a);
+    wb = compute_weight(b);
+    if (wa != wb) {
+      return wa - wb;
+    }
+    return strcmp(a->display_string, b->display_string);
   }
   else {
     ConsoleMessage ("Internal error in compare_windows\n");

Reply via email to