Пример #1
0
void property_notify(xcb_generic_event_t *evt)
{
	xcb_property_notify_event_t *e = (xcb_property_notify_event_t *) evt;

	/* PRINTF("property notify %X\n", e->window); */

	if (e->atom != XCB_ATOM_WM_HINTS && e->atom != XCB_ATOM_WM_NORMAL_HINTS)
		return;

	coordinates_t loc;
	if (!locate_window(e->window, &loc))
			return;

	if (e->atom == XCB_ATOM_WM_HINTS) {
		xcb_icccm_wm_hints_t hints;
		if (xcb_icccm_get_wm_hints_reply(dpy, xcb_icccm_get_wm_hints(dpy, e->window), &hints, NULL) == 1 &&
		    (hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY))
			set_urgency(loc.monitor, loc.desktop, loc.node, xcb_icccm_wm_hints_get_urgency(&hints));
	} else if (e->atom == XCB_ATOM_WM_NORMAL_HINTS) {
		client_t *c = loc.node->client;
		xcb_size_hints_t size_hints;
		if (xcb_icccm_get_wm_normal_hints_reply(dpy, xcb_icccm_get_wm_normal_hints(dpy, e->window), &size_hints, NULL) == 1 &&
		    (size_hints.flags & (XCB_ICCCM_SIZE_HINT_P_MIN_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE))) {
			c->min_width = size_hints.min_width;
			c->max_width = size_hints.max_width;
			c->min_height = size_hints.min_height;
			c->max_height = size_hints.max_height;
			int w = c->floating_rectangle.width;
			int h = c->floating_rectangle.height;
			restrain_floating_size(c, &w, &h);
			c->floating_rectangle.width = w;
			c->floating_rectangle.height = h;
			arrange(loc.monitor, loc.desktop);
		}
	}
}
Пример #2
0
void track_pointer(int root_x, int root_y)
{
	if (frozen_pointer->action == ACTION_NONE)
		return;

	int delta_x, delta_y, x = 0, y = 0, w = 1, h = 1;

	pointer_action_t pac = frozen_pointer->action;
	monitor_t *m = frozen_pointer->monitor;
	desktop_t *d = frozen_pointer->desktop;
	node_t *n = frozen_pointer->node;
	client_t *c = frozen_pointer->client;
	xcb_window_t win = frozen_pointer->window;
	xcb_rectangle_t rect = frozen_pointer->rectangle;
	node_t *vertical_fence = frozen_pointer->vertical_fence;
	node_t *horizontal_fence = frozen_pointer->horizontal_fence;

	delta_x = root_x - frozen_pointer->position.x;
	delta_y = root_y - frozen_pointer->position.y;

	switch (pac) {
		case ACTION_MOVE:
			if (frozen_pointer->is_tiled) {
				xcb_window_t pwin = XCB_NONE;
				query_pointer(&pwin, NULL);
				if (pwin == win)
					return;
				coordinates_t loc;
				bool is_managed = (pwin == XCB_NONE ? false : locate_window(pwin, &loc));
				if (is_managed && !IS_FLOATING(loc.node->client) && loc.monitor == m) {
					swap_nodes(m, d, n, m, d, loc.node);
					arrange(m, d);
				} else {
					if (is_managed && loc.monitor == m) {
						return;
					} else if (!is_managed) {
						xcb_point_t pt = (xcb_point_t) {root_x, root_y};
						monitor_t *pmon = monitor_from_point(pt);
						if (pmon == NULL || pmon == m) {
							return;
						} else {
							loc.monitor = pmon;
							loc.desktop = pmon->desk;
						}
					}
					bool focused = (n == mon->desk->focus);
					transfer_node(m, d, n, loc.monitor, loc.desktop, loc.desktop->focus);
					if (focused)
						focus_node(loc.monitor, loc.desktop, n);
					frozen_pointer->monitor = loc.monitor;
					frozen_pointer->desktop = loc.desktop;
				}
			} else {
				x = rect.x + delta_x;
				y = rect.y + delta_y;
				window_move(win, x, y);
				c->floating_rectangle.x = x;
				c->floating_rectangle.y = y;
				xcb_point_t pt = (xcb_point_t) {root_x, root_y};
				monitor_t *pmon = monitor_from_point(pt);
				if (pmon == NULL || pmon == m)
					return;
				bool focused = (n == mon->desk->focus);
				transfer_node(m, d, n, pmon, pmon->desk, pmon->desk->focus);
				if (focused)
					focus_node(pmon, pmon->desk, n);
				frozen_pointer->monitor = pmon;
				frozen_pointer->desktop = pmon->desk;
			}
			break;
		case ACTION_RESIZE_SIDE:
		case ACTION_RESIZE_CORNER:
			if (frozen_pointer->is_tiled) {
				if (vertical_fence != NULL) {
					double sr = frozen_pointer->vertical_ratio + (double) delta_x / vertical_fence->rectangle.width;
					sr = MAX(0, sr);
					sr = MIN(1, sr);
					vertical_fence->split_ratio = sr;
				}
				if (horizontal_fence != NULL) {
					double sr = frozen_pointer->horizontal_ratio + (double) delta_y / horizontal_fence->rectangle.height;
					sr = MAX(0, sr);
					sr = MIN(1, sr);
					horizontal_fence->split_ratio = sr;
				}
				arrange(m, d);
			} else {
				if (pac == ACTION_RESIZE_SIDE) {
					switch (frozen_pointer->side) {
						case SIDE_TOP:
							x = rect.x;
							y = rect.y + delta_y;
							w = rect.width;
							h = rect.height - delta_y;
							break;
						case SIDE_RIGHT:
							x = rect.x;
							y = rect.y;
							w = rect.width + delta_x;
							h = rect.height;
							break;
						case SIDE_BOTTOM:
							x = rect.x;
							y = rect.y;
							w = rect.width;
							h = rect.height + delta_y;
							break;
						case SIDE_LEFT:
							x = rect.x + delta_x;
							y = rect.y;
							w = rect.width - delta_x;
							h = rect.height;
							break;
					}
				} else if (pac == ACTION_RESIZE_CORNER) {
					switch (frozen_pointer->corner) {
						case CORNER_TOP_LEFT:
							x = rect.x + delta_x;
							y = rect.y + delta_y;
							w = rect.width - delta_x;
							h = rect.height - delta_y;
							break;
						case CORNER_TOP_RIGHT:
							x = rect.x;
							y = rect.y + delta_y;
							w = rect.width + delta_x;
							h = rect.height - delta_y;
							break;
						case CORNER_BOTTOM_LEFT:
							x = rect.x + delta_x;
							y = rect.y;
							w = rect.width - delta_x;
							h = rect.height + delta_y;
							break;
						case CORNER_BOTTOM_RIGHT:
							x = rect.x;
							y = rect.y;
							w = rect.width + delta_x;
							h = rect.height + delta_y;
							break;
					}
				}

				int oldw = w, oldh = h;
				restrain_floating_size(c, &w, &h);

				if (c->state == STATE_FLOATING) {
					if (oldw == w) {
						c->floating_rectangle.x = x;
						c->floating_rectangle.width = w;
					}
					if (oldh == h) {
						c->floating_rectangle.y = y;
						c->floating_rectangle.height = h;
					}
					window_move_resize(win, c->floating_rectangle.x,
					                        c->floating_rectangle.y,
					                        c->floating_rectangle.width,
					                        c->floating_rectangle.height);
				} else {
					c->floating_rectangle.width = w;
					c->floating_rectangle.height = h;
					arrange(m, d);
				}
			}
			break;
		case ACTION_FOCUS:
		case ACTION_NONE:
			break;
	}
}