<commit_before>/*
 * (C)opyright MMIV-MMVI <NAME> <<EMAIL>>
 * See LICENSE file for license details.
 */

#include <stdlib.h>
#include <string.h>
#include <X11/Xatom.h>

#include "wm.h"

#define CLIENT_MASK		(StructureNotifyMask | PropertyChangeMask | EnterWindowMask)

static Vector *
vector_of_clients(ClientVector *cv)
{
	return (Vector *) cv;
}

static void
update_client_name(Client *c)
{
	XTextProperty name;
	int n;
	char **list = nil;

	name.nitems = 0;
	c->name[0] = 0;
	XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
	if(!name.nitems)
		XGetWMName(dpy, c->win, &name);
	if(!name.nitems)
		return;
	if(name.encoding == XA_STRING)
		cext_strlcpy(c->name, (char *)name.value, sizeof(c->name));
	else {
		if(Xi18nTextPropertyToTextList(dpy, &name, &list, &n) >= Success
				&& n > 0 && *list)
		{
			cext_strlcpy(c->name, *list, sizeof(c->name));
			XFreeStringList(list);
		}
	}
	XFree(name.value);
}

Client *
create_client(Window w, XWindowAttributes *wa)
{
	Client *c = (Client *) cext_emallocz(sizeof(Client));
	XSetWindowAttributes fwa;
	XClassHint ch;
	long msize;
	static unsigned int id = 1;
	static char buf[256];

	c->id = id++;
	c->win = w;
	c->rect.x = wa->x;
	c->rect.y = wa->y;
	c->border = wa->border_width;
	c->rect.width = wa->width + 2 * c->border;
	c->rect.height = wa->height + 2 * c->border;
	XSetWindowBorderWidth(dpy, c->win, 0);
	c->proto = win_proto(c->win);
	XGetTransientForHint(dpy, c->win, &c->trans);
	if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
		c->size.flags = PSize;
	if(c->size.flags & PMinSize && c->size.flags & PMaxSize) {
		if(c->size.min_width == c->size.max_width)
			c->fixedsize = True;
		if(c->size.min_height == c->size.max_height)
			c->fixedsize = True;
	}
	else
		c->fixedsize = False;
	XAddToSaveSet(dpy, c->win);
	update_client_name(c);
	if(XGetClassHint(dpy, c->win, &ch)) {
		snprintf(c->classinst, sizeof(c->classinst), "%s:%s",
				ch.res_class ? ch.res_class : "",
				ch.res_name ? ch.res_name : "");
		if(ch.res_class)
			XFree(ch.res_class);
		if(ch.res_name)
			XFree(ch.res_name);
	}
	fwa.override_redirect = 1;
	fwa.background_pixmap = ParentRelative;
	fwa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
		| ExposureMask | ButtonPressMask | ButtonReleaseMask;

	c->framewin = XCreateWindow(dpy, root, c->rect.x, c->rect.y,
			c->rect.width + 2 * def.border,
			c->rect.height + def.border + height_of_bar(), 0,
			DefaultDepth(dpy, screen), CopyFromParent,
			DefaultVisual(dpy, screen),
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &fwa);
	c->gc = XCreateGC(dpy, c->framewin, 0, 0);
	XSync(dpy, False);
	cext_vattach(vector_of_clients(&client), c);
	snprintf(buf, sizeof(buf), "CreateClient %d\n", client.size - 1);
	write_event(buf);
	return c;
}

void
set_client_state(Client * c, int state)
{
	long data[2];

	data[0] = (long) state;
	data[1] = (long) None;
	XChangeProperty(dpy, c->win, wm_atom[WMState], wm_atom[WMState], 32,
			PropModeReplace, (unsigned char *) data, 2);
}

void
update_client_grab(Client *c, Bool is_sel)
{
	if(is_sel) {
		ungrab_mouse(c->framewin, AnyModifier, AnyButton);
		grab_mouse(c->framewin, def.mod, Button1);
		grab_mouse(c->framewin, def.mod, Button3);
	}
	else
		grab_mouse(c->framewin, AnyModifier, Button1);
}

void
focus_client(Client *c, Bool restack)
{
	Client *old = sel_client();
	Frame *f = c->frame.data[c->sel];
	Client *old_in_area = sel_client_of_area(f->area);
	View *v = f->area->view;
	int i = idx_of_area(f->area);
	static char buf[256];

	v->sel = i;
	f->area->sel = idx_of_frame(f);
	if(restack)
		restack_view(v);
	else {
		if(old)
			update_client_grab(old, False);
		update_client_grab(c, True);
	}

	if(i > 0 && f->area->mode == Colstack)
		arrange_column(f->area, False);
	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
	if(old && old != old_in_area && old != c)
		draw_client(old);
	if(old_in_area && old_in_area != c)
		draw_client(old_in_area);
	draw_client(c);
	XSync(dpy, False);
	snprintf(buf, sizeof(buf), "ClientFocus %d\n", idx_of_client_id(c->id));
	write_event(buf);
}

void
map_client(Client *c)
{
	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
	XMapWindow(dpy, c->win);
	XSelectInput(dpy, c->win, CLIENT_MASK);
	set_client_state(c, NormalState);
}

void
unmap_client(Client *c)
{
	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
	XUnmapWindow(dpy, c->win);
	XSelectInput(dpy, c->win, CLIENT_MASK);
	set_client_state(c, WithdrawnState);
}

void
reparent_client(Client *c, Window w, int x, int y)
{
	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
	XReparentWindow(dpy, c->win, w, x, y);
	XSelectInput(dpy, c->win, CLIENT_MASK);
}

void
configure_client(Client *c)
{
	XConfigureEvent e;
	Frame *f = c->frame.data[c->sel];
	e.type = ConfigureNotify;
	e.event = c->win;
	e.window = c->win;
	e.x = c->rect.x;
	e.y = c->rect.y;
	if(f) {
		e.x += f->rect.x;
		e.y += f->rect.y;
	}
	e.width = c->rect.width;
	e.height = c->rect.height;
	e.border_width = c->border;
	e.above = None;
	e.override_redirect = False;
	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *) & e);
	XSelectInput(dpy, c->win, CLIENT_MASK);
	XSync(dpy, False);
}

static void
send_client_message(Window w, Atom a, long value)
{
	XEvent e;
	e.type = ClientMessage;
	e.xclient.window = w;
	e.xclient.message_type = a;
	e.xclient.format = 32;
	e.xclient.data.l[0] = value;
	e.xclient.data.l[1] = CurrentTime;

	XSendEvent(dpy, w, False, NoEventMask, &e);
	XSync(dpy, False);
}

void
kill_client(Client * c)
{
	if(c->proto & WM_PROTOCOL_DELWIN)
		send_client_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
	else
		XKillClient(dpy, c->win);
}

void
prop_client(Client *c, XPropertyEvent *e)
{
	long msize;

	if(e->atom == wm_atom[WMProtocols]) {
		/* update */
		c->proto = win_proto(c->win);
		return;
	}
	switch (e->atom) {
	case XA_WM_TRANSIENT_FOR:
		XGetTransientForHint(dpy, c->win, &c->trans);
		break;
	case XA_WM_NORMAL_HINTS:
		if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags) {
			c->size.flags = PSize;
		}
		if(c->size.flags & PMinSize && c->size.flags & PMaxSize) {
			if(c->size.min_width == c->size.max_width)
				c->fixedsize = True;
			if(c->size.min_height == c->size.max_height)
				c->fixedsize = True;
		}
		else
			c->fixedsize = False;
		break;
	}
	if(e->atom == XA_WM_NAME || e->atom == net_atom[NetWMName]) {
		update_client_name(c);
		if(c->frame.size)
			draw_client(c);
	}
}

void<commit_msg>small change to fixedsize handling<commit_after>/*
 * (C)opyright MMIV-MMVI <NAME> <<EMAIL>>
 * See LICENSE file for license details.
 */

#include <stdlib.h>
#include <string.h>
#include <X11/Xatom.h>

#include "wm.h"

#define CLIENT_MASK		(StructureNotifyMask | PropertyChangeMask | EnterWindowMask)

static Vector *
vector_of_clients(ClientVector *cv)
{
	return (Vector *) cv;
}

static void
update_client_name(Client *c)
{
	XTextProperty name;
	int n;
	char **list = nil;

	name.nitems = 0;
	c->name[0] = 0;
	XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
	if(!name.nitems)
		XGetWMName(dpy, c->win, &name);
	if(!name.nitems)
		return;
	if(name.encoding == XA_STRING)
		cext_strlcpy(c->name, (char *)name.value, sizeof(c->name));
	else {
		if(Xi18nTextPropertyToTextList(dpy, &name, &list, &n) >= Success
				&& n > 0 && *list)
		{
			cext_strlcpy(c->name, *list, sizeof(c->name));
			XFreeStringList(list);
		}
	}
	XFree(name.value);
}

Client *
create_client(Window w, XWindowAttributes *wa)
{
	Client *c = (Client *) cext_emallocz(sizeof(Client));
	XSetWindowAttributes fwa;
	XClassHint ch;
	long msize;
	static unsigned int id = 1;
	static char buf[256];

	c->id = id++;
	c->win = w;
	c->rect.x = wa->x;
	c->rect.y = wa->y;
	c->border = wa->border_width;
	c->rect.width = wa->width + 2 * c->border;
	c->rect.height = wa->height + 2 * c->border;
	XSetWindowBorderWidth(dpy, c->win, 0);
	c->proto = win_proto(c->win);
	XGetTransientForHint(dpy, c->win, &c->trans);
	if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags)
		c->size.flags = PSize;
	if(c->size.flags & PMinSize && c->size.flags & PMaxSize
		&& c->size.min_width == c->size.max_width
		&& c->size.min_height == c->size.max_height)
			c->fixedsize = True;
	else
		c->fixedsize = False;
	XAddToSaveSet(dpy, c->win);
	update_client_name(c);
	if(XGetClassHint(dpy, c->win, &ch)) {
		snprintf(c->classinst, sizeof(c->classinst), "%s:%s",
				ch.res_class ? ch.res_class : "",
				ch.res_name ? ch.res_name : "");
		if(ch.res_class)
			XFree(ch.res_class);
		if(ch.res_name)
			XFree(ch.res_name);
	}
	fwa.override_redirect = 1;
	fwa.background_pixmap = ParentRelative;
	fwa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
		| ExposureMask | ButtonPressMask | ButtonReleaseMask;

	c->framewin = XCreateWindow(dpy, root, c->rect.x, c->rect.y,
			c->rect.width + 2 * def.border,
			c->rect.height + def.border + height_of_bar(), 0,
			DefaultDepth(dpy, screen), CopyFromParent,
			DefaultVisual(dpy, screen),
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &fwa);
	c->gc = XCreateGC(dpy, c->framewin, 0, 0);
	XSync(dpy, False);
	cext_vattach(vector_of_clients(&client), c);
	snprintf(buf, sizeof(buf), "CreateClient %d\n", client.size - 1);
	write_event(buf);
	return c;
}

void
set_client_state(Client * c, int state)
{
	long data[2];

	data[0] = (long) state;
	data[1] = (long) None;
	XChangeProperty(dpy, c->win, wm_atom[WMState], wm_atom[WMState], 32,
			PropModeReplace, (unsigned char *) data, 2);
}

void
update_client_grab(Client *c, Bool is_sel)
{
	if(is_sel) {
		ungrab_mouse(c->framewin, AnyModifier, AnyButton);
		grab_mouse(c->framewin, def.mod, Button1);
		grab_mouse(c->framewin, def.mod, Button3);
	}
	else
		grab_mouse(c->framewin, AnyModifier, Button1);
}

void
focus_client(Client *c, Bool restack)
{
	Client *old = sel_client();
	Frame *f = c->frame.data[c->sel];
	Client *old_in_area = sel_client_of_area(f->area);
	View *v = f->area->view;
	int i = idx_of_area(f->area);
	static char buf[256];

	v->sel = i;
	f->area->sel = idx_of_frame(f);
	if(restack)
		restack_view(v);
	else {
		if(old)
			update_client_grab(old, False);
		update_client_grab(c, True);
	}

	if(i > 0 && f->area->mode == Colstack)
		arrange_column(f->area, False);
	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
	if(old && old != old_in_area && old != c)
		draw_client(old);
	if(old_in_area && old_in_area != c)
		draw_client(old_in_area);
	draw_client(c);
	XSync(dpy, False);
	snprintf(buf, sizeof(buf), "ClientFocus %d\n", idx_of_client_id(c->id));
	write_event(buf);
}

void
map_client(Client *c)
{
	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
	XMapWindow(dpy, c->win);
	XSelectInput(dpy, c->win, CLIENT_MASK);
	set_client_state(c, NormalState);
}

void
unmap_client(Client *c)
{
	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
	XUnmapWindow(dpy, c->win);
	XSelectInput(dpy, c->win, CLIENT_MASK);
	set_client_state(c, WithdrawnState);
}

void
reparent_client(Client *c, Window w, int x, int y)
{
	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
	XReparentWindow(dpy, c->win, w, x, y);
	XSelectInput(dpy, c->win, CLIENT_MASK);
}

void
configure_client(Client *c)
{
	XConfigureEvent e;
	Frame *f = c->frame.data[c->sel];
	e.type = ConfigureNotify;
	e.event = c->win;
	e.window = c->win;
	e.x = c->rect.x;
	e.y = c->rect.y;
	if(f) {
		e.x += f->rect.x;
		e.y += f->rect.y;
	}
	e.width = c->rect.width;
	e.height = c->rect.height;
	e.border_width = c->border;
	e.above = None;
	e.override_redirect = False;
	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *) & e);
	XSelectInput(dpy, c->win, CLIENT_MASK);
	XSync(dpy, False);
}

static void
send_client_message(Window w, Atom a, long value)
{
	XEvent e;
	e.type = ClientMessage;
	e.xclient.window = w;
	e.xclient.message_type = a;
	e.xclient.format = 32;
	e.xclient.data.l[0] = value;
	e.xclient.data.l[1] = CurrentTime;

	XSendEvent(dpy, w, False, NoEventMask, &e);
	XSync(dpy, False);
}

void
kill_client(Client * c)
{
	if(c->proto & WM_PROTOCOL_DELWIN)
		send_client_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
	else
		XKillClient(dpy, c->win);
}

void
prop_client(Client *c, XPropertyEvent *e)
{
	long msize;

	if(e->atom == wm_atom[WMProtocols]) {
		/* update */
		c->proto = win_proto(c->win);
		return;
	}
	switch (e->atom) {
	case XA_WM_TRANSIENT_FOR:
		XGetTransientForHint(dpy, c->win, &c->trans);
		break;
	case XA_WM_NORMAL_HINTS:
		if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags) {
			c->size.flags = PSize;
		}
		if(c->size.flags & PMinSize && c->size.flags & PMaxSize
			&& c->size.min_width == c->size.max_width
			&& c->size.min_height == c->size.max_height)
				c->fixedsize = True;
		else
			c->fixedsize = False;
		break;
	}
	if(e->atom == XA_WM_NAME || e->atom == net_atom[NetWMName]) {
		update_client_name(c);
		if(c->frame.size)
			draw_client(c);
	}
}

void
{'fraction_non_alphanumeric': 0.1762950493534318, 'fraction_numerical': 0.005815288086311118, 'mean_word_length': 4.457202505219207, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 253, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1495112', 'n_tokens_mistral': 5826, 'n_tokens_neox': 5539, 'n_words': 1019}