Exemplo n.º 1
0
Arquivo: monitor.c Projeto: dj95/bspwm
void update_root(monitor_t *m, xcb_rectangle_t *rect)
{
	xcb_rectangle_t last_rect = m->rectangle;
	m->rectangle = *rect;
	if (m->root == XCB_NONE) {
		uint32_t values[] = {XCB_EVENT_MASK_ENTER_WINDOW};
		m->root = xcb_generate_id(dpy);
		xcb_create_window(dpy, XCB_COPY_FROM_PARENT, m->root, root,
		                  rect->x, rect->y, rect->width, rect->height, 0,
		                  XCB_WINDOW_CLASS_INPUT_ONLY, XCB_COPY_FROM_PARENT, XCB_CW_EVENT_MASK, values);
		xcb_icccm_set_wm_class(dpy, m->root, sizeof(ROOT_WINDOW_IC), ROOT_WINDOW_IC);
		window_lower(m->root);
		if (focus_follows_pointer) {
			window_show(m->root);
		}
	} else {
		window_move_resize(m->root, rect->x, rect->y, rect->width, rect->height);
		put_status(SBSC_MASK_MONITOR_GEOMETRY, "monitor_geometry 0x%08X %ux%u+%i+%i\n",
		           m->id, rect->width, rect->height, rect->x, rect->y);
	}
	for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
		for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
			if (n->client == NULL) {
				continue;
			}
			adapt_geometry(&last_rect, rect, n);
		}
		arrange(m, d);
	}
}
Exemplo n.º 2
0
static int action_window (Display *disp, Window win, char mode) {/*{{{*/
    p_verbose("Using window: 0x%.8lx\n", win);
    switch (mode) {
        case 'a':
            return activate_window(disp, win, True);

        case 'c':
            return close_window(disp, win);

        case 'e':
            /* resize/move the window around the desktop => -r -e */
            return window_move_resize(disp, win, options.param);

        case 't':
            /* move the window to the specified desktop => -r -t */
            return window_to_desktop(disp, win, atoi(options.param));
        
        case 'R':
            /* move the window to the current desktop and activate it => -r */
            if (window_to_desktop(disp, win, -1) == EXIT_SUCCESS) {
                usleep(100000); /* 100 ms - make sure the WM has enough
                    time to move the window, before we activate it */
                return activate_window(disp, win, False);
            }
            else {
                return EXIT_FAILURE;
            }

        default:
            fprintf(stderr, "Unknown action: '%c'\n", mode);
            return EXIT_FAILURE;
    }
}/*}}}*/
Exemplo n.º 3
0
void transfer_node(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd, node_t *n)
{
    if (n == NULL || ds == NULL || dd == NULL || ms == NULL || md == NULL || (ms == md && dd == ds))
        return;

    PRINTF("transfer node %X\n", n->client->window);

    unlink_node(ds, n);
    insert_node(md, dd, n);
    ewmh_set_wm_desktop(n, dd);

    if (ds == ms->desk && dd != md->desk) {
        window_hide(n->client->window);
    }

    fit_monitor(md, n->client);

    if (n->client->fullscreen)
        window_move_resize(n->client->window, md->rectangle.x, md->rectangle.y, md->rectangle.width, md->rectangle.height);

    if (ds != ms->desk && dd == md->desk) {
        window_show(n->client->window);
        focus_node(md, dd, n, true);
    } else {
        focus_node(md, dd, n, false);
    }

    if (ds == ms->desk || dd == md->desk)
        update_current();
}
Exemplo n.º 4
0
Arquivo: window.c Projeto: nfnty/bspwm
void draw_presel_feedback(monitor_t *m, desktop_t *d, node_t *n)
{
	if (n == NULL || n->presel == NULL || d->layout == LAYOUT_MONOCLE) {
		return;
	}

	if (focus_follows_pointer) {
		listen_enter_notify(d->root, false);
	}

	bool exists = (n->presel->feedback != XCB_NONE);
	if (!exists) {
		initialize_presel_feedback(n);
	}

	int gap = gapless_monocle && IS_MONOCLE(d) ? 0 : d->window_gap;
	presel_t *p = n->presel;
	xcb_rectangle_t rect = n->rectangle;
	rect.x = rect.y = 0;
	rect.width -= gap;
	rect.height -= gap;
	xcb_rectangle_t presel_rect = rect;

	switch (p->split_dir) {
		case DIR_NORTH:
			presel_rect.height = p->split_ratio * rect.height;
			break;
		case DIR_EAST:
			presel_rect.width = (1 - p->split_ratio) * rect.width;
			presel_rect.x = rect.width - presel_rect.width;
			break;
		case DIR_SOUTH:
			presel_rect.height = (1 - p->split_ratio) * rect.height;
			presel_rect.y = rect.height - presel_rect.height;
			break;
		case DIR_WEST:
			presel_rect.width = p->split_ratio * rect.width;
			break;
	}

	window_move_resize(p->feedback, n->rectangle.x + presel_rect.x, n->rectangle.y + presel_rect.y,
	                   presel_rect.width, presel_rect.height);

	if (!exists && m->desk == d) {
		window_show(p->feedback);
	}

	if (focus_follows_pointer) {
		listen_enter_notify(d->root, true);
	}
}
Exemplo n.º 5
0
void update_root(monitor_t *m)
{
    xcb_rectangle_t rect = m->rectangle;
    window_move_resize(m->root, rect.x, rect.y, rect.width, rect.height);
}
Exemplo n.º 6
0
void track_pointer(int root_x, int root_y)
{
    if (frozen_pointer->action == ACTION_NONE)
        return;

    int16_t delta_x, delta_y, x = 0, y = 0, w = 1, h = 1;
    uint16_t width, height;

    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_tiled(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(mon, mon->desk);
            } 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;
                    }
                    width = MAX(1, w);
                    height = MAX(1, h);
                    window_move_resize(win, x, y, width, height);
                    c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
                    window_draw_border(n, d->focus == n, mon == m);
                } 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;
                    }
                    width = MAX(1, w);
                    height = MAX(1, h);
                    window_move_resize(win, x, y, width, height);
                    c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
                    window_draw_border(n, d->focus == n, mon == m);
                }
            }
            break;
        case ACTION_FOCUS:
        case ACTION_NONE:
            break;
    }
}
Exemplo n.º 7
0
Arquivo: window.c Projeto: nfnty/bspwm
bool resize_client(coordinates_t *loc, resize_handle_t rh, int dx, int dy)
{
	node_t *n = loc->node;
	if (n == NULL || n->client == NULL || n->client->state == STATE_FULLSCREEN) {
		return false;
	}
	node_t *horizontal_fence = NULL, *vertical_fence = NULL;
	xcb_rectangle_t rect = get_rectangle(NULL, n);
	uint16_t width = rect.width, height = rect.height;
	int16_t x = rect.x, y = rect.y;
	if (n->client->state == STATE_TILED) {
		if (rh & HANDLE_LEFT) {
			vertical_fence = find_fence(n, DIR_WEST);
		} else if (rh & HANDLE_RIGHT) {
			vertical_fence = find_fence(n, DIR_EAST);
		}
		if (rh & HANDLE_TOP) {
			horizontal_fence = find_fence(n, DIR_NORTH);
		} else if (rh & HANDLE_BOTTOM) {
			horizontal_fence = find_fence(n, DIR_SOUTH);
		}
		if (vertical_fence == NULL && horizontal_fence == NULL) {
			return false;
		}
		if (vertical_fence != NULL) {
			double sr = vertical_fence->split_ratio + (double) dx / vertical_fence->rectangle.width;
			sr = MAX(0, sr);
			sr = MIN(1, sr);
			vertical_fence->split_ratio = sr;
		}
		if (horizontal_fence != NULL) {
			double sr = horizontal_fence->split_ratio + (double) dy / horizontal_fence->rectangle.height;
			sr = MAX(0, sr);
			sr = MIN(1, sr);
			horizontal_fence->split_ratio = sr;
		}
		arrange(loc->monitor, loc->desktop);
	} else {
		int w = width + dx * (rh & HANDLE_LEFT ? -1 : (rh & HANDLE_RIGHT ? 1 : 0));
		int h = height + dy * (rh & HANDLE_TOP ? -1 : (rh & HANDLE_BOTTOM ? 1 : 0));
		width = MAX(1, w);
		height = MAX(1, h);
		apply_size_hints(n->client, &width, &height);
		if (rh & HANDLE_LEFT) {
			x += rect.width - width;
		}
		if (rh & HANDLE_TOP) {
			y += rect.height - height;
		}
		n->client->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
		if (n->client->state == STATE_FLOATING) {
			if (focus_follows_pointer) {
				listen_enter_notify(loc->desktop->root, false);
			}

			window_move_resize(n->id, x, y, width, height);

			if (focus_follows_pointer) {
				listen_enter_notify(loc->desktop->root, true);
			}

			if (!grabbing) {
				put_status(SBSC_MASK_NODE_GEOMETRY, "node_geometry 0x%08X 0x%08X 0x%08X %ux%u+%i+%i\n", loc->monitor->id, loc->desktop->id, loc->node->id, width, height, x, y);
			}
		} else {
			arrange(loc->monitor, loc->desktop);
		}
	}
	return true;
}
Exemplo n.º 8
0
void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, xcb_rectangle_t root_rect)
{
    if (n == NULL)
        return;

    n->rectangle = rect;

    if (is_leaf(n)) {
        if (n->client->fullscreen)
            return;

        if (is_floating(n->client) && n->client->border_width != border_width) {
            int ds = 2 * (border_width - n->client->border_width);
            n->client->floating_rectangle.width += ds;
            n->client->floating_rectangle.height += ds;
        }

        if (borderless_monocle && is_tiled(n->client) && d->layout == LAYOUT_MONOCLE)
            n->client->border_width = 0;
        else
            n->client->border_width = border_width;

        xcb_rectangle_t r;
        if (is_tiled(n->client)) {
            if (d->layout == LAYOUT_TILED)
                r = rect;
            else if (d->layout == LAYOUT_MONOCLE)
                r = root_rect;
            int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : window_gap);
            int bleed = wg + 2 * n->client->border_width;
            r.width = (bleed < r.width ? r.width - bleed : 1);
            r.height = (bleed < r.height ? r.height - bleed : 1);
            n->client->tiled_rectangle = r;
        } else {
            r = n->client->floating_rectangle;
        }

        window_move_resize(n->client->window, r.x, r.y, r.width, r.height);
        window_border_width(n->client->window, n->client->border_width);
        window_draw_border(n, n == d->focus, m == mon);

    } else {
        xcb_rectangle_t first_rect;
        xcb_rectangle_t second_rect;

        if (n->first_child->vacant || n->second_child->vacant) {
            first_rect = second_rect = rect;
        } else {
            unsigned int fence;
            if (n->split_type == TYPE_VERTICAL) {
                fence = rect.width * n->split_ratio;
                first_rect = (xcb_rectangle_t) {rect.x, rect.y, fence, rect.height};
                second_rect = (xcb_rectangle_t) {rect.x + fence, rect.y, rect.width - fence, rect.height};

            } else if (n->split_type == TYPE_HORIZONTAL) {
                fence = rect.height * n->split_ratio;
                first_rect = (xcb_rectangle_t) {rect.x, rect.y, rect.width, fence};
                second_rect = (xcb_rectangle_t) {rect.x, rect.y + fence, rect.width, rect.height - fence};
            }
        }

        apply_layout(m, d, n->first_child, first_rect, root_rect);
        apply_layout(m, d, n->second_child, second_rect, root_rect);
    }
}