diff options
Diffstat (limited to 'desktop/bar/patches/bar-monitor-option.patch')
-rw-r--r-- | desktop/bar/patches/bar-monitor-option.patch | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/desktop/bar/patches/bar-monitor-option.patch b/desktop/bar/patches/bar-monitor-option.patch new file mode 100644 index 0000000000..d5c5fafa0d --- /dev/null +++ b/desktop/bar/patches/bar-monitor-option.patch @@ -0,0 +1,300 @@ +diff --git a/README.pod b/README.pod +index 565f188..2d2075d 100644 +--- a/README.pod ++++ b/README.pod +@@ -4,7 +4,7 @@ bar - bar ain't recursive + + =head1 SYNOPSIS + +-I<bar> [-h | -g I<width>B<x>I<height>B<+>I<x> | -b | -d | -f I<font> | -p | -u I<pixel> | -B I<color> | -F I<color>] ++I<bar> [-h | -g I<width>B<x>I<height>B<+>I<x> | -m I<monitor>B<:>I<monitor>B<:>... | -b | -d | -f I<font> | -p | -u I<pixel> | -B I<color> | -F I<color>] + + =head1 DESCRIPTION + +@@ -22,6 +22,10 @@ Display the help and exit. + + Set the window geometry. If a parameter is omitted it's filled with the default value. + ++=item B<-m> I<monitor>B<:>I<monitor>B<:>I<...> ++ ++Set monitors to be used and in what order. Positive numeric arguments only, separated by colons. ++ + =item B<-b> + + Dock the bar at the bottom of the screen. +diff --git a/bar.c b/bar.c +index 1ccc907..0f9f694 100644 +--- a/bar.c ++++ b/bar.c +@@ -17,6 +17,8 @@ + #define max(a,b) ((a) > (b) ? (a) : (b)) + #define min(a,b) ((a) < (b) ? (a) : (b)) + #define indexof(c,s) (strchr((s),(c))-(s)) ++#define MONITORS_MAX 32 ++#define N 10 + + typedef struct font_t { + xcb_font_t ptr; +@@ -39,8 +41,6 @@ typedef struct area_t { + char *cmd; + } area_t; + +-#define N 10 +- + typedef struct area_stack_t { + int pos; + area_t slot[N]; +@@ -80,6 +80,9 @@ static char *mfont, *afont; + static uint32_t fgc, bgc, ugc; + static uint32_t dfgc, dbgc; + static area_stack_t astack; ++static uint32_t mons = 0; ++static int nmons = 0; ++static int monlist[MONITORS_MAX]; + + void + update_gc (void) +@@ -302,7 +305,8 @@ parse (char *text) + + memset(&astack, 0, sizeof(area_stack_t)); + +- fill_rect(cur_mon->pixmap, gc[GC_CLEAR], 0, 0, bw, bh); ++ for (monitor_t *m = monhead; m; m = m->next) ++ fill_rect(m->pixmap, gc[GC_CLEAR], 0, 0, bw, bh); + + for (;;) { + if (*p == '\0' || *p == '\n') +@@ -356,7 +360,6 @@ parse (char *text) + + p++; + pos_x = 0; +- fill_rect(cur_mon->pixmap, gc[GC_CLEAR], 0, 0, cur_mon->width, bh); + break; + + /* In case of error keep parsing after the closing } */ +@@ -562,14 +565,40 @@ rect_sort_cb (const void *p1, const void *p2) + void + monitor_create_chain (xcb_rectangle_t *rects, const int num) + { +- int width = bw; ++ int i, cnt; ++ int width = 0; + int left = bx; + + /* Sort before use */ + qsort(rects, num, sizeof(xcb_rectangle_t), rect_sort_cb); + ++ if (nmons) { ++ xcb_rectangle_t r[num]; ++ /* Get combined width of specified monitors and set aside specified monitors */ ++ for (i = cnt = 0; i < nmons; i++) { ++ if (monlist[i] >= num) { ++ fprintf(stderr, "Specified monitor %d not found\n", monlist[i]); ++ continue; ++ } ++ width += rects[monlist[i]].width; ++ memcpy(&r[cnt++], &rects[monlist[i]], sizeof(xcb_rectangle_t)); ++ } ++ memcpy(rects, r, cnt * sizeof(xcb_rectangle_t)); ++ } ++ else { ++ /* Else default to X screen width */ ++ width = scr->width_in_pixels; ++ cnt = num; ++ } ++ ++ /* If I fits I sits */ ++ if (bw < 0) ++ bw = width - bx; ++ else ++ width = bw - bx; ++ + /* Left is a positive number or zero therefore monitors with zero width are excluded */ +- for (int i = 0; i < num; i++) { ++ for (int i = 0; i < cnt; i++) { + if (rects[i].width > left) { + monitor_t *mon = monitor_new( + rects[i].x + left, +@@ -598,7 +627,7 @@ get_randr_monitors (void) + { + xcb_randr_get_screen_resources_current_reply_t *rres_reply; + xcb_randr_output_t *outputs; +- int num, valid = 0; ++ int i, j, num, valid = 0; + + rres_reply = xcb_randr_get_screen_resources_current_reply(c, + xcb_randr_get_screen_resources_current(c, scr->root), NULL); +@@ -621,7 +650,7 @@ get_randr_monitors (void) + xcb_rectangle_t rects[num]; + + /* Get all outputs */ +- for (int i = 0; i < num; i++) { ++ for (i = 0; i < num; i++) { + xcb_randr_get_output_info_reply_t *oi_reply; + xcb_randr_get_crtc_info_reply_t *ci_reply; + +@@ -657,11 +686,11 @@ get_randr_monitors (void) + free(rres_reply); + + /* Check for clones and inactive outputs */ +- for (int i = 0; i < num; i++) { ++ for (i = 0; i < num; i++) { + if (rects[i].width == 0) + continue; + +- for (int j = 0; j < num; j++) { ++ for (j = 0; j < num; j++) { + /* Does I countain J ? */ + + if (i != j && rects[j].width) { +@@ -679,7 +708,20 @@ get_randr_monitors (void) + return; + } + ++ /* Use allocated array to pass to monitor_create_chain, the dynamic will out of scope */ ++ xcb_rectangle_t *r = malloc(valid * sizeof(xcb_rectangle_t)); ++ if (!r) { ++ fprintf(stderr, "Malloc failed!\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ /* Copy only used monitors */ ++ for (i = j = 0; i < num && j < valid; i++) ++ if (rects[i].width) ++ memcpy(&r[j++], &rects[i], sizeof(xcb_rectangle_t)); ++ + monitor_create_chain(rects, num); ++ free(r); + } + + void +@@ -695,7 +737,11 @@ get_xinerama_monitors (void) + iter = xcb_xinerama_query_screens_screen_info_iterator(xqs_reply); + screens = iter.rem; + +- xcb_rectangle_t rects[screens]; ++ xcb_rectangle_t *rects = malloc(screens * sizeof(xcb_rectangle_t)); ++ if (!rects) { ++ fprintf(stderr, "Malloc failed!\n"); ++ exit(EXIT_FAILURE); ++ } + + /* Fetch all the screens first */ + for (int i = 0; iter.rem; i++) { +@@ -709,6 +755,7 @@ get_xinerama_monitors (void) + free(xqs_reply); + + monitor_create_chain(rects, screens); ++ free(rects); + } + + xcb_visualid_t +@@ -755,10 +802,6 @@ xconn (void) + void + init (void) + { +- /* If I fits I sits */ +- if (bw < 0) +- bw = scr->width_in_pixels - bx; +- + /* Load the fonts */ + main_font = font_load(mfont ? mfont : "fixed"); + if (!main_font) +@@ -801,9 +844,14 @@ init (void) + } + } + +- if (!monhead) ++ if (!monhead) { ++ /* If I fits I sits */ ++ if (bw < 0) ++ bw = scr->width_in_pixels - bx; ++ + /* If no RandR outputs or Xinerama screens, fall back to using whole screen */ + monhead = monitor_new(0, 0, bw, scr->height_in_pixels); ++ } + + if (!monhead) + exit(EXIT_FAILURE); +@@ -921,6 +969,44 @@ parse_geometry_string (char *str, int *tmp) + return true; + } + ++bool ++parse_monitor_string (char *str) ++{ ++ char *p = str; ++ int i = 0, j; ++ ++ if (!str || !*str) ++ return false; ++ ++ while (*p) { ++ /* Skip separator */ ++ if (*p == ':' || *p == ',') ++ if (!*++p) ++ break; ++ /* A digit must follow */ ++ if (!isdigit(*p)) { ++ fprintf(stderr, "Invalid monitor specified\n"); ++ return false; ++ } ++ /* Try to parse the number */ ++ errno = 0; ++ j = strtoul(p, &p, 10); ++ if (errno || j >= MONITORS_MAX) { ++ fprintf(stderr, "Monitor value out of range\n"); ++ return false; ++ } ++ ++ if (j >= MONITORS_MAX || j < 0) { ++ fprintf(stderr, "Invalid monitor specified: %d\n", j); ++ continue; ++ } ++ mons |= 1 << j; ++ monlist[nmons++] = j; ++ } ++ ++ return true; ++} ++ + void + parse_font_list (char *str) + { +@@ -968,12 +1054,13 @@ main (int argc, char **argv) + ugc = fgc; + + char ch; +- while ((ch = getopt(argc, argv, "hg:bdf:a:pu:B:F:")) != -1) { ++ while ((ch = getopt(argc, argv, "hg:m:bdf:a:pu:B:F:")) != -1) { + switch (ch) { + case 'h': +- printf ("usage: %s [-h | -g | -b | -d | -f | -a | -p | -u | -B | -F]\n" ++ printf ("usage: %s [-h | -g | -m | -b | -d | -f | -a | -p | -u | -B | -F]\n" + "\t-h Show this help\n" + "\t-g Set the bar geometry {width}x{height})\n" ++ "\t-m Set monitors to use and in what order {0:2:1...}\n" + "\t-b Put bar at the bottom of the screen\n" + "\t-d Force docking (use this if your WM isn't EWMH compliant)\n" + "\t-f Bar font list, comma separated\n" +@@ -983,6 +1070,7 @@ main (int argc, char **argv) + "\t-F Set foreground color in #AARRGGBB\n", argv[0]); + exit (EXIT_SUCCESS); + case 'g': (void)parse_geometry_string(optarg, geom_v); break; ++ case 'm': (void)parse_monitor_string(optarg); break; + case 'p': permanent = true; break; + case 'b': topbar = false; break; + case 'd': dock = true; break; +@@ -998,12 +1086,6 @@ main (int argc, char **argv) + bh = geom_v[1]; + bx = geom_v[2]; + +- /* Check the geometry */ +- if (bx >= scr->width_in_pixels || bx + bw > scr->width_in_pixels) { +- fprintf(stderr, "The geometry specified doesn't fit the screen!\n"); +- return EXIT_FAILURE; +- } +- + /* Do the heavy lifting */ + init(); + /* Get the fd to Xserver */ |