Ejemplo n.º 1
0
void move_fence(node_t *n, direction_t dir, fence_move_t mov)
{
    node_t *fence = find_fence(n, dir);

    if (fence == NULL)
        return;

    if ((mov == MOVE_PUSH && (dir == DIR_RIGHT || dir == DIR_DOWN))
            || (mov == MOVE_PULL && (dir == DIR_LEFT || dir == DIR_UP)))
        change_split_ratio(fence, CHANGE_INCREASE);
    else
        change_split_ratio(fence, CHANGE_DECREASE);
}
Ejemplo n.º 2
0
node_t *find_neighbor(node_t *n, direction_t dir)
{
    node_t *fence = find_fence(n, dir);

    if (fence == NULL)
        return NULL;

    if (dir == DIR_UP || dir == DIR_LEFT)
        return second_extrema(fence->first_child);
    else if (dir == DIR_DOWN || dir == DIR_RIGHT)
        return first_extrema(fence->second_child);

    return NULL;
}
Ejemplo n.º 3
0
void grab_pointer(pointer_action_t pac)
{
    PRINTF("grab pointer %u\n", pac);

    xcb_window_t win = XCB_NONE;
    xcb_point_t pos;

    query_pointer(&win, &pos);

    coordinates_t loc;
    if (locate_window(win, &loc)) {
        client_t *c = NULL;
        frozen_pointer->position = pos;
        frozen_pointer->action = pac;
        c = loc.node->client;
        frozen_pointer->monitor = loc.monitor;
        frozen_pointer->desktop = loc.desktop;
        frozen_pointer->node = loc.node;
        frozen_pointer->client = c;
        frozen_pointer->window = c->window;
        frozen_pointer->horizontal_fence = NULL;
        frozen_pointer->vertical_fence = NULL;

        switch (pac)  {
            case ACTION_FOCUS:
                if (loc.node != mon->desk->focus) {
                    bool backup = pointer_follows_monitor;
                    pointer_follows_monitor = false;
                    focus_node(loc.monitor, loc.desktop, loc.node);
                    pointer_follows_monitor = backup;
                } else if (focus_follows_pointer) {
                    stack(loc.node, STACK_ABOVE);
                }
                frozen_pointer->action = ACTION_NONE;
                break;
            case ACTION_MOVE:
            case ACTION_RESIZE_SIDE:
            case ACTION_RESIZE_CORNER:
                if (is_tiled(c)) {
                    frozen_pointer->rectangle = c->tiled_rectangle;
                    frozen_pointer->is_tiled = true;
                } else if (is_floating(c)) {
                    frozen_pointer->rectangle = c->floating_rectangle;
                    frozen_pointer->is_tiled = false;
                } else {
                    frozen_pointer->action = ACTION_NONE;
                    return;
                }
                if (pac == ACTION_RESIZE_SIDE) {
                    float W = frozen_pointer->rectangle.width;
                    float H = frozen_pointer->rectangle.height;
                    float ratio = W / H;
                    float x = pos.x - frozen_pointer->rectangle.x;
                    float y = pos.y - frozen_pointer->rectangle.y;
                    float diag_a = ratio * y;
                    float diag_b = W - diag_a;
                    if (x < diag_a) {
                        if (x < diag_b)
                            frozen_pointer->side = SIDE_LEFT;
                        else
                            frozen_pointer->side = SIDE_BOTTOM;
                    } else {
                        if (x < diag_b)
                            frozen_pointer->side = SIDE_TOP;
                        else
                            frozen_pointer->side = SIDE_RIGHT;
                    }
                } else if (pac == ACTION_RESIZE_CORNER) {
                    int16_t mid_x = frozen_pointer->rectangle.x + (frozen_pointer->rectangle.width / 2);
                    int16_t mid_y = frozen_pointer->rectangle.y + (frozen_pointer->rectangle.height / 2);
                    if (pos.x > mid_x) {
                        if (pos.y > mid_y)
                            frozen_pointer->corner = CORNER_BOTTOM_RIGHT;
                        else
                            frozen_pointer->corner = CORNER_TOP_RIGHT;
                    } else {
                        if (pos.y > mid_y)
                            frozen_pointer->corner = CORNER_BOTTOM_LEFT;
                        else
                            frozen_pointer->corner = CORNER_TOP_LEFT;
                    }
                }
                if (frozen_pointer->is_tiled) {
                    if (pac == ACTION_RESIZE_SIDE) {
                        switch (frozen_pointer->side) {
                            case SIDE_TOP:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
                                break;
                            case SIDE_RIGHT:
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
                                break;
                            case SIDE_BOTTOM:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
                                break;
                            case SIDE_LEFT:
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
                                break;
                        }
                    } else if (pac == ACTION_RESIZE_CORNER) {
                        switch (frozen_pointer->corner) {
                            case CORNER_TOP_LEFT:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
                                break;
                            case CORNER_TOP_RIGHT:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP);
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
                                break;
                            case CORNER_BOTTOM_RIGHT:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT);
                                break;
                            case CORNER_BOTTOM_LEFT:
                                frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN);
                                frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT);
                                break;
                        }
                    }
                    if (frozen_pointer->horizontal_fence != NULL)
                        frozen_pointer->horizontal_ratio = frozen_pointer->horizontal_fence->split_ratio;
                    if (frozen_pointer->vertical_fence != NULL)
                        frozen_pointer->vertical_ratio = frozen_pointer->vertical_fence->split_ratio;
                }
                break;
            case ACTION_NONE:
                break;
        }
    } else {
        if (pac == ACTION_FOCUS) {
            monitor_t *m = monitor_from_point(pos);
            if (m != NULL && m != mon)
                focus_node(m, m->desk, m->desk->focus);
        }
        frozen_pointer->action = ACTION_NONE;
    }
}
Ejemplo n.º 4
0
void grab_pointer(pointer_action_t pac)
{
	xcb_window_t win = XCB_NONE;
	xcb_point_t pos;

	query_pointer(&win, &pos);

	coordinates_t loc;
	if (locate_window(win, &loc)) {
		client_t *c = loc.node->client;

		frozen_pointer->position = pos;
		frozen_pointer->action = pac;
		frozen_pointer->monitor = loc.monitor;
		frozen_pointer->desktop = loc.desktop;
		frozen_pointer->node = loc.node;
		frozen_pointer->client = c;
		frozen_pointer->window = loc.node->id;
		frozen_pointer->horizontal_fence = NULL;
		frozen_pointer->vertical_fence = NULL;

		switch (pac)  {
			case ACTION_FOCUS:
				if (loc.node != mon->desk->focus) {
					bool backup = pointer_follows_monitor;
					pointer_follows_monitor = false;
					focus_node(loc.monitor, loc.desktop, loc.node);
					pointer_follows_monitor = backup;
				} else if (focus_follows_pointer) {
					stack(loc.desktop, loc.node, true);
				}
				frozen_pointer->action = ACTION_NONE;
				break;
			case ACTION_MOVE:
			case ACTION_RESIZE_SIDE:
			case ACTION_RESIZE_CORNER:
				if (IS_FLOATING(c)) {
					frozen_pointer->rectangle = c->floating_rectangle;
					frozen_pointer->is_tiled = false;
				} else if (IS_TILED(c)) {
					frozen_pointer->rectangle = c->tiled_rectangle;
					frozen_pointer->is_tiled = (pac == ACTION_MOVE || c->state != STATE_PSEUDO_TILED);
				} else {
					frozen_pointer->action = ACTION_NONE;
					return;
				}
				if (pac == ACTION_RESIZE_SIDE) {
					float W = frozen_pointer->rectangle.width;
					float H = frozen_pointer->rectangle.height;
					float ratio = W / H;
					float x = pos.x - frozen_pointer->rectangle.x;
					float y = pos.y - frozen_pointer->rectangle.y;
					float diag_a = ratio * y;
					float diag_b = W - diag_a;
					if (x < diag_a) {
						if (x < diag_b) {
							frozen_pointer->side = SIDE_LEFT;
						} else {
							frozen_pointer->side = SIDE_BOTTOM;
						}
					} else {
						if (x < diag_b) {
							frozen_pointer->side = SIDE_TOP;
						} else {
							frozen_pointer->side = SIDE_RIGHT;
						}
					}
				} else if (pac == ACTION_RESIZE_CORNER) {
					int16_t mid_x = frozen_pointer->rectangle.x + (frozen_pointer->rectangle.width / 2);
					int16_t mid_y = frozen_pointer->rectangle.y + (frozen_pointer->rectangle.height / 2);
					if (pos.x > mid_x) {
						if (pos.y > mid_y) {
							frozen_pointer->corner = CORNER_BOTTOM_RIGHT;
						} else {
							frozen_pointer->corner = CORNER_TOP_RIGHT;
						}
					} else {
						if (pos.y > mid_y) {
							frozen_pointer->corner = CORNER_BOTTOM_LEFT;
						} else {
							frozen_pointer->corner = CORNER_TOP_LEFT;
						}
					}
				}
				if (frozen_pointer->is_tiled) {
					if (pac == ACTION_RESIZE_SIDE) {
						switch (frozen_pointer->side) {
							case SIDE_TOP:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_NORTH);
								break;
							case SIDE_RIGHT:
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_EAST);
								break;
							case SIDE_BOTTOM:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_SOUTH);
								break;
							case SIDE_LEFT:
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_WEST);
								break;
						}
					} else if (pac == ACTION_RESIZE_CORNER) {
						switch (frozen_pointer->corner) {
							case CORNER_TOP_LEFT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_NORTH);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_WEST);
								break;
							case CORNER_TOP_RIGHT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_NORTH);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_EAST);
								break;
							case CORNER_BOTTOM_RIGHT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_SOUTH);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_EAST);
								break;
							case CORNER_BOTTOM_LEFT:
								frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_SOUTH);
								frozen_pointer->vertical_fence = find_fence(loc.node, DIR_WEST);
								break;
						}
					}
					if (frozen_pointer->horizontal_fence != NULL) {
						frozen_pointer->horizontal_ratio = frozen_pointer->horizontal_fence->split_ratio;
					}
					if (frozen_pointer->vertical_fence != NULL) {
						frozen_pointer->vertical_ratio = frozen_pointer->vertical_fence->split_ratio;
					}
				}
				break;
			case ACTION_NONE:
				break;
		}
	} else {
		if (pac == ACTION_FOCUS) {
			monitor_t *m = monitor_from_point(pos);
			if (m != NULL && m != mon && (win == XCB_NONE || win == m->root)) {
				focus_node(m, m->desk, m->desk->focus);
			}
		}
		frozen_pointer->action = ACTION_NONE;
	}
}
Ejemplo n.º 5
0
Archivo: window.c Proyecto: 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;
}