void mouse_function_zoom(XMotionEvent* me) { // stretch, where center stays at the same position int x_diff = me->x_root - g_button_drag_start.x; int y_diff = me->y_root - g_button_drag_start.y; // relative x/y coords in drag window HSMonitor* m = g_drag_monitor; int rel_x = monitor_get_relative_x(m, g_button_drag_start.x) - g_win_drag_start.x; int rel_y = monitor_get_relative_y(m, g_button_drag_start.y) - g_win_drag_start.y; int cent_x = g_win_drag_start.x + g_win_drag_start.width / 2; int cent_y = g_win_drag_start.y + g_win_drag_start.height / 2; if (rel_x < g_win_drag_start.width/2) { x_diff *= -1; } if (rel_y < g_win_drag_start.height/2) { y_diff *= -1; } HSClient* client = g_win_drag_client; // avoid an overflow int new_width = g_win_drag_start.width + 2 * x_diff; int new_height = g_win_drag_start.height + 2 * y_diff; // apply new rect client->float_size = g_win_drag_start; client->float_size.x = cent_x - new_width / 2; client->float_size.y = cent_y - new_height / 2; client->float_size.width = new_width; client->float_size.height = new_height; // snap it to other windows int right_dx, bottom_dy; int left_dx, top_dy; // we have to distinguish the direction in which we zoom client_snap_vector(g_win_drag_client, m, (SnapFlags)(SNAP_EDGE_BOTTOM | SNAP_EDGE_RIGHT), &right_dx, &bottom_dy); client_snap_vector(g_win_drag_client, m, (SnapFlags)(SNAP_EDGE_TOP | SNAP_EDGE_LEFT), &left_dx, &top_dy); // e.g. if window snaps by vector (3,3) at topleft, window has to be shrinked // but if the window snaps by vector (3,3) at bottomright, window has to grow if (abs(right_dx) < abs(left_dx)) { right_dx = -left_dx; } if (abs(bottom_dy) < abs(top_dy)) { bottom_dy = -top_dy; } new_width += 2 * right_dx; new_height += 2 * bottom_dy; applysizehints(client, &new_width, &new_height); // center window again client->float_size.width = new_width; client->float_size.height = new_height; client->float_size.x = cent_x - new_width / 2; client->float_size.y = cent_y - new_height / 2; client_resize_floating(g_win_drag_client, g_drag_monitor); }
void mouse_function_move(XMotionEvent* me) { int x_diff = me->x_root - g_button_drag_start.x; int y_diff = me->y_root - g_button_drag_start.y; g_win_drag_client->float_size = g_win_drag_start; g_win_drag_client->float_size.x += x_diff; g_win_drag_client->float_size.y += y_diff; // snap it to other windows int dx, dy; client_snap_vector(g_win_drag_client, g_drag_monitor, SNAP_EDGE_ALL, &dx, &dy); g_win_drag_client->float_size.x += dx; g_win_drag_client->float_size.y += dy; client_resize_floating(g_win_drag_client, g_drag_monitor); }
void event_on_configure(XEvent event) { XConfigureRequestEvent* cre = &event.xconfigurerequest; HSClient* client = get_client_from_window(cre->window); XConfigureEvent ce; ce.type = ConfigureNotify; ce.display = g_display; ce.event = cre->window; ce.window = cre->window; if (client) { bool changes = false; if (client->sizehints && !client->dragged) { cre->width += 2*cre->border_width - 2*client->last_border_width; cre->height += 2*cre->border_width - 2*client->last_border_width; if (client->float_size.width != cre->width) changes = true; if (client->float_size.height != cre->height) changes = true; client->float_size.width = cre->width; client->float_size.height = cre->height; ce.x = client->last_size.x; ce.y = client->last_size.y; ce.width = client->last_size.width; ce.height = client->last_size.height; ce.override_redirect = False; ce.border_width = cre->border_width; ce.above = cre->above; } if (changes && client->tag->floating) { client_resize_floating(client, find_monitor_with_tag(client->tag)); } else if (changes && client->pseudotile) { monitor_apply_layout(find_monitor_with_tag(client->tag)); } else { // FIXME: why send event and not XConfigureWindow or XMoveResizeWindow?? XSendEvent(g_display, cre->window, False, StructureNotifyMask, (XEvent*)&ce); } } else { // if client not known.. then allow configure. // its probably a nice conky or dzen2 bar :) XWindowChanges wc; wc.x = cre->x; wc.y = cre->y; wc.width = cre->width; wc.height = cre->height; wc.border_width = cre->border_width; wc.sibling = cre->above; wc.stack_mode = cre->detail; XConfigureWindow(g_display, cre->window, cre->value_mask, &wc); } }
void event_on_configure(XEvent event) { XConfigureRequestEvent* cre = &event.xconfigurerequest; HSClient* client = get_client_from_window(cre->window); if (client) { bool changes = false; Rectangle newRect = client->float_size; if (client->sizehints_floating && (is_client_floated(client) || client->pseudotile)) { bool width_requested = 0 != (cre->value_mask & CWWidth); bool height_requested = 0 != (cre->value_mask & CWHeight); bool x_requested = 0 != (cre->value_mask & CWX); bool y_requested = 0 != (cre->value_mask & CWY); cre->width += 2*cre->border_width; cre->height += 2*cre->border_width; if (width_requested && newRect.width != cre->width) changes = true; if (height_requested && newRect.height != cre->height) changes = true; if (x_requested || y_requested) changes = true; if (x_requested) newRect.x = cre->x; if (y_requested) newRect.y = cre->y; if (width_requested) newRect.width = cre->width; if (height_requested) newRect.height = cre->height; } if (changes && is_client_floated(client)) { client->float_size = newRect; client_resize_floating(client, find_monitor_with_tag(client->tag)); } else if (changes && client->pseudotile) { client->float_size = newRect; monitor_apply_layout(find_monitor_with_tag(client->tag)); } else { // FIXME: why send event and not XConfigureWindow or XMoveResizeWindow?? client_send_configure(client); } } else { // if client not known.. then allow configure. // its probably a nice conky or dzen2 bar :) XWindowChanges wc; wc.x = cre->x; wc.y = cre->y; wc.width = cre->width; wc.height = cre->height; wc.border_width = cre->border_width; wc.sibling = cre->above; wc.stack_mode = cre->detail; XConfigureWindow(g_display, cre->window, cre->value_mask, &wc); } }
void mouse_function_resize(XMotionEvent* me) { int x_diff = me->x_root - g_button_drag_start.x; int y_diff = me->y_root - g_button_drag_start.y; g_win_drag_client->float_size = g_win_drag_start; // relative x/y coords in drag window HSMonitor* m = g_drag_monitor; int rel_x = monitor_get_relative_x(m, g_button_drag_start.x) - g_win_drag_start.x; int rel_y = monitor_get_relative_y(m, g_button_drag_start.y) - g_win_drag_start.y; bool top = false; bool left = false; if (rel_y < g_win_drag_start.height/2) { top = true; y_diff *= -1; } if (rel_x < g_win_drag_start.width/2) { left = true; x_diff *= -1; } // avoid an overflow int new_width = g_win_drag_client->float_size.width + x_diff; int new_height = g_win_drag_client->float_size.height + y_diff; int min_width = WINDOW_MIN_WIDTH; int min_height = WINDOW_MIN_HEIGHT; HSClient* client = g_win_drag_client; if (client->sizehints_floating) { min_width = MAX(WINDOW_MIN_WIDTH, client->minw); min_height = MAX(WINDOW_MIN_HEIGHT, client->minh); } if (new_width < min_width) { new_width = min_width; x_diff = new_width - g_win_drag_client->float_size.width; } if (new_height < min_height) { new_height = min_height; y_diff = new_height - g_win_drag_client->float_size.height; } if (left) g_win_drag_client->float_size.x -= x_diff; if (top) g_win_drag_client->float_size.y -= y_diff; g_win_drag_client->float_size.width = new_width; g_win_drag_client->float_size.height = new_height; // snap it to other windows int dx, dy; int snap_flags = 0; if (left) snap_flags |= SNAP_EDGE_LEFT; else snap_flags |= SNAP_EDGE_RIGHT; if (top) snap_flags |= SNAP_EDGE_TOP; else snap_flags |= SNAP_EDGE_BOTTOM; client_snap_vector(g_win_drag_client, g_drag_monitor, (SnapFlags)snap_flags, &dx, &dy); if (left) { g_win_drag_client->float_size.x += dx; dx *= -1; } if (top) { g_win_drag_client->float_size.y += dy; dy *= -1; } g_win_drag_client->float_size.width += dx; g_win_drag_client->float_size.height += dy; client_resize_floating(g_win_drag_client, g_drag_monitor); }