Attached is slightly edited dual window demo. It changes code so that primary window gets initial focus, and that secondary window places ImGui window over point {0,0}.
Now, when you click into secondary window for the first time (and hold the click longer than single frame), it behaves as if you clicked at {0,0} on the first frame, and then dragged the mouse to wherever you have actually clicked on the next frame.
According to my analysis, this is caused by following code in ImGui::SFML::Update
|
if (!s_currWindowCtx->mouseMoved) |
|
{ |
|
if (sf::Touch::isDown(0)) |
|
s_currWindowCtx->touchPos = sf::Touch::getPosition(0, window); |
|
|
|
Update(s_currWindowCtx->touchPos, sf::Vector2f(target.getSize()), dt); |
|
} |
|
else |
|
{ |
|
Update(sf::Mouse::getPosition(window), sf::Vector2f(target.getSize()), dt); |
|
} |
Particulary the line 502 sets mouse position to s_currWindowCtx->touchPos (which is {0,0}) every frame, when mouse is not moved. I don't understand what the intended logic behind this code was, but this is obviously wrong. I don't have any touch devices, so I can't properly test any PR, unfortunately.
Code (using imgui-sfml v3.0):
#include "imgui.h"
#include "imgui-SFML.h"
#include <SFML/Graphics.hpp>
int main()
{
// EDIT: display child window first
sf::RenderWindow childWindow(sf::VideoMode({640, 480}), "ImGui-SFML Child window");
childWindow.setFramerateLimit(60);
if (!ImGui::SFML::Init(childWindow))
return -1;
childWindow.setPosition({0,800});
sf::RenderWindow window(sf::VideoMode({1280, 720}), "ImGui + SFML = <3");
window.setFramerateLimit(60);
if (!ImGui::SFML::Init(window))
return -1;
window.setPosition({0,0});
sf::Clock deltaClock;
while (window.isOpen())
{
// Main window event processing
while (const auto event = window.pollEvent())
{
ImGui::SFML::ProcessEvent(window, *event);
if (event->is<sf::Event::Closed>())
{
if (childWindow.isOpen())
{
childWindow.close();
}
window.close();
ImGui::SFML::Shutdown();
return 0;
}
}
// Child window event processing
static sf::Color child_window_color = sf::Color::Red;
if (childWindow.isOpen())
{
while (const auto event = childWindow.pollEvent())
{
ImGui::SFML::ProcessEvent(childWindow, *event);
// Workaround: Deliver Event::MouseMoved to ImGui manually
if (auto mm = event->getIf<sf::Event::MouseMoved>()) {
const auto [x, y] = sf::Vector2f(mm->position);
ImGui::GetIO().AddMousePosEvent(x, y);
}
if (event->is<sf::Event::Closed>())
{
childWindow.close();
ImGui::SFML::Shutdown(childWindow);
}
if (event->is<sf::Event::MouseButtonPressed>() && !ImGui::GetIO().WantCaptureMouse)
child_window_color.b ^= 0xFF;
}
}
// Update child window
const sf::Time dt = deltaClock.restart();
ImGui::SFML::Update(window, dt);
if (childWindow.isOpen())
{
ImGui::SFML::Update(childWindow, dt);
}
// Add ImGui widgets in the first window
ImGui::SFML::SetCurrentWindow(window);
ImGui::Begin("Hello, world!");
ImGui::Button("Look at this pretty button");
ImGui::End();
ImGui::ShowDemoWindow();
// Add ImGui widgets in the child window
if (childWindow.isOpen())
{
ImGui::SFML::SetCurrentWindow(childWindow);
// EDIT: make sure ImGui window lies at {0,0}
ImGui::SetNextWindowPos({0,0}, ImGuiCond_Once);
ImGui::Begin("Works in a second window!");
ImGui::Button("Example button");
ImGui::Text("WantCaptureMouse: %s", ImGui::GetIO().WantCaptureMouse ? "true" : "false");
ImGui::End();
}
// Main window drawing
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
window.clear();
window.draw(shape);
ImGui::SFML::Render(window);
window.display();
// Child window drawing
if (childWindow.isOpen())
{
sf::CircleShape shape2(50.f);
shape2.setFillColor(child_window_color);
childWindow.clear();
childWindow.draw(shape2);
ImGui::SFML::Render(childWindow);
childWindow.display();
}
}
}
Demonstration:
https://github.com/user-attachments/assets/f422df29-e0da-402a-914b-c81aa5a0787d
Attached is slightly edited dual window demo. It changes code so that primary window gets initial focus, and that secondary window places ImGui window over point {0,0}.
Now, when you click into secondary window for the first time (and hold the click longer than single frame), it behaves as if you clicked at {0,0} on the first frame, and then dragged the mouse to wherever you have actually clicked on the next frame.
According to my analysis, this is caused by following code in ImGui::SFML::Update
imgui-sfml/imgui-SFML.cpp
Lines 497 to 507 in ab6b5cf
Particulary the line 502 sets mouse position to s_currWindowCtx->touchPos (which is {0,0}) every frame, when mouse is not moved. I don't understand what the intended logic behind this code was, but this is obviously wrong. I don't have any touch devices, so I can't properly test any PR, unfortunately.
Code (using imgui-sfml v3.0):
Demonstration:
https://github.com/user-attachments/assets/f422df29-e0da-402a-914b-c81aa5a0787d