-int resize_graphical_handler(xcb_connection_t *conn, Workspace *ws, int first, int second,
- resize_orientation_t orientation, xcb_button_press_event_t *event) {
- int new_position;
- i3Screen *screen = get_screen_containing(event->root_x, event->root_y);
- if (screen == NULL) {
- ELOG("BUG: No screen found at this position (%d, %d)\n", event->root_x, event->root_y);
- return 1;
- }
-
- /* We cannot use the X root window's width_in_pixels or height_in_pixels
- * attributes here since they are not updated when you configure new
- * screens during runtime. Instead, we just use the most right and most
- * bottom Xinerama screen and use their position + width/height to get
- * the area of pixels currently in use */
- i3Screen *most_right = get_screen_most(D_RIGHT, screen),
- *most_bottom = get_screen_most(D_DOWN, screen);
-
- DLOG("event->event_x = %d, event->root_x = %d\n", event->event_x, event->root_x);
-
- DLOG("Screen dimensions: (%d, %d) %d x %d\n", screen->rect.x, screen->rect.y, screen->rect.width, screen->rect.height);
-
- uint32_t mask = 0;
- uint32_t values[2];
-
- mask = XCB_CW_OVERRIDE_REDIRECT;
- values[0] = 1;
-
- /* Open a new window, the resizebar. Grab the pointer and move the window around
- as the user moves the pointer. */
- Rect grabrect = {0,
- 0,
- most_right->rect.x + most_right->rect.width,
- most_bottom->rect.x + most_bottom->rect.height};
- xcb_window_t grabwin = create_window(conn, grabrect, XCB_WINDOW_CLASS_INPUT_ONLY, -1, true, mask, values);
-
- Rect helprect;
- if (orientation == O_VERTICAL) {
- helprect.x = event->root_x;
- helprect.y = screen->rect.y;
- helprect.width = 2;
- helprect.height = screen->rect.height;
- new_position = event->root_x;
- } else {
- helprect.x = screen->rect.x;
- helprect.y = event->root_y;
- helprect.width = screen->rect.width;
- helprect.height = 2;
- new_position = event->root_y;
- }
-
- mask = XCB_CW_BACK_PIXEL;
- values[0] = config.client.focused.border;
-
- mask |= XCB_CW_OVERRIDE_REDIRECT;
- values[1] = 1;
-
- xcb_window_t helpwin = create_window(conn, helprect, XCB_WINDOW_CLASS_INPUT_OUTPUT,
- (orientation == O_VERTICAL ?
- XCB_CURSOR_SB_V_DOUBLE_ARROW :
- XCB_CURSOR_SB_H_DOUBLE_ARROW), true, mask, values);
-
- xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, helpwin);
-
- xcb_flush(conn);
-
- void resize_callback(Rect *old_rect, uint32_t new_x, uint32_t new_y) {
- DLOG("new x = %d, y = %d\n", new_x, new_y);
- if (orientation == O_VERTICAL) {
- /* Check if the new coordinates are within screen boundaries */
- if (new_x > (screen->rect.x + screen->rect.width - 25) ||
- new_x < (screen->rect.x + 25))
- return;
-
- values[0] = new_position = new_x;
- xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_X, values);
- } else {
- if (new_y > (screen->rect.y + screen->rect.height - 25) ||
- new_y < (screen->rect.y + 25))
- return;
-
- values[0] = new_position = new_y;
- xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_Y, values);
- }
-
- xcb_flush(conn);
- }
-
- drag_pointer(conn, NULL, event, grabwin, BORDER_TOP, resize_callback);
-
- xcb_destroy_window(conn, helpwin);
- xcb_destroy_window(conn, grabwin);
- xcb_flush(conn);
-
- int pixels;
- if (orientation == O_VERTICAL)
- pixels = (new_position - event->root_x);
- else pixels = (new_position - event->root_y);
- resize_container(conn, ws, first, second, orientation, pixels);
-
- return 1;
+struct callback_params {
+ orientation_t orientation;
+ Con *output;
+ xcb_window_t helpwin;
+ uint32_t *new_position;
+};
+
+DRAGGING_CB(resize_callback) {
+ struct callback_params *params = extra;
+ Con *output = params->output;
+ DLOG("new x = %d, y = %d\n", new_x, new_y);
+ if (params->orientation == HORIZ) {
+ /* Check if the new coordinates are within screen boundaries */
+ if (new_x > (output->rect.x + output->rect.width - 25) ||
+ new_x < (output->rect.x + 25))
+ return;
+
+ *(params->new_position) = new_x;
+ xcb_configure_window(conn, params->helpwin, XCB_CONFIG_WINDOW_X, params->new_position);
+ } else {
+ if (new_y > (output->rect.y + output->rect.height - 25) ||
+ new_y < (output->rect.y + 25))
+ return;
+
+ *(params->new_position) = new_y;
+ xcb_configure_window(conn, params->helpwin, XCB_CONFIG_WINDOW_Y, params->new_position);
+ }
+
+ xcb_flush(conn);