dwm

Kris's build of dwm
git clone git clone https://git.krisyotam.com/krisyotam/dwm.git
Log | Files | Refs | README | LICENSE

seamless_restart.c (12367B)


      1 void
      2 persistmonitorstate(Monitor *m)
      3 {
      4 	Client *c;
      5 	unsigned int i;
      6 
      7 	setmonitortags(m);
      8 	setmonitorfields(m);
      9 
     10 	/* Set client atoms */
     11 	for (i = 1, c = m->clients; c; c = c->next, ++i) {
     12 		c->idx = i;
     13 		persistclientstate(c);
     14 		#if SWALLOW_PATCH
     15 		if (c->swallowing) {
     16 			c->swallowing->idx = i;
     17 			persistclientstate(c->swallowing);
     18 		}
     19 		#endif // SWALLOW_PATCH
     20 	}
     21 }
     22 
     23 int
     24 restoremonitorstate(Monitor *m)
     25 {
     26 	return getmonitortags(m) | getmonitorfields(m);
     27 }
     28 
     29 void
     30 persistclientstate(Client *c)
     31 {
     32 	setclienttags(c);
     33 	setclientfields(c);
     34 	#if SAVEFLOATS_PATCH
     35 	savewindowfloatposition(c, c->mon);
     36 	#endif // SAVEFLOATS_PATCH
     37 }
     38 
     39 int
     40 restoreclientstate(Client *c)
     41 {
     42 	int restored = getclientfields(c);
     43 	getclienttags(c);
     44 	#if SAVEFLOATS_PATCH
     45 	restorewindowfloatposition(c, c->mon ? c->mon : selmon);
     46 	#endif // SAVEFLOATS_PATCH
     47 	return restored;
     48 }
     49 
     50 void setmonitorfields(Monitor *m)
     51 {
     52 	#if PERTAG_PATCH
     53 	unsigned int i;
     54 	#endif // PERTAG_PATCH
     55 	char atom[22] = {0};
     56 	Atom monitor_fields;
     57 	#if FLEXTILE_DELUXE_LAYOUT
     58 	unsigned int flextile_deluxe_bitmask;
     59 	#endif // FLEXTILE_DELUXE_LAYOUT
     60 
     61 	sprintf(atom, "_DWM_MONITOR_FIELDS_%u", m->num);
     62 	monitor_fields = XInternAtom(dpy, atom, False);
     63 
     64 	/* Perists workspace information in 32 bits laid out like this:
     65 	 *
     66 	 * |0|0000|0|0000|0000|0000|0000|0000|000|000
     67 	 * | |    | |    |    |    |    |    |   |-- nmaster
     68 	 * | |    | |    |    |    |    |    |-- nstack
     69 	 * | |    | |    |    |    |    |-- layout
     70 	 * | |    | |    |    |    |-- flextile LAYOUT (split)
     71 	 * | |    | |    |    |-- flextile MASTER
     72 	 * | |    | |    |-- flextile STACK1
     73 	 * | |    | |-- flextile STACK2
     74 	 * | |    |-- flextile mirror layout (indicated by negative layout)
     75 	 * | |
     76 	 * | |-- reserved
     77 	 * |-- showbar
     78 	 */
     79 	#if PERTAG_PATCH
     80 	for (i = 0; i <= NUMTAGS; i++) {
     81 		#if FLEXTILE_DELUXE_LAYOUT
     82 		flextile_deluxe_bitmask = (m->pertag->nstacks[i] & 0x7) << 3;
     83 		if (m->pertag->ltidxs[i][m->pertag->sellts[i]]->arrange == flextile) {
     84 			flextile_deluxe_bitmask |=
     85 				(abs(m->pertag->ltaxis[i][LAYOUT]) & 0xF) << 10 |
     86 				(m->pertag->ltaxis[i][MASTER] & 0xF) << 14 |
     87 				(m->pertag->ltaxis[i][STACK]  & 0xF) << 18 |
     88 				(m->pertag->ltaxis[i][STACK2] & 0xF) << 22 |
     89 				(m->pertag->ltaxis[i][LAYOUT] < 0 ? 1 : 0) << 24;
     90 		}
     91 		#endif // FLEXTILE_DELUXE_L1AYOUT
     92 		uint32_t data[] = {
     93 			#if FLEXTILE_DELUXE_LAYOUT
     94 			flextile_deluxe_bitmask |
     95 			#endif // FLEXTILE_DELUXE_LAYOUT
     96 			(m->pertag->nmasters[i] & 0x7) |
     97 			(getlayoutindex(m->pertag->ltidxs[i][m->pertag->sellts[i]]) & 0xF) << 6 |
     98 			#if PERTAGBAR_PATCH
     99 			m->pertag->showbars[i] << 31
    100 			#else
    101 			m->showbar << 31
    102 			#endif // PERTAGBAR_PATCH
    103 		};
    104 
    105 		XChangeProperty(dpy, root, monitor_fields, XA_CARDINAL, 32,
    106 			i ? PropModeAppend : PropModeReplace, (unsigned char *)data, 1);
    107 	}
    108 	#else // !PERTAG_PATCH
    109 	#if FLEXTILE_DELUXE_LAYOUT
    110 	flextile_deluxe_bitmask = (m->nstack & 0x7) << 3;
    111 	if (m->lt[m->sellt]->arrange == flextile) {
    112 		flextile_deluxe_bitmask |=
    113 			(abs(m->ltaxis[LAYOUT]) & 0xF) << 10 |
    114 			(m->ltaxis[MASTER] & 0xF) << 14 |
    115 			(m->ltaxis[STACK]  & 0xF) << 18 |
    116 			(m->ltaxis[STACK2] & 0xF) << 22 |
    117 			(m->ltaxis[LAYOUT] < 0 ? 1 : 0) << 24;
    118 	}
    119 	#endif // FLEXTILE_DELUXE_L1AYOUT
    120 	uint32_t data[] = {
    121 		#if FLEXTILE_DELUXE_LAYOUT
    122 		flextile_deluxe_bitmask |
    123 		#endif // FLEXTILE_DELUXE_LAYOUT
    124 		(m->nmaster & 0x7) |
    125 		(getlayoutindex(m->lt[m->sellt]) & 0xF) << 6 |
    126 		m->showbar << 31
    127 	};
    128 
    129 	XChangeProperty(dpy, root, monitor_fields, XA_CARDINAL, 32, PropModeReplace,
    130 		(unsigned char *)data, 1);
    131 	#endif // PERTAG_PATCH
    132 }
    133 
    134 int
    135 getlayoutindex(const Layout *layout)
    136 {
    137 	int i;
    138 
    139 	for (i = 0; i < LENGTH(layouts) && &layouts[i] != layout; i++);
    140 	if (i == LENGTH(layouts))
    141 		i = 0;
    142 	return i;
    143 }
    144 
    145 int
    146 getmonitorfields(Monitor *m)
    147 {
    148 	int di, layout_index;
    149 	#if PERTAG_PATCH
    150 	unsigned int i, restored = 0;
    151 	unsigned int tags = m->tagset[m->seltags] << 1;
    152 	#endif // PERTAG_PATCH
    153 	unsigned long dl, nitems;
    154 	unsigned char *p = NULL;
    155 	char atom[22] = {0};
    156 	Atom da, state = None;
    157 
    158 	sprintf(atom, "_DWM_MONITOR_FIELDS_%u", m->num);
    159 	Atom dwm_monitor = XInternAtom(dpy, atom, False);
    160 	if (!dwm_monitor)
    161 		return 0;
    162 
    163 	#if PERTAG_PATCH
    164 	for (i = 0; i <= NUMTAGS; i++) {
    165 		if (!(XGetWindowProperty(dpy, root, dwm_monitor, i, (NUMTAGS + 1) * sizeof dl,
    166 				False, AnyPropertyType, &da, &di, &nitems, &dl, &p) == Success && p)) {
    167 			break;
    168 		}
    169 
    170 		if (!nitems) {
    171 			XFree(p);
    172 			break;
    173 		}
    174 
    175 		/* See bit layout in the persistmonitorstate function */
    176 		state = *(Atom *)p;
    177 
    178 		m->pertag->nmasters[i] = state & 0x7;
    179 		layout_index = (state >> 6) & 0xF;
    180 		if (layout_index < LENGTH(layouts))
    181 			m->pertag->ltidxs[i][m->pertag->sellts[i]] = &layouts[layout_index];
    182 		#if FLEXTILE_DELUXE_LAYOUT
    183 		m->pertag->nstacks[i] = (state >> 3) & 0x7;
    184 		if (m->pertag->ltidxs[i][m->pertag->sellts[i]]->arrange == flextile) {
    185 			m->pertag->ltaxis[i][LAYOUT] = (state >> 10) & 0xF;
    186 			m->pertag->ltaxis[i][MASTER] = (state >> 14) & 0xF;
    187 			m->pertag->ltaxis[i][STACK]  = (state >> 18) & 0xF;
    188 			m->pertag->ltaxis[i][STACK2] = (state >> 22) & 0xF;
    189 			if (state >> 24 & 0x1) {
    190 				m->pertag->ltaxis[i][LAYOUT] *= -1;
    191 			}
    192 		}
    193 		#endif // FLEXTILE_DELUXE_LAYOUT
    194 		#if PERTAGBAR_PATCH
    195 		m->pertag->showbars[i] = (state >> 31) & 0x1;
    196 		#endif // PERTAGBAR_PATCH
    197 
    198 		if (!restored && i && (tags & (1 << i))) {
    199 			m->nmaster = m->pertag->nmasters[i];
    200 			m->sellt = m->pertag->sellts[i];
    201 			m->lt[m->sellt] = m->pertag->ltidxs[i][m->sellt];
    202 			#if FLEXTILE_DELUXE_LAYOUT
    203 			m->nstack = m->pertag->nstacks[i];
    204 			if (m->lt[m->sellt]->arrange == flextile) {
    205 				m->ltaxis[LAYOUT] = m->pertag->ltaxis[i][LAYOUT];
    206 				m->ltaxis[MASTER] = m->pertag->ltaxis[i][MASTER];
    207 				m->ltaxis[STACK]  = m->pertag->ltaxis[i][STACK];
    208 				m->ltaxis[STACK2] = m->pertag->ltaxis[i][STACK2];
    209 			}
    210 			#endif // FLEXTILE_DELUXE_LAYOUT
    211 			#if PERTAGBAR_PATCH
    212 			m->showbar = m->pertag->showbars[i];
    213 			#else
    214 			m->showbar = (state >> 31) & 0x1;
    215 			#endif // PERTAGBAR_PATCH
    216 			restored = 1;
    217 		}
    218 
    219 		XFree(p);
    220 	}
    221 
    222 	return restored;
    223 	#else // !PERTAG_PATCH
    224 	if (!(XGetWindowProperty(dpy, root, dwm_monitor, 0L, sizeof dl,
    225 			False, AnyPropertyType, &da, &di, &nitems, &dl, &p) == Success && p)) {
    226 		return 0;
    227 	}
    228 
    229 	if (nitems) {
    230 		state = *(Atom *)p;
    231 
    232 		/* See bit layout in the persistmonitorstate function */
    233 		m->nmaster = state & 0x7;
    234 		#if FLEXTILE_DELUXE_LAYOUT
    235 		m->nstack = (state >> 3) & 0x7;
    236 		#endif // FLEXTILE_DELUXE_LAYOUT
    237 		layout_index = (state >> 6) & 0xF;
    238 		if (layout_index < LENGTH(layouts))
    239 			m->lt[m->sellt] = &layouts[layout_index];
    240 		#if FLEXTILE_DELUXE_LAYOUT
    241 		if (m->lt[m->sellt]->arrange == flextile) {
    242 			m->ltaxis[LAYOUT] = (state >> 10) & 0xF;
    243 			m->ltaxis[MASTER] = (state >> 14) & 0xF;
    244 			m->ltaxis[STACK]  = (state >> 18) & 0xF;
    245 			m->ltaxis[STACK2] = (state >> 22) & 0xF;
    246 		}
    247 		#endif // FLEXTILE_DELUXE_LAYOUT
    248 		m->showbar = (state >> 31) & 0x1;
    249 	}
    250 
    251 	XFree(p);
    252 	return 1;
    253 	#endif // PERTAG_PATCH
    254 }
    255 
    256 void
    257 setmonitortags(Monitor *m)
    258 {
    259 	char atom[22] = {0};
    260 	Atom monitor_tags;
    261 
    262 	sprintf(atom, "_DWM_MONITOR_TAGS_%u", m->num);
    263 	monitor_tags = XInternAtom(dpy, atom, False);
    264 
    265 	uint32_t data[] = { m->tagset[m->seltags] };
    266 	XChangeProperty(dpy, root, monitor_tags, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
    267 }
    268 
    269 int
    270 getmonitortags(Monitor *m)
    271 {
    272 	int di;
    273 	unsigned long dl, nitems;
    274 	unsigned char *p = NULL;
    275 	char atom[22] = {0};
    276 	Atom da, monitor_tags = None, tags;
    277 
    278 	sprintf(atom, "_DWM_MONITOR_TAGS_%u", m->num);
    279 	monitor_tags = XInternAtom(dpy, atom, False);
    280 
    281 	if (!(XGetWindowProperty(dpy, root, monitor_tags, 0L, sizeof dl,
    282 			False, AnyPropertyType, &da, &di, &nitems, &dl, &p) == Success && p)) {
    283 		return 0;
    284 	}
    285 
    286 	if (nitems) {
    287 		tags = *(Atom *)p;
    288 		m->tagset[m->seltags] = tags & TAGMASK;
    289 	}
    290 
    291 	XFree(p);
    292 	return 1;
    293 }
    294 
    295 void
    296 setclientfields(Client *c)
    297 {
    298 	/* Perists client information in 32 bits laid out like this:
    299 	 *
    300 	 * |00000000|00000|0|0|0|0|0|0|0|0|00000000|000
    301 	 * |        |     | | | | | | | | |        |-- monitor index
    302 	 * |        |     | | | | | | | | |-- client index
    303 	 * |        |     | | | | | | | |-- isfloating
    304 	 * |        |     | | | | | | |-- ispermanent
    305 	 * |        |     | | | | | |-- isterminal
    306 	 * |        |     | | | | |-- noswallow
    307 	 * |        |     | | | |-- issteam
    308 	 * |        |     | | |-- issticky
    309 	 * |        |     | |-- fakefullscreen
    310 	 * |        |     |-- isfreesize
    311 	 * |        |
    312 	 * |        |-- reserved
    313 	 * |-- scratchkey (for scratchpads)
    314 	 */
    315 	uint32_t data[] = {
    316 		(c->mon->num & 0x7)
    317 		| (c->idx & 0xFF) << 3
    318 		| (c->isfloating & 0x1) << 11
    319 		#if ISPERMANENT_PATCH
    320 		| (c->ispermanent & 0x1) << 12
    321 		#endif // ISPERMANENT_PATCH
    322 		#if SWALLOW_PATCH
    323 		| (c->isterminal & 0x1) << 13
    324 		| (c->noswallow & 0x1) << 14
    325 		#endif // SWALLOW_PATCH
    326 		#if STEAM_PATCH
    327 		| (c->issteam & 0x1) << 15
    328 		#endif // STEAM_PATCH
    329 		#if STICKY_PATCH
    330 		| (c->issticky & 0x1) << 16
    331 		#endif // STICKY_PATCH
    332 		#if !FAKEFULLSCREEN_PATCH && FAKEFULLSCREEN_CLIENT_PATCH
    333 		| (c->fakefullscreen & 0x1) << 17
    334 		#endif // FAKEFULLSCREEN_CLIENT_PATCH
    335 		#if SIZEHINTS_ISFREESIZE_PATCH
    336 		| (c->isfreesize & 0x1) << 18
    337 		#endif // SIZEHINTS_ISFREESIZE_PATCH
    338 		#if RENAMED_SCRATCHPADS_PATCH
    339 		| (c->scratchkey & 0xFF) << 24
    340 		#endif // RENAMED_SCRATCHPADS_PATCH
    341 	};
    342 	XChangeProperty(dpy, c->win, clientatom[ClientFields], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
    343 }
    344 
    345 int
    346 getclientfields(Client *c)
    347 {
    348 	Monitor *m;
    349 	Atom fields = getatomprop(c, clientatom[ClientFields], AnyPropertyType);
    350 	if (fields == None)
    351 		return 0;
    352 
    353 	/* See bit layout in the setclientfields function */
    354 	for (m = mons; m; m = m->next)
    355 		if (m->num == (fields & 0x7)) {
    356 			c->mon = m;
    357 			break;
    358 		}
    359 	c->idx = (fields >> 3) & 0xFF;
    360 	c->isfloating = (fields >> 11) & 0x1;
    361 	#if ISPERMANENT_PATCH
    362 	c->ispermanent = (fields >> 12) & 0x1;
    363 	#endif // ISPERMANENT_PATCH
    364 	#if SWALLOW_PATCH
    365 	c->isterminal = (fields >> 13) & 0x1;
    366 	c->noswallow = (fields >> 14) & 0x1;
    367 	#endif // SWALLOW_PATCH
    368 	#if STEAM_PATCH
    369 	c->issteam = (fields >> 15) & 0x1;
    370 	#endif // STEAM_PATCH
    371 	#if STICKY_PATCH
    372 	c->issticky = (fields >> 16) & 0x1;
    373 	#endif // STICKY_PATCH
    374 	#if !FAKEFULLSCREEN_PATCH && FAKEFULLSCREEN_CLIENT_PATCH
    375 	c->fakefullscreen = (fields >> 17) & 0x1;
    376 	#endif // FAKEFULLSCREEN_CLIENT_PATCH
    377 	#if SIZEHINTS_ISFREESIZE_PATCH
    378 	c->isfreesize = (fields >> 18) & 0x1;
    379 	#endif // SIZEHINTS_ISFREESIZE_PATCH
    380 	#if RENAMED_SCRATCHPADS_PATCH
    381 	c->scratchkey = (fields >> 24) & 0xFF;
    382 	#endif // RENAMED_SCRATCHPADS_PATCH
    383 	return 1;
    384 }
    385 
    386 void
    387 setclienttags(Client *c)
    388 {
    389 	uint32_t data[] = { c->tags };
    390 	XChangeProperty(dpy, c->win, clientatom[ClientTags], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
    391 }
    392 
    393 int
    394 getclienttags(Client *c)
    395 {
    396 	Atom tags = getatomprop(c, clientatom[ClientTags], AnyPropertyType);
    397 	if (tags == None)
    398 		return 0;
    399 
    400 	c->tags = tags & TAGMASK;
    401 	return 1;
    402 }
    403 
    404 #if SAVEFLOATS_PATCH
    405 void
    406 savewindowfloatposition(Client *c, Monitor *m)
    407 {
    408 	char atom[22] = {0};
    409 	if (c->sfx == -9999)
    410 		return;
    411 
    412 	sprintf(atom, "_DWM_FLOATPOS_%u", m->num);
    413 	uint32_t pos[] = { (MAX(c->sfx - m->mx, 0) & 0xffff) | ((MAX(c->sfy - m->my, 0) & 0xffff) << 16) };
    414 	XChangeProperty(dpy, c->win, XInternAtom(dpy, atom, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)pos, 1);
    415 
    416 	sprintf(atom, "_DWM_FLOATSIZE_%u", m->num);
    417 	uint32_t size[] = { (c->sfw & 0xffff) | ((c->sfh & 0xffff) << 16) };
    418 	XChangeProperty(dpy, c->win, XInternAtom(dpy, atom, False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)size, 1);
    419 
    420 	XSync(dpy, False);
    421 }
    422 
    423 int
    424 restorewindowfloatposition(Client *c, Monitor *m)
    425 {
    426 	char atom[22] = {0};
    427 	Atom key, value;
    428 	int x, y, w, h;
    429 
    430 	if (m == NULL)
    431 		return 0;
    432 
    433 	sprintf(atom, "_DWM_FLOATPOS_%u", m->num);
    434 
    435 	key = XInternAtom(dpy, atom, False);
    436 	if (!key)
    437 		return 0;
    438 
    439 	value = getatomprop(c, key, AnyPropertyType);
    440 	if (!value)
    441 		return 0;
    442 
    443 	x = value & 0xffff;
    444 	y = value >> 16;
    445 
    446 	sprintf(atom, "_DWM_FLOATSIZE_%u", m->num);
    447 
    448 	key = XInternAtom(dpy, atom, False);
    449 	if (!key)
    450 		return 0;
    451 
    452 	value = getatomprop(c, key, AnyPropertyType);
    453 	if (!value)
    454 		return 0;
    455 
    456 	w = value & 0xffff;
    457 	h = value >> 16;
    458 
    459 	if (w <= 0 || h <= 0) {
    460 		fprintf(stderr, "restorewindowfloatposition: bad float values x = %d, y = %d, w = %d, h = %d for client = %s\n", x, y, w, h, c->name);
    461 		return 0;
    462 	}
    463 
    464 	c->sfx = m->mx + x;
    465 	c->sfy = m->my + y;
    466 	c->sfw = w;
    467 	c->sfh = h;
    468 
    469 	if (c->isfloating) {
    470 		c->x = c->sfx;
    471 		c->y = c->sfy;
    472 		c->w = c->sfw;
    473 		c->h = c->sfh;
    474 	}
    475 
    476 	return 1;
    477 }
    478 #endif // SAVEFLOATS_PATCH