Esempio n. 1
0
bool move_focus(enum movement_direction direction) {
	swayc_t *old_view = get_focused_container(&root_container);
	swayc_t *new_view = get_swayc_in_direction(old_view, direction);
	if (!new_view) {
		return false;
	} else if (new_view->type == C_ROOT) {
		sway_log(L_DEBUG, "Not setting focus above the workspace level");
		return false;
	} else if (new_view->type == C_OUTPUT) {
		return set_focused_container(swayc_active_workspace_for(new_view));
	} else if (direction == MOVE_PARENT || direction == MOVE_CHILD) {
		return set_focused_container(new_view);
	} else if (config->mouse_warping) {
		swayc_t *old_op = old_view->type == C_OUTPUT ?
			old_view : swayc_parent_by_type(old_view, C_OUTPUT);
		swayc_t *focused = get_focused_view(new_view);
		if (set_focused_container(focused)) {
			if (old_op != swayc_active_output() && focused && focused->type == C_VIEW) {
				center_pointer_on(focused);
			}
			return true;
		}
	} else {
		return set_focused_container(get_focused_view(new_view));
	}
	return false;
}
Esempio n. 2
0
File: log.c Progetto: zetok/sway
/* XXX:DEBUG:XXX */
static void container_log(const swayc_t *c) {
	fprintf(stderr, "focus:%c|",
			c == get_focused_view(&root_container) ? 'K':
			c == get_focused_container(&root_container) ? 'F' : // Focused
			c == swayc_active_workspace() ? 'W' : // active workspace
			c == &root_container  ? 'R' : // root
			'X');// not any others
	fprintf(stderr,"(%p)",c);
	fprintf(stderr,"(p:%p)",c->parent);
	fprintf(stderr,"(f:%p)",c->focused);
	fprintf(stderr,"(h:%ld)",c->handle);
	fprintf(stderr,"Type:");
	fprintf(stderr,
			c->type == C_ROOT   ? "Root|" :
			c->type == C_OUTPUT ? "Output|" :
			c->type == C_WORKSPACE ? "Workspace|" :
			c->type == C_CONTAINER ? "Container|" :
			c->type == C_VIEW   ? "View|" : "Unknown|");
	fprintf(stderr,"layout:");
	fprintf(stderr,
			c->layout == L_NONE ? "NONE|" :
			c->layout == L_HORIZ ? "Horiz|":
			c->layout == L_VERT ? "Vert|":
			c->layout == L_STACKED  ? "Stacked|":
			c->layout == L_FLOATING ? "Floating|":
			"Unknown|");
	fprintf(stderr, "w:%.f|h:%.f|", c->width, c->height);
	fprintf(stderr, "x:%.f|y:%.f|", c->x, c->y);
	fprintf(stderr, "g:%d|",c->gaps);
	fprintf(stderr, "vis:%c|", c->visible?'t':'f');
	fprintf(stderr, "name:%.16s|", c->name);
	fprintf(stderr, "children:%d\n",c->children?c->children->length:0);
}
Esempio n. 3
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;
}
Esempio n. 4
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) {
        swayc_t *pointer = focus_pointer();
        return (pointer && pointer != focused);
    }
    return false;
}
Esempio n. 5
0
bool move_focus(enum movement_direction direction) {
	swayc_t *view = get_focused_container(&root_container);
	view = get_swayc_in_direction(view, direction);
	if (view) {
		if (direction == MOVE_PARENT) {
			return set_focused_container(view);
		} else {
			return set_focused_container(get_focused_view(view));
		}
	}
	return false;
}
Esempio n. 6
0
swayc_t *focus_pointer(void) {
    swayc_t *focused = get_focused_container(&root_container);
    if (!(wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN)) {
        swayc_t *pointer = find_container(&root_container, pointer_test, &mouse_origin);
        if (pointer && focused != pointer) {
            unfocus_all(&root_container);
            focus_view(pointer);
        } else if (!focused) {
            focus_view(active_workspace);
        }
        focused = pointer;
    }
    return focused;
}
Esempio n. 7
0
static bool handle_view_created(wlc_handle handle) {
    swayc_t *focused = get_focused_container(&root_container);
    uint32_t type = wlc_view_get_type(handle);
    // If override_redirect/unmanaged/popup/modal/splach
    if (type) {
        sway_log(L_DEBUG,"Unmanaged window of type %x left alone", type);
        wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
        if (type & WLC_BIT_UNMANAGED) {
            return true;
        }
        // For things like Dmenu
        if (type & WLC_BIT_OVERRIDE_REDIRECT) {
            override_redirect = true;
            wlc_view_focus(handle);
        }

        // Float popups
        if (type & WLC_BIT_POPUP) {
            swayc_t *view = new_floating_view(handle);
            wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, false);
            focus_view(view);
            arrange_windows(active_workspace, -1, -1);
        }
    } else {
        swayc_t *view = new_view(focused, handle);
        //Set maximize flag for windows.
        //TODO: floating windows have this unset
        wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, true);
        unfocus_all(&root_container);
        focus_view(view);
        arrange_windows(view->parent, -1, -1);
    }
    if (wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) {
        unfocus_all(&root_container);
        focus_view(focused);
        arrange_windows(focused, -1, -1);
    }
    return true;
}
Esempio n. 8
0
bool move_focus(enum movement_direction direction) {
	swayc_t *old_view = get_focused_container(&root_container);
	swayc_t *new_view = get_swayc_in_direction(old_view, direction);
	if (!new_view) {
		return false;
	} else if (direction == MOVE_PARENT) {
		return set_focused_container(new_view);
	} else if (config->mouse_warping) {
		swayc_t *old_op = old_view->type == C_OUTPUT ?
			old_view : swayc_parent_by_type(old_view, C_OUTPUT);
		swayc_t *focused = get_focused_view(new_view);
		if (set_focused_container(focused)) {
			if (old_op != swayc_active_output() && focused && focused->type == C_VIEW) {
				center_pointer_on(focused);
			}
			return true;
		}
	} else {
		return set_focused_container(get_focused_view(new_view));
	}
	return false;
}
Esempio n. 9
0
static void handle_view_destroyed(wlc_handle handle) {
    sway_log(L_DEBUG, "Destroying window %u", (unsigned int)handle);

    // Properly handle unmanaged views
    uint32_t type = wlc_view_get_type(handle);
    if (type) {
        wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
        sway_log(L_DEBUG,"Unmanaged window of type %x was destroyed", type);
        if (type & WLC_BIT_UNMANAGED) {
            // We need to call focus_view() on focus_pointer because unmanaged windows
            // do not alter the focus structure of the container tree. This makes focus_pointer()
            // think that it doesn't need to do anything, so we manually focus the result.
            focus_view(focus_pointer());
            return;
        }

        if (type & WLC_BIT_OVERRIDE_REDIRECT) {
            override_redirect = false;
            focus_view(focus_pointer());
            return;
        }

        // WLC_BIT_POPUP doesn't need to be dealt with since it's
        // treated as a floating view.
    }

    swayc_t *view = get_swayc_for_handle(handle, &root_container);
    swayc_t *parent;
    swayc_t *focused = get_focused_container(&root_container);

    if (view) {
        parent = destroy_view(view);
        arrange_windows(parent, -1, -1);
    }
    if (!focused || focused == view) {
        focus_pointer();
    }
}
Esempio n. 10
0
/* XXX:DEBUG:XXX */
static void container_log(const swayc_t *c, int depth) {
	fprintf(stderr, "focus:%c",
			c == get_focused_view(&root_container) ? 'K':
			c == get_focused_container(&root_container) ? 'F' : // Focused
			c == swayc_active_workspace() ? 'W' : // active workspace
			c == &root_container  ? 'R' : // root
			'X');// not any others
	for (int i = 6; i > depth; i--) { fprintf(stderr, " "); }
	fprintf(stderr,"|(%p)",c);
	fprintf(stderr,"(p:%-8p)",c->parent);
	fprintf(stderr,"(f:%-8p)",c->focused);
	fprintf(stderr,"(h:%2" PRIuPTR ")",c->handle);
	fprintf(stderr,"Type:%-4s|",
			c->type == C_ROOT   ? "root" :
			c->type == C_OUTPUT ? "op" :
			c->type == C_WORKSPACE ? "ws" :
			c->type == C_CONTAINER ? "cont" :
			c->type == C_VIEW   ? "view" : "?");
	fprintf(stderr,"layout:%-5s|",
			c->layout == L_NONE ? "-" :
			c->layout == L_HORIZ ? "Horiz":
			c->layout == L_VERT ? "Vert":
			c->layout == L_STACKED  ? "Stack":
			c->layout == L_TABBED  ? "Tab":
			c->layout == L_FLOATING ? "Float":
			c->layout == L_AUTO_LEFT ? "A_lft":
			c->layout == L_AUTO_RIGHT ? "A_rgt":
			c->layout == L_AUTO_TOP ? "A_top":
			c->layout == L_AUTO_BOTTOM ? "A_bot":
			"Unknown");
	fprintf(stderr, "w:%4.f|h:%4.f|", c->width, c->height);
	fprintf(stderr, "x:%4.f|y:%4.f|", c->x, c->y);
	fprintf(stderr, "g:%3d|",c->gaps);
	fprintf(stderr, "vis:%c|", c->visible?'t':'f');
	fprintf(stderr, "children:%2d|",c->children?c->children->length:0);
	fprintf(stderr, "name:%.16s\n", c->name);
}
Esempio n. 11
0
static bool handle_view_created(wlc_handle handle) {
	swayc_t *focused = get_focused_container(&root_container);
	swayc_t *newview = NULL;
	switch (wlc_view_get_type(handle)) {
	// regular view created regularly
	case 0:
		newview = new_view(focused, handle);
		wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, true);
		break;
	// takes keyboard focus
	case WLC_BIT_OVERRIDE_REDIRECT:
		sway_log(L_DEBUG, "view %ld with OVERRIDE_REDIRECT", handle);
		locked_view_focus = true;
		wlc_view_focus(handle);
		wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
		wlc_view_bring_to_front(handle);
		break;
	// Takes container focus
	case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED:
		sway_log(L_DEBUG, "view %ld with OVERRIDE_REDIRECT|WLC_BIT_MANAGED", handle);
		wlc_view_bring_to_front(handle);
		locked_container_focus = true;
		break;
	// set modals as floating containers
	case WLC_BIT_MODAL:
		wlc_view_bring_to_front(handle);
		newview = new_floating_view(handle);
	case WLC_BIT_POPUP:
		break;
	}
	if (newview) {
		set_focused_container(newview);
		arrange_windows(newview->parent, -1, -1);
	}
	return true;
}
Esempio n. 12
0
swayc_t *workspace_create(const char* name) {
	swayc_t *parent;
	// Search for workspace<->output pair
	int i, e = config->workspace_outputs->length;
	for (i = 0; i < e; ++i) {
		struct workspace_output *wso = config->workspace_outputs->items[i];
		if (strcasecmp(wso->workspace, name) == 0)
		{
			// Find output to use if it exists
			e = root_container.children->length;
			for (i = 0; i < e; ++i) {
				parent = root_container.children->items[i];
				if (strcmp(parent->name, wso->output) == 0) {
					return new_workspace(parent, name);
				}
			}
			break;
		}
	}
	// Otherwise create a new one
	parent = get_focused_container(&root_container);
	parent = swayc_parent_by_type(parent, C_OUTPUT);
	return new_workspace(parent, name);
}
Esempio n. 13
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, 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;
}
Esempio n. 14
0
swayc_t *workspace_create(const char* name) {
	swayc_t *parent = get_focused_container(&root_container);
	parent = swayc_parent_by_type(parent, C_OUTPUT);
	return new_workspace(parent, name);
}
Esempio n. 15
0
static bool handle_view_created(wlc_handle handle) {
	// if view is child of another view, the use that as focused container
	wlc_handle parent = wlc_view_get_parent(handle);
	swayc_t *focused = NULL;
	swayc_t *newview = NULL;

	// Get parent container, to add view in
	if (parent) {
		focused = get_swayc_for_handle(parent, &root_container);
	}
	if (!focused || focused->type == C_OUTPUT) {
		focused = get_focused_container(&root_container);
	}
	sway_log(L_DEBUG, "handle:%ld type:%x state:%x parent:%ld "
			"mask:%d (x:%d y:%d w:%d h:%d) title:%s "
			"class:%s appid:%s",
		handle, wlc_view_get_type(handle), wlc_view_get_state(handle), parent,
		wlc_view_get_mask(handle), wlc_view_get_geometry(handle)->origin.x,
		wlc_view_get_geometry(handle)->origin.y,wlc_view_get_geometry(handle)->size.w,
		wlc_view_get_geometry(handle)->size.h, wlc_view_get_title(handle),
		wlc_view_get_class(handle), wlc_view_get_app_id(handle));

	// TODO properly figure out how each window should be handled.
	switch (wlc_view_get_type(handle)) {
	// regular view created regularly
	case 0:
		newview = new_view(focused, handle);
		wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, true);
		break;

	// Dmenu keeps viewfocus, but others with this flag dont, for now simulate
	// dmenu
	case WLC_BIT_OVERRIDE_REDIRECT:
// 		locked_view_focus = true;
		wlc_view_focus(handle);
		wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
		wlc_view_bring_to_front(handle);
		break;

	// Firefox popups have this flag set.
	case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED:
		wlc_view_bring_to_front(handle);
		locked_container_focus = true;
		break;

	// Modals, get focus, popups do not
	case WLC_BIT_MODAL:
		wlc_view_focus(handle);
		wlc_view_bring_to_front(handle);
		newview = new_floating_view(handle);
	case WLC_BIT_POPUP:
		wlc_view_bring_to_front(handle);
		break;
	}

	if (newview) {
		set_focused_container(newview);
		swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT);
		arrange_windows(output, -1, -1);
	}
	return true;
}
Esempio n. 16
0
struct cmd_results *cmd_layout(int argc, char **argv) {
	struct cmd_results *error = NULL;
	if (config->reading) return cmd_results_new(CMD_FAILURE, "layout", "Can't be used in config file.");
	if (!config->active) return cmd_results_new(CMD_FAILURE, "layout", "Can only be used when sway is running.");
	if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) {
		return error;
	}
	swayc_t *parent = get_focused_container(&root_container);
	if (parent->is_floating) {
		return cmd_results_new(CMD_FAILURE, "layout", "Unable to change layout of floating windows");
	}

	while (parent->type == C_VIEW) {
		parent = parent->parent;
	}

	enum swayc_layouts old_layout = parent->layout;

	if (strcasecmp(argv[0], "default") == 0) {
		swayc_change_layout(parent, parent->prev_layout);
		if (parent->layout == L_NONE) {
			swayc_t *output = swayc_parent_by_type(parent, C_OUTPUT);
			swayc_change_layout(parent, default_layout(output));
		}
	} else {
		if (parent->layout != L_TABBED && parent->layout != L_STACKED) {
			parent->prev_layout = parent->layout;
		}

		if (strcasecmp(argv[0], "tabbed") == 0) {
			if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){
				parent = new_container(parent, L_TABBED);
			}

			swayc_change_layout(parent, L_TABBED);
		} else if (strcasecmp(argv[0], "stacking") == 0) {
			if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)) {
				parent = new_container(parent, L_STACKED);
			}

			swayc_change_layout(parent, L_STACKED);
		} else if (strcasecmp(argv[0], "splith") == 0) {
			swayc_change_layout(parent, L_HORIZ);
		} else if (strcasecmp(argv[0], "splitv") == 0) {
			swayc_change_layout(parent, L_VERT);
		} else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) {
			if (parent->layout == L_HORIZ && (parent->workspace_layout == L_NONE || parent->workspace_layout == L_HORIZ)) {
				swayc_change_layout(parent, L_VERT);
			} else {
				swayc_change_layout(parent, L_HORIZ);
			}
		}
	}

	update_layout_geometry(parent, old_layout);
	update_geometry(parent);

	arrange_windows(parent, parent->width, parent->height);

	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
Esempio n. 17
0
int move_focus(enum movement_direction direction) {
	swayc_t *current = get_focused_container(&root_container);
	swayc_t *parent = current->parent;

	if (direction == MOVE_PARENT) {
		current = parent;
		parent  = parent->parent;
		if (parent->type == C_ROOT) {
			sway_log(L_DEBUG, "Focus cannot move to parent");
			return 1;
		} else {
			sway_log(L_DEBUG, "Moving focus away from %p", current);
			unfocus_all(parent);
			focus_view(parent);
			return 0;
		}
	}

	while (true) {
		sway_log(L_DEBUG, "Moving focus away from %p", current);

		// Test if we can even make a difference here
		bool can_move = false;
		int diff = 0;
		if (direction == MOVE_LEFT || direction == MOVE_RIGHT) {
			if (parent->layout == L_HORIZ) {
				can_move = true;
				diff = direction == MOVE_LEFT ? -1 : 1;
			}
		} else {
			if (parent->layout == L_VERT) {
				can_move = true;
				diff = direction == MOVE_UP ? -1 : 1;
			}
		}
		sway_log(L_DEBUG, "Can move? %s", can_move ? "yes" : "no");
		if (can_move) {
			int i;
			for (i = 0; i < parent->children->length; ++i) {
				swayc_t *child = parent->children->items[i];
				if (child == current) {
					break;
				}
			}
			int desired = i + diff;
			sway_log(L_DEBUG, "Moving from %d to %d", i, desired);
			if (desired < 0 || desired >= parent->children->length) {
				can_move = false;
			} else {
				unfocus_all(&root_container);
				focus_view(parent->children->items[desired]);
				return 0;
			}
		}
		if (!can_move) {
			sway_log(L_DEBUG, "Can't move at current level, moving up tree");
			current = parent;
			parent = parent->parent;
			if (parent->type == C_ROOT) {
				// Nothing we can do
				return 1;
			}
		}
	}
}