Browse Source

Added ability to move starting points of selections with arrow keys, and made pressing enter accept the current selection rather than cancel it.

Dalton Nell 10 years ago
parent
commit
6285e519f0
7 changed files with 90 additions and 8 deletions
  1. 1
    1
      CMakeLists.txt
  2. 10
    1
      README.md
  3. 1
    1
      src/cmdline.c
  4. 59
    5
      src/main.cpp
  5. 5
    0
      src/options.ggo
  6. 13
    0
      src/x.cpp
  7. 1
    0
      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 3 )
5 5
 set( slop_VERSION_MINOR 1 )
6
-set( slop_VERSION_PATCH 9 )
6
+set( slop_VERSION_PATCH 10 )
7 7
 
8 8
 set( BIN_TARGET     "${PROJECT_NAME}" )
9 9
 set( CMAKE_INSTALL_PREFIX "/usr/bin" )

+ 10
- 1
README.md View File

@@ -82,7 +82,7 @@ Make sure to check out and install [maim](https://github.com/naelstrof/maim) too
82 82
 help
83 83
 ----
84 84
 ```text
85
-slop v3.1.9
85
+slop v3.1.10
86 86
 
87 87
 Copyright (C) 2014 Dalton Nell, Slop Contributors
88 88
 (https://github.com/naelstrof/slop/graphs/contributors)
@@ -152,4 +152,13 @@ Examples
152 152
     $ Y=$(echo $slopoutput | awk '{print $2}')
153 153
     $ W=$(echo $slopoutput | awk '{print $3}')
154 154
     $ H=$(echo $slopoutput | awk '{print $4}')
155
+
156
+Tips
157
+    * You can use the arrow keys to move the starting point of a
158
+drag-selection, just in case you missed it by a few pixels.
159
+    * If you don't like a selection: you can cancel it by right-clicking
160
+regardless of which options are enabled or disabled for slop.
161
+    * If slop doesn't seem to select a window accurately, the problem could be
162
+because of decorations getting in the way. Try enabling the --nodecorations
163
+flag.
155 164
 ```

+ 1
- 1
src/cmdline.c View File

@@ -49,7 +49,7 @@ const char *gengetopt_args_info_help[] = {
49 49
   "      --max=INT                 Set the maximum output of width or height\n                                  values. Setting min and max to the same value\n                                  disables drag selections.  (default=`0')",
50 50
   "  -l, --highlight               Instead of outlining selections, slop\n                                  highlights it. This is only useful when\n                                  --color is set to a transparent color.\n                                  (default=off)",
51 51
   "  -f, --format=STRING           Set the output format string. Format specifiers\n                                  are %x, %y, %w, %h, %i, %g, and %c.\n                                  (default=`X=%x\\nY=%y\\nW=%w\\nH=%h\\nG=%g\\nID=%i\\nCancel=%c\\n')",
52
-  "\nExamples\n    $ # Gray, thick, transparent border for maximum visiblity.\n    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n\n    $ # Remove window decorations.\n    $ slop --nodecorations\n\n    $ # Disable window selections. Useful for selecting individual pixels.\n    $ slop -t 0\n\n    $ # Classic Windows XP selection.\n    $ slop -l -c 0.3,0.4,0.6,0.4\n\n    $ # Change output format to use safer parsing\n    $ slopoutput=$(slop -f \"%x %y %w %h\")\n    $ X=$(echo $slopoutput | awk '{print $1}')\n    $ Y=$(echo $slopoutput | awk '{print $2}')\n    $ W=$(echo $slopoutput | awk '{print $3}')\n    $ H=$(echo $slopoutput | awk '{print $4}')\n",
52
+  "\nExamples\n    $ # Gray, thick, transparent border for maximum visiblity.\n    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n\n    $ # Remove window decorations.\n    $ slop --nodecorations\n\n    $ # Disable window selections. Useful for selecting individual pixels.\n    $ slop -t 0\n\n    $ # Classic Windows XP selection.\n    $ slop -l -c 0.3,0.4,0.6,0.4\n\n    $ # Change output format to use safer parsing\n    $ slopoutput=$(slop -f \"%x %y %w %h\")\n    $ X=$(echo $slopoutput | awk '{print $1}')\n    $ Y=$(echo $slopoutput | awk '{print $2}')\n    $ W=$(echo $slopoutput | awk '{print $3}')\n    $ H=$(echo $slopoutput | awk '{print $4}')\n\nTips\n    * You can use the arrow keys to move the starting point of a\ndrag-selection, just in case you missed it by a few pixels.\n    * If you don't like a selection: you can cancel it by right-clicking\nregardless of which options are enabled or disabled for slop.\n    * If slop doesn't seem to select a window accurately, the problem could be\nbecause of decorations getting in the way. Try enabling the --nodecorations\nflag.\n",
53 53
     0
54 54
 };
55 55
 

+ 59
- 5
src/main.cpp View File

@@ -20,6 +20,7 @@
20 20
 #include <unistd.h>
21 21
 #include <cstdio>
22 22
 #include <sstream>
23
+
23 24
 #include "x.hpp"
24 25
 #include "rectangle.hpp"
25 26
 #include "cmdline.h"
@@ -161,6 +162,23 @@ void constrain( int sx, int sy, int ex, int ey, int padding, int minimumsize, in
161 162
     *rey = y + h;
162 163
 }
163 164
 
165
+// Some complicated key detection to replicate key repeating
166
+bool keyRepeat( KeySym key, double curtime, double repeatdelay, double* time, bool* memory ) {
167
+    if ( xengine->keyPressed( key ) != *memory ) {
168
+        if ( xengine->keyPressed( key ) ) {
169
+            *memory = true;
170
+            *time = curtime;
171
+            return true;
172
+        } else {
173
+            *memory = false;
174
+        }
175
+    }
176
+    if ( xengine->keyPressed( key ) && curtime - *time > repeatdelay ) {
177
+        return true;
178
+    }
179
+    return false;
180
+}
181
+
164 182
 int app( int argc, char** argv ) {
165 183
     gengetopt_args_info options;
166 184
     int err = cmdline_parser( argc, argv, &options );
@@ -192,6 +210,8 @@ int app( int argc, char** argv ) {
192 210
     bool keyboard = !options.nokeyboard_flag;
193 211
     bool decorations = !options.nodecorations_flag;
194 212
     timespec start, time;
213
+    int xoffset = 0;
214
+    int yoffset = 0;
195 215
     int cx = 0;
196 216
     int cy = 0;
197 217
     int xmem = 0;
@@ -200,6 +220,12 @@ int app( int argc, char** argv ) {
200 220
     int hmem = 0;
201 221
     int minimumsize = options.min_arg;
202 222
     int maximumsize = options.max_arg;
223
+    bool pressedMemory[4];
224
+    double pressedTime[4];
225
+    for ( int i=0;i<4;i++ ) {
226
+        pressedMemory[ i ] = false;
227
+        pressedTime[ i ] = 0;
228
+    }
203 229
     std::string format = options.format_arg;
204 230
     cmdline_parser_free( &options );
205 231
 
@@ -228,10 +254,35 @@ int app( int argc, char** argv ) {
228 254
         xengine->tick();
229 255
         // If the user presses any key on the keyboard, exit the application.
230 256
         // Make sure at least gracetime has passed before allowing canceling
231
-        double timei = double( time.tv_sec*1000000000L + time.tv_nsec )/1000000000.f;
232
-        double starti = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
233
-        if ( timei - starti > gracetime ) {
234
-            if ( ( xengine->anyKeyPressed() && keyboard ) || xengine->mouseDown( 3 ) ) {
257
+        double curtime = double( time.tv_sec*1000000000L + time.tv_nsec )/1000000000.f;
258
+        double starttime = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
259
+        if ( curtime - starttime > gracetime ) {
260
+            if ( keyRepeat( XK_Up, curtime, 0.5, &pressedTime[ 0 ], &pressedMemory[ 0 ] ) ) {
261
+                yoffset -= 1;
262
+            }
263
+            if ( keyRepeat( XK_Down, curtime, 0.5, &pressedTime[ 1 ], &pressedMemory[ 1 ] ) ) {
264
+                yoffset += 1;
265
+            }
266
+            if ( keyRepeat( XK_Left, curtime, 0.5, &pressedTime[ 2 ], &pressedMemory[ 2 ] ) ) {
267
+                xoffset -= 1;
268
+            }
269
+            if ( keyRepeat( XK_Right, curtime, 0.5, &pressedTime[ 3 ], &pressedMemory[ 3 ] ) ) {
270
+                xoffset += 1;
271
+            }
272
+            // If we pressed enter we move the state onward.
273
+            if ( xengine->keyPressed( XK_Return ) ) {
274
+                // If we're highlight windows, just select the active window.
275
+                if ( state == 0 ) {
276
+                    state = 1;
277
+                // If we're making a custom selection, select the custom selection.
278
+                } else if ( state == 2 ) {
279
+                    state = 3;
280
+                }
281
+            }
282
+            // If we press any key other than the arrow keys or enter key, we shut down!
283
+            if ( !( xengine->keyPressed( XK_Up ) || xengine->keyPressed( XK_Down ) || xengine->keyPressed( XK_Left ) || xengine->keyPressed( XK_Right ) ) &&
284
+                !( xengine->keyPressed( XK_Return ) ) &&
285
+                ( ( xengine->anyKeyPressed() && keyboard ) || xengine->mouseDown( 3 ) ) ) {
235 286
                 printSelection( format, true, 0, 0, 0, 0, None );
236 287
                 fprintf( stderr, "User pressed key. Canceled selection.\n" );
237 288
                 state = -1;
@@ -278,6 +329,9 @@ int app( int argc, char** argv ) {
278 329
                 // Set the mouse position of where we clicked, used so that click tolerance doesn't affect the rectangle's position.
279 330
                 cx = xengine->m_mousex;
280 331
                 cy = xengine->m_mousey;
332
+                // Make sure we don't have un-seen applied offsets.
333
+                xoffset = 0;
334
+                yoffset = 0;
281 335
                 // Also remember where the original selection was
282 336
                 if ( selection ) {
283 337
                     xmem = selection->m_x;
@@ -343,7 +397,7 @@ int app( int argc, char** argv ) {
343 397
                 int sx, sy, ex, ey;
344 398
                 constrain( cx, cy, xengine->m_mousex, xengine->m_mousey, padding, minimumsize, maximumsize, &sx, &sy, &ex, &ey );
345 399
                 // Set the selection rectangle's dimensions to mouse movement.
346
-                selection->setGeo( sx, sy, ex, ey );
400
+                selection->setGeo( sx + xoffset, sy + yoffset, ex, ey );
347 401
                 break;
348 402
             }
349 403
             case 3: {

+ 5
- 0
src/options.ggo View File

@@ -85,3 +85,8 @@ text "    $ X=$(echo $slopoutput | awk '{print $1}')\n"
85 85
 text "    $ Y=$(echo $slopoutput | awk '{print $2}')\n"
86 86
 text "    $ W=$(echo $slopoutput | awk '{print $3}')\n"
87 87
 text "    $ H=$(echo $slopoutput | awk '{print $4}')\n"
88
+
89
+text "\nTips\n"
90
+text "    * You can use the arrow keys to move the starting point of a drag-selection, just in case you missed it by a few pixels.\n"
91
+text "    * If you don't like a selection: you can cancel it by right-clicking regardless of which options are enabled or disabled for slop.\n"
92
+text "    * If slop doesn't seem to select a window accurately, the problem could be because of decorations getting in the way. Try enabling the --nodecorations flag.\n"

+ 13
- 0
src/x.cpp View File

@@ -102,6 +102,19 @@ int slop::XEngine::init( std::string display ) {
102 102
     return EXIT_SUCCESS;
103 103
 }
104 104
 
105
+bool slop::XEngine::keyPressed( KeySym key ) {
106
+    KeyCode keycode = XKeysymToKeycode( m_display, key );
107
+    if ( keycode != 0 ) {
108
+        // Get the whole keyboard state
109
+        char keys[32];
110
+        XQueryKeymap( m_display, keys );
111
+        // Check our keycode
112
+        return ( keys[ keycode / 8 ] & ( 1 << ( keycode % 8 ) ) ) != 0;
113
+    } else {
114
+        return false;
115
+    }
116
+}
117
+
105 118
 bool slop::XEngine::anyKeyPressed() {
106 119
     if ( !m_good ) {
107 120
         return false;

+ 1
- 0
src/x.hpp View File

@@ -73,6 +73,7 @@ public:
73 73
     int                 grabCursor( slop::CursorType type );
74 74
     int                 grabKeyboard();
75 75
     bool                anyKeyPressed();
76
+    bool                keyPressed( KeySym key );
76 77
     int                 releaseCursor();
77 78
     int                 releaseKeyboard();
78 79
     void                setCursor( slop::CursorType type );