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