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; }
static void handle_output_focused(wlc_handle output, bool focus) { swayc_t *c = get_swayc_for_handle(output, &root_container); if (!c) return; if (focus) { unfocus_all(&root_container); focus_view(c); } }
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; }
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(); } }
char * message_view(View *v, IxpMsg *m) { Area *a; char *s; int i; s = getword(m); switch(getsym(s)) { case LSEND: return send_client(v, m, 0); case LSWAP: return send_client(v, m, 1); case LSELECT: return select_area(v->sel, m); case LCOLMODE: s = getword(m); if((a = strarea(v, s)) == nil || a->floating) return Ebadvalue; s = getword(m); if((i = str2colmode(s)) == -1) return Ebadvalue; a->mode = i; arrange_column(a, True); restack_view(v); if(v == screen->sel) focus_view(screen, v); draw_frames(); return nil; default: return Ebadcmd; } /* not reached */ }
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; } } } }
char * message_root(void *p, IxpMsg *m) { Font *fn; char *s, *ret; ulong n; USED(p); ret = nil; s = getword(m); switch(getsym(s)) { case LQUIT: srv.running = 0; break; case LEXEC: execstr = smprint("exec %s", (char*)m->pos); srv.running = 0; break; case LVIEW: select_view((char*)m->pos); break; case LSELCOLORS: fprint(2, "%s: warning: selcolors have been removed\n", argv0); return Ebadcmd; case LFOCUSCOLORS: ret = parse_colors(m, &def.focuscolor); focus_view(screen, screen->sel); break; case LNORMCOLORS: ret = parse_colors(m, &def.normcolor); focus_view(screen, screen->sel); break; case LFONT: fn = loadfont((char*)m->pos); if(fn) { freefont(def.font); def.font = fn; resize_bar(screen); }else ret = "can't load font"; focus_view(screen, screen->sel); break; case LBORDER: if(!getulong(getword(m), &n)) return Ebadvalue; def.border = n; focus_view(screen, screen->sel); break; case LGRABMOD: s = getword(m); n = str2modmask(s); if((n & (Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) == 0) return Ebadvalue; utflcpy(def.grabmod, s, sizeof(def.grabmod)); def.mod = n; break; default: return Ebadcmd; } return ret; }