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

[PATCH 2/4] New command: bring - frame_current_bring()



---
 NEWS                 |    1 +
 doc/herbstluftwm.txt |    4 ++++
 src/command.c        |    3 +++
 src/layout.c         |   44 ++++++++++++++++++++++++++++++++++++++++++++
 src/layout.h         |    1 +
 src/main.c           |    1 +
 6 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index 6948c9f..7965157 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,7 @@ Changes:
     * clients are restored (i.e. managed) from _NET_CLIENT_LIST even if they
       are not visible
     * new command: focus_nth
+    * new command: bring
 
 Release 0.3 on 2012-04-12
 -------------------------
diff --git a/doc/herbstluftwm.txt b/doc/herbstluftwm.txt
index 5d76951..cdf2ec0 100644
--- a/doc/herbstluftwm.txt
+++ b/doc/herbstluftwm.txt
@@ -298,6 +298,10 @@ jumpto urgent|'0xWINID'::
     Puts the focus to the specified window, which is an arbitrary urgent window
     or specified by the hexadecimal '0xWINID'.
 
+bring urgent|'0xWINID'::
+    Moves specified window to the current frame. The window is an arbitrary
+    urgent window or specified by the hexadecimal '0xWINID'.
+
 resize 'DIRECTION' 'FRACTIONDELTA'::
     Changes the next fraction in specified 'DIRECTION' by 'FRACTIONDELTA'.
     'DIRECTION' is specified at the 'focus' command. You should not omit the
diff --git a/src/command.c b/src/command.c
index f70fa73..fee213a 100644
--- a/src/command.c
+++ b/src/command.c
@@ -54,6 +54,7 @@ struct {
     { "list_commands",  0,  no_completion },
     { "list_keybinds",  0,  no_completion },
     { "add_monitor",    7,  no_completion },
+    { "bring",          2,  no_completion },
     { "focus_nth",      2,  no_completion },
     { "cycle",          2,  no_completion },
     { "cycle_all",      3,  no_completion },
@@ -125,6 +126,8 @@ struct {
 } g_completions[] = {
     /* name , relation, index,  completion method                   */
     { "add_monitor",    EQ, 2,  .function = complete_against_tags },
+    { "bring",          EQ, 1,  .list = completion_special_winids },
+    { "bring",          EQ, 1,  .function = complete_against_winids },
     { "cycle",          EQ, 1,  .list = completion_pm_one },
     { "cycle_all",      EQ, 1,  .list = completion_cycle_all_args },
     { "cycle_all",      EQ, 1,  .list = completion_pm_one },
diff --git a/src/layout.c b/src/layout.c
index 9856638..6f2fec6 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -900,6 +900,50 @@ HSFrame* frame_current_selection() {
     return frame;
 }
 
+int frame_current_bring(int argc, char** argv) {
+    HSClient* client;
+
+    string_to_client((argc > 1) ? argv[1] : "", &client);
+    if (!client) {
+        return HERBST_INVALID_ARGUMENT;
+    }
+
+    HSMonitor* monitor = get_current_monitor();
+    HSFrame* frame = frame_current_selection();
+    if (!frame) {
+        return HERBST_UNKNOWN_ERROR;
+    }
+
+    HSMonitor* monitor_source = NULL;
+    // remove window from old frame
+    if (client->tag && client->tag->frame) {
+        frame_remove_window(client->tag->frame, client->window);
+        // and arrange monitor
+        monitor_source = find_monitor_with_tag(client->tag);
+        if (monitor_source) {
+            monitor_apply_layout(monitor_source);
+        }
+    }
+
+    // insert window to current frame
+    frame_insert_window(frame, client->window);
+    stack_remove_slice(client->tag->stack, client->slice);
+    client->tag = monitor->tag;
+    stack_insert_slice(client->tag->stack, client->slice);
+    ewmh_window_update_tag(client->window, client->tag);
+
+    // and arrange monitor
+    monitor_apply_layout(monitor);
+
+    if (!monitor_source) {
+        window_show(client->window);
+    }
+
+    tag_set_flags_dirty();
+
+    return 0;
+}
+
 int frame_current_set_selection(int argc, char** argv) {
     int index = 0;
     if (argc >= 2) {
diff --git a/src/layout.h b/src/layout.h
index 9685c76..49759e0 100644
--- a/src/layout.h
+++ b/src/layout.h
@@ -126,6 +126,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString** errormsg);
 int find_layout_by_name(char* name);
 int find_align_by_name(char* name);
 
+int frame_current_bring(int argc, char** argv);
 int frame_current_set_selection(int argc, char** argv);
 int frame_current_cycle_selection(int argc, char** argv);
 int cycle_all_command(int argc, char** argv);
diff --git a/src/main.c b/src/main.c
index 8cb3042..968ea44 100644
--- a/src/main.c
+++ b/src/main.c
@@ -95,6 +95,7 @@ CommandBinding g_commands[] = {
     CMD_BIND_NO_OUTPUT(   "spawn",          spawn),
     CMD_BIND_NO_OUTPUT(   "wmexec",         wmexec),
     CMD_BIND_NO_OUTPUT(   "emit_hook",      custom_hook_emit),
+    CMD_BIND_NO_OUTPUT(   "bring",          frame_current_bring),
     CMD_BIND_NO_OUTPUT(   "focus_nth",      frame_current_set_selection),
     CMD_BIND_NO_OUTPUT(   "cycle",          frame_current_cycle_selection),
     CMD_BIND_NO_OUTPUT(   "cycle_all",      cycle_all_command),
-- 
1.7.8.6