示例#1
0
static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
		uint32_t button, enum wlc_button_state state) {
	swayc_t *focused = get_focused_container(&root_container);
	if (state == WLC_BUTTON_STATE_PRESSED) {
		sway_log(L_DEBUG, "Mouse button %u pressed", button);
		if (button == 272) {
			m1_held = true;
		}
		if (button == 273) {
			m2_held = true;
		}
		swayc_t *pointer = container_under_pointer();
		set_focused_container(pointer);
		return (pointer && pointer != focused);
	} else {
		sway_log(L_DEBUG, "Mouse button %u released", button);
		if (button == 272) {
			m1_held = false;
		}
		if (button == 273) {
			m2_held = false;
		}
	}
	return false;
}
示例#2
0
void pointer_position_set(struct wlc_point *new_origin, bool force_focus) {
	struct wlc_point origin;
	wlc_pointer_get_position(&origin);
	pointer_state.delta.x = new_origin->x - origin.x;
	pointer_state.delta.y = new_origin->y - origin.y;

	wlc_pointer_set_position(new_origin);

	// Update view under pointer
	swayc_t *prev_view = pointer_state.view;
	pointer_state.view = container_under_pointer();

	// If pointer is in a mode, update it
	if (pointer_state.mode) {
		pointer_mode_update();
	// Otherwise change focus if config is set
	} else if (force_focus || (prev_view != pointer_state.view && config->focus_follows_mouse)) {
		if (pointer_state.view && pointer_state.view->type == C_VIEW) {
			set_focused_container(pointer_state.view);
		}
	}
}
示例#3
0
文件: handlers.c 项目: Luminarys/sway
static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) {
	// Update pointer origin
	pointer_state.delta.x = origin->x - pointer_state.origin.x;
	pointer_state.delta.y = origin->y - pointer_state.origin.y;
	pointer_state.origin.x = origin->x;
	pointer_state.origin.y = origin->y;

	// Update view under pointer
	swayc_t *prev_view = pointer_state.view;
	pointer_state.view = container_under_pointer();

	// If pointer is in a mode, update it
	if (pointer_state.mode) {
		pointer_mode_update();
	}
	// Otherwise change focus if config is set an
	else if (prev_view != pointer_state.view && config->focus_follows_mouse) {
		if (pointer_state.view && pointer_state.view->type == C_VIEW) {
			set_focused_container(pointer_state.view);
		}
	}
	return EVENT_PASSTHROUGH;
}
示例#4
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;
	int i = 0;
	// Do checks to determine if proper keys are being held
	swayc_t *view = active_workspace->focused;
	if (m1_held && view) {
		if (view->is_floating) {
			while (keys_pressed[i++]) {
				if (keys_pressed[i] == config->floating_mod) {
					int dx = mouse_origin.x - prev_pos.x;
					int dy = mouse_origin.y - prev_pos.y;
					sway_log(L_DEBUG, "Moving from px: %d to cx: %d and from py: %d to cy: %d", prev_pos.x, mouse_origin.x, prev_pos.y, mouse_origin.y);
					sway_log(L_DEBUG, "Moving: dx: %d, dy: %d", dx, dy);

					view->x += dx;
					view->y += dy;
					changed_floating = true;
					break;
				}
			}
		}
	} else if (m2_held && view) {
		if (view->is_floating) {
			while (keys_pressed[i++]) {
				if (keys_pressed[i] == config->floating_mod) {
					int dx = mouse_origin.x - prev_pos.x;
					int dy = mouse_origin.y - prev_pos.y;
					sway_log(L_DEBUG, "Moving from px: %d to cx: %d and from py: %d to cy: %d", prev_pos.x, mouse_origin.x, prev_pos.y, mouse_origin.y);
					sway_log(L_INFO, "Moving: dx: %d, dy: %d", dx, dy);

					// 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) {
						changed_floating = true;
						if (mouse_origin.x > midway_x) {
							sway_log(L_INFO, "Downsizing view to the left");
							view->width += dx;
						} else {
							sway_log(L_INFO, "Upsizing view to the left");
							view->x += dx;
							view->width -= dx;
						}
					} else if (dx > 0){
						changed_floating = true;
						if (mouse_origin.x > midway_x) {
							sway_log(L_INFO, "Upsizing to the right");
							view->width += dx;
						} else {
							sway_log(L_INFO, "Downsizing to the right");
							view->x += dx;
							view->width -= dx;
						}
					}

					if (dy < 0) {
						changed_floating = true;
						if (mouse_origin.y > midway_y) {
							sway_log(L_INFO, "Downsizing view to the top");
							view->height += dy;
						} else {
							sway_log(L_INFO, "Upsizing the view to the top");
							view->y += dy;
							view->height -= dy;
						}
					} else if (dy > 0) {
						changed_floating = true;
						if (mouse_origin.y > midway_y) {
							sway_log(L_INFO, "Upsizing to the bottom");
							view->height += dy;
						} else {
							sway_log(L_INFO, "Downsizing to the bottom");
							view->y += dy;
							view->height -= dy;
						}
					}
					break;
				}
			}
		}
	}
	if (config->focus_follows_mouse && prev_handle != handle) {
		set_focused_container(container_under_pointer());
	}
	prev_handle = handle;
	prev_pos = mouse_origin;
	if (changed_floating) {
		arrange_windows(view, -1, -1);
		return true;
	}
	return false;
}
示例#5
0
文件: handlers.c 项目: illblew/sway
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;
	}
示例#6
0
struct cmd_results *cmd_floating(int argc, char **argv) {
	struct cmd_results *error = NULL;
	if (config->reading) return cmd_results_new(CMD_FAILURE, "floating", "Can't be used in config file.");
	if ((error = checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1))) {
		return error;
	}
	swayc_t *view = current_container;
	bool wants_floating;
	if (strcasecmp(argv[0], "enable") == 0) {
		wants_floating = true;
	} else if (strcasecmp(argv[0], "disable") == 0) {
		wants_floating = false;
	} else if (strcasecmp(argv[0], "toggle") == 0) {
		wants_floating = !view->is_floating;
	} else {
		return cmd_results_new(CMD_FAILURE, "floating",
			"Expected 'floating <enable|disable|toggle>");
	}

	// Prevent running floating commands on things like workspaces
	if (view->type != C_VIEW) {
		return cmd_results_new(CMD_SUCCESS, NULL, NULL);
	}

	// Change from nonfloating to floating
	if (!view->is_floating && wants_floating) {
		// Remove view from its current location
		destroy_container(remove_child(view));

		// and move it into workspace floating
		add_floating(swayc_active_workspace(), view);
		view->x = (swayc_active_workspace()->width - view->width)/2;
		view->y = (swayc_active_workspace()->height - view->height)/2;
		if (view->desired_width != -1) {
			view->width = view->desired_width;
		}
		if (view->desired_height != -1) {
			view->height = view->desired_height;
		}
		arrange_windows(swayc_active_workspace(), -1, -1);

	} else if (view->is_floating && !wants_floating) {
		// Delete the view from the floating list and unset its is_floating flag
		remove_child(view);
		view->is_floating = false;
		// Get the properly focused container, and add in the view there
		swayc_t *focused = container_under_pointer();
		// If focused is null, it's because the currently focused container is a workspace
		if (focused == NULL || focused->is_floating) {
			focused = swayc_active_workspace();
		}
		set_focused_container(focused);

		sway_log(L_DEBUG, "Non-floating focused container is %p", focused);

		// Case of focused workspace, just create as child of it
		if (focused->type == C_WORKSPACE) {
			add_child(focused, view);
		}
		// Regular case, create as sibling of current container
		else {
			add_sibling(focused, view);
		}
		// Refocus on the view once its been put back into the layout
		view->width = view->height = 0;
		arrange_windows(swayc_active_workspace(), -1, -1);
		remove_view_from_scratchpad(view);
		ipc_event_window(view, "floating");
	}
	set_focused_container(view);
	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
示例#7
0
文件: handlers.c 项目: Luminarys/sway
static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
		uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) {

	// Update view pointer is on
	pointer_state.view = container_under_pointer();

	// Update pointer origin
	pointer_state.origin.x = origin->x;
	pointer_state.origin.y = origin->y;

	// Update pointer_state
	switch (button) {
	case M_LEFT_CLICK:
		if (state == WLC_BUTTON_STATE_PRESSED) {
			pointer_state.left.held = true;
			pointer_state.left.x = origin->x;
			pointer_state.left.y = origin->y;
			pointer_state.left.view = pointer_state.view;
		} else {
			pointer_state.left.held = false;
		}
		break;

	case M_RIGHT_CLICK:
		if (state == WLC_BUTTON_STATE_PRESSED) {
			pointer_state.right.held = true;
			pointer_state.right.x = origin->x;
			pointer_state.right.y = origin->y;
			pointer_state.right.view = pointer_state.view;
		} else {
			pointer_state.right.held = false;
		}
		break;

	case M_SCROLL_CLICK:
		if (state == WLC_BUTTON_STATE_PRESSED) {
			pointer_state.scroll.held = true;
			pointer_state.scroll.x = origin->x;
			pointer_state.scroll.y = origin->y;
			pointer_state.scroll.view = pointer_state.view;
		} else {
			pointer_state.scroll.held = false;
		}
		break;

		//TODO scrolling behavior
	case M_SCROLL_UP:
	case M_SCROLL_DOWN:
		break;
	}

	// get focused window and check if to change focus on mouse click
	swayc_t *focused = get_focused_container(&root_container);

	// dont change focus or mode if fullscreen
	if (swayc_is_fullscreen(focused)) {
		return EVENT_PASSTHROUGH;
	}

	// set pointer mode only if floating mod has been set
	if (config->floating_mod) {
		pointer_mode_set(button, !(modifiers->mods ^ config->floating_mod));
	}

	// Check whether to change focus
	swayc_t *pointer = pointer_state.view;
	if (pointer) {
		if (focused != pointer) {
			set_focused_container(pointer_state.view);
		}
		// Send to front if floating
		if (pointer->is_floating) {
			int i;
			for (i = 0; i < pointer->parent->floating->length; i++) {
				if (pointer->parent->floating->items[i] == pointer) {
					list_del(pointer->parent->floating, i);
					list_add(pointer->parent->floating, pointer);
					break;
				}
			}
			wlc_view_bring_to_front(pointer->handle);
		}
	}

	// Return if mode has been set
	if (pointer_state.mode) {
		return EVENT_HANDLED;
	}

	// Always send mouse release
	if (state == WLC_BUTTON_STATE_RELEASED) {
		return EVENT_PASSTHROUGH;
	}

	// Finally send click
	return EVENT_PASSTHROUGH;
}