Beispiel #1
0
/**
 * @brief Set basic properties on a window.
 */
void
wm_wid_set_info(session_t *ps, Window wid, const char *name,
		Atom window_type) {
	// Set window name
	{
		char *textcpy = mstrjoin("skippy-xd ", name);
		{
			XTextProperty text_prop = { };
			if (Success == XmbTextListToTextProperty(ps->dpy, &textcpy, 1,
						XStdICCTextStyle, &text_prop))
				XSetWMName(ps->dpy, wid, &text_prop);
			sxfree(text_prop.value);
		}
		wm_wid_set_prop_utf8(ps, wid, _NET_WM_NAME, textcpy);
		free(textcpy);
	}

	// Set window class
	{
		XClassHint *classh = allocchk(XAllocClassHint());
		classh->res_name = "skippy-xd";
		classh->res_class = "skippy-xd";
		XSetClassHint(ps->dpy, wid, classh);
		XFree(classh);
	}

	// Set window type
	{
		if (!window_type)
			window_type = _NET_WM_WINDOW_TYPE_NORMAL;
		long val = window_type;
		XChangeProperty(ps->dpy, wid, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
				PropModeReplace, (unsigned char *) &val, 1);
	}
}
Beispiel #2
0
/**
 * @brief Set a UTF-8 string property on a window.
 */
bool
wm_wid_set_prop_utf8(session_t *ps, Window wid, Atom prop, char *text) {
	XTextProperty text_prop = { };
	bool success = (Success == XmbTextListToTextProperty(ps->dpy, &text, 1,
				XUTF8StringStyle, &text_prop));
	if (success)
		XSetTextProperty(ps->dpy, wid, &text_prop, prop);
	sxfree(text_prop.value);
	return success;
}
Beispiel #3
0
/**
 * @brief Get the first string in a UTF-8 string property on a window.
 */
char *
wm_wid_get_prop_utf8(session_t *ps, Window wid, Atom prop) {
	XTextProperty text_prop = { };
	char *ret = NULL;
	if (XGetTextProperty(ps->dpy, wid, &text_prop, prop)) {
		char **strlst = NULL;
		int cstr = 0;
		Xutf8TextPropertyToTextList(ps->dpy, &text_prop, &strlst, &cstr);
		if (cstr) ret = mstrdup(strlst[0]);
		if (strlst) XFreeStringList(strlst);
	}
	sxfree(text_prop.value);
	return ret;
}
Beispiel #4
0
/**
 * @brief Get the raw string from a string property.
 */
char *
wm_wid_get_prop_rstr(session_t *ps, Window wid, Atom prop) {
	Atom type_ret = None;
	int fmt_ret = 0;
	unsigned long nitems = 0;
	unsigned long bytes_after_ret = 0;
	unsigned char *data = NULL;
	char *ret = NULL;
	if (Success == XGetWindowProperty(ps->dpy, wid, prop, 0, BUF_LEN,
				False, AnyPropertyType, &type_ret, &fmt_ret, &nitems,
				&bytes_after_ret, &data) && nitems && 8 == fmt_ret)
		ret = mstrdup((char *) data);
	sxfree(data);
	return ret;
}
Beispiel #5
0
/**
 * @brief Find out the WM frame of a client window by querying X.
 *
 * @param ps current session
 * @param wid window ID
 * @return window ID of the frame window
 */
static Window
wm_find_frame(session_t *ps, Window wid) {
  // We traverse through its ancestors to find out the frame
  for (Window cwid = wid; cwid && cwid != ps->root; ) {
    Window rroot = None;
    Window *children = NULL;
    unsigned nchildren = 0;
	wid = cwid;
    if (!XQueryTree(ps->dpy, cwid, &rroot, &cwid, &children,
          &nchildren))
			cwid = 0;
    sxfree(children);
  }

  return wid;
}
Beispiel #6
0
pictw_t *
simg_load_icon(session_t *ps, Window wid, int desired_size) {
	pictw_t *pictw = NULL;
	bool processed = false;

	{
		// _NET_WM_ICON
		int best_width = 0, best_height = 0;
		float best_scale = 1.0f, best_area = 0.0f;
		const unsigned char *best_data = NULL;
		winprop_t prop = wid_get_prop_adv(ps, wid, _NET_WM_ICON, 0, ICON_PROP_MAXLEN, XA_CARDINAL, 32);
		if (prop.nitems) {
			int width = 0, height = 0;
			const long *end = prop.data32 + prop.nitems;
			// Format: WIDTH HEIGHT DATA (32-bit)
			int wanted_bytes = 0;
			for (const long *p = prop.data32; p < end; p += wanted_bytes) {
				if (p + 2 >= end) {
					printfef("(%#010lx): %d trailing byte(s).", wid, (int) (end - p));
					break;
				}
				width = p[0];
				height = p[1];
				if (width <= 0 || height <= 0) {
					printfef("(%#010lx): (offset %d, width %d, height %d) Invalid width/height.",
							wid, (int) (p - prop.data32), width, height);
					break;
				}
				wanted_bytes = 2 + width * height;
				if ((end - p) < wanted_bytes) {
					printfef("(%#010lx): (offset %d, width %d, height %d) Not enough bytes (%d/%d).",
							wid, (int) (p - prop.data32), width, height, (int) (end - p), wanted_bytes);
					break;
				}
				// Prefer larger ones if possible
				if (best_width >= desired_size && best_height >= desired_size
						&& (width < desired_size || height < desired_size))
					continue;
				float scale = MAX(1.0f,
						MIN((float) best_height / height, (float) best_width / width));
				float area = width * height * scale * scale;
				if (area > best_area) {
					best_width = width;
					best_height = height;
					best_scale = scale;
					best_area = area;
					best_data = (const unsigned char *) (p + 2);
				}
			}
		}
		if (best_data) {
			{
				unsigned char *converted_data = simg_data32_from_long(
						(const long *) best_data, best_width * best_height);
				simg_data32_premultiply(converted_data, best_width * best_height);
				pictw = simg_data_to_pictw(ps, best_width, best_height, 32, converted_data, 0);
				if (converted_data != best_data)
					free(converted_data);
			}
			if (!pictw)
				printfef("(%#010lx): Failed to create picture.", wid);
			/* if (pictw)
				printfdf("(%#010lx): (offset %d, width %d, height %d) Loaded.",
						wid, (int) (best_data - prop.data8), pictw->width, pictw->height); */
		}
		free_winprop(&prop);
	}

	if (pictw) goto simg_load_icon_end;

	// WM_HINTS
	// Our method probably fills 1-8 bit pixmaps as black instead of using
	// "suitable background/foreground". I hope it isn't a problem, though.
	{
		XWMHints *h = XGetWMHints(ps->dpy, wid);
		if (h && (IconPixmapHint & h->flags) && h->icon_pixmap)
			pictw = simg_pixmap_to_pictw(ps, 0, 0, 0, h->icon_pixmap, h->icon_mask);
		sxfree(h);
	}

	if (pictw) goto simg_load_icon_end;

	// KWM_WIN_ICON
	// Same issue as above.
	{
		winprop_t prop = wid_get_prop_adv(ps, wid, KWM_WIN_ICON, 0, 2, KWM_WIN_ICON, 32);
		if (prop.nitems) {
			Pixmap pxmap = prop.data32[0],
						 mask = (prop.nitems >= 2 ? prop.data32[1]: None);
			if (pxmap)
				pictw = simg_pixmap_to_pictw(ps, 0, 0, 0, pxmap, mask);
		}
		free_winprop(&prop);
	}

	if (pictw) goto simg_load_icon_end;

simg_load_icon_end:
	// Post-processing
	if (pictw && !processed) {
		pictw = simg_postprocess(ps, pictw, PICTPOSP_SCALEK,
				desired_size, desired_size, ALIGN_MID, ALIGN_MID, NULL);
		/* printfdf("(%#010lx): (width %d, height %d) Processed.",
				wid, pictw->width, pictw->height); */
	}

	return pictw;
}