/* тему стоило бы назвать как-нить типа «призер олимпиады по
* русскому языку не справился с простейшим вопросом в подворотне
* Южного Бутово», но это было бы не очень информативно
*/
В общем, пытаюсь поймать событие ButtonRelease при *завершении* изменения размера окна, чтобы не ловить постоянно «Window resized to %{newX}x${newY}
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/Xcursor/Xcursor.h>
#define PointerMotionHint (1 << 16)
int main()
{
Display *display;
Window rootWindow, selectedWindow, window = None;
Cursor cursor;
XWindowAttributes windowCurAttributes;
XEvent event;
int prevWidth, prevHeight, rootX, rootY, winX, winY;
unsigned int mask;
bool resizing = false;
display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
cursor = XCreateFontCursor(display, XC_hand2);
XDefineCursor(display, XRootWindow(display, DefaultScreen(display)), cursor);
XChangeActivePointerGrab(display, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, cursor, CurrentTime);
XGrabPointer(display, DefaultRootWindow(display), False,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, cursor,
CurrentTime);
while (1) {
XNextEvent(display, &event);
switch (event.type) {
case ButtonPress:
XQueryPointer(display, DefaultRootWindow(display), &rootWindow, &selectedWindow, &rootX,
&rootY, &winX, &winY, &mask);
window = selectedWindow;
XSelectInput(display, window, StructureNotifyMask | PointerMotionMask | ButtonReleaseMask);
printf("Selected window with ID 0x%lx\n", window);
// XGrabPointer(display, DefaultRootWindow(display), False,
XGrabPointer(display, window, False,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync,
GrabModeAsync, None, None, CurrentTime);
XGetWindowAttributes(display, window, &windowCurAttributes);
prevWidth = windowCurAttributes.width;
prevHeight = windowCurAttributes.height;
printf("pointer has been grabbed\n");
break;
case ConfigureNotify:
if (event.xconfigure.window == window) {
if (1 || resizing) {
if (event.xconfigure.width > prevWidth) {
printf("Window is being enlarged in width: %dx%d\n",
event.xconfigure.width, event.xconfigure.height);
}
else if (event.xconfigure.width < prevWidth) {
printf("Window is being shrunk in width: %dx%d\n",
event.xconfigure.width, event.xconfigure.height);
}
if (event.xconfigure.height > prevHeight) {
printf("Window is being enlarged in height: %dx%d\n",
event.xconfigure.width, event.xconfigure.height);
}
else if (event.xconfigure.height < prevHeight) {
printf("Window is being shrunk in height: %dx%d\n",
event.xconfigure.width, event.xconfigure.height);
}
prevWidth = event.xconfigure.width;
prevHeight = event.xconfigure.height;
}
}
break;
case MotionNotify:
if (window != None) {
int rootX, rootY, winX, winY;
unsigned int mask;
XQueryPointer(display, window, &rootWindow, &selectedWindow, &rootX, &rootY, &winX,
&winY, &mask);
int border_size = 5;
if (winX <= border_size) {
if (winY <= border_size) {
cursor = XcursorShapeLoadCursor(display, XC_top_left_corner);
XChangeActivePointerGrab(display, PointerMotionMask | ButtonReleaseMask,
cursor, CurrentTime);
resizing = true;
}
else if (winY >= event.xconfigure.height - border_size) {
cursor = XcursorShapeLoadCursor(display, XC_bottom_left_corner);
XChangeActivePointerGrab(display, PointerMotionMask | ButtonReleaseMask,
cursor, CurrentTime);
resizing = true;
}
else {
XChangeActivePointerGrab(display, PointerMotionMask | ButtonReleaseMask,
None, CurrentTime);
resizing = false;
}
}
else if (winX >= event.xconfigure.width - border_size) {
if (winY <= border_size) {
cursor = XcursorShapeLoadCursor(display, XC_top_right_corner);
XChangeActivePointerGrab(display, PointerMotionMask | ButtonReleaseMask,
cursor, CurrentTime);
resizing = true;
}
else if (winY >= event.xconfigure.height - border_size) {
cursor = XcursorShapeLoadCursor(display, XC_bottom_right_corner);
XChangeActivePointerGrab(display, PointerMotionMask | ButtonReleaseMask,
cursor, CurrentTime);
resizing = true;
}
else {
XChangeActivePointerGrab(display, PointerMotionMask | ButtonReleaseMask,
None, CurrentTime);
resizing = false;
}
}
else {
XChangeActivePointerGrab(display, PointerMotionMask | ButtonReleaseMask,
None, CurrentTime);
resizing = false;
}
}
break;
case ButtonRelease:
printf("Button released\n");
if (window != None) {
XUngrabPointer(display, CurrentTime);
printf("Pointer ungrabbed\n");
printf("Window resizing has been finished\n");
}
break;
default:
break;
}
if (event.type == ConfigureNotify) {
printf("Window resized to %dx%d\n", event.xconfigure.width, event.xconfigure.height);
}// else
// printf("event.type == %d\n", event.type);
}
}
но получается только один раз при выборе окна:
$ ./scnotify
Selected window with ID 0x170917c
pointer has been grabbed
Button released
Pointer ungrabbed
Window resizing has been finished
Window is being enlarged in width: 1310x780
Window resized to 1310x780
Window is being enlarged in width: 1311x780
Window resized to 1311x780
Window is being enlarged in width: 1312x780
Window resized to 1312x780
^C # а ожидался "Button released"
У нас остались люди сведущие в Xlib? Где я косячу?