[sawfish] Completes recent RandR patch. At least it's correct if you have only one screen, or if you use Xiner



commit 45018829c8fea41bf75ab7f6ca003deb53e8d796
Author: Teika kazura <teika lavabit com>
Date:   Tue May 11 14:14:45 2010 +0900

    Completes recent RandR patch. At least it's correct if you have only one screen, or if you use Xinerama.
    Most importantly, XRRUpdateConfiguration is called after XRRScreenChangeNotifyEvent. This ensures update inside of Xlib.
    
    Other changes:
    NULL display check of the RandR is changed to Sawfish conventional way. (Just to be in accordance.)
    Minor memeory leak fix.
    Doc. 'configure-notify-hook' is described, too.

 man/news.texi       |    4 +-
 man/sawfish.texi    |   74 ++++++++++++++++++++++++++++++++++++++++++---------
 src/display.c       |    2 +-
 src/events.c        |   67 ++++++++++++++++++++++-----------------------
 src/functions.c     |    7 +++-
 src/sawfish_subrs.h |    2 +-
 6 files changed, 103 insertions(+), 53 deletions(-)
---
diff --git a/man/news.texi b/man/news.texi
index e2ba0fc..a355050 100644
--- a/man/news.texi
+++ b/man/news.texi
@@ -36,8 +36,8 @@ the file, if the first valid line is not [Desktop Entry].
 @item New Features
 @itemize @minus
 
- item Added a way to response to XRandR changed events (eg resolution changes)
-via @code{randr-changed-notify-hook} [Daniel M. German]
+ item XRandR events (eg resolution changes) call the new hook
+ code{randr-changed-notify-hook} [Daniel M. German]
 
 @item Tabbed windowing system improvements [Fuchur]
 @itemize +
diff --git a/man/sawfish.texi b/man/sawfish.texi
index 3fdcf4f..dd964bd 100644
--- a/man/sawfish.texi
+++ b/man/sawfish.texi
@@ -76,7 +76,7 @@ For edit history, see @file{ChangeLog} file.
 * Window Frames::		Decorating windows
 * Viewports::			Subdivided desktop areas
 * Workspaces::			Multiple desktop areas
-* Multi-Head Environments::     Multiple monitors
+* RandR and Xinerama::          Many monitors and updates
 * Window Placement::            Controlling placement of new windows
 * Popup Menus::			Displaying menus
 * Events::			Input event types
@@ -4321,7 +4321,7 @@ When true, windows uniconify to the current viewport, rather than to
 the viewport they were iconified on.  Defaults to true.
 @end defvr
 
- node Workspaces, Multi-Head Environments, Viewports, Top
+ node Workspaces, RandR and Xinerama, Viewports, Top
 @chapter Workspaces
 @cindex Workspaces
 @cindex Desktop workspaces
@@ -4741,21 +4741,43 @@ Add edge windows used to implement flipping.
 Remove the edge windows used to implement flipping.
 @end defun
 
- node Multi-Head Environments, Window Placement, Workspaces, Top
- chapter Multi-Head Environments
+ node RandR and Xinerama, Window Placement, Workspaces, Top
+ chapter RandR and Xinerama
+ cindex RandR
+ cindex Xrandr
+ cindex Xinerama
+
+Sawfish supports multiple monitors displaying a single logical screen.
+Partial support of RandR is done.
+
+ defun has-randr-p
+Returns @code{t} if RandR is supported.
+ end defun
+
+ menu
+* Multi-head Environment::
+* Screen Change Notification::
+ end menu
+
+ node Multi-head Environment, Screen Change Notification,, RandR and Xinerama
+ section Multi-head Environment
 @cindex Multi-head environments
 @cindex Environments, multi-head
 @cindex Monitors, multiple
- cindex Xinerama
 
-Sawfish supports multiple monitors displaying a single logical screen,
-as provided by Xinerama.
+Functions which provide information on monitor geometries are
+available. On the other hand, few user interface functions take them
+into account, so for example, windows often appear across multiple
+monitors.
+
+Currently, monitor geometries are taken from Xinerama only. RandR
+support in this regard is yet to be done.
 
 A ``head'' means each physical monitor. When there're multiple heads,
 the word ``screen'' means the entire screen which is the combination
 of all heads. For example the function @code{screen-width} returns the
 width of the ``screen'' in this sense. A viewport contains the entire
-screen.  The only exception is that maximization is done within a
+screen. The only exception is maximizations which are done within a
 head, unless stated explicitly that it's xinerama.
 
 @defun find-head x y
@@ -4813,8 +4835,29 @@ containing the window @var{window}, or the pointer if @var{window} is
 false).  Returns @code{'(0 . 0)} if no such head can be identified.
 @end defun
 
+ node Screen Change Notification, , Multi-head Environment, RandR and Xinerama
+ section Screen Change Notification
+ cindex Screen change notification
+ cindex Change, of screen
+
+If some changes happen to the screen, hot-plugging, removal, or
+resolution change, then you can receive the notification.
+
+One way is to use @code{configure-notify-hook}.(@pxref{X Hooks})
+Then the window argument is set to the symbol @code{root}. The other way
+is to use @code{randr-change-notify-hook} below. Both are called,
+but there's no guarantee of the order.
 
- node Window Placement, Popup Menus, Multi-Head Environments, Top
+Notice that both may be called several times for one change. For
+example, ``xrandr'' command invocation from shell triggers three
+calls of both hooks in an author's environment.
+
+ defvr {Hook} randr-change-notify-hook
+Called when screen configuration changes, via RandR extension support.
+When RandR is not supported, then this hook will never be called.
+ end defvr
+
+ node Window Placement, Popup Menus, RandR and Xinerama, Top
 @chapter Window Placement
 @cindex Placement of windows
 
@@ -6859,6 +6902,11 @@ of configure request properties.  This alist may contain items
 and @code{(dimensions . @var{dimensions})}.
 @end defvr
 
+ defvr {Window Hook} configure-notify-hook
+Called when an X @code{ConfigureNotify} event is received, i.e.
+when window configuration request is complete.
+ end defvr
+
 @defvr {Window Hook} property-notify-hook
 Called whenever an X window property (not a Sawfish window property)
 changes.  In addition to the window, the hook is called with the
@@ -6866,7 +6914,7 @@ atom name and one of the symbols @code{new-value} or @code{deleted}.
 @end defvr
 
 @defvr {Window Hook} window-state-change-hook
-Called whenver certain window manager hints change for a window.
+Called whenever certain window manager hints change for a window.
 Currently only @code{urgency} is monitored.  The hint is an additional
 argument to the hook.
 @end defvr
@@ -6970,12 +7018,12 @@ possible.
 @end defvr
 
 @defvr {Hook} viewport-resized-hook
-Called when the number of rows and columns in each virtual workspace is
-changed.
+Hook called when the number of rows and columns in each
+workspace is changed.
 @end defvr
 
 @defvr {Hook} viewport-moved-hook
-Called when the origin of the viewport into the virtual workspace is
+Called when the origin of the viewport into the workspace is
 moved.
 @end defvr
 
diff --git a/src/display.c b/src/display.c
index 24d622c..d1378b0 100644
--- a/src/display.c
+++ b/src/display.c
@@ -45,7 +45,7 @@
 #endif
 
 char *visual_name;
-Display *dpy = NULL;
+Display *dpy;
 int screen_num, screen_width, screen_height;
 Window root_window, no_focus_window;
 int shape_event_base, shape_error_base;
diff --git a/src/events.c b/src/events.c
index dec7716..3e9501e 100644
--- a/src/events.c
+++ b/src/events.c
@@ -76,7 +76,7 @@ static int has_randr = FALSE;
 static int randr_event_base; /* Will give us the offset for the xrandr events */
 #endif
 
-
+/* variables */
 DEFSYM(visibility_notify_hook, "visibility-notify-hook");
 DEFSYM(destroy_notify_hook, "destroy-notify-hook");
 DEFSYM(map_notify_hook, "map-notify-hook");
@@ -97,11 +97,7 @@ DEFSYM(enter_frame_part_hook, "enter-frame-part-hook");
 DEFSYM(leave_frame_part_hook, "leave-frame-part-hook");
 DEFSYM(configure_request_hook, "configure-request-hook");
 DEFSYM(configure_notify_hook, "configure-notify-hook");
-
-#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
 DEFSYM(randr_change_notify_hook, "randr-change-notify-hook");
-#endif
-
 DEFSYM(window_state_change_hook, "window-state-change-hook");
 
 DEFSYM(pointer_motion_threshold, "pointer-motion-threshold");
@@ -1238,6 +1234,26 @@ configure_notify (XEvent *ev)
      }
 }
 
+#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
+static void
+randr_screen_change_notify (XEvent *ev)
+{
+  /* If ev is XRRScreenChangeNotifyEvent, then it's a superior
+     version to XConfigureEvent one.
+  */
+  XRRUpdateConfiguration( ev );
+
+  update_xinerama_info();
+
+  int snum = DefaultScreen(dpy);
+  screen_width = DisplayWidth(dpy, snum);
+  screen_height = DisplayHeight(dpy, snum);
+
+  // Call the hook
+  Fcall_hook(Qrandr_change_notify_hook, Qnil, Qnil);
+}
+#endif
+
 static void
 create_notify (XEvent *ev)
 {
@@ -1278,21 +1294,6 @@ shape_notify (XEvent *ev)
     }
 }
 
-#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-static void
-randr_screen_change_notify (XEvent *ev)
-{
-    // Only do it if we are sure we are handling the event
-    if (has_randr) {
-        fprintf(stderr, "Yes, we are handling the screen change event\n");
-        // We should add the call to the hook
-        XRRUpdateConfiguration( ev );
-        // Call the hook
-        Fcall_hook(Qrandr_change_notify_hook, Qnil, Qnil);
-    }
-}
-#endif
-
 static int synthetic_configure_mutex;
 
 /* From the afterstep sources, ``According to the July 27, 1988 ICCCM
@@ -1435,8 +1436,9 @@ inner_handle_input (repv arg)
     else if (ev->type == shape_event_base + ShapeNotify)
 	shape_notify (ev);
 #ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-    else if (ev->type == randr_event_base + RRScreenChangeNotify)
-        randr_screen_change_notify(ev);
+    else if (ev->type == randr_event_base + RRScreenChangeNotify){
+      randr_screen_change_notify(ev);
+    }
 #endif
     else 
 	fprintf (stderr, "warning: unhandled event: %d\n", ev->type);
@@ -1701,6 +1703,13 @@ DEFUN("clicked-frame-part", Fclicked_frame_part,
     return (clicked_frame_part != 0) ? rep_VAL (clicked_frame_part) : Qnil;
 }
 
+DEFUN("has-randr-p", Fhas_randr_p,
+      Shas_randr_p, (void), rep_Subr0)
+{
+  return has_randr ? Qt : Qnil;
+}
+
+
 /* initialisation */
 
 void
@@ -1715,14 +1724,13 @@ events_init (void)
 #ifdef HAVE_X11_EXTENSIONS_XRANDR_H
     // This code is executed even in batch mode, in 
     // which case dpy is not set
-    if (dpy != NULL) {
+    if (dpy != 0) {
         has_randr = XRRQueryExtension( dpy, &randr_event_base, &dummy );
         if( has_randr )
         {
            int major, minor;
            XRRQueryVersion( dpy, &major, &minor );
            has_randr = ( major > 1 || ( major == 1 && minor >= 1 ) );
-           fprintf(stderr, "it Has randr %d\n", has_randr);
            XRRSelectInput( dpy, root_window, RRScreenChangeNotifyMask );
         }
     }
@@ -1754,16 +1762,6 @@ events_init (void)
     event_handlers[CirculateNotify] = circulate_notify;
     event_handlers[MappingNotify] = mapping_notify;
 
-#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
-    if (has_randr) 
-    {
-        fprintf(stderr, "Setting handler at event %d\n", randr_event_base + RRScreenChangeNotify);
-        // we can't handle the event in the usual manner because the sizes of the
-        // arrays event_handler and event_names are defined at compile time.
-        rep_INTERN_SPECIAL(randr_change_notify_hook);
-    }
-#endif
-
     event_names[KeyPress] = "KeyPress";
     event_names[KeyRelease] = "KeyRelease";
     event_names[ButtonPress] = "ButtonPress";
@@ -1867,6 +1865,7 @@ events_init (void)
     rep_INTERN_SPECIAL(configure_notify_hook);
     rep_INTERN_SPECIAL(configure_request_hook);
     rep_INTERN_SPECIAL(window_state_change_hook);
+    rep_INTERN_SPECIAL(randr_change_notify_hook);
 
     rep_INTERN_SPECIAL(pointer_motion_threshold);
 
diff --git a/src/functions.c b/src/functions.c
index dfd0f4c..6047f5c 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -52,7 +52,7 @@ static int xinerama_heads;
 
 #ifdef HAVE_X11_EXTENSIONS_XINERAMA_H
 # include <X11/extensions/Xinerama.h>
-  static XineramaScreenInfo *xinerama_head_info;
+  static XineramaScreenInfo *xinerama_head_info = NULL;
 # ifdef TEST_XINERAMA
    static XineramaScreenInfo debug_heads[2] = {
      { 0, 0, 0, 512, 768 },
@@ -948,7 +948,10 @@ update_xinerama_info (void)
 	if (XineramaQueryExtension (dpy, &xinerama_event_base,
 				    &xinerama_error_base))
 	{
-	    xinerama_head_info = XineramaQueryScreens (dpy, &xinerama_heads);
+	  if(xinerama_head_info != NULL){
+	    XFree(xinerama_head_info);
+	  }
+	  xinerama_head_info = XineramaQueryScreens (dpy, &xinerama_heads);
 	}
     }
 # else
diff --git a/src/sawfish_subrs.h b/src/sawfish_subrs.h
index 2f4dd8e..2616759 100644
--- a/src/sawfish_subrs.h
+++ b/src/sawfish_subrs.h
@@ -78,7 +78,7 @@ extern XEvent *current_x_event;
 extern repv Qvisibility_notify_hook, Qdestroy_notify_hook, Qmap_notify_hook,
     Qunmap_notify_hook, Qreparent_notify_hook, Qenter_notify_hook,
     Qleave_notify_hook, Qfocus_in_hook, Qfocus_out_hook, Qclient_message_hook,
-    Qwindow_moved_hook, Qwindow_resized_hook;
+    Qwindow_moved_hook, Qwindow_resized_hook, Qrandr_change_notify_hook;
 extern repv Qiconify_window, Quniconify_window;
 extern struct frame_part *clicked_frame_part;
 extern void save_timestamp (Time t);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]