Add movement support
This commit is contained in:
parent
1669da719c
commit
9f091c7f82
|
@ -8,6 +8,7 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "stringop.h"
|
#include "stringop.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
#include "movement.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
||||||
|
@ -97,6 +98,23 @@ int cmd_exit(struct sway_config *config, int argc, char **argv) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cmd_focus(struct sway_config *config, int argc, char **argv) {
|
||||||
|
if (argc != 1) {
|
||||||
|
sway_log(L_ERROR, "Invalid focus command (expected 1 arguments, got %d)", argc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (strcasecmp(argv[0], "left") == 0) {
|
||||||
|
move_focus(MOVE_LEFT);
|
||||||
|
} else if (strcasecmp(argv[0], "right") == 0) {
|
||||||
|
move_focus(MOVE_RIGHT);
|
||||||
|
} else if (strcasecmp(argv[0], "up") == 0) {
|
||||||
|
move_focus(MOVE_UP);
|
||||||
|
} else if (strcasecmp(argv[0], "down") == 0) {
|
||||||
|
move_focus(MOVE_DOWN);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv) {
|
int cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv) {
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
sway_log(L_ERROR, "Invalid focus_follows_mouse command (expected 1 arguments, got %d)", argc);
|
sway_log(L_ERROR, "Invalid focus_follows_mouse command (expected 1 arguments, got %d)", argc);
|
||||||
|
@ -184,6 +202,7 @@ struct cmd_handler handlers[] = {
|
||||||
{ "bindsym", cmd_bindsym },
|
{ "bindsym", cmd_bindsym },
|
||||||
{ "exec", cmd_exec },
|
{ "exec", cmd_exec },
|
||||||
{ "exit", cmd_exit },
|
{ "exit", cmd_exit },
|
||||||
|
{ "focus", cmd_focus },
|
||||||
{ "focus_follows_mouse", cmd_focus_follows_mouse },
|
{ "focus_follows_mouse", cmd_focus_follows_mouse },
|
||||||
{ "layout", cmd_layout },
|
{ "layout", cmd_layout },
|
||||||
{ "set", cmd_set },
|
{ "set", cmd_set },
|
||||||
|
|
|
@ -163,6 +163,7 @@ void add_view(wlc_handle view_handle) {
|
||||||
view->type = C_VIEW;
|
view->type = C_VIEW;
|
||||||
add_child(parent, view);
|
add_child(parent, view);
|
||||||
|
|
||||||
|
unfocus_all(&root_container);
|
||||||
focus_view(view);
|
focus_view(view);
|
||||||
|
|
||||||
arrange_windows(parent, -1, -1);
|
arrange_windows(parent, -1, -1);
|
||||||
|
@ -209,6 +210,7 @@ void destroy_view(swayc_t *view) {
|
||||||
parent->focused = NULL;
|
parent->focused = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unfocus_all(&root_container);
|
||||||
if (parent->children->length != 0) {
|
if (parent->children->length != 0) {
|
||||||
focus_view(parent->children->items[0]);
|
focus_view(parent->children->items[0]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -238,12 +240,17 @@ void unfocus_all(swayc_t *container) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void focus_view(swayc_t *view) {
|
void focus_view(swayc_t *view) {
|
||||||
if (view->type == C_VIEW) {
|
sway_log(L_DEBUG, "Setting focus for %p", view);
|
||||||
unfocus_all(&root_container);
|
|
||||||
wlc_view_set_state(view->handle, WLC_BIT_ACTIVATED, true);
|
|
||||||
wlc_view_focus(view->handle);
|
|
||||||
}
|
|
||||||
if (view == &root_container) {
|
if (view == &root_container) {
|
||||||
|
// Propegate wayland focus down
|
||||||
|
swayc_t *child = view->focused;
|
||||||
|
while (child && child->type != C_VIEW) {
|
||||||
|
child = child->focused;
|
||||||
|
}
|
||||||
|
if (child) {
|
||||||
|
wlc_view_set_state(child->handle, WLC_BIT_ACTIVATED, true);
|
||||||
|
wlc_view_focus(child->handle);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
view->parent->focused = view;
|
view->parent->focused = view;
|
||||||
|
@ -285,6 +292,7 @@ void add_output(wlc_handle output) {
|
||||||
add_child(container, workspace);
|
add_child(container, workspace);
|
||||||
|
|
||||||
if (root_container.focused == NULL) {
|
if (root_container.focused == NULL) {
|
||||||
|
unfocus_all(&root_container);
|
||||||
focus_view(workspace);
|
focus_view(workspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ void add_output(wlc_handle output);
|
||||||
void destroy_output(wlc_handle output);
|
void destroy_output(wlc_handle output);
|
||||||
void destroy_view(swayc_t *view);
|
void destroy_view(swayc_t *view);
|
||||||
void add_view(wlc_handle view);
|
void add_view(wlc_handle view);
|
||||||
|
void unfocus_all(swayc_t *container);
|
||||||
void focus_view(swayc_t *view);
|
void focus_view(swayc_t *view);
|
||||||
void arrange_windows(swayc_t *container, int width, int height);
|
void arrange_windows(swayc_t *container, int width, int height);
|
||||||
swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
|
swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
|
||||||
|
|
|
@ -28,6 +28,7 @@ void list_add(list_t *list, void *item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_insert(list_t *list, int index, void *item) {
|
void list_insert(list_t *list, int index, void *item) {
|
||||||
|
// TODO: Implement this properly
|
||||||
if (list->length == list->capacity) {
|
if (list->length == list->capacity) {
|
||||||
list->capacity += 10;
|
list->capacity += 10;
|
||||||
list->items = realloc(list->items, sizeof(void*) * list->capacity);
|
list->items = realloc(list->items, sizeof(void*) * list->capacity);
|
||||||
|
|
58
sway/movement.c
Normal file
58
sway/movement.c
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "list.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "layout.h"
|
||||||
|
#include "movement.h"
|
||||||
|
|
||||||
|
void move_focus(enum movement_direction direction) {
|
||||||
|
swayc_t *current = get_focused_container(&root_container);
|
||||||
|
swayc_t *parent = current->parent;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
sway/movement.h
Normal file
16
sway/movement.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef _SWAY_MOVEMENT_H
|
||||||
|
#define _SWAY_MOVEMENT_H
|
||||||
|
|
||||||
|
#include <wlc/wlc.h>
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
enum movement_direction{
|
||||||
|
MOVE_LEFT,
|
||||||
|
MOVE_RIGHT,
|
||||||
|
MOVE_UP,
|
||||||
|
MOVE_DOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
void move_focus(enum movement_direction direction);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue