summaryrefslogtreecommitdiff
path: root/src/actions.c
diff options
context:
space:
mode:
authorsabetts <sabetts>2003-06-23 01:35:46 +0000
committersabetts <sabetts>2003-06-23 01:35:46 +0000
commit3832aed09a9d93ef47bc33a80e01747df3585f2a (patch)
tree6b8bdfde40f615cfac56f1572d8c1e66f02b835f /src/actions.c
parent5cf9d01be5ec1a370337a286447bec0c422a7c4a (diff)
downloadratpoison-3832aed09a9d93ef47bc33a80e01747df3585f2a.zip
(cmd_groups): print a * beside the current
group. if non-interactively called, return the string. (sync_wins): rewrite.
Diffstat (limited to 'src/actions.c')
-rw-r--r--src/actions.c225
1 files changed, 194 insertions, 31 deletions
diff --git a/src/actions.c b/src/actions.c
index d3af66c..ce74a6f 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -2930,6 +2930,155 @@ cmd_warp (int interactive, char *data)
return NULL;
}
+/* FIXME: This is sorely broken. */
+static void
+sync_wins (rp_screen *s)
+{
+ rp_window *win;
+ XWindowAttributes attr;
+ unsigned int i, nwins;
+ Window dw1, dw2, *wins;
+ XQueryTree(dpy, s->root, &dw1, &dw2, &wins, &nwins);
+
+ /* Remove any windows in our cached lists that aren't in the query
+ tree. These windows have been destroyed. */
+ list_for_each_entry (win, &rp_mapped_window, node)
+ {
+ int found;
+
+ found = 0;
+ for (i=0; i<nwins; i++)
+ {
+ if (win->w == wins[i])
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ {
+ ignore_badwindow++;
+
+ /* If, somehow, the window is not withdrawn before it is destroyed,
+ perform the necessary steps to withdraw the window before it is
+ unmanaged. */
+ if (win->state == IconicState)
+ {
+ PRINT_DEBUG (("Destroying Iconic Window (%s)\n", window_name (win)));
+ withdraw_window (win);
+ }
+ else if (win->state == NormalState)
+ {
+ rp_frame *frame;
+
+ PRINT_DEBUG (("Destroying Normal Window (%s)\n", window_name (win)));
+ frame = find_windows_frame (win);
+ if (frame)
+ {
+ cleanup_frame (frame);
+ if (frame->number == win->scr->current_frame)
+ set_active_frame (frame);
+ }
+ withdraw_window (win);
+ }
+
+ /* Now that the window is guaranteed to be in the unmapped window
+ list, we can safely stop managing it. */
+ unmanage (win);
+ ignore_badwindow--;
+ }
+ }
+
+
+ for (i=0; i<nwins; i++)
+ {
+ XGetWindowAttributes(dpy, wins[i], &attr);
+ if (wins[i] == s->bar_window
+ || wins[i] == s->key_window
+ || wins[i] == s->input_window
+ || wins[i] == s->frame_window
+ || wins[i] == s->help_window
+ || attr.override_redirect == True) continue;
+
+ /* Find the window in our mapped window list. */
+ win = find_window_in_list (wins[i], &rp_mapped_window);
+ if (win)
+ {
+ rp_frame *frame;
+ /* If the window is viewable and it is in a frame, then
+ maximize it and go to the next window. */
+ if (attr.map_state == IsViewable)
+ {
+ frame = find_windows_frame (win);
+ if (frame)
+ {
+ maximize (win);
+ }
+ else
+ {
+ hide_window (win);
+ }
+ }
+ else if (attr.map_state == IsUnmapped
+ && get_state (win) == IconicState)
+ {
+ frame = find_windows_frame (win);
+ if (frame)
+ {
+ unhide_window (win);
+ maximize (win);
+ }
+ }
+ else
+ {
+ PRINT_DEBUG (("I don't know what to do...\n"));
+ }
+
+ /* We've handled the window. */
+ continue;
+ }
+
+ /* Try the unmapped window list. */
+ win = find_window_in_list (wins[i], &rp_unmapped_window);
+ if (win)
+ {
+ rp_frame *frame;
+ /* If the window is viewable and it is in a frame, then
+ maximize it and go to the next window. */
+ if (attr.map_state == IsViewable)
+ {
+ /* We need to map it since it's visible now. */
+ map_window (win);
+ }
+ else if (attr.map_state == IsUnmapped
+ && get_state (win) == IconicState)
+ {
+ /* We need to map the window and then hide it. */
+ map_window (win);
+ hide_window (win);
+ }
+ else
+ {
+ PRINT_DEBUG (("I think it's all sync'd up...\n"));
+ }
+
+ /* We've handled the window. */
+ continue;
+ }
+
+ /* The window isn't in the mapped or unmapped window list so add
+ it. */
+ win = add_to_window_list (s, wins[i]);
+
+ /* If it's visible or iconized. "Map" it. */
+ if (attr.map_state == IsViewable
+ || (attr.map_state == IsUnmapped
+ && get_state (win) == IconicState))
+ map_window (win);
+ }
+
+}
+
/* Temporarily give control over to another window manager, reclaiming
control when that WM terminates. */
char *
@@ -2937,6 +3086,7 @@ cmd_tmpwm (int interactive, char *data)
{
struct list_head *tmp, *iter;
rp_window *win = NULL;
+ int child;
int status;
int pid;
int i;
@@ -2964,30 +3114,12 @@ cmd_tmpwm (int interactive, char *data)
XSync (dpy, False);
- /* FIXME: drop all our windows. We shouldn't do this. */
- list_for_each_safe_entry (win, iter, tmp, &rp_mapped_window, node)
- {
- rp_frame *frame;
-
- /* Remove the window from the frame. */
- frame = find_windows_frame (win);
- if (frame) cleanup_frame (frame);
- if (frame->number == win->scr->current_frame) set_active_frame (frame);
-
- /* put the window in the unmapped list. */
- numset_release (rp_window_numset, win->number);
- list_move_tail(&win->node, &rp_unmapped_window);
- }
-
- /* Now that all the windows are in the unmapped list, unmanage them. */
- list_for_each_safe_entry (win, iter, tmp, &rp_unmapped_window, node)
- {
- unmanage (win);
- }
-
/* Launch the new WM and wait for it to terminate. */
pid = spawn (data);
- waitpid (pid, &status, 0);
+ do
+ {
+ child = waitpid (pid, &status, 0);
+ } while (child != pid);
/* Enable the event selection on the root window. */
for (i=0; i<num_screens; i++)
@@ -3000,9 +3132,12 @@ cmd_tmpwm (int interactive, char *data)
}
XSync (dpy, False);
- /* Pick up all the windows. */
+ /* Sort through all the windows in each group and pick out the ones
+ that are unmapped or destroyed. */
for (i=0; i<num_screens; i++)
- scanwins (&screens[i]);
+ {
+ sync_wins (&screens[i]);
+ }
/* If no window has focus, give the key_window focus. */
if (current_window() == NULL)
@@ -3405,27 +3540,55 @@ cmd_groups (int interactive, char *data)
buffer = sbuf_new (0);
+ /* Generate the string. */
list_for_each_entry (cur, &rp_groups, node)
{
char *fmt;
+ char separator;
if (cur == rp_current_group)
mark_start = strlen (sbuf_get (buffer));
- fmt = xsprintf ("%d-%s", cur->number, cur->name);
+ /* Pad start of group name with a space for row style. */
+ if (defaults.window_list_style == STYLE_ROW)
+ sbuf_concat (buffer, " ");
+
+ if(cur == rp_current_group)
+ separator = '*';
+ else
+ separator = '-';
+
+ fmt = xsprintf ("%d%c%s", cur->number, separator, cur->name);
sbuf_concat (buffer, fmt);
- if (cur->node.next != &rp_groups)
- sbuf_concat (buffer, "\n");
+ /* Pad end of group name with a space for row style. */
+ if (defaults.window_list_style == STYLE_ROW)
+ {
+ sbuf_concat (buffer, " ");
+ }
+ else
+ {
+ if (cur->node.next != &rp_groups)
+ sbuf_concat (buffer, "\n");
+ }
if (cur == rp_current_group)
mark_end = strlen (sbuf_get (buffer));
}
- marked_message (sbuf_get (buffer), mark_start, mark_end);
- sbuf_free (buffer);
-
- return NULL;
+ /* Display it or return it. */
+ if (interactive)
+ {
+ marked_message (sbuf_get (buffer), mark_start, mark_end);
+ sbuf_free (buffer);
+ return NULL;
+ }
+ else
+ {
+ char* tmp = sbuf_get(buffer);
+ free(buffer);
+ return tmp;
+ }
}
/* Move a window to a different group. */