const unsigned int calc_height = 570;
const int xephyr_width = 450; /* Set your desired pixel width */
-const float centered_height = .95;
-// const float centered_width = .65;
-const float centered_width = .75;
+// const float centered_height = .95;
+// const float centered_width = .75;
+/* centered_width and centered_height per monitor */
+static const float centered_width[] = { 0.75, 0.60 };
+static const float centered_height[] = { 0.95, 0.95 };
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
static char tags[][MAX_TAGNAME_LEN] = { "1\0", "2\0", "3\0", "4\0", "5\0"};
+/* layout(s) */
+static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */
+static const int nmaster = 1; /* number of clients in master area */
+static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
+static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
+static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */
+
+static const Layout layouts[] = {
+ /* symbol arrange function */
+ { "[]=", tile }, /* first entry is default */
+ { "><>", NULL }, /* no layout function means floating behavior */
+ { "[M]", monocle },
+ { "|M|", centeredmaster },
+ // { ">M>", centeredfloatingmaster },
+};
+
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
*/
// Keep ffplay floating a and in all tags for facecam script
// last tag is for calendar
- /* class instance title tags mask isfloating isCentered isSidePanel monitor resize hint*/
+ /* class instance title tags mask isfloating isCentered isSidePanel monitor resize hint layout switchto*/
//
- { NULL, NULL, NULL, 0, 1, 1, 0, -1, 0 },
- { NULL, NULL, "facecam", (1<<4)-1, 0, 0, 1, -1, 1, },
- // { "SpeedCrunch", NULL, "calculator", 0, 1, 0, 0, -1, 0, },
- { "SpeedCrunch", NULL, "calculator", 0, 0, 0, 1, -1, 0, },
- //{ "SpeedCrunch", NULL, "SpeedCrunch", 0, 0, 0, 0, -1, 1, },
- { NULL, NULL, "youtube-upload", (1<<9)-1, 1, 0, 0, -1, 0, },
- { NULL, NULL, "Calendar", 0, 0, 0, 0, -1, 0, },
- { "Xephyr", NULL, NULL, 0, 0, 0, 1, -1, 0, },
- { "Brave-browser", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "Alacritty", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "Zathura", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "steam", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "steam", NULL, "Friends List", 0, 0, 0, 1, -1, 1, },
- { "steam", NULL, "Steam Settings", 0, 1, 0, 0, -1, 0, },
- { "Gimp", NULL, "Open Image", 0, 1, 1, 0, -1, 0, },
- { "Gimp", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "discord", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "Blender", NULL,"Blender File View", 0, 1, 1, 0, -1, 0 },
- { "Blender", NULL,"Blender Render", 0, 0, 0, 1, -1, 0 },
- { "Blender", NULL, NULL, 0, 0, 1, 0, -1, 0 },
- { NULL, NULL, "note", 0, 1, 0, 0, -1, 0, },
- { NULL, NULL, "pulsemixer", (1<<9)-1, 1, 0, 0, -1, 0, },
- { NULL, NULL, "htop", (1<<9)-1, 1, 0, 0, -1, 0, },
- // { NULL, NULL, NULL, 0, 0, 1, 0, -1 },
+ { NULL, NULL, NULL, 0, 1, 1, 0, -1, 0, NULL, 0},
+ { NULL, NULL, "facecam", (1<<4)-1, 0, 0, 1, 1, 1, NULL, 0},
+ // { "SpeedCrunch", NULL, "calculator", 0, 1, 0, 0, -1, 0, NULL, 0},
+ { "SpeedCrunch", NULL, "calculator", 0, 0, 0, 1, 1, 0, NULL, 1},
+ //{ "SpeedCrunch", NULL, "SpeedCrunch", 0, 0, 0, 0, -1, 1, NULL, 0},
+ { NULL, NULL, "youtube-upload", (1<<9)-1, 1, 0, 0, -1, 0, NULL, 0},
+ { NULL, NULL, "Calendar", 0, 0, 0, 0, 1, 0, NULL, 1},
+ { "Xephyr", NULL, NULL, 0, 0, 0, 1, 1, 0, NULL, 1},
+ { "Brave-browser", NULL, NULL, 1<<0, 0, 1, 0, 1, 0, NULL, 1},
+ { "Alacritty", NULL, NULL, 1<<0, 0, 1, 0, 0, 0, NULL, 1},
+ { "Zathura", NULL, NULL, 1<<0, 0, 1, 0, 1, 0, &layouts[2], 1},
+ { "steam", NULL, NULL, 1<<1, 0, 1, 0, 0, 0, &layouts[2], 0},
+ { "steam", NULL, "Friends List", 1<<1, 0, 0, 1, 1, 1, NULL, 0},
+ { "steam", NULL, "Steam Settings", 0, 1, 0, 0, 0, 0, NULL, 0},
+ { "Gimp", NULL, "Open Image", 1<<1, 1, 1, 0, 0, 0, &layouts[2], 1},
+ { "Gimp", NULL, NULL, 1<<1, 0, 1, 0, 0, 0, &layouts[2], 1},
+ { "discord", NULL, NULL, 1<<1, 0, 1, 0, 1, 0, &layouts[2], 0},
+ { "Blender", NULL,"Blender File View", 1<<1, 1, 1, 0, 0, 0, &layouts[2], 1},
+ { "Blender", NULL,"Blender Render", 1<<1, 0, 0, 1, 0, 0, &layouts[2], 1},
+ { "Blender", NULL, NULL, 1<<1, 0, 1, 0, 0, 0, &layouts[2], 1},
+ { NULL, NULL, "note", 0, 1, 0, 0, -1, 0, NULL, 0},
+ { NULL, NULL, "pulsemixer", (1<<9)-1, 1, 0, 0, 1, 0, NULL, 1},
+ { NULL, NULL, "htop", (1<<9)-1, 1, 0, 0, 1, 0, NULL, 1},
+ // { NULL, NULL, NULL, 0, 0, 1, 0, -1 },
// there is a possibility to need a terminal in misc tag as well..
// { NULL, NULL, "Alacritty", 1 << 0, 0, -1 },
// { "KeePassXC", NULL, NULL, 1 << 4, 0, -1 },
};
-/* layout(s) */
-static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */
-static const int nmaster = 1; /* number of clients in master area */
-static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
-static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
-static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
- { "|M|", centeredmaster },
- // { ">M>", centeredfloatingmaster },
-};
-
const char *
geticon(char *class)
{
static const char *voldowncmd[] = { "/usr/local/bin/dwm_volume_down", NULL };
static const char *volmutecmd[] = { "/usr/local/bin/dwm_volume_mute", NULL };
static const char *mixercmd[] = { "/usr/local/bin/dwm-term-toggle", "pulsemixer", NULL };
-static const char *calccmd[] = { "/usr/local/bin/dwm-speedcrunch-toggle", NULL };
static const char *calc_mcw_cmd[] = { "/usr/local/bin/dwm-speedcrunch-move", "cw", NULL };
static const char *calc_mccw_cmd[] = { "/usr/local/bin/dwm-speedcrunch-move", "ccw", NULL };
static const char *facecamcmd[] = { "/usr/local/bin/facecam", NULL };
{ MODKEY, XK_F3, spawn, {.v = volupcmd } },
{ MODKEY, XK_F4, spawn, {.v = volmutecmd } },
{ MODKEY|ShiftMask, XK_m, spawn, {.v = cpucmd } },
- { MODKEY|ShiftMask, XK_e, spawn, {.v = calccmd } },
- { MODKEY, XK_e, spawn, {.v = calc_mccw_cmd } },
- { MODKEY|ControlMask, XK_e, spawn, {.v = calc_mcw_cmd } },
+ // { MODKEY, XK_e, spawn, {.v = calc_mccw_cmd } },
+ // { MODKEY|ControlMask, XK_e, spawn, {.v = calc_mcw_cmd } },
+ { MODKEY, XK_o, focuscalculator, {0} },
{ MODKEY|ShiftMask, XK_f, spawn, {.v = facecamcmd } },
{ MODKEY|ShiftMask, XK_b, spawn, {.v = brightnesscmd} },
{ MODKEY|ShiftMask, XK_p, spawn, {.v = calendarcmd} },
const unsigned int calc_height = 570;
const int xephyr_width = 450; /* Set your desired pixel width */
-const float centered_height = .95;
-// const float centered_width = .65;
-const float centered_width = .75;
+// const float centered_height = .95;
+// const float centered_width = .75;
+/* centered_width and centered_height per monitor */
+static const float centered_width[] = { 0.75, 0.60 };
+static const float centered_height[] = { 0.95, 0.95 };
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
static char tags[][MAX_TAGNAME_LEN] = { "1\0", "2\0", "3\0", "4\0", "5\0"};
+/* layout(s) */
+static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */
+static const int nmaster = 1; /* number of clients in master area */
+static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
+static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
+static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */
+
+static const Layout layouts[] = {
+ /* symbol arrange function */
+ { "[]=", tile }, /* first entry is default */
+ { "><>", NULL }, /* no layout function means floating behavior */
+ { "[M]", monocle },
+ { "|M|", centeredmaster },
+ // { ">M>", centeredfloatingmaster },
+};
+
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
*/
// Keep ffplay floating a and in all tags for facecam script
// last tag is for calendar
- /* class instance title tags mask isfloating isCentered isSidePanel monitor resize hint*/
+ /* class instance title tags mask isfloating isCentered isSidePanel monitor resize hint layout switchto*/
//
- { NULL, NULL, NULL, 0, 1, 1, 0, -1, 0 },
- { NULL, NULL, "facecam", (1<<4)-1, 0, 0, 1, -1, 1, },
- // { "SpeedCrunch", NULL, "calculator", 0, 1, 0, 0, -1, 0, },
- { "SpeedCrunch", NULL, "calculator", 0, 0, 0, 1, -1, 0, },
- //{ "SpeedCrunch", NULL, "SpeedCrunch", 0, 0, 0, 0, -1, 1, },
- { NULL, NULL, "youtube-upload", (1<<9)-1, 1, 0, 0, -1, 0, },
- { NULL, NULL, "Calendar", 0, 0, 0, 0, -1, 0, },
- { "Xephyr", NULL, NULL, 0, 0, 0, 1, -1, 0, },
- { "Brave-browser", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "Alacritty", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "Zathura", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "steam", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "steam", NULL, "Friends List", 0, 0, 0, 1, -1, 1, },
- { "steam", NULL, "Steam Settings", 0, 1, 0, 0, -1, 0, },
- { "Gimp", NULL, "Open Image", 0, 1, 1, 0, -1, 0, },
- { "Gimp", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "discord", NULL, NULL, 0, 0, 1, 0, -1, 0, },
- { "Blender", NULL,"Blender File View", 0, 1, 1, 0, -1, 0 },
- { "Blender", NULL,"Blender Render", 0, 0, 0, 1, -1, 0 },
- { "Blender", NULL, NULL, 0, 0, 1, 0, -1, 0 },
- { NULL, NULL, "note", 0, 1, 0, 0, -1, 0, },
- { NULL, NULL, "pulsemixer", (1<<9)-1, 1, 0, 0, -1, 0, },
- { NULL, NULL, "htop", (1<<9)-1, 1, 0, 0, -1, 0, },
- // { NULL, NULL, NULL, 0, 0, 1, 0, -1 },
+ { NULL, NULL, NULL, 0, 1, 1, 0, -1, 0, NULL, 0},
+ { NULL, NULL, "facecam", (1<<4)-1, 0, 0, 1, 1, 1, NULL, 0},
+ // { "SpeedCrunch", NULL, "calculator", 0, 1, 0, 0, -1, 0, NULL, 0},
+ { "SpeedCrunch", NULL, "calculator", 0, 0, 0, 1, 1, 0, NULL, 1},
+ //{ "SpeedCrunch", NULL, "SpeedCrunch", 0, 0, 0, 0, -1, 1, NULL, 0},
+ { NULL, NULL, "youtube-upload", (1<<9)-1, 1, 0, 0, -1, 0, NULL, 0},
+ { NULL, NULL, "Calendar", 0, 0, 0, 0, 1, 0, NULL, 1},
+ { "Xephyr", NULL, NULL, 0, 0, 0, 1, 1, 0, NULL, 1},
+ { "Brave-browser", NULL, NULL, 1<<0, 0, 1, 0, 1, 0, NULL, 1},
+ { "Alacritty", NULL, NULL, 1<<0, 0, 1, 0, 0, 0, NULL, 1},
+ { "Zathura", NULL, NULL, 1<<0, 0, 1, 0, 1, 0, &layouts[2], 1},
+ { "steam", NULL, NULL, 1<<1, 0, 1, 0, 0, 0, &layouts[2], 0},
+ { "steam", NULL, "Friends List", 1<<1, 0, 0, 1, 1, 1, NULL, 0},
+ { "steam", NULL, "Steam Settings", 0, 1, 0, 0, 0, 0, NULL, 0},
+ { "Gimp", NULL, "Open Image", 1<<1, 1, 1, 0, 0, 0, &layouts[2], 1},
+ { "Gimp", NULL, NULL, 1<<1, 0, 1, 0, 0, 0, &layouts[2], 1},
+ { "discord", NULL, NULL, 1<<1, 0, 1, 0, 1, 0, &layouts[2], 0},
+ { "Blender", NULL,"Blender File View", 1<<1, 1, 1, 0, 0, 0, &layouts[2], 1},
+ { "Blender", NULL,"Blender Render", 1<<1, 0, 0, 1, 0, 0, &layouts[2], 1},
+ { "Blender", NULL, NULL, 1<<1, 0, 1, 0, 0, 0, &layouts[2], 1},
+ { NULL, NULL, "note", 0, 1, 0, 0, -1, 0, NULL, 0},
+ { NULL, NULL, "pulsemixer", (1<<9)-1, 1, 0, 0, 1, 0, NULL, 1},
+ { NULL, NULL, "htop", (1<<9)-1, 1, 0, 0, 1, 0, NULL, 1},
+ // { NULL, NULL, NULL, 0, 0, 1, 0, -1 },
// there is a possibility to need a terminal in misc tag as well..
// { NULL, NULL, "Alacritty", 1 << 0, 0, -1 },
// { "KeePassXC", NULL, NULL, 1 << 4, 0, -1 },
};
-/* layout(s) */
-static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */
-static const int nmaster = 1; /* number of clients in master area */
-static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
-static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
-static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
- { "|M|", centeredmaster },
- // { ">M>", centeredfloatingmaster },
-};
-
const char *
geticon(char *class)
{
static const char *voldowncmd[] = { "/usr/local/bin/dwm_volume_down", NULL };
static const char *volmutecmd[] = { "/usr/local/bin/dwm_volume_mute", NULL };
static const char *mixercmd[] = { "/usr/local/bin/dwm-term-toggle", "pulsemixer", NULL };
-static const char *calccmd[] = { "/usr/local/bin/dwm-speedcrunch-toggle", NULL };
static const char *calc_mcw_cmd[] = { "/usr/local/bin/dwm-speedcrunch-move", "cw", NULL };
static const char *calc_mccw_cmd[] = { "/usr/local/bin/dwm-speedcrunch-move", "ccw", NULL };
static const char *facecamcmd[] = { "/usr/local/bin/facecam", NULL };
{ MODKEY, XK_F3, spawn, {.v = volupcmd } },
{ MODKEY, XK_F4, spawn, {.v = volmutecmd } },
{ MODKEY|ShiftMask, XK_m, spawn, {.v = cpucmd } },
- { MODKEY|ShiftMask, XK_e, spawn, {.v = calccmd } },
- { MODKEY, XK_e, spawn, {.v = calc_mccw_cmd } },
- { MODKEY|ControlMask, XK_e, spawn, {.v = calc_mcw_cmd } },
+ // { MODKEY, XK_e, spawn, {.v = calc_mccw_cmd } },
+ // { MODKEY|ControlMask, XK_e, spawn, {.v = calc_mcw_cmd } },
+ { MODKEY, XK_o, focuscalculator, {0} },
{ MODKEY|ShiftMask, XK_f, spawn, {.v = facecamcmd } },
{ MODKEY|ShiftMask, XK_b, spawn, {.v = brightnesscmd} },
{ MODKEY|ShiftMask, XK_p, spawn, {.v = calendarcmd} },
int bw, oldbw;
int isPopup;
unsigned int tags;
- int isfixed, iscentered, isfloating, isSidePanel, isurgent, neverfocus, oldstate, isfullscreen, resizehints;
+ int isfixed, iscentered, isfloating, isSidePanel, isurgent, neverfocus,
+ oldstate, isfullscreen, resizehints, explicit_tags, explicit_monitor,
+ switchto;
Client *next;
Client *snext;
Monitor *mon;
int isSidePanel;
int monitor;
int resizehints;
+ const Layout *layout;
+ int switchto;
} Rule;
unsigned char one_window = 0;
/* function declarations */
-static void setopacity(Client *c, double opacity);
static void applyrules(Client *c);
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
static void arrange(Monitor *m);
static void zoom(const Arg *arg);
static void centeredmaster(Monitor *m);
static void centeredfloatingmaster(Monitor *m);
+static void update_alacritty_opacity(Monitor *m);
+static void focuscalculator(const Arg *arg);
/* variables */
static const char broken[] = "broken";
}
}
-void
-update_alacritty_opacity(Monitor *m)
-{
- static double last_opacity = -1.0;
- if (!m || !m->lt[m->sellt])
- return;
-
- double target_opacity = (m->lt[m->sellt]->arrange == monocle) ? 1.0 : 0.93;
-
- /* Only send IPC message if opacity state changed to prevent unnecessary commands */
- if (target_opacity != last_opacity) {
- char cmd[128];
- snprintf(cmd, sizeof(cmd),
- "alacritty msg config \"window.opacity=%.2f\" >/dev/null 2>&1 &",
- target_opacity);
- system(cmd);
- last_opacity = target_opacity;
- }
-}
-
static void
get_layout_box(Monitor *m, unsigned int force_centered, unsigned int *out_nt, int *bx, int *by, int *bw, int *bh)
{
&& (!r->instance || strstr(instance, r->instance)))
{
c->isfloating = r->isfloating;
+
+ /* --- UPDATE: Track explicit tag assignment --- */
+ if (r->tags) {
+ c->tags |= r->tags;
+ c->explicit_tags = 1;
+ }
+ /* ------------------------------------------- */
+
c->tags |= r->tags;
c->resizehints = r->resizehints;
c->iscentered = r->iscentered;
c->isSidePanel = r->isSidePanel;
+ c->switchto = r->switchto;
/* --- THE PERMANENT FIX --- */
/* If this is the calculator, force the dimensions NOW.
/* ------------------------- */
for (m = mons; m && m->num != r->monitor; m = m->next);
- if (m)
+ if (m) {
c->mon = m;
+ if (r->monitor != -1)
+ c->explicit_monitor = 1;
+ }
+
+ /* --- PER-TAG LAYOUT RULE --- */
+ if (r->layout) {
+ Monitor *tm = c->mon;
+ unsigned int target_tags = r->tags ? r->tags : c->tags;
+
+ /* Update the pertag layout index for every tag targeted by this rule */
+ for (int t = 0; t < LENGTH(tags); t++) {
+ if (target_tags & (1 << t)) {
+ int tag_idx = t + 1; /* pertag uses 1-based indexing */
+ tm->pertag->ltidxs[tag_idx][0] = (Layout *)r->layout;
+ tm->pertag->ltidxs[tag_idx][1] = (Layout *)r->layout;
+ }
+ }
+
+ /* If the monitor is currently viewing that tag, update the active layout immediately */
+ if (tm->pertag->curtag > 0 && (target_tags & (1 << (tm->pertag->curtag - 1)))) {
+ tm->lt[tm->sellt] = tm->pertag->ltidxs[tm->pertag->curtag][tm->sellt];
+ strncpy(tm->ltsymbol, tm->lt[tm->sellt]->symbol, sizeof tm->ltsymbol);
+ }
+ }
}
}
return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
}
-// void
-// arrange(Monitor *m)
-// {
-// if (m)
-// showhide(m->stack);
-// else for (m = mons; m; m = m->next)
-// showhide(m->stack);
-// if (m) {
-// arrangemon(m);
-// restack(m);
-// } else for (m = mons; m; m = m->next)
-// arrangemon(m);
-// }
-
void
arrange(Monitor *m)
{
if (m)
showhide(m->stack);
- else
- for (m = mons; m; m = m->next)
- showhide(m->stack);
-
- /* Update global Alacritty opacity based on active layout */
- update_alacritty_opacity(m ? m : selmon);
-
+ else for (m = mons; m; m = m->next)
+ showhide(m->stack);
if (m) {
arrangemon(m);
restack(m);
- } else {
- for (m = mons; m; m = m->next)
- arrangemon(m);
- }
+ update_alacritty_opacity(m);
+ } else for (m = mons; m; m = m->next) {
+ arrangemon(m);
+ update_alacritty_opacity(m);
+ }
}
void
// return m;
// }
+// Monitor *
+// createmon(void)
+// {
+// Monitor *m;
+// unsigned int i;
+
+// m = ecalloc(1, sizeof(Monitor));
+// m->tagset[0] = m->tagset[1] = 1;
+// m->mfact = mfact;
+// m->hfact = centered_height;
+// m->cwfact = centered_width;
+// // m->center_mfact = center_mfact;
+// m->nmaster = nmaster;
+// m->showbar = showbar;
+// m->topbar = topbar;
+// m->lt[0] = &layouts[0];
+// m->lt[1] = &layouts[1 % LENGTH(layouts)];
+// strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+
+// m->pertag = ecalloc(1, sizeof(Pertag));
+// m->pertag->curtag = m->pertag->prevtag = 1;
+
+// /* Ensure this is large enough to hold all tags */
+// m->tags = ecalloc(LENGTH(tags), sizeof(char *));
+
+// for (i = 0; i <= LENGTH(tags); i++) {
+// m->pertag->nmasters[i] = m->nmaster;
+// m->pertag->mfacts[i] = m->mfact;
+// m->pertag->ltidxs[i][0] = m->lt[0];
+// m->pertag->ltidxs[i][1] = m->lt[1];
+// m->pertag->sellts[i] = m->sellt;
+// m->pertag->showbars[i] = m->showbar;
+
+// /* INITIALIZE FOCUS HISTORY */
+// m->pertag->selclients[i] = NULL;
+
+// /* SAFETY: Only allocate/copy tags for valid tag indices (0 to LENGTH-1) */
+// if (i < LENGTH(tags)) {
+// m->tags[i] = ecalloc(1, sizeof(char) * (MAX_TAGNAME_LEN + 1));
+// strncpy(m->tags[i], tags[i], MAX_TAGNAME_LEN);
+// }
+// }
+
+// return m;
+// }
+
Monitor *
createmon(void)
{
- Monitor *m;
- unsigned int i;
+ Monitor *m, *tm;
+ unsigned int i, mon_idx = 0;
+
+ /* Count existing monitors to get index for new monitor */
+ for (tm = mons; tm; tm = tm->next)
+ mon_idx++;
m = ecalloc(1, sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
- m->hfact = centered_height;
- m->cwfact = centered_width;
- // m->center_mfact = center_mfact;
+
+ /* Set per-monitor centered float values with fallback to index 0 */
+ m->cwfact = (mon_idx < LENGTH(centered_width)) ? centered_width[mon_idx] : centered_width[0];
+ m->hfact = (mon_idx < LENGTH(centered_height)) ? centered_height[mon_idx] : centered_height[0];
+
m->nmaster = nmaster;
m->showbar = showbar;
m->topbar = topbar;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
-
+
m->pertag = ecalloc(1, sizeof(Pertag));
m->pertag->curtag = m->pertag->prevtag = 1;
- /* Ensure this is large enough to hold all tags */
- m->tags = ecalloc(LENGTH(tags), sizeof(char *));
+ m->tags = ecalloc(LENGTH(tags), sizeof(char *));
for (i = 0; i <= LENGTH(tags); i++) {
m->pertag->nmasters[i] = m->nmaster;
m->pertag->sellts[i] = m->sellt;
m->pertag->showbars[i] = m->showbar;
- /* INITIALIZE FOCUS HISTORY */
m->pertag->selclients[i] = NULL;
- /* SAFETY: Only allocate/copy tags for valid tag indices (0 to LENGTH-1) */
if (i < LENGTH(tags)) {
m->tags[i] = ecalloc(1, sizeof(char) * (MAX_TAGNAME_LEN + 1));
strncpy(m->tags[i], tags[i], MAX_TAGNAME_LEN);
{
Client *c = NULL, *i;
/* Helper to check if a window should be skipped in navigation */
- #define ISSKIPPABLE(X) (X->resizehints && (!X->name || strcmp(X->name, "calculator") != 0))
+ // #define ISSKIPPABLE(X) (X->resizehints && (!X->name || strcmp(X->name, "calculator") != 0))
+ #define ISSKIPPABLE(X) ((X)->resizehints || ((X)->name && strstr((X)->name, "calculator") != NULL))
if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
return;
} else {
c->mon = selmon;
applyrules(c);
+ /* 2. Apply Rules & Hardcoded Dimensions */
+ if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
+ c->mon = t->mon;
+ c->tags = t->tags;
+ } else {
+ c->mon = selmon;
+ applyrules(c);
+ }
+
}
+ // /* --- NEW: AUTO-SWITCH TAG ON LAUNCH --- */
+ // if (c->explicit_tags && !(c->tags & c->mon->tagset[c->mon->seltags])) {
+ // Monitor *oldselmon = selmon;
+ // selmon = c->mon;
+ // view(&(Arg){ .ui = c->tags });
+ // selmon = oldselmon;
+ // }
+ // /* ------------------------------------- */
+ //
+ /* --- AUTO-SWITCH MONITOR AND TAG ON LAUNCH --- */
+
+ if (c->switchto && (c->explicit_monitor || c->explicit_tags)) {
+ selmon = c->mon;
+ if (c->explicit_tags && !(c->tags & selmon->tagset[selmon->seltags])) {
+ view(&(Arg){ .ui = c->tags });
+ }
+ }
+ /* --------------------------------------------- */
+
/* 3. Geometric Constraints */
if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
c->x = c->mon->wx + c->mon->ww - WIDTH(c);
arrange(selmon);
else
drawbar(selmon);
+
}
void
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+ netatom[NetWMOpacity] = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
{
struct sigaction sa;
- if (arg->v == dmenucmd)
+ if (arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
+
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
return EXIT_SUCCESS;
}
#include "movestack.c"
+
+// void
+// update_alacritty_opacity(Monitor *m)
+// {
+// double target_opacity = (m->lt[m->sellt]->arrange == monocle) ? 1.0 : 0.93;
+
+// if (!m)
+// m = selmon; /* Fallback to currently focused monitor */
+
+// for (Client *c = m->clients; c; c = c->next) {
+// if (ISVISIBLE(c)) {
+// Window win_id = c->win;
+
+// char cmd[128];
+// snprintf(cmd, sizeof(cmd),
+// "alacritty msg config -w %lu \"window.opacity=%.2f\" >/dev/null 2>&1 &",
+// win_id, target_opacity);
+// system(cmd);
+// }
+// }
+// }
+
+// void
+// update_alacritty_opacity(Monitor *m)
+// {
+// /* Fix 2: Fallback to selmon BEFORE accessing properties */
+// if (!m)
+// m = selmon;
+
+// if (!m || !m->lt[m->sellt])
+// return;
+
+// double target_opacity = (m->lt[m->sellt]->arrange == monocle) ? 1.0 : 0.93;
+
+// for (Client *c = m->clients; c; c = c->next) {
+// /* Fix 3: Ensure window belongs to Alacritty before sending command */
+// if (ISVISIBLE(c) && c->class && strstr(c->class, "Alacritty")) {
+// Window win_id = c->win;
+
+// char cmd[128];
+// snprintf(cmd, sizeof(cmd),
+// "alacritty msg config -w %lu \"window.opacity=%.2f\" >/dev/null 2>&1 &",
+// (unsigned long)win_id, target_opacity);
+// system(cmd);
+// }
+// }
+// }
+
+// void
+// update_alacritty_opacity(Monitor *m)
+// {
+// if (!m)
+// m = selmon;
+
+// if (!m || !m->lt[m->sellt])
+// return;
+
+// /* Check if any visible window is actually Alacritty before firing IPC */
+// int has_alacritty = 0;
+// for (Client *c = m->clients; c; c = c->next) {
+// if (ISVISIBLE(c) && c->class && strstr(c->class, "Alacritty")) {
+// has_alacritty = 1;
+// break;
+// }
+// }
+
+// if (!has_alacritty)
+// return;
+
+// double target_opacity = (m->lt[m->sellt]->arrange == monocle) ? 1.0 : 0.93;
+
+// char cmd[128];
+// snprintf(cmd, sizeof(cmd),
+// "alacritty msg config \"window.opacity=%.2f\" >/dev/null 2>&1 &",
+// target_opacity);
+// system(cmd);
+// }
+
void
setopacity(Client *c, double opacity)
{
- if (!c)
- return;
- unsigned long opa = (unsigned long)(opacity * 0xffffffff);
- if (opacity >= 1.0)
+ if (opacity >= 1.0) {
XDeleteProperty(dpy, c->win, netatom[NetWMOpacity]);
- else
- XChangeProperty(dpy, c->win, netatom[NetWMOpacity], XA_CARDINAL, 32,
- PropModeReplace, (unsigned char *)&opa, 1);
+ } else {
+ unsigned int opa = (unsigned int)(opacity * 0xffffffff);
+ XChangeProperty(dpy, c->win, netatom[NetWMOpacity], XA_CARDINAL,
+ 32, PropModeReplace, (unsigned char *)&opa, 1);
+ }
+}
+
+void
+update_alacritty_opacity(Monitor *m)
+{
+ if (!m)
+ m = selmon;
+
+ if (!m || !m->lt[m->sellt])
+ return;
+
+ double target_opacity = (m->lt[m->sellt]->arrange == monocle) ? 1.0 : 0.93;
+
+ for (Client *c = m->clients; c; c = c->next) {
+ /* strcasestr handles case variations like "alacritty" or "Alacritty" */
+ if (ISVISIBLE(c) && c->class && strcasestr(c->class, "alacritty")) {
+ setopacity(c, target_opacity);
+ }
+ }
+}
+// void
+// focuscalculator(const Arg *arg)
+// {
+// Client *c;
+// for (c = selmon->clients; c; c = c->next) {
+// if (ISVISIBLE(c) && c->name && strstr(c->name, "calculator")) {
+// focus(c);
+// restack(selmon);
+// return;
+// }
+// }
+// }
+
+// void
+// focuscalculator(const Arg *arg)
+// {
+// static Client *prev_focus = NULL;
+// Client *c, *calc = NULL;
+
+// /* Find the calculator window */
+// for (c = selmon->clients; c; c = c->next) {
+// if (ISVISIBLE(c) && c->name && strstr(c->name, "calculator")) {
+// calc = c;
+// break;
+// }
+// }
+
+// if (!calc)
+// return;
+
+// /* If calculator is currently focused, return to previous window */
+// if (selmon->sel == calc) {
+// int valid = 0;
+// for (c = selmon->clients; c; c = c->next) {
+// if (c == prev_focus) {
+// valid = 1;
+// break;
+// }
+// }
+// if (valid && ISVISIBLE(prev_focus)) {
+// focus(prev_focus);
+// restack(selmon);
+// }
+// } else {
+// /* Save currently focused window and focus calculator */
+// prev_focus = selmon->sel;
+// focus(calc);
+// restack(selmon);
+// }
+// }
+
+// void
+// focuscalculator(const Arg *arg)
+// {
+// static Client *prev_focus = NULL;
+// Client *c, *calc = NULL;
+// static const char *speedcrunch_cmd[] = { "/usr/local/bin/dwm-speedcrunch-toggle", NULL };
+
+// /* Find the calculator window */
+// for (c = selmon->clients; c; c = c->next) {
+// if (ISVISIBLE(c) && c->name &&
+// (strstr(c->name, "calculator") || strstr(c->name, "SpeedCrunch") || strstr(c->name, "speedcrunch"))) {
+// calc = c;
+// break;
+// }
+// }
+
+// /* If calculator is not found, launch speedcrunch */
+// if (!calc) {
+// spawn(&(Arg){ .v = speedcrunch_cmd });
+// return;
+// }
+
+// /* If calculator is currently focused, return to previous window */
+// if (selmon->sel == calc) {
+// int valid = 0;
+// for (c = selmon->clients; c; c = c->next) {
+// if (c == prev_focus) {
+// valid = 1;
+// break;
+// }
+// }
+// if (valid && ISVISIBLE(prev_focus)) {
+// focus(prev_focus);
+// restack(selmon);
+// }
+// } else {
+// /* Save currently focused window and focus calculator */
+// prev_focus = selmon->sel;
+// focus(calc);
+// restack(selmon);
+// }
+// }
+
+void
+focuscalculator(const Arg *arg)
+{
+ static Client *prev_focus = NULL;
+ Client *c, *calc = NULL;
+ static const char *speedcrunch_cmd[] = { "/usr/local/bin/dwm-speedcrunch-toggle", NULL };
+
+ /* Find the calculator window */
+ for (c = selmon->clients; c; c = c->next) {
+ if (ISVISIBLE(c) && c->name &&
+ (strstr(c->name, "calculator") || strstr(c->name, "SpeedCrunch") || strstr(c->name, "speedcrunch"))) {
+ calc = c;
+ break;
+ }
+ }
+
+ /* If calculator is not found, save current active window and launch speedcrunch */
+ if (!calc) {
+ prev_focus = selmon->sel;
+ spawn(&(Arg){ .v = speedcrunch_cmd });
+ return;
+ }
+
+ /* If calculator is currently focused, return to previous window */
+ if (selmon->sel == calc) {
+ int valid = 0;
+ for (c = selmon->clients; c; c = c->next) {
+ if (c == prev_focus) {
+ valid = 1;
+ break;
+ }
+ }
+ if (valid && ISVISIBLE(prev_focus)) {
+ focus(prev_focus);
+ restack(selmon);
+ } else {
+ /* Fallback to first non-calculator visible client if prev_focus was closed */
+ for (c = selmon->clients; c; c = c->next) {
+ if (ISVISIBLE(c) && c != calc) {
+ focus(c);
+ restack(selmon);
+ break;
+ }
+ }
+ }
+ } else {
+ /* Save currently focused window and focus calculator */
+ prev_focus = selmon->sel;
+ focus(calc);
+ restack(selmon);
+ }
}