Browse Source

Fixed a lot of accuracy issues.

It was due to the mouse in X11 selecting pixels one left and one above where you actually can put the mouse,
and doing some window border math wrong.
This caused you to be incapable of selecting the whole screen since the mouse can't position itself completely in the lower right corner,
and judging a window's reported size wrong.
I also made the tolerance option more functional; setting it to 0 will disable window selections.
Because of this I also removed the --nowindow option.
naelstrof 11 years ago
parent
commit
e078d082ca
3 changed files with 40 additions and 25 deletions
  1. 39
    19
      main.cpp
  2. 1
    5
      options.cpp
  3. 0
    1
      options.hpp

+ 39
- 19
main.cpp View File

24
     timespec start, time;
24
     timespec start, time;
25
     int cx = 0;
25
     int cx = 0;
26
     int cy = 0;
26
     int cy = 0;
27
+    int cxoffset = 0;
28
+    int cyoffset = 0;
29
+    int woffset = 0;
30
+    int hoffset = 0;
27
 
31
 
28
     // First we set up the x interface and grab the mouse,
32
     // First we set up the x interface and grab the mouse,
29
     // if we fail for either we exit immediately.
33
     // if we fail for either we exit immediately.
93
                 // If xengine has found a window we're hovering over (or if it changed)
97
                 // If xengine has found a window we're hovering over (or if it changed)
94
                 // create a rectangle around it so the user knows he/she can click on it.
98
                 // create a rectangle around it so the user knows he/she can click on it.
95
                 // --but only if the user wants us to
99
                 // --but only if the user wants us to
96
-                if ( window != xengine->m_hoverXWindow && options->m_window ) {
100
+                if ( window != xengine->m_hoverXWindow && tolerance > 0 ) {
97
                     // Make sure to delete the old selection rectangle.
101
                     // Make sure to delete the old selection rectangle.
98
                     if ( windowselection ) {
102
                     if ( windowselection ) {
99
                         xengine->removeRect( windowselection ); // removeRect also dealloc's the rectangle for us.
103
                         xengine->removeRect( windowselection ); // removeRect also dealloc's the rectangle for us.
101
                     slop::WindowRectangle t = xengine->m_hoverWindow;
105
                     slop::WindowRectangle t = xengine->m_hoverWindow;
102
                     windowselection = new slop::Rectangle( t.m_x - t.m_border,
106
                     windowselection = new slop::Rectangle( t.m_x - t.m_border,
103
                                                          t.m_y - t.m_border,
107
                                                          t.m_y - t.m_border,
104
-                                                         t.m_width + t.m_border,
105
-                                                         t.m_height + t.m_border,
108
+                                                         t.m_width + t.m_border * 2,
109
+                                                         t.m_height + t.m_border * 2,
106
                                                          borderSize, padding,
110
                                                          borderSize, padding,
107
                                                          r, g, b );
111
                                                          r, g, b );
108
                     xengine->addRect( windowselection );
112
                     xengine->addRect( windowselection );
133
                     break;
137
                     break;
134
                 }
138
                 }
135
                 // Check to make sure the user actually wants to drag for a selection before creating a rectangle.
139
                 // Check to make sure the user actually wants to drag for a selection before creating a rectangle.
136
-                int w = xengine->m_mousex - cx + 1;
137
-                int h = xengine->m_mousey - cy + 1;
138
-                if ( ( std::abs( w ) > tolerance || std::abs( h ) > tolerance ) && !selection ) {
140
+                int w = xengine->m_mousex - cx;
141
+                int h = xengine->m_mousey - cy;
142
+                if ( ( std::abs( w ) >= tolerance || std::abs( h ) >= tolerance ) && !selection ) {
139
                     selection = new slop::Rectangle( cx, cy, 0, 0, borderSize, padding, r, g, b );
143
                     selection = new slop::Rectangle( cx, cy, 0, 0, borderSize, padding, r, g, b );
140
                     xengine->addRect( selection );
144
                     xengine->addRect( selection );
141
-                } else if ( std::abs( w ) <= tolerance && std::abs( h ) <= tolerance ) {
145
+                } else if ( !selection ) {
142
                     continue;
146
                     continue;
143
                 }
147
                 }
144
-                // Set the selection rectangle's dimensions to mouse movement.
145
-                // We use the function setDim since rectangles can't have negative widths,
146
-                // and because the rectangles have borders and padding to worry about.
147
-                selection->setDim( w, h );
148
                 // We also detect which way the user is pulling and set the mouse icon accordingly.
148
                 // We also detect which way the user is pulling and set the mouse icon accordingly.
149
+                // and offset the rectangle to be accurate, this is because the mouse actually selects a pixel up and to the left.
149
                 bool x = selection->m_flippedx;
150
                 bool x = selection->m_flippedx;
150
                 bool y = selection->m_flippedy;
151
                 bool y = selection->m_flippedy;
151
                 if ( !x && !y ) {
152
                 if ( !x && !y ) {
153
+                    cxoffset = 0;
154
+                    cyoffset = 0;
155
+                    woffset = 1;
156
+                    hoffset = 1;
152
                     xengine->setCursor( slop::LowerRightCorner );
157
                     xengine->setCursor( slop::LowerRightCorner );
153
                 } else if ( x && !y ) {
158
                 } else if ( x && !y ) {
159
+                    cxoffset = 1;
160
+                    cyoffset = 0;
161
+                    woffset = -1;
162
+                    hoffset = 1;
154
                     xengine->setCursor( slop::LowerLeftCorner );
163
                     xengine->setCursor( slop::LowerLeftCorner );
155
                 } else if ( !x && y ) {
164
                 } else if ( !x && y ) {
165
+                    cxoffset = 0;
166
+                    cyoffset = 1;
167
+                    woffset = 1;
168
+                    hoffset = -1;
156
                     xengine->setCursor( slop::UpperRightCorner );
169
                     xengine->setCursor( slop::UpperRightCorner );
157
                 } else {
170
                 } else {
171
+                    cxoffset = 1;
172
+                    cyoffset = 1;
173
+                    woffset = -1;
174
+                    hoffset = -1;
158
                     xengine->setCursor( slop::UpperLeftCorner );
175
                     xengine->setCursor( slop::UpperLeftCorner );
159
                 }
176
                 }
160
-
177
+                // Set the selection rectangle's dimensions to mouse movement.
178
+                // We use the function setDim since rectangles can't have negative widths,
179
+                // and because the rectangles have borders and padding to worry about.
180
+                selection->setPos( cx + cxoffset, cy + cyoffset );
181
+                selection->setDim( w + woffset, h + hoffset );
161
                 break;
182
                 break;
162
             }
183
             }
163
             case 3: {
184
             case 3: {
174
                     h = selection->m_height;
195
                     h = selection->m_height;
175
                     // Delete the rectangle.
196
                     // Delete the rectangle.
176
                     xengine->removeRect( selection );
197
                     xengine->removeRect( selection );
177
-                    // If the user simply clicked (and thus made the width and height smaller than
178
-                    // our tolerance) or if we're not hovering over a window, just print the selection
179
-                    // rectangle's stuff.
180
-                    if ( w > tolerance || h > tolerance || xengine->m_hoverXWindow == None ) {
198
+                    // if we're not hovering over a window, or our selection is larger than our tolerance
199
+                    // just print the selection.
200
+                    if ( w >= tolerance || h >= tolerance || xengine->m_hoverXWindow == None ) {
181
                         printf( "X=%i\n", x );
201
                         printf( "X=%i\n", x );
182
                         printf( "Y=%i\n", y );
202
                         printf( "Y=%i\n", y );
183
                         printf( "W=%i\n", w );
203
                         printf( "W=%i\n", w );
187
                 }
207
                 }
188
                 // Otherwise lets grab the window's dimensions and use those (with padding).
208
                 // Otherwise lets grab the window's dimensions and use those (with padding).
189
                 // --but only if the user lets us, if the user doesn't just select a single pixel there.
209
                 // --but only if the user lets us, if the user doesn't just select a single pixel there.
190
-                if ( options->m_window ) {
210
+                if ( tolerance > 0 ) {
191
                     slop::WindowRectangle t = xengine->m_hoverWindow;
211
                     slop::WindowRectangle t = xengine->m_hoverWindow;
192
                     x = t.m_x - padding - t.m_border;
212
                     x = t.m_x - padding - t.m_border;
193
                     y = t.m_y - padding - t.m_border;
213
                     y = t.m_y - padding - t.m_border;
194
-                    w = t.m_width + t.m_border + padding*2;
195
-                    h = t.m_height + t.m_border + padding*2;
214
+                    w = t.m_width + t.m_border * 2 + padding*2;
215
+                    h = t.m_height + t.m_border * 2 + padding*2;
196
                 } else {
216
                 } else {
197
                     x = cx;
217
                     x = cx;
198
                     y = cy;
218
                     y = cy;

+ 1
- 5
options.cpp View File

12
     m_blue = 0;
12
     m_blue = 0;
13
     m_gracetime = 0.1;
13
     m_gracetime = 0.1;
14
     m_keyboard = true;
14
     m_keyboard = true;
15
-    m_window = true;
16
 }
15
 }
17
 
16
 
18
 void slop::Options::printHelp() {
17
 void slop::Options::printHelp() {
24
     printf( "    -nkb, --nokeyboard             don't try to grab the keyboard. This may fix problems with certain window managers.\n" );
23
     printf( "    -nkb, --nokeyboard             don't try to grab the keyboard. This may fix problems with certain window managers.\n" );
25
     printf( "    -b=INT, --bordersize=INT       set selection rectangle border size.\n" );
24
     printf( "    -b=INT, --bordersize=INT       set selection rectangle border size.\n" );
26
     printf( "    -p=INT, --padding=INT          set padding size for selection.\n" );
25
     printf( "    -p=INT, --padding=INT          set padding size for selection.\n" );
27
-    printf( "    -t=INT, --tolerance=INT        if you have a shaky mouse, increasing this value will make slop detect single clicks better. Rather than interpreting your shaky clicks as region selections.\n" );
26
+    printf( "    -t=INT, --tolerance=INT        if you have a shaky mouse, increasing this value will make slop detect single clicks better. Rather than interpreting your shaky clicks as region selections. Setting to zero will disable window selections.\n" );
28
     printf( "    -x=STRING, --xdisplay=STRING   set x display (STRING must be hostname:number.screen_number format)\n" );
27
     printf( "    -x=STRING, --xdisplay=STRING   set x display (STRING must be hostname:number.screen_number format)\n" );
29
     printf( "    -c=COLOR, --color=COLOR        set selection rectangle color, COLOR is in format FLOAT,FLOAT,FLOAT\n" );
28
     printf( "    -c=COLOR, --color=COLOR        set selection rectangle color, COLOR is in format FLOAT,FLOAT,FLOAT\n" );
30
     printf( "    -g=FLOAT, --gracetime=FLOAT    set the amount of time before slop will check for keyboard cancellations in seconds.\n" );
29
     printf( "    -g=FLOAT, --gracetime=FLOAT    set the amount of time before slop will check for keyboard cancellations in seconds.\n" );
31
-    printf( "    -nw, --nowindow                disable automatically selecting a whole window on single-clicks, and instead just select a single pixel.\n" );
32
     printf( "examples\n" );
30
     printf( "examples\n" );
33
     printf( "    slop -b=10 -x=:0 -p=-30 -t=4 -c=0.5,0.5,0.5 -g=.2\n" );
31
     printf( "    slop -b=10 -x=:0 -p=-30 -t=4 -c=0.5,0.5,0.5 -g=.2\n" );
34
 }
32
 }
79
             }
77
             }
80
         } else if ( matches( arg, "-nkb", "--nokeyboard" ) ) {
78
         } else if ( matches( arg, "-nkb", "--nokeyboard" ) ) {
81
             m_keyboard = false;
79
             m_keyboard = false;
82
-        } else if ( matches( arg, "-nw", "--nowindow" ) ) {
83
-            m_window = false;
84
         } else if ( matches( arg, "-h", "--help" ) ) {
80
         } else if ( matches( arg, "-h", "--help" ) ) {
85
             printHelp();
81
             printHelp();
86
             return 2;
82
             return 2;

+ 0
- 1
options.hpp View File

20
     std::string m_xdisplay;
20
     std::string m_xdisplay;
21
     float       m_gracetime;
21
     float       m_gracetime;
22
     bool        m_keyboard;
22
     bool        m_keyboard;
23
-    bool        m_window;
24
 private:
23
 private:
25
     int         parseInt( std::string arg, int* returnInt );
24
     int         parseInt( std::string arg, int* returnInt );
26
     int         parseFloat( std::string arg, float* returnFloat );
25
     int         parseFloat( std::string arg, float* returnFloat );