introduced i3 command for changing the hidden state and the mode of i3bar
The hidden_state and mode of each i3bar instance can now be controlled from within i3. Therefore, two new i3 command were introduced: _ bar hidden_state show|hide|toggle [<bar_id>] show: always show the bar hide: normal hide mode toggle: toggle between show and hide (individually for each bar) _ bar mode dock|hide|invisible|toggle [<bar_id>] hide,dock: like before invisible: always keep the bar hidden toggle: toggle between dock and hide (individually for each bar) This patch introduces a hidden_state ("hidden_state hide|show") in the barconfig, which indicates the current hidden_state of each i3bar instance. It only affects the bar when in hide mode. Additionally, a new invisible mode was introduced. In order to change the hidden_state or mode of the bar from i3, a barconfig-update event was introduced, for which a bar can subscribe and the bar then gets notified about the currently set hidden_state and mode in its barconfig. For convenience, an id field ("id <bar_id>") was added to the barconfig, where one can set the desired id for the corresponding bar. If the id is not specified, i3 will deterministically choose an id; otherwise, with the previous random approach for finding a new id, which is actually not shared with i3bar, as it would determine its id on startup, the event-subscription would be destroyed on reload. Still, this issue remains when manually changing the bar_id in the config and then reloading. fixes #833, #651
This commit is contained in:
parent
f0eba6d15c
commit
e3913093b6
21
docs/ipc
21
docs/ipc
|
@ -626,6 +626,9 @@ mode (2)::
|
||||||
window (3)::
|
window (3)::
|
||||||
Sent when a client's window is successfully reparented (that is when i3
|
Sent when a client's window is successfully reparented (that is when i3
|
||||||
has finished fitting it into a container).
|
has finished fitting it into a container).
|
||||||
|
barconfig_update (4)::
|
||||||
|
Sent when the hidden_state or mode field in the barconfig of any bar
|
||||||
|
instance was updated.
|
||||||
|
|
||||||
*Example:*
|
*Example:*
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
|
@ -723,6 +726,24 @@ window title as "urxvt").
|
||||||
}
|
}
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
=== barconfig_update event
|
||||||
|
|
||||||
|
This event consists of a single serialized map reporting on options from the
|
||||||
|
barconfig of the specified bar_id that were updated in i3. The map always
|
||||||
|
consists of a property +id (string)+, which specifies to which bar instance the
|
||||||
|
sent config update belongs, a property +hidden_state (string)+, which indicates
|
||||||
|
the hidden_state of an i3bar instance, and a property +mode (string)+, which
|
||||||
|
corresponds to the current mode.
|
||||||
|
|
||||||
|
*Example:*
|
||||||
|
---------------------------
|
||||||
|
{
|
||||||
|
"id": "bar-0",
|
||||||
|
"hidden_state": "hide"
|
||||||
|
"mode": "hide"
|
||||||
|
}
|
||||||
|
---------------------------
|
||||||
|
|
||||||
== See also (existing libraries)
|
== See also (existing libraries)
|
||||||
|
|
||||||
[[libraries]]
|
[[libraries]]
|
||||||
|
|
|
@ -996,20 +996,39 @@ bar {
|
||||||
|
|
||||||
=== Display mode
|
=== Display mode
|
||||||
|
|
||||||
You can have i3bar either be visible permanently at one edge of the screen
|
You can either have i3bar be visible permanently at one edge of the screen
|
||||||
(+dock+ mode) or make it show up when you press your modifier key (+hide+
|
(+dock+ mode) or make it show up when you press your modifier key (+hide+ mode).
|
||||||
|
It is also possible to force i3bar to always stay hidden (+invisible+
|
||||||
mode). The modifier key can be configured using the +modifier+ option.
|
mode). The modifier key can be configured using the +modifier+ option.
|
||||||
|
|
||||||
|
The mode option can be changed during runtime through the +bar mode+ command.
|
||||||
|
On reload the mode will be reverted to its configured value.
|
||||||
|
|
||||||
The hide mode maximizes screen space that can be used for actual windows. Also,
|
The hide mode maximizes screen space that can be used for actual windows. Also,
|
||||||
i3bar sends the +SIGSTOP+ and +SIGCONT+ signals to the statusline process to
|
i3bar sends the +SIGSTOP+ and +SIGCONT+ signals to the statusline process to
|
||||||
save battery power.
|
save battery power.
|
||||||
|
|
||||||
The default is dock mode; in hide mode, the default modifier is Mod4 (usually
|
Invisible mode allows to permanently maximize screen space, as the bar is never
|
||||||
the windows key).
|
shown. Thus, you can configure i3bar to not disturb you by popping up because
|
||||||
|
of an urgency hint or because the modifier key is pressed.
|
||||||
|
|
||||||
|
In order to control whether i3bar is hidden or shown in hide mode, there exists
|
||||||
|
the hidden_state option, which has no effect in dock mode or invisible mode. It
|
||||||
|
indicates the current hidden_state of the bar: (1) The bar acts like in normal
|
||||||
|
hide mode, it is hidden and is only unhidden in case of urgency hints or by
|
||||||
|
pressing the modifier key (+hide+ state), or (2) it is drawn on top of the
|
||||||
|
currently visible workspace (+show+ state).
|
||||||
|
|
||||||
|
Like the mode, the hidden_state can also be controlled through i3, this can be
|
||||||
|
done by using the +bar hidden_state+ command.
|
||||||
|
|
||||||
|
The default mode is dock mode; in hide mode, the default modifier is Mod4 (usually
|
||||||
|
the windows key). The default value for the hidden_state is hide.
|
||||||
|
|
||||||
*Syntax*:
|
*Syntax*:
|
||||||
----------------
|
----------------
|
||||||
mode <dock|hide>
|
mode <dock|hide|invisible>
|
||||||
|
hidden_state <hide|show>
|
||||||
modifier <Modifier>
|
modifier <Modifier>
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -1017,12 +1036,31 @@ modifier <Modifier>
|
||||||
----------------
|
----------------
|
||||||
bar {
|
bar {
|
||||||
mode hide
|
mode hide
|
||||||
|
hidden_state hide
|
||||||
modifier Mod1
|
modifier Mod1
|
||||||
}
|
}
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Available modifiers are Mod1-Mod5, Shift, Control (see +xmodmap(1)+).
|
Available modifiers are Mod1-Mod5, Shift, Control (see +xmodmap(1)+).
|
||||||
|
|
||||||
|
=== Bar ID
|
||||||
|
|
||||||
|
Specifies the bar ID for the configured bar instance. If this option is missing,
|
||||||
|
the ID is set to 'bar-x', where x corresponds to the position of the embedding
|
||||||
|
bar block in the config file ('bar-0', 'bar-1', ...).
|
||||||
|
|
||||||
|
*Syntax*:
|
||||||
|
---------------------
|
||||||
|
id <bar_id>
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
*Example*:
|
||||||
|
---------------------
|
||||||
|
bar {
|
||||||
|
id bar-1
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
|
||||||
[[i3bar_position]]
|
[[i3bar_position]]
|
||||||
=== Position
|
=== Position
|
||||||
|
|
||||||
|
@ -1775,6 +1813,38 @@ bindsym $mod+minus scratchpad show
|
||||||
bindsym mod4+s [title="^Sup ::"] scratchpad show
|
bindsym mod4+s [title="^Sup ::"] scratchpad show
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
|
=== i3bar control
|
||||||
|
|
||||||
|
There are two options in the configuration of each i3bar instance that can be
|
||||||
|
changed during runtime by invoking a command through i3. The commands +bar
|
||||||
|
hidden_state+ and +bar mode+ allow setting the current hidden_state
|
||||||
|
respectively mode option of each bar. It is also possible to toggle between
|
||||||
|
hide state and show state as well as between dock mode and hide mode. Each
|
||||||
|
i3bar instance can be controlled individually by specifying a bar_id, if none
|
||||||
|
is given, the command is executed for all bar instances.
|
||||||
|
|
||||||
|
*Syntax*:
|
||||||
|
---------------
|
||||||
|
bar hidden_state hide|show|toggle [<bar_id>]
|
||||||
|
|
||||||
|
bar mode dock|hide|invisible|toggle [<bar_id>]
|
||||||
|
---------------
|
||||||
|
|
||||||
|
*Examples*:
|
||||||
|
------------------------------------------------
|
||||||
|
# Toggle between hide state and show state
|
||||||
|
bindsym $mod+m bar hidden_state toggle
|
||||||
|
|
||||||
|
# Toggle between dock mode and hide mode
|
||||||
|
bindsym $mod+n bar mode toggle
|
||||||
|
|
||||||
|
# Set the bar instance with id 'bar-1' to switch to hide mode
|
||||||
|
bindsym $mod+b bar mode hide bar-1
|
||||||
|
|
||||||
|
# Set the bar instance with id 'bar-1' to always stay hidden
|
||||||
|
bindsym $mod+Shift+b bar mode invisible bar-1
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
[[multi_monitor]]
|
[[multi_monitor]]
|
||||||
|
|
||||||
== Multiple monitors
|
== Multiple monitors
|
||||||
|
|
|
@ -19,7 +19,6 @@ typedef enum {
|
||||||
} position_t;
|
} position_t;
|
||||||
|
|
||||||
typedef struct config_t {
|
typedef struct config_t {
|
||||||
int hide_on_modifier;
|
|
||||||
int modifier;
|
int modifier;
|
||||||
position_t position;
|
position_t position;
|
||||||
int verbose;
|
int verbose;
|
||||||
|
@ -31,6 +30,12 @@ typedef struct config_t {
|
||||||
char *tray_output;
|
char *tray_output;
|
||||||
int num_outputs;
|
int num_outputs;
|
||||||
char **outputs;
|
char **outputs;
|
||||||
|
|
||||||
|
/* Bar display mode (hide unless modifier is pressed or show in dock mode or always hide in invisible mode) */
|
||||||
|
enum { M_DOCK = 0, M_HIDE = 1, M_INVISIBLE = 2 } hide_on_modifier;
|
||||||
|
|
||||||
|
/* The current hidden_state of the bar, which indicates whether it is hidden or shown */
|
||||||
|
enum { S_HIDE = 0, S_SHOW = 1 } hidden_state;
|
||||||
} config_t;
|
} config_t;
|
||||||
|
|
||||||
config_t config;
|
config_t config;
|
||||||
|
|
|
@ -73,7 +73,15 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in
|
||||||
|
|
||||||
if (!strcmp(cur_key, "mode")) {
|
if (!strcmp(cur_key, "mode")) {
|
||||||
DLOG("mode = %.*s, len = %d\n", len, val, len);
|
DLOG("mode = %.*s, len = %d\n", len, val, len);
|
||||||
config.hide_on_modifier = (len == 4 && !strncmp((const char*)val, "hide", strlen("hide")));
|
config.hide_on_modifier = (len == 4 && !strncmp((const char*)val, "dock", strlen("dock")) ? M_DOCK
|
||||||
|
: (len == 4 && !strncmp((const char*)val, "hide", strlen("hide")) ? M_HIDE
|
||||||
|
: M_INVISIBLE));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(cur_key, "hidden_state")) {
|
||||||
|
DLOG("hidden_state = %.*s, len = %d\n", len, val, len);
|
||||||
|
config.hidden_state = (len == 4 && !strncmp((const char*)val, "hide", strlen("hide")) ? S_HIDE : S_SHOW);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,12 +149,37 @@ void got_mode_event(char *event) {
|
||||||
draw_bars(false);
|
draw_bars(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called, when a barconfig_update event arrives (i.e. i3 changed the bar hidden_state or mode)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void got_bar_config_update(char *event) {
|
||||||
|
/* check whether this affect this bar instance by checking the bar_id */
|
||||||
|
char *expected_id;
|
||||||
|
sasprintf(&expected_id, "\"id\":\"%s\"", config.bar_id);
|
||||||
|
char *found_id = strstr(event, expected_id);
|
||||||
|
FREE(expected_id);
|
||||||
|
if (found_id == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Data-structure to easily call the reply-handlers later */
|
/* update the configuration with the received settings */
|
||||||
|
DLOG("Received bar config update \"%s\"\n", event);
|
||||||
|
int old_mode = config.hide_on_modifier;
|
||||||
|
parse_config_json(event);
|
||||||
|
if (old_mode != config.hide_on_modifier) {
|
||||||
|
reconfig_windows();
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_bars(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data-structure to easily call the event-handlers later */
|
||||||
handler_t event_handlers[] = {
|
handler_t event_handlers[] = {
|
||||||
&got_workspace_event,
|
&got_workspace_event,
|
||||||
&got_output_event,
|
&got_output_event,
|
||||||
&got_mode_event
|
&got_mode_event,
|
||||||
|
NULL,
|
||||||
|
&got_bar_config_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -310,8 +335,8 @@ void destroy_connection(void) {
|
||||||
*/
|
*/
|
||||||
void subscribe_events(void) {
|
void subscribe_events(void) {
|
||||||
if (config.disable_ws) {
|
if (config.disable_ws) {
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"output\", \"mode\" ]");
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"output\", \"mode\", \"barconfig_update\" ]");
|
||||||
} else {
|
} else {
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"workspace\", \"output\", \"mode\" ]");
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"workspace\", \"output\", \"mode\", \"barconfig_update\" ]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
107
i3bar/src/xcb.c
107
i3bar/src/xcb.c
|
@ -198,7 +198,7 @@ void refresh_statusline(void) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void hide_bars(void) {
|
void hide_bars(void) {
|
||||||
if (!config.hide_on_modifier) {
|
if ((config.hide_on_modifier == M_DOCK) || (config.hidden_state == S_SHOW)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ void hide_bars(void) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void unhide_bars(void) {
|
void unhide_bars(void) {
|
||||||
if (!config.hide_on_modifier) {
|
if (config.hide_on_modifier != M_HIDE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,25 +988,13 @@ char *init_xcb_early() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialization which depends on 'config' being usable. Called after the
|
* Register for xkb keyevents. To grab modifiers without blocking other applications from receiving key-events
|
||||||
* configuration has arrived.
|
* involving that modifier, we sadly have to use xkb which is not yet fully supported
|
||||||
|
* in xcb.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void init_xcb_late(char *fontname) {
|
void register_xkb_keyevents() {
|
||||||
if (fontname == NULL)
|
if (xkb_dpy == NULL) {
|
||||||
fontname = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
|
|
||||||
|
|
||||||
/* Load the font */
|
|
||||||
font = load_font(fontname, true);
|
|
||||||
set_font(&font);
|
|
||||||
DLOG("Calculated Font-height: %d\n", font.height);
|
|
||||||
|
|
||||||
xcb_flush(xcb_connection);
|
|
||||||
|
|
||||||
/* To grab modifiers without blocking other applications from receiving key-events
|
|
||||||
* involving that modifier, we sadly have to use xkb which is not yet fully supported
|
|
||||||
* in xcb */
|
|
||||||
if (config.hide_on_modifier) {
|
|
||||||
int xkb_major, xkb_minor, xkb_errbase, xkb_err;
|
int xkb_major, xkb_minor, xkb_errbase, xkb_err;
|
||||||
xkb_major = XkbMajorVersion;
|
xkb_major = XkbMajorVersion;
|
||||||
xkb_minor = XkbMinorVersion;
|
xkb_minor = XkbMinorVersion;
|
||||||
|
@ -1046,6 +1034,39 @@ void init_xcb_late(char *fontname) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deregister from xkb keyevents.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void deregister_xkb_keyevents() {
|
||||||
|
if (xkb_dpy != NULL) {
|
||||||
|
ev_io_stop (main_loop, xkb_io);
|
||||||
|
close(xkb_io->fd);
|
||||||
|
FREE(xkb_io);
|
||||||
|
FREE(xkb_dpy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialization which depends on 'config' being usable. Called after the
|
||||||
|
* configuration has arrived.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void init_xcb_late(char *fontname) {
|
||||||
|
if (fontname == NULL)
|
||||||
|
fontname = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
|
||||||
|
|
||||||
|
/* Load the font */
|
||||||
|
font = load_font(fontname, true);
|
||||||
|
set_font(&font);
|
||||||
|
DLOG("Calculated Font-height: %d\n", font.height);
|
||||||
|
|
||||||
|
xcb_flush(xcb_connection);
|
||||||
|
|
||||||
|
if (config.hide_on_modifier == M_HIDE)
|
||||||
|
register_xkb_keyevents();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inform clients waiting for a new _NET_SYSTEM_TRAY that we took the
|
* Inform clients waiting for a new _NET_SYSTEM_TRAY that we took the
|
||||||
* selection.
|
* selection.
|
||||||
|
@ -1368,8 +1389,8 @@ void reconfig_windows(void) {
|
||||||
mask = XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
|
mask = XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
|
||||||
/* Black background */
|
/* Black background */
|
||||||
values[0] = colors.bar_bg;
|
values[0] = colors.bar_bg;
|
||||||
/* If hide_on_modifier is set, i3 is not supposed to manage our bar-windows */
|
/* If hide_on_modifier is set to hide or invisible mode, i3 is not supposed to manage our bar-windows */
|
||||||
values[1] = config.hide_on_modifier;
|
values[1] = (config.hide_on_modifier == M_DOCK ? 0 : 1);
|
||||||
/* We enable the following EventMask fields:
|
/* We enable the following EventMask fields:
|
||||||
* EXPOSURE, to get expose events (we have to re-draw then)
|
* EXPOSURE, to get expose events (we have to re-draw then)
|
||||||
* SUBSTRUCTURE_REDIRECT, to get ConfigureRequests when the tray
|
* SUBSTRUCTURE_REDIRECT, to get ConfigureRequests when the tray
|
||||||
|
@ -1490,7 +1511,7 @@ void reconfig_windows(void) {
|
||||||
|
|
||||||
/* We finally map the bar (display it on screen), unless the modifier-switch is on */
|
/* We finally map the bar (display it on screen), unless the modifier-switch is on */
|
||||||
xcb_void_cookie_t map_cookie;
|
xcb_void_cookie_t map_cookie;
|
||||||
if (!config.hide_on_modifier) {
|
if (config.hide_on_modifier == M_DOCK) {
|
||||||
map_cookie = xcb_map_window_checked(xcb_connection, walk->bar);
|
map_cookie = xcb_map_window_checked(xcb_connection, walk->bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1501,7 +1522,7 @@ void reconfig_windows(void) {
|
||||||
xcb_request_failed(name_cookie, "Could not set WM_NAME") ||
|
xcb_request_failed(name_cookie, "Could not set WM_NAME") ||
|
||||||
xcb_request_failed(strut_cookie, "Could not set strut") ||
|
xcb_request_failed(strut_cookie, "Could not set strut") ||
|
||||||
xcb_request_failed(gc_cookie, "Could not create graphical context") ||
|
xcb_request_failed(gc_cookie, "Could not create graphical context") ||
|
||||||
(!config.hide_on_modifier && xcb_request_failed(map_cookie, "Could not map window"))) {
|
((config.hide_on_modifier == M_DOCK) && xcb_request_failed(map_cookie, "Could not map window"))) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1533,6 +1554,14 @@ void reconfig_windows(void) {
|
||||||
mask,
|
mask,
|
||||||
values);
|
values);
|
||||||
|
|
||||||
|
mask = XCB_CW_OVERRIDE_REDIRECT;
|
||||||
|
values[0] = (config.hide_on_modifier == M_DOCK ? 0 : 1);
|
||||||
|
DLOG("Changing Window attribute override_redirect for output %s to %d\n", walk->name, values[0]);
|
||||||
|
xcb_void_cookie_t chg_cookie = xcb_change_window_attributes(xcb_connection,
|
||||||
|
walk->bar,
|
||||||
|
mask,
|
||||||
|
values);
|
||||||
|
|
||||||
DLOG("Recreating buffer for output %s\n", walk->name);
|
DLOG("Recreating buffer for output %s\n", walk->name);
|
||||||
xcb_void_cookie_t pm_cookie = xcb_create_pixmap_checked(xcb_connection,
|
xcb_void_cookie_t pm_cookie = xcb_create_pixmap_checked(xcb_connection,
|
||||||
root_screen->root_depth,
|
root_screen->root_depth,
|
||||||
|
@ -1541,10 +1570,27 @@ void reconfig_windows(void) {
|
||||||
walk->rect.w,
|
walk->rect.w,
|
||||||
walk->rect.h);
|
walk->rect.h);
|
||||||
|
|
||||||
if (xcb_request_failed(cfg_cookie, "Could not reconfigure window")) {
|
/* Unmap the window, and draw it again when in dock mode */
|
||||||
exit(EXIT_FAILURE);
|
xcb_void_cookie_t umap_cookie = xcb_unmap_window_checked(xcb_connection, walk->bar);
|
||||||
|
xcb_void_cookie_t map_cookie;
|
||||||
|
if (config.hide_on_modifier == M_DOCK) {
|
||||||
|
cont_child();
|
||||||
|
map_cookie = xcb_map_window_checked(xcb_connection, walk->bar);
|
||||||
}
|
}
|
||||||
if (xcb_request_failed(pm_cookie, "Could not create pixmap")) {
|
|
||||||
|
if (config.hide_on_modifier == M_HIDE) {
|
||||||
|
/* Switching to hide mode, register for keyevents */
|
||||||
|
register_xkb_keyevents();
|
||||||
|
} else {
|
||||||
|
/* Switching to dock/invisible mode, deregister from keyevents */
|
||||||
|
deregister_xkb_keyevents();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xcb_request_failed(cfg_cookie, "Could not reconfigure window") ||
|
||||||
|
xcb_request_failed(chg_cookie, "Could not change window") ||
|
||||||
|
xcb_request_failed(pm_cookie, "Could not create pixmap") ||
|
||||||
|
xcb_request_failed(umap_cookie, "Could not unmap window") ||
|
||||||
|
((config.hide_on_modifier == M_DOCK) && xcb_request_failed(map_cookie, "Could not map window"))) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1718,11 +1764,14 @@ void draw_bars(bool unhide) {
|
||||||
i = 1;
|
i = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assure the bar is hidden/unhidden according to the specified hidden_state and mode */
|
||||||
|
bool should_unhide = (config.hidden_state == S_SHOW || (unhide && config.hidden_state == S_HIDE));
|
||||||
|
bool should_hide = (config.hide_on_modifier == M_INVISIBLE);
|
||||||
|
|
||||||
if (!mod_pressed) {
|
if (!mod_pressed) {
|
||||||
if (unhide) {
|
if ((unhide || should_unhide) && !should_hide) {
|
||||||
/* The urgent-hint should get noticed, so we unhide the bars shortly */
|
|
||||||
unhide_bars();
|
unhide_bars();
|
||||||
} else if (walks_away) {
|
} else if (walks_away || should_hide) {
|
||||||
FREE(last_urgent_ws);
|
FREE(last_urgent_ws);
|
||||||
hide_bars();
|
hide_bars();
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,4 +265,10 @@ void cmd_scratchpad_show(I3_CMD);
|
||||||
*/
|
*/
|
||||||
void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name);
|
void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of 'bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) [<bar_id>]'
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -199,6 +199,9 @@ struct Config {
|
||||||
/* just ignore the popup, that is, don’t map it */
|
/* just ignore the popup, that is, don’t map it */
|
||||||
PDF_IGNORE = 2,
|
PDF_IGNORE = 2,
|
||||||
} popup_during_fullscreen;
|
} popup_during_fullscreen;
|
||||||
|
|
||||||
|
/* The number of currently parsed barconfigs */
|
||||||
|
int number_barconfigs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,8 +229,11 @@ struct Barconfig {
|
||||||
* root window! */
|
* root window! */
|
||||||
char *socket_path;
|
char *socket_path;
|
||||||
|
|
||||||
/** Bar display mode (hide unless modifier is pressed or show in dock mode) */
|
/** Bar display mode (hide unless modifier is pressed or show in dock mode or always hide in invisible mode) */
|
||||||
enum { M_DOCK = 0, M_HIDE = 1 } mode;
|
enum { M_DOCK = 0, M_HIDE = 1, M_INVISIBLE = 2 } mode;
|
||||||
|
|
||||||
|
/* The current hidden_state of the bar, which indicates whether it is hidden or shown */
|
||||||
|
enum { S_HIDE = 0, S_SHOW = 1 } hidden_state;
|
||||||
|
|
||||||
/** Bar modifier (to show bar when in hide mode). */
|
/** Bar modifier (to show bar when in hide mode). */
|
||||||
enum {
|
enum {
|
||||||
|
@ -323,6 +329,12 @@ void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch);
|
||||||
*/
|
*/
|
||||||
void switch_mode(const char *new_mode);
|
void switch_mode(const char *new_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the current bar configuration as an event to all barconfig_update listeners.
|
||||||
|
* This update mechnism currently only includes the hidden_state and the mode in the config.
|
||||||
|
*
|
||||||
|
*/void update_barconfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a pointer to the Binding with the specified modifiers and keycode
|
* Returns a pointer to the Binding with the specified modifiers and keycode
|
||||||
* or NULL if no such binding exists.
|
* or NULL if no such binding exists.
|
||||||
|
|
|
@ -62,6 +62,8 @@ CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *ke
|
||||||
|
|
||||||
CFGFUN(bar_font, const char *font);
|
CFGFUN(bar_font, const char *font);
|
||||||
CFGFUN(bar_mode, const char *mode);
|
CFGFUN(bar_mode, const char *mode);
|
||||||
|
CFGFUN(bar_hidden_state, const char *hidden_state);
|
||||||
|
CFGFUN(bar_id, const char *bar_id);
|
||||||
CFGFUN(bar_output, const char *output);
|
CFGFUN(bar_output, const char *output);
|
||||||
CFGFUN(bar_verbose, const char *verbose);
|
CFGFUN(bar_verbose, const char *verbose);
|
||||||
CFGFUN(bar_modifier, const char *modifier);
|
CFGFUN(bar_modifier, const char *modifier);
|
||||||
|
|
|
@ -99,4 +99,7 @@ typedef struct i3_ipc_header {
|
||||||
/* The window event will be triggered upon window changes */
|
/* The window event will be triggered upon window changes */
|
||||||
#define I3_IPC_EVENT_WINDOW (I3_IPC_EVENT_MASK | 3)
|
#define I3_IPC_EVENT_WINDOW (I3_IPC_EVENT_MASK | 3)
|
||||||
|
|
||||||
|
/** Bar config update will be triggered to update the bar config */
|
||||||
|
#define I3_IPC_EVENT_BARCONFIG_UPDATE (I3_IPC_EVENT_MASK | 4)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,6 +35,7 @@ state INITIAL:
|
||||||
'nop' -> NOP
|
'nop' -> NOP
|
||||||
'scratchpad' -> SCRATCHPAD
|
'scratchpad' -> SCRATCHPAD
|
||||||
'mode' -> MODE
|
'mode' -> MODE
|
||||||
|
'bar' -> BAR
|
||||||
|
|
||||||
state CRITERIA:
|
state CRITERIA:
|
||||||
ctype = 'class' -> CRITERION
|
ctype = 'class' -> CRITERION
|
||||||
|
@ -319,3 +320,24 @@ state NOP:
|
||||||
state SCRATCHPAD:
|
state SCRATCHPAD:
|
||||||
'show'
|
'show'
|
||||||
-> call cmd_scratchpad_show()
|
-> call cmd_scratchpad_show()
|
||||||
|
|
||||||
|
# bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) [<bar_id>]
|
||||||
|
state BAR:
|
||||||
|
bar_type = 'hidden_state'
|
||||||
|
-> BAR_HIDDEN_STATE
|
||||||
|
bar_type = 'mode'
|
||||||
|
-> BAR_MODE
|
||||||
|
|
||||||
|
state BAR_HIDDEN_STATE:
|
||||||
|
bar_value = 'hide', 'show', 'toggle'
|
||||||
|
-> BAR_W_ID
|
||||||
|
|
||||||
|
state BAR_MODE:
|
||||||
|
bar_value = 'dock', 'hide', 'invisible', 'toggle'
|
||||||
|
-> BAR_W_ID
|
||||||
|
|
||||||
|
state BAR_W_ID:
|
||||||
|
bar_id = word
|
||||||
|
->
|
||||||
|
end
|
||||||
|
-> call cmd_bar($bar_type, $bar_value, $bar_id)
|
||||||
|
|
|
@ -349,6 +349,8 @@ state BAR:
|
||||||
'status_command' -> BAR_STATUS_COMMAND
|
'status_command' -> BAR_STATUS_COMMAND
|
||||||
'socket_path' -> BAR_SOCKET_PATH
|
'socket_path' -> BAR_SOCKET_PATH
|
||||||
'mode' -> BAR_MODE
|
'mode' -> BAR_MODE
|
||||||
|
'hidden_state' -> BAR_HIDDEN_STATE
|
||||||
|
'id' -> BAR_ID
|
||||||
'modifier' -> BAR_MODIFIER
|
'modifier' -> BAR_MODIFIER
|
||||||
'position' -> BAR_POSITION
|
'position' -> BAR_POSITION
|
||||||
'output' -> BAR_OUTPUT
|
'output' -> BAR_OUTPUT
|
||||||
|
@ -378,9 +380,17 @@ state BAR_SOCKET_PATH:
|
||||||
-> call cfg_bar_socket_path($path); BAR
|
-> call cfg_bar_socket_path($path); BAR
|
||||||
|
|
||||||
state BAR_MODE:
|
state BAR_MODE:
|
||||||
mode = 'dock', 'hide'
|
mode = 'dock', 'hide', 'invisible'
|
||||||
-> call cfg_bar_mode($mode); BAR
|
-> call cfg_bar_mode($mode); BAR
|
||||||
|
|
||||||
|
state BAR_HIDDEN_STATE:
|
||||||
|
hidden_state = 'hide', 'show'
|
||||||
|
-> call cfg_bar_hidden_state($hidden_state); BAR
|
||||||
|
|
||||||
|
state BAR_ID:
|
||||||
|
bar_id = word
|
||||||
|
-> call cfg_bar_id($bar_id); BAR
|
||||||
|
|
||||||
state BAR_MODIFIER:
|
state BAR_MODIFIER:
|
||||||
modifier = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Control', 'Ctrl', 'Shift'
|
modifier = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Control', 'Ctrl', 'Shift'
|
||||||
-> call cfg_bar_modifier($modifier); BAR
|
-> call cfg_bar_modifier($modifier); BAR
|
||||||
|
|
112
src/commands.c
112
src/commands.c
|
@ -1632,6 +1632,8 @@ void cmd_reload(I3_CMD) {
|
||||||
x_set_i3_atoms();
|
x_set_i3_atoms();
|
||||||
/* Send an IPC event just in case the ws names have changed */
|
/* Send an IPC event just in case the ws names have changed */
|
||||||
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"reload\"}");
|
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"reload\"}");
|
||||||
|
/* Send an update event for the barconfig just in case it has changed */
|
||||||
|
update_barconfig();
|
||||||
|
|
||||||
// XXX: default reply for now, make this a better reply
|
// XXX: default reply for now, make this a better reply
|
||||||
ysuccess(true);
|
ysuccess(true);
|
||||||
|
@ -1915,3 +1917,113 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) {
|
||||||
|
|
||||||
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"rename\"}");
|
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"rename\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of 'bar mode dock|hide|invisible|toggle [<bar_id>]'
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool cmd_bar_mode(char *bar_mode, char *bar_id) {
|
||||||
|
int mode;
|
||||||
|
bool toggle = false;
|
||||||
|
if (strcmp(bar_mode, "dock") == 0)
|
||||||
|
mode = M_DOCK;
|
||||||
|
else if (strcmp(bar_mode, "hide") == 0)
|
||||||
|
mode = M_HIDE;
|
||||||
|
else if (strcmp(bar_mode, "invisible") == 0)
|
||||||
|
mode = M_INVISIBLE;
|
||||||
|
else if (strcmp(bar_mode, "toggle") == 0)
|
||||||
|
toggle = true;
|
||||||
|
else {
|
||||||
|
ELOG("Unknown bar mode \"%s\", this is a mismatch between code and parser spec.\n", bar_mode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool changed_sth = false;
|
||||||
|
Barconfig *current = NULL;
|
||||||
|
TAILQ_FOREACH(current, &barconfigs, configs) {
|
||||||
|
if (bar_id && strcmp(current->id, bar_id) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (toggle)
|
||||||
|
mode = (current->mode + 1) % 2;
|
||||||
|
|
||||||
|
DLOG("Changing bar mode of bar_id '%s' to '%s (%d)'\n", current->id, bar_mode, mode);
|
||||||
|
current->mode = mode;
|
||||||
|
changed_sth = true;
|
||||||
|
|
||||||
|
if (bar_id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bar_id && !changed_sth) {
|
||||||
|
DLOG("Changing bar mode of bar_id %s failed, bar_id not found.\n", bar_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of 'bar hidden_state hide|show|toggle [<bar_id>]'
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool cmd_bar_hidden_state(char *bar_hidden_state, char *bar_id) {
|
||||||
|
int hidden_state;
|
||||||
|
bool toggle = false;
|
||||||
|
if (strcmp(bar_hidden_state, "hide") == 0)
|
||||||
|
hidden_state = S_HIDE;
|
||||||
|
else if (strcmp(bar_hidden_state, "show") == 0)
|
||||||
|
hidden_state = S_SHOW;
|
||||||
|
else if (strcmp(bar_hidden_state, "toggle") == 0)
|
||||||
|
toggle = true;
|
||||||
|
else {
|
||||||
|
ELOG("Unknown bar state \"%s\", this is a mismatch between code and parser spec.\n", bar_hidden_state);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool changed_sth = false;
|
||||||
|
Barconfig *current = NULL;
|
||||||
|
TAILQ_FOREACH(current, &barconfigs, configs) {
|
||||||
|
if (bar_id && strcmp(current->id, bar_id) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (toggle)
|
||||||
|
hidden_state = (current->hidden_state + 1) % 2;
|
||||||
|
|
||||||
|
DLOG("Changing bar hidden_state of bar_id '%s' to '%s (%d)'\n", current->id, bar_hidden_state, hidden_state);
|
||||||
|
current->hidden_state = hidden_state;
|
||||||
|
changed_sth = true;
|
||||||
|
|
||||||
|
if (bar_id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bar_id && !changed_sth) {
|
||||||
|
DLOG("Changing bar hidden_state of bar_id %s failed, bar_id not found.\n", bar_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of 'bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) [<bar_id>]'
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void cmd_bar(I3_CMD, char *bar_type, char *bar_value, char *bar_id) {
|
||||||
|
bool ret;
|
||||||
|
if (strcmp(bar_type, "mode") == 0)
|
||||||
|
ret = cmd_bar_mode(bar_value, bar_id);
|
||||||
|
else if (strcmp(bar_type, "hidden_state") == 0)
|
||||||
|
ret = cmd_bar_hidden_state(bar_value, bar_id);
|
||||||
|
else {
|
||||||
|
ELOG("Unknown bar option type \"%s\", this is a mismatch between code and parser spec.\n", bar_type);
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ysuccess(ret);
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
update_barconfig();
|
||||||
|
}
|
||||||
|
|
43
src/config.c
43
src/config.c
|
@ -210,6 +210,49 @@ void switch_mode(const char *new_mode) {
|
||||||
ELOG("ERROR: Mode not found\n");
|
ELOG("ERROR: Mode not found\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends the current bar configuration as an event to all barconfig_update listeners.
|
||||||
|
* This update mechnism currently only includes the hidden_state and the mode in the config.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void update_barconfig() {
|
||||||
|
Barconfig *current;
|
||||||
|
TAILQ_FOREACH(current, &barconfigs, configs) {
|
||||||
|
/* Build json message */
|
||||||
|
char *hidden_state;
|
||||||
|
switch (current->hidden_state) {
|
||||||
|
case S_SHOW:
|
||||||
|
hidden_state ="show";
|
||||||
|
break;
|
||||||
|
case S_HIDE:
|
||||||
|
default:
|
||||||
|
hidden_state = "hide";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *mode;
|
||||||
|
switch (current->mode) {
|
||||||
|
case M_HIDE:
|
||||||
|
mode ="hide";
|
||||||
|
break;
|
||||||
|
case M_INVISIBLE:
|
||||||
|
mode ="invisible";
|
||||||
|
break;
|
||||||
|
case M_DOCK:
|
||||||
|
default:
|
||||||
|
mode = "dock";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send an event to all barconfig listeners*/
|
||||||
|
char *event_msg;
|
||||||
|
sasprintf(&event_msg, "{ \"id\":\"%s\", \"hidden_state\":\"%s\", \"mode\":\"%s\" }", current->id, hidden_state, mode);
|
||||||
|
|
||||||
|
ipc_send_event("barconfig_update", I3_IPC_EVENT_BARCONFIG_UPDATE, event_msg);
|
||||||
|
FREE(event_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the path of the first configuration file found. If override_configpath
|
* Get the path of the first configuration file found. If override_configpath
|
||||||
* is specified, that path is returned and saved for further calls. Otherwise,
|
* is specified, that path is returned and saved for further calls. Otherwise,
|
||||||
|
|
|
@ -452,7 +452,15 @@ CFGFUN(bar_font, const char *font) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGFUN(bar_mode, const char *mode) {
|
CFGFUN(bar_mode, const char *mode) {
|
||||||
current_bar.mode = (strcmp(mode, "hide") == 0 ? M_HIDE : M_DOCK);
|
current_bar.mode = (strcmp(mode, "dock") == 0 ? M_DOCK : (strcmp(mode, "hide") == 0 ? M_HIDE : M_INVISIBLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
CFGFUN(bar_hidden_state, const char *hidden_state) {
|
||||||
|
current_bar.hidden_state = (strcmp(hidden_state, "hide") == 0 ? S_HIDE : S_SHOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFGFUN(bar_id, const char *bar_id) {
|
||||||
|
current_bar.id = sstrdup(bar_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGFUN(bar_output, const char *output) {
|
CFGFUN(bar_output, const char *output) {
|
||||||
|
@ -548,15 +556,11 @@ CFGFUN(bar_workspace_buttons, const char *value) {
|
||||||
|
|
||||||
CFGFUN(bar_finish) {
|
CFGFUN(bar_finish) {
|
||||||
DLOG("\t new bar configuration finished, saving.\n");
|
DLOG("\t new bar configuration finished, saving.\n");
|
||||||
/* Generate a unique ID for this bar */
|
/* Generate a unique ID for this bar if not already configured */
|
||||||
current_bar.id = sstrdup("bar-XXXXXX");
|
if (!current_bar.id)
|
||||||
/* This works similar to mktemp in that it replaces the last six X with
|
sasprintf(¤t_bar.id, "bar-%d", config.number_barconfigs);
|
||||||
* random letters, but without the restriction that the given buffer
|
|
||||||
* has to contain a valid path name. */
|
config.number_barconfigs++;
|
||||||
char *x = current_bar.id + strlen("bar-");
|
|
||||||
while (*x != '\0') {
|
|
||||||
*(x++) = (rand() % 26) + 'a';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no font was explicitly set, we use the i3 font as default */
|
/* If no font was explicitly set, we use the i3 font as default */
|
||||||
if (!current_bar.font && font_pattern)
|
if (!current_bar.font && font_pattern)
|
||||||
|
|
24
src/ipc.c
24
src/ipc.c
|
@ -621,9 +621,29 @@ IPC_HANDLER(get_bar_config) {
|
||||||
YSTR_IF_SET(socket_path);
|
YSTR_IF_SET(socket_path);
|
||||||
|
|
||||||
ystr("mode");
|
ystr("mode");
|
||||||
if (config->mode == M_HIDE)
|
switch (config->mode) {
|
||||||
|
case M_HIDE:
|
||||||
ystr("hide");
|
ystr("hide");
|
||||||
else ystr("dock");
|
break;
|
||||||
|
case M_INVISIBLE:
|
||||||
|
ystr("invisible");
|
||||||
|
break;
|
||||||
|
case M_DOCK:
|
||||||
|
default:
|
||||||
|
ystr("dock");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ystr("hidden_state");
|
||||||
|
switch (config->hidden_state) {
|
||||||
|
case S_SHOW:
|
||||||
|
ystr("show");
|
||||||
|
break;
|
||||||
|
case S_HIDE:
|
||||||
|
default:
|
||||||
|
ystr("hide");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ystr("modifier");
|
ystr("modifier");
|
||||||
switch (config->modifier) {
|
switch (config->modifier) {
|
||||||
|
|
|
@ -144,7 +144,7 @@ is(parser_calls("\nworkspace test"),
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
is(parser_calls('unknown_literal'),
|
is(parser_calls('unknown_literal'),
|
||||||
"ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'resize', 'rename', 'nop', 'scratchpad', 'mode'\n" .
|
"ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar'\n" .
|
||||||
"ERROR: Your command: unknown_literal\n" .
|
"ERROR: Your command: unknown_literal\n" .
|
||||||
"ERROR: ^^^^^^^^^^^^^^^",
|
"ERROR: ^^^^^^^^^^^^^^^",
|
||||||
'error for unknown literal ok');
|
'error for unknown literal ok');
|
||||||
|
|
|
@ -627,7 +627,7 @@ EOT
|
||||||
|
|
||||||
$expected = <<'EOT';
|
$expected = <<'EOT';
|
||||||
cfg_bar_output(LVDS-1)
|
cfg_bar_output(LVDS-1)
|
||||||
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'modifier', 'position', 'output', 'tray_output', 'font', 'workspace_buttons', 'verbose', 'colors', '}'
|
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'position', 'output', 'tray_output', 'font', 'workspace_buttons', 'verbose', 'colors', '}'
|
||||||
ERROR: CONFIG: (in file <stdin>)
|
ERROR: CONFIG: (in file <stdin>)
|
||||||
ERROR: CONFIG: Line 1: bar {
|
ERROR: CONFIG: Line 1: bar {
|
||||||
ERROR: CONFIG: Line 2: output LVDS-1
|
ERROR: CONFIG: Line 2: output LVDS-1
|
||||||
|
|
Loading…
Reference in New Issue