Browse Source

slop now blocks until window is destroyed

naelstrof 7 years ago
parent
commit
170a6d0a80
4 changed files with 45 additions and 34 deletions
  1. 39
    15
      src/slop.cpp
  2. 1
    17
      src/slopstates.cpp
  3. 3
    2
      src/window.cpp
  4. 2
    0
      src/xshaperectangle.cpp

+ 39
- 15
src/slop.cpp View File

120
 
120
 
121
 slop::SlopSelection slop::XShapeSlopSelect( slop::SlopOptions* options, bool* cancelled ) {
121
 slop::SlopSelection slop::XShapeSlopSelect( slop::SlopOptions* options, bool* cancelled ) {
122
     // Init our little state machine, memory is a tad of a misnomer
122
     // Init our little state machine, memory is a tad of a misnomer
123
-    slop::SlopMemory memory( options, new XShapeRectangle(glm::vec2(0,0), glm::vec2(0,0), options->borderSize, options->padding, glm::vec4( options->r, options->g, options->b, options->a ), options->highlight) );
124
-    slop::mouse = new slop::Mouse( x11, options->nodecorations, ((XShapeRectangle*)memory.rectangle)->window );
123
+    slop::SlopMemory* memory = new slop::SlopMemory( options, new XShapeRectangle(glm::vec2(0,0), glm::vec2(0,0), options->borderSize, options->padding, glm::vec4( options->r, options->g, options->b, options->a ), options->highlight) );
124
+    slop::mouse = new slop::Mouse( x11, options->nodecorations, ((XShapeRectangle*)memory->rectangle)->window );
125
 
125
 
126
     // We have no GL context, so the matrix is useless...
126
     // We have no GL context, so the matrix is useless...
127
     glm::mat4 fake;
127
     glm::mat4 fake;
128
     // This is where we'll run through all of our stuffs
128
     // This is where we'll run through all of our stuffs
129
     auto last = std::chrono::high_resolution_clock::now();
129
     auto last = std::chrono::high_resolution_clock::now();
130
-    while( memory.running ) {
130
+    while( memory->running ) {
131
         slop::mouse->update();
131
         slop::mouse->update();
132
         if ( !options->nokeyboard ) {
132
         if ( !options->nokeyboard ) {
133
             slop::keyboard->update();
133
             slop::keyboard->update();
136
         auto current = std::chrono::high_resolution_clock::now();
136
         auto current = std::chrono::high_resolution_clock::now();
137
         std::chrono::duration<double, std::milli> frametime = current-last;
137
         std::chrono::duration<double, std::milli> frametime = current-last;
138
         last = current;
138
         last = current;
139
-        memory.update( frametime.count()/1000.f );
139
+        memory->update( frametime.count()/1000.f );
140
 
140
 
141
         // We don't actually draw anything, but the state machine uses
141
         // We don't actually draw anything, but the state machine uses
142
         // this to know when to spawn the window.
142
         // this to know when to spawn the window.
143
-        memory.draw( fake );
143
+        memory->draw( fake );
144
 
144
 
145
         // X11 explodes if we update as fast as possible, here's a tiny sleep.
145
         // X11 explodes if we update as fast as possible, here's a tiny sleep.
146
         XFlush(x11->display);
146
         XFlush(x11->display);
148
 
148
 
149
         // Then we draw the framebuffer to the screen
149
         // Then we draw the framebuffer to the screen
150
         if ( (!options->nokeyboard && slop::keyboard->anyKeyDown()) || slop::mouse->getButton( 3 ) ) {
150
         if ( (!options->nokeyboard && slop::keyboard->anyKeyDown()) || slop::mouse->getButton( 3 ) ) {
151
-            memory.running = false;
151
+            memory->running = false;
152
             if ( cancelled ) {
152
             if ( cancelled ) {
153
                 *cancelled = true;
153
                 *cancelled = true;
154
             }
154
             }
158
     }
158
     }
159
 
159
 
160
     // Now we should have a selection! We parse everything we know about it here.
160
     // Now we should have a selection! We parse everything we know about it here.
161
-    glm::vec4 output = memory.rectangle->getRect();
161
+    glm::vec4 output = memory->rectangle->getRect();
162
 
162
 
163
     // Lets now clear both front and back buffers before closing.
163
     // Lets now clear both front and back buffers before closing.
164
     // hopefully it'll be completely transparent while closing!
164
     // hopefully it'll be completely transparent while closing!
165
     // Then we clean up.
165
     // Then we clean up.
166
     delete slop::mouse;
166
     delete slop::mouse;
167
+    Window selectedWindow = memory->selectedWindow;
168
+    delete memory;
169
+
170
+    // Try to detect the window dying.
171
+    int tries = 0;
172
+    while( tries < 50 ) {
173
+        XEvent event;
174
+        if ( XCheckTypedEvent( x11->display, UnmapNotify, &event ) ) { break; }
175
+        if ( XCheckTypedEvent( x11->display, DestroyNotify, &event ) ) { break; }
176
+        std::this_thread::sleep_for(std::chrono::milliseconds(10));
177
+        tries++;
178
+    }
167
     // Finally return the data.
179
     // Finally return the data.
168
-    return slop::SlopSelection( output.x, output.y, output.z, output.w, memory.selectedWindow );
180
+    return slop::SlopSelection( output.x, output.y, output.z, output.w, selectedWindow );
169
 }
181
 }
170
 
182
 
171
 slop::SlopSelection slop::GLSlopSelect( slop::SlopOptions* options, bool* cancelled, SlopWindow* window ) {
183
 slop::SlopSelection slop::GLSlopSelect( slop::SlopOptions* options, bool* cancelled, SlopWindow* window ) {
184
         }
196
         }
185
     }
197
     }
186
     // Init our little state machine, memory is a tad of a misnomer
198
     // Init our little state machine, memory is a tad of a misnomer
187
-    slop::SlopMemory memory( options, new GLRectangle(glm::vec2(0,0), glm::vec2(0,0), options->borderSize, options->padding, glm::vec4( options->r, options->g, options->b, options->a ), options->highlight) );
199
+    slop::SlopMemory* memory = new slop::SlopMemory( options, new GLRectangle(glm::vec2(0,0), glm::vec2(0,0), options->borderSize, options->padding, glm::vec4( options->r, options->g, options->b, options->a ), options->highlight) );
188
 
200
 
189
     slop::Framebuffer* pingpong = new slop::Framebuffer(WidthOfScreen(x11->screen), HeightOfScreen(x11->screen));
201
     slop::Framebuffer* pingpong = new slop::Framebuffer(WidthOfScreen(x11->screen), HeightOfScreen(x11->screen));
190
 
202
 
191
     // This is where we'll run through all of our stuffs
203
     // This is where we'll run through all of our stuffs
192
     auto start = std::chrono::high_resolution_clock::now();
204
     auto start = std::chrono::high_resolution_clock::now();
193
     auto last = start;
205
     auto last = start;
194
-    while( memory.running ) {
206
+    while( memory->running ) {
195
         slop::mouse->update();
207
         slop::mouse->update();
196
         if ( !options->nokeyboard ) {
208
         if ( !options->nokeyboard ) {
197
             slop::keyboard->update();
209
             slop::keyboard->update();
200
         auto current = std::chrono::high_resolution_clock::now();
212
         auto current = std::chrono::high_resolution_clock::now();
201
         std::chrono::duration<double, std::milli> frametime = current-last;
213
         std::chrono::duration<double, std::milli> frametime = current-last;
202
         last = current;
214
         last = current;
203
-        memory.update( frametime.count()/1000.f );
215
+        memory->update( frametime.count()/1000.f );
204
 
216
 
205
         // Then we draw our junk to a framebuffer.
217
         // Then we draw our junk to a framebuffer.
206
         window->framebuffer->setShader( textured );
218
         window->framebuffer->setShader( textured );
207
         window->framebuffer->bind();
219
         window->framebuffer->bind();
208
         glClearColor (0.0, 0.0, 0.0, 0.0);
220
         glClearColor (0.0, 0.0, 0.0, 0.0);
209
         glClear (GL_COLOR_BUFFER_BIT);
221
         glClear (GL_COLOR_BUFFER_BIT);
210
-        memory.draw( window->camera );
222
+        memory->draw( window->camera );
211
         window->framebuffer->unbind();
223
         window->framebuffer->unbind();
212
 
224
 
213
         std::chrono::duration<double, std::milli> elapsed = current-start;
225
         std::chrono::duration<double, std::milli> elapsed = current-start;
259
             throw new std::runtime_error( "OpenGL threw an error: " + error );
271
             throw new std::runtime_error( "OpenGL threw an error: " + error );
260
         }
272
         }
261
         if ( (!options->nokeyboard && slop::keyboard->anyKeyDown()) || slop::mouse->getButton( 3 ) ) {
273
         if ( (!options->nokeyboard && slop::keyboard->anyKeyDown()) || slop::mouse->getButton( 3 ) ) {
262
-            memory.running = false;
274
+            memory->running = false;
263
             if ( cancelled ) {
275
             if ( cancelled ) {
264
                 *cancelled = true;
276
                 *cancelled = true;
265
             }
277
             }
269
     }
281
     }
270
 
282
 
271
     // Now we should have a selection! We parse everything we know about it here.
283
     // Now we should have a selection! We parse everything we know about it here.
272
-    glm::vec4 output = memory.rectangle->getRect();
284
+    glm::vec4 output = memory->rectangle->getRect();
273
 
285
 
274
     // Lets now clear both front and back buffers before closing.
286
     // Lets now clear both front and back buffers before closing.
275
     // hopefully it'll be completely transparent while closing!
287
     // hopefully it'll be completely transparent while closing!
281
     // Then we clean up.
293
     // Then we clean up.
282
     delete window;
294
     delete window;
283
     delete slop::mouse;
295
     delete slop::mouse;
296
+    Window selectedWindow = memory->selectedWindow;
297
+    delete memory;
298
+
299
+    // Try to detect the window dying.
300
+    int tries = 0;
301
+    while( tries < 50 ) {
302
+        XEvent event;
303
+        if ( XCheckTypedEvent( x11->display, UnmapNotify, &event ) ) { break; }
304
+        if ( XCheckTypedEvent( x11->display, DestroyNotify, &event ) ) { break; }
305
+        std::this_thread::sleep_for(std::chrono::milliseconds(10));
306
+        tries++;
307
+    }
284
     // Finally return the data.
308
     // Finally return the data.
285
-    return slop::SlopSelection( output.x, output.y, output.z, output.w, memory.selectedWindow );
309
+    return slop::SlopSelection( output.x, output.y, output.z, output.w, selectedWindow );
286
 }
310
 }

+ 1
- 17
src/slopstates.cpp View File

88
 
88
 
89
 void slop::SlopStartDrag::onEnter( SlopMemory& memory ) {
89
 void slop::SlopStartDrag::onEnter( SlopMemory& memory ) {
90
     memory.rectangle->setPoints(startPoint, startPoint);
90
     memory.rectangle->setPoints(startPoint, startPoint);
91
-    repeatTimer = 0;
92
-    multiplier = 1;
93
 }
91
 }
94
 
92
 
95
 void slop::SlopStartDrag::update( SlopMemory& memory, double dt ) {
93
 void slop::SlopStartDrag::update( SlopMemory& memory, double dt ) {
115
     if ( !mouse->getButton( 1 ) ) {
113
     if ( !mouse->getButton( 1 ) ) {
116
         memory.setState( (SlopState*)new SlopEndDrag() );
114
         memory.setState( (SlopState*)new SlopEndDrag() );
117
     }
115
     }
118
-    int arrows[2];
119
-    arrows[0] = keyboard->getKey(XK_Down)-keyboard->getKey(XK_Up);
120
-    arrows[1] = keyboard->getKey(XK_Right)-keyboard->getKey(XK_Left);
121
-    if ( arrows[0] || arrows[1] ) {
122
-        if ( repeatTimer == 0 || repeatTimer > .4 ) {
123
-            startPoint.y += arrows[0]*multiplier;
124
-            startPoint.x += arrows[1]*multiplier;
125
-        }
126
-        if ( repeatTimer > 1 ) {
127
-            multiplier += dt*2;
128
-        }
129
-        repeatTimer += dt;
130
-    } else {
131
-        repeatTimer = 0;
132
-        multiplier = 1;
116
+    if ( keyboard->getKey( XK_Down ) ) {
133
     }
117
     }
134
 }
118
 }
135
 
119
 

+ 3
- 2
src/window.cpp View File

48
     // Disable window decorations.
48
     // Disable window decorations.
49
     attributes.override_redirect = True;
49
     attributes.override_redirect = True;
50
     // Make sure we know when we've been successfully destroyed later!
50
     // Make sure we know when we've been successfully destroyed later!
51
-    //attributes.event_mask = StructureNotifyMask;
52
-    unsigned long valueMask = CWOverrideRedirect | CWColormap | CWBackPixmap | CWBorderPixel;
51
+    attributes.event_mask = StructureNotifyMask;
52
+    unsigned long valueMask = CWOverrideRedirect | CWColormap | CWBackPixmap | CWBorderPixel | CWEventMask;
53
 
53
 
54
 
54
 
55
     // Create the window
55
     // Create the window
118
     glClear( GL_COLOR_BUFFER_BIT );
118
     glClear( GL_COLOR_BUFFER_BIT );
119
     display();
119
     display();
120
     glXDestroyContext( x11->display, context );
120
     glXDestroyContext( x11->display, context );
121
+    XUnmapWindow( x11->display, window );
121
     XDestroyWindow( x11->display, window );
122
     XDestroyWindow( x11->display, window );
122
 }
123
 }
123
 
124
 

+ 2
- 0
src/xshaperectangle.cpp View File

113
 }
113
 }
114
 
114
 
115
 slop::XShapeRectangle::~XShapeRectangle() {
115
 slop::XShapeRectangle::~XShapeRectangle() {
116
+    XUnmapWindow( x11->display, window );
117
+    XDestroyWindow( x11->display, window );
116
 }
118
 }
117
 
119
 
118
 void slop::XShapeRectangle::draw( glm::mat4& matrix ) {
120
 void slop::XShapeRectangle::draw( glm::mat4& matrix ) {