From 07d5d72b9d16fa2e1c23b9b71f3bae961505bdc3 Mon Sep 17 00:00:00 2001 From: Jeff Abrahamson Date: Mon, 15 Sep 2014 20:20:00 +0200 Subject: [PATCH 4/6] Add command pullwindow. Refactor pullwindow and pushwindow to share code. Document some concerns to address before merging into trunk. --- src/actions.c | 35 ++++++++++++++++------------------- src/actions.h | 1 + src/window.c | 29 +++++++++++++++++++++++++++++ src/window.h | 1 + 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/actions.c b/src/actions.c index 7ce76c1..668d7c6 100644 --- a/src/actions.c +++ b/src/actions.c @@ -295,6 +295,8 @@ init_user_commands(void) "Hook: ", arg_HOOK); add_command ("meta", cmd_meta, 1, 0, 0, "key: ", arg_KEY); + add_command("pullwindow", cmd_pullwindow, 1, 1, 1, + "Pull window to current frame: ", arg_FRAME); add_command("pushwindow", cmd_pushwindow, 1, 1, 1, "Push current window to frame: ", arg_FRAME); add_command ("msgwait", cmd_msgwait, 1, 0, 0, @@ -761,7 +763,7 @@ initialize_default_keybindings (void) add_keybinding (XK_i, RP_CONTROL_MASK, "info", map); add_keybinding (XK_k, 0, "delete", map); add_keybinding (XK_k, RP_CONTROL_MASK, "delete", map); - add_keybinding (XK_l, 0, "redisplay", map); + add_keybinding (XK_l, 0, "pushwindow", map); add_keybinding (XK_l, RP_CONTROL_MASK, "redisplay", map); add_keybinding (XK_m, 0, "lastmsg", map); add_keybinding (XK_m, RP_CONTROL_MASK, "lastmsg", map); @@ -3687,29 +3689,24 @@ set_maxsizegravity (struct cmdarg **args) } cmdret * +cmd_pullwindow (int interactive UNUSED, struct cmdarg **args) +{ + rp_frame *src_frame = ARG(0, frame); + rp_frame *dest_frame = current_frame(); + if (move_window_between_frames(src_frame, dest_frame)) + return cmdret_new (RET_FAILURE, "no window to pull"); + set_active_frame(dest_frame, 0); + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * cmd_pushwindow (int interactive UNUSED, struct cmdarg **args) { rp_frame *src_frame = current_frame(); rp_frame *dest_frame = ARG(0, frame); - - rp_window *window_to_move = find_window_number(src_frame->win_number); - rp_window *window_to_reveal = find_window_for_frame (src_frame); - rp_window *window_to_cover = set_frames_window(dest_frame, window_to_move); - maximize (window_to_move); - unhide_window (window_to_move); - XRaiseWindow (dpy, window_to_move->w); - - hide_window(window_to_cover); - - set_frames_window(src_frame, window_to_reveal); - maximize (window_to_reveal); - unhide_window (window_to_reveal); - XRaiseWindow (dpy, window_to_reveal->w); - + if (move_window_between_frames(src_frame, dest_frame)) + return cmdret_new (RET_FAILURE, "no window to push"); set_active_frame(src_frame, 0); - - // Note that I haven't pushed anything to the undo stack yet. - return cmdret_new (RET_SUCCESS, NULL); } diff --git a/src/actions.h b/src/actions.h index 47564ec..43e792e 100644 --- a/src/actions.h +++ b/src/actions.h @@ -165,6 +165,7 @@ RP_CMD (other); RP_CMD (prev); RP_CMD (prev_frame); RP_CMD (prevscreen); +RP_CMD (pullwindow); RP_CMD (pushwindow); RP_CMD (quit); RP_CMD (redisplay); diff --git a/src/window.c b/src/window.c index de9032a..74be244 100644 --- a/src/window.c +++ b/src/window.c @@ -105,6 +105,35 @@ window_name (rp_window *win) return NULL; } +int move_window_between_frames(rp_frame *src_frame, rp_frame *dest_frame) +{ + rp_window *window_to_move = find_window_number(src_frame->win_number); + if (!window_to_move) + return -1; + rp_window *window_to_reveal = find_window_for_frame (src_frame); + rp_window *window_to_cover = set_frames_window(dest_frame, window_to_move); + maximize (window_to_move); + unhide_window (window_to_move); + XRaiseWindow (dpy, window_to_move->w); + + hide_window(window_to_cover); + + if (!window_to_reveal) + window_to_reveal = window_to_cover; + if (window_to_reveal) { + // It could happen that we are moving a window with no window to + // replace it. In that case, just leave the frame empty. + set_frames_window(src_frame, window_to_reveal); + maximize (window_to_reveal); + unhide_window (window_to_reveal); + XRaiseWindow (dpy, window_to_reveal->w); + } + // TODO(jma): What if a window is transient? + // TODO(jma): What if we are covering a transient window? + // TODO(jma): What manages active and inactive frame coloring? Probably give_window_focus(). + return 0; +} + /* FIXME: we need to verify that the window is running on the same host as something. otherwise there could be overlapping PIDs. */ struct rp_child_info * diff --git a/src/window.h b/src/window.h index fdd246c..f32a2e8 100644 --- a/src/window.h +++ b/src/window.h @@ -36,6 +36,7 @@ void goto_window (rp_window *win); void set_current_window (rp_window *win); void update_window_gravity (rp_window *win); char *window_name (rp_window *win); +int move_window_between_frames(rp_frame *src_frame, rp_frame *dest_frame); /* int goto_window_name (char *name); */ rp_window *find_window_other (rp_screen *screen); -- 1.9.1