* Florian Bruhin <me _at_ the _minus_ compiler _dot_ org> [2012-11-18 00:53:01 +0100]: > Phew. I thought it wouldn't be much work to add error messages to > herbstluftwm, turns out it was: ARGH not again. I really should learn how to use git-send-email. -- () ascii ribbon campaign - stop html mail www.asciiribbon.org /\ www.the-compiler.org | I love long mails http://email.is-not-s.ms/ "Paul Lynde to block..." -- a contestant on "Hollywood Squares"
From 45b6163f4e47b3d605e976029022c08b45cb8df4 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 15:53:30 +0100 Subject: [PATCH 01/25] Use HERBST_NEED_MORE_ARGS if a cmd needs more args Now a command returns HERBST_NEED_MORE_ARGS in the specific case when it needs more arguments, instead of HERBST_INVALID_ARGUMENT. This allows ipc-client to output an error message in this case. --- ipc-client/main.c | 10 +++++++++- src/command.c | 4 ++-- src/ipc-protocol.h | 1 + src/key.c | 6 ++---- src/layout.c | 13 ++++++------- src/main.c | 11 +++++------ src/monitor.c | 20 +++++++++----------- src/mouse.c | 2 +- src/rules.c | 2 +- src/settings.c | 8 ++++---- src/tag.c | 10 +++++----- 11 files changed, 45 insertions(+), 42 deletions(-) diff --git a/ipc-client/main.c b/ipc-client/main.c index 14567ab..3f57db7 100644 --- a/ipc-client/main.c +++ b/ipc-client/main.c @@ -14,6 +14,7 @@ #include "ipc-client.h" #include "../src/globals.h" #include "../src/utils.h" +#include "../src/ipc-protocol.h" void print_help(char* command); void init_hook_regex(int argc, char* argv[]); @@ -197,7 +198,14 @@ int main(int argc, char* argv[]) { fprintf(stderr, "Error: Could not send command.\n"); return EXIT_FAILURE; } - fputs(output->str, stdout); + if (command_status == 0) { // success, output to stdout + fputs(output->str, stdout); + } else if (command_status == HERBST_NEED_MORE_ARGS) { // needs more arguments + fputs(output->str, stderr); + fprintf(stderr, "%s: not enough arguments\n", argv[arg_index]); // first argument == cmd + } else { // other error, output to stderr + fputs(output->str, stderr); + } if (g_ensure_newline) { if (output->len > 0 && output->str[output->len - 1] != '\n') { fputs("\n", stdout); diff --git a/src/command.c b/src/command.c index badd487..fac10f5 100644 --- a/src/command.c +++ b/src/command.c @@ -372,7 +372,7 @@ bool parameter_expected(int argc, char** argv, int pos) { int complete_command(int argc, char** argv, GString* output) { // usage: complete POSITION command to complete ... if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } // index must be between first and last arg of "command to complete ..." int position = CLAMP(atoi(argv[1]), 0, argc-2); @@ -566,7 +566,7 @@ int command_chain_command(int argc, char** argv, GString* output) { cmd = STATIC_TABLE_FIND_STR(Cmd2Condition, g_cmd2condition, cmd, argv[0]); (void)SHIFT(argc, argv); if (argc <= 1) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } char* separator = argv[0]; (void)SHIFT(argc, argv); diff --git a/src/ipc-protocol.h b/src/ipc-protocol.h index 8038597..be599bd 100644 --- a/src/ipc-protocol.h +++ b/src/ipc-protocol.h @@ -30,6 +30,7 @@ enum { HERBST_FORBIDDEN, HERBST_NO_PARAMETER_EXPECTED, HERBST_ENV_UNSET, + HERBST_NEED_MORE_ARGS, }; #endif diff --git a/src/key.c b/src/key.c index 85b030a..55e8a67 100644 --- a/src/key.c +++ b/src/key.c @@ -94,8 +94,7 @@ char* modifiermask2name(unsigned int mask) { int keybind(int argc, char** argv) { if (argc <= 2) { - fprintf(stderr, "keybind: not enough arguments\n"); - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } KeyBinding new_bind; // get keycode @@ -188,8 +187,7 @@ void handle_key_press(XEvent* ev) { int keyunbind(int argc, char** argv) { if (argc <= 1) { - fprintf(stderr, "keybind: not enough arguments\n"); - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } // remove all keybinds if wanted if (!strcmp(argv[1], "-F") || !strcmp(argv[1], "--all")) { diff --git a/src/layout.c b/src/layout.c index 4266637..c476a41 100644 --- a/src/layout.c +++ b/src/layout.c @@ -634,8 +634,7 @@ int frame_current_cycle_client_layout(int argc, char** argv) { int frame_current_set_client_layout(int argc, char** argv) { int layout = 0; if (argc <= 1) { - fprintf(stderr, "set_layout: not enough arguments\n"); - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } layout = find_layout_by_name(argv[1]); if (layout < 0) { @@ -903,7 +902,7 @@ int frame_current_set_selection(int argc, char** argv) { if (argc >= 2) { index = atoi(argv[1]); } else { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } // find current selection HSFrame* frame = frame_current_selection(); @@ -1145,7 +1144,7 @@ void frame_split(HSFrame* frame, int align, int fraction) { int frame_split_command(int argc, char** argv) { // usage: split h|v FRACTION if (argc < 3) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } int align = ALIGN_VERTICAL; if (argv[1][0] == 'h') { @@ -1167,7 +1166,7 @@ int frame_split_command(int argc, char** argv) { int frame_change_fraction_command(int argc, char** argv) { // usage: fraction DIRECTION DELTA if (argc < 3) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } char direction = argv[1][0]; double delta_double = atof(argv[2]); @@ -1316,7 +1315,7 @@ int frame_inner_neighbour_index(HSFrame* frame, char direction) { int frame_focus_command(int argc, char** argv) { // usage: focus [-e|-i] left|right|up|down - if (argc < 2) return HERBST_INVALID_ARGUMENT; + if (argc < 2) return HERBST_NEED_MORE_ARGS; if (!g_cur_frame) { fprintf(stderr, "warning: no frame is selected\n"); return HERBST_UNKNOWN_ERROR; @@ -1356,7 +1355,7 @@ int frame_focus_command(int argc, char** argv) { int frame_move_window_command(int argc, char** argv) { // usage: move left|right|up|down - if (argc < 2) return HERBST_INVALID_ARGUMENT; + if (argc < 2) return HERBST_NEED_MORE_ARGS; if (!g_cur_frame) { fprintf(stderr, "warning: no frame is selected\n"); return HERBST_UNKNOWN_ERROR; diff --git a/src/main.c b/src/main.c index b1b04ad..e59ace5 100644 --- a/src/main.c +++ b/src/main.c @@ -203,7 +203,7 @@ int load_command(int argc, char** argv, GString* output) { // usage: load TAG LAYOUT HSTag* tag = NULL; if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } char* layout_string = argv[1]; if (argc >= 3) { @@ -288,8 +288,7 @@ int custom_hook_emit(int argc, char** argv) { // spawn() heavily inspired by dwm.c int spawn(int argc, char** argv) { if (argc < 2) { - fprintf(stderr, "spawn: too few parameters\n"); - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } if (fork() == 0) { // only look in child @@ -360,7 +359,7 @@ int jumpto_command(int argc, char** argv) { int getenv_command(int argc, char** argv, GString* output) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } char* envvar = getenv(argv[1]); if (envvar == NULL) { @@ -372,7 +371,7 @@ int getenv_command(int argc, char** argv, GString* output) { int setenv_command(int argc, char** argv) { if (argc < 3) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } if (setenv(argv[1], argv[2], 1) != 0) { return HERBST_INVALID_ARGUMENT; @@ -382,7 +381,7 @@ int setenv_command(int argc, char** argv) { int unsetenv_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } if (unsetenv(argv[1]) != 0) { return HERBST_INVALID_ARGUMENT; diff --git a/src/monitor.c b/src/monitor.c index e3c84a9..7e798fd 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -254,8 +254,7 @@ static RectList* disjoin_rects(XRectangle* buf, size_t count) { int disjoin_rects_command(int argc, char** argv, GString* output) { (void)SHIFT(argc, argv); if (argc < 1) { - g_string_append_printf(output, "At least one rect is required.\n"); - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } XRectangle* buf = g_new(XRectangle, argc); for (int i = 0; i < argc; i++) { @@ -276,8 +275,7 @@ int disjoin_rects_command(int argc, char** argv, GString* output) { int set_monitor_rects_command(int argc, char** argv, GString* output) { (void)SHIFT(argc, argv); if (argc < 1) { - g_string_append_printf(output, "At least one monitor is required.\n"); - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } XRectangle* templates = g_new0(XRectangle, argc); for (int i = 0; i < argc; i++) { @@ -334,7 +332,7 @@ HSMonitor* add_monitor(XRectangle rect, HSTag* tag) { int add_monitor_command(int argc, char** argv) { // usage: add_monitor RECTANGLE [TAG [PADUP [PADRIGHT [PADDOWN [PADLEFT]]]]] if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } XRectangle rect = parse_rectangle(argv[1]); HSTag* tag = NULL; @@ -367,7 +365,7 @@ int add_monitor_command(int argc, char** argv) { int remove_monitor_command(int argc, char** argv) { // usage: remove_monitor INDEX if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } int index = atoi(argv[1]); return remove_monitor(index); @@ -409,7 +407,7 @@ int move_monitor_command(int argc, char** argv) { // usage: move_monitor INDEX RECT [PADUP [PADRIGHT [PADDOWN [PADLEFT]]]] // moves monitor with number to RECT if (argc < 3) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } int index = atoi(argv[1]); if (index < 0 || index >= g_monitors->len) { @@ -481,7 +479,7 @@ int monitor_rect_command(int argc, char** argv, GString* output) { int monitor_set_pad_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } int index = atoi(argv[1]); if (index < 0 || index >= g_monitors->len) { @@ -621,7 +619,7 @@ void monitor_set_tag(HSMonitor* monitor, HSTag* tag) { int monitor_set_tag_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } HSMonitor* monitor = get_current_monitor(); HSTag* tag = find_tag(argv[1]); @@ -635,7 +633,7 @@ int monitor_set_tag_command(int argc, char** argv) { int monitor_set_tag_by_index_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } bool skip_visible = false; if (argc >= 3 && !strcmp(argv[2], "--skip-visible")) { @@ -651,7 +649,7 @@ int monitor_set_tag_by_index_command(int argc, char** argv) { int monitor_focus_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } int new_selection = atoi(argv[1]); // really change selection diff --git a/src/mouse.c b/src/mouse.c index b2bc9f4..74e6e5f 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -157,7 +157,7 @@ int mouse_binding_equals(MouseBinding* a, MouseBinding* b) { int mouse_bind_command(int argc, char** argv) { if (argc < 3) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } unsigned int modifiers = 0; char* string = argv[1]; diff --git a/src/rules.c b/src/rules.c index 474f09c..78e9a11 100644 --- a/src/rules.c +++ b/src/rules.c @@ -360,7 +360,7 @@ int rule_add_command(int argc, char** argv) { int rule_remove_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } if (!strcmp(argv[1], "--all") || !strcmp(argv[1], "-F")) { diff --git a/src/settings.c b/src/settings.c index b473bcc..944e37e 100644 --- a/src/settings.c +++ b/src/settings.c @@ -116,7 +116,7 @@ SettingsPair* settings_find(char* name) { int settings_set_command(int argc, char** argv) { if (argc < 3) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } SettingsPair* pair = settings_find(argv[1]); if (!pair) { @@ -155,7 +155,7 @@ int settings_set(SettingsPair* pair, char* value) { int settings_get(int argc, char** argv, GString* output) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } SettingsPair* pair = settings_find(argv[1]); if (!pair) { @@ -172,7 +172,7 @@ int settings_get(int argc, char** argv, GString* output) { // toggle integer-like values int settings_toggle(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } SettingsPair* pair = settings_find(argv[1]); if (!pair) { @@ -209,7 +209,7 @@ bool memberequals_settingspair(void* pmember, void* needle) { int settings_cycle_value(int argc, char** argv) { if (argc < 3) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } SettingsPair* pair = settings_find(argv[1]); if (!pair) { diff --git a/src/tag.c b/src/tag.c index 8c2de3c..a2629d7 100644 --- a/src/tag.c +++ b/src/tag.c @@ -142,7 +142,7 @@ HSTag* add_tag(char* name) { int tag_add_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } if (!strcmp("", argv[1])) { HSDebug("A empty tag name is not permitted\n"); @@ -155,7 +155,7 @@ int tag_add_command(int argc, char** argv) { int tag_rename_command(int argc, char** argv) { if (argc < 3) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } HSTag* tag = find_tag(argv[1]); if (!tag) { @@ -175,7 +175,7 @@ int tag_remove_command(int argc, char** argv) { // it removes an TAG and moves all its wins to TARGET // if no TARGET is given, current tag is used if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } HSTag* tag = find_tag(argv[1]); HSTag* target = (argc >= 3) ? find_tag(argv[2]) : get_current_monitor()->tag; @@ -313,7 +313,7 @@ HSTag* find_tag_with_toplevel_frame(HSFrame* frame) { int tag_move_window_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } HSTag* target = find_tag(argv[1]); if (!target) { @@ -325,7 +325,7 @@ int tag_move_window_command(int argc, char** argv) { int tag_move_window_by_index_command(int argc, char** argv) { if (argc < 2) { - return HERBST_INVALID_ARGUMENT; + return HERBST_NEED_MORE_ARGS; } bool skip_visible = false; if (argc >= 3 && !strcmp(argv[2], "--skip-visible")) { -- 1.8.0
From 8dca6d918ef04d99a17d2d9f0d7955c064f89eab Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 15:57:52 +0100 Subject: [PATCH 02/25] Output error message if command is not found --- src/command.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/command.c b/src/command.c index fac10f5..7d1869c 100644 --- a/src/command.c +++ b/src/command.c @@ -211,6 +211,8 @@ int call_command(int argc, char** argv, GString* output) { i++; } if (!bind) { + g_string_append_printf(output, + "error: Command \"%s\" not found!\n", argv[0]); return HERBST_COMMAND_NOT_FOUND; } int status; -- 1.8.0
From 4ea300112d73784261af4887b5f0317e99530c75 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 16:02:56 +0100 Subject: [PATCH 03/25] Add error output for nearly every command --- NEWS | 1 + src/key.c | 13 ++++--- src/key.h | 4 +-- src/layout.c | 19 ++++++---- src/layout.h | 6 ++-- src/main.c | 112 ++++++++++++++++++++++++++++++++++----------------------- src/monitor.c | 56 ++++++++++++++++++++++------- src/monitor.h | 18 +++++----- src/mouse.c | 10 ++++-- src/mouse.h | 3 +- src/rules.c | 42 +++++++++++++--------- src/rules.h | 4 +-- src/settings.c | 16 +++++++-- src/settings.h | 6 ++-- src/tag.c | 36 +++++++++++++++---- src/tag.h | 10 +++--- 16 files changed, 235 insertions(+), 121 deletions(-) diff --git a/NEWS b/NEWS index c1f803a..2559bcd 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,7 @@ Changes: * new rule: ewmhnotify * floating, fullscreen, pseudotile: default to toggle if no argument is given + * add error messages for herbstclient Release: 0.4.1 on 2012-08-30 ---------------------------- diff --git a/src/key.c b/src/key.c index 55e8a67..2d59c41 100644 --- a/src/key.c +++ b/src/key.c @@ -92,19 +92,22 @@ char* modifiermask2name(unsigned int mask) { return NULL; } -int keybind(int argc, char** argv) { +int keybind(int argc, char** argv, GString* output) { if (argc <= 2) { return HERBST_NEED_MORE_ARGS; } KeyBinding new_bind; // get keycode if (!string2key(argv[1], &(new_bind.modifiers), &(new_bind.keysym))) { + g_string_append_printf(output, + "%s: No such KeySym/modifier!\n", argv[0]); return HERBST_INVALID_ARGUMENT; } KeyCode keycode = XKeysymToKeycode(g_display, new_bind.keysym); if (!keycode) { - fprintf(stderr, "keybind: no keycode for symbol %s\n", - XKeysymToString(new_bind.keysym)); + g_string_append_printf(output, + "%s: no keycode for symbol %s\n", + argv[0], XKeysymToString(new_bind.keysym)); return HERBST_INVALID_ARGUMENT; } // remove existing binding with same keysym/modifiers @@ -185,7 +188,7 @@ void handle_key_press(XEvent* ev) { } } -int keyunbind(int argc, char** argv) { +int keyunbind(int argc, char** argv, GString* output) { if (argc <= 1) { return HERBST_NEED_MORE_ARGS; } @@ -198,6 +201,8 @@ int keyunbind(int argc, char** argv) { KeySym keysym; // get keycode if (!string2key(argv[1], &modifiers, &keysym)) { + g_string_append_printf(output, + "%s: No such KeySym/modifier!\n", argv[0]); return HERBST_INVALID_ARGUMENT; } key_remove_bind_with_keysym(modifiers, keysym); diff --git a/src/key.h b/src/key.h index 0c4748d..7a274f0 100644 --- a/src/key.h +++ b/src/key.h @@ -24,8 +24,8 @@ char* modifiermask2name(unsigned int mask); bool string2modifiers(char* string, unsigned int* modmask); bool string2key(char* string, unsigned int* modmask, KeySym* keysym); -int keybind(int argc, char** argv); -int keyunbind(int argc, char** argv); //removes a keybinding +int keybind(int argc, char** argv, GString* output); +int keyunbind(int argc, char** argv, GString* output); //removes a keybinding void keybinding_free(KeyBinding* binding); int key_list_binds(int argc, char** argv, GString* output); diff --git a/src/layout.c b/src/layout.c index c476a41..36f1a5e 100644 --- a/src/layout.c +++ b/src/layout.c @@ -98,7 +98,7 @@ static void fetch_frame_colors() { g_warning("too few characters in setting tree_style\n"); // ensure that it is long enough char* argv[] = { "set", "tree_style", "01234567" }; - settings_set_command(LENGTH(argv), argv); + settings_set_command(LENGTH(argv), argv, NULL); } } @@ -597,7 +597,8 @@ void frame_apply_floating_layout(HSFrame* frame, HSMonitor* m) { } } -int frame_current_cycle_client_layout(int argc, char** argv) { +int frame_current_cycle_client_layout(int argc, char** argv, GString* output) { + char* cmd_name = argv[0]; // save this before shifting int delta = 1; if (argc >= 2) { delta = atoi(argv[1]); @@ -617,6 +618,8 @@ int frame_current_cycle_client_layout(int argc, char** argv) { idx %= argc; layout_index = find_layout_by_name(argv[idx]); if (layout_index < 0) { + g_string_append_printf(output, + "%s: Invalid layout name \"%s\"\n", cmd_name, argv[idx]); return HERBST_INVALID_ARGUMENT; } } else { @@ -631,14 +634,15 @@ int frame_current_cycle_client_layout(int argc, char** argv) { return 0; } -int frame_current_set_client_layout(int argc, char** argv) { +int frame_current_set_client_layout(int argc, char** argv, GString* output) { int layout = 0; if (argc <= 1) { return HERBST_NEED_MORE_ARGS; } layout = find_layout_by_name(argv[1]); if (layout < 0) { - HSDebug("set_layout: invalid layout name \"%s\"\n", argv[1]); + g_string_append_printf(output, + "%s: invalid layout name \"%s\"\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } if (g_cur_frame && g_cur_frame->type == TYPE_CLIENTS) { @@ -1163,7 +1167,7 @@ int frame_split_command(int argc, char** argv) { return 0; } -int frame_change_fraction_command(int argc, char** argv) { +int frame_change_fraction_command(int argc, char** argv, GString* output) { // usage: fraction DIRECTION DELTA if (argc < 3) { return HERBST_NEED_MORE_ARGS; @@ -1180,7 +1184,10 @@ int frame_change_fraction_command(int argc, char** argv) { case 'r': break; case 'u': delta *= -1; break; case 'd': break; - default: return HERBST_INVALID_ARGUMENT; + default: + g_string_append_printf(output, + "%s: Invalid direction \"%s\"\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; } HSFrame* neighbour = frame_neighbour(g_cur_frame, direction); if (!neighbour) { diff --git a/src/layout.h b/src/layout.h index ea7733b..9503a3f 100644 --- a/src/layout.h +++ b/src/layout.h @@ -109,7 +109,7 @@ bool frame_remove_window(HSFrame* frame, Window window); void frame_destroy(HSFrame* frame, Window** buf, size_t* count); void frame_split(HSFrame* frame, int align, int fraction); int frame_split_command(int argc, char** argv); -int frame_change_fraction_command(int argc, char** argv); +int frame_change_fraction_command(int argc, char** argv, GString* output); void frame_apply_layout(HSFrame* frame, XRectangle rect); void frame_apply_floating_layout(HSFrame* frame, struct HSMonitor* m); @@ -153,8 +153,8 @@ int frame_foreach_client(HSFrame* frame, ClientAction action, void* data); void frame_apply_client_layout_linear(HSFrame* frame, XRectangle rect, bool vertical); void frame_apply_client_layout_horizontal(HSFrame* frame, XRectangle rect); void frame_apply_client_layout_vertical(HSFrame* frame, XRectangle rect); -int frame_current_cycle_client_layout(int argc, char** argv); -int frame_current_set_client_layout(int argc, char** argv); +int frame_current_cycle_client_layout(int argc, char** argv, GString* output); +int frame_current_set_client_layout(int argc, char** argv, GString* output); int frame_split_count_to_root(HSFrame* frame, int align); // returns the Window that is focused diff --git a/src/main.c b/src/main.c index e59ace5..a473a65 100644 --- a/src/main.c +++ b/src/main.c @@ -29,6 +29,7 @@ #include <sys/select.h> #include <sys/wait.h> #include <assert.h> +#include <errno.h> // gui #include <X11/Xlib.h> #include <X11/Xproto.h> @@ -59,10 +60,10 @@ int spawn(int argc, char** argv); int wmexec(int argc, char** argv); static void remove_zombies(int signal); int custom_hook_emit(int argc, char** argv); -int jumpto_command(int argc, char** argv); +int jumpto_command(int argc, char** argv, GString* output); int getenv_command(int argc, char** argv, GString* output); -int setenv_command(int argc, char** argv); -int unsetenv_command(int argc, char** argv); +int setenv_command(int argc, char** argv, GString* output); +int unsetenv_command(int argc, char** argv, GString* output); // handler for X-Events void buttonpress(XEvent* event); @@ -92,9 +93,9 @@ CommandBinding g_commands[] = { CMD_BIND( "disjoin_rects", disjoin_rects_command), CMD_BIND( "list_keybinds", key_list_binds), CMD_BIND( "list_padding", list_padding), - CMD_BIND_NO_OUTPUT( "keybind", keybind), - CMD_BIND_NO_OUTPUT( "keyunbind", keyunbind), - CMD_BIND_NO_OUTPUT( "mousebind", mouse_bind_command), + CMD_BIND( "keybind", keybind), + CMD_BIND( "keyunbind", keyunbind), + CMD_BIND( "mousebind", mouse_bind_command), CMD_BIND_NO_OUTPUT( "mouseunbind", mouse_unbind_all), CMD_BIND_NO_OUTPUT( "spawn", spawn), CMD_BIND_NO_OUTPUT( "wmexec", wmexec), @@ -103,42 +104,42 @@ CommandBinding g_commands[] = { 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), - CMD_BIND_NO_OUTPUT( "cycle_layout", frame_current_cycle_client_layout), + CMD_BIND( "cycle_layout", frame_current_cycle_client_layout), CMD_BIND_NO_OUTPUT( "close", window_close_current), CMD_BIND_NO_OUTPUT( "close_or_remove",close_or_remove_command), CMD_BIND_NO_OUTPUT( "split", frame_split_command), - CMD_BIND_NO_OUTPUT( "resize", frame_change_fraction_command), + CMD_BIND( "resize", frame_change_fraction_command), CMD_BIND_NO_OUTPUT( "focus", frame_focus_command), CMD_BIND_NO_OUTPUT( "shift", frame_move_window_command), CMD_BIND_NO_OUTPUT( "remove", frame_remove_command), - CMD_BIND_NO_OUTPUT( "set", settings_set_command), - CMD_BIND_NO_OUTPUT( "toggle", settings_toggle), - CMD_BIND_NO_OUTPUT( "cycle_value", settings_cycle_value), + CMD_BIND( "set", settings_set_command), + 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( "get", settings_get), - CMD_BIND_NO_OUTPUT( "add", tag_add_command), - CMD_BIND_NO_OUTPUT( "use", monitor_set_tag_command), - CMD_BIND_NO_OUTPUT( "use_index", monitor_set_tag_by_index_command), - CMD_BIND_NO_OUTPUT( "jumpto", jumpto_command), + CMD_BIND( "add", tag_add_command), + CMD_BIND( "use", monitor_set_tag_command), + CMD_BIND( "use_index", monitor_set_tag_by_index_command), + CMD_BIND( "jumpto", jumpto_command), CMD_BIND( "floating", tag_set_floating_command), CMD_BIND_NO_OUTPUT( "fullscreen", client_set_property_command), CMD_BIND_NO_OUTPUT( "pseudotile", client_set_property_command), CMD_BIND( "tag_status", print_tag_status_command), - CMD_BIND_NO_OUTPUT( "merge_tag", tag_remove_command), - CMD_BIND_NO_OUTPUT( "rename", tag_rename_command), - CMD_BIND_NO_OUTPUT( "move", tag_move_window_command), + CMD_BIND( "merge_tag", tag_remove_command), + CMD_BIND( "rename", tag_rename_command), + CMD_BIND( "move", tag_move_window_command), CMD_BIND_NO_OUTPUT( "rotate", layout_rotate_command), - CMD_BIND_NO_OUTPUT( "move_index", tag_move_window_by_index_command), - CMD_BIND_NO_OUTPUT( "add_monitor", add_monitor_command), - CMD_BIND_NO_OUTPUT( "raise_monitor", monitor_raise_command), + CMD_BIND( "move_index", tag_move_window_by_index_command), + CMD_BIND( "add_monitor", add_monitor_command), + CMD_BIND( "raise_monitor", monitor_raise_command), CMD_BIND_NO_OUTPUT( "remove_monitor", remove_monitor_command), - CMD_BIND_NO_OUTPUT( "move_monitor", move_monitor_command), + CMD_BIND( "move_monitor", move_monitor_command), CMD_BIND( "monitor_rect", monitor_rect_command), - CMD_BIND_NO_OUTPUT( "pad", monitor_set_pad_command), + CMD_BIND( "pad", monitor_set_pad_command), CMD_BIND_NO_OUTPUT( "raise", raise_command), - CMD_BIND_NO_OUTPUT( "rule", rule_add_command), - CMD_BIND_NO_OUTPUT( "unrule", rule_remove_command), + CMD_BIND( "rule", rule_add_command), + CMD_BIND( "unrule", rule_remove_command), CMD_BIND( "layout", print_layout_command), CMD_BIND( "stack", print_stack_command), CMD_BIND( "dump", print_layout_command), @@ -146,16 +147,16 @@ CommandBinding g_commands[] = { CMD_BIND( "complete", complete_command), CMD_BIND_NO_OUTPUT( "lock", monitors_lock_command), CMD_BIND_NO_OUTPUT( "unlock", monitors_unlock_command), - CMD_BIND_NO_OUTPUT( "lock_tag", monitor_lock_tag_command), - CMD_BIND_NO_OUTPUT( "unlock_tag", monitor_unlock_tag_command), - CMD_BIND_NO_OUTPUT( "set_layout", frame_current_set_client_layout), - CMD_BIND_NO_OUTPUT( "detect_monitors",detect_monitors_command), + CMD_BIND( "lock_tag", monitor_lock_tag_command), + CMD_BIND( "unlock_tag", monitor_unlock_tag_command), + CMD_BIND( "set_layout", frame_current_set_client_layout), + CMD_BIND( "detect_monitors",detect_monitors_command), CMD_BIND( "chain", command_chain_command), CMD_BIND( "and", command_chain_command), CMD_BIND( "or", command_chain_command), CMD_BIND( "getenv", getenv_command), - CMD_BIND_NO_OUTPUT( "setenv", setenv_command), - CMD_BIND_NO_OUTPUT( "unsetenv", unsetenv_command), + CMD_BIND( "setenv", setenv_command), + CMD_BIND( "unsetenv", unsetenv_command), {{ NULL }} }; @@ -184,9 +185,12 @@ int print_layout_command(int argc, char** argv, GString* output) { HSTag* tag = NULL; if (argc >= 2) { tag = find_tag(argv[1]); - } - // if no tag was found - if (!tag) { + if (!tag) { + g_string_append_printf(output, + "%s: error: tag \"%s\" not found!\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; + } + } else { // use current tag HSMonitor* m = get_current_monitor(); tag = m->tag; } @@ -209,9 +213,12 @@ int load_command(int argc, char** argv, GString* output) { if (argc >= 3) { tag = find_tag(argv[1]); layout_string = argv[2]; - } - // if no tag was found - if (!tag) { + if (!tag) { + g_string_append_printf(output, + "load_command: error: tag \"%s\" not found!\n", argv[1]); + return HERBST_INVALID_ARGUMENT; + } + } else { // use current tag HSMonitor* m = get_current_monitor(); tag = m->tag; } @@ -230,6 +237,8 @@ int load_command(int argc, char** argv, GString* output) { frame_hide_recursive(tag->frame); } if (!rest) { + g_string_append_printf(output, + "%s: layout \"%s\" unknown\n", argv[0], layout_string); return HERBST_INVALID_ARGUMENT; } if (rest[0] != '\0') { // if string was not parsed completely @@ -348,13 +357,22 @@ int raise_command(int argc, char** argv) { return 0; } -int jumpto_command(int argc, char** argv) { +int jumpto_command(int argc, char** argv, GString* output) { HSClient* client = NULL; string_to_client((argc > 1) ? argv[1] : "", &client); if (client) { focus_window(client->window, true, true); + return 0; + } else { + g_string_append_printf(output, + "%s: error: Could not find client", argv[0]); + if (argc > 1) { + g_string_append_printf(output, " \"%s\".\n", argv[1]); + } else { + g_string_append(output, ".\n"); + } + return HERBST_INVALID_ARGUMENT; } - return 0; } int getenv_command(int argc, char** argv, GString* output) { @@ -363,28 +381,34 @@ int getenv_command(int argc, char** argv, GString* output) { } char* envvar = getenv(argv[1]); if (envvar == NULL) { + g_string_append_printf(output, + "Environment variable \"%s\" is not set!\n", argv[1]); return HERBST_ENV_UNSET; } g_string_append_printf(output, "%s\n", envvar); return 0; } -int setenv_command(int argc, char** argv) { +int setenv_command(int argc, char** argv, GString* output) { if (argc < 3) { return HERBST_NEED_MORE_ARGS; } if (setenv(argv[1], argv[2], 1) != 0) { - return HERBST_INVALID_ARGUMENT; + g_string_append_printf(output, + "Could not set environment variable: %s\n", strerror(errno)); + return HERBST_UNKNOWN_ERROR; } return 0; } -int unsetenv_command(int argc, char** argv) { +int unsetenv_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } if (unsetenv(argv[1]) != 0) { - return HERBST_INVALID_ARGUMENT; + g_string_append_printf(output, + "Could not unset environment variable: %s\n", strerror(errno)); + return HERBST_UNKNOWN_ERROR; } return 0; } @@ -697,7 +721,7 @@ void configurenotify(XEvent* event) { if (event->xconfigure.window == g_root && settings_find("auto_detect_monitors")->value.i) { char* args[] = { "detect_monitors" }; - detect_monitors_command(LENGTH(args), args); + detect_monitors_command(LENGTH(args), args, NULL); } // HSDebug("name is: ConfigureNotify\n"); } diff --git a/src/monitor.c b/src/monitor.c index 7e798fd..90fdb67 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -283,6 +283,10 @@ int set_monitor_rects_command(int argc, char** argv, GString* output) { } int status = set_monitor_rects(templates, argc); g_free(templates); + if (status == HERBST_TAG_IN_USE) { + g_string_append_printf(output, + "%s: there are not enough free tags!\n", argv[0]); + } return status; } @@ -329,7 +333,7 @@ HSMonitor* add_monitor(XRectangle rect, HSTag* tag) { return g_array_index(g_monitors, HSMonitor*, g_monitors->len-1); } -int add_monitor_command(int argc, char** argv) { +int add_monitor_command(int argc, char** argv, GString* output) { // usage: add_monitor RECTANGLE [TAG [PADUP [PADRIGHT [PADDOWN [PADLEFT]]]]] if (argc < 2) { return HERBST_NEED_MORE_ARGS; @@ -339,16 +343,22 @@ int add_monitor_command(int argc, char** argv) { if (argc == 2 || !strcmp("", argv[2])) { tag = find_unused_tag(); if (!tag) { + g_string_append_printf(output, + "%s: there are not enough free tags!\n", argv[0]); return HERBST_TAG_IN_USE; } } else { tag = find_tag(argv[2]); if (!tag) { + g_string_append_printf(output, + "%s: The tag \"%s\" does not exist!\n", argv[0], argv[2]); return HERBST_INVALID_ARGUMENT; } } if (find_monitor_with_tag(tag)) { + g_string_append_printf(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); @@ -403,7 +413,7 @@ int remove_monitor(int index) { return 0; } -int move_monitor_command(int argc, char** argv) { +int move_monitor_command(int argc, char** argv, GString* output) { // usage: move_monitor INDEX RECT [PADUP [PADRIGHT [PADDOWN [PADLEFT]]]] // moves monitor with number to RECT if (argc < 3) { @@ -411,10 +421,14 @@ int move_monitor_command(int argc, char** argv) { } int index = atoi(argv[1]); if (index < 0 || index >= g_monitors->len) { + g_string_append_printf(output, + "%s: index %i is out of range!\n", argv[0], index); return HERBST_INVALID_ARGUMENT; } XRectangle rect = parse_rectangle(argv[2]); if (rect.width < WINDOW_MIN_WIDTH || rect.height < WINDOW_MIN_HEIGHT) { + g_string_append_printf(output, + "%s: rectangle is too small!\n", argv[0]); return HERBST_INVALID_ARGUMENT; } // else: just move it: @@ -444,8 +458,8 @@ int monitor_rect_command(int argc, char** argv, GString* output) { if (!strcmp("-p", argv[1])) { with_pad = true; } else { - fprintf(stderr, "monitor_rect_command: invalid argument \"%s\"\n", - argv[1]); + g_string_append_printf(output, + "%s: invalid argument \"%s\"\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } } @@ -455,8 +469,8 @@ int monitor_rect_command(int argc, char** argv, GString* output) { if (1 == sscanf(index_str, "%d", &index)) { m = monitor_with_index(index); if (!m) { - fprintf(stderr,"monitor_rect_command: invalid index \"%s\"\n", - index_str); + g_string_append_printf(output, + "%s: invalid index \"%s\"\n", argv[0], index_str); return HERBST_INVALID_ARGUMENT; } } @@ -477,12 +491,14 @@ int monitor_rect_command(int argc, char** argv, GString* output) { return 0; } -int monitor_set_pad_command(int argc, char** argv) { +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) { + g_string_append_printf(output, + "%s: index %i is out of range!\n", argv[0], index); return HERBST_INVALID_ARGUMENT; } HSMonitor* monitor = monitor_with_index(index); @@ -617,7 +633,7 @@ void monitor_set_tag(HSMonitor* monitor, HSTag* tag) { emit_tag_changed(tag, g_cur_monitor); } -int monitor_set_tag_command(int argc, char** argv) { +int monitor_set_tag_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } @@ -627,11 +643,13 @@ int monitor_set_tag_command(int argc, char** argv) { monitor_set_tag(monitor, tag); return 0; } else { + g_string_append_printf(output, + "%s: Invalid monitor or tag!\n", argv[0]); return HERBST_INVALID_ARGUMENT; } } -int monitor_set_tag_by_index_command(int argc, char** argv) { +int monitor_set_tag_by_index_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } @@ -641,6 +659,8 @@ int monitor_set_tag_by_index_command(int argc, char** argv) { } HSTag* tag = get_tag_by_index_str(argv[1], skip_visible); if (!tag) { + g_string_append_printf(output, + "%s: Invalid index \"%s\"!\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } monitor_set_tag(get_current_monitor(), tag); @@ -811,7 +831,7 @@ void monitors_lock_changed() { } } -int monitor_lock_tag_command(int argc, char** argv) { +int monitor_lock_tag_command(int argc, char** argv, GString* output) { (void)SHIFT(argc, argv); HSMonitor *monitor; if (argc >= 1) { @@ -820,13 +840,15 @@ int monitor_lock_tag_command(int argc, char** argv) { 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) { +int monitor_unlock_tag_command(int argc, char** argv, GString* output) { (void)SHIFT(argc, argv); HSMonitor *monitor; if (argc >= 1) { @@ -835,6 +857,8 @@ int monitor_unlock_tag_command(int argc, char** argv) { 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; @@ -904,7 +928,7 @@ bool detect_monitors_simple(XRectangle** ret_rects, size_t* ret_count) { return true; } -int detect_monitors_command(int argc, char **argv) { +int detect_monitors_command(int argc, char **argv, GString* output) { MonitorDetection detect[] = { detect_monitors_xinerama, detect_monitors_simple, @@ -923,6 +947,10 @@ int detect_monitors_command(int argc, char **argv) { // apply it int ret = set_monitor_rects(monitors, count); g_free(monitors); + if (ret == HERBST_TAG_IN_USE && output != NULL) { + g_string_append_printf(output, + "%s: there are not enough free tags!\n", argv[0]); + } return ret; } @@ -938,7 +966,7 @@ HSStack* get_monitor_stack() { return g_monitor_stack; } -int monitor_raise_command(int argc, char** argv) { +int monitor_raise_command(int argc, char** argv, GString* output) { (void)SHIFT(argc, argv); HSMonitor* monitor; if (argc >= 1) { @@ -947,6 +975,8 @@ int monitor_raise_command(int argc, char** argv) { 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); diff --git a/src/monitor.h b/src/monitor.h index 98cd24d..212d9f9 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -55,8 +55,8 @@ 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 add_monitor_command(int argc, char** argv); -int monitor_raise_command(int argc, char** argv); +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); int remove_monitor(int index); int list_monitors(int argc, char** argv, GString* output); @@ -64,19 +64,19 @@ int list_padding(int argc, char** argv, GString* output); 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); +int move_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(); void monitor_set_tag(HSMonitor* monitor, struct HSTag* tag); -int monitor_set_pad_command(int argc, char** argv); -int monitor_set_tag_command(int argc, char** argv); -int monitor_set_tag_by_index_command(int argc, char** argv); +int monitor_set_pad_command(int argc, char** argv, GString* output); +int monitor_set_tag_command(int argc, char** argv, GString* output); +int monitor_set_tag_by_index_command(int argc, char** argv, GString* output); int monitors_lock_command(int argc, char** argv); int monitors_unlock_command(int argc, char** argv); void monitors_lock_changed(); -int monitor_lock_tag_command(int argc, char** argv); -int monitor_unlock_tag_command(int argc, char** argv); +int monitor_lock_tag_command(int argc, char** argv, GString* output); +int monitor_unlock_tag_command(int argc, char** argv, GString* output); void monitor_apply_layout(HSMonitor* monitor); void all_monitors_apply_layout(); void ensure_monitors_are_available(); @@ -90,7 +90,7 @@ struct HSStack* get_monitor_stack(); typedef bool (*MonitorDetection)(XRectangle**, size_t*); bool detect_monitors_xinerama(XRectangle** ret_rects, size_t* ret_count); bool detect_monitors_simple(XRectangle** ret_rects, size_t* ret_count); -int detect_monitors_command(int argc, char **argv); +int detect_monitors_command(int argc, char **argv, GString* output); #endif diff --git a/src/mouse.c b/src/mouse.c index 74e6e5f..dac1c9e 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -155,25 +155,29 @@ int mouse_binding_equals(MouseBinding* a, MouseBinding* b) { } } -int mouse_bind_command(int argc, char** argv) { +int mouse_bind_command(int argc, char** argv, GString* output) { if (argc < 3) { return HERBST_NEED_MORE_ARGS; } unsigned int modifiers = 0; char* string = argv[1]; if (!string2modifiers(string, &modifiers)) { + g_string_append_printf(output, + "%s: Modifier \"%s\" does not exist!\n", argv[0], string); return HERBST_INVALID_ARGUMENT; } // last one is the mouse button char* last_token = strlasttoken(string, KEY_COMBI_SEPARATORS); unsigned int button = string2button(last_token); if (button == 0) { - fprintf(stderr, "warning: unknown mouse button \"%s\"\n", last_token); + g_string_append_printf(output, + "%s: Unknown mouse button \"%s\"!\n", argv[0], last_token); return HERBST_INVALID_ARGUMENT; } MouseFunction function = string2mousefunction(argv[2]); if (!function) { - fprintf(stderr, "warning: unknown mouse action \"%s\"\n", argv[2]); + g_string_append_printf(output, + "%s: Unknown mouse action \"%s\"!\n", argv[0], argv[2]); return HERBST_INVALID_ARGUMENT; } mouse_bind_function(modifiers, button, function); diff --git a/src/mouse.h b/src/mouse.h index cff847c..ca5bee2 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -8,6 +8,7 @@ #include <X11/Xlib.h> #include <stdbool.h> +#include <glib.h> // various snap-flags enum SnapFlags { @@ -39,7 +40,7 @@ int mouse_binding_equals(MouseBinding* a, MouseBinding* b); void mouse_bind_function(unsigned int modifiers, unsigned int button, MouseFunction function); -int mouse_bind_command(int argc, char** argv); +int mouse_bind_command(int argc, char** argv, GString* output); int mouse_unbind_all(); MouseBinding* mouse_binding_find(unsigned int modifiers, unsigned int button); diff --git a/src/rules.c b/src/rules.c index 78e9a11..5d18dc2 100644 --- a/src/rules.c +++ b/src/rules.c @@ -114,10 +114,11 @@ int find_condition_type(char* name) { return -1; } -HSCondition* condition_create(int type, char op, char* value) { +HSCondition* condition_create(int type, char op, char* value, GString* output) { HSCondition cond; if (op != '=' && type == g_maxage_type) { - fprintf(stderr, "condition maxage only supports the = operator\n"); + g_string_append_printf(output, + "condition maxage only supports the = operator\n"); return NULL; } switch (op) { @@ -125,7 +126,8 @@ HSCondition* condition_create(int type, char op, char* value) { if (type == g_maxage_type) { cond.value_type = CONDITION_VALUE_TYPE_INTEGER; if (1 != sscanf(value, "%d", &cond.value.integer)) { - fprintf(stderr, "cannot integer from \"%s\"\n", value); + g_string_append_printf(output, + "cannot integer from \"%s\"\n", value); return NULL; } } else { @@ -140,16 +142,16 @@ HSCondition* condition_create(int type, char op, char* value) { if (status != 0) { char buf[ERROR_STRING_BUF_SIZE]; regerror(status, &cond.value.exp, buf, ERROR_STRING_BUF_SIZE); - fprintf(stderr, "Cannot parse value \"%s\"", value); - fprintf(stderr, "from condition \"%s\": ", - g_condition_types[type].name); - fprintf(stderr, "\"%s\"\n", buf); + g_string_append_printf(output, + "Cannot parse value \"%s\" from condition \"%s\": \"%s\"\n", + value, g_condition_types[type].name, buf); return NULL; } break; default: - fprintf(stderr, "unknown rule condition operation \"%c\"\n", op); + g_string_append_printf(output, + "unknown rule condition operation \"%c\"\n", op); return NULL; break; } @@ -194,7 +196,7 @@ int find_consequence_type(char* name) { return -1; } -HSConsequence* consequence_create(int type, char op, char* value) { +HSConsequence* consequence_create(int type, char op, char* value, GString* output) { HSConsequence cons; switch (op) { case '=': @@ -203,7 +205,8 @@ HSConsequence* consequence_create(int type, char op, char* value) { break; default: - fprintf(stderr, "unknown rule consequence operation \"%c\"\n", op); + g_string_append_printf(output, + "unknown rule consequence operation \"%c\"\n", op); return NULL; break; } @@ -288,13 +291,13 @@ static void rule_add_consequence(HSRule* rule, HSConsequence* cons) { } -int rule_add_command(int argc, char** argv) { +int rule_add_command(int argc, char** argv, GString* output) { // usage: rule COND=VAL ... then // temporary data structures HSRule* rule = rule_create(); HSCondition* cond; - HSConsequence* cons; + HSConsequence* cons; bool negated = false; struct { char* name; @@ -329,7 +332,7 @@ int rule_add_command(int argc, char** argv) { } else if (consorcond && (type = find_condition_type(name)) >= 0) { - cond = condition_create(type, op, value); + cond = condition_create(type, op, value, output); if (!cond) { rule_destroy(rule); return HERBST_INVALID_ARGUMENT; @@ -340,7 +343,7 @@ int rule_add_command(int argc, char** argv) { } else if (consorcond && (type = find_consequence_type(name)) >= 0) { - cons = consequence_create(type, op, value); + cons = consequence_create(type, op, value, output); if (!cons) { rule_destroy(rule); return HERBST_INVALID_ARGUMENT; @@ -349,16 +352,21 @@ int rule_add_command(int argc, char** argv) { } else { - fprintf(stderr, "rule: unknown argument \"%s\"\n", *argv); + // need to hardcode "rule:" here because args are shifted + g_string_append_printf(output, + "rule: unknown argument \"%s\"\n", *argv); return HERBST_INVALID_ARGUMENT; } } + if (output->len > 0) { // if there was output + g_string_prepend(output, "rule: "); + } g_queue_push_tail(&g_rules, rule); return 0; } -int rule_remove_command(int argc, char** argv) { +int rule_remove_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } @@ -370,6 +378,8 @@ int rule_remove_command(int argc, char** argv) { return 0; } + g_string_append_printf(output, + "%s: this command must be used with --all/-F for the time being\n", argv[0]); return HERBST_INVALID_ARGUMENT; } diff --git a/src/rules.h b/src/rules.h index d2bb2b7..741ff4b 100644 --- a/src/rules.h +++ b/src/rules.h @@ -71,8 +71,8 @@ void client_changes_free_members(HSClientChanges* changes); HSRule* rule_create(); void rule_destroy(HSRule* rule); -int rule_add_command(int argc, char** argv); -int rule_remove_command(int argc, char** argv); +int rule_add_command(int argc, char** argv, GString* output); +int rule_remove_command(int argc, char** argv, GString* output); #endif diff --git a/src/settings.c b/src/settings.c index 944e37e..fd0e5d2 100644 --- a/src/settings.c +++ b/src/settings.c @@ -114,12 +114,16 @@ SettingsPair* settings_find(char* name) { return STATIC_TABLE_FIND_STR(SettingsPair, g_settings, name, name); } -int settings_set_command(int argc, char** argv) { +int settings_set_command(int argc, char** argv, GString* output) { if (argc < 3) { return HERBST_NEED_MORE_ARGS; } SettingsPair* pair = settings_find(argv[1]); if (!pair) { + if (output != NULL) { + g_string_append_printf(output, + "%s: setting \"%s\" not found!\n", argv[0], argv[1]); + } return HERBST_SETTING_NOT_FOUND; } return settings_set(pair, argv[2]); @@ -159,6 +163,8 @@ int settings_get(int argc, char** argv, GString* output) { } SettingsPair* pair = settings_find(argv[1]); if (!pair) { + g_string_append_printf(output, + "%s: setting \"%s\" not found!\n", argv[0], argv[1]); return HERBST_SETTING_NOT_FOUND; } if (pair->type == HS_Int) { @@ -170,12 +176,14 @@ int settings_get(int argc, char** argv, GString* output) { } // toggle integer-like values -int settings_toggle(int argc, char** argv) { +int settings_toggle(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } SettingsPair* pair = settings_find(argv[1]); if (!pair) { + g_string_append_printf(output, + "%s: setting \"%s\" not found!\n", argv[0], argv[1]); return HERBST_SETTING_NOT_FOUND; } if (pair->type == HS_Int) { @@ -207,12 +215,14 @@ bool memberequals_settingspair(void* pmember, void* needle) { } } -int settings_cycle_value(int argc, char** argv) { +int settings_cycle_value(int argc, char** argv, GString* output) { if (argc < 3) { return HERBST_NEED_MORE_ARGS; } SettingsPair* pair = settings_find(argv[1]); if (!pair) { + g_string_append_printf(output, + "%s: setting \"%s\" not found!", argv[0], argv[1]); return HERBST_SETTING_NOT_FOUND; } (void)SHIFT(argc, argv); diff --git a/src/settings.h b/src/settings.h index 7b28803..22a7e1b 100644 --- a/src/settings.h +++ b/src/settings.h @@ -33,9 +33,9 @@ void settings_destroy(); SettingsPair* settings_find(char* name); int settings_set(SettingsPair* pair, char* value); -int settings_set_command(int argc, char** argv); -int settings_toggle(int argc, char** argv); -int settings_cycle_value(int argc, char** argv); +int settings_set_command(int argc, char** argv, GString* output); +int settings_toggle(int argc, char** argv, GString* output); +int settings_cycle_value(int argc, char** argv, GString* output); int settings_count(); int settings_get(int argc, char** argv, GString* output); diff --git a/src/tag.c b/src/tag.c index a2629d7..c7524a2 100644 --- a/src/tag.c +++ b/src/tag.c @@ -140,12 +140,13 @@ HSTag* add_tag(char* name) { return tag; } -int tag_add_command(int argc, char** argv) { +int tag_add_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } if (!strcmp("", argv[1])) { - HSDebug("A empty tag name is not permitted\n"); + g_string_append_printf(output, + "%s: An empty tag name is not permitted\n", argv[0]); return HERBST_INVALID_ARGUMENT; } HSTag* tag = add_tag(argv[1]); @@ -153,15 +154,19 @@ int tag_add_command(int argc, char** argv) { return 0; } -int tag_rename_command(int argc, char** argv) { +int tag_rename_command(int argc, char** argv, GString* output) { if (argc < 3) { return HERBST_NEED_MORE_ARGS; } HSTag* tag = find_tag(argv[1]); if (!tag) { + g_string_append_printf(output, + "%s: Tag \"%s\" not found!\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } if (find_tag(argv[2])) { + g_string_append_printf(output, + "%s: Tag \"%s\" already exists!\n", argv[0], argv[2]); return HERBST_TAG_IN_USE; } g_string_assign(tag->name, argv[2]); @@ -170,7 +175,7 @@ int tag_rename_command(int argc, char** argv) { return 0; } -int tag_remove_command(int argc, char** argv) { +int tag_remove_command(int argc, char** argv, GString* output) { // usage: remove TAG [TARGET] // it removes an TAG and moves all its wins to TARGET // if no TARGET is given, current tag is used @@ -179,12 +184,23 @@ int tag_remove_command(int argc, char** argv) { } HSTag* tag = find_tag(argv[1]); HSTag* target = (argc >= 3) ? find_tag(argv[2]) : get_current_monitor()->tag; - if (!tag || !target || (tag == target)) { + if (!tag) { + g_string_append_printf(output, + "%s: Tag \"%s\" not found!\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; + } else if (!target) { + g_string_append_printf(output, + "%s: Tag \"%s\" not found!\n", argv[0], argv[2]); + } else if (tag == target) { + g_string_append_printf(output, + "%s: Cannot merge tag \"%s\" into itself!\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } HSMonitor* monitor = find_monitor_with_tag(tag); HSMonitor* monitor_target = find_monitor_with_tag(target); if (monitor) { + g_string_append_printf(output, + "%s: Cannot merge the currently viewed tag!\n", argv[0]); return HERBST_TAG_IN_USE; } // save all these windows @@ -234,6 +250,8 @@ int tag_set_floating_command(int argc, char** argv, GString* output) { tag = find_tag(argv[1]); action = argv[2]; if (!tag) { + g_string_append_printf(output, + "%s: Tag \"%s\" not found!\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } } @@ -311,19 +329,21 @@ HSTag* find_tag_with_toplevel_frame(HSFrame* frame) { return NULL; } -int tag_move_window_command(int argc, char** argv) { +int tag_move_window_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } HSTag* target = find_tag(argv[1]); if (!target) { + g_string_append_printf(output, + "%s: Tag \"%s\" not found!\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } tag_move_focused_client(target); return 0; } -int tag_move_window_by_index_command(int argc, char** argv) { +int tag_move_window_by_index_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } @@ -333,6 +353,8 @@ int tag_move_window_by_index_command(int argc, char** argv) { } HSTag* tag = get_tag_by_index_str(argv[1], skip_visible); if (!tag) { + g_string_append_printf(output, + "%s: Invalid index \"%s\"\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } tag_move_focused_client(tag); diff --git a/src/tag.h b/src/tag.h index d066f67..6f66def 100644 --- a/src/tag.h +++ b/src/tag.h @@ -36,13 +36,13 @@ HSTag* find_unused_tag(); HSTag* find_tag_with_toplevel_frame(struct HSFrame* frame); HSTag* get_tag_by_index(int index); HSTag* get_tag_by_index_str(char* index_str, bool skip_visible_tags); -int tag_add_command(int argc, char** argv); -int tag_rename_command(int argc, char** argv); -int tag_move_window_command(int argc, char** argv); -int tag_move_window_by_index_command(int argc, char** argv); +int tag_add_command(int argc, char** argv, GString* output); +int tag_rename_command(int argc, char** argv, GString* output); +int tag_move_window_command(int argc, char** argv, GString* output); +int tag_move_window_by_index_command(int argc, char** argv, GString* output); void tag_move_focused_client(HSTag* target); void tag_move_client(struct HSClient* client,HSTag* target); -int tag_remove_command(int argc, char** argv); +int tag_remove_command(int argc, char** argv, GString* output); int tag_set_floating_command(int argc, char** argv, GString* output); void tag_update_focus_layer(HSTag* tag); void tag_foreach(void (*action)(HSTag*)); -- 1.8.0
From d877a677ee05bc3bcc522ccf8524c0b48dd3b4f1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Mon, 12 Nov 2012 22:37:10 +0100 Subject: [PATCH 04/25] Check if the rule command has enough arguments --- src/rules.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rules.c b/src/rules.c index 5d18dc2..ecacb79 100644 --- a/src/rules.c +++ b/src/rules.c @@ -294,6 +294,9 @@ static void rule_add_consequence(HSRule* rule, HSConsequence* cons) { int rule_add_command(int argc, char** argv, GString* output) { // usage: rule COND=VAL ... then + if (argc < 2) { + return HERBST_NEED_MORE_ARGS; + } // temporary data structures HSRule* rule = rule_create(); HSCondition* cond; -- 1.8.0
From 61dd09acf5fdcad7651e54626214b05e658296ed Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Mon, 12 Nov 2012 17:30:13 +0100 Subject: [PATCH 05/25] Return status code in key_remove_bind_with_keysym --- src/key.c | 5 +++-- src/key.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/key.c b/src/key.c index 2d59c41..af7b8b7 100644 --- a/src/key.c +++ b/src/key.c @@ -210,19 +210,20 @@ int keyunbind(int argc, char** argv, GString* output) { return 0; } -void key_remove_bind_with_keysym(unsigned int modifiers, KeySym keysym){ +int key_remove_bind_with_keysym(unsigned int modifiers, KeySym keysym){ KeyBinding bind; bind.modifiers = modifiers; bind.keysym = keysym; // search this keysym in list and remove it GList* element = g_list_find_custom(g_key_binds, &bind, (GCompareFunc)keysym_equals); if (!element) { - return; + return 1; } KeyBinding* data = element->data; keybinding_free(data); g_key_binds = g_list_remove_link(g_key_binds, element); g_list_free_1(element); + return 0; } void regrab_keys() { diff --git a/src/key.h b/src/key.h index 7a274f0..9e017cb 100644 --- a/src/key.h +++ b/src/key.h @@ -29,7 +29,7 @@ int keyunbind(int argc, char** argv, GString* output); //removes a keybinding void keybinding_free(KeyBinding* binding); int key_list_binds(int argc, char** argv, GString* output); -void key_remove_bind_with_keysym(unsigned int modifiers, KeySym sym); +int key_remove_bind_with_keysym(unsigned int modifiers, KeySym sym); void key_remove_all_binds(); GString* keybinding_to_g_string(KeyBinding* binding); void key_find_binds(char* needle, GString* output); -- 1.8.0
From e15dd2c748320ac38faf0dae1beecadaeb85867e Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 14:41:45 +0100 Subject: [PATCH 06/25] Add error message when an unbound key is unbinded --- src/key.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/key.c b/src/key.c index af7b8b7..6d541e6 100644 --- a/src/key.c +++ b/src/key.c @@ -205,7 +205,10 @@ int keyunbind(int argc, char** argv, GString* output) { "%s: No such KeySym/modifier!\n", argv[0]); return HERBST_INVALID_ARGUMENT; } - key_remove_bind_with_keysym(modifiers, keysym); + if (key_remove_bind_with_keysym(modifiers, keysym) != 0) { + g_string_append_printf(output, + "%s: Key \"%s\" is not bound!\n", argv[0], argv[1]); + } regrab_keys(); return 0; } -- 1.8.0
From 60ef324f4381c46bdb845e22a29000082071ebf1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Wed, 14 Nov 2012 18:57:13 +0100 Subject: [PATCH 07/25] split: print error message if alignment is invalid --- src/layout.c | 10 ++++++++-- src/layout.h | 2 +- src/main.c | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/layout.c b/src/layout.c index 36f1a5e..0ef9d19 100644 --- a/src/layout.c +++ b/src/layout.c @@ -1145,7 +1145,7 @@ void frame_split(HSFrame* frame, int align, int fraction) { frame->content.layout.fraction = fraction; } -int frame_split_command(int argc, char** argv) { +int frame_split_command(int argc, char** argv, GString* output) { // usage: split h|v FRACTION if (argc < 3) { return HERBST_NEED_MORE_ARGS; @@ -1153,7 +1153,13 @@ int frame_split_command(int argc, char** argv) { int align = ALIGN_VERTICAL; if (argv[1][0] == 'h') { align = ALIGN_HORIZONTAL; - } // else: layout is vertical + } else if (argv[1][0] == 'v') { + align = ALIGN_VERTICAL; + } else { + g_string_append_printf(output, + "%s: invalid alignment \"%s\"\n", argv[0], argv[1]); + return HERBST_INVALID_ARGUMENT; + } int fraction = FRACTION_UNIT* CLAMP(atof(argv[2]), 0.0 + FRAME_MIN_FRACTION, 1.0 - FRAME_MIN_FRACTION); diff --git a/src/layout.h b/src/layout.h index 9503a3f..ebb2882 100644 --- a/src/layout.h +++ b/src/layout.h @@ -108,7 +108,7 @@ bool frame_remove_window(HSFrame* frame, Window window); // YOU have to g_free the resulting window-buf void frame_destroy(HSFrame* frame, Window** buf, size_t* count); void frame_split(HSFrame* frame, int align, int fraction); -int frame_split_command(int argc, char** argv); +int frame_split_command(int argc, char** argv, GString* output); int frame_change_fraction_command(int argc, char** argv, GString* output); void frame_apply_layout(HSFrame* frame, XRectangle rect); diff --git a/src/main.c b/src/main.c index a473a65..6cce92c 100644 --- a/src/main.c +++ b/src/main.c @@ -107,7 +107,7 @@ CommandBinding g_commands[] = { CMD_BIND( "cycle_layout", frame_current_cycle_client_layout), CMD_BIND_NO_OUTPUT( "close", window_close_current), CMD_BIND_NO_OUTPUT( "close_or_remove",close_or_remove_command), - CMD_BIND_NO_OUTPUT( "split", frame_split_command), + CMD_BIND( "split", frame_split_command), CMD_BIND( "resize", frame_change_fraction_command), CMD_BIND_NO_OUTPUT( "focus", frame_focus_command), CMD_BIND_NO_OUTPUT( "shift", frame_move_window_command), -- 1.8.0
From c1d6b8d21603aed0f6d6ca93d68e15f57324bb58 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Wed, 14 Nov 2012 19:14:39 +0100 Subject: [PATCH 08/25] Print error when frame neighbours are missing --- src/layout.c | 17 +++++++++++++---- src/layout.h | 4 ++-- src/main.c | 4 ++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/layout.c b/src/layout.c index 0ef9d19..259d888 100644 --- a/src/layout.c +++ b/src/layout.c @@ -1207,8 +1207,9 @@ int frame_change_fraction_command(int argc, char** argv, GString* output) { } neighbour = frame_neighbour(g_cur_frame, direction); if (!neighbour) { - // nothing to do - return 0; + g_string_append_printf(output, + "%s: No neighbour found!", argv[0]); + return HERBST_FORBIDDEN; } } HSFrame* parent = neighbour->parent; @@ -1326,7 +1327,7 @@ int frame_inner_neighbour_index(HSFrame* frame, char direction) { return index; } -int frame_focus_command(int argc, char** argv) { +int frame_focus_command(int argc, char** argv, GString* output) { // usage: focus [-e|-i] left|right|up|down if (argc < 2) return HERBST_NEED_MORE_ARGS; if (!g_cur_frame) { @@ -1361,12 +1362,16 @@ int frame_focus_command(int argc, char** argv) { // change focus if possible frame_focus_recursive(parent); monitor_apply_layout(get_current_monitor()); + } else { + g_string_append_printf(output, + "%s: No neighbour found!", argv[0]); + return HERBST_FORBIDDEN; } } return 0; } -int frame_move_window_command(int argc, char** argv) { +int frame_move_window_command(int argc, char** argv, GString* output) { // usage: move left|right|up|down if (argc < 2) return HERBST_NEED_MORE_ARGS; if (!g_cur_frame) { @@ -1429,6 +1434,10 @@ int frame_move_window_command(int argc, char** argv) { } // layout was changed, so update it monitor_apply_layout(get_current_monitor()); + } else { + g_string_append_printf(output, + "%s: No neighbour found!", argv[0]); + return HERBST_FORBIDDEN; } } return 0; diff --git a/src/layout.h b/src/layout.h index ebb2882..f09a07f 100644 --- a/src/layout.h +++ b/src/layout.h @@ -138,7 +138,7 @@ void frame_unfocus(); // unfocus currently focused window // returns the neighbour or NULL if there is no one HSFrame* frame_neighbour(HSFrame* frame, char direction); int frame_inner_neighbour_index(HSFrame* frame, char direction); -int frame_focus_command(int argc, char** argv); +int frame_focus_command(int argc, char** argv, GString* output); // follow selection to leave and focus this frame int frame_focus_recursive(HSFrame* frame); @@ -163,7 +163,7 @@ Window frame_focused_window(HSFrame* frame); bool frame_focus_window(HSFrame* frame, Window win); bool focus_window(Window win, bool switch_tag, bool switch_monitor); // moves a window to an other frame -int frame_move_window_command(int argc, char** argv); +int frame_move_window_command(int argc, char** argv, GString* output); /// removes the current frame int frame_remove_command(int argc, char** argv); int close_or_remove_command(int argc, char** argv); diff --git a/src/main.c b/src/main.c index 6cce92c..455d800 100644 --- a/src/main.c +++ b/src/main.c @@ -109,8 +109,8 @@ CommandBinding g_commands[] = { CMD_BIND_NO_OUTPUT( "close_or_remove",close_or_remove_command), CMD_BIND( "split", frame_split_command), CMD_BIND( "resize", frame_change_fraction_command), - CMD_BIND_NO_OUTPUT( "focus", frame_focus_command), - CMD_BIND_NO_OUTPUT( "shift", frame_move_window_command), + CMD_BIND( "focus", frame_focus_command), + CMD_BIND( "shift", frame_move_window_command), CMD_BIND_NO_OUTPUT( "remove", frame_remove_command), CMD_BIND( "set", settings_set_command), CMD_BIND( "toggle", settings_toggle), -- 1.8.0
From 897f49168092d1706747abcbae96bc40a30d089f Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Wed, 14 Nov 2012 19:21:38 +0100 Subject: [PATCH 09/25] bring: add error message when client is invalid --- src/layout.c | 9 ++++++++- src/layout.h | 2 +- src/main.c | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/layout.c b/src/layout.c index 259d888..2e016a7 100644 --- a/src/layout.c +++ b/src/layout.c @@ -889,11 +889,18 @@ HSFrame* frame_current_selection() { return frame; } -int frame_current_bring(int argc, char** argv) { +int frame_current_bring(int argc, char** argv, GString* output) { HSClient* client = NULL; string_to_client((argc > 1) ? argv[1] : "", &client); if (!client) { + g_string_append_printf(output, + "%s: error: Could not find client", argv[0]); + if (argc > 1) { + g_string_append_printf(output, " \"%s\".\n", argv[1]); + } else { + g_string_append(output, ".\n"); + } return HERBST_INVALID_ARGUMENT; } tag_move_client(client, get_current_monitor()->tag); diff --git a/src/layout.h b/src/layout.h index f09a07f..1336343 100644 --- a/src/layout.h +++ b/src/layout.h @@ -127,7 +127,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_bring(int argc, char** argv, GString* output); 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 455d800..1fda630 100644 --- a/src/main.c +++ b/src/main.c @@ -100,7 +100,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( "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.8.0
From c3119791571d0e39f1dd7b04adcf9ef88ccab3ac Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Wed, 14 Nov 2012 20:45:32 +0100 Subject: [PATCH 10/25] Make arguments mandatory in jumpto/bring When jumpto/bring were called without an argument, they defaulted to "currently focused client", but that doesn't make sense with these commands. --- src/layout.c | 5 ++++- src/main.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/layout.c b/src/layout.c index 2e016a7..bba2f78 100644 --- a/src/layout.c +++ b/src/layout.c @@ -892,7 +892,10 @@ HSFrame* frame_current_selection() { int frame_current_bring(int argc, char** argv, GString* output) { HSClient* client = NULL; - string_to_client((argc > 1) ? argv[1] : "", &client); + if (argc < 2) { + return HERBST_NEED_MORE_ARGS; + } + string_to_client(argv[1], &client); if (!client) { g_string_append_printf(output, "%s: error: Could not find client", argv[0]); diff --git a/src/main.c b/src/main.c index 1fda630..1dc8e0d 100644 --- a/src/main.c +++ b/src/main.c @@ -346,9 +346,12 @@ int wmexec(int argc, char** argv) { } int raise_command(int argc, char** argv) { + if (argc < 2) { + return HERBST_NEED_MORE_ARGS; + } Window win; HSClient* client = NULL; - win = string_to_client((argc > 1) ? argv[1] : "", &client); + win = string_to_client(argv[1], &client); if (client) { client_raise(client); } else { @@ -358,8 +361,11 @@ int raise_command(int argc, char** argv) { } int jumpto_command(int argc, char** argv, GString* output) { + if (argc < 2) { + return HERBST_NEED_MORE_ARGS; + } HSClient* client = NULL; - string_to_client((argc > 1) ? argv[1] : "", &client); + string_to_client(argv[1], &client); if (client) { focus_window(client->window, true, true); return 0; -- 1.8.0
From a6c4ebb2b86954cf4cfeb9f99f244fbac1abd8dd Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 07:01:34 +0100 Subject: [PATCH 11/25] Print help when there are no hc-arguments --- ipc-client/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ipc-client/main.c b/ipc-client/main.c index 3f57db7..49f3367 100644 --- a/ipc-client/main.c +++ b/ipc-client/main.c @@ -185,6 +185,12 @@ int main(int argc, char* argv[]) { } } int arg_index = optind; // index of the first-non-option argument + if ((argc - arg_index == 0) && !g_wait_for_hook) { + // if there are no non-option arguments, and no --idle/--wait, display + // the help and exit + print_help(argv[0]); + exit(EXIT_FAILURE); + } // do communication int command_status; if (g_wait_for_hook == 1) { -- 1.8.0
From f77144993a18db82fd250a0df21b5ed1bb1faced Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 19:29:49 +0100 Subject: [PATCH 12/25] Cleanup of error messages - Don't display "error:" anywhere - Use argv[0] where possible - If argv[0] is not possible, display function-name hardcoded - Capitalize first letter after colon - Some rewording - Always print a newline after output - Don't print a exclamation mark at the end - Whitespace fixes --- src/command.c | 2 +- src/key.c | 8 ++++---- src/layout.c | 24 ++++++++++++------------ src/main.c | 16 ++++++++-------- src/monitor.c | 30 +++++++++++++++--------------- src/mouse.c | 6 +++--- src/rules.c | 16 ++++++++-------- src/settings.c | 8 ++++---- src/tag.c | 16 ++++++++-------- 9 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/command.c b/src/command.c index 7d1869c..9a892b4 100644 --- a/src/command.c +++ b/src/command.c @@ -212,7 +212,7 @@ int call_command(int argc, char** argv, GString* output) { } if (!bind) { g_string_append_printf(output, - "error: Command \"%s\" not found!\n", argv[0]); + "error: Command \"%s\" not found\n", argv[0]); return HERBST_COMMAND_NOT_FOUND; } int status; diff --git a/src/key.c b/src/key.c index 6d541e6..15e926b 100644 --- a/src/key.c +++ b/src/key.c @@ -100,13 +100,13 @@ int keybind(int argc, char** argv, GString* output) { // get keycode if (!string2key(argv[1], &(new_bind.modifiers), &(new_bind.keysym))) { g_string_append_printf(output, - "%s: No such KeySym/modifier!\n", argv[0]); + "%s: No such KeySym/modifier\n", argv[0]); return HERBST_INVALID_ARGUMENT; } KeyCode keycode = XKeysymToKeycode(g_display, new_bind.keysym); if (!keycode) { g_string_append_printf(output, - "%s: no keycode for symbol %s\n", + "%s: No keycode for symbol %s\n", argv[0], XKeysymToString(new_bind.keysym)); return HERBST_INVALID_ARGUMENT; } @@ -202,12 +202,12 @@ int keyunbind(int argc, char** argv, GString* output) { // get keycode if (!string2key(argv[1], &modifiers, &keysym)) { g_string_append_printf(output, - "%s: No such KeySym/modifier!\n", argv[0]); + "%s: No such KeySym/modifier\n", argv[0]); return HERBST_INVALID_ARGUMENT; } if (key_remove_bind_with_keysym(modifiers, keysym) != 0) { g_string_append_printf(output, - "%s: Key \"%s\" is not bound!\n", argv[0], argv[1]); + "%s: Key \"%s\" is not bound\n", argv[0], argv[1]); } regrab_keys(); return 0; diff --git a/src/layout.c b/src/layout.c index bba2f78..dced9d3 100644 --- a/src/layout.c +++ b/src/layout.c @@ -345,7 +345,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { if (3 != sscanf(args, "%[^"SEP"]"SEP"%lf"SEP"%d", align_name, &fraction_double, &selection)) { g_string_append_printf(errormsg, - "cannot parse frame args \"%s\"\n", args); + "load: Can not parse frame args \"%s\"\n", args); return NULL; } #undef SEP @@ -353,7 +353,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { g_free(align_name); if (align < 0) { g_string_append_printf(errormsg, - "invalid align name in args \"%s\"\n", args); + "load: Invalid align name in args \"%s\"\n", args); return NULL; } selection = !!selection; // CLAMP it to [0;1] @@ -368,7 +368,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { frame_split(frame, align, fraction); if (frame->type != TYPE_FRAMES) { g_string_append_printf(errormsg, - "cannot split frame"); + "load: Can not split frame\n"); return NULL; } } @@ -389,7 +389,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { if (2 != sscanf(args, "%[^"SEP"]"SEP"%d", layout_name, &selection)) { g_string_append_printf(errormsg, - "cannot parse frame args \"%s\"\n", args); + "load: Can not parse frame args \"%s\"\n", args); return NULL; } #undef SEP @@ -397,7 +397,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { g_free(layout_name); if (layout < 0) { g_string_append_printf(errormsg, - "cannot parse layout from args \"%s\"\n", args); + "load: Can not parse layout from args \"%s\"\n", args); return NULL; } @@ -434,7 +434,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { Window win; if (1 != sscanf(description, "0x%lx\n", &win)) { g_string_append_printf(errormsg, - "cannot parse window id from \"%s\"\n", description); + "load: Can not parse window id from \"%s\"\n", description); return NULL; } // jump over window id and over whitespaces @@ -642,7 +642,7 @@ int frame_current_set_client_layout(int argc, char** argv, GString* output) { layout = find_layout_by_name(argv[1]); if (layout < 0) { g_string_append_printf(output, - "%s: invalid layout name \"%s\"\n", argv[0], argv[1]); + "%s: Invalid layout name \"%s\"\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } if (g_cur_frame && g_cur_frame->type == TYPE_CLIENTS) { @@ -898,7 +898,7 @@ int frame_current_bring(int argc, char** argv, GString* output) { string_to_client(argv[1], &client); if (!client) { g_string_append_printf(output, - "%s: error: Could not find client", argv[0]); + "%s: Could not find client", argv[0]); if (argc > 1) { g_string_append_printf(output, " \"%s\".\n", argv[1]); } else { @@ -1167,7 +1167,7 @@ int frame_split_command(int argc, char** argv, GString* output) { align = ALIGN_VERTICAL; } else { g_string_append_printf(output, - "%s: invalid alignment \"%s\"\n", argv[0], argv[1]); + "%s: Invalid alignment \"%s\"\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } int fraction = FRACTION_UNIT* CLAMP(atof(argv[2]), @@ -1218,7 +1218,7 @@ int frame_change_fraction_command(int argc, char** argv, GString* output) { neighbour = frame_neighbour(g_cur_frame, direction); if (!neighbour) { g_string_append_printf(output, - "%s: No neighbour found!", argv[0]); + "%s: No neighbour found\n", argv[0]); return HERBST_FORBIDDEN; } } @@ -1374,7 +1374,7 @@ int frame_focus_command(int argc, char** argv, GString* output) { monitor_apply_layout(get_current_monitor()); } else { g_string_append_printf(output, - "%s: No neighbour found!", argv[0]); + "%s: No neighbour found\n", argv[0]); return HERBST_FORBIDDEN; } } @@ -1446,7 +1446,7 @@ int frame_move_window_command(int argc, char** argv, GString* output) { monitor_apply_layout(get_current_monitor()); } else { g_string_append_printf(output, - "%s: No neighbour found!", argv[0]); + "%s: No neighbour found\n", argv[0]); return HERBST_FORBIDDEN; } } diff --git a/src/main.c b/src/main.c index 1dc8e0d..5b27526 100644 --- a/src/main.c +++ b/src/main.c @@ -187,7 +187,7 @@ int print_layout_command(int argc, char** argv, GString* output) { tag = find_tag(argv[1]); if (!tag) { g_string_append_printf(output, - "%s: error: tag \"%s\" not found!\n", argv[0], argv[1]); + "%s: Tag \"%s\" not found\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } } else { // use current tag @@ -215,7 +215,7 @@ int load_command(int argc, char** argv, GString* output) { layout_string = argv[2]; if (!tag) { g_string_append_printf(output, - "load_command: error: tag \"%s\" not found!\n", argv[1]); + "%s: Tag \"%s\" not found\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } } else { // use current tag @@ -238,12 +238,12 @@ int load_command(int argc, char** argv, GString* output) { } if (!rest) { g_string_append_printf(output, - "%s: layout \"%s\" unknown\n", argv[0], layout_string); + "%s: Layout \"%s\" unknown\n", argv[0], layout_string); return HERBST_INVALID_ARGUMENT; } if (rest[0] != '\0') { // if string was not parsed completely g_string_append_printf(output, - "%s: layout description was too long\n", argv[0]); + "%s: Layout description was too long\n", argv[0]); g_string_append_printf(output, "%s: \"%s\" has not been parsed\n", argv[0], rest); return HERBST_INVALID_ARGUMENT; @@ -371,7 +371,7 @@ int jumpto_command(int argc, char** argv, GString* output) { return 0; } else { g_string_append_printf(output, - "%s: error: Could not find client", argv[0]); + "%s: Could not find client", argv[0]); if (argc > 1) { g_string_append_printf(output, " \"%s\".\n", argv[1]); } else { @@ -388,7 +388,7 @@ int getenv_command(int argc, char** argv, GString* output) { char* envvar = getenv(argv[1]); if (envvar == NULL) { g_string_append_printf(output, - "Environment variable \"%s\" is not set!\n", argv[1]); + "%s: Environment variable \"%s\" is not set\n", argv[0], argv[1]); return HERBST_ENV_UNSET; } g_string_append_printf(output, "%s\n", envvar); @@ -401,7 +401,7 @@ int setenv_command(int argc, char** argv, GString* output) { } if (setenv(argv[1], argv[2], 1) != 0) { g_string_append_printf(output, - "Could not set environment variable: %s\n", strerror(errno)); + "%s: Could not set environment variable: %s\n", argv[0], strerror(errno)); return HERBST_UNKNOWN_ERROR; } return 0; @@ -413,7 +413,7 @@ int unsetenv_command(int argc, char** argv, GString* output) { } if (unsetenv(argv[1]) != 0) { g_string_append_printf(output, - "Could not unset environment variable: %s\n", strerror(errno)); + "%s: Could not unset environment variable: %s\n", argv[0], strerror(errno)); return HERBST_UNKNOWN_ERROR; } return 0; diff --git a/src/monitor.c b/src/monitor.c index 90fdb67..b641a3d 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -285,7 +285,7 @@ int set_monitor_rects_command(int argc, char** argv, GString* output) { g_free(templates); if (status == HERBST_TAG_IN_USE) { g_string_append_printf(output, - "%s: there are not enough free tags!\n", argv[0]); + "%s: There are not enough free tags\n", argv[0]); } return status; } @@ -344,7 +344,7 @@ int add_monitor_command(int argc, char** argv, GString* output) { tag = find_unused_tag(); if (!tag) { g_string_append_printf(output, - "%s: there are not enough free tags!\n", argv[0]); + "%s: There are not enough free tags\n", argv[0]); return HERBST_TAG_IN_USE; } } @@ -352,13 +352,13 @@ int add_monitor_command(int argc, char** argv, GString* output) { tag = find_tag(argv[2]); if (!tag) { g_string_append_printf(output, - "%s: The tag \"%s\" does not exist!\n", argv[0], argv[2]); + "%s: The tag \"%s\" does not exist\n", argv[0], argv[2]); return HERBST_INVALID_ARGUMENT; } } if (find_monitor_with_tag(tag)) { g_string_append_printf(output, - "%s: The tag \"%s\" is already viewed on a monitor!\n", argv[0], argv[2]); + "%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); @@ -422,13 +422,13 @@ int move_monitor_command(int argc, char** argv, GString* output) { int index = atoi(argv[1]); if (index < 0 || index >= g_monitors->len) { g_string_append_printf(output, - "%s: index %i is out of range!\n", argv[0], index); + "%s: Index %i is out of range\n", argv[0], index); return HERBST_INVALID_ARGUMENT; } XRectangle rect = parse_rectangle(argv[2]); if (rect.width < WINDOW_MIN_WIDTH || rect.height < WINDOW_MIN_HEIGHT) { g_string_append_printf(output, - "%s: rectangle is too small!\n", argv[0]); + "%s: Rectangle is too small\n", argv[0]); return HERBST_INVALID_ARGUMENT; } // else: just move it: @@ -459,7 +459,7 @@ int monitor_rect_command(int argc, char** argv, GString* output) { with_pad = true; } else { g_string_append_printf(output, - "%s: invalid argument \"%s\"\n", argv[0], argv[1]); + "%s: Invalid argument \"%s\"\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } } @@ -470,7 +470,7 @@ int monitor_rect_command(int argc, char** argv, GString* output) { m = monitor_with_index(index); if (!m) { g_string_append_printf(output, - "%s: invalid index \"%s\"\n", argv[0], index_str); + "%s: Invalid index \"%s\"\n", argv[0], index_str); return HERBST_INVALID_ARGUMENT; } } @@ -498,7 +498,7 @@ int monitor_set_pad_command(int argc, char** argv, GString* output) { int index = atoi(argv[1]); if (index < 0 || index >= g_monitors->len) { g_string_append_printf(output, - "%s: index %i is out of range!\n", argv[0], index); + "%s: Index %i is out of range\n", argv[0], index); return HERBST_INVALID_ARGUMENT; } HSMonitor* monitor = monitor_with_index(index); @@ -644,7 +644,7 @@ int monitor_set_tag_command(int argc, char** argv, GString* output) { return 0; } else { g_string_append_printf(output, - "%s: Invalid monitor or tag!\n", argv[0]); + "%s: Invalid monitor or tag\n", argv[0]); return HERBST_INVALID_ARGUMENT; } } @@ -660,7 +660,7 @@ int monitor_set_tag_by_index_command(int argc, char** argv, GString* output) { HSTag* tag = get_tag_by_index_str(argv[1], skip_visible); if (!tag) { g_string_append_printf(output, - "%s: Invalid index \"%s\"!\n", argv[0], argv[1]); + "%s: Invalid index \"%s\"\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } monitor_set_tag(get_current_monitor(), tag); @@ -841,7 +841,7 @@ int monitor_lock_tag_command(int argc, char** argv, GString* output) { } if (!monitor) { g_string_append_printf(output, - "%s: Invalid monitor!\n", argv[0]); + "%s: Invalid monitor\n", argv[0]); return HERBST_INVALID_ARGUMENT; } monitor->lock_tag = true; @@ -858,7 +858,7 @@ int monitor_unlock_tag_command(int argc, char** argv, GString* output) { } if (!monitor) { g_string_append_printf(output, - "%s: Invalid monitor!\n", argv[0]); + "%s: Invalid monitor\n", argv[0]); return HERBST_INVALID_ARGUMENT; } monitor->lock_tag = false; @@ -949,7 +949,7 @@ int detect_monitors_command(int argc, char **argv, GString* output) { g_free(monitors); if (ret == HERBST_TAG_IN_USE && output != NULL) { g_string_append_printf(output, - "%s: there are not enough free tags!\n", argv[0]); + "%s: There are not enough free tags\n", argv[0]); } return ret; } @@ -976,7 +976,7 @@ int monitor_raise_command(int argc, char** argv, GString* output) { } if (!monitor) { g_string_append_printf(output, - "%s: Invalid monitor!\n", argv[0]); + "%s: Invalid monitor\n", argv[0]); return HERBST_INVALID_ARGUMENT; } stack_raise_slide(g_monitor_stack, monitor->slice); diff --git a/src/mouse.c b/src/mouse.c index dac1c9e..b2da143 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -163,7 +163,7 @@ int mouse_bind_command(int argc, char** argv, GString* output) { char* string = argv[1]; if (!string2modifiers(string, &modifiers)) { g_string_append_printf(output, - "%s: Modifier \"%s\" does not exist!\n", argv[0], string); + "%s: Modifier \"%s\" does not exist\n", argv[0], string); return HERBST_INVALID_ARGUMENT; } // last one is the mouse button @@ -171,13 +171,13 @@ int mouse_bind_command(int argc, char** argv, GString* output) { unsigned int button = string2button(last_token); if (button == 0) { g_string_append_printf(output, - "%s: Unknown mouse button \"%s\"!\n", argv[0], last_token); + "%s: Unknown mouse button \"%s\"\n", argv[0], last_token); return HERBST_INVALID_ARGUMENT; } MouseFunction function = string2mousefunction(argv[2]); if (!function) { g_string_append_printf(output, - "%s: Unknown mouse action \"%s\"!\n", argv[0], argv[2]); + "%s: Unknown mouse action \"%s\"\n", argv[0], argv[2]); return HERBST_INVALID_ARGUMENT; } mouse_bind_function(modifiers, button, function); diff --git a/src/rules.c b/src/rules.c index ecacb79..831f91f 100644 --- a/src/rules.c +++ b/src/rules.c @@ -118,7 +118,7 @@ HSCondition* condition_create(int type, char op, char* value, GString* output) { HSCondition cond; if (op != '=' && type == g_maxage_type) { g_string_append_printf(output, - "condition maxage only supports the = operator\n"); + "rule: Condition maxage only supports the = operator\n"); return NULL; } switch (op) { @@ -127,7 +127,7 @@ HSCondition* condition_create(int type, char op, char* value, GString* output) { cond.value_type = CONDITION_VALUE_TYPE_INTEGER; if (1 != sscanf(value, "%d", &cond.value.integer)) { g_string_append_printf(output, - "cannot integer from \"%s\"\n", value); + "rule: Can not integer from \"%s\"\n", value); return NULL; } } else { @@ -143,7 +143,7 @@ HSCondition* condition_create(int type, char op, char* value, GString* output) { char buf[ERROR_STRING_BUF_SIZE]; regerror(status, &cond.value.exp, buf, ERROR_STRING_BUF_SIZE); g_string_append_printf(output, - "Cannot parse value \"%s\" from condition \"%s\": \"%s\"\n", + "rule: Can not parse value \"%s\" from condition \"%s\": \"%s\"\n", value, g_condition_types[type].name, buf); return NULL; } @@ -151,7 +151,7 @@ HSCondition* condition_create(int type, char op, char* value, GString* output) { default: g_string_append_printf(output, - "unknown rule condition operation \"%c\"\n", op); + "rule: Unknown rule condition operation \"%c\"\n", op); return NULL; break; } @@ -206,7 +206,7 @@ HSConsequence* consequence_create(int type, char op, char* value, GString* outpu default: g_string_append_printf(output, - "unknown rule consequence operation \"%c\"\n", op); + "rule: Unknown rule consequence operation \"%c\"\n", op); return NULL; break; } @@ -300,7 +300,7 @@ int rule_add_command(int argc, char** argv, GString* output) { // temporary data structures HSRule* rule = rule_create(); HSCondition* cond; - HSConsequence* cons; + HSConsequence* cons; bool negated = false; struct { char* name; @@ -357,7 +357,7 @@ int rule_add_command(int argc, char** argv, GString* output) { else { // need to hardcode "rule:" here because args are shifted g_string_append_printf(output, - "rule: unknown argument \"%s\"\n", *argv); + "rule: Unknown argument \"%s\"\n", *argv); return HERBST_INVALID_ARGUMENT; } } @@ -382,7 +382,7 @@ int rule_remove_command(int argc, char** argv, GString* output) { } g_string_append_printf(output, - "%s: this command must be used with --all/-F for the time being\n", argv[0]); + "%s: This command must be used with --all/-F\n", argv[0]); return HERBST_INVALID_ARGUMENT; } diff --git a/src/settings.c b/src/settings.c index fd0e5d2..e79afab 100644 --- a/src/settings.c +++ b/src/settings.c @@ -122,7 +122,7 @@ int settings_set_command(int argc, char** argv, GString* output) { if (!pair) { if (output != NULL) { g_string_append_printf(output, - "%s: setting \"%s\" not found!\n", argv[0], argv[1]); + "%s: Setting \"%s\" not found\n", argv[0], argv[1]); } return HERBST_SETTING_NOT_FOUND; } @@ -164,7 +164,7 @@ int settings_get(int argc, char** argv, GString* output) { SettingsPair* pair = settings_find(argv[1]); if (!pair) { g_string_append_printf(output, - "%s: setting \"%s\" not found!\n", argv[0], argv[1]); + "%s: Setting \"%s\" not found\n", argv[0], argv[1]); return HERBST_SETTING_NOT_FOUND; } if (pair->type == HS_Int) { @@ -183,7 +183,7 @@ int settings_toggle(int argc, char** argv, GString* output) { SettingsPair* pair = settings_find(argv[1]); if (!pair) { g_string_append_printf(output, - "%s: setting \"%s\" not found!\n", argv[0], argv[1]); + "%s: Setting \"%s\" not found\n", argv[0], argv[1]); return HERBST_SETTING_NOT_FOUND; } if (pair->type == HS_Int) { @@ -222,7 +222,7 @@ int settings_cycle_value(int argc, char** argv, GString* output) { SettingsPair* pair = settings_find(argv[1]); if (!pair) { g_string_append_printf(output, - "%s: setting \"%s\" not found!", argv[0], argv[1]); + "%s: Setting \"%s\" not found\n", argv[0], argv[1]); return HERBST_SETTING_NOT_FOUND; } (void)SHIFT(argc, argv); diff --git a/src/tag.c b/src/tag.c index c7524a2..18d4e0d 100644 --- a/src/tag.c +++ b/src/tag.c @@ -161,12 +161,12 @@ int tag_rename_command(int argc, char** argv, GString* output) { HSTag* tag = find_tag(argv[1]); if (!tag) { g_string_append_printf(output, - "%s: Tag \"%s\" not found!\n", argv[0], argv[1]); + "%s: Tag \"%s\" not found\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } if (find_tag(argv[2])) { g_string_append_printf(output, - "%s: Tag \"%s\" already exists!\n", argv[0], argv[2]); + "%s: Tag \"%s\" already exists\n", argv[0], argv[2]); return HERBST_TAG_IN_USE; } g_string_assign(tag->name, argv[2]); @@ -186,21 +186,21 @@ int tag_remove_command(int argc, char** argv, GString* output) { HSTag* target = (argc >= 3) ? find_tag(argv[2]) : get_current_monitor()->tag; if (!tag) { g_string_append_printf(output, - "%s: Tag \"%s\" not found!\n", argv[0], argv[1]); + "%s: Tag \"%s\" not found\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } else if (!target) { g_string_append_printf(output, - "%s: Tag \"%s\" not found!\n", argv[0], argv[2]); + "%s: Tag \"%s\" not found\n", argv[0], argv[2]); } else if (tag == target) { g_string_append_printf(output, - "%s: Cannot merge tag \"%s\" into itself!\n", argv[0], argv[1]); + "%s: Cannot merge tag \"%s\" into itself\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } HSMonitor* monitor = find_monitor_with_tag(tag); HSMonitor* monitor_target = find_monitor_with_tag(target); if (monitor) { g_string_append_printf(output, - "%s: Cannot merge the currently viewed tag!\n", argv[0]); + "%s: Cannot merge the currently viewed tag\n", argv[0]); return HERBST_TAG_IN_USE; } // save all these windows @@ -251,7 +251,7 @@ int tag_set_floating_command(int argc, char** argv, GString* output) { action = argv[2]; if (!tag) { g_string_append_printf(output, - "%s: Tag \"%s\" not found!\n", argv[0], argv[1]); + "%s: Tag \"%s\" not found\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } } @@ -336,7 +336,7 @@ int tag_move_window_command(int argc, char** argv, GString* output) { HSTag* target = find_tag(argv[1]); if (!target) { g_string_append_printf(output, - "%s: Tag \"%s\" not found!\n", argv[0], argv[1]); + "%s: Tag \"%s\" not found\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } tag_move_focused_client(target); -- 1.8.0
From 01c210daa1502610c10c4ff39f23ed09db9ac612 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 21:30:17 +0100 Subject: [PATCH 13/25] Add an error message if "raise" can't find client --- src/main.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 5b27526..b8e9ed8 100644 --- a/src/main.c +++ b/src/main.c @@ -55,7 +55,7 @@ int print_layout_command(int argc, char** argv, GString* output); int load_command(int argc, char** argv, GString* output); int print_tag_status_command(int argc, char** argv, GString* output); void execute_autostart_file(); -int raise_command(int argc, char** argv); +int raise_command(int argc, char** argv, GString* output); int spawn(int argc, char** argv); int wmexec(int argc, char** argv); static void remove_zombies(int signal); @@ -137,7 +137,7 @@ CommandBinding g_commands[] = { CMD_BIND( "move_monitor", move_monitor_command), CMD_BIND( "monitor_rect", monitor_rect_command), CMD_BIND( "pad", monitor_set_pad_command), - CMD_BIND_NO_OUTPUT( "raise", raise_command), + CMD_BIND( "raise", raise_command), CMD_BIND( "rule", rule_add_command), CMD_BIND( "unrule", rule_remove_command), CMD_BIND( "layout", print_layout_command), @@ -345,7 +345,7 @@ int wmexec(int argc, char** argv) { return EXIT_SUCCESS; } -int raise_command(int argc, char** argv) { +int raise_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } @@ -354,6 +354,14 @@ int raise_command(int argc, char** argv) { win = string_to_client(argv[1], &client); if (client) { client_raise(client); + } else if (win == 0) { + g_string_append_printf(output, + "%s: Could not find client", argv[0]); + if (argc > 1) { + g_string_append_printf(output, " \"%s\".\n", argv[1]); + } else { + g_string_append(output, ".\n"); + } } else { XRaiseWindow(g_display, win); } -- 1.8.0
From 11ad15af5889b36cd64076c4117e15f3a7d45e3b Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 21:42:24 +0100 Subject: [PATCH 14/25] Add error messages for remove_monitor --- src/main.c | 2 +- src/monitor.c | 12 ++++++++++-- src/monitor.h | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index b8e9ed8..0373380 100644 --- a/src/main.c +++ b/src/main.c @@ -133,7 +133,7 @@ CommandBinding g_commands[] = { CMD_BIND( "move_index", tag_move_window_by_index_command), CMD_BIND( "add_monitor", add_monitor_command), CMD_BIND( "raise_monitor", monitor_raise_command), - CMD_BIND_NO_OUTPUT( "remove_monitor", remove_monitor_command), + CMD_BIND( "remove_monitor", remove_monitor_command), CMD_BIND( "move_monitor", move_monitor_command), CMD_BIND( "monitor_rect", monitor_rect_command), CMD_BIND( "pad", monitor_set_pad_command), diff --git a/src/monitor.c b/src/monitor.c index b641a3d..51e4208 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -372,13 +372,21 @@ int add_monitor_command(int argc, char** argv, GString* output) { return 0; } -int remove_monitor_command(int argc, char** argv) { +int remove_monitor_command(int argc, char** argv, GString* output) { // usage: remove_monitor INDEX if (argc < 2) { return HERBST_NEED_MORE_ARGS; } int index = atoi(argv[1]); - return remove_monitor(index); + int ret = remove_monitor(index); + if (ret == HERBST_INVALID_ARGUMENT) { + g_string_append_printf(output, + "%s: Index needs to be between 0 and %d\n", argv[0], g_monitors->len - 1); + } else if (ret == HERBST_FORBIDDEN) { + g_string_append_printf(output, + "%s: Can't remove the last monitor\n", argv[0]); + } + return ret; } int remove_monitor(int index) { diff --git a/src/monitor.h b/src/monitor.h index 212d9f9..6f268e8 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -57,7 +57,7 @@ int monitor_cycle_command(int argc, char** argv); int monitor_focus_command(int argc, char** argv); 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); +int remove_monitor_command(int argc, char** argv, GString* output); int remove_monitor(int index); int list_monitors(int argc, char** argv, GString* output); int list_padding(int argc, char** argv, GString* output); -- 1.8.0
From 091271825d84850e14805c01512be25a6b478e34 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 21:42:57 +0100 Subject: [PATCH 15/25] Add error message for set_monitors --- src/monitor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/monitor.c b/src/monitor.c index 51e4208..c560ff2 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -286,6 +286,9 @@ int set_monitor_rects_command(int argc, char** argv, GString* output) { if (status == HERBST_TAG_IN_USE) { g_string_append_printf(output, "%s: There are not enough free tags\n", argv[0]); + } else if (status == HERBST_INVALID_ARGUMENT) { + g_string_append_printf(output, + "%s: Need at least one rectangle\n", argv[0]); } return status; } -- 1.8.0
From 062dd40390219c96f837fac53abc695784409d8d Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 21:43:27 +0100 Subject: [PATCH 16/25] Add error message for toggle for non-ints --- src/settings.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/settings.c b/src/settings.c index e79afab..a62e94d 100644 --- a/src/settings.c +++ b/src/settings.c @@ -197,6 +197,8 @@ int settings_toggle(int argc, char** argv, GString* output) { } } else { // only toggle numbers + g_string_append_printf(output, + "%s: Only numbers can be toggled\n", argv[0]); return HERBST_INVALID_ARGUMENT; } // on successful change, call callback -- 1.8.0
From d0b89e551e07a0efed4050c768b875ef19c056c3 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 21:52:26 +0100 Subject: [PATCH 17/25] Add error message when setting a wrong type --- src/settings.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/settings.c b/src/settings.c index a62e94d..648c764 100644 --- a/src/settings.c +++ b/src/settings.c @@ -126,7 +126,12 @@ int settings_set_command(int argc, char** argv, GString* output) { } return HERBST_SETTING_NOT_FOUND; } - return settings_set(pair, argv[2]); + int ret = settings_set(pair, argv[2]); + if (ret == HERBST_INVALID_ARGUMENT) { + g_string_append_printf(output, + "%s: Invalid value for setting \"%s\"\n", argv[0], argv[1]); + } + return ret; } int settings_set(SettingsPair* pair, char* value) { @@ -232,6 +237,11 @@ int settings_cycle_value(int argc, char** argv, GString* output) { char** pcurrent = table_find(argv, sizeof(*argv), argc, 0, memberequals_settingspair, pair); int i = pcurrent ? ((INDEX_OF(argv, pcurrent) + 1) % argc) : 0; - return settings_set(pair, argv[i]); + int ret = settings_set(pair, argv[i]); + if (ret == HERBST_INVALID_ARGUMENT) { + g_string_append_printf(output, + "%s: Invalid value for setting \"%s\"\n", argv[0], argv[1]); + } + return ret; } -- 1.8.0
From 6e1ffc469dcbb1ceebbd69fb874a25df68ec666f Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 22:49:49 +0100 Subject: [PATCH 18/25] prepend "load: " to msgs in load_command --- src/layout.c | 12 ++++++------ src/main.c | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/layout.c b/src/layout.c index dced9d3..ec7de7d 100644 --- a/src/layout.c +++ b/src/layout.c @@ -345,7 +345,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { if (3 != sscanf(args, "%[^"SEP"]"SEP"%lf"SEP"%d", align_name, &fraction_double, &selection)) { g_string_append_printf(errormsg, - "load: Can not parse frame args \"%s\"\n", args); + "Can not parse frame args \"%s\"\n", args); return NULL; } #undef SEP @@ -353,7 +353,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { g_free(align_name); if (align < 0) { g_string_append_printf(errormsg, - "load: Invalid align name in args \"%s\"\n", args); + "Invalid align name in args \"%s\"\n", args); return NULL; } selection = !!selection; // CLAMP it to [0;1] @@ -368,7 +368,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { frame_split(frame, align, fraction); if (frame->type != TYPE_FRAMES) { g_string_append_printf(errormsg, - "load: Can not split frame\n"); + "Can not split frame\n"); return NULL; } } @@ -389,7 +389,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { if (2 != sscanf(args, "%[^"SEP"]"SEP"%d", layout_name, &selection)) { g_string_append_printf(errormsg, - "load: Can not parse frame args \"%s\"\n", args); + "Can not parse frame args \"%s\"\n", args); return NULL; } #undef SEP @@ -397,7 +397,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { g_free(layout_name); if (layout < 0) { g_string_append_printf(errormsg, - "load: Can not parse layout from args \"%s\"\n", args); + "Can not parse layout from args \"%s\"\n", args); return NULL; } @@ -434,7 +434,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { Window win; if (1 != sscanf(description, "0x%lx\n", &win)) { g_string_append_printf(errormsg, - "load: Can not parse window id from \"%s\"\n", description); + "Can not parse window id from \"%s\"\n", description); return NULL; } // jump over window id and over whitespaces diff --git a/src/main.c b/src/main.c index 0373380..76b99f0 100644 --- a/src/main.c +++ b/src/main.c @@ -224,6 +224,9 @@ int load_command(int argc, char** argv, GString* output) { } assert(tag != NULL); char* rest = load_frame_tree(tag->frame, layout_string, output); + if (output->len > 0) { + g_string_prepend(output, "load: "); + } tag_set_flags_dirty(); // we probably changed some window positions // arrange monitor HSMonitor* m = find_monitor_with_tag(tag); -- 1.8.0
From 53a3c1e9036944961e8eb376435f191303a3d681 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 22:51:36 +0100 Subject: [PATCH 19/25] Avoid shifting in monitor commands --- src/monitor.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/monitor.c b/src/monitor.c index c560ff2..d5bfea5 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -273,15 +273,14 @@ int disjoin_rects_command(int argc, char** argv, GString* output) { } int set_monitor_rects_command(int argc, char** argv, GString* output) { - (void)SHIFT(argc, argv); - if (argc < 1) { + if (argc < 2) { return HERBST_NEED_MORE_ARGS; } - XRectangle* templates = g_new0(XRectangle, argc); - for (int i = 0; i < argc; i++) { + XRectangle* templates = g_new0(XRectangle, argc - 1); + for (int i = 1; i < (argc - 1); i++) { templates[i] = parse_rectangle(argv[i]); } - int status = set_monitor_rects(templates, argc); + int status = set_monitor_rects(templates, argc - 1); g_free(templates); if (status == HERBST_TAG_IN_USE) { g_string_append_printf(output, @@ -843,10 +842,9 @@ void monitors_lock_changed() { } int monitor_lock_tag_command(int argc, char** argv, GString* output) { - (void)SHIFT(argc, argv); HSMonitor *monitor; - if (argc >= 1) { - monitor = monitor_with_index(atoi(argv[0])); + if (argc >= 2) { + monitor = monitor_with_index(atoi(argv[1])); } else { monitor = get_current_monitor(); } @@ -860,10 +858,9 @@ int monitor_lock_tag_command(int argc, char** argv, GString* output) { } int monitor_unlock_tag_command(int argc, char** argv, GString* output) { - (void)SHIFT(argc, argv); HSMonitor *monitor; - if (argc >= 1) { - monitor = monitor_with_index(atoi(argv[0])); + if (argc >= 2) { + monitor = monitor_with_index(atoi(argv[1])); } else { monitor = get_current_monitor(); } @@ -978,10 +975,9 @@ HSStack* get_monitor_stack() { } int monitor_raise_command(int argc, char** argv, GString* output) { - (void)SHIFT(argc, argv); HSMonitor* monitor; - if (argc >= 1) { - monitor = monitor_with_index(atoi(argv[0])); + if (argc >= 2) { + monitor = monitor_with_index(atoi(argv[1])); } else { monitor = get_current_monitor(); } -- 1.8.0
From 26c7b5b97afd41c0411a46c25714b31238a16ed2 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 22:52:16 +0100 Subject: [PATCH 20/25] rule: handle function name for error msgs better --- src/rules.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/rules.c b/src/rules.c index 831f91f..f4b830b 100644 --- a/src/rules.c +++ b/src/rules.c @@ -118,7 +118,7 @@ HSCondition* condition_create(int type, char op, char* value, GString* output) { HSCondition cond; if (op != '=' && type == g_maxage_type) { g_string_append_printf(output, - "rule: Condition maxage only supports the = operator\n"); + "Condition maxage only supports the = operator\n"); return NULL; } switch (op) { @@ -127,7 +127,7 @@ HSCondition* condition_create(int type, char op, char* value, GString* output) { cond.value_type = CONDITION_VALUE_TYPE_INTEGER; if (1 != sscanf(value, "%d", &cond.value.integer)) { g_string_append_printf(output, - "rule: Can not integer from \"%s\"\n", value); + "Can not integer from \"%s\"\n", value); return NULL; } } else { @@ -143,7 +143,7 @@ HSCondition* condition_create(int type, char op, char* value, GString* output) { char buf[ERROR_STRING_BUF_SIZE]; regerror(status, &cond.value.exp, buf, ERROR_STRING_BUF_SIZE); g_string_append_printf(output, - "rule: Can not parse value \"%s\" from condition \"%s\": \"%s\"\n", + "Can not parse value \"%s\" from condition \"%s\": \"%s\"\n", value, g_condition_types[type].name, buf); return NULL; } @@ -151,7 +151,7 @@ HSCondition* condition_create(int type, char op, char* value, GString* output) { default: g_string_append_printf(output, - "rule: Unknown rule condition operation \"%c\"\n", op); + "Unknown rule condition operation \"%c\"\n", op); return NULL; break; } @@ -206,7 +206,7 @@ HSConsequence* consequence_create(int type, char op, char* value, GString* outpu default: g_string_append_printf(output, - "rule: Unknown rule consequence operation \"%c\"\n", op); + "Unknown rule consequence operation \"%c\"\n", op); return NULL; break; } @@ -297,6 +297,7 @@ int rule_add_command(int argc, char** argv, GString* output) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } + char* cmd_name = argv[0]; // save this before shifting // temporary data structures HSRule* rule = rule_create(); HSCondition* cond; @@ -336,6 +337,12 @@ int rule_add_command(int argc, char** argv, GString* output) { else if (consorcond && (type = find_condition_type(name)) >= 0) { cond = condition_create(type, op, value, output); + if (output->len > 0) { // if there was output + // Equivalent to this, but there is no g_string_prepend_printf: + // g_string_prepend_printf(output, "%s: ", cmd_name); + g_string_prepend(output, ": "); + g_string_prepend(output, cmd_name); + } if (!cond) { rule_destroy(rule); return HERBST_INVALID_ARGUMENT; @@ -347,6 +354,12 @@ int rule_add_command(int argc, char** argv, GString* output) { else if (consorcond && (type = find_consequence_type(name)) >= 0) { cons = consequence_create(type, op, value, output); + if (output->len > 0) { // if there was output + // Equivalent to this, but there is no g_string_prepend_printf: + // g_string_prepend_printf(output, "%s: ", cmd_name); + g_string_prepend(output, ": "); + g_string_prepend(output, cmd_name); + } if (!cons) { rule_destroy(rule); return HERBST_INVALID_ARGUMENT; @@ -355,16 +368,12 @@ int rule_add_command(int argc, char** argv, GString* output) { } else { - // need to hardcode "rule:" here because args are shifted g_string_append_printf(output, - "rule: Unknown argument \"%s\"\n", *argv); + "Unknown argument \"%s\"\n", *argv); return HERBST_INVALID_ARGUMENT; } } - if (output->len > 0) { // if there was output - g_string_prepend(output, "rule: "); - } g_queue_push_tail(&g_rules, rule); return 0; } -- 1.8.0
From 29d38c53b53010f7bd8fde72a4ec980dfc9a68ba Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 22:54:19 +0100 Subject: [PATCH 21/25] Handle argv-shifting correctly in settings --- src/settings.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/settings.c b/src/settings.c index 648c764..2318131 100644 --- a/src/settings.c +++ b/src/settings.c @@ -223,6 +223,8 @@ bool memberequals_settingspair(void* pmember, void* needle) { } int settings_cycle_value(int argc, char** argv, GString* output) { + char* cmd_name = argv[0]; + char* setting_name = argv[1]; // save this before shifting if (argc < 3) { return HERBST_NEED_MORE_ARGS; } @@ -240,7 +242,7 @@ int settings_cycle_value(int argc, char** argv, GString* output) { int ret = settings_set(pair, argv[i]); if (ret == HERBST_INVALID_ARGUMENT) { g_string_append_printf(output, - "%s: Invalid value for setting \"%s\"\n", argv[0], argv[1]); + "%s: Invalid value for setting \"%s\"\n", cmd_name, setting_name); } return ret; } -- 1.8.0
From 4bd3b810ff986d4cd35180240a0db22f33163edc Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Thu, 15 Nov 2012 23:10:34 +0100 Subject: [PATCH 22/25] Add error message if tag can't be switched --- src/monitor.c | 27 ++++++++++++++++++--------- src/monitor.h | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/monitor.c b/src/monitor.c index d5bfea5..7b30758 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -573,11 +573,11 @@ void all_monitors_apply_layout() { } } -void monitor_set_tag(HSMonitor* monitor, HSTag* tag) { +int monitor_set_tag(HSMonitor* monitor, HSTag* tag) { HSMonitor* other = find_monitor_with_tag(tag); if (monitor == other) { // nothing to do - return; + return 0; } if (monitor->lock_tag) { // If the monitor tag is locked, do not change the tag @@ -586,7 +586,7 @@ void monitor_set_tag(HSMonitor* monitor, HSTag* tag) { // displaying monitor monitor_focus_by_index(monitor_index_of(other)); } - return; + return 1; } if (other != NULL) { if (*g_swap_monitors_to_get_tag) { @@ -594,7 +594,7 @@ void monitor_set_tag(HSMonitor* monitor, HSTag* tag) { // the monitor we want to steal the tag from is // locked. focus that monitor instead monitor_focus_by_index(monitor_index_of(other)); - return; + return 1; } // swap tags other->tag = monitor->tag; @@ -614,7 +614,7 @@ void monitor_set_tag(HSMonitor* monitor, HSTag* tag) { emit_tag_changed(other->tag, monitor_index_of(other)); emit_tag_changed(tag, g_cur_monitor); } - return; + return 0; } HSTag* old_tag = monitor->tag; // 1. show new tag @@ -641,6 +641,7 @@ void monitor_set_tag(HSMonitor* monitor, HSTag* tag) { while (XCheckMaskEvent(g_display, EnterWindowMask, &ev)); ewmh_update_current_desktop(); emit_tag_changed(tag, g_cur_monitor); + return 0; } int monitor_set_tag_command(int argc, char** argv, GString* output) { @@ -650,8 +651,12 @@ int monitor_set_tag_command(int argc, char** argv, GString* output) { HSMonitor* monitor = get_current_monitor(); HSTag* tag = find_tag(argv[1]); if (monitor && tag) { - monitor_set_tag(monitor, tag); - return 0; + int ret = monitor_set_tag(monitor, tag); + if (ret != 0) { + g_string_append_printf(output, + "%s: Could not change tag (maybe monitor is locked?)\n", argv[0]); + } + return ret; } else { g_string_append_printf(output, "%s: Invalid monitor or tag\n", argv[0]); @@ -673,8 +678,12 @@ int monitor_set_tag_by_index_command(int argc, char** argv, GString* output) { "%s: Invalid index \"%s\"\n", argv[0], argv[1]); return HERBST_INVALID_ARGUMENT; } - monitor_set_tag(get_current_monitor(), tag); - return 0; + int ret = monitor_set_tag(get_current_monitor(), tag); + if (ret != 0) { + g_string_append_printf(output, + "%s: Could not change tag (maybe monitor is locked?)\n", argv[0]); + } + return ret; } int monitor_focus_command(int argc, char** argv) { diff --git a/src/monitor.h b/src/monitor.h index 6f268e8..a23adca 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -68,7 +68,7 @@ int move_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(); -void monitor_set_tag(HSMonitor* monitor, struct HSTag* tag); +int monitor_set_tag(HSMonitor* monitor, struct HSTag* tag); int monitor_set_pad_command(int argc, char** argv, GString* output); int monitor_set_tag_command(int argc, char** argv, GString* output); int monitor_set_tag_by_index_command(int argc, char** argv, GString* output); -- 1.8.0
From 7fd3bfc4c15efd73179a546998939138ea981a34 Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Sat, 17 Nov 2012 23:06:51 +0100 Subject: [PATCH 23/25] dump: More / clearer error messages --- src/layout.c | 6 ++++-- src/main.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/layout.c b/src/layout.c index ec7de7d..f2a5672 100644 --- a/src/layout.c +++ b/src/layout.c @@ -302,7 +302,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { // find next ( description = strchr(description, LAYOUT_DUMP_BRACKETS[0]); if (!description) { - g_string_append_printf(errormsg, "missing %c\n", + g_string_append_printf(errormsg, "Missing %c\n", LAYOUT_DUMP_BRACKETS[0]); return NULL; } @@ -328,10 +328,12 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { // jump over args substring description += args_len; if (!*description) { + g_string_append_printf(errormsg, "Missing %c or arguments\n", LAYOUT_DUMP_BRACKETS[1]); return NULL; } description += strspn(description, LAYOUT_DUMP_WHITESPACES); if (!*description) { + g_string_append_printf(errormsg, "Missing %c or arguments\n", LAYOUT_DUMP_BRACKETS[1]); return NULL; } @@ -353,7 +355,7 @@ char* load_frame_tree(HSFrame* frame, char* description, GString* errormsg) { g_free(align_name); if (align < 0) { g_string_append_printf(errormsg, - "Invalid align name in args \"%s\"\n", args); + "Invalid alignment name in args \"%s\"\n", args); return NULL; } selection = !!selection; // CLAMP it to [0;1] diff --git a/src/main.c b/src/main.c index 76b99f0..2995395 100644 --- a/src/main.c +++ b/src/main.c @@ -241,7 +241,7 @@ int load_command(int argc, char** argv, GString* output) { } if (!rest) { g_string_append_printf(output, - "%s: Layout \"%s\" unknown\n", argv[0], layout_string); + "%s: Error while parsing!\n", argv[0]); return HERBST_INVALID_ARGUMENT; } if (rest[0] != '\0') { // if string was not parsed completely -- 1.8.0
From 3e2ca29b313a65a7526f2755dcbbd39bbb214bee Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Sat, 17 Nov 2012 23:20:58 +0100 Subject: [PATCH 24/25] tag_status: CLAMP correctly --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 2995395..552358d 100644 --- a/src/main.c +++ b/src/main.c @@ -259,7 +259,7 @@ int print_tag_status_command(int argc, char** argv, GString* output) { if (argc >= 2) { monitor_index = atoi(argv[1]); } - monitor_index = CLAMP(monitor_index, 0, monitor_count()); + 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'); -- 1.8.0
From 670aa00903e6fc1a0c3b7838d781a360182ac3dd Mon Sep 17 00:00:00 2001 From: Florian Bruhin <git _at_ the _minus_ compiler _dot_ org> Date: Sun, 18 Nov 2012 00:36:31 +0100 Subject: [PATCH 25/25] Update MIGRATION --- MIGRATION | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MIGRATION b/MIGRATION index 5406512..5cf7b4d 100644 --- a/MIGRATION +++ b/MIGRATION @@ -4,6 +4,12 @@ herbstluftwm migration guide This guide describes the list of incompatible changes between the different herbstluftwm releases and how to migrate scripts and configuration. +0.4 to 0.5 +~~~~~~~~~~ +herbstclient now returns the exitstatus 9 (HERBST_NEED_MORE_ARGS) instead of 3 +(HERBST_INVALID_ARGUMENT) when a command needs more arguments. When an error +occurs, it now outputs an error message to stderr. + 0.3 to 0.4 ~~~~~~~~~~ The setting window_gap is now called frame_gap. Simply replace all occurrences -- 1.8.0
Attachment:
pgp8_4qP0RMXO.pgp
Description: PGP signature