ソースを参照

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 11 年 前
コミット
6285e519f0
共有7 個のファイルを変更した90 個の追加8 個の削除を含む
  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 ファイルの表示

3
 project( "slop" )
3
 project( "slop" )
4
 set( slop_VERSION_MAJOR 3 )
4
 set( slop_VERSION_MAJOR 3 )
5
 set( slop_VERSION_MINOR 1 )
5
 set( slop_VERSION_MINOR 1 )
6
-set( slop_VERSION_PATCH 9 )
6
+set( slop_VERSION_PATCH 10 )
7
 
7
 
8
 set( BIN_TARGET     "${PROJECT_NAME}" )
8
 set( BIN_TARGET     "${PROJECT_NAME}" )
9
 set( CMAKE_INSTALL_PREFIX "/usr/bin" )
9
 set( CMAKE_INSTALL_PREFIX "/usr/bin" )

+ 10
- 1
README.md ファイルの表示

82
 help
82
 help
83
 ----
83
 ----
84
 ```text
84
 ```text
85
-slop v3.1.9
85
+slop v3.1.10
86
 
86
 
87
 Copyright (C) 2014 Dalton Nell, Slop Contributors
87
 Copyright (C) 2014 Dalton Nell, Slop Contributors
88
 (https://github.com/naelstrof/slop/graphs/contributors)
88
 (https://github.com/naelstrof/slop/graphs/contributors)
152
     $ Y=$(echo $slopoutput | awk '{print $2}')
152
     $ Y=$(echo $slopoutput | awk '{print $2}')
153
     $ W=$(echo $slopoutput | awk '{print $3}')
153
     $ W=$(echo $slopoutput | awk '{print $3}')
154
     $ H=$(echo $slopoutput | awk '{print $4}')
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 ファイルの表示

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')",
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
   "  -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)",
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
   "  -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')",
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
     0
53
     0
54
 };
54
 };
55
 
55
 

+ 59
- 5
src/main.cpp ファイルの表示

20
 #include <unistd.h>
20
 #include <unistd.h>
21
 #include <cstdio>
21
 #include <cstdio>
22
 #include <sstream>
22
 #include <sstream>
23
+
23
 #include "x.hpp"
24
 #include "x.hpp"
24
 #include "rectangle.hpp"
25
 #include "rectangle.hpp"
25
 #include "cmdline.h"
26
 #include "cmdline.h"
161
     *rey = y + h;
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
 int app( int argc, char** argv ) {
182
 int app( int argc, char** argv ) {
165
     gengetopt_args_info options;
183
     gengetopt_args_info options;
166
     int err = cmdline_parser( argc, argv, &options );
184
     int err = cmdline_parser( argc, argv, &options );
192
     bool keyboard = !options.nokeyboard_flag;
210
     bool keyboard = !options.nokeyboard_flag;
193
     bool decorations = !options.nodecorations_flag;
211
     bool decorations = !options.nodecorations_flag;
194
     timespec start, time;
212
     timespec start, time;
213
+    int xoffset = 0;
214
+    int yoffset = 0;
195
     int cx = 0;
215
     int cx = 0;
196
     int cy = 0;
216
     int cy = 0;
197
     int xmem = 0;
217
     int xmem = 0;
200
     int hmem = 0;
220
     int hmem = 0;
201
     int minimumsize = options.min_arg;
221
     int minimumsize = options.min_arg;
202
     int maximumsize = options.max_arg;
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
     std::string format = options.format_arg;
229
     std::string format = options.format_arg;
204
     cmdline_parser_free( &options );
230
     cmdline_parser_free( &options );
205
 
231
 
228
         xengine->tick();
254
         xengine->tick();
229
         // If the user presses any key on the keyboard, exit the application.
255
         // If the user presses any key on the keyboard, exit the application.
230
         // Make sure at least gracetime has passed before allowing canceling
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
                 printSelection( format, true, 0, 0, 0, 0, None );
286
                 printSelection( format, true, 0, 0, 0, 0, None );
236
                 fprintf( stderr, "User pressed key. Canceled selection.\n" );
287
                 fprintf( stderr, "User pressed key. Canceled selection.\n" );
237
                 state = -1;
288
                 state = -1;
278
                 // Set the mouse position of where we clicked, used so that click tolerance doesn't affect the rectangle's position.
329
                 // Set the mouse position of where we clicked, used so that click tolerance doesn't affect the rectangle's position.
279
                 cx = xengine->m_mousex;
330
                 cx = xengine->m_mousex;
280
                 cy = xengine->m_mousey;
331
                 cy = xengine->m_mousey;
332
+                // Make sure we don't have un-seen applied offsets.
333
+                xoffset = 0;
334
+                yoffset = 0;
281
                 // Also remember where the original selection was
335
                 // Also remember where the original selection was
282
                 if ( selection ) {
336
                 if ( selection ) {
283
                     xmem = selection->m_x;
337
                     xmem = selection->m_x;
343
                 int sx, sy, ex, ey;
397
                 int sx, sy, ex, ey;
344
                 constrain( cx, cy, xengine->m_mousex, xengine->m_mousey, padding, minimumsize, maximumsize, &sx, &sy, &ex, &ey );
398
                 constrain( cx, cy, xengine->m_mousex, xengine->m_mousey, padding, minimumsize, maximumsize, &sx, &sy, &ex, &ey );
345
                 // Set the selection rectangle's dimensions to mouse movement.
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
                 break;
401
                 break;
348
             }
402
             }
349
             case 3: {
403
             case 3: {

+ 5
- 0
src/options.ggo ファイルの表示

85
 text "    $ Y=$(echo $slopoutput | awk '{print $2}')\n"
85
 text "    $ Y=$(echo $slopoutput | awk '{print $2}')\n"
86
 text "    $ W=$(echo $slopoutput | awk '{print $3}')\n"
86
 text "    $ W=$(echo $slopoutput | awk '{print $3}')\n"
87
 text "    $ H=$(echo $slopoutput | awk '{print $4}')\n"
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 ファイルの表示

102
     return EXIT_SUCCESS;
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
 bool slop::XEngine::anyKeyPressed() {
118
 bool slop::XEngine::anyKeyPressed() {
106
     if ( !m_good ) {
119
     if ( !m_good ) {
107
         return false;
120
         return false;

+ 1
- 0
src/x.hpp ファイルの表示

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