|
@@ -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: {
|