Compare commits

...
Author SHA1 Message Date
HanifKoh 70da7e89bb Release the Slice Button's Mouse Capture When a Press Loses Its Release (#16358) 2026-10-11 15:49:04 +08:00
HanifKoh a671bf605d Dismiss the Slice-Plate Popup on Every Path Into the Filament Grouping Dialog (#16359)
#16284 closed the Slice-plate hover popup only when the Slice button opened
the filament grouping dialog. The dialog also opens from the plate's filament
grouping icon, the preview legend, slicing notification links and the send
dialog, and a popup still shown on those paths keeps the mouse capture on
macOS and starves the modal dialog of clicks. Dismiss it in
FilamentMapDialog::ShowModal() instead, so every path is covered.

The popup could also stay up on its own on macOS: an enter event stopped its
close timer, and when the timer fired with the cursor inside it returned
without re-arming, so without a later leave event the popup never closed. On
macOS the timer now keeps running while the popup is shown and closes it once
the cursor is outside. The popup also stops and frees its timer when destroyed.
2026-10-11 15:48:49 +08:00
SoftFever bae8f64b8b Complete and refine Simplified Chinese translations (#16356)
* Complete Simplified Chinese translations

* Fix Simplified Chinese 3D view, camera and extruder terms

* Use Chinese CAD view names on the navigator cube
2026-10-11 15:35:29 +08:00
7 changed files with 619 additions and 287 deletions
File diff suppressed because it is too large Load Diff
+15 -2
View File
@@ -379,14 +379,24 @@ void FilamentGroupPopup::OnTimer(wxTimerEvent &event)
// leaving event got triggered. So the timer is stopped first, then started
// again, causing the popup being dismissed immediately.
// To fix this, we check if cursor is still inside the popup window before
// dismissing.
// dismissing, and keep checking while it is: a leave event is not guaranteed
// to follow, and a popup left open keeps grabbing the mouse capture.
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
if (this->GetClientRect().Contains(pos)) return;
if (this->GetClientRect().Contains(pos)) {
StartTimer();
return;
}
#endif
Dismiss();
}
FilamentGroupPopup::~FilamentGroupPopup()
{
m_timer->Stop();
delete m_timer;
}
void FilamentGroupPopup::Dismiss() {
m_active = false;
PopupWindow::Dismiss();
@@ -405,7 +415,10 @@ void FilamentGroupPopup::OnEnterWindow(wxMouseEvent &)
// Ignore spurious ENTER synthesized by PopupWindow::OnMouseEvent2 on macOS.
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
if (!this->GetClientRect().Contains(pos)) return;
// On macOS the timer keeps running instead, and OnTimer closes the popup once the cursor has left it.
#ifndef __APPLE__
ResetTimer();
#endif
}
void FilamentGroupPopup::UpdateButtonStatus(int hover_idx)
+1
View File
@@ -27,6 +27,7 @@ class FilamentGroupPopup : public PopupWindow
{
public:
FilamentGroupPopup(wxWindow *parent);
~FilamentGroupPopup() override;
void tryPopup(Plater* plater,PartPlate* plate, bool slice_all);
void tryClose();
void Dismiss() override;
+9
View File
@@ -20,6 +20,8 @@
#include <wx/gdicmn.h>
#include <wx/dialog.h>
#include "slic3r/GUI/FilamentMapPanel.hpp"
#include "slic3r/GUI/FilamentGroupPopup.hpp"
#include "slic3r/GUI/MainFrame.hpp"
namespace Slic3r { namespace GUI {
@@ -377,6 +379,13 @@ FilamentMapMode FilamentMapDialog::get_mode()
int FilamentMapDialog::ShowModal()
{
// The Slice-plate hover popup is a transient popup that keeps grabbing the mouse
// capture while shown. Left behind this modal dialog it would starve the dialog of
// mouse events, so close it synchronously first, whichever path opened the dialog.
if (MainFrame* frame = wxGetApp().mainframe;
frame && frame->m_filament_group_popup && frame->m_filament_group_popup->IsShown())
frame->m_filament_group_popup->Dismiss();
update_panel_status(m_page_type);
return wxDialog::ShowModal();
}
-6
View File
@@ -2309,12 +2309,6 @@ wxBoxSizer* MainFrame::create_side_tools()
bool slice = true;
// The Slice-plate hover popup is a transient popup that keeps grabbing
// the mouse capture while shown. Left behind the modal grouping dialog it
// would starve that dialog of mouse events, so close it synchronously first.
if (m_filament_group_popup)
m_filament_group_popup->Dismiss();
auto curr_plate = m_plater->get_partplate_list().get_curr_plate();
#ifdef __linux__
PresetBundle* preset = wxGetApp().preset_bundle;
+13 -2
View File
@@ -17,6 +17,7 @@
BEGIN_EVENT_TABLE(SideButton, wxWindow)
EVT_LEFT_DOWN(SideButton::mouseDown)
EVT_LEFT_UP(SideButton::mouseReleased)
EVT_MOUSE_CAPTURE_LOST(SideButton::mouseCaptureLost)
EVT_PAINT(SideButton::paintEvent)
END_EVENT_TABLE()
@@ -331,20 +332,30 @@ void SideButton::mouseDown(wxMouseEvent& event)
event.Skip();
pressedDown = true;
SetFocus();
CaptureMouse();
// Capturing twice pushes this button onto the capture stack twice, and the
// release would then hand the capture straight back to it.
if (!HasCapture())
CaptureMouse();
}
void SideButton::mouseReleased(wxMouseEvent& event)
{
event.Skip();
// A press whose release went elsewhere still holds the capture.
if (HasCapture())
ReleaseMouse();
if (pressedDown) {
pressedDown = false;
ReleaseMouse();
if (wxRect({0, 0}, GetSize()).Contains(event.GetPosition()))
sendButtonEvent();
}
}
void SideButton::mouseCaptureLost(wxMouseCaptureLostEvent&)
{
pressedDown = false;
}
void SideButton::sendButtonEvent()
{
wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
+1
View File
@@ -94,6 +94,7 @@ private:
void mouseDown(wxMouseEvent& event);
void mouseReleased(wxMouseEvent& event);
void mouseCaptureLost(wxMouseCaptureLostEvent& event);
void sendButtonEvent();