Ejemplo n.º 1
0
/*
 * @brief range a column of window on the given geometry.
 */
static void
relayout_onecol(const wlc_handle *views, const size_t nviews,
		const struct wlc_geometry *geo)
{
	if (nviews == 0)
		return;
	size_t y = geo->origin.y;
	//if nviews == 0, crashes
	size_t srow = (size_t) (geo->size.h / nviews);
	for (size_t i = 0; i < nviews; i++) {
		struct wlc_geometry g = {
			{geo->origin.x, y},//point
			{geo->size.w, srow}//size
		};
		//fprintf(debug_file, "the geometry for %d view is: x %d, y %d, w %d, h %d\n",
		//	i,
		//	g.origin.x,
		//	g.origin.y,
		//	g.size.w,
		//	g.size.h);
		//fflush(debug_file);
		
		y += srow;
		wlc_view_set_geometry(views[i], 0, &g);
	}
}
Ejemplo n.º 2
0
/**
 * 
 * @brief the simple floating windows relayout strategy, which is actually
 * doing nothing.
 *
 * Tested
 */
static void
relayout_float(const tw_handle *views, const size_t nviews,
	       const wlc_geometry *geo)
{
	//this method has to be called in safe env.
	if(!views || !geo)
		return;
	const wlc_size *r = &geo->size;
	//this method is not safe, how do you ensure you will not access
	//unallocated memory? c++ vector?
	for (size_t i = 0; i < nviews; i++) {
		debug_log("relayout_float\n");
		//the only thing we are doing here is ensure the the window
		//does not go out or border, but is may not be good, since
		//windows can have border
		struct wlc_geometry g = *wlc_view_get_geometry(views[i]);
		g.size.h = (g.size.h > 0) ? g.size.h : 100;//give a initial height if not avaliable
		g.size.w = (g.size.w > 0) ? g.size.w : 100;//give a initial wpidth if not avaliable
		
		int32_t view_botton = g.origin.y+g.size.h;
		int32_t view_right = g.origin.x+g.size.w;
		
		g.size.h = MIN(view_botton, r->h) - g.origin.y;
		g.size.w = MIN(view_right, r->w) - g.origin.x;
		wlc_view_set_geometry(views[i], 0, &g);
		wlc_view_bring_to_front(views[i]);
	}
}
Ejemplo n.º 3
0
static void
relayout_onerow(const wlc_handle *views, const size_t nviews,
		const struct wlc_geometry *geo)
{
	if (nviews == 0)
		return;
	size_t x = geo->origin.x;
	//if nviews == 0, crashes
	size_t scol = (size_t) (geo->size.w / nviews);
	for (size_t i = 0; i < nviews; i++) {
		struct wlc_geometry g = {
			{x, geo->origin.y},//point
			{scol, geo->size.h}//size
		};
		x += scol;
		wlc_view_set_geometry(views[i], 0, &g);
	}
}
Ejemplo n.º 4
0
Archivo: example.c Proyecto: hsoft/wlc
static void
relayout(wlc_handle output)
{
   const struct wlc_size *r;
   if (!(r = wlc_output_get_resolution(output)))
      return;

   size_t memb;
   const wlc_handle *views = wlc_output_get_views(output, &memb);

   bool toggle = false;
   uint32_t y = 0;
   uint32_t w = r->w / 2, h = r->h / chck_maxu32((1 + memb) / 2, 1);
   for (size_t i = 0; i < memb; ++i) {
      struct wlc_geometry g = { { (toggle ? w : 0), y }, { (!toggle && i == memb - 1 ? r->w : w), h } };
      wlc_view_set_geometry(views[i], &g);
      y = y + (!(toggle = !toggle) ? h : 0);
   }
}
Ejemplo n.º 5
0
static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) {
	static struct wlc_origin prev_pos;
	static wlc_handle prev_handle = 0;
	mouse_origin = *origin;
	bool changed_floating = false;
	bool changed_tiling = false;
	int min_sane_w = 100;
	int min_sane_h = 60;
	if (!active_workspace) {
		return false;
	}
	// Do checks to determine if proper keys are being held
	swayc_t *view = container_under_pointer();
	uint32_t edge = 0;
	if (pointer_state.floating.drag && view) {
		if (view->is_floating) {
			int dx = mouse_origin.x - prev_pos.x;
			int dy = mouse_origin.y - prev_pos.y;
			view->x += dx;
			view->y += dy;
			changed_floating = true;
		}
	} else if (pointer_state.floating.resize && view) {
		if (view->is_floating) {
			int dx = mouse_origin.x - prev_pos.x;
			int dy = mouse_origin.y - prev_pos.y;

			// Move and resize the view based on the dx/dy and mouse position
			int midway_x = view->x + view->width/2;
			int midway_y = view->y + view->height/2;
			if (dx < 0) {
				if (!pointer_state.lock.right) {
					if (view->width > min_sane_w) {
						changed_floating = true;
						view->width += dx;
						edge += WLC_RESIZE_EDGE_RIGHT;
					}
				} else if (mouse_origin.x < midway_x && !pointer_state.lock.left) {
					changed_floating = true;
					view->x += dx;
					view->width -= dx;
					edge += WLC_RESIZE_EDGE_LEFT;
				}
			} else if (dx > 0) {
				if (mouse_origin.x > midway_x && !pointer_state.lock.right) {
					changed_floating = true;
					view->width += dx;
					edge += WLC_RESIZE_EDGE_RIGHT;
				} else if (!pointer_state.lock.left) {
					if (view->width > min_sane_w) {
						changed_floating = true;
						view->x += dx;
						view->width -= dx;
						edge += WLC_RESIZE_EDGE_LEFT;
					}
				}
			}

			if (dy < 0) {
				if (!pointer_state.lock.bottom) {
					if (view->height > min_sane_h) {
						changed_floating = true;
						view->height += dy;
						edge += WLC_RESIZE_EDGE_BOTTOM;
					}
				} else if (mouse_origin.y < midway_y && !pointer_state.lock.top) {
					changed_floating = true;
					view->y += dy;
					view->height -= dy;
					edge += WLC_RESIZE_EDGE_TOP;
				}
			} else if (dy > 0) {
				if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) {
					changed_floating = true;
					view->height += dy;
					edge += WLC_RESIZE_EDGE_BOTTOM;
				} else if (!pointer_state.lock.top) {
					if (view->height > min_sane_h) {
						changed_floating = true;
						view->y += dy;
						view->height -= dy;
						edge += WLC_RESIZE_EDGE_TOP;
					}
				}
			}
		}
	} else if (pointer_state.tiling.resize && view) {
		bool valid = true;
		double dx = mouse_origin.x - prev_pos.x;
		double dy = mouse_origin.y - prev_pos.y;

		if ((dx < 0 || mouse_origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) {
			changed_tiling = true;
			valid = false;
		} else if (dx > 0 && pointer_state.lock.temp_left) {
			pointer_state.lock.temp_left = false;
		}

		if ((dx > 0 || mouse_origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) {
			changed_tiling = true;
			valid = false;
		} else if (dx < 0 && pointer_state.lock.temp_right) {
			pointer_state.lock.temp_right = false;
		}

		if ((dy < 0 || mouse_origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) {
			changed_tiling = true;
			valid = false;
		} else if (dy > 0 && pointer_state.lock.temp_up) {
			pointer_state.lock.temp_up = false;
		}

		if ((dy > 0 || mouse_origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) {
			changed_tiling = true;
			valid = false;
		} else if (dy < 0 && pointer_state.lock.temp_down) {
			pointer_state.lock.temp_down = false;
		}

		if (!view->is_floating && valid) {
			// Handle layout resizes -- Find the biggest parent container then apply resizes to that
			// and its bordering siblings
			swayc_t *parent = view;
			if (!pointer_state.lock.bottom) {
				while (parent->type != C_WORKSPACE) {
					// TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
					// way of doing this.
					if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
						parent = parent->parent;
					} else {
						break;
					}
				}
				if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
					swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
					if (sibling) {
						if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
							recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
							recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
							changed_tiling = true;
						} else {
							pointer_state.tiling.lock_pos.y = mouse_origin.y;
							if (parent->height < min_sane_h) {
								pointer_state.lock.temp_up = true;
							} else if (sibling->height < min_sane_h) {
								pointer_state.lock.temp_down = true;
							}
						}
					}
				}
			} else if (!pointer_state.lock.top) {
				while (parent->type != C_WORKSPACE) {
					if (fabs(parent->parent->y - view->y) <= 1) {
						parent = parent->parent;
					} else {
						break;
					}
				}
				if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
					swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
					if (sibling) {
						if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
							recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
							recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
							changed_tiling = true;
						} else {
							pointer_state.tiling.lock_pos.y = mouse_origin.y;
							if (parent->height < min_sane_h) {
								pointer_state.lock.temp_down = true;
							} else if (sibling->height < min_sane_h) {
								pointer_state.lock.temp_up = true;
							}
						}
					}
				}
			}

			parent = view;
			if (!pointer_state.lock.right) {
				while (parent->type != C_WORKSPACE) {
					if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
						parent = parent->parent;
					} else {
						sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
						break;
					}
				}
				if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
					swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
					if (sibling) {
						if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
							recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
							recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
							changed_tiling = true;
						} else {
							pointer_state.tiling.lock_pos.x = mouse_origin.x;
							if (parent->width < min_sane_w) {
								pointer_state.lock.temp_left = true;
							} else if (sibling->width < min_sane_w) {
								pointer_state.lock.temp_right = true;
							}
						}
					}
				}
			} else if (!pointer_state.lock.left) {
				while (parent->type != C_WORKSPACE) {
					if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
						parent = parent->parent;
					} else {
						break;
					}
				}
				if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
					swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
					if (sibling) {
						if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
							recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
							recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
							changed_tiling = true;
						} else {
							pointer_state.tiling.lock_pos.x = mouse_origin.x;
							if (parent->width < min_sane_w) {
								pointer_state.lock.temp_right = true;
							} else if (sibling->width < min_sane_w) {
								pointer_state.lock.temp_left = true;
							}
						}
					}
				}
			}
			arrange_windows(active_workspace, -1, -1);
		}
	}
	if (config->focus_follows_mouse && prev_handle != handle) {
		// Dont change focus if fullscreen
		swayc_t *focused = get_focused_view(view);
		if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN)
				&& !(pointer_state.l_held || pointer_state.r_held)) {
			set_focused_container(container_under_pointer());
		}
	}
	prev_handle = handle;
	prev_pos = mouse_origin;
	if (changed_floating) {
		struct wlc_geometry geometry = {
			.origin = {
				.x = view->x,
				.y = view->y
			},
			.size = {
				.w = view->width,
				.h = view->height
			}
		};
		wlc_view_set_geometry(view->handle, edge, &geometry);
		return true;
	}
Ejemplo n.º 6
0
void arrange_windows(swayc_t *container, int width, int height) {
	int i;
	if (width == -1 || height == -1) {
		sway_log(L_DEBUG, "Arranging layout for %p", container);
		width = container->width;
		height = container->height;
	}

	int x = 0, y = 0;
	switch (container->type) {
	case C_ROOT:
		for (i = 0; i < container->children->length; ++i) {
			swayc_t *child = container->children->items[i];
			sway_log(L_DEBUG, "Arranging output at %d", x);
			child->x = x;
			child->y = y;
			arrange_windows(child, -1, -1);
			// Removed for now because wlc works with relative positions
			// Addition can be reconsidered once wlc positions are changed
			// x += child->width;
		}
		return;
	case C_OUTPUT:
		container->width = width;
		container->height = height;
		// These lines make x/y negative and result in stuff glitching out
		// Their addition can be reconsidered once wlc positions are changed
		// x -= container->x;
		// y -= container->y;
		for (i = 0; i < container->children->length; ++i) {
			swayc_t *child = container->children->items[i];
			child->x = x + container->gaps;
			child->y = y + container->gaps;
			child->width = width - container->gaps * 2;
			child->height = height - container->gaps * 2;
			sway_log(L_DEBUG, "Arranging workspace #%d at %d, %d", i, child->x, child->y);
			arrange_windows(child, -1, -1);
		}
		return;
	case C_VIEW:
		{
			struct wlc_geometry geometry = {
				.origin = {
					.x = container->x + container->gaps,
					.y = container->y + container->gaps
				},
				.size = {
					.w = width - container->gaps * 2,
					.h = height - container->gaps * 2
				}
			};
			if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) {
				swayc_t *parent = container;
				while (parent->type != C_OUTPUT) {
					parent = parent->parent;
				}
				geometry.origin.x = 0;
				geometry.origin.y = 0;
				geometry.size.w = parent->width;
				geometry.size.h = parent->height;
				wlc_view_set_geometry(container->handle, 0, &geometry);
				wlc_view_bring_to_front(container->handle);
			} else {
				wlc_view_set_geometry(container->handle, 0, &geometry);
				container->width = width;
				container->height = height;
			}
			sway_log(L_DEBUG, "Set view to %d x %d @ %d, %d", geometry.size.w, geometry.size.h,
					geometry.origin.x, geometry.origin.y);
		}
		return;
	default:
		container->width = width;
		container->height = height;
		break;
	}