So yeah, I implemented monitor names :) As previously mentioned I'll probably correct the small changes you proposed in the error messages patchset soon. If you have more time than me currently, feel free to do it yourself ;) MIGRATION | 9 ++ NEWS | 1 + doc/herbstluftwm.txt | 79 +++++++------ src/command.c | 35 +++++- src/command.h | 1 + src/main.c | 15 ++- src/monitor.c | 275 ++++++++++++++++++++++++++++++++----------- src/monitor.h | 12 +- src/stack.c | 9 +- 9 files changed, 322 insertions(+), 114 deletions(-) Florian Bruhin (10): Add monitor names to add_monitor Add monitor names to stack command Add monitor names to list_monitors Add string_to_monitor/monitor_index functions Make focus_monitor accept output Add monitor names to all commands using monitors Add monitor argument to list_padding Add new command name_monitor Implement completion for monitor names Add monitor names to shift_to_monitor -- () ascii ribbon campaign - stop html mail www.asciiribbon.org /\ www.the-compiler.org | I love long mails http://email.is-not-s.ms/ The more things change, the more they stay insane.
From e969d9eb63406fff7ed147db05dd4d44b3968ac0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Sun, 25 Nov 2012 23:59:00 +0100 Subject: [PATCH 01/10] Add monitor names to add_monitor --- MIGRATION | 5 +++++ NEWS | 1 + doc/herbstluftwm.txt | 11 +++++------ src/monitor.c | 55 +++++++++++++++++++++++++++++++++++++++++++--------- src/monitor.h | 5 ++++- 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/MIGRATION b/MIGRATION index 64974dc..fe742af 100644 --- a/MIGRATION +++ b/MIGRATION @@ -10,6 +10,11 @@ herbstclient now returns the exitstatus 9 (HERBST_NEED_MORE_ARGS) instead of 3 (HERBST_INVALID_ARGUMENT) if a command needs more arguments. If an error occurs, it now outputs an error message to stderr. +The padding arguments have been removed from add_monitor and a monitor name has +been added instead. If you add a monitor with padding, instead of 'hc +add_monitor 1024x768+0+0 1 2 3 4' now use 'hc add_monitor 1024x768+0+0; hc pad N +1 2 3 4'. + 0.3 to 0.4 ~~~~~~~~~~ The setting window_gap is now called frame_gap. Simply replace all occurrences diff --git a/NEWS b/NEWS index 7a69e51..75a5095 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,7 @@ Changes: * add error messages for herbstclient * new command: shift_edge * new command: shift_to_monitor + * optional names for monitors Release: 0.4.1 on 2012-08-30 ---------------------------- diff --git a/doc/herbstluftwm.txt b/doc/herbstluftwm.txt index 54178f6..fd52ae2 100644 --- a/doc/herbstluftwm.txt +++ b/doc/herbstluftwm.txt @@ -503,15 +503,14 @@ detect_monitors:: Xinerama extension is missing, it will fall back to one monitor across the entire screen. -add_monitor 'RECT' ['TAG' ['PADUP' ['PADRIGHT' ['PADDOWN' ['PADLEFT']]]]]:: +add_monitor 'RECT' ['TAG' ['NAME']]:: Adds a monitor on the specified rectangle 'RECT' and displays 'TAG' on it. 'TAG' currently must not be displayed on any other monitor. 'RECT' is a - string of the form 'WxH±X±Y'. The padding specifies extra space around the - monitor for some statusbars/panels. If no or an empty padding is given, it - is set to 0. If no or an empty 'TAG' is given, then any free tag will be - chosen. Example: + string of the form 'WxH±X±Y'. If no or an empty 'TAG' is given, then any + free tag will be chosen. If a 'NAME' is given, you can reference to this + monitor by its name instead of using an index. Example: - * add_monitor 1024x768-20+0 mynewtag 16 + * add_monitor 1024x768-20+0 mynewtag main remove_monitor 'INDEX':: diff --git a/src/monitor.c b/src/monitor.c index a3be74c..a08bb31 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -7,6 +7,7 @@ #include <string.h> #include <stdio.h> #include <stdbool.h> +#include <ctype.h> #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif /* XINERAMA */ @@ -310,7 +311,7 @@ int set_monitor_rects(XRectangle* templates, size_t count) { if (!tag) { return HERBST_TAG_IN_USE; } - add_monitor(templates[i], tag); + add_monitor(templates[i], tag, NULL); frame_show_recursive(tag->frame); } // remove monitors if there are too much @@ -321,11 +322,32 @@ int set_monitor_rects(XRectangle* templates, size_t count) { return 0; } -HSMonitor* add_monitor(XRectangle rect, HSTag* tag) { +int find_monitor_index_by_name(char* name) { + int i; + for (i = 0; i < g_monitors->len; i++) { + HSMonitor* mon = monitor_with_index(i); + if (mon != NULL && mon->name != NULL && !strcmp(mon->name->str, name)) { + return i; + } + } + return -1; +} + +HSMonitor* find_monitor_by_name(char* name) { + int i = find_monitor_index_by_name(name); + if (i == -1) { + return NULL; + } else { + return monitor_with_index(i); + } +} + +HSMonitor* add_monitor(XRectangle rect, HSTag* tag, char* name) { assert(tag != NULL); HSMonitor* m = g_new0(HSMonitor, 1); m->rect = rect; m->tag = tag; + m->name = (name ? g_string_new(name) : NULL); m->mouse.x = 0; m->mouse.y = 0; m->dirty = true; @@ -338,12 +360,13 @@ HSMonitor* add_monitor(XRectangle rect, HSTag* tag) { } int add_monitor_command(int argc, char** argv, GString* output) { - // usage: add_monitor RECTANGLE [TAG [PADUP [PADRIGHT [PADDOWN [PADLEFT]]]]] + // usage: add_monitor RECTANGLE [TAG [NAME]] if (argc < 2) { return HERBST_NEED_MORE_ARGS; } XRectangle rect = parse_rectangle(argv[1]); HSTag* tag = NULL; + char* name = NULL; if (argc == 2 || !strcmp("", argv[2])) { tag = find_unused_tag(); if (!tag) { @@ -365,11 +388,25 @@ int add_monitor_command(int argc, char** argv, GString* output) { "%s: The tag \"%s\" is already viewed on a monitor\n", argv[0], argv[2]); return HERBST_TAG_IN_USE; } - HSMonitor* monitor = add_monitor(rect, tag); - if (argc > 3 && argv[3][0] != '\0') monitor->pad_up = atoi(argv[3]); - if (argc > 4 && argv[4][0] != '\0') monitor->pad_right = atoi(argv[4]); - if (argc > 5 && argv[5][0] != '\0') monitor->pad_down = atoi(argv[5]); - if (argc > 6 && argv[6][0] != '\0') monitor->pad_left = atoi(argv[6]); + if (argc > 3) { + name = argv[3]; + if (isdigit(name[0])) { + g_string_append_printf(output, + "%s: The monitor name may not start with a number\n", argv[0]); + return HERBST_INVALID_ARGUMENT; + } + if (!strcmp("", name)) { + g_string_append_printf(output, + "%s: An empty monitor name is not permitted\n", argv[0]); + return HERBST_INVALID_ARGUMENT; + } + if (find_monitor_by_name(name)) { + g_string_append_printf(output, + "%s: A monitor with the same name already exists\n", argv[0]); + return HERBST_INVALID_ARGUMENT; + } + } + HSMonitor* monitor = add_monitor(rect, tag, name); frame_show_recursive(tag->frame); monitor_apply_layout(monitor); emit_tag_changed(tag, g_monitors->len - 1); @@ -546,7 +583,7 @@ void ensure_monitors_are_available() { }; ensure_tags_are_available(); // add monitor with first tag - HSMonitor* m = add_monitor(rect, g_array_index(g_tags, HSTag*, 0)); + HSMonitor* m = add_monitor(rect, g_array_index(g_tags, HSTag*, 0), NULL); g_cur_monitor = 0; g_cur_frame = m->tag->frame; } diff --git a/src/monitor.h b/src/monitor.h index 1b7d9dd..ca846e1 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -21,6 +21,7 @@ struct HSStack; typedef struct HSMonitor { struct HSTag* tag; // currently viewed tag struct HSSlice* slice; // slice in the monitor stack + GString* name; int pad_up; int pad_right; int pad_down; @@ -48,13 +49,15 @@ HSMonitor* monitor_with_frame(struct HSFrame* frame); HSMonitor* monitor_with_coordinate(int x, int y); HSMonitor* monitor_with_index(int index); HSMonitor* find_monitor_with_tag(struct HSTag* tag); -HSMonitor* add_monitor(XRectangle rect, struct HSTag* tag); +HSMonitor* add_monitor(XRectangle rect, struct HSTag* tag, char* name); void monitor_focus_by_index(int new_selection); int monitor_get_relative_x(HSMonitor* m, int x_root); int monitor_get_relative_y(HSMonitor* m, int y_root); int monitor_index_of(HSMonitor* monitor); int monitor_cycle_command(int argc, char** argv); int monitor_focus_command(int argc, char** argv); +int find_monitor_index_by_name(char* name); +HSMonitor* find_monitor_by_name(char* name); int add_monitor_command(int argc, char** argv, GString* output); int monitor_raise_command(int argc, char** argv, GString* output); int remove_monitor_command(int argc, char** argv, GString* output); -- 1.8.0.1
From c98302263ed022980fb49889c29b3f6794d722ad Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Mon, 26 Nov 2012 00:27:30 +0100 Subject: [PATCH 02/10] Add monitor names to stack command --- src/stack.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/stack.c b/src/stack.c index 5915e89..5ca8e61 100644 --- a/src/stack.c +++ b/src/stack.c @@ -108,6 +108,7 @@ void stack_remove_slice(HSStack* s, HSSlice* elem) { static void slice_append_caption(HSTree root, GString* output) { HSSlice* slice = (HSSlice*)root; + GString* monitor_name = g_string_new(""); switch (slice->type) { case SLICE_WINDOW: g_string_append_printf(output, "Window 0x%lx", @@ -119,11 +120,17 @@ static void slice_append_caption(HSTree root, GString* output) { slice->data.client->title->str); break; case SLICE_MONITOR: - g_string_append_printf(output, "Monitor %d with tag \"%s\"", + if (slice->data.monitor->name != NULL) { + g_string_append_printf(monitor_name, " (\"%s\")", + slice->data.monitor->name->str); + } + g_string_append_printf(output, "Monitor %d%s with tag \"%s\"", monitor_index_of(slice->data.monitor), + monitor_name->str, slice->data.monitor->tag->name->str); break; } + g_string_free(monitor_name, true); } static struct HSTreeInterface slice_nth_child(HSTree root, size_t idx) { -- 1.8.0.1
From 80970c28664d34e3a8206393e695e17b0c33ff91 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Mon, 26 Nov 2012 07:12:42 +0100 Subject: [PATCH 03/10] Add monitor names to list_monitors --- MIGRATION | 3 +++ doc/herbstluftwm.txt | 4 ++-- src/monitor.c | 11 ++++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/MIGRATION b/MIGRATION index fe742af..c7e3e22 100644 --- a/MIGRATION +++ b/MIGRATION @@ -15,6 +15,9 @@ been added instead. If you add a monitor with padding, instead of 'hc add_monitor 1024x768+0+0 1 2 3 4' now use 'hc add_monitor 1024x768+0+0; hc pad N 1 2 3 4'. +As a result from adding monitor names, the output of list_monitors and stack +changes a bit for named monitors. + 0.3 to 0.4 ~~~~~~~~~~ The setting window_gap is now called frame_gap. Simply replace all occurrences diff --git a/doc/herbstluftwm.txt b/doc/herbstluftwm.txt index fd52ae2..6183619 100644 --- a/doc/herbstluftwm.txt +++ b/doc/herbstluftwm.txt @@ -140,8 +140,8 @@ list_commands:: Lists all available commands. [[list_monitors]]list_monitors:: - List currently configured monitors with their index, area (as rectangle) and - currently viewed tag. + List currently configured monitors with their index, area (as rectangle), + name (if named) and currently viewed tag. list_keybinds:: Lists all bound keys with their associated command. Each line consists of diff --git a/src/monitor.c b/src/monitor.c index a08bb31..be08055 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -104,16 +104,25 @@ int list_monitors(int argc, char** argv, GString* output) { (void)argc; (void)argv; int i; + GString* monitor_name = g_string_new(""); for (i = 0; i < g_monitors->len; i++) { HSMonitor* monitor = monitor_with_index(i); - g_string_append_printf(output, "%d: %dx%d%+d%+d with tag \"%s\"%s%s\n", + if (monitor->name != NULL ) { + g_string_printf(monitor_name, ", named \"%s\"", + monitor->name->str); + } else { + g_string_truncate(monitor_name, 0); + } + g_string_append_printf(output, "%d: %dx%d%+d%+d with tag \"%s\"%s%s%s\n", i, monitor->rect.width, monitor->rect.height, monitor->rect.x, monitor->rect.y, monitor->tag ? monitor->tag->name->str : "???", + monitor_name->str, (g_cur_monitor == i) ? " [FOCUS]" : "", monitor->lock_tag ? " [LOCKED]" : ""); } + g_string_free(monitor_name, true); return 0; } -- 1.8.0.1
From 14ef2b4b0969d8390591de2000a5ef9fa610f718 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Tue, 27 Nov 2012 22:17:07 +0100 Subject: [PATCH 04/10] Add string_to_monitor/monitor_index functions --- src/monitor.c | 35 +++++++++++++++++++++++++++++++++++ src/monitor.h | 2 ++ 2 files changed, 37 insertions(+) diff --git a/src/monitor.c b/src/monitor.c index be08055..41ecd95 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -351,6 +351,41 @@ HSMonitor* find_monitor_by_name(char* name) { } } +int string_to_monitor_index(char* string) { + int idx = -1; + if (string[0] == '\0') { + return -1; + } + if (isdigit(string[0])) { + // monitor index + idx = atoi(string); + if (idx < 0 || idx >= g_monitors->len) { + return -1; + } + return idx; + } else { + // monitor string + return find_monitor_index_by_name(string); + } +} + +HSMonitor* string_to_monitor(char* string) { + if (string[0] == '\0') { + return NULL; + } + if (isdigit(string[0])) { + // monitor index + int idx = atoi(string); + if (idx < 0 || idx >= g_monitors->len) { + return NULL; + } + return monitor_with_index(idx); + } else { + // monitor string + return find_monitor_by_name(string); + } +} + HSMonitor* add_monitor(XRectangle rect, HSTag* tag, char* name) { assert(tag != NULL); HSMonitor* m = g_new0(HSMonitor, 1); diff --git a/src/monitor.h b/src/monitor.h index ca846e1..7265139 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -58,6 +58,8 @@ int monitor_cycle_command(int argc, char** argv); int monitor_focus_command(int argc, char** argv); int find_monitor_index_by_name(char* name); HSMonitor* find_monitor_by_name(char* name); +HSMonitor* string_to_monitor(char* string); +int string_to_monitor_index(char* string); int add_monitor_command(int argc, char** argv, GString* output); int monitor_raise_command(int argc, char** argv, GString* output); int remove_monitor_command(int argc, char** argv, GString* output); -- 1.8.0.1
From 07be0f5c9ff73ac7557d02699221e6f23f43dc92 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Wed, 28 Nov 2012 23:19:12 +0100 Subject: [PATCH 05/10] Make focus_monitor accept output --- src/main.c | 2 +- src/monitor.c | 2 +- src/monitor.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index f375da9..d095227 100644 --- a/src/main.c +++ b/src/main.c @@ -118,7 +118,7 @@ CommandBinding g_commands[] = { CMD_BIND( "toggle", settings_toggle), CMD_BIND( "cycle_value", settings_cycle_value), CMD_BIND_NO_OUTPUT( "cycle_monitor", monitor_cycle_command), - CMD_BIND_NO_OUTPUT( "focus_monitor", monitor_focus_command), + CMD_BIND( "focus_monitor", monitor_focus_command), CMD_BIND( "get", settings_get), CMD_BIND( "add", tag_add_command), CMD_BIND( "use", monitor_set_tag_command), diff --git a/src/monitor.c b/src/monitor.c index 41ecd95..d901d45 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -769,7 +769,7 @@ int monitor_set_tag_by_index_command(int argc, char** argv, GString* output) { return ret; } -int monitor_focus_command(int argc, char** argv) { +int monitor_focus_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } diff --git a/src/monitor.h b/src/monitor.h index 7265139..bd4e6c5 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -55,7 +55,7 @@ int monitor_get_relative_x(HSMonitor* m, int x_root); int monitor_get_relative_y(HSMonitor* m, int y_root); int monitor_index_of(HSMonitor* monitor); int monitor_cycle_command(int argc, char** argv); -int monitor_focus_command(int argc, char** argv); +int monitor_focus_command(int argc, char** argv, GString* output); int find_monitor_index_by_name(char* name); HSMonitor* find_monitor_by_name(char* name); HSMonitor* string_to_monitor(char* string); -- 1.8.0.1
From d10d2a7eb1a97081fbcb2655737af2a14158c26d Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Tue, 27 Nov 2012 23:06:58 +0100 Subject: [PATCH 06/10] Add monitor names to all commands using monitors --- doc/herbstluftwm.txt | 55 ++++++++++++++++-------------- src/main.c | 12 +++++-- src/monitor.c | 94 ++++++++++++++++++++++++++++------------------------ 3 files changed, 90 insertions(+), 71 deletions(-) diff --git a/doc/herbstluftwm.txt b/doc/herbstluftwm.txt index 6183619..7b64dff 100644 --- a/doc/herbstluftwm.txt +++ b/doc/herbstluftwm.txt @@ -117,8 +117,18 @@ Tags are very similar to workspaces, virtual desktops or window groups. Each tag has one layout. There is a list of tags. You can add or remove tags dynamically. -There is also a list of monitors. Each monitor displays exactly one tag on a -specified rectangle on the screen. +[[MONITORS]] +MONITORS +-------- +Monitors in *herbstluftwm* are totally independent of the actual physical +screens. This means you can for example split your screen in two virtual +monitors to view two tags at once on a big screen. + +Each monitor displays exactly one tag on a specified rectangle on the screen. + +A monitor can be referenced in two ways: by its 'INDEX' as listed in the +*list_monitors* command, or by a name defined when adding the monitor. + [[COMMANDS]] COMMANDS @@ -413,9 +423,8 @@ cycle_value 'NAME' 'VALUES' ...:: cycle_monitor ['DELTA']:: Cycles monitor focused by 'DELTA'. 'DELTA' defaults to 1. -focus_monitor 'INDEX':: - Puts focus to monitor with specified 'INDEX' (as specified by the - list_monitors command) +focus_monitor 'MONITOR':: + Puts focus to specified monitor. add 'TAG':: Creates a new empty tag named 'TAG'. @@ -448,8 +457,8 @@ move_index 'INDEX' [*--skip-visible*]:: treated relative. If *--skip-visible* is passed with a relative index, then already visible tags are skipped. -lock_tag ['INDEX']:: - Lock the tag switching on the monitor specified by INDEX. If no +lock_tag ['MONITOR']:: + Lock the tag switching on the specified monitor. If no argument is given, the currently focused monitor is used. When the tag switching is disabled for a monitor, the commands *use* and *use_index* have no effect, when executed there. When @@ -458,8 +467,8 @@ lock_tag ['INDEX']:: stealing it from there. The lock state of a monitor is indicated by "[LOCKED]" in the *list_monitors* output. -unlock_tag ['INDEX']:: - Re-enables the tag switching on the monitor specified by INDEX. If no +unlock_tag ['MONITOR']:: + Re-enables the tag switching on the specified monitor. If no argument is given, the currently focused monitor is used. This is the reverse operation to *lock_tag* and has no further side effects but removing this lock. @@ -513,17 +522,15 @@ add_monitor 'RECT' ['TAG' ['NAME']]:: * add_monitor 1024x768-20+0 mynewtag main -remove_monitor 'INDEX':: - Removes the monitor with specified 'INDEX'. Its 'INDEX' can be found out via - the <<list_monitors,'list_monitors'>> command. +remove_monitor 'MONITOR':: + Removes the specified monitor. -move_monitor 'INDEX' 'RECT' ['PADUP' ['PADRIGHT' ['PADDOWN' ['PADLEFT']]]]:: - Moves the monitor with specified 'INDEX' to rectangle 'RECT'. 'INDEX' and - 'RECT' are defined as in 'remove_monitor' and 'add_monitor'. If no or an - empty pad is given, it is not changed. +move_monitor 'MONITOR' 'RECT' ['PADUP' ['PADRIGHT' ['PADDOWN' ['PADLEFT']]]]:: + Moves the specified monitor to rectangle 'RECT'. 'RECT' is defined as in + 'add_monitor'. If no or an empty pad is given, it is not changed. -raise_monitor ['INDEX']:: - Raises the monitor with the given 'INDEX' or the current one if 'INDEX' is +raise_monitor ['MONITOR']:: + Raises the specified monitor or the current one if 'MONITOR' is omitted. stack:: @@ -531,15 +538,15 @@ stack:: tree. The order printed stack is top to bottom. The style is configured by the 'tree_style' setting. -monitor_rect [[-p] 'INDEX']:: - Prints the rectangle of the specified 'INDEX' in the format: *X Y W H* + - If no 'INDEX' or 'cur' is given, then the current Monitor is used. If '-p' +monitor_rect [[-p] 'MONITOR']:: + Prints the rectangle of the specified monitor in the format: *X Y W H* + + If no 'MONITOR' or 'cur' is given, then the current Monitor is used. If '-p' is supplied, then the remaining rect without the pad around this monitor is printed. -pad 'INDEX' ['PADUP' ['PADRIGHT' ['PADDOWN' ['PADLEFT']]]]:: - Sets the pad of indexed monitor to the specified padding. If no or an empty - padding is given, it is not changed. +pad 'MONITOR' ['PADUP' ['PADRIGHT' ['PADDOWN' ['PADLEFT']]]]:: + Sets the pad of specified monitor to the specified padding. If no or an + empty padding is given, it is not changed. list_padding:: Lists the padding of all monitors. diff --git a/src/main.c b/src/main.c index d095227..12501a3 100644 --- a/src/main.c +++ b/src/main.c @@ -261,13 +261,19 @@ int load_command(int argc, char** argv, GString* output) { } int print_tag_status_command(int argc, char** argv, GString* output) { + HSMonitor* monitor; int monitor_index = g_cur_monitor; if (argc >= 2) { - monitor_index = atoi(argv[1]); + monitor = string_to_monitor(argv[1]); + } else { + monitor = monitor_with_index(g_cur_monitor); + } + if (monitor == NULL) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; } - monitor_index = CLAMP(monitor_index, 0, monitor_count() - 1); tag_update_flags(); - HSMonitor* monitor = monitor_with_index(monitor_index); g_string_append_c(output, '\t'); for (int i = 0; i < g_tags->len; i++) { HSTag* tag = g_array_index(g_tags, HSTag*, i); diff --git a/src/monitor.c b/src/monitor.c index d901d45..3d4db11 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -462,7 +462,12 @@ int remove_monitor_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } - int index = atoi(argv[1]); + int index = string_to_monitor_index(argv[1]); + if (index == -1) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; + } int ret = remove_monitor(index); if (ret == HERBST_INVALID_ARGUMENT) { g_string_append_printf(output, @@ -512,10 +517,10 @@ int move_monitor_command(int argc, char** argv, GString* output) { if (argc < 3) { return HERBST_NEED_MORE_ARGS; } - int index = atoi(argv[1]); - if (index < 0 || index >= g_monitors->len) { + HSMonitor* monitor = string_to_monitor(argv[1]); + if (monitor == NULL) { g_string_append_printf(output, - "%s: Index %i is out of range\n", argv[0], index); + "%s: Monitor \"%s\" not found!\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } XRectangle rect = parse_rectangle(argv[2]); @@ -525,7 +530,6 @@ int move_monitor_command(int argc, char** argv, GString* output) { return HERBST_INVALID_ARGUMENT; } // else: just move it: - HSMonitor* monitor = monitor_with_index(index); monitor->rect = rect; if (argc > 3 && argv[3][0] != '\0') monitor->pad_up = atoi(argv[3]); if (argc > 4 && argv[4][0] != '\0') monitor->pad_right = atoi(argv[4]); @@ -537,17 +541,17 @@ int move_monitor_command(int argc, char** argv, GString* output) { int monitor_rect_command(int argc, char** argv, GString* output) { // usage: monitor_rect [[-p] INDEX] - char* index_str = NULL; + char* monitor_str = NULL; HSMonitor* m = NULL; bool with_pad = false; - // if index is supplied + // if monitor is supplied if (argc > 1) { - index_str = argv[1]; + monitor_str = argv[1]; } // if -p is supplied if (argc > 2) { - index_str = argv[2]; + monitor_str = argv[2]; if (!strcmp("-p", argv[1])) { with_pad = true; } else { @@ -557,19 +561,14 @@ int monitor_rect_command(int argc, char** argv, GString* output) { } } // if an index is set - if (index_str) { - int index; - if (1 == sscanf(index_str, "%d", &index)) { - m = monitor_with_index(index); - if (!m) { - g_string_append_printf(output, - "%s: Invalid index \"%s\"\n", argv[0], index_str); - return HERBST_INVALID_ARGUMENT; - } + if (monitor_str) { + m = string_to_monitor(monitor_str); + if (m == NULL) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", argv[0], monitor_str); + return HERBST_INVALID_ARGUMENT; } - } - - if (!m) { + } else { m = get_current_monitor(); } XRectangle rect = m->rect; @@ -588,13 +587,12 @@ int monitor_set_pad_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } - int index = atoi(argv[1]); - if (index < 0 || index >= g_monitors->len) { + HSMonitor* monitor = string_to_monitor(argv[1]); + if (monitor == NULL) { g_string_append_printf(output, - "%s: Index %i is out of range\n", argv[0], index); + "%s: Monitor \"%s\" not found!\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } - HSMonitor* monitor = monitor_with_index(index); if (argc > 2 && argv[2][0] != '\0') monitor->pad_up = atoi(argv[2]); if (argc > 3 && argv[3][0] != '\0') monitor->pad_right = atoi(argv[3]); if (argc > 4 && argv[4][0] != '\0') monitor->pad_down = atoi(argv[4]); @@ -773,7 +771,12 @@ int monitor_focus_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } - int new_selection = atoi(argv[1]); + int new_selection = string_to_monitor_index(argv[1]); + if (new_selection == -1) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; + } // really change selection monitor_focus_by_index(new_selection); return 0; @@ -934,35 +937,37 @@ void monitors_lock_changed() { } int monitor_lock_tag_command(int argc, char** argv, GString* output) { + char* cmd_name = argv[0]; (void)SHIFT(argc, argv); HSMonitor *monitor; if (argc >= 1) { - monitor = monitor_with_index(atoi(argv[0])); + monitor = string_to_monitor(argv[0]); + if (monitor == NULL) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", cmd_name, argv[0]); + return HERBST_INVALID_ARGUMENT; + } } else { monitor = get_current_monitor(); } - if (!monitor) { - g_string_append_printf(output, - "%s: Invalid monitor\n", argv[0]); - return HERBST_INVALID_ARGUMENT; - } monitor->lock_tag = true; return 0; } int monitor_unlock_tag_command(int argc, char** argv, GString* output) { + char* cmd_name = argv[0]; (void)SHIFT(argc, argv); HSMonitor *monitor; if (argc >= 1) { - monitor = monitor_with_index(atoi(argv[0])); + monitor = string_to_monitor(argv[0]); + if (monitor == NULL) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", cmd_name, argv[0]); + return HERBST_INVALID_ARGUMENT; + } } else { monitor = get_current_monitor(); } - if (!monitor) { - g_string_append_printf(output, - "%s: Invalid monitor\n", argv[0]); - return HERBST_INVALID_ARGUMENT; - } monitor->lock_tag = false; return 0; } @@ -1070,18 +1075,19 @@ HSStack* get_monitor_stack() { } int monitor_raise_command(int argc, char** argv, GString* output) { + char* cmd_name = argv[0]; (void)SHIFT(argc, argv); HSMonitor* monitor; if (argc >= 1) { - monitor = monitor_with_index(atoi(argv[0])); + monitor = string_to_monitor(argv[0]); + if (monitor == NULL) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", cmd_name, argv[0]); + return HERBST_INVALID_ARGUMENT; + } } else { monitor = get_current_monitor(); } - if (!monitor) { - g_string_append_printf(output, - "%s: Invalid monitor\n", argv[0]); - return HERBST_INVALID_ARGUMENT; - } stack_raise_slide(g_monitor_stack, monitor->slice); return 0; } -- 1.8.0.1
From 158dc4a135e43cc85a47f66b847b8cbe14938c70 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Tue, 27 Nov 2012 23:18:04 +0100 Subject: [PATCH 07/10] Add monitor argument to list_padding --- MIGRATION | 3 ++- doc/herbstluftwm.txt | 5 +++-- src/command.c | 2 +- src/monitor.c | 26 +++++++++++++++----------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/MIGRATION b/MIGRATION index c7e3e22..17b4ecc 100644 --- a/MIGRATION +++ b/MIGRATION @@ -16,7 +16,8 @@ add_monitor 1024x768+0+0 1 2 3 4' now use 'hc add_monitor 1024x768+0+0; hc pad N 1 2 3 4'. As a result from adding monitor names, the output of list_monitors and stack -changes a bit for named monitors. +changes a bit for named monitors. list_padding only outputs the padding for one +monitor now. 0.3 to 0.4 ~~~~~~~~~~ diff --git a/doc/herbstluftwm.txt b/doc/herbstluftwm.txt index 7b64dff..01890ce 100644 --- a/doc/herbstluftwm.txt +++ b/doc/herbstluftwm.txt @@ -548,8 +548,9 @@ pad 'MONITOR' ['PADUP' ['PADRIGHT' ['PADDOWN' ['PADLEFT']]]]:: Sets the pad of specified monitor to the specified padding. If no or an empty padding is given, it is not changed. -list_padding:: - Lists the padding of all monitors. +list_padding ['MONITOR']:: + Lists the padding of the specified monitor, or the currently focused monitor + if no monitor is given. layout ['TAG' ['INDEX']]:: Prints the layout of frame with 'INDEX' in 'TAG', in a nice tree style. diff --git a/src/command.c b/src/command.c index 5214ad8..e57500b 100644 --- a/src/command.c +++ b/src/command.c @@ -104,7 +104,7 @@ struct { { "stack", 2, no_completion }, { "monitor_rect", 3, no_completion }, { "pad", 6, no_completion }, - { "list_padding", 1, no_completion }, + { "list_padding", 2, no_completion }, { "layout", 3, no_completion }, { "dump", 3, no_completion }, { "load", 3, no_completion }, diff --git a/src/monitor.c b/src/monitor.c index 3d4db11..e31276f 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -127,18 +127,22 @@ int list_monitors(int argc, char** argv, GString* output) { } int list_padding(int argc, char** argv, GString* output) { - (void)argc; - (void)argv; - int i; - for (i = 0; i < g_monitors->len; i++) { - HSMonitor* monitor = monitor_with_index(i); - g_string_append_printf(output, "%d: %d %d %d %d\n", - i, - monitor->pad_up, - monitor->pad_right, - monitor->pad_down, - monitor->pad_left); + HSMonitor* monitor; + if (argc < 2) { + monitor = get_current_monitor(); + } else { + monitor = string_to_monitor(argv[1]); + if (monitor == NULL) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; + } } + g_string_append_printf(output, "%d %d %d %d\n", + monitor->pad_up, + monitor->pad_right, + monitor->pad_down, + monitor->pad_left); return 0; } -- 1.8.0.1
From 78534587fa81f227bb73b861a1305eeef883502e Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Wed, 28 Nov 2012 00:11:32 +0100 Subject: [PATCH 08/10] Add new command name_monitor --- NEWS | 2 +- doc/herbstluftwm.txt | 4 ++++ src/command.c | 1 + src/main.c | 1 + src/monitor.c | 38 ++++++++++++++++++++++++++++++++++++++ src/monitor.h | 1 + 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 75a5095..2ee6c5e 100644 --- a/NEWS +++ b/NEWS @@ -27,7 +27,7 @@ Changes: * add error messages for herbstclient * new command: shift_edge * new command: shift_to_monitor - * optional names for monitors + * optional names for monitors, new command name_monitor Release: 0.4.1 on 2012-08-30 ---------------------------- diff --git a/doc/herbstluftwm.txt b/doc/herbstluftwm.txt index 01890ce..c6ffc6e 100644 --- a/doc/herbstluftwm.txt +++ b/doc/herbstluftwm.txt @@ -533,6 +533,10 @@ raise_monitor ['MONITOR']:: Raises the specified monitor or the current one if 'MONITOR' is omitted. +name_monitor 'MONITOR' 'NAME':: + (Re)names an already existing monitor. If 'NAME' is empty, removes the + monitor's name. + stack:: Prints the stack of monitors with the visible tags and their layers as a tree. The order printed stack is top to bottom. The style is configured by diff --git a/src/command.c b/src/command.c index e57500b..71c1b00 100644 --- a/src/command.c +++ b/src/command.c @@ -98,6 +98,7 @@ struct { { "unlock_tag", 2, no_completion }, { "detect_monitors",1, no_completion }, { "add_monitor", 7, no_completion }, + { "name_monitor", 3, no_completion }, { "remove_monitor", 2, no_completion }, { "move_monitor", 7, no_completion }, { "raise_monitor", 2, no_completion }, diff --git a/src/main.c b/src/main.c index 12501a3..3d11c90 100644 --- a/src/main.c +++ b/src/main.c @@ -137,6 +137,7 @@ CommandBinding g_commands[] = { CMD_BIND( "raise_monitor", monitor_raise_command), CMD_BIND( "remove_monitor", remove_monitor_command), CMD_BIND( "move_monitor", move_monitor_command), + CMD_BIND( "name_monitor", name_monitor_command), CMD_BIND( "monitor_rect", monitor_rect_command), CMD_BIND( "pad", monitor_set_pad_command), CMD_BIND( "raise", raise_command), diff --git a/src/monitor.c b/src/monitor.c index e31276f..9a8bcf3 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -543,6 +543,44 @@ int move_monitor_command(int argc, char** argv, GString* output) { return 0; } +int name_monitor_command(int argc, char** argv, GString* output) { + if (argc < 3) { + return HERBST_NEED_MORE_ARGS; + } + HSMonitor* mon = string_to_monitor(argv[1]); + if (mon == NULL) { + g_string_append_printf(output, + "%s: Monitor \"%s\" not found!\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; + } + if (isdigit(argv[2][0])) { + g_string_append_printf(output, + "%s: The monitor name may not start with a number\n", argv[0]); + return HERBST_INVALID_ARGUMENT; + } else if (!strcmp("", argv[2])) { + // empty name -> clear name + if (mon->name != NULL) { + g_string_free(mon->name, true); + mon->name = NULL; + } + return 0; + } + if (find_monitor_by_name(argv[2])) { + g_string_append_printf(output, + "%s: A monitor with the same name already exists\n", argv[0]); + return HERBST_INVALID_ARGUMENT; + } + if (mon->name == NULL) { + // not named before + GString* name = g_string_new(argv[2]); + mon->name = name; + } else { + // already named + g_string_assign(mon->name, argv[2]); + } + return 0; +} + int monitor_rect_command(int argc, char** argv, GString* output) { // usage: monitor_rect [[-p] INDEX] char* monitor_str = NULL; diff --git a/src/monitor.h b/src/monitor.h index bd4e6c5..4fd6836 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -70,6 +70,7 @@ int set_monitor_rects_command(int argc, char** argv, GString* output); int disjoin_rects_command(int argc, char** argv, GString* output); int set_monitor_rects(XRectangle* templates, size_t count); int move_monitor_command(int argc, char** argv, GString* output); +int name_monitor_command(int argc, char** argv, GString* output); int monitor_rect_command(int argc, char** argv, GString* output); HSMonitor* get_current_monitor(); int monitor_count(); -- 1.8.0.1
From ccee8d40e930ade8cb0945a8b840b00b8df711d6 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Wed, 28 Nov 2012 00:24:40 +0100 Subject: [PATCH 09/10] Implement completion for monitor names --- src/command.c | 32 ++++++++++++++++++++++++++++++++ src/command.h | 1 + src/monitor.c | 1 - src/monitor.h | 2 ++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index 71c1b00..a4cb743 100644 --- a/src/command.c +++ b/src/command.c @@ -10,6 +10,7 @@ #include "layout.h" #include "key.h" #include "clientlist.h" +#include "monitor.h" #include <glib.h> #include <string.h> @@ -102,6 +103,7 @@ struct { { "remove_monitor", 2, no_completion }, { "move_monitor", 7, no_completion }, { "raise_monitor", 2, no_completion }, + { "name_monitor", 3, no_completion }, { "stack", 2, no_completion }, { "monitor_rect", 3, no_completion }, { "pad", 6, no_completion }, @@ -197,6 +199,17 @@ struct { { "use", EQ, 1, .function = complete_against_tags }, { "use_index", EQ, 1, .list = completion_pm_one }, { "use_index", EQ, 2, .list = completion_use_index_args }, + { "focus_monitor", EQ, 1, .function = complete_against_monitors }, + { "lock_tag", EQ, 1, .function = complete_against_monitors }, + { "unlock_tag", EQ, 1, .function = complete_against_monitors }, + { "remove_monitor", EQ, 1, .function = complete_against_monitors }, + { "move_monitor", EQ, 1, .function = complete_against_monitors }, + { "raise_monitor", EQ, 1, .function = complete_against_monitors }, + { "name_monitor", EQ, 1, .function = complete_against_monitors }, + { "monitor_rect", EQ, 1, .function = complete_against_monitors }, + { "pad", EQ, 1, .function = complete_against_monitors }, + { "list_padding", EQ, 1, .function = complete_against_monitors }, + { "tag_status", EQ, 1, .function = complete_against_monitors }, { 0 }, }; @@ -286,6 +299,25 @@ void complete_negate(int argc, char** argv, int pos, GString* output) { complete_against_commands(argc, argv, pos, output); } +void complete_against_monitors(int argc, char** argv, int pos, GString* output) { + char* needle; + if (pos >= argc) { + needle = ""; + } else { + needle = argv[pos]; + } + size_t len = strlen(needle); + for (int i = 0; i < g_monitors->len; i++) { + GString* name = g_array_index(g_monitors, HSMonitor*, i)->name; + if (name != NULL) { + if (!strncmp(needle, name->str, len)) { + g_string_append(output, name->str); + g_string_append(output, "\n"); + } + } + } +} + struct wcd { /* window id completion data */ char* needle; size_t needlelen; diff --git a/src/command.h b/src/command.h index a4e329e..759c1ff 100644 --- a/src/command.h +++ b/src/command.h @@ -43,6 +43,7 @@ int complete_command(int argc, char** argv, GString* output); void complete_settings(char* str, GString* output); void complete_against_list(char* needle, char** list, GString* output); void complete_against_tags(int argc, char** argv, int pos, GString* output); +void complete_against_monitors(int argc, char** argv, int pos, GString* output); void complete_against_winids(int argc, char** argv, int pos, GString* output); void complete_merge_tag(int argc, char** argv, int pos, GString* output); void complete_negate(int argc, char** argv, int pos, GString* output); diff --git a/src/monitor.c b/src/monitor.c index 9a8bcf3..73ad0c9 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -30,7 +30,6 @@ int* g_swap_monitors_to_get_tag; int* g_smart_frame_surroundings; int* g_mouse_recenter_gap; HSStack* g_monitor_stack; -GArray* g_monitors; // Array of HSMonitor* typedef struct RectList { XRectangle rect; diff --git a/src/monitor.h b/src/monitor.h index 4fd6836..ba9235d 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -18,6 +18,8 @@ struct HSFrame; struct HSSlice; struct HSStack; +GArray* g_monitors; // Array of HSMonitor* + typedef struct HSMonitor { struct HSTag* tag; // currently viewed tag struct HSSlice* slice; // slice in the monitor stack -- 1.8.0.1
From 2dc8296d0d7960a57948084fc47a67bdf2db7fb7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Sun, 9 Dec 2012 23:56:08 +0100 Subject: [PATCH 10/10] Add monitor names to shift_to_monitor --- src/monitor.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/monitor.c b/src/monitor.c index 73ad0c9..ef2e848 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -1156,17 +1156,20 @@ int shift_to_monitor(int argc, char** argv, GString* output) { if (argc <= 1) { return HERBST_NEED_MORE_ARGS; } - char* index_str = argv[1]; - bool is_relative = array_find("+-", 2, sizeof(char), &index_str[0]) >= 0; - int i = atoi(index_str); + HSMonitor* monitor = NULL; + char* monitor_str = argv[1]; + bool is_relative = array_find("+-", 2, sizeof(char), &monitor_str[0]) >= 0; if (is_relative) { + int i = atoi(monitor_str); i += g_cur_monitor; i = MOD(i, g_monitors->len); + monitor = monitor_with_index(i); + } else { + monitor = string_to_monitor(monitor_str); } - HSMonitor* monitor = monitor_with_index(i); if (!monitor) { g_string_append_printf(output, - "%s: Invalid monitor\n", index_str); + "%s: Invalid monitor\n", monitor_str); return HERBST_INVALID_ARGUMENT; } tag_move_focused_client(monitor->tag); -- 1.8.0.1
Attachment:
pgp1UIJ0YK71V.pgp
Description: PGP signature