Bladeren bron

fixed a few bugs and added window selections

naelstrof 11 jaren geleden
bovenliggende
commit
a4afa890fe
4 gewijzigde bestanden met toevoegingen van 135 en 27 verwijderingen
  1. 7
    3
      README.md
  2. 51
    9
      main.cpp
  3. 64
    15
      x.cpp
  4. 13
    0
      x.hpp

+ 7
- 3
README.md Bestand weergeven

1
 slrn
1
 slrn
2
-----
2
+====
3
 
3
 
4
 slrn is an application that literally just allows a user to select a region of his screen. It grabs the cursor, draws a fancy box, and prints the selection's dimensions and position to stdout.
4
 slrn is an application that literally just allows a user to select a region of his screen. It grabs the cursor, draws a fancy box, and prints the selection's dimensions and position to stdout.
5
 
5
 
6
-It does a better job than scrot's selection since it doesn't draw directly to the root window, it creates its own to draw the selection rectangle.
7
-However due to the X11's Shape extension and window resizing not being synchronized it doesn't render a perfect box during movement. I'm hoping to fix this later by never resizing the window.
6
+features
7
+--------
8
+* Clicking on a window makes slrn return the dimensions of the window.
9
+* Clicking and dragging causes a selection rectangle to appear, renders pretty well (compared to scrot). And will return the dimensions of that rectangle in absolute screen coords.
10
+* Hovering over a window will cause a selection rectangle to appear over it.
11
+* On startup it turns your cursor into a crosshair, then adjusts the cursor into angles as you drag the selection rectangle.

+ 51
- 9
main.cpp Bestand weergeven

5
     int state = 0;
5
     int state = 0;
6
     bool running = true;
6
     bool running = true;
7
     is::Rectangle* selection;
7
     is::Rectangle* selection;
8
+    is::Rectangle* windowselection = NULL;
9
+    Window window = None;
8
 
10
 
9
     xengine->init( ":0" );
11
     xengine->init( ":0" );
10
     xengine->grabCursor( is::Cross );
12
     xengine->grabCursor( is::Cross );
11
     while ( running ) {
13
     while ( running ) {
12
         xengine->tick();
14
         xengine->tick();
15
+        if ( xengine->mouseDown( 3 ) ) {
16
+            printf( "X: 0\n" );
17
+            printf( "Y: 0\n" );
18
+            printf( "W: 0\n" );
19
+            printf( "H: 0\n" );
20
+            printf( "User right-clicked. Canceled selection.\n" );
21
+            state = -1;
22
+            running = false;
23
+        }
13
         switch ( state ) {
24
         switch ( state ) {
25
+            default: {
26
+                break;
27
+            }
14
             case 0: {
28
             case 0: {
29
+                if ( window != xengine->m_hoverXWindow ) {
30
+                    if ( windowselection ) {
31
+                        xengine->removeRect( windowselection );
32
+                    }
33
+                    is::WindowRectangle t = xengine->m_hoverWindow;
34
+                    windowselection = new is::Rectangle( t.m_x,
35
+                                                         t.m_y,
36
+                                                         t.m_width,
37
+                                                         t.m_height,
38
+                                                         10, 0 );
39
+                    xengine->addRect( windowselection );
40
+                    window = xengine->m_hoverXWindow;
41
+                }
15
                 if ( xengine->mouseDown( 1 ) ) {
42
                 if ( xengine->mouseDown( 1 ) ) {
43
+                    if ( windowselection ) {
44
+                        xengine->removeRect( windowselection );
45
+                    }
16
                     state++;
46
                     state++;
17
                 }
47
                 }
18
                 break;
48
                 break;
19
             }
49
             }
20
             case 1: {
50
             case 1: {
21
-                // Check to make sure we actually have a cursor position before creating the selection rectangle.
22
-                if ( xengine->m_mousex == -1 ) {
23
-                    break;
24
-                }
25
-                selection = new is::Rectangle( xengine->m_mousex, xengine->m_mousey, 1, 1, 10, 0 );
51
+                selection = new is::Rectangle( xengine->m_mousex, xengine->m_mousey, 0, 0, 10, 0 );
26
                 selection->setPos( xengine->m_mousex, xengine->m_mousey );
52
                 selection->setPos( xengine->m_mousex, xengine->m_mousey );
27
                 xengine->addRect( selection );
53
                 xengine->addRect( selection );
28
                 state++;
54
                 state++;
50
                 break;
76
                 break;
51
             }
77
             }
52
             case 3: {
78
             case 3: {
53
-                printf( "X: %i\n", selection->m_x+selection->m_xoffset );
54
-                printf( "Y: %i\n", selection->m_y+selection->m_yoffset );
55
-                printf( "W: %i\n", selection->m_width + 1 );
56
-                printf( "H: %i\n", selection->m_height + 1 );
79
+                int x = selection->m_x+selection->m_xoffset;
80
+                int y = selection->m_y+selection->m_yoffset;
81
+                int w = selection->m_width;
82
+                int h = selection->m_height;
57
                 xengine->removeRect( selection );
83
                 xengine->removeRect( selection );
58
                 running = false;
84
                 running = false;
85
+                if ( w || h || xengine->m_hoverXWindow == None ) {
86
+                    printf( "X: %i\n", x );
87
+                    printf( "Y: %i\n", y );
88
+                    printf( "W: %i\n", w + 1 );
89
+                    printf( "H: %i\n", h + 1 );
90
+                    break;
91
+                }
92
+                is::WindowRectangle t = xengine->m_hoverWindow;
93
+                x = t.m_x;
94
+                y = t.m_y;
95
+                w = t.m_width + t.m_border;
96
+                h = t.m_height + t.m_border;
97
+                printf( "X: %i\n", x );
98
+                printf( "Y: %i\n", y );
99
+                printf( "W: %i\n", w );
100
+                printf( "H: %i\n", h );
59
                 break;
101
                 break;
60
             }
102
             }
61
         }
103
         }

+ 64
- 15
x.cpp Bestand weergeven

9
     m_good = false;
9
     m_good = false;
10
     m_mousex = -1;
10
     m_mousex = -1;
11
     m_mousey = -1;
11
     m_mousey = -1;
12
+    m_hoverXWindow = None;
12
 }
13
 }
13
 
14
 
14
 is::XEngine::~XEngine() {
15
 is::XEngine::~XEngine() {
76
         printf( "Failed to grab X cursor\n" );
77
         printf( "Failed to grab X cursor\n" );
77
         return 1;
78
         return 1;
78
     }
79
     }
80
+
81
+    // Quickly set the mouse position so we don't have to worry about x11 generating an event.
82
+    Window root, child;
83
+    int mx, my;
84
+    int wx, wy;
85
+    unsigned int mask;
86
+    XQueryPointer( m_display, m_root, &root, &child, &mx, &my, &wx, &wy, &mask );
87
+    m_mousex = mx;
88
+    m_mousex = my;
89
+    updateHoverWindow( child );
79
     return 0;
90
     return 0;
80
 }
91
 }
81
 
92
 
91
     if ( !m_good ) {
102
     if ( !m_good ) {
92
         return;
103
         return;
93
     }
104
     }
94
-    XFlush( m_display );
105
+    XSync( m_display, false );
95
     XEvent event;
106
     XEvent event;
96
     while ( XPending( m_display ) ) {
107
     while ( XPending( m_display ) ) {
97
         XNextEvent( m_display, &event );
108
         XNextEvent( m_display, &event );
119
                 }
130
                 }
120
                 break;
131
                 break;
121
             }
132
             }
133
+            default: break;
122
         }
134
         }
123
     }
135
     }
136
+
137
+    // Since I couldn't get Xlib to send a EnterNotify or LeaveNotify events, we need to query the underlying window every frame.
138
+    updateHoverWindow();
124
 }
139
 }
125
 
140
 
126
 Cursor is::XEngine::getCursor( is::CursorType type ) {
141
 Cursor is::XEngine::getCursor( is::CursorType type ) {
153
     }
168
     }
154
     Cursor xfontcursor = getCursor( type );
169
     Cursor xfontcursor = getCursor( type );
155
     XChangeActivePointerGrab( m_display,
170
     XChangeActivePointerGrab( m_display,
156
-                              ButtonMotionMask | ButtonPressMask | ButtonReleaseMask,
171
+                              PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
157
                               xfontcursor, CurrentTime );
172
                               xfontcursor, CurrentTime );
158
 }
173
 }
159
 
174
 
181
         m_yoffset += m_height;
196
         m_yoffset += m_height;
182
         m_height = -m_height;
197
         m_height = -m_height;
183
     }
198
     }
184
-    if ( m_width == 0 ) {
185
-        m_width = 1;
186
-    }
187
-    if ( m_height == 0 ) {
188
-        m_height = 1;
189
-    }
190
 
199
 
191
     XAllocNamedColor( xengine->m_display, xengine->m_colormap, "black", &m_forground, &m_forgroundExact );
200
     XAllocNamedColor( xengine->m_display, xengine->m_colormap, "black", &m_forground, &m_forgroundExact );
192
     XAllocNamedColor( xengine->m_display, xengine->m_colormap, "white", &m_background, &m_backgroundExact );
201
     XAllocNamedColor( xengine->m_display, xengine->m_colormap, "white", &m_background, &m_backgroundExact );
200
                               CWSaveUnder | CWOverrideRedirect |
209
                               CWSaveUnder | CWOverrideRedirect |
201
                               CWColormap;
210
                               CWColormap;
202
 
211
 
203
-    m_window = XCreateWindow( xengine->m_display, xengine->m_root, m_x+m_xoffset, m_y+m_yoffset, m_width+m_border*2, m_height+m_border*2,
212
+    m_window = XCreateWindow( xengine->m_display, xengine->m_root, m_x-m_border+m_xoffset, m_y-m_border+m_yoffset, m_width+m_border*2, m_height+m_border*2,
204
                               0, CopyFromParent, InputOutput,
213
                               0, CopyFromParent, InputOutput,
205
                               CopyFromParent, valueMask, &attributes );
214
                               CopyFromParent, valueMask, &attributes );
206
     XRectangle rect;
215
     XRectangle rect;
240
         m_yoffset += h;
249
         m_yoffset += h;
241
         m_height = -h;
250
         m_height = -h;
242
     }
251
     }
243
-    if ( m_width == 0 ) {
244
-        m_width = 1;
245
-    }
246
-    if ( m_height == 0 ) {
247
-        m_height = 1;
248
-    }
249
     XResizeWindow( xengine->m_display, m_window, m_width+m_border*2, m_height+m_border*2 );
252
     XResizeWindow( xengine->m_display, m_window, m_width+m_border*2, m_height+m_border*2 );
250
     XMoveWindow( xengine->m_display, m_window, m_x-m_border+m_xoffset, m_y-m_border+m_yoffset );
253
     XMoveWindow( xengine->m_display, m_window, m_x-m_border+m_xoffset, m_y-m_border+m_yoffset );
251
     // Now punch another hole in it.
254
     // Now punch another hole in it.
264
 
267
 
265
 void is::Rectangle::draw() {
268
 void is::Rectangle::draw() {
266
 }
269
 }
270
+
271
+void is::XEngine::updateHoverWindow() {
272
+    Window root, child;
273
+    int mx, my;
274
+    int wx, wy;
275
+    unsigned int mask;
276
+    XQueryPointer( m_display, m_root, &root, &child, &mx, &my, &wx, &wy, &mask );
277
+    if ( m_hoverXWindow == child ) {
278
+        return;
279
+    }
280
+    for ( unsigned int i=0; i<m_rects.size(); i++ ) {
281
+        if ( m_rects.at( i )->m_window == child ) {
282
+            return;
283
+        }
284
+    }
285
+    m_hoverXWindow = child;
286
+    if ( child == None ) {
287
+        return;
288
+    }
289
+    unsigned int depth;
290
+    XGetGeometry( m_display, child, &root,
291
+                  &(m_hoverWindow.m_x), &(m_hoverWindow.m_y),
292
+                  &(m_hoverWindow.m_width), &(m_hoverWindow.m_height),
293
+                  &(m_hoverWindow.m_border), &depth );
294
+}
295
+
296
+void is::XEngine::updateHoverWindow( Window child ) {
297
+    if ( m_hoverXWindow == child ) {
298
+        return;
299
+    }
300
+    for ( unsigned int i=0; i<m_rects.size(); i++ ) {
301
+        if ( m_rects.at( i )->m_window == child ) {
302
+            return;
303
+        }
304
+    }
305
+    m_hoverXWindow = child;
306
+    if ( child == None ) {
307
+        return;
308
+    }
309
+    unsigned int depth;
310
+    Window root;
311
+    XGetGeometry( m_display, child, &root,
312
+                  &(m_hoverWindow.m_x), &(m_hoverWindow.m_y),
313
+                  &(m_hoverWindow.m_width), &(m_hoverWindow.m_height),
314
+                  &(m_hoverWindow.m_border), &depth );
315
+}

+ 13
- 0
x.hpp Bestand weergeven

25
     LowerLeftCorner
25
     LowerLeftCorner
26
 };
26
 };
27
 
27
 
28
+class WindowRectangle {
29
+public:
30
+    int m_x;
31
+    int m_y;
32
+    unsigned int m_width;
33
+    unsigned int m_height;
34
+    unsigned int m_border;
35
+};
36
+
28
 class Rectangle {
37
 class Rectangle {
29
 public:
38
 public:
30
             Rectangle( int x, int y, int width, int height, int border, int padding );
39
             Rectangle( int x, int y, int width, int height, int border, int padding );
66
     int                 m_mousey;
75
     int                 m_mousey;
67
     std::vector<bool>   m_mouse;
76
     std::vector<bool>   m_mouse;
68
     bool                mouseDown( unsigned int button );
77
     bool                mouseDown( unsigned int button );
78
+    WindowRectangle     m_hoverWindow;
79
+    Window              m_hoverXWindow;
69
 private:
80
 private:
81
+    void                updateHoverWindow();
82
+    void                updateHoverWindow( Window child );
70
     bool                m_good;
83
     bool                m_good;
71
     std::vector<Cursor> m_cursors;
84
     std::vector<Cursor> m_cursors;
72
     std::vector<Rectangle*> m_rects;
85
     std::vector<Rectangle*> m_rects;