mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-05-26 21:37:31 -04:00
feat: add rect indicator for drag tile to tile
This commit is contained in:
parent
975142d46a
commit
aa5b907613
5 changed files with 189 additions and 49 deletions
|
|
@ -119,6 +119,7 @@ scratchpad_height_ratio=0.9
|
||||||
borderpx=4
|
borderpx=4
|
||||||
rootcolor=0x201b14ff
|
rootcolor=0x201b14ff
|
||||||
bordercolor=0x444444ff
|
bordercolor=0x444444ff
|
||||||
|
dropcolor=0x8FBA7C55
|
||||||
focuscolor=0xc9b890ff
|
focuscolor=0xc9b890ff
|
||||||
maximizescreencolor=0x89aa61ff
|
maximizescreencolor=0x89aa61ff
|
||||||
urgentcolor=0xad401fff
|
urgentcolor=0xad401fff
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ rootcolor=0x323232ff
|
||||||
# Inactive window border
|
# Inactive window border
|
||||||
bordercolor=0x444444ff
|
bordercolor=0x444444ff
|
||||||
|
|
||||||
|
# Drop shadow when dragging windows
|
||||||
|
dropcolor=0x8FBA7C55
|
||||||
|
|
||||||
# Active window border
|
# Active window border
|
||||||
focuscolor=0xc66b25ff
|
focuscolor=0xc66b25ff
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,90 @@ struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void client_set_drop_area(Client *c) {
|
||||||
|
|
||||||
|
bool first_draw = false;
|
||||||
|
int32_t drop_direction = UNDIR;
|
||||||
|
|
||||||
|
if (!c->enable_drop_area_draw && !c->droparea->node.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c->enable_drop_area_draw && c->droparea->node.enabled) {
|
||||||
|
wlr_scene_node_lower_to_bottom(&c->droparea->node);
|
||||||
|
wlr_scene_node_set_enabled(&c->droparea->node, false);
|
||||||
|
return;
|
||||||
|
} else if (c->enable_drop_area_draw && !c->droparea->node.enabled) {
|
||||||
|
wlr_scene_node_raise_to_top(&c->droparea->node);
|
||||||
|
wlr_scene_node_set_enabled(&c->droparea->node, true);
|
||||||
|
first_draw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t bw = (int32_t)c->bw;
|
||||||
|
int32_t client_width = c->geom.width - 2 * bw;
|
||||||
|
int32_t client_height = c->geom.height - 2 * bw;
|
||||||
|
|
||||||
|
// 光标在窗口客户区内的相对坐标
|
||||||
|
double rel_x = cursor->x - c->geom.x - bw;
|
||||||
|
double rel_y = cursor->y - c->geom.y - bw;
|
||||||
|
|
||||||
|
struct wlr_box drop_box;
|
||||||
|
|
||||||
|
// 左边缘:x 在 0~30% 客户区宽度,且 y 在 30%~70% 客户区高度
|
||||||
|
if (rel_x < client_width * 0.3 && rel_y > client_height * 0.3 &&
|
||||||
|
rel_y < client_height * 0.7) {
|
||||||
|
drop_box.x = bw;
|
||||||
|
drop_box.y = bw;
|
||||||
|
drop_box.width = client_width * 0.3;
|
||||||
|
drop_box.height = client_height;
|
||||||
|
drop_direction = LEFT;
|
||||||
|
}
|
||||||
|
// 右边缘:x 在 70%~100% 客户区宽度,且 y 在 30%~70% 客户区高度
|
||||||
|
else if (rel_x > client_width * 0.7 && rel_y > client_height * 0.3 &&
|
||||||
|
rel_y < client_height * 0.7) {
|
||||||
|
drop_box.x = bw + client_width * 0.7;
|
||||||
|
drop_box.y = bw;
|
||||||
|
drop_box.width = client_width * 0.3;
|
||||||
|
drop_box.height = client_height;
|
||||||
|
drop_direction = RIGHT;
|
||||||
|
}
|
||||||
|
// 上边缘:x 在 30%~70% 客户区宽度,且 y 在 0~30% 客户区高度
|
||||||
|
else if (rel_x > client_width * 0.3 && rel_x < client_width * 0.7 &&
|
||||||
|
rel_y < client_height * 0.3) {
|
||||||
|
drop_box.x = bw;
|
||||||
|
drop_box.y = bw;
|
||||||
|
drop_box.width = client_width;
|
||||||
|
drop_box.height = client_height * 0.3;
|
||||||
|
drop_direction = UP;
|
||||||
|
}
|
||||||
|
// 下边缘:x 在 30%~70% 客户区宽度,且 y 在 70%~100% 客户区高度
|
||||||
|
else if (rel_x > client_width * 0.3 && rel_x < client_width * 0.7 &&
|
||||||
|
rel_y > client_height * 0.7) {
|
||||||
|
drop_box.x = bw;
|
||||||
|
drop_box.y = bw + client_height * 0.7;
|
||||||
|
drop_box.width = client_width;
|
||||||
|
drop_box.height = client_height * 0.3;
|
||||||
|
drop_direction = DOWN;
|
||||||
|
}
|
||||||
|
// 中心(或其他角落):显示在中间区域
|
||||||
|
else {
|
||||||
|
drop_box.x = bw + client_width * 0.3;
|
||||||
|
drop_box.y = bw + client_height * 0.3;
|
||||||
|
drop_box.width = client_width * 0.4;
|
||||||
|
drop_box.height = client_height * 0.4;
|
||||||
|
drop_direction = UNDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first_draw && c->drop_direction == drop_direction) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
c->drop_direction = drop_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_scene_node_set_position(&c->droparea->node, drop_box.x, drop_box.y);
|
||||||
|
wlr_scene_rect_set_size(c->droparea, drop_box.width, drop_box.height);
|
||||||
|
}
|
||||||
|
|
||||||
void client_apply_clip(Client *c, float factor) {
|
void client_apply_clip(Client *c, float factor) {
|
||||||
|
|
||||||
if (c->iskilling || !client_surface(c)->mapped)
|
if (c->iskilling || !client_surface(c)->mapped)
|
||||||
|
|
|
||||||
|
|
@ -315,6 +315,7 @@ typedef struct {
|
||||||
float scratchpad_height_ratio;
|
float scratchpad_height_ratio;
|
||||||
float rootcolor[4];
|
float rootcolor[4];
|
||||||
float bordercolor[4];
|
float bordercolor[4];
|
||||||
|
float dropcolor[4];
|
||||||
float focuscolor[4];
|
float focuscolor[4];
|
||||||
float maximizescreencolor[4];
|
float maximizescreencolor[4];
|
||||||
float urgentcolor[4];
|
float urgentcolor[4];
|
||||||
|
|
@ -1740,6 +1741,17 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
} else {
|
} else {
|
||||||
convert_hex_to_rgba(config->bordercolor, color);
|
convert_hex_to_rgba(config->bordercolor, color);
|
||||||
}
|
}
|
||||||
|
} else if (strcmp(key, "dropcolor") == 0) {
|
||||||
|
int64_t color = parse_color(value);
|
||||||
|
if (color == -1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Invalid dropcolor "
|
||||||
|
"format: %s\n",
|
||||||
|
value);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
convert_hex_to_rgba(config->dropcolor, color);
|
||||||
|
}
|
||||||
} else if (strcmp(key, "focuscolor") == 0) {
|
} else if (strcmp(key, "focuscolor") == 0) {
|
||||||
int64_t color = parse_color(value);
|
int64_t color = parse_color(value);
|
||||||
if (color == -1) {
|
if (color == -1) {
|
||||||
|
|
@ -3446,6 +3458,10 @@ void set_value_default() {
|
||||||
config.bordercolor[1] = 0x44 / 255.0f;
|
config.bordercolor[1] = 0x44 / 255.0f;
|
||||||
config.bordercolor[2] = 0x44 / 255.0f;
|
config.bordercolor[2] = 0x44 / 255.0f;
|
||||||
config.bordercolor[3] = 1.0f;
|
config.bordercolor[3] = 1.0f;
|
||||||
|
config.dropcolor[0] = 0x8f / 255.0f;
|
||||||
|
config.dropcolor[1] = 0xba / 255.0f;
|
||||||
|
config.dropcolor[2] = 0x7c / 255.0f;
|
||||||
|
config.dropcolor[3] = 0.5f;
|
||||||
config.focuscolor[0] = 0xc6 / 255.0f;
|
config.focuscolor[0] = 0xc6 / 255.0f;
|
||||||
config.focuscolor[1] = 0x6b / 255.0f;
|
config.focuscolor[1] = 0x6b / 255.0f;
|
||||||
config.focuscolor[2] = 0x25 / 255.0f;
|
config.focuscolor[2] = 0x25 / 255.0f;
|
||||||
|
|
|
||||||
134
src/mango.c
134
src/mango.c
|
|
@ -314,6 +314,7 @@ struct Client {
|
||||||
Monitor *mon;
|
Monitor *mon;
|
||||||
struct wlr_scene_tree *scene;
|
struct wlr_scene_tree *scene;
|
||||||
struct wlr_scene_rect *border; /* top, bottom, left, right */
|
struct wlr_scene_rect *border; /* top, bottom, left, right */
|
||||||
|
struct wlr_scene_rect *droparea;
|
||||||
struct wlr_scene_shadow *shadow;
|
struct wlr_scene_shadow *shadow;
|
||||||
struct wlr_scene_tree *scene_surface;
|
struct wlr_scene_tree *scene_surface;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
@ -422,6 +423,8 @@ struct Client {
|
||||||
bool isfocusing;
|
bool isfocusing;
|
||||||
struct Client *next_in_stack;
|
struct Client *next_in_stack;
|
||||||
struct Client *prev_in_stack;
|
struct Client *prev_in_stack;
|
||||||
|
bool enable_drop_area_draw;
|
||||||
|
int32_t drop_direction;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -873,7 +876,7 @@ static KeyboardGroup *kb_group;
|
||||||
static struct wl_list inputdevices;
|
static struct wl_list inputdevices;
|
||||||
static struct wl_list keyboard_shortcut_inhibitors;
|
static struct wl_list keyboard_shortcut_inhibitors;
|
||||||
static uint32_t cursor_mode;
|
static uint32_t cursor_mode;
|
||||||
static Client *grabc;
|
static Client *grabc, *dropc;
|
||||||
static int32_t rzcorner;
|
static int32_t rzcorner;
|
||||||
static int32_t grabcx, grabcy; /* client-relative */
|
static int32_t grabcx, grabcy; /* client-relative */
|
||||||
static int32_t drag_begin_cursorx, drag_begin_cursory; /* client-relative */
|
static int32_t drag_begin_cursorx, drag_begin_cursory; /* client-relative */
|
||||||
|
|
@ -2122,49 +2125,41 @@ void scroller_insert_stack(Client *c, Client *target_client,
|
||||||
}
|
}
|
||||||
|
|
||||||
void try_scroller_drop(Client *c, Client *closest, int vertical) {
|
void try_scroller_drop(Client *c, Client *closest, int vertical) {
|
||||||
double ratio_main, ratio_cross;
|
|
||||||
int32_t main_pos, cross_pos;
|
Client *stack_head = get_scroll_stack_head(closest);
|
||||||
int32_t main_size, cross_size;
|
|
||||||
Client *stack_head = NULL;
|
|
||||||
|
|
||||||
if (vertical) {
|
if (vertical) {
|
||||||
main_pos = cursor->y;
|
if (closest->drop_direction == LEFT) {
|
||||||
cross_pos = cursor->x;
|
setfloating(c, 0);
|
||||||
main_size = closest->geom.height;
|
|
||||||
cross_size = closest->geom.width;
|
|
||||||
} else {
|
|
||||||
main_pos = cursor->x;
|
|
||||||
cross_pos = cursor->y;
|
|
||||||
main_size = closest->geom.width;
|
|
||||||
cross_size = closest->geom.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
ratio_main =
|
|
||||||
(double)(main_pos - (vertical ? closest->geom.y : closest->geom.x)) /
|
|
||||||
main_size;
|
|
||||||
ratio_cross =
|
|
||||||
(double)(cross_pos - (vertical ? closest->geom.x : closest->geom.y)) /
|
|
||||||
cross_size;
|
|
||||||
|
|
||||||
if (ratio_main > 0.3 && ratio_main < 0.7 &&
|
|
||||||
(ratio_cross < 0.3 || ratio_cross > 0.7)) {
|
|
||||||
setfloating(c, 0);
|
|
||||||
if (ratio_cross < 0.3) {
|
|
||||||
scroller_insert_stack(c, closest, true);
|
scroller_insert_stack(c, closest, true);
|
||||||
} else {
|
return;
|
||||||
|
} else if (closest->drop_direction == RIGHT) {
|
||||||
|
setfloating(c, 0);
|
||||||
scroller_insert_stack(c, closest, false);
|
scroller_insert_stack(c, closest, false);
|
||||||
|
return;
|
||||||
|
} else if (closest->drop_direction == UP) {
|
||||||
|
wl_list_remove(&c->link);
|
||||||
|
wl_list_insert(stack_head->link.prev, &c->link);
|
||||||
|
} else if (closest->drop_direction == DOWN) {
|
||||||
|
wl_list_remove(&c->link);
|
||||||
|
wl_list_insert(&stack_head->link, &c->link);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
stack_head = get_scroll_stack_head(closest);
|
|
||||||
|
|
||||||
if (ratio_main < 0.3) {
|
|
||||||
wl_list_remove(&c->link);
|
|
||||||
wl_list_insert(stack_head->link.prev, &c->link);
|
|
||||||
} else {
|
} else {
|
||||||
wl_list_remove(&c->link);
|
if (closest->drop_direction == UP) {
|
||||||
wl_list_insert(&stack_head->link, &c->link);
|
setfloating(c, 0);
|
||||||
|
scroller_insert_stack(c, closest, true);
|
||||||
|
return;
|
||||||
|
} else if (closest->drop_direction == DOWN) {
|
||||||
|
setfloating(c, 0);
|
||||||
|
scroller_insert_stack(c, closest, false);
|
||||||
|
return;
|
||||||
|
} else if (closest->drop_direction == LEFT) {
|
||||||
|
wl_list_remove(&c->link);
|
||||||
|
wl_list_insert(stack_head->link.prev, &c->link);
|
||||||
|
} else if (closest->drop_direction == RIGHT) {
|
||||||
|
wl_list_remove(&c->link);
|
||||||
|
wl_list_insert(&stack_head->link, &c->link);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setfloating(c, 0);
|
setfloating(c, 0);
|
||||||
|
|
@ -2177,22 +2172,27 @@ void place_drag_tile_client(Client *c) {
|
||||||
const Layout *layout =
|
const Layout *layout =
|
||||||
closest->mon->pertag->ltidxs[closest->mon->pertag->curtag];
|
closest->mon->pertag->ltidxs[closest->mon->pertag->curtag];
|
||||||
|
|
||||||
if (layout) {
|
if (closest->drop_direction == UNDIR) {
|
||||||
if (layout->id == SCROLLER) {
|
exchange_two_client(c, closest);
|
||||||
try_scroller_drop(c, closest, 0);
|
setfloating(c, 0);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (layout->id == VERTICAL_SCROLLER) {
|
|
||||||
try_scroller_drop(c, closest, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closest->link.prev != &c->link) {
|
if (layout->id == SCROLLER) {
|
||||||
|
try_scroller_drop(c, closest, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (layout->id == VERTICAL_SCROLLER) {
|
||||||
|
try_scroller_drop(c, closest, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closest->drop_direction == LEFT || closest->drop_direction == UP) {
|
||||||
wl_list_remove(&c->link);
|
wl_list_remove(&c->link);
|
||||||
wl_list_insert(closest->link.prev, &c->link);
|
wl_list_insert(closest->link.prev, &c->link);
|
||||||
} else {
|
} else {
|
||||||
exchange_two_client(c, closest);
|
wl_list_remove(&c->link);
|
||||||
|
wl_list_insert(&closest->link, &c->link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2317,6 +2317,11 @@ buttonpress(struct wl_listener *listener, void *data) {
|
||||||
apply_window_snap(tmpc);
|
apply_window_snap(tmpc);
|
||||||
}
|
}
|
||||||
tmpc->drag_to_tile = false;
|
tmpc->drag_to_tile = false;
|
||||||
|
if (dropc) {
|
||||||
|
dropc->enable_drop_area_draw = false;
|
||||||
|
client_set_drop_area(dropc);
|
||||||
|
dropc = NULL;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
cursor_mode = CurNormal;
|
cursor_mode = CurNormal;
|
||||||
|
|
@ -4182,6 +4187,8 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx,
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_client_properties(Client *c) {
|
void init_client_properties(Client *c) {
|
||||||
|
c->drop_direction = UNDIR;
|
||||||
|
c->enable_drop_area_draw = false;
|
||||||
c->isfocusing = false;
|
c->isfocusing = false;
|
||||||
c->isfloating = 0;
|
c->isfloating = 0;
|
||||||
c->isfakefullscreen = 0;
|
c->isfakefullscreen = 0;
|
||||||
|
|
@ -4323,6 +4330,12 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// extra node
|
// extra node
|
||||||
|
|
||||||
|
c->droparea = wlr_scene_rect_create(c->scene, 0, 0, config.dropcolor);
|
||||||
|
wlr_scene_node_lower_to_bottom(&c->droparea->node);
|
||||||
|
wlr_scene_node_set_position(&c->droparea->node, 0, 0);
|
||||||
|
wlr_scene_node_set_enabled(&c->droparea->node, false);
|
||||||
|
|
||||||
c->border = wlr_scene_rect_create(
|
c->border = wlr_scene_rect_create(
|
||||||
c->scene, 0, 0, c->isurgent ? config.urgentcolor : config.bordercolor);
|
c->scene, 0, 0, c->isurgent ? config.urgentcolor : config.bordercolor);
|
||||||
wlr_scene_node_lower_to_bottom(&c->border->node);
|
wlr_scene_node_lower_to_bottom(&c->border->node);
|
||||||
|
|
@ -4513,6 +4526,7 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
||||||
double dy, double dx_unaccel, double dy_unaccel) {
|
double dy, double dx_unaccel, double dy_unaccel) {
|
||||||
double sx = 0, sy = 0, sx_confined, sy_confined;
|
double sx = 0, sy = 0, sx_confined, sy_confined;
|
||||||
Client *c = NULL, *w = NULL;
|
Client *c = NULL, *w = NULL;
|
||||||
|
Client *closet_drop_client = NULL;
|
||||||
LayerSurface *l = NULL;
|
LayerSurface *l = NULL;
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
struct wlr_pointer_constraint_v1 *constraint;
|
struct wlr_pointer_constraint_v1 *constraint;
|
||||||
|
|
@ -4584,6 +4598,24 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
||||||
.y = (int32_t)round(cursor->y) - grabcy,
|
.y = (int32_t)round(cursor->y) - grabcy,
|
||||||
.width = grabc->geom.width,
|
.width = grabc->geom.width,
|
||||||
.height = grabc->geom.height};
|
.height = grabc->geom.height};
|
||||||
|
if (config.drag_tile_to_tile && grabc->drag_to_tile) {
|
||||||
|
closet_drop_client = find_closest_tiled_client(grabc);
|
||||||
|
if (closet_drop_client && dropc && closet_drop_client != dropc) {
|
||||||
|
dropc->enable_drop_area_draw = false;
|
||||||
|
client_set_drop_area(dropc);
|
||||||
|
dropc = closet_drop_client;
|
||||||
|
dropc->enable_drop_area_draw = true;
|
||||||
|
client_set_drop_area(dropc);
|
||||||
|
} else if (closet_drop_client) {
|
||||||
|
dropc = closet_drop_client;
|
||||||
|
dropc->enable_drop_area_draw = true;
|
||||||
|
client_set_drop_area(dropc);
|
||||||
|
} else if (dropc) {
|
||||||
|
dropc->enable_drop_area_draw = false;
|
||||||
|
client_set_drop_area(dropc);
|
||||||
|
dropc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
resize(grabc, grabc->float_geom, 1);
|
resize(grabc, grabc->float_geom, 1);
|
||||||
return;
|
return;
|
||||||
} else if (cursor_mode == CurResize) {
|
} else if (cursor_mode == CurResize) {
|
||||||
|
|
@ -6210,6 +6242,10 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
||||||
grabc = NULL;
|
grabc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c == dropc) {
|
||||||
|
dropc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
if (!m->wlr_output->enabled) {
|
if (!m->wlr_output->enabled) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue