/* These are only relevant for XKB, which we only need for grabbing modifiers */
int xkb_base;
-int mod_pressed = 0;
+bool mod_pressed = 0;
/* Event watchers, to interact with the user */
ev_prepare *xcb_prep;
return 0;
}
-uint32_t get_sep_offset(struct status_block *block) {
+static uint32_t get_sep_offset(struct status_block *block) {
if (!block->no_separator && block->sep_block_width > 0)
return block->sep_block_width / 2 + block->sep_block_width % 2;
return 0;
}
-int get_tray_width(struct tc_head *trayclients) {
+static int get_tray_width(struct tc_head *trayclients) {
trayclient *trayclient;
int tray_width = 0;
TAILQ_FOREACH_REVERSE(trayclient, trayclients, tc_head, tailq) {
}
}
-uint32_t predict_statusline_length(bool use_short_text) {
+static uint32_t predict_statusline_length(bool use_short_text) {
uint32_t width = 0;
struct status_block *block;
/*
* Redraws the statusline to the output's statusline_buffer
*/
-void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_colors, bool use_short_text) {
+static void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_colors, bool use_short_text) {
struct status_block *block;
color_t bar_color = (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg);
* Hides all bars (unmaps them)
*
*/
-void hide_bars(void) {
+static void hide_bars(void) {
if ((config.hide_on_modifier == M_DOCK) || (config.hidden_state == S_SHOW && config.hide_on_modifier == M_HIDE)) {
return;
}
* Unhides all bars (maps them)
*
*/
-void unhide_bars(void) {
+static void unhide_bars(void) {
if (config.hide_on_modifier != M_HIDE) {
return;
}
* wheel was used and change the workspace appropriately
*
*/
-void handle_button(xcb_button_press_event_t *event) {
+static void handle_button(xcb_button_press_event_t *event) {
/* Determine, which bar was clicked */
i3_output *walk;
xcb_window_t bar = event->event;
/* If the child asked for click events,
* check if a status block has been clicked. */
int tray_width = get_tray_width(walk->trayclients);
- int block_x = 0, last_block_x;
- int offset = walk->rect.w - walk->statusline_width - tray_width - logical_px(sb_hoff_px);
+ int last_block_x = 0;
+ int offset = walk->rect.w - walk->statusline_width - tray_width - logical_px((tray_width > 0) * sb_hoff_px);
int32_t statusline_x = x - offset;
if (statusline_x >= 0 && statusline_x < walk->statusline_width) {
struct status_block *block;
- int sep_offset_remainder = 0;
TAILQ_FOREACH(block, &statusline_head, blocks) {
i3String *text = block->full_text;
if (i3string_get_num_bytes(text) == 0)
continue;
- last_block_x = block_x;
- block_x += render->width + render->x_offset + render->x_append + get_sep_offset(block) + sep_offset_remainder;
-
- if (statusline_x <= block_x && statusline_x >= last_block_x) {
+ const int relative_x = statusline_x - last_block_x;
+ if (relative_x >= 0 && (uint32_t)relative_x <= render->width) {
send_block_clicked(event->detail, block->name, block->instance,
- event->root_x, event->root_y, statusline_x - last_block_x, event->event_y, block_x - last_block_x, bar_height);
+ event->root_x, event->root_y, relative_x, event->event_y, render->width, bar_height);
return;
}
- sep_offset_remainder = block->sep_block_width - get_sep_offset(block);
+ last_block_x += render->width + render->x_append + render->x_offset + block->sep_block_width;
}
}
}
const size_t len = namelen + strlen("workspace \"\"") + 1;
char *buffer = scalloc(len + num_quotes, 1);
- strncpy(buffer, "workspace \"", strlen("workspace \""));
+ memcpy(buffer, "workspace \"", strlen("workspace \""));
size_t inpos, outpos;
for (inpos = 0, outpos = strlen("workspace \"");
inpos < namelen;
if (event->type == atoms[I3_SYNC]) {
xcb_window_t window = event->data.data32[0];
uint32_t rnd = event->data.data32[1];
- DLOG("[i3 sync protocol] Forwarding random value %d, X11 window 0x%08x to i3\n", rnd, window);
-
- void *reply = scalloc(32, 1);
- xcb_client_message_event_t *ev = reply;
-
- ev->response_type = XCB_CLIENT_MESSAGE;
- ev->window = window;
- ev->type = atoms[I3_SYNC];
- ev->format = 32;
- ev->data.data32[0] = window;
- ev->data.data32[1] = rnd;
-
- xcb_send_event(conn, false, xcb_root, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *)ev);
- xcb_flush(conn);
- free(reply);
+ /* Forward the request to i3 via the IPC interface so that all pending
+ * IPC messages are guaranteed to be handled. */
+ char *payload = NULL;
+ sasprintf(&payload, "{\"rnd\":%d, \"window\":%d}", rnd, window);
+ i3_send_msg(I3_IPC_MESSAGE_TYPE_SYNC, payload);
+ free(payload);
} else if (event->type == atoms[_NET_SYSTEM_TRAY_OPCODE] &&
event->format == 32) {
DLOG("_NET_SYSTEM_TRAY_OPCODE received\n");
* events from X11, handle them, then flush our outgoing queue.
*
*/
-void xcb_prep_cb(struct ev_loop *loop, ev_prepare *watcher, int revents) {
+static void xcb_prep_cb(struct ev_loop *loop, ev_prepare *watcher, int revents) {
xcb_generic_event_t *event;
if (xcb_connection_has_error(xcb_connection)) {
DLOG("received an xkb event\n");
xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
+ const uint32_t mod = (config.modifier & 0xFFFF);
+ mod_pressed = (mod != 0 && (state->mods & mod) == mod);
if (state->xkbType == XCB_XKB_STATE_NOTIFY && config.modifier != XCB_NONE) {
- int modstate = state->mods & config.modifier;
-
-#define DLOGMOD(modmask, status) \
- do { \
- switch (modmask) { \
- case ShiftMask: \
- DLOG("ShiftMask got " #status "!\n"); \
- break; \
- case ControlMask: \
- DLOG("ControlMask got " #status "!\n"); \
- break; \
- case Mod1Mask: \
- DLOG("Mod1Mask got " #status "!\n"); \
- break; \
- case Mod2Mask: \
- DLOG("Mod2Mask got " #status "!\n"); \
- break; \
- case Mod3Mask: \
- DLOG("Mod3Mask got " #status "!\n"); \
- break; \
- case Mod4Mask: \
- DLOG("Mod4Mask got " #status "!\n"); \
- break; \
- case Mod5Mask: \
- DLOG("Mod5Mask got " #status "!\n"); \
- break; \
- } \
- } while (0)
-
- if (modstate != mod_pressed) {
- if (modstate == 0) {
- DLOGMOD(config.modifier, released);
- if (!activated_mode)
- hide_bars();
- } else {
- DLOGMOD(config.modifier, pressed);
- activated_mode = false;
- unhide_bars();
- }
- mod_pressed = modstate;
+ if (mod_pressed) {
+ activated_mode = false;
+ unhide_bars();
+ } else if (!activated_mode) {
+ hide_bars();
}
-#undef DLOGMOD
}
free(event);
* are triggered
*
*/
-void xcb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
+static void xcb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
}
/*
* depend on 'config'.
*
*/
-char *init_xcb_early() {
+char *init_xcb_early(void) {
/* FIXME: xcb_connect leaks memory */
xcb_connection = xcb_connect(NULL, &screen);
if (xcb_connection_has_error(xcb_connection)) {
* in xcb.
*
*/
-void register_xkb_keyevents() {
+static void register_xkb_keyevents(void) {
const xcb_query_extension_reply_t *extreply;
extreply = xcb_get_extension_data(conn, &xcb_xkb_id);
if (!extreply->present) {
* Deregister from xkb keyevents.
*
*/
-void deregister_xkb_keyevents() {
+static void deregister_xkb_keyevents(void) {
xcb_xkb_select_events(conn,
XCB_XKB_ID_USE_CORE_KBD,
0,
* atom. Afterwards, tray clients will send ClientMessages to our window.
*
*/
-void init_tray(void) {
+static void init_tray(void) {
DLOG("Initializing system tray functionality\n");
/* request the tray manager atom for the X11 display we are running on */
char atomname[strlen("_NET_SYSTEM_TRAY_S") + 11];
/* Strut partial tells i3 where to reserve space for i3bar. This is determined
* by the `position` bar config directive. */
-xcb_void_cookie_t config_strut_partial(i3_output *output) {
+static xcb_void_cookie_t config_strut_partial(i3_output *output) {
/* A local struct to save the strut_partial property */
struct {
uint32_t left;
DLOG("Printing statusline!\n");
int tray_width = get_tray_width(outputs_walk->trayclients);
- uint32_t max_statusline_width = outputs_walk->rect.w - workspace_width - tray_width - 2 * logical_px(sb_hoff_px);
+ uint32_t hoff = logical_px(((workspace_width > 0) + (tray_width > 0)) * sb_hoff_px);
+ uint32_t max_statusline_width = outputs_walk->rect.w - workspace_width - tray_width - hoff;
uint32_t clip_left = 0;
uint32_t statusline_width = full_statusline_width;
bool use_short_text = false;
}
int16_t visible_statusline_width = MIN(statusline_width, max_statusline_width);
- int x_dest = outputs_walk->rect.w - tray_width - logical_px(sb_hoff_px) - visible_statusline_width;
+ int x_dest = outputs_walk->rect.w - tray_width - logical_px((tray_width > 0) * sb_hoff_px) - visible_statusline_width;
draw_statusline(outputs_walk, clip_left, use_focus_colors, use_short_text);
draw_util_copy_surface(&outputs_walk->statusline_buffer, &outputs_walk->buffer, 0, 0,
I3STRING_FREE(binding.name);
binding = *current;
activated_mode = binding.name != NULL;
- return;
}