fix thinko in handling of cue page context menus

Context menus should (unless there is a very strong reason otherwise) be
popped up on button press, not button release. In addition Gtk::Menu::popup()
should be given the button ID of the button used, so that it can manage
both styles of menu interaction (press/drag/release and press/release/drag/press)
This commit is contained in:
Paul Davis 2025-04-28 14:26:15 -06:00
parent 975b01060a
commit fece4f0ca8
6 changed files with 84 additions and 94 deletions

View file

@ -34,6 +34,7 @@
#include "gtkmm2ext/actions.h" #include "gtkmm2ext/actions.h"
#include "gtkmm2ext/colors.h" #include "gtkmm2ext/colors.h"
#include "gtkmm2ext/keyboard.h"
#include "gtkmm2ext/utils.h" #include "gtkmm2ext/utils.h"
#include "ardour_ui.h" #include "ardour_ui.h"
@ -226,7 +227,7 @@ CueBoxUI::~CueBoxUI ()
} }
void void
CueBoxUI::context_menu (uint64_t idx) CueBoxUI::context_menu (GdkEventButton* ev, uint64_t idx)
{ {
using namespace Gtk; using namespace Gtk;
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
@ -298,7 +299,7 @@ CueBoxUI::context_menu (uint64_t idx)
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Clear All..."), sigc::bind (sigc::mem_fun (*this, &CueBoxUI::clear_all_triggers), idx))); items.push_back (MenuElem (_("Clear All..."), sigc::bind (sigc::mem_fun (*this, &CueBoxUI::clear_all_triggers), idx)));
_context_menu->popup (3, gtk_get_current_event_time ()); _context_menu->popup (ev->button, gtk_get_current_event_time ());
} }
void void
@ -436,21 +437,15 @@ bool
CueBoxUI::event (GdkEvent* ev, uint64_t n) CueBoxUI::event (GdkEvent* ev, uint64_t n)
{ {
switch (ev->type) { switch (ev->type) {
case GDK_BUTTON_PRESS: case GDK_BUTTON_PRESS:
if (ev->button.button==1) { if (ev->button.button == 1) {
trigger_cue_row (n); trigger_cue_row (n);
} } else if (Gtkmm2ext::Keyboard::is_context_menu_event (&ev->button)) {
break; context_menu (&ev->button, n);
case GDK_2BUTTON_PRESS: }
break; break;
case GDK_BUTTON_RELEASE: default:
switch (ev->button.button) { break;
case 3:
context_menu (n);
return true;
}
default:
break;
} }
return false; return false;

View file

@ -84,7 +84,7 @@ private:
bool text_event (GdkEvent*, uint64_t); bool text_event (GdkEvent*, uint64_t);
void build (); void build ();
void context_menu (uint64_t idx); void context_menu (GdkEventButton*, uint64_t idx);
void get_slots (TriggerList &triggerlist, uint64_t idx); void get_slots (TriggerList &triggerlist, uint64_t idx);
void clear_all_triggers(uint64_t idx); void clear_all_triggers(uint64_t idx);

View file

@ -267,6 +267,9 @@ TriggerMaster::event_handler (GdkEvent* ev)
} else { } else {
_triggerbox->stop_all_quantized (); _triggerbox->stop_all_quantized ();
} }
break;
} else if (Gtkmm2ext::Keyboard::is_context_menu_event (&ev->button)) {
context_menu (&ev->button);
} }
break; break;
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
@ -281,11 +284,7 @@ TriggerMaster::event_handler (GdkEvent* ev)
} }
redraw (); redraw ();
break; break;
case GDK_BUTTON_RELEASE:
switch (ev->button.button) {
case 3:
context_menu ();
}
default: default:
break; break;
} }
@ -294,7 +293,7 @@ TriggerMaster::event_handler (GdkEvent* ev)
} }
void void
TriggerMaster::context_menu () TriggerMaster::context_menu (GdkEventButton* ev)
{ {
using namespace Gtk; using namespace Gtk;
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
@ -358,7 +357,7 @@ TriggerMaster::context_menu ()
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Clear All..."), sigc::mem_fun (*this, &TriggerMaster::clear_all_triggers))); items.push_back (MenuElem (_("Clear All..."), sigc::mem_fun (*this, &TriggerMaster::clear_all_triggers)));
_context_menu->popup (1, gtk_get_current_event_time ()); _context_menu->popup (ev->button, gtk_get_current_event_time ());
} }
void void
@ -576,36 +575,32 @@ bool
CueMaster::event_handler (GdkEvent* ev) CueMaster::event_handler (GdkEvent* ev)
{ {
switch (ev->type) { switch (ev->type) {
case GDK_BUTTON_PRESS: case GDK_BUTTON_PRESS:
if (ev->button.button == 1) { if (ev->button.button == 1) {
if (Keyboard::modifier_state_equals (ev->button.state, Keyboard::PrimaryModifier)) { if (Keyboard::modifier_state_equals (ev->button.state, Keyboard::PrimaryModifier)) {
_session->trigger_stop_all (true); //stop 'now' _session->trigger_stop_all (true); //stop 'now'
} else { } else {
_session->trigger_stop_all (false); //stop quantized (bar end) _session->trigger_stop_all (false); //stop quantized (bar end)
}
return true;
} }
break; return true;
case GDK_BUTTON_RELEASE: } else if (Gtkmm2ext::Keyboard::is_context_menu_event (&ev->button)) {
switch (ev->button.button) { context_menu (&ev->button);
case 3: }
context_menu (); break;
return true; case GDK_ENTER_NOTIFY:
} if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
break; stop_shape->set_fill_color (UIConfiguration::instance ().color ("neutral:foreground"));
case GDK_ENTER_NOTIFY: set_fill_color (HSV (fill_color ()).lighter (0.25).color ());
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) { }
stop_shape->set_fill_color (UIConfiguration::instance ().color ("neutral:foreground")); break;
set_fill_color (HSV (fill_color ()).lighter (0.25).color ()); case GDK_LEAVE_NOTIFY:
} if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
break; set_default_colors ();
case GDK_LEAVE_NOTIFY: }
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) { break;
set_default_colors ();
} default:
break; break;
default:
break;
} }
return false; return false;
@ -652,7 +647,7 @@ CueMaster::ui_parameter_changed (std::string const& p)
} }
void void
CueMaster::context_menu () CueMaster::context_menu (GdkEventButton* ev)
{ {
using namespace Gtk; using namespace Gtk;
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
@ -721,7 +716,7 @@ CueMaster::context_menu ()
items.push_back (SeparatorElem()); items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Clear All..."), sigc::mem_fun (*this, &CueMaster::clear_all_triggers))); items.push_back (MenuElem (_("Clear All..."), sigc::mem_fun (*this, &CueMaster::clear_all_triggers)));
_context_menu->popup (3, gtk_get_current_event_time ()); _context_menu->popup (ev->button, gtk_get_current_event_time ());
} }
void void

View file

@ -79,7 +79,7 @@ public:
void selection_change (); void selection_change ();
private: private:
void context_menu (); void context_menu (GdkEventButton*);
void clear_all_triggers(); void clear_all_triggers();
void set_all_colors(); void set_all_colors();
@ -127,7 +127,7 @@ public:
bool event_handler (GdkEvent*); bool event_handler (GdkEvent*);
private: private:
void context_menu (); void context_menu (GdkEventButton*);
void get_boxen (TriggerBoxList &boxlist); void get_boxen (TriggerBoxList &boxlist);
void clear_all_triggers(); void clear_all_triggers();

View file

@ -411,8 +411,7 @@ TriggerUI::context_menu ()
items.push_back (MenuElem (_("MIDI Learn"), sigc::mem_fun (*this, &TriggerUI::trigger_midi_learn))); items.push_back (MenuElem (_("MIDI Learn"), sigc::mem_fun (*this, &TriggerUI::trigger_midi_learn)));
items.push_back (MenuElem (_("MIDI un-Learn"), sigc::mem_fun (*this, &TriggerUI::trigger_midi_unlearn))); items.push_back (MenuElem (_("MIDI un-Learn"), sigc::mem_fun (*this, &TriggerUI::trigger_midi_unlearn)));
_context_menu->popup (1, gtk_get_current_event_time ());
_context_menu->popup (3, gtk_get_current_event_time ());
} }
void void
@ -547,7 +546,7 @@ TriggerUI::launch_context_menu ()
dynamic_cast<Gtk::CheckMenuItem*> (&items.back ())->set_active (true); dynamic_cast<Gtk::CheckMenuItem*> (&items.back ())->set_active (true);
} }
_launch_context_menu->popup (3, gtk_get_current_event_time ()); _launch_context_menu->popup (1, gtk_get_current_event_time ());
} }
void void

View file

@ -627,42 +627,43 @@ bool
TriggerEntry::name_button_event (GdkEvent* ev) TriggerEntry::name_button_event (GdkEvent* ev)
{ {
switch (ev->type) { switch (ev->type) {
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) { if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
set_widget_colors (NameEntered); set_widget_colors (NameEntered);
} }
break; break;
case GDK_LEAVE_NOTIFY: case GDK_LEAVE_NOTIFY:
if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) { if (ev->crossing.detail != GDK_NOTIFY_INFERIOR) {
set_widget_colors (NoneEntered); set_widget_colors (NoneEntered);
} }
break; break;
case GDK_BUTTON_PRESS: case GDK_BUTTON_PRESS:
break; if (Gtkmm2ext::Keyboard::is_context_menu_event (&ev->button)) {
case GDK_2BUTTON_PRESS: PublicEditor::instance ().get_selection ().set (this);
#if SELECTION_PROPERTIES_BOX_TODO context_menu ();
edit_trigger (); return true;
#endif }
break;
case GDK_2BUTTON_PRESS:
#if SELECTION_PROPERTIES_BOX_TODO
edit_trigger ();
#endif
return true;
case GDK_BUTTON_RELEASE:
if (Gtkmm2ext::Keyboard::is_delete_event (&ev->button)) {
clear_trigger ();
return true;
}
switch (ev->button.button) {
case 1:
PublicEditor::instance ().get_selection ().set (this);
return true; return true;
case GDK_BUTTON_RELEASE:
if (Gtkmm2ext::Keyboard::is_delete_event (&ev->button)) {
clear_trigger ();
return true;
}
switch (ev->button.button) {
case 3:
PublicEditor::instance ().get_selection ().set (this);
context_menu ();
return true;
case 1:
PublicEditor::instance ().get_selection ().set (this);
return true;
default:
break;
}
break;
default: default:
break; break;
}
break;
default:
break;
} }
return false; return false;