Thanks everyone
]]>EDIT: I just tried my code. I had to also set tv_usec at the start of the function to ensure it was zeroed. After that it worked. But the real problem is how to detect mouse buttons at all. DWM, by default, won't even detect mouse events without the associated modifier key being pressed. You can modify this to capture all mouse events, but then you have to relay all these events to client windows, or you wont be able to click on any client programs.
EDIT: the following works just as well, and is simpler - but I see no way to stop it from eating all mouse events:
void buttonpress(XEvent *e) {
static Time t;
if (t == e->xbutton.time) {
/* XPutBackEvent for e? */
return;
}
t = e->xbutton.time;
XEvent ev;
int i;
for (i = 0; i < 2000 && !XCheckMaskEvent(dpy,ButtonReleaseMask,&ev); i++, usleep(100));
if (i < 2000) { /* released before 2 seconds */
/* XPutBackEvent for e and &ev ?
return;
}
/* code here to move window: */
mouse("move");
}
You should, then XPutBackEvent anything that you get via XNextEvent that isn't a ButtonRelease. If the select function times out, then you do your window moving code.
EDIT: you won't be able to put back events, sorry. That would cause a viscous little cycle. Instead, use XCheckMaskEvent to only retrieve ButtonRelease events.
EDIT: this is completely untested, but it should be a good start:
void buttonpress(XEvent *e) {
struct timeval tv;
tv.tv_sec = 2;
int ret = 1, xfd = ConnectionNumber(dpy);
fd_set fds;
XEvent ev;
while(ret && !XCheckMaskEvent(dpy,ButtonReleaseMask,&ev)) {
FD_ZERO(&fds);
FD_SET(xfd,&fds);
ret = select(xfd+1,&fds,NULL,NULL,&tv);
}
if (ret) { /* released before 2 seconds */
/* should probably put pack the two mouse events here before returning (e, and &ev), otherwise this may 'eat' mouse clicks */
return;
}
/* held for 2+ seconds: window moving stuff here */
}
EDIT: putting back events will still be an issue. You'll have to use XSendEvent, and ignore sendevents at the beginning of this buttonpress function.
These, as the first three lines of the function *should* avoid this problem, but I've never had to do such a thing:
static Time t;
if (t == e->time) return;
t = e->time;
int some_number;
a_timer_function() {
int nother_number = 0;
do {
sleep(1);
++nother_number;
if(nother_number == 2)
some_window_moving_function();
} until(some_number == 1);
}
buttonpress() {
some_number = 0;
a_timer_function(0);
}
buttonrelease() {
some_number = 1;
}
HTH
edit: forgot a semi-colon
]]>Thanks for your thoughts
]]>OK, no problem:
Receive ButtonDown. Record time and location.
After two seconds, get the new location.
If the new location is greater than a five pixel radius, do your new fanciness.
Otherwise, proceed as usual.
...Did I get it this time?
]]>I thought perhaps Xlib could detect how long I've been pressing my mousebuttons?
I don't know Xlib... But if it can receive a "mouse down" event and a "mouse up" event then you can calculate how long it was pressed.
]]>I want to modify DWM so that I don't need a modifier key anymore to move/resize clients with the mouse. As an alternative, I thought perhaps Xlib could detect how long I've been pressing my mousebuttons? If possible, I would like to go that way: a quick one or two click still does not move the client but once the mousebutton is hold for, say, 2 seconds, DWM would grab the client so I can move/resize it. (of course, there could be an issue with Drag and Drop in applications but I rarely use that)
I've been skimming through Xlib documentation but I haven't found this. Do you know if it's possible?
Also, whilst I'm at it now (admittedly, I haven't searched for this yet), how would I detect if a mousepointer is against the edge of the screen?
Thanks in advance!
]]>