index

grouping of related Emacs frames (X windows)

Summary:

Ediff control frame & the slave frame are tagged as forming a "window group", so that Window Managers can treat them as related: raise them together, switch focus between them.

Motivation

My window manager (sawfish) can use the window-group hint of X windows to limit window-cycling to a group or to raise the whole group (& other commands). When I started to use it, I was disappointed that the groups were not well formed: all windows of Mozilla (firefox). The only good case was gimp "tool windows".

ediff case

I tend do leave windows open, and when I get to emacs ediff's control window, it raises the related 2-buffer window, but when i want to cycle to that buffer window I have to "find" it myself. My WM honors the raise-window, but does not bring it at the top of the "Cycle ring".

So I wanted to use the cycle-group command to get to the 2-buffer window quickly. But allas, to the WM the 2 windows seemed unrelated.

Code

So, I implemented the WM hinting in C, and extended ediff to use it:

lisp/ediff-wind.el http://maruska.dyndns.org/comp/activity/emacs/patches/ediff-wind.el.patch

src/frame.c

#if 1
/* mmc: */
/*       0, 1, "",*/

DEFUN ("set-frame-group-leader", Fset_frame_group_leader, Sset_frame_group_leader,
       1, 2, 0,
       doc: /* Make the frame FRAME into an icon.
If omitted, FRAME defaults to the currently selected frame.  */)
        (frame, id)
     Lisp_Object frame;
     Lisp_Object id;
{
  if (NILP (frame))
    frame = selected_frame;

  CHECK_LIVE_FRAME (frame);

  CHECK_NUMBER (id);

  struct frame *f = XFRAME (frame);
  /* mmc:  */
  if (1) /* FRAME_X_DISPLAY_INFO(f)->client_leader_window != 0)*/
    {
      f->output_data.x->wm_hints.flags |= WindowGroupHint;
      f->output_data.x->wm_hints.window_group = XINT (id); /* FRAME_X_DISPLAY_INFO(f)->client_leader_window */
    }
  XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
	       &f->output_data.x->wm_hints);

  return Qnil;
}


DEFUN ("frame-group-leader", Fframe_group_leader, Sframe_group_leader,
       1, 1, 0,
       doc: /* Make the frame FRAME into an icon.
If omitted, FRAME defaults to the currently selected frame.  */)
        (frame)
     Lisp_Object frame;
{
  if (NILP (frame))
    frame = selected_frame;
  CHECK_LIVE_FRAME (frame);

  struct frame *f = XFRAME (frame);
  return make_number (f->output_data.x->wm_hints.window_group);
}
#endif

and src/xfns.c

void
x_window (f)
     struct frame *f;

....
  f->output_data.x->wm_hints.input = True;
  f->output_data.x->wm_hints.flags |= InputHint;

+  /* no leader for now: */
+  f->output_data.x->wm_hints.window_group = 0;