From fab11adc940f3258dc53c823903f242d9c65da91 Mon Sep 17 00:00:00 2001 From: sabetts Date: Fri, 27 Feb 2004 08:28:16 +0000 Subject: * src/window.c (give_window_focus): save the mouse position before checking if win is NULL. (give_window_focus): set rp_current_screen to xine_screen_num of the window's screen. (set_active_window): when using xinerama get the frame from the current screen. * src/split.c (set_frames_window): update the window's scr attribute to point to the frame's screen. (find_window_for_frame): when xinerama is being used search all windows. (set_active_frame): update rp_current_screen to point to the frame's screen. * src/screen.h (init_screens): new prototype (is_rp_window_for_screen): likewise * src/screen.c: include string.h and X11/cursorfont.h (init_screens): new function (is_rp_window_for_screen): new function. (init_screen): fill in xine_screen_num when using xinerama. * src/ratpoison.h: include xinerama.h * src/manage.c (current_screen): use xine_screen_num to find the current screen. (scanwins): use is_rp_window_for_screen to skip over ratpoison windows. (scanwins): when using xinerama only manage windows inside the viewable area. * src/main.c (main): call init_xinerama and init_screens. Move screen initing code to these functions. (init_rat_cursor): move to screen.c (init_screen): likewise (find_screen): likewise (clean_up): call free_xinerama * src/group.c (group_last_window): only check windows in the current screen, unless xinerama is being used in which case all windows are accessible. (group_next_window): likewise (group_prev_window): likewise * src/globals.h: new globals rp_have_xinerama, xine_screen_num. * src/events.c (new_window): when using xinerama, the new window's screen is the current screen. (key_press): when using xinerama, use the current screen. * src/data.h (struct rp_screen): remove root_attr and add left, top, width, height. All dependant code updated. Add xine_screen_num. * src/actions.c (cmd_remove): show the frame indicator in the new current frame after removing the frame. * src/Makefile.am (ratpoison_SOURCES): add xinerama.c and xinerama.h --- ChangeLog | 59 +++++++++++++++ configure.in | 7 +- src/Makefile.am | 6 +- src/actions.c | 23 +++--- src/bar.c | 12 ++-- src/data.h | 9 ++- src/events.c | 23 +++++- src/globals.h | 3 + src/group.c | 6 +- src/main.c | 139 ++--------------------------------- src/manage.c | 23 +++--- src/ratpoison.h | 1 + src/screen.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/screen.h | 4 ++ src/split.c | 24 +++++-- src/window.c | 28 +++++--- 16 files changed, 394 insertions(+), 192 deletions(-) diff --git a/ChangeLog b/ChangeLog index c1ad8b1..7c9fd21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,62 @@ +2004-02-27 Shawn Betts + + * src/window.c (give_window_focus): save the mouse position before + checking if win is NULL. + (give_window_focus): set rp_current_screen to xine_screen_num of + the window's screen. + (set_active_window): when using xinerama get the frame from the + current screen. + + * src/split.c (set_frames_window): update the window's scr + attribute to point to the frame's screen. + (find_window_for_frame): when xinerama is being used search all + windows. + (set_active_frame): update rp_current_screen to point to the + frame's screen. + + * src/screen.h (init_screens): new prototype + (is_rp_window_for_screen): likewise + + * src/screen.c: include string.h and X11/cursorfont.h + (init_screens): new function + (is_rp_window_for_screen): new function. + (init_screen): fill in xine_screen_num when using xinerama. + + * src/ratpoison.h: include xinerama.h + + * src/manage.c (current_screen): use xine_screen_num to find the + current screen. + (scanwins): use is_rp_window_for_screen to skip over ratpoison windows. + (scanwins): when using xinerama only manage windows inside the viewable area. + + * src/main.c (main): call init_xinerama and init_screens. Move + screen initing code to these functions. + (init_rat_cursor): move to screen.c + (init_screen): likewise + (find_screen): likewise + (clean_up): call free_xinerama + + + * src/group.c (group_last_window): only check windows in the + current screen, unless xinerama is being used in which case all + windows are accessible. + (group_next_window): likewise + (group_prev_window): likewise + + * src/globals.h: new globals rp_have_xinerama, xine_screen_num. + + * src/events.c (new_window): when using xinerama, the new window's + screen is the current screen. + (key_press): when using xinerama, use the current screen. + + * src/data.h (struct rp_screen): remove root_attr and add left, + top, width, height. All dependant code updated. Add xine_screen_num. + + * src/actions.c (cmd_remove): show the frame indicator in the new + current frame after removing the frame. + + * src/Makefile.am (ratpoison_SOURCES): add xinerama.c and xinerama.h + 2004-02-26 Shawn Betts * src/split.c (hide_frame_indicator): unmap all 'current frame' diff --git a/configure.in b/configure.in index 6d58f3a..2ec5025 100644 --- a/configure.in +++ b/configure.in @@ -17,7 +17,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl $Id: configure.in,v 1.39 2003/11/03 03:17:59 sabetts Exp $ +dnl $Id: configure.in,v 1.40 2004/02/27 08:28:16 sabetts Exp $ AC_INIT(src/main.c) AM_INIT_AUTOMAKE(ratpoison, 1.3.0-cvs) @@ -87,6 +87,11 @@ CFLAGS="$CFLAGS $X_CFLAGS" AC_CHECK_LIB(X11, XOpenDisplay,, AC_MSG_ERROR([*** Can't find libX11])) +AC_CHECK_HEADERS([X11/extensions/Xinerama.h]) +AC_CHECK_LIB(Xext, XMissingExtension, [LIBS="-lXext $LIBS"],, $CFLAGS $LDFLAGS) +AC_CHECK_LIB(Xinerama, XineramaQueryScreens, [LIBS="-lXinerama $LIBS"],, $CFLAGS $LDFLAGS) + + dnl Check for electric fence library dnl AC_CHECK_LIB(efence,malloc,,) diff --git a/src/Makefile.am b/src/Makefile.am index 3cd61b6..c295497 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## -## $Id: Makefile.am,v 1.19 2003/07/17 05:41:41 sabetts Exp $ +## $Id: Makefile.am,v 1.20 2004/02/27 08:28:17 sabetts Exp $ bin_PROGRAMS = ratpoison @@ -66,4 +66,6 @@ ratpoison_SOURCES = actions.c \ split.c \ split.h \ window.c \ - window.h \ No newline at end of file + window.h \ + xinerama.c \ + xinerama.h diff --git a/src/actions.c b/src/actions.c index 98cf640..59221e0 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1660,6 +1660,7 @@ cmd_remove (int interactive, char *data) { remove_frame (current_frame()); set_active_frame (frame); + show_frame_indicator(); } return NULL; @@ -1792,7 +1793,7 @@ cmd_banish (int interactive, char *data) s = current_screen (); - XWarpPointer (dpy, None, s->root, 0, 0, 0, 0, s->root_attr.width - 2, s->root_attr.height - 2); + XWarpPointer (dpy, None, s->root, 0, 0, 0, 0, s->left + s->width - 2, s->top + s->height - 2); return NULL; } @@ -1854,8 +1855,8 @@ cmd_license (int interactive, char *data) } /* Offset the text so its in the center. */ - x = (s->root_attr.width - max_width) / 2; - y = (s->root_attr.height - i * FONT_HEIGHT (defaults.font)) / 2; + x = s->left + (s->width - max_width) / 2; + y = s->top + (s->height - i * FONT_HEIGHT (defaults.font)) / 2; if (x < 0) x = 0; if (y < 0) y = 0; @@ -1967,7 +1968,7 @@ cmd_help (int interactive, char *data) y += FONT_HEIGHT (defaults.font); /* Make sure the next line fits entirely within the window. */ - if (y + FONT_HEIGHT (defaults.font) >= s->root_attr.height) + if (y + FONT_HEIGHT (defaults.font) >= (s->top + s->height)) { if (drawing_keys) { @@ -2354,8 +2355,8 @@ cmd_defpadding (int interactive, char *data) frame->width += bk_pos - l; } - if (bk_pos + bk_len == current_screen()->root_attr.width - defaults.padding_right) - frame->width = current_screen()->root_attr.width - r - frame->x; + if ((bk_pos + bk_len) == (current_screen()->left + current_screen()->width - defaults.padding_right)) + frame->width = current_screen()->left + current_screen()->width - r - frame->x; /* Resize vertically. */ bk_pos = frame->y; @@ -2367,8 +2368,8 @@ cmd_defpadding (int interactive, char *data) frame->height += bk_pos - t; } - if (bk_pos + bk_len == current_screen()->root_attr.height - defaults.padding_bottom) - frame->height = current_screen()->root_attr.height - b - frame->y; + if ((bk_pos + bk_len) == (current_screen()->top + current_screen()->height - defaults.padding_bottom)) + frame->height = current_screen()->top + current_screen()->height - b - frame->y; maximize_all_windows_in_frame (frame); } @@ -2747,8 +2748,8 @@ cmd_info (int interactive, char *data) if (current_window() == NULL) { marked_message_printf (0, 0, " (%d, %d) No window ", - current_screen()->root_attr.width, - current_screen()->root_attr.height); + current_screen()->width, + current_screen()->height); } else { @@ -3325,7 +3326,7 @@ cmd_fselect (int interactive, char *data) height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2); /* Create and map the window. */ - wins[i] = XCreateWindow (dpy, s->root, cur->x, cur->y, width, height, 1, + wins[i] = XCreateWindow (dpy, s->root, s->left + cur->x, s->top + cur->y, width, height, 1, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect | CWBorderPixel | CWBackPixel, &attr); diff --git a/src/bar.c b/src/bar.c index 5dedac9..cb7d45d 100644 --- a/src/bar.c +++ b/src/bar.c @@ -96,17 +96,17 @@ bar_x (rp_screen *s, int width) case NorthWestGravity: case WestGravity: case SouthWestGravity: - x = 0; + x = s->left; break; case NorthGravity: case CenterGravity: case SouthGravity: - x = (s->root_attr.width - width - defaults.bar_border_width * 2) / 2; + x = s->left + (s->width - width - defaults.bar_border_width * 2) / 2; break; case NorthEastGravity: case EastGravity: case SouthEastGravity: - x = s->root_attr.width - width - defaults.bar_border_width * 2; + x = s->left + s->width - width - defaults.bar_border_width * 2; break; } @@ -123,18 +123,18 @@ bar_y (rp_screen *s, int height) case NorthEastGravity: case NorthGravity: case NorthWestGravity: - y = 0; + y = s->top; break; case EastGravity: case CenterGravity: case WestGravity: - y = (s->root_attr.height - height + y = s->top + (s->height - height - defaults.bar_border_width * 2) / 2; break; case SouthEastGravity: case SouthGravity: case SouthWestGravity: - y = (s->root_attr.height - height + y = s->top + (s->height - height - defaults.bar_border_width * 2); break; } diff --git a/src/data.h b/src/data.h index 5cfd550..5969ae4 100644 --- a/src/data.h +++ b/src/data.h @@ -50,7 +50,7 @@ struct rp_frame /* For determining the last frame. */ int last_access; - + struct list_head node; }; @@ -137,14 +137,17 @@ struct rp_group struct rp_screen { GC normal_gc; - XWindowAttributes root_attr; Window root, bar_window, key_window, input_window, frame_window, help_window; int bar_is_raised; int screen_num; /* Our screen number as dictated my X */ + int xine_screen_num; /* Our screen number for the Xinerama extension */ Colormap def_cmap; Cursor rat; unsigned long fg_color, bg_color; /* The pixel color. */ - + + /* Here to abstract over the Xinerama vs X screens difference */ + int left, top, width, height; + char *display_string; /* A list of frames that may or may not contain windows. There should diff --git a/src/events.c b/src/events.c index 97de6af..2498be2 100644 --- a/src/events.c +++ b/src/events.c @@ -50,9 +50,22 @@ new_window (XCreateWindowEvent *e) if (e->override_redirect) return; - s = find_screen (e->parent); win = find_window (e->window); + /* In Xinerama mode, all windows have the same root, so check + * all Xinerama screens + */ + if (rp_have_xinerama) + { + /* New windows belong to the current screen */ + s = &screens[rp_current_screen]; + } + else + { + s = find_screen (e->parent); + } + if (is_rp_window_for_screen(e->window, s)) return; + if (s && win == NULL && e->window != s->key_window && e->window != s->bar_window @@ -376,10 +389,13 @@ key_press (XEvent *ev) unsigned int modifier; KeySym ks; - s = find_screen (ev->xkey.root); + if (rp_have_xinerama) + s = current_screen(); + else + s = find_screen (ev->xkey.root); #ifdef HIDE_MOUSE - XWarpPointer (dpy, None, s->root, 0, 0, 0, 0, s->root_attr.width - 2, s->root_attr.height - 2); + XWarpPointer (dpy, None, s->root, 0, 0, 0, 0, s->left + s->width - 2, s->top + s->height - 2); #endif if (!s) return; @@ -825,3 +841,4 @@ listen_for_events () } } } + diff --git a/src/globals.h b/src/globals.h index 2e5ac29..4a4ed46 100644 --- a/src/globals.h +++ b/src/globals.h @@ -141,4 +141,7 @@ extern struct rp_hook_db_entry rp_hook_db[]; void set_rp_window_focus (rp_window *win); void set_window_focus (Window window); +extern int rp_have_xinerama; +extern int xine_screen_count; + #endif diff --git a/src/group.c b/src/group.c index c4815ec..3e637aa 100644 --- a/src/group.c +++ b/src/group.c @@ -331,7 +331,7 @@ group_last_window (rp_group *g) if (cur->win->last_access >= last_access && cur->win != current_window() && !find_windows_frame (cur->win) - && cur->win->scr == s) + && (cur->win->scr == s || rp_have_xinerama)) { most_recent = cur; last_access = cur->win->last_access; @@ -365,7 +365,7 @@ group_next_window (rp_group *g, rp_window *win) cur != we; cur = list_next_entry (cur, &g->mapped_windows, node)) { - if (!find_windows_frame (cur->win) && cur->win->scr == current_screen()) + if (!find_windows_frame (cur->win) && (cur->win->scr == current_screen() || rp_have_xinerama)) { return cur->win; } @@ -395,7 +395,7 @@ group_prev_window (rp_group *g, rp_window *win) cur != we; cur = list_prev_entry (cur, &g->mapped_windows, node)) { - if (!find_windows_frame (cur->win) && cur->win->scr == current_screen()) + if (!find_windows_frame (cur->win) && (cur->win->scr == current_screen() || rp_have_xinerama)) { return cur->win; } diff --git a/src/main.c b/src/main.c index b2daf7a..aace543 100644 --- a/src/main.c +++ b/src/main.c @@ -44,8 +44,6 @@ # define WAIT_ANY -1 #endif -static void init_screen (rp_screen *s, int screen_num); - /* Command line options */ static struct option ratpoison_longopts[] = { {"help", no_argument, 0, 'h'}, @@ -614,38 +612,8 @@ main (int argc, char *argv[]) init_defaults (); init_groups (); init_window_stuff (); - - /* Get the number of screens */ - num_screens = ScreenCount (dpy); - - /* make sure the screen specified is valid. */ - if (screen_arg) - { - if (screen_num < 0 || screen_num >= num_screens) - { - fprintf (stderr, "%d is an invalid screen for the display\n", screen_num); - exit (EXIT_FAILURE); - } - - /* we're only going to use one screen. */ - num_screens = 1; - } - - /* Initialize the screens */ - screens = (rp_screen *)xmalloc (sizeof (rp_screen) * num_screens); - PRINT_DEBUG (("%d screens.\n", num_screens)); - - if (screen_arg) - { - init_screen (&screens[0], screen_num); - } - else - { - for (i=0; irat = XCreateFontCursor( dpy, XC_icon ); -} - -static void -init_screen (rp_screen *s, int screen_num) -{ - XGCValues gv; - - /* Select on some events on the root window, if this fails, then - there is already a WM running and the X Error handler will catch - it, terminating ratpoison. */ - XSelectInput(dpy, RootWindow (dpy, screen_num), - PropertyChangeMask | ColormapChangeMask - | SubstructureRedirectMask | SubstructureNotifyMask ); - XSync (dpy, False); - - /* Create the numset for the frames. */ - s->frames_numset = numset_new (); - - /* Build the display string for each screen */ - s->display_string = xmalloc (strlen(DisplayString (dpy)) + 21); - sprintf (s->display_string, "DISPLAY=%s", DisplayString (dpy)); - if (strrchr (DisplayString (dpy), ':')) - { - char *dot; - - dot = strrchr(s->display_string, '.'); - if (dot) - sprintf(dot, ".%i", screen_num); - } - - PRINT_DEBUG (("%s\n", s->display_string)); - - s->screen_num = screen_num; - s->root = RootWindow (dpy, screen_num); - s->def_cmap = DefaultColormap (dpy, screen_num); - XGetWindowAttributes (dpy, s->root, &s->root_attr); - - init_rat_cursor (s); - - s->fg_color = BlackPixel (dpy, s->screen_num); - s->bg_color = WhitePixel (dpy, s->screen_num); - - /* Setup the GC for drawing the font. */ - gv.foreground = s->fg_color; - gv.background = s->bg_color; - gv.function = GXcopy; - gv.line_width = 1; - gv.subwindow_mode = IncludeInferiors; - gv.font = defaults.font->fid; - s->normal_gc = XCreateGC(dpy, s->root, - GCForeground | GCBackground | GCFunction - | GCLineWidth | GCSubwindowMode | GCFont, - &gv); - - /* Create the program bar window. */ - s->bar_is_raised = 0; - s->bar_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, - defaults.bar_border_width, - s->fg_color, s->bg_color); - - /* Setup the window that will receive all keystrokes once the prefix - key has been pressed. */ - s->key_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, 0, - WhitePixel (dpy, s->screen_num), - BlackPixel (dpy, s->screen_num)); - XSelectInput (dpy, s->key_window, KeyPressMask | KeyReleaseMask); - XMapWindow (dpy, s->key_window); - - /* Create the input window. */ - s->input_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, - defaults.bar_border_width, - s->fg_color, s->bg_color); - XSelectInput (dpy, s->input_window, KeyPressMask | KeyReleaseMask); - - /* Create the frame indicator window */ - s->frame_window = XCreateSimpleWindow (dpy, s->root, 1, 1, 1, 1, defaults.bar_border_width, - s->fg_color, s->bg_color); - - /* Create the help window */ - s->help_window = XCreateSimpleWindow (dpy, s->root, 0, 0, s->root_attr.width, - s->root_attr.height, 0, s->fg_color, s->bg_color); - XSelectInput (dpy, s->help_window, KeyPressMask); - - XSync (dpy, 0); -} - static void free_screen (rp_screen *s) { @@ -824,6 +702,8 @@ clean_up () } free (screens); + free_xinerama(); + XFreeFont (dpy, defaults.font); free (defaults.window_fmt); @@ -831,14 +711,3 @@ clean_up () XCloseDisplay (dpy); } -/* Given a root window, return the rp_screen struct */ -rp_screen * -find_screen (Window w) -{ - int i; - - for (i=0; ibar_window - || wins[i] == s->key_window - || wins[i] == s->input_window - || wins[i] == s->frame_window - || wins[i] == s->help_window + if (is_rp_window_for_screen(wins[i], s) || attr.override_redirect == True || unmanaged_window (wins[i])) continue; + /* FIXME - with this code, windows which are entirely off-screen + * when RP starts won't ever be managed when Xinerama is enabled. + */ + if (rp_have_xinerama + && ((attr.x > s->left + s->width) + || (attr.x < s->left) + || (attr.y > s->top + s->height) + || (attr.y < s->top))) continue; + win = add_to_window_list (s, wins[i]); PRINT_DEBUG (("map_state: %s\n", @@ -671,7 +676,7 @@ maximize (rp_window *win) /* Actually do the maximizing. */ - XMoveResizeWindow (dpy, win->w, win->x, win->y, win->width, win->height); + XMoveResizeWindow (dpy, win->w, win->scr->left + win->x, win->scr->top + win->y, win->width, win->height); XSetWindowBorderWidth (dpy, win->w, win->border); XSync (dpy, False); @@ -696,7 +701,7 @@ force_maximize (rp_window *win) problem. */ if (win->hints->flags & PResizeInc) { - XMoveResizeWindow (dpy, win->w, win->x, win->y, + XMoveResizeWindow (dpy, win->w, win->scr->left + win->x, win->scr->top + win->y, win->width + win->hints->width_inc, win->height + win->hints->height_inc); } @@ -708,7 +713,7 @@ force_maximize (rp_window *win) XSync (dpy, False); /* Resize the window to its proper maximum size. */ - XMoveResizeWindow (dpy, win->w, win->x, win->y, win->width, win->height); + XMoveResizeWindow (dpy, win->w, win->scr->left + win->x, win->scr->top + win->y, win->width, win->height); XSetWindowBorderWidth (dpy, win->w, win->border); XSync (dpy, False); diff --git a/src/ratpoison.h b/src/ratpoison.h index 0a9719e..eb34dcf 100644 --- a/src/ratpoison.h +++ b/src/ratpoison.h @@ -84,6 +84,7 @@ extern XGCValues gv; #endif /* HAVE_READLINE_HISTORY_H */ #include "completions.h" #include "hook.h" +#include "xinerama.h" void clean_up (); rp_screen *find_screen (Window w); diff --git a/src/screen.c b/src/screen.c index dec512a..f46e3ca 100644 --- a/src/screen.c +++ b/src/screen.c @@ -19,23 +19,27 @@ */ #include "ratpoison.h" +#include +#include + +static void init_screen (rp_screen *s, int screen_num); int screen_width (rp_screen *s) { - return DisplayWidth (dpy, s->screen_num) - defaults.padding_right - defaults.padding_left; + return s->width - defaults.padding_right - defaults.padding_left; } int screen_height (rp_screen *s) { - return DisplayHeight (dpy, s->screen_num) - defaults.padding_bottom - defaults.padding_top; + return s->height - defaults.padding_bottom - defaults.padding_top; } int screen_left (rp_screen *s) { - return defaults.padding_left; + return s->left + defaults.padding_left; } int @@ -47,7 +51,7 @@ screen_right (rp_screen *s) int screen_top (rp_screen *s) { - return defaults.padding_top; + return s->top + defaults.padding_top; } int @@ -116,3 +120,210 @@ screen_get_frame (rp_screen *s, int frame_num) return NULL; } + +/* Given a root window, return the rp_screen struct */ +rp_screen * +find_screen (Window w) +{ + int i; + + for (i=0; i= num_screens) + { + fprintf (stderr, "%d is an invalid screen for the display\n", screen_num); + exit (EXIT_FAILURE); + } + + /* we're only going to use one screen. */ + num_screens = 1; + } + + /* Initialize the screens */ + screens = (rp_screen *)xmalloc (sizeof (rp_screen) * num_screens); + PRINT_DEBUG (("%d screens.\n", num_screens)); + + if (screen_arg) + { + init_screen (&screens[0], screen_num); + } + else + { + for (i=0; irat = XCreateFontCursor( dpy, XC_icon ); +} + +static void +init_screen (rp_screen *s, int screen_num) +{ + XGCValues gv; + int xine_screen_num; + + /* We use screen_num below to refer to the real X screen number, but + * if we're using Xinerama, it will only be the Xinerama logical screen + * number. So we shuffle it away and replace it with the real one now, + * to cause confusion. -- CP + */ + if (rp_have_xinerama) + { + xine_screen_num = screen_num; + screen_num = DefaultScreen(dpy); + xinerama_get_screen_info(xine_screen_num, + &s->left, &s->top, &s->width, &s->height); + } + else + { + xine_screen_num = screen_num; + s->left = 0; + s->top = 0; + s->width = DisplayWidth(dpy, screen_num); + s->height = DisplayHeight(dpy, screen_num); + } + + /* Select on some events on the root window, if this fails, then + there is already a WM running and the X Error handler will catch + it, terminating ratpoison. */ + XSelectInput(dpy, RootWindow (dpy, screen_num), + PropertyChangeMask | ColormapChangeMask + | SubstructureRedirectMask | SubstructureNotifyMask ); + XSync (dpy, False); + + /* Create the numset for the frames. */ + s->frames_numset = numset_new (); + + /* Build the display string for each screen */ + s->display_string = xmalloc (strlen(DisplayString (dpy)) + 21); + sprintf (s->display_string, "DISPLAY=%s", DisplayString (dpy)); + if (strrchr (DisplayString (dpy), ':')) + { + char *dot; + + dot = strrchr(s->display_string, '.'); + if (dot) + sprintf(dot, ".%i", screen_num); + } + + PRINT_DEBUG (("%s\n", s->display_string)); + + s->screen_num = screen_num; + s->xine_screen_num = xine_screen_num; + s->root = RootWindow (dpy, screen_num); + s->def_cmap = DefaultColormap (dpy, screen_num); + + init_rat_cursor (s); + + s->fg_color = BlackPixel (dpy, s->screen_num); + s->bg_color = WhitePixel (dpy, s->screen_num); + + /* Setup the GC for drawing the font. */ + gv.foreground = s->fg_color; + gv.background = s->bg_color; + gv.function = GXcopy; + gv.line_width = 1; + gv.subwindow_mode = IncludeInferiors; + gv.font = defaults.font->fid; + s->normal_gc = XCreateGC(dpy, s->root, + GCForeground | GCBackground | GCFunction + | GCLineWidth | GCSubwindowMode | GCFont, + &gv); + + /* Create the program bar window. */ + s->bar_is_raised = 0; + s->bar_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, + defaults.bar_border_width, + s->fg_color, s->bg_color); + + /* Setup the window that will receive all keystrokes once the prefix + key has been pressed. */ + s->key_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, 0, + WhitePixel (dpy, s->screen_num), + BlackPixel (dpy, s->screen_num)); + XSelectInput (dpy, s->key_window, KeyPressMask | KeyReleaseMask); + XMapWindow (dpy, s->key_window); + + /* Create the input window. */ + s->input_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, + defaults.bar_border_width, + s->fg_color, s->bg_color); + XSelectInput (dpy, s->input_window, KeyPressMask | KeyReleaseMask); + + /* Create the frame indicator window */ + s->frame_window = XCreateSimpleWindow (dpy, s->root, 1, 1, 1, 1, defaults.bar_border_width, + s->fg_color, s->bg_color); + + /* Create the help window */ + s->help_window = XCreateSimpleWindow (dpy, s->root, s->left, s->top, s->width, + s->height, 0, s->fg_color, s->bg_color); + XSelectInput (dpy, s->help_window, KeyPressMask); + + XSync (dpy, 0); +} + +static int +is_rp_window_for_given_screen (Window w, rp_screen *s) +{ + if (w != s->key_window && + w != s->bar_window && + w != s->input_window && + w != s->frame_window && + w != s->help_window) + return 0; + return 1; +} + +int +is_rp_window_for_screen(Window w, rp_screen *s) +{ + int i; + + if (rp_have_xinerama) + { + for (i=0; itransient && !(win->hints->flags & PMaxSize - && win->hints->max_width < win->scr->root_attr.width - && win->hints->max_height < win->scr->root_attr.height)) + && win->hints->max_width < win->scr->width + && win->hints->max_height < win->scr->height)) #else if (!win->transient) #endif @@ -99,6 +101,11 @@ set_frames_window (rp_frame *frame, rp_window *win) { frame->win_number = win->number; win->frame_number = frame->number; + + /* We need to make sure that win and frame are on the same screen, + * since with Xinerama, windows can move from one screen to another. + */ + win->scr = frames_screen(frame); } else { @@ -272,7 +279,7 @@ find_window_for_frame (rp_frame *frame) list_for_each_entry (cur, &rp_current_group->mapped_windows, node) { - if (cur->win->scr == s + if ((cur->win->scr == s || rp_have_xinerama) && cur->win != current_window() && !find_windows_frame (cur->win) && cur->win->last_access >= last_access @@ -840,7 +847,7 @@ set_active_frame (rp_frame *frame) s->current_frame = frame->number; /* If frame->win == NULL, then rp_current_screen is not updated. */ - rp_current_screen = s->screen_num; + rp_current_screen = s->xine_screen_num; update_bar (s); @@ -913,9 +920,14 @@ show_frame_message (char *msg) width = defaults.bar_x_padding * 2 + XTextWidth (defaults.font, msg, strlen (msg)); height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2); + /* We don't want another frame indicator to be displayed on another + * screen at the same time, so we hide it before bringing it back again. + */ + hide_frame_indicator (); + XMoveResizeWindow (dpy, s->frame_window, - frame->x + frame->width / 2 - width / 2, - frame->y + frame->height / 2 - height / 2, + s->left + frame->x + frame->width / 2 - width / 2, + s->top + frame->y + frame->height / 2 - height / 2, width, height); XMapRaised (dpy, s->frame_window); diff --git a/src/window.c b/src/window.c index 1ac063c..c39142a 100644 --- a/src/window.c +++ b/src/window.c @@ -320,6 +320,11 @@ give_window_focus (rp_window *win, rp_window *last_win) we can track which window was last accessed. */ static int counter = 1; + /* Warp the cursor to the window's saved position if last_win and + win are different windows. */ + if (last_win != NULL && win != last_win) + save_mouse_position (last_win); + if (win == NULL) return; counter++; @@ -327,11 +332,6 @@ give_window_focus (rp_window *win, rp_window *last_win) unhide_window (win); - /* Warp the cursor to the window's saved position if last_win and - win are different windows. */ - if (last_win != NULL && win != last_win) - save_mouse_position (last_win); - if (defaults.warp) { PRINT_DEBUG (("Warp pointer\n")); @@ -344,7 +344,7 @@ give_window_focus (rp_window *win, rp_window *last_win) XInstallColormap (dpy, win->colormap); /* Finally, give the window focus */ - rp_current_screen = win->scr->screen_num; + rp_current_screen = win->scr->xine_screen_num; set_rp_window_focus (win); XSync (dpy, False); @@ -464,7 +464,17 @@ set_active_window (rp_window *win) if (win == NULL) return; - frame = screen_get_frame (win->scr, win->scr->current_frame); + /* With Xinerama, we can move a window over to the current screen; otherwise + * we have to switch to the screen that the window belongs to. + */ + if (rp_have_xinerama) + { + frame = screen_get_frame (current_screen(), current_screen()->current_frame); + } + else + { + frame = screen_get_frame (win->scr, win->scr->current_frame); + } last_win = set_frames_window (frame, win); if (last_win) PRINT_DEBUG (("last window: %s\n", window_name (last_win))); @@ -481,8 +491,8 @@ set_active_window (rp_window *win) #ifdef MAXSIZE_WINDOWS_ARE_TRANSIENTS if (!win->transient && !(win->hints->flags & PMaxSize - && (win->hints->max_width < win->scr->root_attr.width - || win->hints->max_height < win->scr->root_attr.height))) + && (win->hints->max_width < win->scr->width + || win->hints->max_height < win->scr->height))) #else if (!win->transient) #endif -- cgit v1.2.3