Home » Developing U++ » U++ Developers corner » Using Pen with U++
Re: Using Pen with U++ [message #56904 is a reply to message #56903] |
Wed, 28 April 2021 16:39 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
Mirek,
OK, I can live without history in GTK for now.
Do you think it would still be better to include the GDK_SOURCE_TOUCHSCREEN option to support pen on Ubuntu, although without history processing? Or maybe just announce pen support for Windows at this time?
Best regards,
Tom
|
|
|
|
Re: Using Pen with U++ [message #56919 is a reply to message #56918] |
Fri, 30 April 2021 11:08 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
Hi Mirek,
Before applying the below code, please consider the following: Although this makes it work on Ubuntu 2021.4 in addition to Linux Mint 20.1 with Wacom, it seems like accepting a bug in Ubuntu and adapting to it. (Pretty much like what we have to do in Windows normally...)
I also tried to address the missing tilt information here by reading gdk_device_get_axes() and behaving accordingly, but that does not seem to work either. Tilt remains constantly on both axis at 0.00787... Is it the same with your XPPEN tablet?
#if GTK_CHECK_VERSION(3, 22, 0)
GdkDevice *d = gdk_event_get_source_device(event);
int s=d?gdk_device_get_source(d):0;
if(d && ((s==GDK_SOURCE_PEN) || (s==GDK_SOURCE_TOUCHSCREEN))) {
e.pen = true;
e.pen_barrel = MouseState & GDK_BUTTON3_MASK;
double *axes = NULL;
if(event->type == GDK_MOTION_NOTIFY)
axes = ((GdkEventMotion *)event)->axes;
if(findarg(event->type, GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_3BUTTON_PRESS, GDK_BUTTON_RELEASE) >= 0)
axes = ((GdkEventButton *)event)->axes;
if(axes) {
GdkAxisFlags flags = gdk_device_get_axes (d);
if(flags & GDK_AXIS_FLAG_PRESSURE) gdk_device_get_axis(d, axes, GDK_AXIS_PRESSURE, &e.pen_pressure);
if(flags & GDK_AXIS_FLAG_ROTATION) gdk_device_get_axis(d, axes, GDK_AXIS_ROTATION, &e.pen_rotation);
if(flags & GDK_AXIS_FLAG_XTILT) gdk_device_get_axis(d, axes, GDK_AXIS_XTILT, &e.pen_tilt.x);
if(flags & GDK_AXIS_FLAG_YTILT) gdk_device_get_axis(d, axes, GDK_AXIS_YTILT, &e.pen_tilt.y);
}
}
#endif
Best regards,
Tom
|
|
|
Re: Using Pen with U++ [message #56921 is a reply to message #56919] |
Fri, 30 April 2021 17:08 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
Mirek,
This might only apply after release 2021.1, but I found a solution for history -- or rather the backlog of mouse events:
In GtkCreate.cpp on line 44 we should have:
gtk_widget_set_events(top->window, GDK_ALL_EVENTS_MASK & ~GDK_POINTER_MOTION_HINT_MASK);
This drops the deprecated event mask for reducing the number of GDK_MOTION_NOTIFY events.
Additionally in GtkEvent.cpp we need:
...
static Point s_mousepos;
Point Ctrl::GetMouseInfo(GdkWindow *win, GdkModifierType& mod)
{
#if GTK_CHECK_VERSION(3, 20, 0)
GdkDisplay *display = gdk_window_get_display (win);
GdkDevice *pointer = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
double x, y;
gdk_window_get_device_position_double (win, pointer, &x, &y, &mod);
return s_mousepos; //return Point((int)SCL(x), (int)SCL(y));
#else
gint x, y;
gdk_window_get_pointer(win, &x, &y, &mod);
return Point(SCL(x), SCL(y));
#endif
}
void Ctrl::AddEvent(gpointer user_data, int type, const Value& value, GdkEvent *event)
{
if(Events.GetCount() > 50000)
return;
GEvent& e = Events.AddTail();
e.windowid = (uint32)(uintptr_t)user_data;
e.type = type;
e.value = value;
GdkModifierType mod;
e.mousepos = GetMouseInfo(gdk_get_default_root_window(), mod);
if(event->type == GDK_MOTION_NOTIFY){
GdkEventMotion *mevent = (GdkEventMotion *)event;
e.mousepos = s_mousepos = Point(SCL(mevent->x_root), SCL(mevent->y_root));
}
e.state = (mod & ~(GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK)) | MouseState;
e.count = 1;
e.event = NULL;
#if GTK_CHECK_VERSION(3, 22, 0)
GdkDevice *d = gdk_event_get_source_device(event);
int s=d?gdk_device_get_source(d):0;
if(d && ((s==GDK_SOURCE_PEN) || (s==GDK_SOURCE_TOUCHSCREEN))) {
e.pen = true;
e.pen_barrel = MouseState & GDK_BUTTON3_MASK;
double *axes = NULL;
switch(event->type){
case GDK_BUTTON_PRESS:
gdk_window_set_event_compression(((GdkEventButton *)event)->window, false);
case GDK_2BUTTON_PRESS:
case GDK_3BUTTON_PRESS:
axes = ((GdkEventButton *)event)->axes;
break;
case GDK_BUTTON_RELEASE:
gdk_window_set_event_compression(((GdkEventButton *)event)->window, true);
axes = ((GdkEventButton *)event)->axes;
break;
case GDK_MOTION_NOTIFY:{
GdkEventMotion *mevent = (GdkEventMotion *)event;
e.mousepos = s_mousepos = Point(SCL(mevent->x_root), SCL(mevent->y_root));
axes = ((GdkEventMotion *)event)->axes;
break;
}
}
if(axes) {
if(!gdk_device_get_axis(d, axes, GDK_AXIS_PRESSURE, &e.pen_pressure)) e.pen_pressure=Null;
if(!gdk_device_get_axis(d, axes, GDK_AXIS_ROTATION, &e.pen_rotation)) e.pen_rotation=Null;
if(!gdk_device_get_axis(d, axes, GDK_AXIS_XTILT, &e.pen_tilt.x)) e.pen_tilt.x=Null;
if(!gdk_device_get_axis(d, axes, GDK_AXIS_YTILT, &e.pen_tilt.y)) e.pen_tilt.y=Null;
}
}
#endif
...
And finally also in GtkEvent.cpp:
...
bool Ctrl::ProcessEvent0(bool *quit, bool fetch)
{
ASSERT(IsMainThread());
bool r = false;
if(IsWaitingEvent0(fetch)) {
while(Events.GetCount() > 1) { // GEvent compression (coalesce autorepeat, mouse moves/wheel, configure)
GEvent& a = Events[0];
GEvent& b = Events[1];
if(b.type == a.type && a.windowid == b.windowid && a.state == b.state) {
if(a.type == GDK_KEY_PRESS && a.value == b.value)
b.count += a.count;
else
if(a.type == GDK_SCROLL)
b.value = (int)b.value + (int)a.value;
else
// if(findarg(a.type, GDK_MOTION_NOTIFY, GDK_CONFIGURE) < 0)
if(findarg(a.type, GDK_CONFIGURE) < 0) // *** HERE: We cannot drop GDK_MOTION_NOTIFY events
break;
Events.DropHead();
...
This last one dropped queued GDK_MOTION_NOTIFY events and ruined all attempts to get them through.
However, performance questions may need further considerations... It works here in virtual machine quite well on both Ubuntu 2021.4 and Linux Mint 20.1, but hardware varies of course.
Best regards,
Tom
|
|
|
Re: Using Pen with U++ [message #56925 is a reply to message #56919] |
Sat, 01 May 2021 10:16 |
|
mirek
Messages: 14112 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Fri, 30 April 2021 11:08Hi Mirek,
Before applying the below code, please consider the following: Although this makes it work on Ubuntu 2021.4 in addition to Linux Mint 20.1 with Wacom, it seems like accepting a bug in Ubuntu and adapting to it. (Pretty much like what we have to do in Windows normally...)
I also tried to address the missing tilt information here by reading gdk_device_get_axes() and behaving accordingly, but that does not seem to work either. Tilt remains constantly on both axis at 0.00787... Is it the same with your XPPEN tablet?
#if GTK_CHECK_VERSION(3, 22, 0)
GdkDevice *d = gdk_event_get_source_device(event);
int s=d?gdk_device_get_source(d):0;
if(d && ((s==GDK_SOURCE_PEN) || (s==GDK_SOURCE_TOUCHSCREEN))) {
e.pen = true;
e.pen_barrel = MouseState & GDK_BUTTON3_MASK;
double *axes = NULL;
if(event->type == GDK_MOTION_NOTIFY)
axes = ((GdkEventMotion *)event)->axes;
if(findarg(event->type, GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_3BUTTON_PRESS, GDK_BUTTON_RELEASE) >= 0)
axes = ((GdkEventButton *)event)->axes;
if(axes) {
GdkAxisFlags flags = gdk_device_get_axes (d);
if(flags & GDK_AXIS_FLAG_PRESSURE) gdk_device_get_axis(d, axes, GDK_AXIS_PRESSURE, &e.pen_pressure);
if(flags & GDK_AXIS_FLAG_ROTATION) gdk_device_get_axis(d, axes, GDK_AXIS_ROTATION, &e.pen_rotation);
if(flags & GDK_AXIS_FLAG_XTILT) gdk_device_get_axis(d, axes, GDK_AXIS_XTILT, &e.pen_tilt.x);
if(flags & GDK_AXIS_FLAG_YTILT) gdk_device_get_axis(d, axes, GDK_AXIS_YTILT, &e.pen_tilt.y);
}
}
#endif
Best regards,
Tom
OK, applied with cosmetics. Hopefully the last change for 2021.1....
Mirek
|
|
|
|
Re: Using Pen with U++ [message #56930 is a reply to message #56925] |
Sat, 01 May 2021 16:56 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
Hi,
Thanks, Mirek. I will test the applied changes on Monday at the office then.
For the future, i.e. post 2021.1: As for the pen history processing, should we consider some mechanism that would provide full motion history as a Vector<> of pen data. Then callbacks would be compressed, but the target Ctrl would decide if it wants to process the full history Vector or just the latest observation. This would scale well in my opinion, but still easily provide full pen trace.
Best regards,
Tom
|
|
|
Re: Using Pen with U++ [message #56932 is a reply to message #56930] |
Sat, 01 May 2021 17:57 |
|
mirek
Messages: 14112 Registered: November 2005
|
Ultimate Member |
|
|
Tom1 wrote on Sat, 01 May 2021 16:56Hi,
Thanks, Mirek. I will test the applied changes on Monday at the office then.
For the future, i.e. post 2021.1: As for the pen history processing, should we consider some mechanism that would provide full motion history as a Vector<> of pen data. Then callbacks would be compressed, but the target Ctrl would decide if it wants to process the full history Vector or just the latest observation. This would scale well in my opinion, but still easily provide full pen trace.
Best regards,
Tom
I think all is OK as long as those "overflow" events are delivered only to Pen. We already have history flag, do not we?
I am just afraid that doing that for all MouseMoves could overhelm some widgets that do not account for this....
Mirek
|
|
|
Re: Using Pen with U++ [message #56937 is a reply to message #56932] |
Sat, 01 May 2021 22:56 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
mirek wrote on Sat, 01 May 2021 18:57
I think all is OK as long as those "overflow" events are delivered only to Pen. We already have history flag, do not we?
I am just afraid that doing that for all MouseMoves could overhelm some widgets that do not account for this....
Mirek
Actually, I'm not so sure about overwhelming anything. Even when we do:
gtk_widget_set_events(top->window, GDK_ALL_EVENTS_MASK & ~GDK_POINTER_MOTION_HINT_MASK);
to disable deprecated motion compression, there will be modern default motion compression enabled, which is only disabled for full data by:
gdk_window_set_event_compression(((GdkEventButton *)event)->window, false);
And this I only used for pen and touch when some button is down in the above code. Not for mouse at all, so it should really be compressed in GDK. However, what is missing is that the history flag should be set in some smart way to improve efficiency of widgets that do not need this much detail from pen. In my opinion when the pen is in mouse emulation and not using Pen() interface, it should be compressed for best response from widgets not prepared for such stream of moves. One critical example would be a Splitter, which can cause a terrible load from refreshing complex child widgets.
Best regards,
Tom
|
|
|
Re: Using Pen with U++ [message #56947 is a reply to message #56925] |
Mon, 03 May 2021 09:18 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
mirek wrote on Sat, 01 May 2021 11:16
OK, applied with cosmetics. Hopefully the last change for 2021.1....
Mirek
Hi Mirek,
Confirmed: It works on Ubuntu 2021.4 and Linux Mint 20.1 with Wacom.
Best regards,
Tom
|
|
|
Re: Using Pen with U++ [message #57012 is a reply to message #56947] |
Fri, 14 May 2021 09:04 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
Hi Mirek,
Now that the release is happily completed, how shall we continue with pen history processing in GTK? (I think we should get over with it before the details fade away.)
Best regards,
Tom
|
|
|
|
Re: Using Pen with U++ [message #57159 is a reply to message #57158] |
Wed, 02 June 2021 11:28 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
mirek wrote on Wed, 02 June 2021 11:53After checking the code, looks reasonable enough, applied.
That said, during testing I had performance issue, sometimes turning the whole process into slide-show, however it seems like these need to be fixed on more fundamental level of GTK backend....
Hi Mirek,
Thanks! This seems to work fine here. Also with splitter.
However, I do have one more wish: Is it possible to get the mouse cursor to follow the pen? As you may have noticed, the pen does not currently have any cursor at all in Linux. Preferably, it should work the same way as in Windows.
Best regards,
Tom
|
|
|
|
Re: Using Pen with U++ [message #57161 is a reply to message #57160] |
Wed, 02 June 2021 11:40 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
mirek wrote on Wed, 02 June 2021 12:38
I am not sure what you mean here. For me, it seems to work the same way as in Windows.
Unfortunately not in my Wacom case... Here I can move the real mouse around the screen and simultaneously draw with pen on a different location. The cursor follows the real mouse and the pen does not have any cursor at all.
BR,
Tom
|
|
|
|
Re: Using Pen with U++ [message #57163 is a reply to message #57162] |
Wed, 02 June 2021 12:00 |
Tom1
Messages: 1253 Registered: March 2007
|
Senior Contributor |
|
|
mirek wrote on Wed, 02 June 2021 12:45
Maybe some system setting?
Probably. I just realized that cannot see a cursor for pen anywhere on the desktop. They are just two completely separated pointing devices and only mouse does have the cursor. I need to do some googling here...
Thanks and best regards,
Tom
|
|
|
|
|
|
Goto Forum:
Current Time: Sun Nov 10 20:24:22 CET 2024
Total time taken to generate the page: 0.01166 seconds
|