Client-initiated window drag

This commit is contained in:
Kevin Lange 2014-05-18 11:54:20 -07:00
parent dff654ae93
commit 3cb7b18c60
5 changed files with 97 additions and 34 deletions

View File

@ -206,6 +206,11 @@ void ttk_check_click(struct yutani_msg_window_mouse_event * evt) {
}
}
}
} else if (evt->command == YUTANI_MOUSE_EVENT_DOWN) {
fprintf(stderr, "Mouse down: %d, %d\n", evt->new_x, evt->new_y);
if (evt->new_y < decor_top_height) {
yutani_window_drag_start(yctx, wina);
}
}
}

View File

@ -1054,6 +1054,46 @@ static void add_key_bind(yutani_globals_t * yg, struct yutani_msg_key_bind * req
}
}
static void mouse_start_drag(yutani_globals_t * yg) {
set_focused_at(yg, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE);
yg->mouse_window = get_focused(yg);
if (yg->mouse_window) {
if (yg->mouse_window->z == YUTANI_ZORDER_BOTTOM || yg->mouse_window->z == YUTANI_ZORDER_TOP) {
yg->mouse_state = YUTANI_MOUSE_STATE_NORMAL;
yg->mouse_window = NULL;
} else {
yg->mouse_state = YUTANI_MOUSE_STATE_MOVING;
yg->mouse_init_x = yg->mouse_x;
yg->mouse_init_y = yg->mouse_y;
yg->mouse_win_x = yg->mouse_window->x;
yg->mouse_win_y = yg->mouse_window->y;
make_top(yg, yg->mouse_window);
}
}
}
static void mouse_start_resize(yutani_globals_t * yg) {
set_focused_at(yg, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE);
yg->mouse_window = get_focused(yg);
if (yg->mouse_window) {
if (yg->mouse_window->z == YUTANI_ZORDER_BOTTOM || yg->mouse_window->z == YUTANI_ZORDER_TOP) {
yg->mouse_state = YUTANI_MOUSE_STATE_NORMAL;
yg->mouse_window = NULL;
} else {
fprintf(stderr, "[yutani-server] resize starting for wid=%d\n", yg->mouse_window -> wid);
yg->mouse_state = YUTANI_MOUSE_STATE_RESIZING;
yg->mouse_init_x = yg->mouse_x;
yg->mouse_init_y = yg->mouse_y;
yg->mouse_win_x = yg->mouse_window->x;
yg->mouse_win_y = yg->mouse_window->y;
yg->resizing_window = yg->mouse_window;
yg->resizing_w = yg->mouse_window->width;
yg->resizing_h = yg->mouse_window->height;
make_top(yg, yg->mouse_window);
}
}
}
static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_event * me) {
yg->mouse_x += me->event.x_difference * 3;
yg->mouse_y -= me->event.y_difference * 3;
@ -1067,41 +1107,9 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev
case YUTANI_MOUSE_STATE_NORMAL:
{
if ((me->event.buttons & YUTANI_MOUSE_BUTTON_LEFT) && (yg->kbd_state.k_alt)) {
set_focused_at(yg, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE);
yg->mouse_window = get_focused(yg);
if (yg->mouse_window) {
if (yg->mouse_window->z == YUTANI_ZORDER_BOTTOM || yg->mouse_window->z == YUTANI_ZORDER_TOP) {
yg->mouse_state = YUTANI_MOUSE_STATE_NORMAL;
yg->mouse_window = NULL;
} else {
yg->mouse_state = YUTANI_MOUSE_STATE_MOVING;
yg->mouse_init_x = yg->mouse_x;
yg->mouse_init_y = yg->mouse_y;
yg->mouse_win_x = yg->mouse_window->x;
yg->mouse_win_y = yg->mouse_window->y;
make_top(yg, yg->mouse_window);
}
}
mouse_start_drag(yg);
} else if ((me->event.buttons & YUTANI_MOUSE_BUTTON_MIDDLE) && (yg->kbd_state.k_alt)) {
set_focused_at(yg, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE);
yg->mouse_window = get_focused(yg);
if (yg->mouse_window) {
if (yg->mouse_window->z == YUTANI_ZORDER_BOTTOM || yg->mouse_window->z == YUTANI_ZORDER_TOP) {
yg->mouse_state = YUTANI_MOUSE_STATE_NORMAL;
yg->mouse_window = NULL;
} else {
fprintf(stderr, "[yutani-server] resize starting for wid=%d\n", yg->mouse_window -> wid);
yg->mouse_state = YUTANI_MOUSE_STATE_RESIZING;
yg->mouse_init_x = yg->mouse_x;
yg->mouse_init_y = yg->mouse_y;
yg->mouse_win_x = yg->mouse_window->x;
yg->mouse_win_y = yg->mouse_window->y;
yg->resizing_window = yg->mouse_window;
yg->resizing_w = yg->mouse_window->width;
yg->resizing_h = yg->mouse_window->height;
make_top(yg, yg->mouse_window);
}
}
mouse_start_resize(yg);
} else if ((me->event.buttons & YUTANI_MOUSE_BUTTON_LEFT) && (!yg->kbd_state.k_alt)) {
yg->mouse_state = YUTANI_MOUSE_STATE_DRAGGING;
set_focused_at(yg, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE);
@ -1507,6 +1515,16 @@ int main(int argc, char * argv[]) {
add_key_bind(yg, wa, p->source);
}
break;
case YUTANI_MSG_WINDOW_DRAG_START:
{
struct yutani_msg_window_drag_start * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid);
if (w) {
/* Start dragging */
mouse_start_drag(yg);
}
}
break;
default:
{
fprintf(stderr, "[yutani-server] Unknown type: 0x%8x\n", m->type);

View File

@ -1110,6 +1110,18 @@ void * handle_incoming(void * garbage) {
resize_finish(wr->width, wr->height);
}
break;
case YUTANI_MSG_WINDOW_MOUSE_EVENT:
{
struct yutani_msg_window_mouse_event * me = (void*)m->data;
if (me->command == YUTANI_MOUSE_EVENT_DOWN && me->buttons & YUTANI_MOUSE_BUTTON_LEFT) {
if (!_fullscreen) {
if (me->new_y < decor_top_height) {
yutani_window_drag_start(yctx, window);
}
}
}
}
break;
default:
break;
}

View File

@ -405,6 +405,21 @@ yutani_msg_t * yutani_msg_build_key_bind(kbd_key_t key, kbd_mod_t mod, int respo
return msg;
}
yutani_msg_t * yutani_msg_build_window_drag_start(yutani_wid_t wid) {
size_t s = sizeof(struct yutani_message) + sizeof(struct yutani_msg_window_drag_start);
yutani_msg_t * msg = malloc(s);
msg->magic = YUTANI_MSG__MAGIC;
msg->type = YUTANI_MSG_WINDOW_DRAG_START;
msg->size = s;
struct yutani_msg_window_drag_start * mw = (void *)msg->data;
mw->wid = wid;
return msg;
}
int yutani_msg_send(yutani_t * y, yutani_msg_t * msg) {
return pex_reply(y->sock, msg->size, (char *)msg);
}
@ -654,6 +669,12 @@ void yutani_key_bind(yutani_t * yctx, kbd_key_t key, kbd_mod_t mod, int response
free(m);
}
void yutani_window_drag_start(yutani_t * yctx, yutani_window_t * window) {
yutani_msg_t * m = yutani_msg_build_window_drag_start(window->wid);
int result = yutani_msg_send(yctx, m);
free(m);
}
gfx_context_t * init_graphics_yutani(yutani_window_t * window) {
gfx_context_t * out = malloc(sizeof(gfx_context_t));
out->width = window->width;

View File

@ -130,6 +130,10 @@ struct yutani_msg_key_bind {
int response;
};
struct yutani_msg_window_drag_start {
yutani_wid_t wid;
};
typedef struct yutani_window {
yutani_wid_t wid;
@ -175,6 +179,7 @@ typedef struct yutani_window {
#define YUTANI_MSG_NOTIFY 0x00000023
#define YUTANI_MSG_QUERY_WINDOWS 0x00000024
#define YUTANI_MSG_WINDOW_FOCUS 0x00000025
#define YUTANI_MSG_WINDOW_DRAG_START 0x00000026
#define YUTANI_MSG_SESSION_END 0x00000030
@ -242,6 +247,7 @@ yutani_msg_t * yutani_msg_build_notify(void);
yutani_msg_t * yutani_msg_build_session_end(void);
yutani_msg_t * yutani_msg_build_window_focus(yutani_wid_t wid);
yutani_msg_t * yutani_msg_build_key_bind(kbd_key_t key, kbd_mod_t mod, int response);
yutani_msg_t * yutani_msg_build_window_drag_start(yutani_wid_t wid);
int yutani_msg_send(yutani_t * y, yutani_msg_t * msg);
@ -265,6 +271,7 @@ void yutani_query_windows(yutani_t * y);
void yutani_session_end(yutani_t * y);
void yutani_focus_window(yutani_t * y, yutani_wid_t wid);
void yutani_key_bind(yutani_t * yctx, kbd_key_t key, kbd_mod_t mod, int response);
void yutani_window_drag_start(yutani_t * yctx, yutani_window_t * window);
gfx_context_t * init_graphics_yutani(yutani_window_t * window);