summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog60
-rw-r--r--NEWS4
-rw-r--r--src/actions.c14
-rw-r--r--src/data.h4
-rw-r--r--src/events.c97
-rw-r--r--src/list.c45
-rw-r--r--src/list.h2
-rw-r--r--src/main.c46
-rw-r--r--src/manage.c85
-rw-r--r--src/manage.h4
-rw-r--r--src/split.c30
-rw-r--r--src/split.h1
12 files changed, 270 insertions, 122 deletions
diff --git a/ChangeLog b/ChangeLog
index b6012b5..830f781 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,63 @@
+2001-04-13 shawn <sabetts@diggin.lamenet.tmp>
+
+ * src/split.h (blank_frame): new prototype
+
+ * src/split.c (split_frame): calls unhide_window after maximizing
+ the new frame's window.
+ (remove_all_splits): hide all windows but the current one
+ (remove_all_splits): maximize the current window in its newly
+ resized frame.
+ (remove_frame): hide the frame's window after removing it from the
+ list.
+ (blank_frame): new function
+
+ * src/manage.h (withdraw_window): new prototype
+ (hide_window): likewise
+ (unhide_window): likewise
+
+ * src/manage.c (scanwins): glob ignored windows into 1 if
+ statement.
+ (scanwins): set the window's state to NormalState before calling
+ map_window.
+ (set_state): sets win->state
+ (map_window): calls set_state
+ (hide_window): new function
+ (unhide_window): likewise
+ (withdraw_window): new function
+
+ * src/main.c (main): setup error handlers after --command,
+ --restart, and --kill commands have been processed.
+ (main): doesn't call set_active_window
+ (init_screen): XSync's after selecting ewents on the root window.
+ (clean_up): map iconized windows
+
+ * src/list.h (give_window_focus): prototype updated
+
+ * src/list.c (give_window_focus): takes a second argument,
+ last_win.
+ (give_window_focus): calls unhide_window
+ (give_window_focus): uses last_win instead of current_window()
+ (set_active_window): hides the last window and unhides the new
+ window.
+ (set_active_window): calls give_window_focus
+
+ * src/events.c (cleanup_frame): maximizes the frame's new window
+ (unmap_notify): do nothing if the window is in the iconic
+ state. Withdraw the window if it is in the normal state.
+ (map_request): calls unhide_window if the window is iconized. Do
+ nothing if it is already mapped.
+ (destroy_window): tightened up
+ (client_msg): detects iconize requests from clients.
+
+ * src/data.h (STATE_UNMAPPED): remove. Dependant code uses
+ WithdawnState in its stead.
+ (STATE_MAPPED): likewise. Dependant code uses NormalState in its
+ stead
+
+ * src/actions.c (initialize_default_keybindings): new keybinding -
+ bound to "select -"
+ (cmd_select): the string "-" selects a blank window
+
2001-04-12 shawn <sabetts@badbox.secure.basis.org>
* src/main.c (main): calls XCloseDisplay before exitting after
diff --git a/NEWS b/NEWS
index f0cada9..207f9cb 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ ratpoison NEWS --- history of user-visible changes. -*- outline -*-
* Changes since 0.1.1
+** windows not residing in a frame are hidden
+This gets rid of annoying flickers around the edges of active windows
+as windows in the back update.
+
** rat cursor changes
When you hit the prefix key the rat cursor changes to a square to tell
diff --git a/src/actions.c b/src/actions.c
index ab486bd..097991b 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -95,6 +95,7 @@ initialize_default_keybindings (void)
add_keybinding (XK_7, 0, "select 7");
add_keybinding (XK_8, 0, "select 8");
add_keybinding (XK_9, 0, "select 9");
+ add_keybinding (XK_minus, 0, "select -");
add_keybinding (XK_A, 0, "title");
add_keybinding (XK_A, ControlMask, "title");
add_keybinding (XK_K, 0, "kill");
@@ -468,11 +469,16 @@ cmd_select (void *data)
/* Only search if the string contains something to search for. */
if (strlen (str) > 0)
{
- if ((w = find_window_name (str)))
- goto_window (w);
-
+ if (strlen (str) == 1 && str[0] == '-')
+ {
+ blank_frame (rp_current_frame);
+ }
+/* else if ((w = find_window_name (str))) */
+/* { */
+/* goto_window (w); */
+/* } */
/* try by number */
- if ((n = string_to_window_number (str)) >= 0)
+ else if ((n = string_to_window_number (str)) >= 0)
{
if ((w = find_window_number (n)))
goto_window (w);
diff --git a/src/data.h b/src/data.h
index 300059a..df29704 100644
--- a/src/data.h
+++ b/src/data.h
@@ -28,10 +28,6 @@
#define FONT_HEIGHT(f) ((f)->max_bounds.ascent + (f)->max_bounds.descent)
-#define STATE_UNMAPPED 0
-#define STATE_MAPPED 1
-
-
typedef struct rp_window rp_window;
typedef struct screen_info screen_info;
typedef struct rp_action rp_action;
diff --git a/src/events.c b/src/events.c
index 6476f55..8d48fdb 100644
--- a/src/events.c
+++ b/src/events.c
@@ -59,6 +59,11 @@ static void
cleanup_frame (rp_window_frame *frame)
{
frame->win = find_window_other ();
+ if (frame->win)
+ {
+ maximize (frame->win);
+ unhide_window (frame->win);
+ }
}
void
@@ -75,37 +80,27 @@ unmap_notify (XEvent *ev)
if (s && win)
{
rp_window_frame *frame;
- long data[2] = { WithdrawnState, None };
-
- /* Give back the window number. the window will get another one,
- if it in remapped. */
- return_window_number (win->number);
- win->number = -1;
- win->state = STATE_UNMAPPED;
-
- ignore_badwindow++;
+ /* If the window was inside a frame, fill the frame with another
+ window. */
frame = find_windows_frame (win);
if (frame) cleanup_frame (frame);
- remove_from_list (win);
- append_to_list (win, rp_unmapped_window_sentinel);
-
- /* Update the state of the actual window */
-
- XRemoveFromSaveSet (dpy, win->w);
- XChangeProperty(dpy, win->w, wm_state, wm_state, 32,
- PropModeReplace, (unsigned char *)data, 2);
-
- XSync(dpy, False);
-
- if (frame == rp_current_frame)
+ switch (win->state)
{
- set_active_frame (frame);
+ case IconicState:
+ /* This shouldn't actually happen, since the window is
+ already unmapped, so do nothing */
+ PRINT_DEBUG ("Iconizing iconized window '%s'\n", win->name);
+ break;
+ case NormalState:
+ PRINT_DEBUG ("Withdrawing window '%s'\n", win->name);
+ withdraw_window (win);
+/* hide_window (win); */
+ if (frame == rp_current_frame) set_active_frame (frame);
+ break;
}
- ignore_badwindow--;
-
update_window_names (s);
}
}
@@ -125,7 +120,7 @@ map_request (XEvent *ev)
switch (win->state)
{
- case STATE_UNMAPPED:
+ case WithdrawnState:
PRINT_DEBUG ("Unmapped window\n");
if (unmanaged_window (win->w))
{
@@ -136,17 +131,21 @@ map_request (XEvent *ev)
else
{
PRINT_DEBUG ("managed Window\n");
-
map_window (win);
break;
}
- case STATE_MAPPED:
+ case NormalState:
PRINT_DEBUG ("Mapped Window\n");
+ /* Its already mapped, so we don't have to do anything */
- maximize (win);
- XMapRaised (dpy, win->w);
- set_state (win, NormalState);
- set_active_window (win);
+/* maximize (win); */
+/* XMapRaised (dpy, win->w); */
+/* set_state (win, NormalState); */
+/* set_active_window (win); */
+ break;
+ case IconicState:
+ PRINT_DEBUG ("Mapped iconic window\n");
+ unhide_window (win);
break;
}
}
@@ -174,7 +173,6 @@ void
destroy_window (XDestroyWindowEvent *ev)
{
rp_window *win;
-
ignore_badwindow++;
win = find_window (ev->window);
@@ -185,20 +183,9 @@ destroy_window (XDestroyWindowEvent *ev)
frame = find_windows_frame (win);
if (frame) cleanup_frame (frame);
+ if (frame == rp_current_frame) set_active_frame (frame);
- if (frame == rp_current_frame)
- {
- PRINT_DEBUG ("Destroying the current window.\n");
-
- set_active_frame (frame);
- unmanage (win);
- }
- else
- {
- PRINT_DEBUG ("Destroying some other window.\n");
-
- unmanage (win);
- }
+ unmanage (win);
}
ignore_badwindow--;
@@ -242,7 +229,7 @@ configure_request (XConfigureRequestEvent *e)
PRINT_DEBUG("request CWY %d\n", e->y);
}
- if (e->value_mask & CWStackMode && win->state == STATE_MAPPED)
+ if (e->value_mask & CWStackMode && win->state == NormalState)
{
if (e->detail == Above)
{
@@ -310,6 +297,24 @@ client_msg (XClientMessageEvent *ev)
clean_up ();
exit (EXIT_SUCCESS);
}
+ else if (ev->message_type == wm_change_state)
+ {
+ rp_window *win;
+
+ win = find_window (ev->window);
+ if (win == NULL) return;
+ if (ev->format == 32 && ev->data.l[0] == IconicState)
+ {
+ if (win->state == NormalState)
+ {
+ /* TODO: Handle iconify events */
+ }
+ }
+ else
+ {
+ PRINT_ERROR ("Non-standard WM_CHANGE_STATE format\n");
+ }
+ }
}
static void
diff --git a/src/list.c b/src/list.c
index e4c7680..78359cd 100644
--- a/src/list.c
+++ b/src/list.c
@@ -64,7 +64,7 @@ add_to_window_list (screen_info *s, Window w)
new_window->scr = s;
new_window->last_access = 0;
new_window->prev = NULL;
- new_window->state = STATE_UNMAPPED;
+ new_window->state = WithdrawnState;
new_window->number = -1;
new_window->named = 0;
new_window->hints = XAllocSizeHints ();
@@ -370,51 +370,52 @@ save_mouse_position (rp_window *win)
ignore_badwindow--;
}
+/* Takes focus away from last_win and gives focus to win */
void
-give_window_focus (rp_window *win)
+give_window_focus (rp_window *win, rp_window *last_win)
{
- static int counter = 1; /* increments every time this function
- is called. This way we can track
- which window was last accessed. */
+ /* counter increments every time this function is called. This way
+ we can track which window was last accessed. */
+ static int counter = 1;
if (win == NULL) return;
counter++;
win->last_access = counter;
-/* if (win->scr->bar_is_raised) update_window_names (win->scr); */
-
- if (current_window() != NULL)
- {
- save_mouse_position (current_window());
- }
+ unhide_window (win);
+ /* Warp the cursor to the window's saved position. */
+ if (last_win != NULL) save_mouse_position (last_win);
XWarpPointer (dpy, None, win->scr->root,
0, 0, 0, 0, win->mouse_x, win->mouse_y);
- XSync (dpy, False);
-
- XSetInputFocus (dpy, win->w,
- RevertToPointerRoot, CurrentTime);
/* Swap colormaps */
- if (current_window() != NULL)
- {
- XUninstallColormap (dpy, current_window()->colormap);
- }
+ if (last_win != NULL) XUninstallColormap (dpy, last_win->colormap);
XInstallColormap (dpy, win->colormap);
+
+ /* Finally, give the window focus */
+ XSetInputFocus (dpy, win->w,
+ RevertToPointerRoot, CurrentTime);
+
+ XSync (dpy, False);
}
void
set_active_window (rp_window *win)
{
+ rp_window *last_win;
+
if (win == NULL) return;
- give_window_focus (win);
+ last_win = rp_current_frame->win;
rp_current_frame->win = win;
/* Make sure the window comes up full screen */
- maximize (current_window());
- XRaiseWindow (dpy, win->w);
+ maximize (win);
+ unhide_window (win);
+ give_window_focus (win, last_win);
+ hide_window (last_win);
/* Make sure the program bar is always on the top */
update_window_names (win->scr);
diff --git a/src/list.h b/src/list.h
index c69ff71..2ad0b47 100644
--- a/src/list.h
+++ b/src/list.h
@@ -31,7 +31,7 @@ void last_window ();
rp_window *find_window_in_list (Window w, rp_window *sentinel);
rp_window *find_window (Window w);
void maximize_current_window ();
-void give_window_focus (rp_window *rp_w);
+void give_window_focus (rp_window *win, rp_window *last_win);
void set_active_window (rp_window *win);
void goto_window (rp_window *win);
void set_current_window (rp_window *win);
diff --git a/src/main.c b/src/main.c
index a41973b..ebe18c1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -372,13 +372,6 @@ main (int argc, char *argv[])
return EXIT_FAILURE;
}
- /* Setup signal handlers. */
- XSetErrorHandler(handler);
- set_sig_handler (SIGALRM, alrm_handler);
- set_sig_handler (SIGTERM, sighandler);
- set_sig_handler (SIGINT, sighandler);
- set_sig_handler (SIGHUP, hup_handler);
-
/* Set ratpoison specific Atoms. */
rp_restart = XInternAtom (dpy, "RP_RESTART", False);
rp_kill = XInternAtom (dpy, "RP_KILL", False);
@@ -416,6 +409,14 @@ main (int argc, char *argv[])
wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
+ /* Setup signal handlers. */
+ XSetErrorHandler(handler);
+ set_sig_handler (SIGALRM, alrm_handler);
+ set_sig_handler (SIGTERM, sighandler);
+ set_sig_handler (SIGINT, sighandler);
+ set_sig_handler (SIGHUP, hup_handler);
+
+ /* Setup ratpoison's internal structures */
init_numbers ();
init_window_list ();
init_frame_list ();
@@ -441,9 +442,6 @@ main (int argc, char *argv[])
}
read_startup_files ();
-
- /* Set an initial window as active. */
- set_active_window (find_window_other ());
handle_events ();
@@ -479,6 +477,15 @@ init_screen (screen_info *s, int screen_num)
{
XColor fg_color, bg_color,/* bold_color, */ junk;
+ /* 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 | KeyPressMask | KeyReleaseMask
+ | SubstructureNotifyMask );
+ XSync (dpy, False);
+
s->screen_num = screen_num;
s->root = RootWindow (dpy, screen_num);
s->def_cmap = DefaultColormap (dpy, screen_num);
@@ -520,11 +527,6 @@ init_screen (screen_info *s, int screen_num)
/* | GCLineWidth | GCSubwindowMode | GCFont, */
/* &gv); */
- XSelectInput(dpy, s->root,
- PropertyChangeMask | ColormapChangeMask
- | SubstructureRedirectMask | KeyPressMask | KeyReleaseMask
- | SubstructureNotifyMask );
-
/* Create the program bar window. */
s->bar_is_raised = 0;
s->bar_window = XCreateSimpleWindow (dpy, s->root, 0, 0,
@@ -558,8 +560,22 @@ init_screen (screen_info *s, int screen_num)
void
clean_up ()
{
+ rp_window *cur;
int i;
+
+ /* Map any iconized windows. */
+ for (cur = rp_mapped_window_sentinel->next;
+ cur != rp_mapped_window_sentinel;
+ cur = cur->next)
+ {
+ if (cur->state == IconicState)
+ {
+ unhide_window (cur);
+ }
+ }
+ XSync (dpy, False);
+
for (i=0; i<num_screens; i++)
{
XDestroyWindow (dpy, screens[i].bar_window);
diff --git a/src/manage.c b/src/manage.c
index 1e52fe3..e5bfa4d 100644
--- a/src/manage.c
+++ b/src/manage.c
@@ -233,21 +233,21 @@ scanwins(screen_info *s)
if (wins[i] == s->bar_window
|| wins[i] == s->key_window
|| wins[i] == s->input_window
- || wins[i] == s->frame_window) continue;
+ || wins[i] == s->frame_window
+ || attr.override_redirect == True
+ || unmanaged_window (wins[i])) continue;
- if (attr.override_redirect != True && !unmanaged_window (wins[i]))
+ win = add_to_window_list (s, wins[i]);
+
+ PRINT_DEBUG ("map_state: %d\n", attr.map_state);
+ if (attr.map_state == IsViewable)
{
- win = add_to_window_list (s, wins[i]);
-
- PRINT_DEBUG ("map_state: %d\n", attr.map_state);
- if (attr.map_state == IsViewable)
- {
- map_window (win);
- }
-
+ win->state = NormalState;
+ map_window (win);
}
}
- XFree((void *) wins); /* cast is to shut stoopid compiler up */
+
+ XFree(wins);
}
int
@@ -271,17 +271,15 @@ unmanaged_window (Window w)
return 0;
}
-/* Set the state of the window.
-
- FIXME: This is sort of broken. We should really record the state in
- win->state and mimic the X states NormalState, WithdrawnState,
- IconicState */
+/* Set the state of the window. */
void
set_state (rp_window *win, int state)
{
long data[2];
- data[0] = (long)state;
+ win->state = state;
+
+ data[0] = (long)win->state;
data[1] = (long)None;
XChangeProperty (dpy, win->w, wm_state, wm_state, 32,
@@ -480,19 +478,60 @@ map_window (rp_window *win)
{
PRINT_DEBUG ("Mapping the unmapped window %s\n", win->name);
+ /* Fill in the necessary data about the window */
update_window_information (win);
+ win->number = get_unique_window_number ();
grab_prefix_key (win->w);
- maximize (win);
+ /* Put win in the mapped window list */
+ remove_from_list (win);
+ insert_into_list (win, rp_mapped_window_sentinel);
+
+ /* It is now considered iconic and set_active_window can handle the rest. */
+ set_state (win, IconicState);
+
+ /* FIXME: We may not want a window to pop up out of nowhere */
+ set_active_window (win);
+}
+
+void
+hide_window (rp_window *win)
+{
+ if (win == NULL) return;
+
+ set_state (win, IconicState);
+ XUnmapWindow (dpy, win->w);
+}
+
+void
+unhide_window (rp_window *win)
+{
+ if (win == NULL) return;
+ if (win->state != IconicState) return;
XMapWindow (dpy, win->w);
set_state (win, NormalState);
- set_active_window (win);
+}
- win->state = STATE_MAPPED;
- win->number = get_unique_window_number ();
+void
+withdraw_window (rp_window *win)
+{
+ if (win == NULL) return;
+
+ PRINT_DEBUG ("withdawn_window on '%s'\n", win->name);
+
+ /* Give back the window number. the window will get another one,
+ if it is remapped. */
+ return_window_number (win->number);
+ win->number = -1;
- /* Put win in the mapped window list */
remove_from_list (win);
- insert_into_list (win, rp_mapped_window_sentinel);
+ append_to_list (win, rp_unmapped_window_sentinel);
+
+ XRemoveFromSaveSet (dpy, win->w);
+ set_state (win, WithdrawnState);
+
+ ignore_badwindow++;
+ XSync (dpy, False);
+ ignore_badwindow--;
}
diff --git a/src/manage.h b/src/manage.h
index 22a6127..5607cda 100644
--- a/src/manage.h
+++ b/src/manage.h
@@ -43,4 +43,8 @@ void force_maximize (rp_window *win);
void grab_prefix_key (Window w);
void ungrab_prefix_key (Window w);
+void hide_window (rp_window *win);
+void unhide_window (rp_window *win);
+void withdraw_window (rp_window *win);
+
#endif /* ! _RATPOISION_MANAGE_H */
diff --git a/src/split.c b/src/split.c
index 0533de0..f8150f0 100644
--- a/src/split.c
+++ b/src/split.c
@@ -225,6 +225,7 @@ split_frame (rp_window_frame *frame, int way)
new_frame->win = win;
maximize (win);
+ unhide_window (win);
XRaiseWindow (dpy, win->w);
}
else
@@ -267,17 +268,13 @@ remove_all_splits ()
{
cur = rp_window_frame_sentinel->next;
delete_frame_from_list (cur);
+ if (cur != rp_current_frame) hide_window (cur->win);
free (cur);
}
create_initial_frame ();
rp_current_frame->win = cur_window;
-
- if (cur_window)
- {
- maximize (cur_window);
- XRaiseWindow (dpy, cur_window->w);
- }
+ maximize (cur_window);
}
static int
@@ -384,6 +381,7 @@ remove_frame (rp_window_frame *frame)
PRINT_DEBUG ("Total Area: %d\n", area);
delete_frame_from_list (frame);
+ hide_window (frame->win);
for (cur = rp_window_frame_sentinel->next;
cur != rp_window_frame_sentinel;
@@ -469,7 +467,7 @@ set_active_frame (rp_window_frame *frame)
{
rp_window_frame *old = rp_current_frame;
- give_window_focus (frame->win);
+ give_window_focus (frame->win, rp_current_frame->win);
rp_current_frame = frame;
if (!frame->win || old != rp_current_frame)
@@ -477,6 +475,8 @@ set_active_frame (rp_window_frame *frame)
show_frame_indicator();
}
+ /* If the frame has no window to give focus to, give the frame
+ indicator focus. */
if( !frame->win )
{
XSetInputFocus (dpy, current_screen()->frame_window,
@@ -484,6 +484,22 @@ set_active_frame (rp_window_frame *frame)
}
}
+void
+blank_frame (rp_window_frame *frame)
+{
+ if (frame->win == NULL) return;
+
+ hide_window (frame->win);
+ frame->win = NULL;
+
+ if (frame == rp_current_frame)
+ {
+ show_frame_indicator();
+ XSetInputFocus (dpy, current_screen()->frame_window,
+ RevertToPointerRoot, CurrentTime);
+ }
+}
+
static void
update_frame_indicator ()
{
diff --git a/src/split.h b/src/split.h
index 6ef0186..00139f3 100644
--- a/src/split.h
+++ b/src/split.h
@@ -33,6 +33,7 @@ rp_window_frame *find_frame_prev (rp_window_frame *frame);
rp_window *current_window ();
void init_frame_list ();
void set_active_frame (rp_window_frame *frame);
+void blank_frame (rp_window_frame *frame);
void show_frame_indicator ();
void hide_frame_indicator ();