GNOME Bugzilla – Bug 154260
Support _NET_WM_MOUSE_ACTION EWMH extension
Last modified: 2018-02-10 04:40:06 UTC
The _NET_WM_TAKE_ACTIVITY extension was added to the EWMH in order to handle special cases when raising on click shouldn't happen (and perhaps could also be used to handle special cases when focusing on click shouldn't happen). The email detailing this extension can be found at http://mail.gnome.org/archives/wm-spec-list/2004-April/msg00013.html along with an example patch showing the how the toolkit side of things could be implemented. I have also filed bug 152952 for the Metacity side of things. (It also has a gtk+ patch against gtk-2-4, which I have been running with for a week and a half of testing) I will attach the gtk+ patch against HEAD in a moment. It's suboptimal since it hardcodes the drag-and-drop threshold. That's pretty lame, but I thought calling a gtk function from gdk was worse, and I didn't know what to pass for the GtkWidget parameter of gtk_drag_check_threshold anyway. What would be the correct way to handle this? Also, it would be nice to have some API that would allow setting display_x11->tracking_take_activity_info to FALSE (see comment 6 of bug 152952 for the reason). What would a good function name be for that? gdk_x11_dont_focus_for_current_click () ? I'm hoping that we can get this extension--including the API addition--added for gtk+-2.6. I realize that API freeze for gtk+ is approaching quickly, so that might not be possible. But if it is, I'll try to quickly make any changes you suggest.
Created attachment 32147 [details] [review] Support _NET_WM_TAKE_ACTIVITY EWMH extension
Created attachment 32359 [details] Some possibly related Windows APIs The last 40 or so lines of http://www.gtk.org/plan/meetings/20041005.txt contains some comments about the above patch; this attachment represents my attempts at trying to learn some relevant related Windows APIs. *shrug*
Created attachment 32361 [details] [review] Move drag checking into the gtk layer, but just for GtkRange's for now The other major comment from that IRC meeting was that Owen wanted to see the drag checking move to the gtk layer instead of being in the gdk layer. Here's a patch that does that and that I've tested...but only does so for GtkRange's so far. I'm pasting it here so I can get feedback because I'm not sure I'm going about things correctly. So... comments?
I don't see immediately how the MSDN references are the right one ... we aren't talking about DND here, we are talking about window activation ... how you could handle a mouse click without activating and raising the window. (From a quick look at the patch, if the user clicks without any motion on a scrollbar, presumably it should raise and activate...)
Um, yeah, I'll keep looking. My patch does that. If I click on a scrollbar and release without moving the mouse, then the window is raised and focused. If I move the mouse between ButtonPress and ButtonRelease, the window is not raised or focused.
The way it works in windows is as follows. I'll use as an example an explorer window. On a mouse click, the window is immediately raised and activated if the click is on a non-sensitive area of the window, such as an area with no icons If you click on an icon, however, the raise does not happen until button release if you click without dragging. Ideally a scrollbar click should immediately raise and activate the window, as should any widget click that isn't a potential drag and drop start. It'd be nice if we could do something like make the titlebar a valid drag target for something like a nautilus window, and also make the tasklist a valid drag target also so that you could hover your mouse over a tasklist entry while dragging a file and have it pop up the appropriate window. Don't know how far this spec gets us towards that goal.
Yeah, I'd like to make our behavior like that--though _NET_WM_TAKE_ACTIVITY doesn't currently allow it (Lubos' proposal specifies that the client MUST wait for ButtonRelease, which I think is wrong; it should be able to return a pong immediately if the ButtonPress is where a drag can't happen). I need to email the wm-spec-list about this but haven't yet. Why do you want to have a scrollbar click immediately raise and activate the window? That sounds backward to me. "Activate on click, not click-and-drag" is basically how I was envisioning this feature. Obviously, if there's nothing to be dragged then go ahead and activate, but a scrollbar is draggable. This spec assists with not raising DnD source windows, which is helpful so that the source window doesn't obscure the target one unexpectedly. However, I agree that we really do need another complementary spec in order to raise DnD target windows.
A scrollbar isn't really draggable. You can't grab the scrollbar and drop it into another window. You can use it to scroll the window, sure, but you can't use it to interact with a totally different window, unless the application is very strange indeed. Similarly in a drawing program where you can drag objects around on the canvas. You can move them around with the mouse, but that's not interwindow drag and drop.
I didn't say it was droppable, just draggable. Though, I'm guessing we're just using different definitions. Note that Lubos mentioned in his proposal that a take-activity-pong message wouldn't be returned for scrollbar sliding and text selection in addition to DnD, so if you really do want ButtonPresses on scrollbars to always result in activation then you'll need to get the spec modified. Personally, I like that part of the spec as it is.
You're missing the point: Why would you want windows not to activate when you scroll them? Especially when they're going to get raised on button release anyway? There's no possible interaction that would be aided by failing to raise on scrollbar drags...
You're missing the point: I don't want the windows activated _at all_ if the scrollbar has been moved--not during the moving, and not after the ButtonRelease. I only want the window activated if the scrollbar was not moved between ButtonPress and ButtonRelease. Now, I may be a weird case. I admit that I am. I prefer a do-not-raise-on-unmodified-click environment (even for clicking on a button which can't be moved at all) which is an environment that is very bad for the majority of users; it's basically just crack. But _NET_WM_TAKE_ACTIVTY is _not_ just about drag and drop. See comments 15, 16, and 64 in bug 86108 by Havoc where he explicitly lists selection as another reason to not activate a window (this makes cutting and pasting from a lowered window to another window easier; I think the scrollbar is part of this--I want to be able to scroll to some text that I want to cut and paste in another raised window and having instant raise can make that more difficult than it needs to be). Besides, even if I agreed that ButtonPresses on scrollbars should result in activation, we couldn't do anything about that here. Lubos wrote the proposal and the proposal includes moving scrollbars. Havoc asked for the proposal to be committed to the spec. If you think the proposal is wrong, we need to get the proposal itself changed.
Elijah - OK, I didn't read your patch closely enough. Rob - scrolling windows without raising them is a fairly frequent request for people who work with multiple overlapping windows. It somewhat similar to another request - which is to be able to scroll a scrollbar in an insensitive window. ("Fairly frequent request" doesn't mean that a behavior is right, but it does indicate that there is some point.)
Created attachment 32372 [details] [review] Cover some more cases I was wrong before, I handled GtkRange's, plus generic DnD. I've now tested and dragging icons from nautilus works well. This patch adds support for GtkEntry's and GtkTextView's. I've tested the GtkEntry text selection in a couple different apps and the textview stuff in gedit. I also have a patch to get things to work for text selection in gnome-terminal and will fill a bug against vte for that and mark it as dependent on this bug momentarily.
Created attachment 32475 [details] [review] Support _NET_WM_MOUSE_ACTION (instead of _NET_WM_TAKE_ACTIVITY) Okay, as the discussion Rob and I had above showed, _NET_WM_TAKE_ACTIVITY clearly forces policy into the toolkit instead of allowing the window manager to decide it. It appears there are other cases where it would be nice to just move the policy to the window manger. So, I proposed a new message type at http://mail.gnome.org/archives/wm-spec-list/2004-October/msg00008.html to replace TAKE_ACTIVITY Advantages of the newer proposal: - Policy free for toolkits (WMs decide whether and when to raise/lower/focus, and it can be different for different types of actions (DND, moving sliders, text selection, etc.)) - Supports raising on ButtonPress, not just ButtonRelease - Forces all the work into the GTK layer, instead of GDK, as Owen wanted - Extendible Disadvantage of the newer proposal: - More work--can't use a hack like my original patch It appears that Lubos doesn't like the extra work, so I'd love to hear comments (especially if you could post to the wm-spec-list on how we might reduce the work or why doing more work may or may not be a good thing). Anyway, this patch combined with the Metacity one I will post to bug 152952 in a minute is enough to start trying it out (I only have support for a few widgets so far but adding more is pretty easy--nautilus, for example, was a two line patch to get working)
in case you somehow missed the spam, I just did a 2.8.6 release and branched metacity. Time to start going crazy.
oops sorry, should have made that comment on the metacity bug.
Created attachment 32530 [details] [review] Updated patch The _NET_WM_MOUSE_ACTION proposal changed slightly due to comments on the wm-spec-list (see http://mail.gnome.org/archives/wm-spec-list/2004-October/msg00014.html for the newest version). This incorporates the changes and also makes sure that I'm actually passing toplevel GdkWindows like I'm supposed to.
Oh, I forgot to mention one thing. Bug 152952 has a new patch that helps with debugging, especially with finding widgets that aren't calling gdk_window_begin_mouse_action() and friends but need to.
Created attachment 32567 [details] [review] Fix some incomplete support in gtkdnd.c and gtktextview; add some debugging aids I'm sure that gdk_window_begin_mouse_action(), gdk_window_end_mouse_action(), and gdk_window_mouse_motion_occurred() is all the API we need and is the right API (unless, of course, you guys disagree with the names). However, it appears that API slush-freeze is very soon and there haven't been many comments. Is this feature out of the question for gtk+-2.6, or is it still a possibility?
I don't think this is making gtk+-2.6. I haven't worked on it since my last post, and API slush freeze has already occurred. Chris Kelso has expressed interest in working on it, though, so maybe we will have something for early gtk+-2.7. :-)
Elijah, what is the status of this work ? Do you think there is a chance to get mouse_action to replace take_focus, or are lubos and olivier sold on take_focus ? Is there a simple translation to implement take_focus in terms of mouse_action ?
Do you mean take_activity when you say take_focus? If no, what do you mean by take_focus? If yes, I believe Lubos is fine with mouse_action instead of take_activity (see http://mail.gnome.org/archives/wm-spec-list/2004-October/msg00018.html, though I never heard back and I never posted myself again). One can easily implement take_activity-like behavior using mouse_action by: 1) sending MOUSE_ACTION_MISC messages for all button presses 2) if there's not "threshold" mouse movement before release, send a MOUSE_ACTION_NONE message upon ButtonRelease (the equivalent of sending a _NET_WM_TAKE_ACTIVITY message back; should result in the window being raised, though of course it's up to the WM) 3) if there is "threshold" mouse movement before release, send a MOUSE_ACTION_MISC message upon Buttonrelease (which, assuming the Window Manager doesn't want to raise on any threshold behavior, is equivalent to not sending any message back with _NET_WM_TAKE_ACTIVITY) I haven't worked on this for a while. One of the more aggravating things about these particular patches for mouse_action is that they are sort of all-or-nothing. If one widget is missing support, then clicking on that widget doesn't result in the window being raised as expected. (With lots of widgets missing support, but some having it, things are really nasty) What would be nice is to have GDK have a default where MOUSE_ACTION_MISC messages are sent on ButtonPress and to send MOUSE_ACTION_NONE messages on ButtonRelease if the widget doesn't handle sending mouse_action messages itself. That way widgets would behave no worse than they do now, and when they get further support for mouse_action then they behave even better. That was going to be my next plan of attack (when I get the time...), though I'm not quite sure how to do that. Slightly off-topic: It would also be nice if we could look at solving the complementary bug 112308 (cue window manager when the mouse enters a window during a DND operation) at the same time, since both of these bugs are primarily for improving the DND experience for users. (For the ambitious, bug 135056 has another item to consider--allowing WM keybinding operations (such as alt-tab) during DND))
Not going to happen for 2.8
Ping.
I've been derailed on this by other stuff (release-team work, metacity, libwnck, bugzilla)...it'll be a few months before I get to take a look at it again. I had an idea of perhaps just implementing part of the work, by trying to just detect DND starts/stops and sending MOUSE_ACTION_DND messages for those, and doing MOUSE_ACTION_MISC/NONE for everything else. That'd cover every sane usage of the MOUSE_ACTION stuff anyway... I'll go ahead and mark the relevant patches as needs-work to get them off the unreviewed patch list.
No point pinging unless you have something new to provide for people to look at... ;-)
Created attachment 65055 [details] [review] Only support the DND part of the mouse_action stuff Unlike previous mouse_action patches, this one (when combined with the updated patches I'll soon attach to bug 152952 and bug 155106) is functional. It needs to be cleaned up code-wise (in more ways than one), but I'm guessing that won't take very much time. The main difference in this patch is that I decided to simplify by only implementing the DND part of the MOUSE_ACTION proposal (since that's pretty much all we're interested in anyway). Combined with a simple check in gtk_main_do_event() to make sure a message gets sent out for every ButtonPress/ButtonRelease, this has several advantages: - Far fewer widgets have to be modified (i.e. much less invasive to gtk and outside widgets like vte). - The only widgets that need to be modified are the ones that will benefit from the new feature...and even if the affected widgets aren't modified, it just means they get the old raise-on-button-press behavior. - Avoids the (major) regressions found in the previous patches; it results in the wanted improvements only. - If apps use gtk_drag_source_set() for DND, they won't need any extra customization. - Apps that do their own DND setup (grep for calls to gtk_drag_begin() to find such apps), only need to make a single function call (gdk_window_end_mouse_action(), currently) in their ButtonPress handler to obtain the do-not-raise-on-button-press-of-DND behavior. See the patch I'm about to attach to bug 155106 for an example. Issues with the code: - I mostly reused the old stuff I had; we probably want to simplify the proposal on wm-spec list to only include DND stuff (since no one is likely to implement anything else) and have the code reflect that - I have lots of functions polluting the global namespace when only gdk_window_end_mouse_action() is needed outside gtk+. - I assume that ButtonReleases always follow ButtonPress events before more ButtonPress events come in; but (sane) mice have more than one button so this isn't true. - I'm not all that familiar with the gtk+ code in question; nor with any relevant win32 or osx apis.
My time seems to have disappeared, so this is probably something more suited to the gtk-2-11 timescale now...
Any progress?
Nope, no work has been done at all since I posted comment 28.
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.