diff --git a/userspace/gui/compositor/compositor.c b/userspace/gui/compositor/compositor.c index 707c2630..f0774a2e 100644 --- a/userspace/gui/compositor/compositor.c +++ b/userspace/gui/compositor/compositor.c @@ -1693,6 +1693,21 @@ static void mouse_start_drag(yutani_globals_t * yg) { } } +static void mouse_start_rotate(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) { + yg->mouse_state = YUTANI_MOUSE_STATE_ROTATING; + yg->mouse_init_x = yg->mouse_x; + yg->mouse_init_y = yg->mouse_y; + int32_t x_diff = yg->mouse_x / MOUSE_SCALE - (yg->mouse_window->x + yg->mouse_window->width / 2); + int32_t y_diff = yg->mouse_y / MOUSE_SCALE - (yg->mouse_window->y + yg->mouse_window->height / 2); + int new_r = atan2(x_diff, y_diff) * 180.0 / (-M_PI); + yg->mouse_init_r = yg->mouse_window->rotation - new_r; + make_top(yg, yg->mouse_window); + } +} + static void mouse_start_resize(yutani_globals_t * yg, yutani_scale_direction_t direction) { set_focused_at(yg, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE); yg->mouse_window = get_focused(yg); @@ -1778,15 +1793,11 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev { if ((me->event.buttons & YUTANI_MOUSE_BUTTON_LEFT) && (yg->kbd_state.k_alt)) { mouse_start_drag(yg); -#if YUTANI_RESIZE_RIGHT } else if ((me->event.buttons & YUTANI_MOUSE_BUTTON_RIGHT) && (yg->kbd_state.k_alt)) { - yg->resizing_button = YUTANI_MOUSE_BUTTON_RIGHT; - mouse_start_resize(yg, SCALE_AUTO); -#else + mouse_start_rotate(yg); } else if ((me->event.buttons & YUTANI_MOUSE_BUTTON_MIDDLE) && (yg->kbd_state.k_alt)) { yg->resizing_button = YUTANI_MOUSE_BUTTON_MIDDLE; mouse_start_resize(yg, SCALE_AUTO); -#endif } 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); @@ -1853,6 +1864,23 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev } } break; + case YUTANI_MOUSE_STATE_ROTATING: + { + if (!(me->event.buttons & YUTANI_MOUSE_BUTTON_RIGHT)) { + yg->mouse_window = NULL; + yg->mouse_state = YUTANI_MOUSE_STATE_NORMAL; + mark_screen(yg, yg->mouse_x / MOUSE_SCALE - MOUSE_OFFSET_X, yg->mouse_y / MOUSE_SCALE - MOUSE_OFFSET_Y, MOUSE_WIDTH, MOUSE_HEIGHT); + } else { + /* Calculate rotation and make relative to initial rotation */ + int32_t x_diff = yg->mouse_x / MOUSE_SCALE - (yg->mouse_window->x + yg->mouse_window->width / 2); + int32_t y_diff = yg->mouse_y / MOUSE_SCALE - (yg->mouse_window->y + yg->mouse_window->height / 2); + int new_r = atan2(x_diff, y_diff) * 180.0 / (-M_PI); + mark_window(yg, yg->mouse_window); + yg->mouse_window->rotation = new_r + yg->mouse_init_r; + mark_window(yg, yg->mouse_window); + } + } + break; case YUTANI_MOUSE_STATE_DRAGGING: { if (!(me->event.buttons & yg->mouse_drag_button)) { diff --git a/userspace/gui/compositor/yutani_int.h b/userspace/gui/compositor/yutani_int.h index 3dacf835..3182a5f1 100644 --- a/userspace/gui/compositor/yutani_int.h +++ b/userspace/gui/compositor/yutani_int.h @@ -114,6 +114,7 @@ typedef struct { int mouse_win_y; int mouse_init_x; int mouse_init_y; + int mouse_init_r; int mouse_drag_button; int mouse_moved; diff --git a/userspace/lib/yutani.h b/userspace/lib/yutani.h index be437d1f..563829f8 100644 --- a/userspace/lib/yutani.h +++ b/userspace/lib/yutani.h @@ -270,6 +270,7 @@ typedef struct yutani_window { #define YUTANI_MOUSE_STATE_MOVING 1 #define YUTANI_MOUSE_STATE_DRAGGING 2 #define YUTANI_MOUSE_STATE_RESIZING 3 +#define YUTANI_MOUSE_STATE_ROTATING 4 /* * YUTANI_MOUSE_EVENT