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; }
void move_container_to(swayc_t* container, swayc_t* destination) { if (container == destination || swayc_is_parent_of(container, destination)) { return; } swayc_t *parent = remove_child(container); // reset container geometry container->width = container->height = 0; // Send to new destination if (container->is_floating) { add_floating(swayc_active_workspace_for(destination), container); } else if (destination->type == C_WORKSPACE) { add_child(destination, container); } else { add_sibling(destination, container); } // Destroy old container if we need to parent = destroy_container(parent); // Refocus swayc_t *op1 = swayc_parent_by_type(destination, C_OUTPUT); swayc_t *op2 = swayc_parent_by_type(parent, C_OUTPUT); set_focused_container(get_focused_view(op1)); arrange_windows(op1, -1, -1); update_visibility(op1); if (op1 != op2) { set_focused_container(get_focused_view(op2)); arrange_windows(op2, -1, -1); update_visibility(op2); } }
swayc_t *get_focused_view(swayc_t *parent) { swayc_t *c = parent; while (c && c->type != C_VIEW) { if (c->type == C_WORKSPACE && c->focused == NULL) { return c; } c = c->focused; } if (c == NULL) { c = swayc_active_workspace_for(parent); } return c; }
bool set_focused_container_for(swayc_t *a, swayc_t *c) { if (locked_container_focus || !c) { return false; } swayc_t *find = c; // Ensure that a is an ancestor of c while (find != a && (find = find->parent)) { if (find == &root_container) { return false; } } // Get workspace for c, get that workspaces current focused container. swayc_t *workspace = swayc_active_workspace_for(c); swayc_t *focused = get_focused_view(workspace); // if the workspace we are changing focus to has a fullscreen view return if (swayc_is_fullscreen(focused) && c != focused) { return false; } // Check if we changing a parent container that will see chnage bool effective = true; while (find != &root_container) { if (find->parent->focused != find) { effective = false; } find = find->parent; } if (effective) { // Go to set_focused_container return set_focused_container(c); } sway_log(L_DEBUG, "Setting focus for %p:%ld to %p:%ld", a, a->handle, c, c->handle); c->is_focused = true; swayc_t *p = c; while (p != a) { update_focus(p); p = p->parent; p->is_focused = false; } return true; }
swayc_t *get_focused_view_include_floating(swayc_t *parent) { swayc_t *c = parent; swayc_t *f = NULL; while (c && c->type != C_VIEW) { if (c->type == C_WORKSPACE && c->focused == NULL) { return ((f = get_focused_float(c))) ? f : c; } c = c->focused; } if (c == NULL) { c = swayc_active_workspace_for(parent); } return c; }
void move_container_to(swayc_t* container, swayc_t* destination) { if (container == destination || swayc_is_parent_of(container, destination)) { return; } swayc_t *parent = remove_child(container); // Send to new destination if (container->is_floating) { swayc_t *ws = swayc_active_workspace_for(destination); add_floating(ws, container); // If the workspace only has one child after adding one, it // means that the workspace was just initialized. if (ws->children->length + ws->floating->length == 1) { ipc_event_workspace(NULL, ws, "init"); } } else if (destination->type == C_WORKSPACE) { // reset container geometry container->width = container->height = 0; add_child(destination, container); // If the workspace only has one child after adding one, it // means that the workspace was just initialized. if (destination->children->length + destination->floating->length == 1) { ipc_event_workspace(NULL, destination, "init"); } } else { // reset container geometry container->width = container->height = 0; add_sibling(destination, container); } // Destroy old container if we need to parent = destroy_container(parent); // Refocus swayc_t *op1 = swayc_parent_by_type(destination, C_OUTPUT); swayc_t *op2 = swayc_parent_by_type(parent, C_OUTPUT); set_focused_container(get_focused_view(op1)); arrange_windows(op1, -1, -1); update_visibility(op1); if (op1 != op2) { set_focused_container(get_focused_view(op2)); arrange_windows(op2, -1, -1); update_visibility(op2); } }
bool set_focused_container(swayc_t *c) { if (locked_container_focus || !c) { return false; } swayc_log(L_DEBUG, c, "Setting focus to %p:%ld", c, c->handle); // Get workspace for c, get that workspaces current focused container. swayc_t *workspace = swayc_active_workspace_for(c); swayc_t *focused = get_focused_view(workspace); // if the workspace we are changing focus to has a fullscreen view return if (swayc_is_fullscreen(focused) && focused != c) { return false; } // update container focus from here to root, making necessary changes along // the way swayc_t *p = c; if (p->type != C_OUTPUT && p->type != C_ROOT) { p->is_focused = true; } while (p != &root_container) { update_focus(p); p = p->parent; p->is_focused = false; } // get new focused view and set focus to it. p = get_focused_view(c); if (p->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) { // unactivate previous focus if (focused->type == C_VIEW) { wlc_view_set_state(focused->handle, WLC_BIT_ACTIVATED, false); } // activate current focus if (p->type == C_VIEW) { wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true); // set focus if view_focus is unlocked if (!locked_view_focus) { wlc_view_focus(p->handle); } } } return true; }
static void set_initial_sibling(void) { bool reset = true; swayc_t *ws = swayc_active_workspace_for(initial.ptr); if ((initial.horiz.ptr = get_swayc_in_direction_under(initial.ptr, lock.left ? MOVE_RIGHT: MOVE_LEFT, ws))) { initial.horiz.w = initial.horiz.ptr->width; initial.horiz.parent.ptr = get_swayc_in_direction_under(initial.horiz.ptr, lock.left ? MOVE_LEFT : MOVE_RIGHT, ws); initial.horiz.parent.w = initial.horiz.parent.ptr->width; reset = false; } if ((initial.vert.ptr = get_swayc_in_direction_under(initial.ptr, lock.top ? MOVE_DOWN: MOVE_UP, ws))) { initial.vert.h = initial.vert.ptr->height; initial.vert.parent.ptr = get_swayc_in_direction_under(initial.vert.ptr, lock.top ? MOVE_UP : MOVE_DOWN, ws); initial.vert.parent.h = initial.vert.parent.ptr->height; reset = false; } // If nothing will change just undo the mode if (reset) { pointer_state.mode = 0; } }
bool set_focused_container(swayc_t *c) { if (locked_container_focus || !c || !c->parent) { return false; } swayc_t *active_ws = swayc_active_workspace(); int active_ws_child_count = 0; if (active_ws) { active_ws_child_count = active_ws->children->length + active_ws->floating->length; } swayc_log(L_DEBUG, c, "Setting focus to %p:%" PRIuPTR, c, c->handle); // Get workspace for c, get that workspaces current focused container. swayc_t *workspace = swayc_active_workspace_for(c); swayc_t *focused = get_focused_view(workspace); if (swayc_is_fullscreen(focused) && focused != c) { // if switching to a workspace with a fullscreen view, // focus on the fullscreen view c = focused; } if (c->type == C_VIEW) { // dispatch a window event ipc_event_window(c, "focus"); } // update container focus from here to root, making necessary changes along // the way swayc_t *p = c; if (p->type != C_OUTPUT && p->type != C_ROOT) { p->is_focused = true; } while (p != &root_container) { update_focus(p); p = p->parent; p->is_focused = false; } // get new focused view and set focus to it. p = get_focused_view(c); if (p->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) { // unactivate previous focus if (focused->type == C_VIEW) { wlc_view_set_state(focused->handle, WLC_BIT_ACTIVATED, false); update_view_border(focused); } // activate current focus if (p->type == C_VIEW) { wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true); // set focus if view_focus is unlocked if (!locked_view_focus) { wlc_view_focus(p->handle); if (p->parent->layout != L_TABBED && p->parent->layout != L_STACKED) { update_view_border(p); } } } // rearrange if parent container is tabbed/stacked swayc_t *parent = swayc_tabbed_stacked_ancestor(p); if (parent != NULL) { arrange_backgrounds(); arrange_windows(parent, -1, -1); } } else if (p->type == C_WORKSPACE) { // remove previous focus if view_focus is unlocked if (!locked_view_focus) { wlc_view_focus(0); } } if (active_ws != workspace) { // active_ws might have been destroyed by now // (focus swap away from empty ws = destroy ws) if (active_ws_child_count == 0) { active_ws = NULL; } ipc_event_workspace(active_ws, workspace, "focus"); } return true; }