diff options
| -rw-r--r-- | config.def.h | 5 | ||||
| -rw-r--r-- | glitch.h | 20 | ||||
| -rw-r--r-- | manager.c | 108 | ||||
| -rw-r--r-- | widgets.c | 53 |
4 files changed, 181 insertions, 5 deletions
diff --git a/config.def.h b/config.def.h index 67f78d0..a10d0f9 100644 --- a/config.def.h +++ b/config.def.h | |||
| @@ -28,6 +28,10 @@ static const char *mic_active_bg_color = "firebrick"; | |||
| 28 | static const char *mic_muted_bg_color = "#222222"; | 28 | static const char *mic_muted_bg_color = "#222222"; |
| 29 | static const char *mic_active_fg_color = "white"; | 29 | static const char *mic_active_fg_color = "white"; |
| 30 | static const char *mic_muted_fg_color = "white"; | 30 | static const char *mic_muted_fg_color = "white"; |
| 31 | static const char *layout_tile_bg_color = "darkgreen"; | ||
| 32 | static const char *layout_float_bg_color = "#333333"; | ||
| 33 | static const char *layout_tile_fg_color = "white"; | ||
| 34 | static const char *layout_float_fg_color = "white"; | ||
| 31 | 35 | ||
| 32 | static Shortcut shortcuts[] = { | 36 | static Shortcut shortcuts[] = { |
| 33 | /* Mask KeySym Shell command */ | 37 | /* Mask KeySym Shell command */ |
| @@ -87,6 +91,7 @@ static Keybinds keybinds[] = { | |||
| 87 | { MODKEY | ShiftMask, XK_r, reload, { 0 } }, | 91 | { MODKEY | ShiftMask, XK_r, reload, { 0 } }, |
| 88 | { MODKEY, XK_c, center_window, { 0 } }, | 92 | { MODKEY, XK_c, center_window, { 0 } }, |
| 89 | { MODKEY, XK_m, toggle_mic_mute, { 0 } }, | 93 | { MODKEY, XK_m, toggle_mic_mute, { 0 } }, |
| 94 | { MODKEY, XK_space, toggle_layout, { 0 } }, | ||
| 90 | { MODKEY | ShiftMask, XK_q, quit, { 0 } }, | 95 | { MODKEY | ShiftMask, XK_q, quit, { 0 } }, |
| 91 | { MODKEY, XK_q, close_window, { 0 } }, | 96 | { MODKEY, XK_q, close_window, { 0 } }, |
| 92 | }; | 97 | }; |
| @@ -32,6 +32,11 @@ typedef enum { | |||
| 32 | LOG_ERROR, | 32 | LOG_ERROR, |
| 33 | } LogLevel; | 33 | } LogLevel; |
| 34 | 34 | ||
| 35 | typedef enum { | ||
| 36 | LAYOUT_FLOATING, | ||
| 37 | LAYOUT_TILING, | ||
| 38 | } LayoutMode; | ||
| 39 | |||
| 35 | typedef struct { | 40 | typedef struct { |
| 36 | unsigned long normal_active; | 41 | unsigned long normal_active; |
| 37 | unsigned long normal_inactive; | 42 | unsigned long normal_inactive; |
| @@ -77,16 +82,23 @@ typedef struct { | |||
| 77 | XftColor xft_mic_muted_bg; | 82 | XftColor xft_mic_muted_bg; |
| 78 | XftColor xft_mic_active_fg; | 83 | XftColor xft_mic_active_fg; |
| 79 | XftColor xft_mic_muted_fg; | 84 | XftColor xft_mic_muted_fg; |
| 80 | 85 | XftColor xft_layout_tile_bg; | |
| 86 | XftColor xft_layout_float_bg; | ||
| 87 | XftColor xft_layout_tile_fg; | ||
| 88 | XftColor xft_layout_float_fg; | ||
| 89 | |||
| 81 | unsigned long last_widget_update; | 90 | unsigned long last_widget_update; |
| 82 | Client *clients; | 91 | Client *clients; |
| 83 | 92 | ||
| 84 | int is_cycling; | 93 | int is_cycling; |
| 85 | Window cycle_win; | 94 | Window cycle_win; |
| 86 | Window *cycle_clients; | 95 | Window *cycle_clients; |
| 87 | int cycle_count; | 96 | int cycle_count; |
| 88 | int active_cycle_index; | 97 | int active_cycle_index; |
| 89 | 98 | ||
| 99 | // Layout management | ||
| 100 | LayoutMode layout_modes[NUM_DESKTOPS + 1]; // 1-indexed for convenience | ||
| 101 | |||
| 90 | // PulseAudio | 102 | // PulseAudio |
| 91 | pa_threaded_mainloop *pa_mainloop; | 103 | pa_threaded_mainloop *pa_mainloop; |
| 92 | pa_context *pa_ctx; | 104 | pa_context *pa_ctx; |
| @@ -172,10 +184,14 @@ void center_window(const Arg *arg); | |||
| 172 | void widget_desktop_indicator(void); | 184 | void widget_desktop_indicator(void); |
| 173 | void widget_datetime(void); | 185 | void widget_datetime(void); |
| 174 | void widget_mic_indicator(void); | 186 | void widget_mic_indicator(void); |
| 187 | void widget_layout_indicator(void); | ||
| 175 | void redraw_widgets(void); | 188 | void redraw_widgets(void); |
| 176 | 189 | ||
| 177 | void init_audio(void); | 190 | void init_audio(void); |
| 178 | void deinit_audio(void); | 191 | void deinit_audio(void); |
| 179 | void toggle_mic_mute(const Arg *arg); | 192 | void toggle_mic_mute(const Arg *arg); |
| 180 | 193 | ||
| 194 | void apply_tiling_layout(void); | ||
| 195 | void toggle_layout(const Arg *arg); | ||
| 196 | |||
| 181 | #endif // GLITCH_H | 197 | #endif // GLITCH_H |
| @@ -253,6 +253,11 @@ void init_window_manager(void) { | |||
| 253 | XChangeProperty(wm.dpy, wm.root, _NET_CURRENT_DESKTOP, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)¤t_desktop, 1); | 253 | XChangeProperty(wm.dpy, wm.root, _NET_CURRENT_DESKTOP, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)¤t_desktop, 1); |
| 254 | log_message(stdout, LOG_DEBUG, "Registering %d desktops", NUM_DESKTOPS); | 254 | log_message(stdout, LOG_DEBUG, "Registering %d desktops", NUM_DESKTOPS); |
| 255 | 255 | ||
| 256 | // Initialize layout modes. | ||
| 257 | for (int i = 0; i <= NUM_DESKTOPS; i++) { | ||
| 258 | wm.layout_modes[i] = LAYOUT_FLOATING; | ||
| 259 | } | ||
| 260 | |||
| 256 | // Initialize colormap early as it's needed for Xft. | 261 | // Initialize colormap early as it's needed for Xft. |
| 257 | wm.cmap = DefaultColormap(wm.dpy, wm.screen); | 262 | wm.cmap = DefaultColormap(wm.dpy, wm.screen); |
| 258 | 263 | ||
| @@ -308,6 +313,30 @@ void init_window_manager(void) { | |||
| 308 | XftColorAllocValue(wm.dpy, visual, wm.cmap, &render_color, &wm.xft_mic_muted_fg); | 313 | XftColorAllocValue(wm.dpy, visual, wm.cmap, &render_color, &wm.xft_mic_muted_fg); |
| 309 | } | 314 | } |
| 310 | 315 | ||
| 316 | if (!XftColorAllocName(wm.dpy, visual, wm.cmap, layout_tile_bg_color, &wm.xft_layout_tile_bg)) { | ||
| 317 | log_message(stdout, LOG_WARNING, "Failed to allocate color %s, falling back to dark green", layout_tile_bg_color); | ||
| 318 | XRenderColor render_color = {0x0000, 0x6400, 0x0000, 0xFFFF}; | ||
| 319 | XftColorAllocValue(wm.dpy, visual, wm.cmap, &render_color, &wm.xft_layout_tile_bg); | ||
| 320 | } | ||
| 321 | |||
| 322 | if (!XftColorAllocName(wm.dpy, visual, wm.cmap, layout_float_bg_color, &wm.xft_layout_float_bg)) { | ||
| 323 | log_message(stdout, LOG_WARNING, "Failed to allocate color %s, falling back to gray", layout_float_bg_color); | ||
| 324 | XRenderColor render_color = {0x3333, 0x3333, 0x3333, 0xFFFF}; | ||
| 325 | XftColorAllocValue(wm.dpy, visual, wm.cmap, &render_color, &wm.xft_layout_float_bg); | ||
| 326 | } | ||
| 327 | |||
| 328 | if (!XftColorAllocName(wm.dpy, visual, wm.cmap, layout_tile_fg_color, &wm.xft_layout_tile_fg)) { | ||
| 329 | log_message(stdout, LOG_WARNING, "Failed to allocate color %s, falling back to white", layout_tile_fg_color); | ||
| 330 | XRenderColor render_color = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; | ||
| 331 | XftColorAllocValue(wm.dpy, visual, wm.cmap, &render_color, &wm.xft_layout_tile_fg); | ||
| 332 | } | ||
| 333 | |||
| 334 | if (!XftColorAllocName(wm.dpy, visual, wm.cmap, layout_float_fg_color, &wm.xft_layout_float_fg)) { | ||
| 335 | log_message(stdout, LOG_WARNING, "Failed to allocate color %s, falling back to white", layout_float_fg_color); | ||
| 336 | XRenderColor render_color = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; | ||
| 337 | XftColorAllocValue(wm.dpy, visual, wm.cmap, &render_color, &wm.xft_layout_float_fg); | ||
| 338 | } | ||
| 339 | |||
| 311 | wm.running = 1; | 340 | wm.running = 1; |
| 312 | 341 | ||
| 313 | scan_windows(); | 342 | scan_windows(); |
| @@ -641,7 +670,8 @@ void handle_map_request(void) { | |||
| 641 | grab_buttons(window); | 670 | grab_buttons(window); |
| 642 | 671 | ||
| 643 | add_client(window); | 672 | add_client(window); |
| 644 | 673 | apply_tiling_layout(); | |
| 674 | |||
| 645 | XSync(wm.dpy, False); | 675 | XSync(wm.dpy, False); |
| 646 | XSetErrorHandler(old); | 676 | XSetErrorHandler(old); |
| 647 | 677 | ||
| @@ -663,6 +693,7 @@ void handle_unmap_notify(void) { | |||
| 663 | } | 693 | } |
| 664 | 694 | ||
| 665 | log_message(stdout, LOG_DEBUG, "Window 0x%lx unmapped", window); | 695 | log_message(stdout, LOG_DEBUG, "Window 0x%lx unmapped", window); |
| 696 | apply_tiling_layout(); | ||
| 666 | update_client_list(); | 697 | update_client_list(); |
| 667 | } | 698 | } |
| 668 | 699 | ||
| @@ -673,6 +704,7 @@ void handle_destroy_notify(void) { | |||
| 673 | wm.active = None; | 704 | wm.active = None; |
| 674 | } | 705 | } |
| 675 | remove_client(window); | 706 | remove_client(window); |
| 707 | apply_tiling_layout(); | ||
| 676 | log_message(stdout, LOG_DEBUG, "Window 0x%lx destroyed", window); | 708 | log_message(stdout, LOG_DEBUG, "Window 0x%lx destroyed", window); |
| 677 | update_client_list(); | 709 | update_client_list(); |
| 678 | } | 710 | } |
| @@ -938,6 +970,7 @@ void goto_desktop(const Arg *arg) { | |||
| 938 | 970 | ||
| 939 | set_active_window(new_active, CurrentTime); | 971 | set_active_window(new_active, CurrentTime); |
| 940 | set_active_border(new_active); | 972 | set_active_border(new_active); |
| 973 | apply_tiling_layout(); | ||
| 941 | 974 | ||
| 942 | widget_desktop_indicator(); | 975 | widget_desktop_indicator(); |
| 943 | widget_datetime(); | 976 | widget_datetime(); |
| @@ -956,6 +989,7 @@ void send_window_to_desktop(const Arg *arg) { | |||
| 956 | XUnmapWindow(wm.dpy, wm.active); | 989 | XUnmapWindow(wm.dpy, wm.active); |
| 957 | 990 | ||
| 958 | wm.active = None; | 991 | wm.active = None; |
| 992 | apply_tiling_layout(); | ||
| 959 | widget_desktop_indicator(); | 993 | widget_desktop_indicator(); |
| 960 | widget_datetime(); | 994 | widget_datetime(); |
| 961 | log_message(stdout, LOG_DEBUG, "Moved window to desktop %d", arg->i); | 995 | log_message(stdout, LOG_DEBUG, "Moved window to desktop %d", arg->i); |
| @@ -1612,3 +1646,75 @@ void reload(const Arg *arg) { | |||
| 1612 | wm.restart = 1; | 1646 | wm.restart = 1; |
| 1613 | log_message(stdout, LOG_DEBUG, "Reload window manager"); | 1647 | log_message(stdout, LOG_DEBUG, "Reload window manager"); |
| 1614 | } | 1648 | } |
| 1649 | |||
| 1650 | void apply_tiling_layout(void) { | ||
| 1651 | if (wm.layout_modes[wm.current_desktop] != LAYOUT_TILING) return; | ||
| 1652 | |||
| 1653 | int n = 0; | ||
| 1654 | for (Client *c = wm.clients; c; c = c->next) { | ||
| 1655 | if (window_exists(c->window)) { | ||
| 1656 | unsigned long desktop; | ||
| 1657 | Atom actual_type; | ||
| 1658 | int actual_format; | ||
| 1659 | unsigned long nitems, bytes_after; | ||
| 1660 | unsigned char *prop = NULL; | ||
| 1661 | |||
| 1662 | int status = XGetWindowProperty(wm.dpy, c->window, _NET_WM_DESKTOP, 0, 1, False, XA_CARDINAL, &actual_type, &actual_format, &nitems, &bytes_after, &prop); | ||
| 1663 | if (status == Success && prop && nitems > 0) { | ||
| 1664 | desktop = *(unsigned long *)prop; | ||
| 1665 | XFree(prop); | ||
| 1666 | if (desktop == wm.current_desktop && !is_sticky(c->window) && !is_always_on_top(c->window) && !has_wm_state(c->window, _NET_WM_STATE_FULLSCREEN)) { | ||
| 1667 | n++; | ||
| 1668 | } | ||
| 1669 | } else if (prop) { | ||
| 1670 | XFree(prop); | ||
| 1671 | } | ||
| 1672 | } | ||
| 1673 | } | ||
| 1674 | |||
| 1675 | if (n == 0) return; | ||
| 1676 | |||
| 1677 | int screen_width = DisplayWidth(wm.dpy, wm.screen); | ||
| 1678 | int screen_height = DisplayHeight(wm.dpy, wm.screen); | ||
| 1679 | int mw = (n > 1) ? screen_width / 3 : screen_width; | ||
| 1680 | int i = 0; | ||
| 1681 | |||
| 1682 | for (Client *c = wm.clients; c; c = c->next) { | ||
| 1683 | if (window_exists(c->window)) { | ||
| 1684 | unsigned long desktop; | ||
| 1685 | Atom actual_type; | ||
| 1686 | int actual_format; | ||
| 1687 | unsigned long nitems, bytes_after; | ||
| 1688 | unsigned char *prop = NULL; | ||
| 1689 | |||
| 1690 | int status = XGetWindowProperty(wm.dpy, c->window, _NET_WM_DESKTOP, 0, 1, False, XA_CARDINAL, &actual_type, &actual_format, &nitems, &bytes_after, &prop); | ||
| 1691 | if (status == Success && prop && nitems > 0) { | ||
| 1692 | desktop = *(unsigned long *)prop; | ||
| 1693 | XFree(prop); | ||
| 1694 | if (desktop == wm.current_desktop && !is_sticky(c->window) && !is_always_on_top(c->window) && !has_wm_state(c->window, _NET_WM_STATE_FULLSCREEN)) { | ||
| 1695 | if (n == 1) { | ||
| 1696 | XMoveResizeWindow(wm.dpy, c->window, 0, 0, screen_width - 2 * border_size, screen_height - 2 * border_size); | ||
| 1697 | } else if (i == 0) { // Master | ||
| 1698 | XMoveResizeWindow(wm.dpy, c->window, 0, 0, mw - 2 * border_size, screen_height - 2 * border_size); | ||
| 1699 | } else { // Stack | ||
| 1700 | int h = screen_height / (n - 1); | ||
| 1701 | XMoveResizeWindow(wm.dpy, c->window, mw, (i - 1) * h, screen_width - mw - 2 * border_size, h - 2 * border_size); | ||
| 1702 | } | ||
| 1703 | i++; | ||
| 1704 | } | ||
| 1705 | } else if (prop) { | ||
| 1706 | XFree(prop); | ||
| 1707 | } | ||
| 1708 | } | ||
| 1709 | } | ||
| 1710 | } | ||
| 1711 | |||
| 1712 | void toggle_layout(const Arg *arg) { | ||
| 1713 | (void)arg; | ||
| 1714 | wm.layout_modes[wm.current_desktop] = (wm.layout_modes[wm.current_desktop] == LAYOUT_TILING) ? LAYOUT_FLOATING : LAYOUT_TILING; | ||
| 1715 | if (wm.layout_modes[wm.current_desktop] == LAYOUT_TILING) { | ||
| 1716 | apply_tiling_layout(); | ||
| 1717 | } | ||
| 1718 | redraw_widgets(); | ||
| 1719 | log_message(stdout, LOG_DEBUG, "Toggled layout for desktop %d to %s", wm.current_desktop, wm.layout_modes[wm.current_desktop] == LAYOUT_TILING ? "TILING" : "FLOATING"); | ||
| 1720 | } | ||
| @@ -44,13 +44,20 @@ void widget_mic_indicator(void) { | |||
| 44 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)desktop_buf, strlen(desktop_buf), &desktop_extents); | 44 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)desktop_buf, strlen(desktop_buf), &desktop_extents); |
| 45 | int desktop_size = (wm.font->height > desktop_extents.width ? wm.font->height : desktop_extents.width) + padding * 2; | 45 | int desktop_size = (wm.font->height > desktop_extents.width ? wm.font->height : desktop_extents.width) + padding * 2; |
| 46 | 46 | ||
| 47 | // Layout indicator size | ||
| 48 | LayoutMode mode = wm.layout_modes[wm.current_desktop]; | ||
| 49 | const char *layout_buf = (mode == LAYOUT_TILING) ? "T" : "F"; | ||
| 50 | XGlyphInfo layout_extents; | ||
| 51 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)layout_buf, strlen(layout_buf), &layout_extents); | ||
| 52 | int layout_size_w = (wm.font->height > layout_extents.width ? wm.font->height : layout_extents.width) + padding * 2; | ||
| 53 | |||
| 47 | const char *buf = "MIC"; | 54 | const char *buf = "MIC"; |
| 48 | XGlyphInfo extents; | 55 | XGlyphInfo extents; |
| 49 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)buf, strlen(buf), &extents); | 56 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)buf, strlen(buf), &extents); |
| 50 | 57 | ||
| 51 | int size_w = extents.width + padding * 4; | 58 | int size_w = extents.width + padding * 4; |
| 52 | int size_h = desktop_size; | 59 | int size_h = desktop_size; |
| 53 | int x = screen_width - desktop_size - size_w - 20; | 60 | int x = screen_width - desktop_size - layout_size_w - size_w - 20; |
| 54 | int y = 10; | 61 | int y = 10; |
| 55 | 62 | ||
| 56 | XftColor *bg = wm.mic_muted ? &wm.xft_mic_muted_bg : &wm.xft_mic_active_bg; | 63 | XftColor *bg = wm.mic_muted ? &wm.xft_mic_muted_bg : &wm.xft_mic_active_bg; |
| @@ -66,6 +73,40 @@ void widget_mic_indicator(void) { | |||
| 66 | XftDrawStringUtf8(wm.xft_draw, fg, wm.font, text_x, text_y, (FcChar8 *)buf, strlen(buf)); | 73 | XftDrawStringUtf8(wm.xft_draw, fg, wm.font, text_x, text_y, (FcChar8 *)buf, strlen(buf)); |
| 67 | } | 74 | } |
| 68 | 75 | ||
| 76 | void widget_layout_indicator(void) { | ||
| 77 | int screen_width = DisplayWidth(wm.dpy, wm.screen); | ||
| 78 | int padding = 3; | ||
| 79 | |||
| 80 | // Desktop indicator size | ||
| 81 | char desktop_buf[8]; | ||
| 82 | snprintf(desktop_buf, sizeof(desktop_buf), "%u", wm.current_desktop); | ||
| 83 | XGlyphInfo desktop_extents; | ||
| 84 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)desktop_buf, strlen(desktop_buf), &desktop_extents); | ||
| 85 | int desktop_size = (wm.font->height > desktop_extents.width ? wm.font->height : desktop_extents.width) + padding * 2; | ||
| 86 | |||
| 87 | LayoutMode mode = wm.layout_modes[wm.current_desktop]; | ||
| 88 | const char *buf = (mode == LAYOUT_TILING) ? "T" : "F"; | ||
| 89 | XGlyphInfo extents; | ||
| 90 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)buf, strlen(buf), &extents); | ||
| 91 | |||
| 92 | int size_w = (wm.font->height > extents.width ? wm.font->height : extents.width) + padding * 2; | ||
| 93 | int size_h = desktop_size; | ||
| 94 | int x = screen_width - desktop_size - size_w - 15; | ||
| 95 | int y = 10; | ||
| 96 | |||
| 97 | XftColor *bg = (mode == LAYOUT_TILING) ? &wm.xft_layout_tile_bg : &wm.xft_layout_float_bg; | ||
| 98 | XftColor *fg = (mode == LAYOUT_TILING) ? &wm.xft_layout_tile_fg : &wm.xft_layout_float_fg; | ||
| 99 | |||
| 100 | // Draw the background. | ||
| 101 | XftDrawRect(wm.xft_draw, bg, x, y, size_w, size_h); | ||
| 102 | |||
| 103 | // Center the text. | ||
| 104 | int text_x = x + (size_w - extents.width) / 2 + extents.x; | ||
| 105 | int text_y = y + (size_h - wm.font->ascent - wm.font->descent) / 2 + wm.font->ascent; | ||
| 106 | |||
| 107 | XftDrawStringUtf8(wm.xft_draw, fg, wm.font, text_x, text_y, (FcChar8 *)buf, strlen(buf)); | ||
| 108 | } | ||
| 109 | |||
| 69 | void widget_datetime(void) { | 110 | void widget_datetime(void) { |
| 70 | int screen_width = DisplayWidth(wm.dpy, wm.screen); | 111 | int screen_width = DisplayWidth(wm.dpy, wm.screen); |
| 71 | int padding = 3; | 112 | int padding = 3; |
| @@ -77,13 +118,20 @@ void widget_datetime(void) { | |||
| 77 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)desktop_buf, strlen(desktop_buf), &desktop_extents); | 118 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)desktop_buf, strlen(desktop_buf), &desktop_extents); |
| 78 | int desktop_size = (wm.font->height > desktop_extents.width ? wm.font->height : desktop_extents.width) + padding * 2; | 119 | int desktop_size = (wm.font->height > desktop_extents.width ? wm.font->height : desktop_extents.width) + padding * 2; |
| 79 | 120 | ||
| 121 | // Layout indicator size | ||
| 122 | LayoutMode mode = wm.layout_modes[wm.current_desktop]; | ||
| 123 | const char *layout_buf = (mode == LAYOUT_TILING) ? "T" : "F"; | ||
| 124 | XGlyphInfo layout_extents; | ||
| 125 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)layout_buf, strlen(layout_buf), &layout_extents); | ||
| 126 | int layout_size_w = (wm.font->height > layout_extents.width ? wm.font->height : layout_extents.width) + padding * 2; | ||
| 127 | |||
| 80 | // Mic indicator size | 128 | // Mic indicator size |
| 81 | const char *mic_buf = "MIC"; | 129 | const char *mic_buf = "MIC"; |
| 82 | XGlyphInfo mic_extents; | 130 | XGlyphInfo mic_extents; |
| 83 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)mic_buf, strlen(mic_buf), &mic_extents); | 131 | XftTextExtentsUtf8(wm.dpy, wm.font, (FcChar8 *)mic_buf, strlen(mic_buf), &mic_extents); |
| 84 | int mic_size_w = mic_extents.width + padding * 4; | 132 | int mic_size_w = mic_extents.width + padding * 4; |
| 85 | 133 | ||
| 86 | int offset_x = desktop_size + mic_size_w + 40; | 134 | int offset_x = desktop_size + layout_size_w + mic_size_w + 35; |
| 87 | 135 | ||
| 88 | char time_buf[64]; | 136 | char time_buf[64]; |
| 89 | time_t now = time(NULL); | 137 | time_t now = time(NULL); |
| @@ -107,6 +155,7 @@ void widget_datetime(void) { | |||
| 107 | 155 | ||
| 108 | void redraw_widgets(void) { | 156 | void redraw_widgets(void) { |
| 109 | widget_desktop_indicator(); | 157 | widget_desktop_indicator(); |
| 158 | widget_layout_indicator(); | ||
| 110 | widget_mic_indicator(); | 159 | widget_mic_indicator(); |
| 111 | widget_datetime(); | 160 | widget_datetime(); |
| 112 | } | 161 | } |
