Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/audiograph/source/ui/PluginEditorWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class PluginEditorWindow final : public yup::DocumentWindow
{
return yup::ComponentNative::Options()
.withResizableWindow (editor != nullptr && editor->isResizable())
.withFramerateRedraw (0)
.withFramerateRedraw (0.0f)
.withRenderContinuous (false);
}

Expand Down
6 changes: 6 additions & 0 deletions modules/yup_core/native/yup_Files_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ YUP_END_IGNORE_WARNINGS_GCC_LIKE
//==============================================================================
yup::String toLongPath (const yup::String& path)
{
if (path.startsWith (String (L"\\\\?\\")))
return path;

if (path.startsWith (String (L"\\\\")))
return L"\\\\?\\UNC" + path.substring (1);

return L"\\\\?\\" + path;
}

Expand Down
34 changes: 30 additions & 4 deletions modules/yup_graphics/native/yup_GraphicsContext_d3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ class LowLevelRenderContextD3D : public GraphicsContext
scd.BufferCount = 2;
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

fprintf (stderr, "D3D: CreateSwapChainForHwnd hwnd=%p size=%dx%d\n", window, width, height);
fflush (stderr);

VERIFY_OK (m_d3dFactory->CreateSwapChainForHwnd (m_gpu.Get(),
(HWND) window,
&scd,
Expand Down Expand Up @@ -117,9 +120,18 @@ class LowLevelRenderContextD3D : public GraphicsContext
else
{
ComPtr<ID3D11Texture2D> backbuffer;
VERIFY_OK (m_swapchain->GetBuffer (0,
__uuidof (ID3D11Texture2D),
reinterpret_cast<void**> (backbuffer.ReleaseAndGetAddressOf())));
HRESULT hr = m_swapchain->GetBuffer (0,
__uuidof (ID3D11Texture2D),
reinterpret_cast<void**> (backbuffer.ReleaseAndGetAddressOf()));

if (FAILED (hr))
{
auto reason = m_gpu->GetDeviceRemovedReason();
fprintf (stderr, "D3D: GetBuffer failed: hr=0x%08X, deviceRemovedReason=0x%08X\n", static_cast<unsigned> (hr), static_cast<unsigned> (reason));
fflush (stderr);
m_renderTarget->setTargetTexture (nullptr);
return;
}

m_renderTarget->setTargetTexture (backbuffer);
}
Expand All @@ -130,7 +142,21 @@ class LowLevelRenderContextD3D : public GraphicsContext
m_renderContext->flush (flushDesc);

if (! m_isHeadless)
m_swapchain->Present (0, 0);
{
HRESULT hr = m_swapchain->Present (0, 0);

if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
auto reason = m_gpu->GetDeviceRemovedReason();
fprintf (stderr, "D3D: Present returned device removed/reset: hr=0x%08X, deviceRemovedReason=0x%08X\n", static_cast<unsigned> (hr), static_cast<unsigned> (reason));
fflush (stderr);
}
else if (FAILED (hr))
{
fprintf (stderr, "D3D: Present failed: hr=0x%08X\n", static_cast<unsigned> (hr));
fflush (stderr);
}
}

m_renderTarget->setTargetTexture (nullptr);
}
Expand Down
62 changes: 56 additions & 6 deletions modules/yup_gui/menus/yup_PopupMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ void installGlobalMouseListener()
{
const auto globalPos = event.getScreenPosition();
if (auto* popupMenu = findActivePopupAt (globalPos))
{
YUP_MODULE_DBG (GUI_POPUPMENU, "GlobalMouseListener::mouseMove: dispatching to popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (popupMenu)) << " globalPos=" << globalPos.toString());
popupMenu->mouseMove (makePopupMouseEvent (event, *popupMenu, globalPos));
}
}
} globalMouseListener {};

Expand Down Expand Up @@ -457,6 +460,8 @@ PopupMenu::Ptr PopupMenu::create (const Options& options)

void PopupMenu::dismissAllPopups()
{
YUP_MODULE_DBG (GUI_POPUPMENU, "dismissAllPopups: count=" << activePopups.size());

auto popupsToClose = std::exchange (activePopups, {});

for (const auto& popup : popupsToClose)
Expand Down Expand Up @@ -721,6 +726,8 @@ void PopupMenu::show (std::function<void (int)> callback)

void PopupMenu::showCustom (const Options& options, bool isSubmenu, std::function<void (int)> callback)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "showCustom: isSubmenu=" << (isSubmenu ? 1 : 0) << " isOnDesktop=" << (isOnDesktop() ? 1 : 0) << " numItems=" << getNumItems() << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

if (! isSubmenu)
dismissAllPopups();

Expand Down Expand Up @@ -755,7 +762,10 @@ void PopupMenu::showCustom (const Options& options, bool isSubmenu, std::functio
.withMouseCapture (true);

if (! isOnDesktop())
{
YUP_MODULE_DBG (GUI_POPUPMENU, "showCustom: adding to desktop [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
addToDesktop (nativeOptions);
}
}

removeActivePopup (this);
Expand All @@ -766,6 +776,8 @@ void PopupMenu::showCustom (const Options& options, bool isSubmenu, std::functio

setVisible (true);
toFront (true);

YUP_MODULE_DBG (GUI_POPUPMENU, "showCustom EXIT: visible=" << (isVisible() ? 1 : 0) << " size=" << getWidth() << "x" << getHeight() << " screenBounds=" << getScreenBounds().toString() << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
}

//==============================================================================
Expand All @@ -780,6 +792,8 @@ void PopupMenu::dismiss (int itemID)
if (isBeingDismissed)
return;

YUP_MODULE_DBG (GUI_POPUPMENU, "dismiss: itemID=" << itemID << " isOnDesktop=" << (isOnDesktop() ? 1 : 0) << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

isBeingDismissed = true;

hideSubmenus();
Expand Down Expand Up @@ -898,6 +912,8 @@ void PopupMenu::mouseMove (const MouseEvent& event)

if (itemIndex >= 0 && isItemSelectable (itemIndex))
{
YUP_MODULE_DBG (GUI_POPUPMENU, "mouseMove: itemIndex=" << itemIndex << " (" << items[itemIndex]->text << ") [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

// Set selection on hover for selectable items
setSelectedItemIndex (itemIndex, true);

Expand All @@ -917,6 +933,8 @@ void PopupMenu::mouseMove (const MouseEvent& event)
}
else if (itemIndex < 0)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "mouseMove: itemIndex=" << itemIndex << " (no item) [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

// Mouse is not over any item, clear selection
setSelectedItemIndex (-1, true);
}
Expand All @@ -925,18 +943,24 @@ void PopupMenu::mouseMove (const MouseEvent& event)
void PopupMenu::mouseEnter (const MouseEvent& event)
{
int itemIndex = getItemIndexAt (event.getPosition());
YUP_MODULE_DBG (GUI_POPUPMENU, "mouseEnter: itemIndex=" << itemIndex << " hasVisibleSubmenu=" << (hasVisibleSubmenu() ? 1 : 0) << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

if (itemIndex >= 0 && isItemSelectable (itemIndex))
{
setSelectedItemIndex (itemIndex, true);

auto& item = *items[itemIndex];
if (item.isSubMenu() && item.isEnabled)
showSubmenu (itemIndex);
}
}

void PopupMenu::mouseExit (const MouseEvent& event)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "mouseExit: hasVisibleSubmenu=" << (hasVisibleSubmenu() ? 1 : 0) << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

// Don't clear the hover if we're showing a submenu — the mouse likely
// "left" due to a submenu window appearing on top, not because the user
// intentionally moved away. updateSubmenuVisibility keeps submenus open.
if (hasVisibleSubmenu())
return;

setSelectedItemIndex (-1, true);
}

Expand Down Expand Up @@ -981,18 +1005,29 @@ void PopupMenu::keyDown (const KeyPress& key, const Point<float>& position)

void PopupMenu::showSubmenu (int itemIndex)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "showSubmenu ENTER: itemIndex=" << itemIndex << " currentSubmenuItemIndex=" << submenuItemIndex << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

if (! canShowSubmenu (itemIndex))
{
YUP_MODULE_DBG (GUI_POPUPMENU, "showSubmenu EXIT: canShowSubmenu=false [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
return;
}

auto& item = *items[itemIndex];

// If we're already showing this submenu, no need to do anything
if (isAlreadyShowingSubmenu (itemIndex, item))
{
YUP_MODULE_DBG (GUI_POPUPMENU, "showSubmenu EXIT: alreadyShowing [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
return;
}

// Hide current submenu if different item
if (submenuItemIndex != itemIndex)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "showSubmenu: hiding previous submenu (prev=" << submenuItemIndex << ") [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
hideSubmenus();
}

isShowingSubmenu = true;
submenuItemIndex = itemIndex;
Expand All @@ -1005,7 +1040,6 @@ void PopupMenu::showSubmenu (int itemIndex)

// Reset the submenu's state before showing to ensure clean positioning
currentSubmenu->resetInternalState();
currentSubmenu->parentMenu = this;

// Configure submenu options
auto submenuOptions = prepareSubmenuOptions (currentSubmenu);
Expand All @@ -1016,12 +1050,15 @@ void PopupMenu::showSubmenu (int itemIndex)
// Show the submenu with callback
currentSubmenu->showCustom (submenuOptions, true, [this] (int selectedID)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "showSubmenu callback: selectedID=" << selectedID << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
if (selectedID != 0)
dismiss (selectedID);

isShowingSubmenu = false;
});

YUP_MODULE_DBG (GUI_POPUPMENU, "showSubmenu EXIT: submenu visible=" << (currentSubmenu->isVisible() ? 1 : 0) << " submenu popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (currentSubmenu.get())) << " screenBounds=" << currentSubmenu->getScreenBounds().toString() << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

// Repaint to show active submenu highlight
repaint();
}
Expand All @@ -1040,7 +1077,7 @@ bool PopupMenu::isAlreadyShowingSubmenu (int itemIndex, const Item& item) const
return submenuItemIndex == itemIndex
&& currentSubmenu
&& currentSubmenu == item.subMenu
&& currentSubmenu->isVisible();
&& (currentSubmenu->isVisible() || isShowingSubmenu);
}

void PopupMenu::positionSubmenu (Options& submenuOptions)
Expand Down Expand Up @@ -1131,6 +1168,7 @@ void PopupMenu::hideSubmenus()
{
if (currentSubmenu)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "hideSubmenus: dismissing submenu popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (currentSubmenu.get())) << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
cleanupSubmenu (currentSubmenu);

currentSubmenu = nullptr;
Expand Down Expand Up @@ -1205,14 +1243,21 @@ void PopupMenu::updateSubmenuVisibility (int hoveredItemIndex)
if (item.isSubMenu() && item.isEnabled)
{
if (submenuItemIndex == hoveredItemIndex && hasVisibleSubmenu())
{
YUP_MODULE_DBG (GUI_POPUPMENU, "updateSubmenuVisibility: already showing submenu for itemIndex=" << hoveredItemIndex << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
return;
}

YUP_MODULE_DBG (GUI_POPUPMENU, "updateSubmenuVisibility: showing submenu for itemIndex=" << hoveredItemIndex << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
showSubmenu (hoveredItemIndex);
}
else
{
if (hasVisibleSubmenu())
{
YUP_MODULE_DBG (GUI_POPUPMENU, "updateSubmenuVisibility: hiding submenu (hovered non-submenu itemIndex=" << hoveredItemIndex << ") [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
hideSubmenus();
}
}

return;
Expand All @@ -1225,11 +1270,13 @@ void PopupMenu::updateSubmenuVisibility (int hoveredItemIndex)
auto& newItem = *items[hoveredItemIndex];
if (newItem.isSubMenu() && newItem.isEnabled)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "updateSubmenuVisibility: switching submenu to itemIndex=" << hoveredItemIndex << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
showSubmenu (hoveredItemIndex);
return;
}
else
{
YUP_MODULE_DBG (GUI_POPUPMENU, "updateSubmenuVisibility: hiding submenu (hovered non-submenu itemIndex=" << hoveredItemIndex << ") [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
hideSubmenus();
return;
}
Expand Down Expand Up @@ -1269,6 +1316,7 @@ void PopupMenu::setSelectedItemIndex (int index, bool fromMouse)
{
if (selectedItemIndex == index)
{
YUP_MODULE_DBG (GUI_POPUPMENU, "setSelectedItemIndex: unchanged index=" << index << " fromMouse=" << (fromMouse ? 1 : 0) << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");
if (fromMouse)
updateSubmenuVisibility (index);

Expand All @@ -1283,6 +1331,8 @@ void PopupMenu::setSelectedItemIndex (int index, bool fromMouse)
if (selectedItemIndex >= 0 && selectedItemIndex < static_cast<int> (items.size()))
items[selectedItemIndex]->isHovered = true;

YUP_MODULE_DBG (GUI_POPUPMENU, "setSelectedItemIndex: index=" << index << " fromMouse=" << (fromMouse ? 1 : 0) << " [popup=" << String::toHexString (reinterpret_cast<pointer_sized_uint> (this)) << "]");

if (fromMouse)
updateSubmenuVisibility (index);

Expand Down
Loading
Loading