GNOME Bugzilla – Bug 135666
GtkWidget style property to disable prelight
Last modified: 2014-08-03 14:59:19 UTC
There is no ability to disable prelight and I think there should be. I have seen references that it is enough to set prelight to normal, but it is not correct, because prelight can be reach from normal or from active. My problem is that I am using touchscreen and there users don't move cursor around screen they just touch on one place and the cursor remains there until they touch again. If the user interface contains for example toggle buttons (pushed = on, not pushed = off) then when they touch the cursor remains on the button so the button is prelighted and the user cannot see if the button is pushed or not so they have no confirmation of their action until they touch somewhere else.
> I have seen references that it is enough to set prelight to normal, > but it is not correct, because prelight can be reach from normal or > from active. So, what you are saying is that a widget in the ACTIVE state is sometimes prelighted, and if you set the prelight color to the NORMAL color, you will still see the prelighting?
No, let say the button is in normal state with normal color and user tap on it and it changes it to active but since the cursor stays on the button, the button shows as prelighted so user doesn't really see any difference. So he taps on it again and changes it back to normal but again, the bursor stays on the button and the button shows as prelighted and user doesn't see any difference. To actually see the outcome of his/her action, user must tap somewhere else to see in what state the button is.
But a toggle button is showed pushed down when it is active, so even if its color is the prelight one, it is still possible to see the difference.
Definitely not on my screen or maybe not in my eyes. Since the background color is the same when it is on or off, because cursor is over the button, the only think you can go by is the border of the button. That is not enough, the difference is very small. Especially if your monitor is not extra sharp. I am working on applicatiosn with touchscreens, these are used in conditions, when the light is not ideal, the screen is often dirty from fingers and to go just by difference in one line 1-2 pixel wide is not enough. The users really need to see the difference and the color would help much better.
Of course, really the *right* solution here in some sense is to use XInput drivers for your touchscreen that give ProximityIn/Out events, have GTK+ enable the input device in extended mode, and then react to the ProximtyIn/Out events. But since it's pretty hard to get everything there done, disabling prelight is an easier way of handling this, certainly. It would presumbaly be done as a GtkWidget style property, which we would then make all the widgets that prelight obey. (Style property should probably be GtkWidget::enable-prelight defaulting to TRUE)
Created attachment 60502 [details] [review] Patch The attached patch semi-works: if I change the default value of the enable-prelight property to FALSE there is no prelighting on GtkButtons. However, if I try and change it in a gtkrc file with: style "testing" { GtkWidget::enable-prelight = FALSE } class "GtkWidget" style "testing" I get an error message: Gtk-Message: /home/ross/.gtkrc-2.0:33: failed to retrieve property `GtkWidget::enable-prelight' of type `gboolean' from rc file value "((GString*) 0x8149cc0)" of type `GString' Not sure why that is...
My mistake, I need to use 0 rather than FALSE. The patch works as expected.
Created attachment 60927 [details] [review] Revised patch using gtk-touchscreen-mode A different take using the gtk-touchscreen-mode property. I'm not sure if calling g_object_get in every paint event is sane.
Created attachment 60929 [details] [review] Cunning change This patch is an alternative way of doing patch 60927, which modifies gtk_widget_set_state() to change all prelight states to normal. This is a deeper change, and doesn't effect all widgets as expected: for example scrollbar arrows are still prelighting. However, this change may effect more widgets on its own, but will it break anything?
I don't think it will break things. I like this approach; we'll have to handle the few widgets separately which prelight in some other way.
Okay, I'll carry on with this approach. I'm currently looking at GtkRange.
Indeed, that looks very nice and much less invasive than changing many widgets individually.
Created attachment 60954 [details] [review] Revised patch Updated patch, now handling GtkWidget and GtkRange. How expensive is calling g_object_get(gtk_widget_get_settings(widget)) every expose? Should I listen for notify::gtk-touchscreen-mode when the widget is created instead?
Created attachment 60956 [details] [review] Getting there Now patching gtktogglebutton, so The Widget Factory isn't showing any prelighting at all.
I do agree with Owens comment #5, btw that the really correct way to handle prelighting on touchscreens would make use of proximity events. But that is probably a longer-term project...
I tend to disagree, because proximity requires an active pen, which is only not available if the "pen" is your finger or the 770 stylus.
Ross, that patch looks good to me.
Committed to HEAD, thanks.
Unfortunately, it doesn't work this way :( At least not generically in gtkwidget.c Using PRELIGHT for drawing doesn't neccessarily mean the mouse is hovering the widget (I know it actually should mean that, but it doesn't). For example in GtkMenuItem, we set the item's state to PRELIGHT when it is selected, and there are probably other cases that do similar things. What confuses me quite a bit is that the menu item appears as if it was in SELECTED state, even tho it was set to PRELIGHT. Can anyone un-confuse me please?
Hm, I just replaced all PRELIGHT in the menu code by SELECTED, and it appears to work perfecty, both with any without touchscreen mode enabled. However this doesn't fix my confusion from the previous comment, why does the menu code use PRELIGHT at all, and why does it work?
Mitch you had some newer findings on this, right ?
Yes, i figured that the default PRELIGHT color for menu items is hardcoded in a parsed rc string in gtkrc.c, so this mystery is solved. However since GtkMenuItem uses PRELIGHT where it should use SELECTED, we have a problem here. With the patch from this bug which disables PRELIGHT in gtkwidget.c, it is no longer possible to select any menu item. We can hardly change the states of GtkMenuItem since that would break themes and (rarely) code which checks the states, so the change to gtkwidget.c should probably be reverted.
In case it isn't obvious, at one point, menu items in GTK+ were prelighted identically to buttons, not "selected" in a darker color. So using PRELIGHT wasn't weird at all and it wasn't really possible to change it. I pretty much stand by my comment #5 from two years ago; this needs to be done widget by widget. States in GTK+ are too close to being "colors" to make any assumption about what GtkStateType is used for what semantic meaning.
What's the status of this? I'm having the exact same issue using touch-screens and would very much like this patch or something equivalent to be available.
I believe that this is mostly addressed now with touch support in gtk3