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
|
||||
|
||||
v0.6
|
||||
|
|
|
@ -19,7 +19,7 @@ doc:
|
|||
|
||||
src/%.o: src/%.c ${HEADERS}
|
||||
echo "CC $<"
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
install: all
|
||||
echo "INSTALL"
|
||||
|
|
|
@ -13,9 +13,10 @@ CFLAGS += -idirafter yajl-fallback
|
|||
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -pipe
|
||||
CFLAGS += -Iinclude
|
||||
CFLAGS += -g
|
||||
CFLAGS += -DI3BAR_VERSION=\"${GIT_VERSION}\"
|
||||
|
||||
CPPFLAGS += -DI3BAR_VERSION=\"${GIT_VERSION}\"
|
||||
CPPFLAGS += -Iinclude
|
||||
|
||||
LDFLAGS += -lev
|
||||
LDFLAGS += -lyajl
|
||||
|
|
|
@ -9,19 +9,24 @@ i3bar - xcb-based status- and ws-bar
|
|||
|
||||
== 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
|
||||
|
||||
*-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'::
|
||||
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*::
|
||||
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'::
|
||||
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:
|
||||
|
||||
*--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.
|
||||
|
||||
|
@ -66,11 +71,15 @@ to connect to i3.
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -3,10 +3,18 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
typedef enum {
|
||||
DOCKPOS_NONE = 0,
|
||||
DOCKPOS_TOP,
|
||||
DOCKPOS_BOT
|
||||
} dockpos_t;
|
||||
|
||||
typedef struct config_t {
|
||||
int hide_on_modifier;
|
||||
dockpos_t dockpos;
|
||||
int verbose;
|
||||
xcb_colors_t *colors;
|
||||
int disable_ws;
|
||||
} config_t;
|
||||
|
||||
config_t config;
|
||||
|
|
|
@ -19,6 +19,8 @@ struct xcb_color_strings_t {
|
|||
char *active_ws_bg;
|
||||
char *inactive_ws_fg;
|
||||
char *inactive_ws_bg;
|
||||
char *focus_ws_bg;
|
||||
char *focus_ws_fg;
|
||||
char *urgent_ws_bg;
|
||||
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
|
||||
*
|
||||
*/
|
||||
void init_xcb();
|
||||
char *init_xcb();
|
||||
|
||||
/*
|
||||
* Initialize the colors
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
ATOM_DO(ATOM)
|
||||
ATOM_DO(_NET_WM_WINDOW_TYPE)
|
||||
ATOM_DO(_NET_WM_WINDOW_TYPE_DOCK)
|
||||
ATOM_DO(_NET_WM_STRUT_PARTIAL)
|
||||
ATOM_DO(I3_SOCKET_PATH)
|
||||
#undef ATOM_DO
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -35,13 +36,18 @@ char *statusline_buffer = NULL;
|
|||
*
|
||||
*/
|
||||
void cleanup() {
|
||||
if (stdin_io != NULL) {
|
||||
ev_io_stop(main_loop, stdin_io);
|
||||
ev_child_stop(main_loop, child_sig);
|
||||
FREE(stdin_io);
|
||||
FREE(child_sig);
|
||||
FREE(statusline_buffer);
|
||||
}
|
||||
|
||||
if (child_sig != NULL) {
|
||||
ev_child_stop(main_loop, child_sig);
|
||||
FREE(child_sig);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Callbalk for stdin. We read a line from stdin and store the result
|
||||
* in statusline
|
||||
|
@ -66,18 +72,22 @@ void stdin_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (n == 0) {
|
||||
if (rec == buffer_len) {
|
||||
buffer_len += STDIN_CHUNK_SIZE;
|
||||
buffer = realloc(buffer, buffer_len);
|
||||
} else {
|
||||
if (rec != 0) {
|
||||
/* remove trailing newline and finish up */
|
||||
buffer[rec-1] = '\0';
|
||||
}
|
||||
|
||||
/* end of file, kill the watcher */
|
||||
DLOG("stdin: EOF\n");
|
||||
cleanup();
|
||||
break;
|
||||
}
|
||||
}
|
||||
rec += n;
|
||||
|
||||
if (rec == buffer_len) {
|
||||
buffer_len += STDIN_CHUNK_SIZE;
|
||||
buffer = realloc(buffer, buffer_len);
|
||||
}
|
||||
}
|
||||
if (*buffer == '\0') {
|
||||
FREE(buffer);
|
||||
|
@ -174,9 +184,12 @@ void kill_child() {
|
|||
if (child_pid != 0) {
|
||||
kill(child_pid, SIGCONT);
|
||||
kill(child_pid, SIGTERM);
|
||||
}
|
||||
int status;
|
||||
waitpid(child_pid, &status, 0);
|
||||
child_pid = 0;
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a SIGSTOP to the child-process (if existent)
|
||||
|
|
|
@ -57,6 +57,8 @@ void reconnect() {
|
|||
ELOG("malloc() failed: %s\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
ev_timer_stop(main_loop, reconn);
|
||||
}
|
||||
ev_timer_init(reconn, retry_connection, 0.25, 0.25);
|
||||
ev_timer_start(main_loop, reconn);
|
||||
|
@ -127,8 +129,10 @@ void got_workspace_event(char *event) {
|
|||
void got_output_event(char *event) {
|
||||
DLOG("Got Output Event!\n");
|
||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
|
||||
if (!config.disable_ws) {
|
||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Data-structure to easily call the reply-handlers later */
|
||||
handler_t event_handlers[] = {
|
||||
|
@ -144,7 +148,7 @@ void got_data(struct ev_loop *loop, ev_io *watcher, int events) {
|
|||
DLOG("Got data!\n");
|
||||
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;
|
||||
char *header = malloc(header_len);
|
||||
if (header == NULL) {
|
||||
|
@ -324,5 +328,9 @@ void destroy_connection() {
|
|||
*
|
||||
*/
|
||||
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\" ]");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,17 +75,21 @@ static void free_colors(struct xcb_color_strings_t *colors) {
|
|||
FREE_COLOR(inactive_ws_bg);
|
||||
FREE_COLOR(urgent_ws_fg);
|
||||
FREE_COLOR(urgent_ws_bg);
|
||||
FREE_COLOR(focus_ws_fg);
|
||||
FREE_COLOR(focus_ws_bg);
|
||||
#undef FREE_COLOR
|
||||
}
|
||||
|
||||
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("-c <command>\tExecute <command> to get stdin\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\tand a SIGCONT on unhiding of the bars\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("-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 *command = 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, };
|
||||
|
||||
/* Definition of the standard-config */
|
||||
config.hide_on_modifier = 0;
|
||||
config.dockpos = DOCKPOS_NONE;
|
||||
config.disable_ws = 0;
|
||||
|
||||
static struct option long_opt[] = {
|
||||
{ "socket", required_argument, 0, 's' },
|
||||
{ "command", required_argument, 0, 'c' },
|
||||
{ "hide", no_argument, 0, 'm' },
|
||||
{ "dock", optional_argument, 0, 'd' },
|
||||
{ "font", required_argument, 0, 'f' },
|
||||
{ "nows", no_argument, 0, 'w' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", 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-urgent-ws-bg", required_argument, 0, 'G' },
|
||||
{ "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}
|
||||
};
|
||||
|
||||
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) {
|
||||
case 's':
|
||||
socket_path = expand_path(optarg);
|
||||
|
@ -152,9 +162,27 @@ int main(int argc, char **argv) {
|
|||
case 'm':
|
||||
config.hide_on_modifier = 1;
|
||||
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':
|
||||
fontname = strdup(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
config.disable_ws = 1;
|
||||
break;
|
||||
case 'v':
|
||||
printf("i3bar version " I3BAR_VERSION " © 2010 Axel Wagner and contributors\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
|
@ -186,6 +214,12 @@ int main(int argc, char **argv) {
|
|||
case 'H':
|
||||
read_color(&colors.urgent_ws_fg);
|
||||
break;
|
||||
case 'I':
|
||||
read_color(&colors.focus_ws_bg);
|
||||
break;
|
||||
case 'J':
|
||||
read_color(&colors.focus_ws_fg);
|
||||
break;
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
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";
|
||||
}
|
||||
|
||||
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);
|
||||
if (config.dockpos != DOCKPOS_NONE) {
|
||||
if (config.hide_on_modifier) {
|
||||
ELOG("--dock and --hide are mutually exclusive!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
config.hide_on_modifier = 1;
|
||||
}
|
||||
|
||||
main_loop = ev_default_loop(0);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -222,7 +269,9 @@ int main(int argc, char **argv) {
|
|||
* workspaces. Everything else (creating the bars, showing the right workspace-
|
||||
* buttons and more) is taken care of by the event-driveniness of the code */
|
||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
|
||||
if (!config.disable_ws) {
|
||||
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <i3/ipc.h>
|
||||
#include <yajl/yajl_parse.h>
|
||||
#include <yajl/yajl_version.h>
|
||||
|
@ -111,6 +112,22 @@ static int outputs_string_cb(void *params_, const unsigned char *val, unsigned i
|
|||
#endif
|
||||
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")) {
|
||||
return 0;
|
||||
}
|
||||
|
|
123
i3bar/src/xcb.c
123
i3bar/src/xcb.c
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xproto.h>
|
||||
#include <xcb/xcb_atom.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
@ -18,6 +19,7 @@
|
|||
#include <i3/ipc.h>
|
||||
#include <ev.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
@ -26,11 +28,10 @@
|
|||
#include "common.h"
|
||||
|
||||
/* We save the Atoms in an easy to access array, indexed by an enum */
|
||||
#define NUM_ATOMS 3
|
||||
|
||||
enum {
|
||||
#define ATOM_DO(name) name,
|
||||
#include "xcb_atoms.def"
|
||||
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 urgent_ws_bg;
|
||||
uint32_t urgent_ws_fg;
|
||||
uint32_t focus_ws_bg;
|
||||
uint32_t focus_ws_fg;
|
||||
};
|
||||
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(urgent_ws_fg, "FFFFFF");
|
||||
PARSE_COLOR(urgent_ws_bg, "002400");
|
||||
PARSE_COLOR(focus_ws_fg, "FFFFFF");
|
||||
PARSE_COLOR(focus_ws_bg, "480000");
|
||||
#undef PARSE_COLOR
|
||||
}
|
||||
|
||||
|
@ -348,8 +353,8 @@ void handle_button(xcb_button_press_event_t *event) {
|
|||
break;
|
||||
}
|
||||
|
||||
char buffer[50];
|
||||
snprintf(buffer, 50, "%d", cur_ws->num);
|
||||
char buffer[strlen(cur_ws->name) + 11];
|
||||
snprintf(buffer, 50, "workspace %s", cur_ws->name);
|
||||
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)
|
||||
*
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
*/
|
||||
void init_xcb(char *fontname) {
|
||||
char *init_xcb(char *fontname) {
|
||||
/* FIXME: xcb_connect leaks Memory */
|
||||
xcb_connection = xcb_connect(NULL, NULL);
|
||||
if (xcb_connection_has_error(xcb_connection)) {
|
||||
|
@ -476,7 +481,11 @@ void init_xcb(char *fontname) {
|
|||
xkb_major = XkbMajorVersion;
|
||||
xkb_minor = XkbMinorVersion;
|
||||
|
||||
xkb_dpy = XkbOpenDisplay(":0",
|
||||
char *dispname = getenv("DISPLAY");
|
||||
if (dispname == NULL) {
|
||||
dispname = ":0";
|
||||
}
|
||||
xkb_dpy = XkbOpenDisplay(dispname,
|
||||
&xkb_event_base,
|
||||
&xkb_errbase,
|
||||
&xkb_major,
|
||||
|
@ -556,6 +565,26 @@ void init_xcb(char *fontname) {
|
|||
/* Now we get the atoms and save them in a nice data-structure */
|
||||
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 */
|
||||
font_info = xcb_query_font_reply(xcb_connection,
|
||||
query_font_cookie,
|
||||
|
@ -580,6 +609,8 @@ void init_xcb(char *fontname) {
|
|||
xcb_request_failed(sl_ctx_cookie, "Could not allocate statusline-buffer-context")) {
|
||||
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 */
|
||||
values[1] = config.hide_on_modifier;
|
||||
/* The events we want to receive */
|
||||
values[2] = XCB_EVENT_MASK_EXPOSURE |
|
||||
XCB_EVENT_MASK_BUTTON_PRESS;
|
||||
values[2] = XCB_EVENT_MASK_EXPOSURE;
|
||||
if (!config.disable_ws) {
|
||||
values[2] |= XCB_EVENT_MASK_BUTTON_PRESS;
|
||||
}
|
||||
xcb_void_cookie_t win_cookie = xcb_create_window_checked(xcb_connection,
|
||||
xcb_screen->root_depth,
|
||||
walk->bar,
|
||||
|
@ -737,15 +770,57 @@ void reconfig_windows() {
|
|||
|
||||
/* We want dock-windows (for now). When override_redirect is set, i3 is ignoring
|
||||
* 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,
|
||||
walk->bar,
|
||||
atoms[_NET_WM_WINDOW_TYPE],
|
||||
atoms[ATOM],
|
||||
XCB_ATOM_ATOM,
|
||||
32,
|
||||
1,
|
||||
(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
|
||||
* with which we draw to them) */
|
||||
walk->bargc = xcb_generate_id(xcb_connection);
|
||||
|
@ -765,7 +840,8 @@ void reconfig_windows() {
|
|||
|
||||
if (xcb_request_failed(win_cookie, "Could not create window") ||
|
||||
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") ||
|
||||
(!config.hide_on_modifier && xcb_request_failed(map_cookie, "Could not map window"))) {
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -858,14 +934,23 @@ void draw_bars() {
|
|||
MIN(outputs_walk->rect.w - 4, statusline_width), font_height);
|
||||
}
|
||||
|
||||
if (config.disable_ws) {
|
||||
continue;
|
||||
}
|
||||
|
||||
i3_ws *ws_walk;
|
||||
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
|
||||
DLOG("Drawing Button for WS %s at x = %d\n", ws_walk->name, i);
|
||||
uint32_t fg_color = colors.inactive_ws_fg;
|
||||
uint32_t bg_color = colors.inactive_ws_bg;
|
||||
if (ws_walk->visible) {
|
||||
if (!ws_walk->focused) {
|
||||
fg_color = colors.active_ws_fg;
|
||||
bg_color = colors.active_ws_bg;
|
||||
} else {
|
||||
fg_color = colors.focus_ws_fg;
|
||||
bg_color = colors.focus_ws_bg;
|
||||
}
|
||||
}
|
||||
if (ws_walk->urgent) {
|
||||
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 */
|
||||
unhide_bars();
|
||||
}
|
||||
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
|
||||
uint32_t vals[] = { bg_color, bg_color };
|
||||
xcb_change_gc(xcb_connection,
|
||||
outputs_walk->bargc,
|
||||
XCB_GC_FOREGROUND,
|
||||
&bg_color);
|
||||
xcb_change_gc(xcb_connection,
|
||||
outputs_walk->bargc,
|
||||
XCB_GC_BACKGROUND,
|
||||
&bg_color);
|
||||
mask,
|
||||
vals);
|
||||
xcb_rectangle_t rect = { i + 1, 1, ws_walk->name_width + 8, font_height + 4 };
|
||||
xcb_poly_fill_rectangle(xcb_connection,
|
||||
outputs_walk->buffer,
|
||||
|
@ -901,10 +984,10 @@ void draw_bars() {
|
|||
i += 10 + ws_walk->name_width;
|
||||
}
|
||||
|
||||
redraw_bars();
|
||||
|
||||
i = 0;
|
||||
}
|
||||
|
||||
redraw_bars();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue