You are not logged in.

#1 2013-06-05 16:42:22

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Question on Xlib

Hey guys,

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!


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#2 2013-06-05 18:54:37

drcouzelis
Member
From: Connecticut, USA
Registered: 2009-11-09
Posts: 4,092
Website

Re: Question on Xlib

Unia wrote:

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. smile

Offline

#3 2013-06-05 18:58:30

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: Question on Xlib

Xlib supports ButtonPress and ButtonRelease or something the like, but in order for me to calculate that time I need to release the mousebutton again which makes dragging windows with the mouse rather difficult tongue


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#4 2013-06-05 19:05:14

drcouzelis
Member
From: Connecticut, USA
Registered: 2009-11-09
Posts: 4,092
Website

Re: Question on Xlib

Hmm... Can you calculate how for the mouse has moved between ButtonPress and ButtonRelease? If it's less than a (say) five pixel radius for one complete second, then treat it as special.

Offline

#5 2013-06-05 19:07:53

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: Question on Xlib

I would still have to release the mousebutton to get that ButtonRelease event

Last edited by Unia (2013-06-05 19:08:36)


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#6 2013-06-05 19:45:59

drcouzelis
Member
From: Connecticut, USA
Registered: 2009-11-09
Posts: 4,092
Website

Re: Question on Xlib

Ohhhhhhhh. Touché.

OK, no problem:

  1. Receive ButtonDown. Record time and location.

  2. After two seconds, get the new location.

  3. If the new location is greater than a five pixel radius, do your new fanciness.

  4. Otherwise, proceed as usual.

...Did I get it this time? sad

Offline

#7 2013-06-05 19:56:34

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: Question on Xlib

But meh, that requires a double click tongue Could be a workaround, though, for when Xlib does not support this. On the other hand, I think that if it doesn't I'll stick with what's there now.

Thanks for your thoughts smile


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#8 2013-06-05 23:17:35

moetunes
Member
From: A comfortable couch
Registered: 2010-10-09
Posts: 1,033

Re: Question on Xlib

Maybe something like:

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

Last edited by moetunes (2013-06-05 23:19:10)


You're just jealous because the voices only talk to me.

Offline

#9 2013-06-05 23:38:17

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,422
Website

Re: Question on Xlib

In the mousedown event you could set up a select loop (see lines 984-1006 of alopex.c) that only responded to a ButtonRelease event.

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;

Last edited by Trilby (2013-06-06 00:01:23)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Online

#10 2013-06-06 10:44:05

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: Question on Xlib

Oh wow, this is quickly getting more complicated than I expected. I have other things to do right now, so I will look into both suggestions later today! Thanks!


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#11 2013-06-06 10:54:23

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,422
Website

Re: Question on Xlib

Also for your second question - just check the root_x and root_y values of a MotionNotify event and compare them against DisplayWidth() and DisplayHeight() (the latter two are already stored, in the selmon Monitor structure if I remember correctly.

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");
}

Last edited by Trilby (2013-06-06 11:31:42)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Online

#12 2013-06-08 20:06:17

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: Question on Xlib

I've moved away from DWM again, so this all is kind of put on hold. I'm sorry for stealing your time, but I still do appreciate all the input I've gotten here!

Thanks everyone


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

Board footer

Powered by FluxBB