Browse Source

Fixed a case where slop couldn't grab the mouse due to the window manager already having it grabbed due to a key combination being pressed. Slop simply waits for the duration of --gracetime in order for the key combination to be released, thus freeing up the mouse.

Dalton Nell 9 years ago
parent
commit
f6e72a937b
5 changed files with 33 additions and 5 deletions
  1. 1
    1
      CMakeLists.txt
  2. 1
    1
      README.md
  3. 1
    1
      src/main.cpp
  4. 29
    1
      src/x.cpp
  5. 1
    1
      src/x.hpp

+ 1
- 1
CMakeLists.txt View File

@@ -3,7 +3,7 @@ cmake_minimum_required( VERSION 2.8 )
3 3
 project( "slop" )
4 4
 set( slop_VERSION_MAJOR 4 )
5 5
 set( slop_VERSION_MINOR 1 )
6
-set( slop_VERSION_PATCH 15 )
6
+set( slop_VERSION_PATCH 16 )
7 7
 
8 8
 set( BIN_TARGET     "${PROJECT_NAME}" )
9 9
 if( NOT CMAKE_INSTALL_PREFIX )

+ 1
- 1
README.md View File

@@ -87,7 +87,7 @@ Make sure to check out and install [maim](https://github.com/naelstrof/maim) too
87 87
 help
88 88
 ----
89 89
 ```text
90
-slop v4.1.15
90
+slop v4.1.16
91 91
 
92 92
 Copyright (C) 2014 Dalton Nell, Slop Contributors
93 93
 (https://github.com/naelstrof/slop/graphs/contributors)

+ 1
- 1
src/main.cpp View File

@@ -277,7 +277,7 @@ int app( int argc, char** argv ) {
277 277
         fprintf( stderr, "  Try updating X and making sure you have XExtensions installed. (/usr/lib/libXext.so, /usr/include/X11/extensions/shape.h)\n" );
278 278
         return EXIT_FAILURE;
279 279
     }
280
-    err = xengine->grabCursor( slop::Cross );
280
+    err = xengine->grabCursor( slop::Cross, gracetime );
281 281
     if ( err != EXIT_SUCCESS ) {
282 282
         printSelection( format, true, 0, 0, 0, 0, None );
283 283
         return EXIT_FAILURE;

+ 29
- 1
src/x.cpp View File

@@ -176,7 +176,10 @@ void slop::XEngine::selectAllInputs( Window win, long event_mask) {
176 176
 }
177 177
 
178 178
 // Grabs the cursor, be wary that setCursor changes the mouse masks.
179
-int slop::XEngine::grabCursor( slop::CursorType type ) {
179
+// waittime is how long grabCursor can repeatedly try to grab the cursor, if it fails to grab.
180
+// This is because tiling window managers like i3 grab the mouse while holding down certain keys,
181
+// while these certain keys also launch slop.
182
+int slop::XEngine::grabCursor( slop::CursorType type, double waittime ) {
180 183
     if ( !m_good ) {
181 184
         return EXIT_FAILURE;
182 185
     }
@@ -184,8 +187,33 @@ int slop::XEngine::grabCursor( slop::CursorType type ) {
184 187
     int err = XGrabPointer( m_display, m_root, True,
185 188
                             PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
186 189
                             GrabModeAsync, GrabModeAsync, None, xfontcursor, CurrentTime );
190
+    double accumulationtime = 0;
191
+    int timestep = 10000; // in microseconds
192
+    while ( err != GrabSuccess && accumulationtime < waittime ) {
193
+        err = XGrabPointer( m_display, m_root, True,
194
+                            PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
195
+                            GrabModeAsync, GrabModeAsync, None, xfontcursor, CurrentTime );
196
+        usleep( timestep );
197
+        accumulationtime += double( timestep/1000000.f );
198
+    }
187 199
     if ( err != GrabSuccess ) {
188 200
         fprintf( stderr, "Error: Failed to grab X cursor.\n" );
201
+        switch( err ) {
202
+            case 1:
203
+                fprintf( stderr, "       The cursor is already grabbed by another application.\n" );
204
+                break;
205
+            case 2:
206
+                fprintf( stderr, "       The cursor grab was initiated at an invalid time (in the past?) .\n" );
207
+                break;
208
+            case 3:
209
+                fprintf( stderr, "       The cursor is not viewable or outside of the bounds of the root window.\n" );
210
+                break;
211
+            case 4:
212
+                fprintf( stderr, "       The grab is frozen already by an active grab by another application.\n" );
213
+                break;
214
+            default:
215
+                break;
216
+        }
189 217
         fprintf( stderr, "       This can be caused by launching slop weirdly.\n" );
190 218
         return EXIT_FAILURE;
191 219
     }

+ 1
- 1
src/x.hpp View File

@@ -70,7 +70,7 @@ public:
70 70
                         ~XEngine();
71 71
     int                 init( std::string display );
72 72
     void                tick();
73
-    int                 grabCursor( slop::CursorType type );
73
+    int                 grabCursor( slop::CursorType type, double waittime );
74 74
     int                 grabKeyboard();
75 75
     bool                anyKeyPressed();
76 76
     bool                keyPressed( KeySym key );