<p>One common method is to store the LAST mouse button pressed and then test if the last state was not pressed compared to the current state.</p>
<p>E.g.</p>
<pre><code>bool lastButtonState = false;

void readInput() {
     bool curButtonState = readButton();     

     // Detect &quot;rising&quot; edge of button (AKA, pressed)
     if(curButtonState == true &amp;&amp; curButtonState != lastButtonState) {
         doStuff();
     }

     // Update last state for next call..
     lastButtonState = curButtonState;
}
</code></pre>
<p>You can also detect if the button was released using this method.</p>
<p>e.g.</p>
<pre><code>if(curButtonState == false &amp;&amp; curButtonState != lastButtonState)
    doStuffRelatedToButtonRelease();
</code></pre>
<p>Note: readInput() should be called once per frame because it keeps a copy of the current frames input state.</p>
<p>EDIT: The above example is a general solution, below is a solution specific to GLUT as per your update. You need to use the mouse() function to read the button state, motion() doesn't have the needed button state information. GLUT already tells you if that was pressed (transition from false-&gt;true) or released (transition from true-&gt;false) via the &quot;state&quot; variable.</p>
<pre><code>void mouse(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON) {
        if(state == GLUT_DOWN) 
            onLeftButtonPressed();    // do your thing here..

        // You can also test for (state == GLUT_UP) for mouse button release..
    }
}
</code></pre>

CC BY-SA 4.0
2022-05-12T08:11:05.570Z
Hi Paul, I am a little confused with your answer, I updated my question with the relevant code I'm using. Maybe you could show me your solution in my code?
Arjan Singh
CC BY-SA 4.0
2022-05-12T09:02:32.430Z
Updated with a GLUT specific solution.
PaulHK
CC BY-SA 4.0
2022-05-12T09:08:07.757Z
What you said works but I am getting a lot of drawing lag when I am dragging with the left mouse button down. How could I speed this up? This is related to the bezier curve tool we were discussing on the previous [post](https://computergraphics.stackexchange.com/questions/12677/lines-not-disappearing-after-being-drawn-in-opengl)
Arjan Singh
CC BY-SA 4.0
2022-05-12T09:10:30.223Z
Are you still updating mouse positions from the motion() function ?
PaulHK
CC BY-SA 4.0
2022-05-12T09:11:49.900Z
You need to use both motion()   [to track drags/movement]   and mouse()   [to detect button pressed]    functions.
PaulHK
CC BY-SA 4.0
2022-05-12T09:20:52.137Z
Yes I am using `motion()` to track the drags and `mouse()` to detect the button pressed.
Arjan Singh
CC BY-SA 4.0
2022-05-12T09:22:40.173Z
For your Bezier project, it's probably easier for you to track the current mouse state in a global variable. In mouse() inside the if(button == GLUT_LEFT_BUTTON) block you could capture a snapshot of the current left mouse button state e.g.:   bIsLeftButtonDown = state == GLUT_DOWN;  Then inside your render function you would draw the line for the current editing segment based on this variable. That way you are also controlling the order in which elements are drawn and you don't get out-of-order drawing like you would if that was inside the GLUT input reading functions.
PaulHK
CC BY-SA 4.0
2022-05-12T09:40:37.457Z
Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/136248/discussion-between-arjan-singh-and-paulhk).
Arjan Singh
CC BY-SA 4.0
2022-05-12T08:01:37.483Z
2022-05-12T09:01:14.973Z
2022-05-12T09:01:14.973Z
PaulHK
<p>I am trying to detect when my left mouse button is released to store the result in a boolean variable in OpenGL GLUT. Currently, I am using the <code>motion()</code> function in <code>glutMotionFunc(motion);</code> and setting the boolean variable <code>bool mouseIsHeldDown</code> to true when the left mouse button is held in motion to trigger an if statement in my render function <code>myDisplay()</code>. However, I cannot find an efficient way to find when the left mouse button is released to declare the same variable as false.</p>
<p>Any ideas? Is there a way in Win32?</p>
<pre><code>int main(int argc, char* argv[]) 
{
    ...
    glutMotionFunc(motion);
    ...
}

void motion(int x, int y)
{
    mouseIsHeldDown = true;
}

void myDisplay() 
{
    if (mouseIsHeldDown == true)
    {
        
    }
}
</code></pre>

<opengl><glut>
How to detect when left mouse button is released in GLUT after being held in motion?
Arjan Singh
# How to detect when left mouse button is released in GLUT after being held in motion?

(Asked by: username_0 on 2022-05-12)

I am trying to detect when my left mouse button is released to store the result in a boolean variable in OpenGL GLUT. Currently, I am using the `motion()` function in `glutMotionFunc(motion);` and setting the boolean variable `bool mouseIsHeldDown` to true when the left mouse button is held in motion to trigger an if statement in my render function `myDisplay()`. However, I cannot find an efficient way to find when the left mouse button is released to declare the same variable as false.

Any ideas? Is there a way in Win32?

```
int main(int argc, char* argv[]) 
{
    ...
    glutMotionFunc(motion);
    ...
}

void motion(int x, int y)
{
    mouseIsHeldDown = true;
}

void myDisplay() 
{
    if (mouseIsHeldDown == true)
    {
        
    }
}

```

**Tags:** opengl, glut


---

## 1 answers

### Answer by username_1 on 2022-05-12. Score: 1

One common method is to store the LAST mouse button pressed and then test if the last state was not pressed compared to the current state.

E.g.

```
bool lastButtonState = false;

void readInput() {
     bool curButtonState = readButton();     

     // Detect "rising" edge of button (AKA, pressed)
     if(curButtonState == true && curButtonState != lastButtonState) {
         doStuff();
     }

     // Update last state for next call..
     lastButtonState = curButtonState;
}

```

You can also detect if the button was released using this method.

e.g.

```
if(curButtonState == false && curButtonState != lastButtonState)
    doStuffRelatedToButtonRelease();

```

Note: readInput() should be called once per frame because it keeps a copy of the current frames input state.

EDIT: The above example is a general solution, below is a solution specific to GLUT as per your update. You need to use the mouse() function to read the button state, motion() doesn't have the needed button state information. GLUT already tells you if that was pressed (transition from false->true) or released (transition from true->false) via the "state" variable.

```
void mouse(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON) {
        if(state == GLUT_DOWN) 
            onLeftButtonPressed();    // do your thing here..

        // You can also test for (state == GLUT_UP) for mouse button release..
    }
}

```

> **Comments:**
> **username_0**: Hi Paul, I am a little confused with your answer, I updated my question with the relevant code I'm using. Maybe you could show me your solution in my code?  
> **username_1**: Updated with a GLUT specific solution.  
> **username_0**: What you said works but I am getting a lot of drawing lag when I am dragging with the left mouse button down. How could I speed this up? This is related to the bezier curve tool we were discussing on the previous [post](https://computergraphics.stackexchange.com/questions/12677/lines-not-disappearing-after-being-drawn-in-opengl)  
> **username_1**: Are you still updating mouse positions from the motion() function ?  
> **username_1**: You need to use both motion()   [to track drags/movement]   and mouse()   [to detect button pressed]    functions.  
> **username_0**: Yes I am using `motion()` to track the drags and `mouse()` to detect the button pressed.  
> **username_1**: For your Bezier project, it's probably easier for you to track the current mouse state in a global variable. In mouse() inside the if(button == GLUT_LEFT_BUTTON) block you could capture a snapshot of the current left mouse button state e.g.:   bIsLeftButtonDown = state == GLUT_DOWN;  Then inside your render function you would draw the line for the current editing segment based on this variable. That way you are also controlling the order in which elements are drawn and you don't get out-of-order drawing like you would if that was inside the GLUT input reading functions.  
> **username_0**: Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/136248/discussion-between-username_0-username_0-and-username_1).  

---

