Merge branch 'tree' into next
This commit is contained in:
commit
56158329b3
|
@ -1,3 +1,5 @@
|
||||||
|
- Implement different dock-positions
|
||||||
|
- Hide-on-modifier is now the default behavior
|
||||||
- Bugfix: Recover from closed socket
|
- Bugfix: Recover from closed socket
|
||||||
|
|
||||||
v0.6
|
v0.6
|
||||||
|
|
|
@ -19,7 +19,7 @@ doc:
|
||||||
|
|
||||||
src/%.o: src/%.c ${HEADERS}
|
src/%.o: src/%.c ${HEADERS}
|
||||||
echo "CC $<"
|
echo "CC $<"
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
echo "INSTALL"
|
echo "INSTALL"
|
||||||
|
|
|
@ -13,9 +13,10 @@ CFLAGS += -idirafter yajl-fallback
|
||||||
|
|
||||||
CFLAGS += -Wall
|
CFLAGS += -Wall
|
||||||
CFLAGS += -pipe
|
CFLAGS += -pipe
|
||||||
CFLAGS += -Iinclude
|
|
||||||
CFLAGS += -g
|
CFLAGS += -g
|
||||||
CFLAGS += -DI3BAR_VERSION=\"${GIT_VERSION}\"
|
|
||||||
|
CPPFLAGS += -DI3BAR_VERSION=\"${GIT_VERSION}\"
|
||||||
|
CPPFLAGS += -Iinclude
|
||||||
|
|
||||||
LDFLAGS += -lev
|
LDFLAGS += -lev
|
||||||
LDFLAGS += -lyajl
|
LDFLAGS += -lyajl
|
||||||
|
|
|
@ -9,19 +9,24 @@ i3bar - xcb-based status- and ws-bar
|
||||||
|
|
||||||
== SYNOPSIS
|
== SYNOPSIS
|
||||||
|
|
||||||
*i3bar* [*-s* 'sock_path'] [*-c* 'command'] [*-m*] [*-f* 'font'] [*-V*] [*-h*]
|
*i3bar* [*-s* 'sock_path'] [*-c* 'command'] [*-m*|*-d*['pos']] [*-f* 'font'] [*-V*] [*-h*]
|
||||||
|
|
||||||
== OPTIONS
|
== OPTIONS
|
||||||
|
|
||||||
*-s, --socket* 'sock_path'::
|
*-s, --socket* 'sock_path'::
|
||||||
Specifies the 'socketpath', via which *i3bar* connects to *i3*(1). If *i3bar* can not connect to *i3*, it will exit. Defaults to '~/.i3/ipc.sock'
|
Specifies the 'socketpath', via which *i3bar* connects to *i3*(1). If *i3bar* can not connect to *i3*, it will exit. Defaults to '/tmp/i3-ipc.sock'
|
||||||
|
|
||||||
*-c, --command* 'command'::
|
*-c, --command* 'command'::
|
||||||
Execute '<command>' to get 'stdin'. You can also simply pipe into 'stdin', but starting the coomand for itself, *i3bar* is able to send 'SIGCONT' and 'SIGSTOP', when combined with *-m*
|
Execute '<command>' to get 'stdin'. You can also simply pipe into 'stdin', but starting the coomand for itself, *i3bar* is able to send 'SIGCONT' and 'SIGSTOP', when combined with *-m*
|
||||||
|
|
||||||
*-m, --hide*::
|
*-m, --hide*::
|
||||||
Hide the bar, when 'mod4' is not pressed. With this, dockmode will not be set, and the bar is out of the way most of the time so you have more room.
|
Hide the bar, when 'mod4' is not pressed. With this, dockmode will not be set, and the bar is out of the way most of the time so you have more room.
|
||||||
If *-c* is specified, the childprocess is sent a 'SIGSTOP' on hiding and a 'SIGCONT' on unhiding of the bars
|
If *-c* is specified, the childprocess is sent a 'SIGSTOP' on hiding and a 'SIGCONT' on unhiding of the bars.
|
||||||
|
This is the default behavior of i3bar.
|
||||||
|
|
||||||
|
*-d*['pos']*, --dock*[*=*'pos']::
|
||||||
|
Put i3bar in dockmode. This will reserve some space for it, so it does not overlap other clients.
|
||||||
|
You can specify either *bottom* (default) or *top* as 'pos'.
|
||||||
|
|
||||||
*-f, --font* 'font'::
|
*-f, --font* 'font'::
|
||||||
Specifies a 'X-core-font' to use. You can choose one with *xfontsel*(1). Defaults to '-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1'.
|
Specifies a 'X-core-font' to use. You can choose one with *xfontsel*(1). Defaults to '-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1'.
|
||||||
|
@ -48,7 +53,7 @@ Also, you should disable the internal workspace bar of *i3*(1), when using *i3ba
|
||||||
|
|
||||||
For now this happens with the following command-line-options:
|
For now this happens with the following command-line-options:
|
||||||
|
|
||||||
*--color-bar-fg, --color-bar-bg, --color-active-ws-fg, --color-active-ws-bg, --color-inactive-ws-fg, --color-inactive-ws-bg, color-urgent-ws-bg, color-urgent-ws-fg*
|
*--color-bar-fg, --color-bar-bg, --color-active-ws-fg, --color-active-ws-bg, --color-inactive-ws-fg, --color-inactive-ws-bg, --color-urgent-ws-bg, --color-urgent-ws-fg, --color-focus-ws-fg, --color-focus-ws-bg*
|
||||||
|
|
||||||
For each specified option you need to give a HEX-colorcode.
|
For each specified option you need to give a HEX-colorcode.
|
||||||
|
|
||||||
|
@ -66,11 +71,15 @@ to connect to i3.
|
||||||
|
|
||||||
To get a docked bar with some statusinformation, you use
|
To get a docked bar with some statusinformation, you use
|
||||||
|
|
||||||
*i3status | i3bar*
|
*i3status | i3bar --dock*
|
||||||
|
|
||||||
If you want it to hide when not needed, you should instead use
|
If you rather have it displayed at the top of the screen, you use
|
||||||
|
|
||||||
*i3bar -c i3status -m*
|
*i3status | i3bar --dock=top*
|
||||||
|
|
||||||
|
If you want it to hide when not needed, you should instead simply use
|
||||||
|
|
||||||
|
*i3bar -c i3status*
|
||||||
|
|
||||||
== SEE ALSO
|
== SEE ALSO
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,18 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DOCKPOS_NONE = 0,
|
||||||
|
DOCKPOS_TOP,
|
||||||
|
DOCKPOS_BOT
|
||||||
|
} dockpos_t;
|
||||||
|
|
||||||
typedef struct config_t {
|
typedef struct config_t {
|
||||||
int hide_on_modifier;
|
int hide_on_modifier;
|
||||||
|
dockpos_t dockpos;
|
||||||
int verbose;
|
int verbose;
|
||||||
xcb_colors_t *colors;
|
xcb_colors_t *colors;
|
||||||
|
int disable_ws;
|
||||||
} config_t;
|
} config_t;
|
||||||
|
|
||||||
config_t config;
|
config_t config;
|
||||||
|
|
|
@ -19,6 +19,8 @@ struct xcb_color_strings_t {
|
||||||
char *active_ws_bg;
|
char *active_ws_bg;
|
||||||
char *inactive_ws_fg;
|
char *inactive_ws_fg;
|
||||||
char *inactive_ws_bg;
|
char *inactive_ws_bg;
|
||||||
|
char *focus_ws_bg;
|
||||||
|
char *focus_ws_fg;
|
||||||
char *urgent_ws_bg;
|
char *urgent_ws_bg;
|
||||||
char *urgent_ws_fg;
|
char *urgent_ws_fg;
|
||||||
};
|
};
|
||||||
|
@ -29,7 +31,7 @@ typedef struct xcb_colors_t xcb_colors_t;
|
||||||
* Initialize xcb and use the specified fontname for text-rendering
|
* Initialize xcb and use the specified fontname for text-rendering
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void init_xcb();
|
char *init_xcb();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the colors
|
* Initialize the colors
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
ATOM_DO(ATOM)
|
|
||||||
ATOM_DO(_NET_WM_WINDOW_TYPE)
|
ATOM_DO(_NET_WM_WINDOW_TYPE)
|
||||||
ATOM_DO(_NET_WM_WINDOW_TYPE_DOCK)
|
ATOM_DO(_NET_WM_WINDOW_TYPE_DOCK)
|
||||||
|
ATOM_DO(_NET_WM_STRUT_PARTIAL)
|
||||||
|
ATOM_DO(I3_SOCKET_PATH)
|
||||||
#undef ATOM_DO
|
#undef ATOM_DO
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -35,11 +36,16 @@ char *statusline_buffer = NULL;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
|
if (stdin_io != NULL) {
|
||||||
ev_io_stop(main_loop, stdin_io);
|
ev_io_stop(main_loop, stdin_io);
|
||||||
ev_child_stop(main_loop, child_sig);
|
|
||||||
FREE(stdin_io);
|
FREE(stdin_io);
|
||||||
FREE(child_sig);
|
|
||||||
FREE(statusline_buffer);
|
FREE(statusline_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child_sig != NULL) {
|
||||||
|
ev_child_stop(main_loop, child_sig);
|
||||||
|
FREE(child_sig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -66,18 +72,22 @@ void stdin_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
if (rec == buffer_len) {
|
|
||||||
buffer_len += STDIN_CHUNK_SIZE;
|
|
||||||
buffer = realloc(buffer, buffer_len);
|
|
||||||
} else {
|
|
||||||
if (rec != 0) {
|
if (rec != 0) {
|
||||||
/* remove trailing newline and finish up */
|
/* remove trailing newline and finish up */
|
||||||
buffer[rec-1] = '\0';
|
buffer[rec-1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* end of file, kill the watcher */
|
||||||
|
DLOG("stdin: EOF\n");
|
||||||
|
cleanup();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
rec += n;
|
rec += n;
|
||||||
|
|
||||||
|
if (rec == buffer_len) {
|
||||||
|
buffer_len += STDIN_CHUNK_SIZE;
|
||||||
|
buffer = realloc(buffer, buffer_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (*buffer == '\0') {
|
if (*buffer == '\0') {
|
||||||
FREE(buffer);
|
FREE(buffer);
|
||||||
|
@ -174,8 +184,11 @@ void kill_child() {
|
||||||
if (child_pid != 0) {
|
if (child_pid != 0) {
|
||||||
kill(child_pid, SIGCONT);
|
kill(child_pid, SIGCONT);
|
||||||
kill(child_pid, SIGTERM);
|
kill(child_pid, SIGTERM);
|
||||||
}
|
int status;
|
||||||
|
waitpid(child_pid, &status, 0);
|
||||||
|
child_pid = 0;
|
||||||
cleanup();
|
cleanup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -57,6 +57,8 @@ void reconnect() {
|
||||||
ELOG("malloc() failed: %s\n", strerror(errno));
|
ELOG("malloc() failed: %s\n", strerror(errno));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ev_timer_stop(main_loop, reconn);
|
||||||
}
|
}
|
||||||
ev_timer_init(reconn, retry_connection, 0.25, 0.25);
|
ev_timer_init(reconn, retry_connection, 0.25, 0.25);
|
||||||
ev_timer_start(main_loop, reconn);
|
ev_timer_start(main_loop, reconn);
|
||||||
|
@ -127,7 +129,9 @@ void got_workspace_event(char *event) {
|
||||||
void got_output_event(char *event) {
|
void got_output_event(char *event) {
|
||||||
DLOG("Got Output Event!\n");
|
DLOG("Got Output Event!\n");
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
|
||||||
|
if (!config.disable_ws) {
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Data-structure to easily call the reply-handlers later */
|
/* Data-structure to easily call the reply-handlers later */
|
||||||
|
@ -144,7 +148,7 @@ void got_data(struct ev_loop *loop, ev_io *watcher, int events) {
|
||||||
DLOG("Got data!\n");
|
DLOG("Got data!\n");
|
||||||
int fd = watcher->fd;
|
int fd = watcher->fd;
|
||||||
|
|
||||||
/* First we only read the header, because we know it's length */
|
/* First we only read the header, because we know its length */
|
||||||
uint32_t header_len = strlen(I3_IPC_MAGIC) + sizeof(uint32_t)*2;
|
uint32_t header_len = strlen(I3_IPC_MAGIC) + sizeof(uint32_t)*2;
|
||||||
char *header = malloc(header_len);
|
char *header = malloc(header_len);
|
||||||
if (header == NULL) {
|
if (header == NULL) {
|
||||||
|
@ -324,5 +328,9 @@ void destroy_connection() {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void subscribe_events() {
|
void subscribe_events() {
|
||||||
|
if (config.disable_ws) {
|
||||||
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"output\" ]");
|
||||||
|
} else {
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"workspace\", \"output\" ]");
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"workspace\", \"output\" ]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,17 +75,21 @@ static void free_colors(struct xcb_color_strings_t *colors) {
|
||||||
FREE_COLOR(inactive_ws_bg);
|
FREE_COLOR(inactive_ws_bg);
|
||||||
FREE_COLOR(urgent_ws_fg);
|
FREE_COLOR(urgent_ws_fg);
|
||||||
FREE_COLOR(urgent_ws_bg);
|
FREE_COLOR(urgent_ws_bg);
|
||||||
|
FREE_COLOR(focus_ws_fg);
|
||||||
|
FREE_COLOR(focus_ws_bg);
|
||||||
#undef FREE_COLOR
|
#undef FREE_COLOR
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_usage(char *elf_name) {
|
void print_usage(char *elf_name) {
|
||||||
printf("Usage: %s [-s sock_path] [-c command] [-m] [-f font] [-V] [-h]\n", elf_name);
|
printf("Usage: %s [-s sock_path] [-c command] [-m|-d[pos]] [-f font] [-V] [-h]\n", elf_name);
|
||||||
printf("-s <sock_path>\tConnect to i3 via <sock_path>\n");
|
printf("-s <sock_path>\tConnect to i3 via <sock_path>\n");
|
||||||
printf("-c <command>\tExecute <command> to get stdin\n");
|
printf("-c <command>\tExecute <command> to get stdin\n");
|
||||||
printf("-m\t\tHide the bars, when mod4 is not pressed.\n");
|
printf("-m\t\tHide the bars, when mod4 is not pressed.\n");
|
||||||
|
printf("-d[<pos>]\tEnable dockmode. <pos> is \"top\" or \"bottom\". Default is bottom\n");
|
||||||
printf("\t\tIf -c is specified, the childprocess is sent a SIGSTOP on hiding,\n");
|
printf("\t\tIf -c is specified, the childprocess is sent a SIGSTOP on hiding,\n");
|
||||||
printf("\t\tand a SIGCONT on unhiding of the bars\n");
|
printf("\t\tand a SIGCONT on unhiding of the bars\n");
|
||||||
printf("-f <font>\tUse X-Core-Font <font> for display\n");
|
printf("-f <font>\tUse X-Core-Font <font> for display\n");
|
||||||
|
printf("-w\t\tDisable workspace-buttons\n");
|
||||||
printf("-V\t\tBe (very) verbose with the debug-output\n");
|
printf("-V\t\tBe (very) verbose with the debug-output\n");
|
||||||
printf("-h\t\tDisplay this help-message and exit\n");
|
printf("-h\t\tDisplay this help-message and exit\n");
|
||||||
}
|
}
|
||||||
|
@ -116,17 +120,21 @@ int main(int argc, char **argv) {
|
||||||
char *socket_path = getenv("I3SOCK");
|
char *socket_path = getenv("I3SOCK");
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
char *fontname = NULL;
|
char *fontname = NULL;
|
||||||
char *i3_default_sock_path = "~/.i3/ipc.sock";
|
char *i3_default_sock_path = "/tmp/i3-ipc.sock";
|
||||||
struct xcb_color_strings_t colors = { NULL, };
|
struct xcb_color_strings_t colors = { NULL, };
|
||||||
|
|
||||||
/* Definition of the standard-config */
|
/* Definition of the standard-config */
|
||||||
config.hide_on_modifier = 0;
|
config.hide_on_modifier = 0;
|
||||||
|
config.dockpos = DOCKPOS_NONE;
|
||||||
|
config.disable_ws = 0;
|
||||||
|
|
||||||
static struct option long_opt[] = {
|
static struct option long_opt[] = {
|
||||||
{ "socket", required_argument, 0, 's' },
|
{ "socket", required_argument, 0, 's' },
|
||||||
{ "command", required_argument, 0, 'c' },
|
{ "command", required_argument, 0, 'c' },
|
||||||
{ "hide", no_argument, 0, 'm' },
|
{ "hide", no_argument, 0, 'm' },
|
||||||
|
{ "dock", optional_argument, 0, 'd' },
|
||||||
{ "font", required_argument, 0, 'f' },
|
{ "font", required_argument, 0, 'f' },
|
||||||
|
{ "nows", no_argument, 0, 'w' },
|
||||||
{ "help", no_argument, 0, 'h' },
|
{ "help", no_argument, 0, 'h' },
|
||||||
{ "version", no_argument, 0, 'v' },
|
{ "version", no_argument, 0, 'v' },
|
||||||
{ "verbose", no_argument, 0, 'V' },
|
{ "verbose", no_argument, 0, 'V' },
|
||||||
|
@ -138,10 +146,12 @@ int main(int argc, char **argv) {
|
||||||
{ "color-inactive-ws-bg", required_argument, 0, 'F' },
|
{ "color-inactive-ws-bg", required_argument, 0, 'F' },
|
||||||
{ "color-urgent-ws-bg", required_argument, 0, 'G' },
|
{ "color-urgent-ws-bg", required_argument, 0, 'G' },
|
||||||
{ "color-urgent-ws-fg", required_argument, 0, 'H' },
|
{ "color-urgent-ws-fg", required_argument, 0, 'H' },
|
||||||
|
{ "color-focus-ws-bg", required_argument, 0, 'I' },
|
||||||
|
{ "color-focus-ws-fg", required_argument, 0, 'J' },
|
||||||
{ NULL, 0, 0, 0}
|
{ NULL, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "s:c:mf:hvVA:B:C:D:E:F:G:H:", long_opt, &option_index)) != -1) {
|
while ((opt = getopt_long(argc, argv, "s:c:d::mf:whvVA:B:C:D:E:F:G:H:I:J:", long_opt, &option_index)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 's':
|
case 's':
|
||||||
socket_path = expand_path(optarg);
|
socket_path = expand_path(optarg);
|
||||||
|
@ -152,9 +162,27 @@ int main(int argc, char **argv) {
|
||||||
case 'm':
|
case 'm':
|
||||||
config.hide_on_modifier = 1;
|
config.hide_on_modifier = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
config.hide_on_modifier = 0;
|
||||||
|
if (optarg == NULL) {
|
||||||
|
config.dockpos = DOCKPOS_BOT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!strcmp(optarg, "top")) {
|
||||||
|
config.dockpos = DOCKPOS_TOP;
|
||||||
|
} else if (!strcmp(optarg, "bottom")) {
|
||||||
|
config.dockpos = DOCKPOS_BOT;
|
||||||
|
} else {
|
||||||
|
print_usage(argv[0]);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
fontname = strdup(optarg);
|
fontname = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
config.disable_ws = 1;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
printf("i3bar version " I3BAR_VERSION " © 2010 Axel Wagner and contributors\n");
|
printf("i3bar version " I3BAR_VERSION " © 2010 Axel Wagner and contributors\n");
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
@ -186,6 +214,12 @@ int main(int argc, char **argv) {
|
||||||
case 'H':
|
case 'H':
|
||||||
read_color(&colors.urgent_ws_fg);
|
read_color(&colors.urgent_ws_fg);
|
||||||
break;
|
break;
|
||||||
|
case 'I':
|
||||||
|
read_color(&colors.focus_ws_bg);
|
||||||
|
break;
|
||||||
|
case 'J':
|
||||||
|
read_color(&colors.focus_ws_fg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
@ -200,15 +234,28 @@ int main(int argc, char **argv) {
|
||||||
fontname = "-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1";
|
fontname = "-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket_path == NULL) {
|
if (config.dockpos != DOCKPOS_NONE) {
|
||||||
ELOG("No Socket Path Specified, default to %s\n", i3_default_sock_path);
|
if (config.hide_on_modifier) {
|
||||||
socket_path = expand_path(i3_default_sock_path);
|
ELOG("--dock and --hide are mutually exclusive!\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
config.hide_on_modifier = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
main_loop = ev_default_loop(0);
|
main_loop = ev_default_loop(0);
|
||||||
|
|
||||||
init_colors(&colors);
|
init_colors(&colors);
|
||||||
init_xcb(fontname);
|
char *atom_sock_path = init_xcb(fontname);
|
||||||
|
|
||||||
|
if (socket_path == NULL) {
|
||||||
|
socket_path = atom_sock_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socket_path == NULL) {
|
||||||
|
ELOG("No Socket Path Specified, default to %s\n", i3_default_sock_path);
|
||||||
|
socket_path = expand_path(i3_default_sock_path);
|
||||||
|
}
|
||||||
|
|
||||||
free_colors(&colors);
|
free_colors(&colors);
|
||||||
|
|
||||||
|
@ -222,7 +269,9 @@ int main(int argc, char **argv) {
|
||||||
* workspaces. Everything else (creating the bars, showing the right workspace-
|
* workspaces. Everything else (creating the bars, showing the right workspace-
|
||||||
* buttons and more) is taken care of by the event-driveniness of the code */
|
* buttons and more) is taken care of by the event-driveniness of the code */
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
|
||||||
|
if (!config.disable_ws) {
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* The name of this function is actually misleading. Even if no -c is specified,
|
/* The name of this function is actually misleading. Even if no -c is specified,
|
||||||
* this function initiates the watchers to listen on stdin and react accordingly */
|
* this function initiates the watchers to listen on stdin and react accordingly */
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <i3/ipc.h>
|
#include <i3/ipc.h>
|
||||||
#include <yajl/yajl_parse.h>
|
#include <yajl/yajl_parse.h>
|
||||||
#include <yajl/yajl_version.h>
|
#include <yajl/yajl_version.h>
|
||||||
|
@ -111,6 +112,22 @@ static int outputs_string_cb(void *params_, const unsigned char *val, unsigned i
|
||||||
#endif
|
#endif
|
||||||
struct outputs_json_params *params = (struct outputs_json_params*) params_;
|
struct outputs_json_params *params = (struct outputs_json_params*) params_;
|
||||||
|
|
||||||
|
if (!strcmp(params->cur_key, "current_workspace")) {
|
||||||
|
char *copy = malloc(sizeof(const unsigned char) * (len + 1));
|
||||||
|
strncpy(copy, (const char*) val, len);
|
||||||
|
copy[len] = '\0';
|
||||||
|
|
||||||
|
char *end;
|
||||||
|
errno = 0;
|
||||||
|
long parsed_num = strtol(copy, &end, 10);
|
||||||
|
if (errno == 0 &&
|
||||||
|
(end && *end == '\0'))
|
||||||
|
params->outputs_walk->ws = parsed_num;
|
||||||
|
free(copy);
|
||||||
|
FREE(params->cur_key);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(params->cur_key, "name")) {
|
if (strcmp(params->cur_key, "name")) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
123
i3bar/src/xcb.c
123
i3bar/src/xcb.c
|
@ -10,6 +10,7 @@
|
||||||
*/
|
*/
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
#include <xcb/xcb_atom.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
#include <i3/ipc.h>
|
#include <i3/ipc.h>
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
|
@ -26,11 +28,10 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
/* We save the Atoms in an easy to access array, indexed by an enum */
|
/* We save the Atoms in an easy to access array, indexed by an enum */
|
||||||
#define NUM_ATOMS 3
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
#define ATOM_DO(name) name,
|
#define ATOM_DO(name) name,
|
||||||
#include "xcb_atoms.def"
|
#include "xcb_atoms.def"
|
||||||
|
NUM_ATOMS
|
||||||
};
|
};
|
||||||
|
|
||||||
xcb_intern_atom_cookie_t atom_cookies[NUM_ATOMS];
|
xcb_intern_atom_cookie_t atom_cookies[NUM_ATOMS];
|
||||||
|
@ -75,6 +76,8 @@ struct xcb_colors_t {
|
||||||
uint32_t inactive_ws_bg;
|
uint32_t inactive_ws_bg;
|
||||||
uint32_t urgent_ws_bg;
|
uint32_t urgent_ws_bg;
|
||||||
uint32_t urgent_ws_fg;
|
uint32_t urgent_ws_fg;
|
||||||
|
uint32_t focus_ws_bg;
|
||||||
|
uint32_t focus_ws_fg;
|
||||||
};
|
};
|
||||||
struct xcb_colors_t colors;
|
struct xcb_colors_t colors;
|
||||||
|
|
||||||
|
@ -273,6 +276,8 @@ void init_colors(const struct xcb_color_strings_t *new_colors) {
|
||||||
PARSE_COLOR(inactive_ws_bg, "240000");
|
PARSE_COLOR(inactive_ws_bg, "240000");
|
||||||
PARSE_COLOR(urgent_ws_fg, "FFFFFF");
|
PARSE_COLOR(urgent_ws_fg, "FFFFFF");
|
||||||
PARSE_COLOR(urgent_ws_bg, "002400");
|
PARSE_COLOR(urgent_ws_bg, "002400");
|
||||||
|
PARSE_COLOR(focus_ws_fg, "FFFFFF");
|
||||||
|
PARSE_COLOR(focus_ws_bg, "480000");
|
||||||
#undef PARSE_COLOR
|
#undef PARSE_COLOR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,8 +353,8 @@ void handle_button(xcb_button_press_event_t *event) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[50];
|
char buffer[strlen(cur_ws->name) + 11];
|
||||||
snprintf(buffer, 50, "%d", cur_ws->num);
|
snprintf(buffer, 50, "workspace %s", cur_ws->name);
|
||||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_COMMAND, buffer);
|
i3_send_msg(I3_IPC_MESSAGE_TYPE_COMMAND, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +363,7 @@ void handle_button(xcb_button_press_event_t *event) {
|
||||||
* then (and only then)
|
* then (and only then)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void xcb_prep_cb(struct ev_loop *loop, ev_prepare *watcher, int revenst) {
|
void xcb_prep_cb(struct ev_loop *loop, ev_prepare *watcher, int revents) {
|
||||||
xcb_flush(xcb_connection);
|
xcb_flush(xcb_connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +443,7 @@ void xkb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
|
||||||
* Initialize xcb and use the specified fontname for text-rendering
|
* Initialize xcb and use the specified fontname for text-rendering
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void init_xcb(char *fontname) {
|
char *init_xcb(char *fontname) {
|
||||||
/* FIXME: xcb_connect leaks Memory */
|
/* FIXME: xcb_connect leaks Memory */
|
||||||
xcb_connection = xcb_connect(NULL, NULL);
|
xcb_connection = xcb_connect(NULL, NULL);
|
||||||
if (xcb_connection_has_error(xcb_connection)) {
|
if (xcb_connection_has_error(xcb_connection)) {
|
||||||
|
@ -476,7 +481,11 @@ void init_xcb(char *fontname) {
|
||||||
xkb_major = XkbMajorVersion;
|
xkb_major = XkbMajorVersion;
|
||||||
xkb_minor = XkbMinorVersion;
|
xkb_minor = XkbMinorVersion;
|
||||||
|
|
||||||
xkb_dpy = XkbOpenDisplay(":0",
|
char *dispname = getenv("DISPLAY");
|
||||||
|
if (dispname == NULL) {
|
||||||
|
dispname = ":0";
|
||||||
|
}
|
||||||
|
xkb_dpy = XkbOpenDisplay(dispname,
|
||||||
&xkb_event_base,
|
&xkb_event_base,
|
||||||
&xkb_errbase,
|
&xkb_errbase,
|
||||||
&xkb_major,
|
&xkb_major,
|
||||||
|
@ -556,6 +565,26 @@ void init_xcb(char *fontname) {
|
||||||
/* Now we get the atoms and save them in a nice data-structure */
|
/* Now we get the atoms and save them in a nice data-structure */
|
||||||
get_atoms();
|
get_atoms();
|
||||||
|
|
||||||
|
xcb_get_property_cookie_t path_cookie;
|
||||||
|
path_cookie = xcb_get_property_unchecked(xcb_connection,
|
||||||
|
0,
|
||||||
|
xcb_root,
|
||||||
|
atoms[I3_SOCKET_PATH],
|
||||||
|
XCB_GET_PROPERTY_TYPE_ANY,
|
||||||
|
0, PATH_MAX);
|
||||||
|
|
||||||
|
/* We check, if i3 set it's socket-path */
|
||||||
|
xcb_get_property_reply_t *path_reply = xcb_get_property_reply(xcb_connection,
|
||||||
|
path_cookie,
|
||||||
|
NULL);
|
||||||
|
char *path = NULL;
|
||||||
|
if (path_reply) {
|
||||||
|
int len = xcb_get_property_value_length(path_reply);
|
||||||
|
if (len != 0) {
|
||||||
|
path = strndup(xcb_get_property_value(path_reply), len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Now we save the font-infos */
|
/* Now we save the font-infos */
|
||||||
font_info = xcb_query_font_reply(xcb_connection,
|
font_info = xcb_query_font_reply(xcb_connection,
|
||||||
query_font_cookie,
|
query_font_cookie,
|
||||||
|
@ -580,6 +609,8 @@ void init_xcb(char *fontname) {
|
||||||
xcb_request_failed(sl_ctx_cookie, "Could not allocate statusline-buffer-context")) {
|
xcb_request_failed(sl_ctx_cookie, "Could not allocate statusline-buffer-context")) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -713,8 +744,10 @@ void reconfig_windows() {
|
||||||
/* If hide_on_modifier is set, i3 is not supposed to manage our bar-windows */
|
/* If hide_on_modifier is set, i3 is not supposed to manage our bar-windows */
|
||||||
values[1] = config.hide_on_modifier;
|
values[1] = config.hide_on_modifier;
|
||||||
/* The events we want to receive */
|
/* The events we want to receive */
|
||||||
values[2] = XCB_EVENT_MASK_EXPOSURE |
|
values[2] = XCB_EVENT_MASK_EXPOSURE;
|
||||||
XCB_EVENT_MASK_BUTTON_PRESS;
|
if (!config.disable_ws) {
|
||||||
|
values[2] |= XCB_EVENT_MASK_BUTTON_PRESS;
|
||||||
|
}
|
||||||
xcb_void_cookie_t win_cookie = xcb_create_window_checked(xcb_connection,
|
xcb_void_cookie_t win_cookie = xcb_create_window_checked(xcb_connection,
|
||||||
xcb_screen->root_depth,
|
xcb_screen->root_depth,
|
||||||
walk->bar,
|
walk->bar,
|
||||||
|
@ -737,15 +770,57 @@ void reconfig_windows() {
|
||||||
|
|
||||||
/* We want dock-windows (for now). When override_redirect is set, i3 is ignoring
|
/* We want dock-windows (for now). When override_redirect is set, i3 is ignoring
|
||||||
* this one */
|
* this one */
|
||||||
xcb_void_cookie_t prop_cookie = xcb_change_property(xcb_connection,
|
xcb_void_cookie_t dock_cookie = xcb_change_property(xcb_connection,
|
||||||
XCB_PROP_MODE_REPLACE,
|
XCB_PROP_MODE_REPLACE,
|
||||||
walk->bar,
|
walk->bar,
|
||||||
atoms[_NET_WM_WINDOW_TYPE],
|
atoms[_NET_WM_WINDOW_TYPE],
|
||||||
atoms[ATOM],
|
XCB_ATOM_ATOM,
|
||||||
32,
|
32,
|
||||||
1,
|
1,
|
||||||
(unsigned char*) &atoms[_NET_WM_WINDOW_TYPE_DOCK]);
|
(unsigned char*) &atoms[_NET_WM_WINDOW_TYPE_DOCK]);
|
||||||
|
|
||||||
|
/* We need to tell i3, where to reserve space for i3bar */
|
||||||
|
/* left, right, top, bottom, left_start_y, left_end_y,
|
||||||
|
* right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x,
|
||||||
|
* bottom_end_x */
|
||||||
|
/* A local struct to save the strut_partial property */
|
||||||
|
struct {
|
||||||
|
uint32_t left;
|
||||||
|
uint32_t right;
|
||||||
|
uint32_t top;
|
||||||
|
uint32_t bottom;
|
||||||
|
uint32_t left_start_y;
|
||||||
|
uint32_t left_end_y;
|
||||||
|
uint32_t right_start_y;
|
||||||
|
uint32_t right_end_y;
|
||||||
|
uint32_t top_start_x;
|
||||||
|
uint32_t top_end_x;
|
||||||
|
uint32_t bottom_start_x;
|
||||||
|
uint32_t bottom_end_x;
|
||||||
|
} __attribute__((__packed__)) strut_partial = {0,};
|
||||||
|
switch (config.dockpos) {
|
||||||
|
case DOCKPOS_NONE:
|
||||||
|
break;
|
||||||
|
case DOCKPOS_TOP:
|
||||||
|
strut_partial.top = font_height + 6;
|
||||||
|
strut_partial.top_start_x = walk->rect.x;
|
||||||
|
strut_partial.top_end_x = walk->rect.x + walk->rect.w;
|
||||||
|
break;
|
||||||
|
case DOCKPOS_BOT:
|
||||||
|
strut_partial.bottom = font_height + 6;
|
||||||
|
strut_partial.bottom_start_x = walk->rect.x;
|
||||||
|
strut_partial.bottom_end_x = walk->rect.x + walk->rect.w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xcb_void_cookie_t strut_cookie = xcb_change_property(xcb_connection,
|
||||||
|
XCB_PROP_MODE_REPLACE,
|
||||||
|
walk->bar,
|
||||||
|
atoms[_NET_WM_STRUT_PARTIAL],
|
||||||
|
XCB_ATOM_CARDINAL,
|
||||||
|
32,
|
||||||
|
12,
|
||||||
|
&strut_partial);
|
||||||
|
|
||||||
/* We also want a graphics-context for the bars (it defines the properties
|
/* We also want a graphics-context for the bars (it defines the properties
|
||||||
* with which we draw to them) */
|
* with which we draw to them) */
|
||||||
walk->bargc = xcb_generate_id(xcb_connection);
|
walk->bargc = xcb_generate_id(xcb_connection);
|
||||||
|
@ -765,7 +840,8 @@ void reconfig_windows() {
|
||||||
|
|
||||||
if (xcb_request_failed(win_cookie, "Could not create window") ||
|
if (xcb_request_failed(win_cookie, "Could not create window") ||
|
||||||
xcb_request_failed(pm_cookie, "Could not create pixmap") ||
|
xcb_request_failed(pm_cookie, "Could not create pixmap") ||
|
||||||
xcb_request_failed(prop_cookie, "Could not set dock mode") ||
|
xcb_request_failed(dock_cookie, "Could not set dock mode") ||
|
||||||
|
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 && xcb_request_failed(map_cookie, "Could not map window"))) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -858,14 +934,23 @@ void draw_bars() {
|
||||||
MIN(outputs_walk->rect.w - 4, statusline_width), font_height);
|
MIN(outputs_walk->rect.w - 4, statusline_width), font_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.disable_ws) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
i3_ws *ws_walk;
|
i3_ws *ws_walk;
|
||||||
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
|
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
|
||||||
DLOG("Drawing Button for WS %s at x = %d\n", ws_walk->name, i);
|
DLOG("Drawing Button for WS %s at x = %d\n", ws_walk->name, i);
|
||||||
uint32_t fg_color = colors.inactive_ws_fg;
|
uint32_t fg_color = colors.inactive_ws_fg;
|
||||||
uint32_t bg_color = colors.inactive_ws_bg;
|
uint32_t bg_color = colors.inactive_ws_bg;
|
||||||
if (ws_walk->visible) {
|
if (ws_walk->visible) {
|
||||||
|
if (!ws_walk->focused) {
|
||||||
fg_color = colors.active_ws_fg;
|
fg_color = colors.active_ws_fg;
|
||||||
bg_color = colors.active_ws_bg;
|
bg_color = colors.active_ws_bg;
|
||||||
|
} else {
|
||||||
|
fg_color = colors.focus_ws_fg;
|
||||||
|
bg_color = colors.focus_ws_bg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ws_walk->urgent) {
|
if (ws_walk->urgent) {
|
||||||
DLOG("WS %s is urgent!\n", ws_walk->name);
|
DLOG("WS %s is urgent!\n", ws_walk->name);
|
||||||
|
@ -874,14 +959,12 @@ void draw_bars() {
|
||||||
/* The urgent-hint should get noticed, so we unhide the bars shortly */
|
/* The urgent-hint should get noticed, so we unhide the bars shortly */
|
||||||
unhide_bars();
|
unhide_bars();
|
||||||
}
|
}
|
||||||
|
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
|
||||||
|
uint32_t vals[] = { bg_color, bg_color };
|
||||||
xcb_change_gc(xcb_connection,
|
xcb_change_gc(xcb_connection,
|
||||||
outputs_walk->bargc,
|
outputs_walk->bargc,
|
||||||
XCB_GC_FOREGROUND,
|
mask,
|
||||||
&bg_color);
|
vals);
|
||||||
xcb_change_gc(xcb_connection,
|
|
||||||
outputs_walk->bargc,
|
|
||||||
XCB_GC_BACKGROUND,
|
|
||||||
&bg_color);
|
|
||||||
xcb_rectangle_t rect = { i + 1, 1, ws_walk->name_width + 8, font_height + 4 };
|
xcb_rectangle_t rect = { i + 1, 1, ws_walk->name_width + 8, font_height + 4 };
|
||||||
xcb_poly_fill_rectangle(xcb_connection,
|
xcb_poly_fill_rectangle(xcb_connection,
|
||||||
outputs_walk->buffer,
|
outputs_walk->buffer,
|
||||||
|
@ -901,10 +984,10 @@ void draw_bars() {
|
||||||
i += 10 + ws_walk->name_width;
|
i += 10 + ws_walk->name_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
redraw_bars();
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redraw_bars();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue