Quellcode durchsuchen

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 vor 10 Jahren
Ursprung
Commit
6285e519f0
7 geänderte Dateien mit 90 neuen und 8 gelöschten Zeilen
  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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 );