Use drag_pointer from floating.c for the resize handler
This commit is contained in:
parent
ee217523f1
commit
607b1d071e
@ -11,6 +11,12 @@
|
|||||||
#ifndef _FLOATING_H
|
#ifndef _FLOATING_H
|
||||||
#define _FLOATING_H
|
#define _FLOATING_H
|
||||||
|
|
||||||
|
/** Callback for dragging */
|
||||||
|
typedef void(*callback_t)(Rect*, uint32_t, uint32_t);
|
||||||
|
|
||||||
|
/** On which border was the dragging initiated? */
|
||||||
|
typedef enum { BORDER_LEFT, BORDER_RIGHT, BORDER_TOP, BORDER_BOTTOM} border_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enters floating mode for the given client.
|
* Enters floating mode for the given client.
|
||||||
* Correctly takes care of the position/size (separately stored for tiling/floating mode)
|
* Correctly takes care of the position/size (separately stored for tiling/floating mode)
|
||||||
@ -67,4 +73,15 @@ void floating_move(xcb_connection_t *conn, Client *currently_focused, direction_
|
|||||||
*/
|
*/
|
||||||
void floating_toggle_hide(xcb_connection_t *conn, Workspace *workspace);
|
void floating_toggle_hide(xcb_connection_t *conn, Workspace *workspace);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function grabs your pointer and lets you drag stuff around (borders).
|
||||||
|
* Every time you move your mouse, an XCB_MOTION_NOTIFY event will be received
|
||||||
|
* and the given callback will be called with the parameters specified (client,
|
||||||
|
* border on which the click originally was), the original rect of the client,
|
||||||
|
* the event and the new coordinates (x, y).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_press_event_t *event,
|
||||||
|
xcb_window_t confine_to, border_t border, callback_t callback);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,15 +25,7 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "floating.h"
|
||||||
/* On which border was the dragging initiated? */
|
|
||||||
typedef enum { BORDER_LEFT, BORDER_RIGHT, BORDER_TOP, BORDER_BOTTOM} border_t;
|
|
||||||
/* Callback for dragging */
|
|
||||||
typedef void(*callback_t)(Rect*, uint32_t, uint32_t);
|
|
||||||
|
|
||||||
/* Forward definitions */
|
|
||||||
static void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_press_event_t *event,
|
|
||||||
border_t border, callback_t callback);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Toggles floating mode for the given client.
|
* Toggles floating mode for the given client.
|
||||||
@ -238,7 +230,7 @@ int floating_border_click(xcb_connection_t *conn, Client *client, xcb_button_pre
|
|||||||
|
|
||||||
LOG("border = %d\n", border);
|
LOG("border = %d\n", border);
|
||||||
|
|
||||||
drag_pointer(conn, client, event, border, resize_callback);
|
drag_pointer(conn, client, event, XCB_NONE, border, resize_callback);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -264,7 +256,7 @@ void floating_drag_window(xcb_connection_t *conn, Client *client, xcb_button_pre
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
drag_pointer(conn, client, event, BORDER_TOP /* irrelevant */, drag_window_callback);
|
drag_pointer(conn, client, event, XCB_NONE, BORDER_TOP /* irrelevant */, drag_window_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -275,12 +267,13 @@ void floating_drag_window(xcb_connection_t *conn, Client *client, xcb_button_pre
|
|||||||
* the event and the new coordinates (x, y).
|
* the event and the new coordinates (x, y).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_press_event_t *event,
|
void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_press_event_t *event,
|
||||||
border_t border, callback_t callback) {
|
xcb_window_t confine_to, border_t border, callback_t callback) {
|
||||||
xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
|
xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
|
||||||
uint32_t new_x, new_y;
|
uint32_t new_x, new_y;
|
||||||
Rect old_rect;
|
Rect old_rect;
|
||||||
memcpy(&old_rect, &(client->rect), sizeof(Rect));
|
if (client != NULL)
|
||||||
|
memcpy(&old_rect, &(client->rect), sizeof(Rect));
|
||||||
|
|
||||||
/* Grab the pointer */
|
/* Grab the pointer */
|
||||||
/* TODO: returncode */
|
/* TODO: returncode */
|
||||||
@ -290,7 +283,7 @@ static void drag_pointer(xcb_connection_t *conn, Client *client, xcb_button_pres
|
|||||||
XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION, /* which events to let through */
|
XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION, /* which events to let through */
|
||||||
XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
|
XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
|
||||||
XCB_GRAB_MODE_ASYNC, /* keyboard mode */
|
XCB_GRAB_MODE_ASYNC, /* keyboard mode */
|
||||||
XCB_NONE, /* confine_to = in which window should the cursor stay */
|
confine_to, /* confine_to = in which window should the cursor stay */
|
||||||
XCB_NONE, /* don’t display a special cursor */
|
XCB_NONE, /* don’t display a special cursor */
|
||||||
XCB_CURRENT_TIME);
|
XCB_CURRENT_TIME);
|
||||||
|
|
||||||
|
69
src/resize.c
69
src/resize.c
@ -26,6 +26,7 @@
|
|||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "xinerama.h"
|
#include "xinerama.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "floating.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Renders the resize window between the first/second container and resizes
|
* Renders the resize window between the first/second container and resizes
|
||||||
@ -35,7 +36,6 @@
|
|||||||
int resize_graphical_handler(xcb_connection_t *conn, Workspace *ws, int first, int second,
|
int resize_graphical_handler(xcb_connection_t *conn, Workspace *ws, int first, int second,
|
||||||
resize_orientation_t orientation, xcb_button_press_event_t *event) {
|
resize_orientation_t orientation, xcb_button_press_event_t *event) {
|
||||||
int new_position;
|
int new_position;
|
||||||
xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
|
|
||||||
xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
|
xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
|
||||||
i3Screen *screen = get_screen_containing(event->root_x, event->root_y);
|
i3Screen *screen = get_screen_containing(event->root_x, event->root_y);
|
||||||
if (screen == NULL) {
|
if (screen == NULL) {
|
||||||
@ -91,59 +91,32 @@ int resize_graphical_handler(xcb_connection_t *conn, Workspace *ws, int first, i
|
|||||||
|
|
||||||
xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, helpwin);
|
xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, helpwin);
|
||||||
|
|
||||||
xcb_grab_pointer(conn, false, root, XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION,
|
|
||||||
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, grabwin, XCB_NONE, XCB_CURRENT_TIME);
|
|
||||||
|
|
||||||
xcb_flush(conn);
|
xcb_flush(conn);
|
||||||
|
|
||||||
xcb_generic_event_t *inside_event;
|
void resize_callback(Rect *old_rect, uint32_t new_x, uint32_t new_y) {
|
||||||
/* I’ve always wanted to have my own eventhandler… */
|
LOG("new x = %d, y = %d\n", new_x, new_y);
|
||||||
while ((inside_event = xcb_wait_for_event(conn))) {
|
if (orientation == O_VERTICAL) {
|
||||||
/* Same as get_event_handler in xcb */
|
/* Check if the new coordinates are within screen boundaries */
|
||||||
int nr = inside_event->response_type;
|
if (new_x > (screen->rect.x + screen->rect.width) ||
|
||||||
if (nr == 0) {
|
new_x < screen->rect.x)
|
||||||
/* An error occured */
|
return;
|
||||||
handle_event(NULL, conn, inside_event);
|
|
||||||
free(inside_event);
|
values[0] = new_position = new_x;
|
||||||
continue;
|
xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_X, values);
|
||||||
|
} else {
|
||||||
|
if (new_y > (screen->rect.y + screen->rect.height) ||
|
||||||
|
new_y < screen->rect.y)
|
||||||
|
return;
|
||||||
|
|
||||||
|
values[0] = new_position = new_y;
|
||||||
|
xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_Y, values);
|
||||||
}
|
}
|
||||||
assert(nr < 256);
|
|
||||||
nr &= XCB_EVENT_RESPONSE_TYPE_MASK;
|
|
||||||
assert(nr >= 2);
|
|
||||||
|
|
||||||
/* Check if we need to escape this loop */
|
xcb_flush(conn);
|
||||||
if (nr == XCB_BUTTON_RELEASE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (nr) {
|
|
||||||
case XCB_MOTION_NOTIFY: {
|
|
||||||
xcb_motion_notify_event_t *motion_event = (xcb_motion_notify_event_t*)inside_event;
|
|
||||||
if (orientation == O_VERTICAL) {
|
|
||||||
if (motion_event->root_x < (screen->rect.x + screen->rect.width) &&
|
|
||||||
motion_event->root_x > screen->rect.x) {
|
|
||||||
values[0] = new_position = ((xcb_motion_notify_event_t*)inside_event)->root_x;
|
|
||||||
xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_X, values);
|
|
||||||
} else {
|
|
||||||
LOG("Ignoring new position\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
values[0] = new_position = ((xcb_motion_notify_event_t*)inside_event)->root_y;
|
|
||||||
xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_Y, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
xcb_flush(conn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
LOG("Passing to original handler\n");
|
|
||||||
/* Use original handler */
|
|
||||||
xcb_event_handle(&evenths, inside_event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(inside_event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
|
drag_pointer(conn, NULL, event, grabwin, BORDER_TOP, resize_callback);
|
||||||
|
|
||||||
xcb_destroy_window(conn, helpwin);
|
xcb_destroy_window(conn, helpwin);
|
||||||
xcb_destroy_window(conn, grabwin);
|
xcb_destroy_window(conn, grabwin);
|
||||||
xcb_flush(conn);
|
xcb_flush(conn);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user