From 699fc983aeb5d169fc4738d6a6970ded05a5300d Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 29 Aug 2025 02:50:22 +0200 Subject: [PATCH] Use transient parent for color dialog, and position it to pointer This hopefully fixes an odd macOS specific focus issue. It also moves the dialog to the popup position when showing the same dialog using the editor-mixer and later a detached mixer. --- gtk2_ardour/foldback_strip.cc | 4 ++-- gtk2_ardour/mixer_strip.cc | 5 +++-- gtk2_ardour/route_time_axis.cc | 2 +- gtk2_ardour/route_ui.cc | 4 ++-- gtk2_ardour/route_ui.h | 2 +- gtk2_ardour/stripable_colorpicker.cc | 22 ++++++++++++++++++---- gtk2_ardour/stripable_colorpicker.h | 4 ++-- gtk2_ardour/surround_strip.cc | 2 +- gtk2_ardour/track_record_axis.cc | 2 +- gtk2_ardour/trigger_strip.cc | 2 +- gtk2_ardour/trigger_ui.cc | 1 + gtk2_ardour/vca_master_strip.cc | 2 +- gtk2_ardour/vca_time_axis.cc | 2 +- 13 files changed, 35 insertions(+), 19 deletions(-) diff --git a/gtk2_ardour/foldback_strip.cc b/gtk2_ardour/foldback_strip.cc index 6b96eb3261..ccec2d1d90 100644 --- a/gtk2_ardour/foldback_strip.cc +++ b/gtk2_ardour/foldback_strip.cc @@ -789,7 +789,7 @@ FoldbackStrip::build_route_ops_menu () bool active = _route->active (); if (active) { - items.push_back (MenuElem (_("Color..."), sigc::mem_fun (*this, &RouteUI::choose_color))); + items.push_back (MenuElem (_("Color..."), sigc::bind (sigc::mem_fun (*this, &RouteUI::choose_color), dynamic_cast (get_toplevel())))); items.push_back (MenuElem (_("Comments..."), sigc::mem_fun (*this, &RouteUI::open_comment_editor))); items.push_back (MenuElem (_("Outputs..."), sigc::mem_fun (*this, &RouteUI::edit_output_configuration))); @@ -879,7 +879,7 @@ FoldbackStrip::number_button_press (GdkEventButton* ev) _mixer.select_none(); if (ev->type == GDK_2BUTTON_PRESS) { - choose_color (); + choose_color (dynamic_cast (get_toplevel())); return true; } diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index ca4199b1df..626f77f1fd 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -1069,8 +1069,9 @@ MixerStrip::build_route_ops_menu () MenuList& items = route_ops_menu->items(); if (active) { + Gtk::Window* top = dynamic_cast (get_toplevel()); - items.push_back (MenuElem (_("Color..."), sigc::mem_fun (*this, &RouteUI::choose_color))); + items.push_back (MenuElem (_("Color..."), sigc::bind (sigc::mem_fun (*this, &RouteUI::choose_color), top))); items.push_back (MenuElem (_("Comments..."), sigc::mem_fun (*this, &RouteUI::open_comment_editor))); @@ -1248,7 +1249,7 @@ gboolean MixerStrip::number_button_button_press (GdkEventButton* ev) { if (ev->type == GDK_2BUTTON_PRESS) { - choose_color (); + choose_color (dynamic_cast (get_toplevel())); return true; } diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 70ff9f940f..90c9e8cae6 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -635,7 +635,7 @@ RouteTimeAxisView::build_display_menu () /* now fill it with our stuff */ if (active) { - items.push_back (MenuElem (_("Color..."), sigc::mem_fun (*this, &RouteUI::choose_color))); + items.push_back (MenuElem (_("Color..."), sigc::bind (sigc::mem_fun (*this, &RouteUI::choose_color), PublicEditor::instance ().current_toplevel()))); items.push_back (MenuElem (_("Comments..."), sigc::mem_fun (*this, &RouteUI::open_comment_editor))); diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 8f44226834..a27089ef46 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -1694,9 +1694,9 @@ RouteUI::select_midi_patch () /** Ask the user to choose a colour, and then apply that color to my route */ void -RouteUI::choose_color () +RouteUI::choose_color (Gtk::Window* parent) { - _color_picker.popup (_route); + _color_picker.popup (_route, parent); } /** Set the route's own color. This may not be used for display if diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h index 9e863b8962..fe1a7fb086 100644 --- a/gtk2_ardour/route_ui.h +++ b/gtk2_ardour/route_ui.h @@ -129,7 +129,7 @@ public: void edit_input_configuration (); void edit_output_configuration (); void select_midi_patch (); - void choose_color (); + void choose_color (Gtk::Window*); void route_rename (); void manage_pins (); void duplicate_selected_routes (); diff --git a/gtk2_ardour/stripable_colorpicker.cc b/gtk2_ardour/stripable_colorpicker.cc index bab55e6f65..aac9afb9ac 100644 --- a/gtk2_ardour/stripable_colorpicker.cc +++ b/gtk2_ardour/stripable_colorpicker.cc @@ -105,7 +105,7 @@ StripableColorDialog::reset () } void -StripableColorDialog::popup (const std::string& name, uint32_t color) +StripableColorDialog::popup (const std::string& name, uint32_t color, Gtk::Window* parent) { set_title (string_compose (_("Color Selection: %1"), name)); _initial_color = color; @@ -120,25 +120,39 @@ StripableColorDialog::popup (const std::string& name, uint32_t color) _color_changed_connection.disconnect (); _color_changed_connection = get_color_selection()->signal_color_changed().connect (sigc::mem_fun (*this, &StripableColorDialog::color_changed)); + if (parent) { + set_transient_for (*parent); + } + set_position (Gtk::WIN_POS_MOUSE); present (); } void -StripableColorDialog::popup (std::shared_ptr s) +StripableColorDialog::popup (std::shared_ptr s, Gtk::Window* parent) { if (s && s->active_color_picker()) { + if (parent) { + s->active_color_picker()->set_transient_for (*parent); + } + s->active_color_picker()->set_position (Gtk::WIN_POS_CENTER_ALWAYS); // force update + s->active_color_picker()->set_position (Gtk::WIN_POS_MOUSE); s->active_color_picker()->present (); return; } if (_stripable == s) { /* keep modified color */ + if (parent) { + set_transient_for (*parent); + } + set_position (Gtk::WIN_POS_CENTER_ALWAYS); // force update + set_position (Gtk::WIN_POS_MOUSE); present (); return; } _stripable = s; _stripable->set_active_color_picker (this); - popup (s->name(), _stripable->presentation_info().color ()); + popup (s->name(), _stripable->presentation_info().color (), parent); } void @@ -177,7 +191,7 @@ ArdourColorButton::ArdourColorButton () void ArdourColorButton::on_clicked () { - _color_picker.popup ("", Gtkmm2ext::gdk_color_to_rgba (get_color ())); + _color_picker.popup ("", Gtkmm2ext::gdk_color_to_rgba (get_color ()), dynamic_cast (get_toplevel())); _color_picker.get_window ()->set_transient_for (get_window ()); } diff --git a/gtk2_ardour/stripable_colorpicker.h b/gtk2_ardour/stripable_colorpicker.h index a3cb030336..20e829f06f 100644 --- a/gtk2_ardour/stripable_colorpicker.h +++ b/gtk2_ardour/stripable_colorpicker.h @@ -31,8 +31,8 @@ public: StripableColorDialog (); ~StripableColorDialog (); void reset (); - void popup (std::shared_ptr s); - void popup (const std::string&, uint32_t); + void popup (std::shared_ptr s, Gtk::Window*); + void popup (const std::string&, uint32_t, Gtk::Window*); sigc::signal ColorChanged; private: diff --git a/gtk2_ardour/surround_strip.cc b/gtk2_ardour/surround_strip.cc index 9e5f49e828..109d00fa3d 100644 --- a/gtk2_ardour/surround_strip.cc +++ b/gtk2_ardour/surround_strip.cc @@ -356,7 +356,7 @@ SurroundStrip::build_route_ops_menu () assert (_route->active ()); - items.push_back (MenuElem (_("Color..."), sigc::mem_fun (*this, &RouteUI::choose_color))); + items.push_back (MenuElem (_("Color..."), sigc::bind (sigc::mem_fun (*this, &RouteUI::choose_color), dynamic_cast (get_toplevel())))); items.push_back (MenuElem (_("Comments..."), sigc::mem_fun (*this, &RouteUI::open_comment_editor))); items.push_back (MenuElem (_("Outputs..."), sigc::mem_fun (*this, &RouteUI::edit_output_configuration))); diff --git a/gtk2_ardour/track_record_axis.cc b/gtk2_ardour/track_record_axis.cc index 505640cc55..d9ecb2b54d 100644 --- a/gtk2_ardour/track_record_axis.cc +++ b/gtk2_ardour/track_record_axis.cc @@ -498,7 +498,7 @@ TrackRecordAxis::build_route_ops_menu () MenuList& items = _route_ops_menu->items (); - items.push_back (MenuElem (_("Color..."), sigc::mem_fun (*this, &RouteUI::choose_color))); + items.push_back (MenuElem (_("Color..."), sigc::bind (sigc::mem_fun (*this, &RouteUI::choose_color), dynamic_cast (get_toplevel())))); items.push_back (MenuElem (_("Comments..."), sigc::mem_fun (*this, &RouteUI::open_comment_editor))); items.push_back (MenuElem (_("Inputs..."), sigc::mem_fun (*this, &RouteUI::edit_input_configuration))); items.push_back (MenuElem (_("Outputs..."), sigc::mem_fun (*this, &RouteUI::edit_output_configuration))); diff --git a/gtk2_ardour/trigger_strip.cc b/gtk2_ardour/trigger_strip.cc index 78b5e785f9..418dda63b5 100644 --- a/gtk2_ardour/trigger_strip.cc +++ b/gtk2_ardour/trigger_strip.cc @@ -301,7 +301,7 @@ TriggerStrip::build_route_ops_menu () MenuList& items = _route_ops_menu->items(); if (active) { - items.push_back (MenuElem (_("Color..."), sigc::mem_fun (*this, &RouteUI::choose_color))); + items.push_back (MenuElem (_("Color..."), sigc::bind (sigc::mem_fun (*this, &RouteUI::choose_color), dynamic_cast (get_toplevel())))); items.push_back (MenuElem (_("Comments..."), sigc::mem_fun (*this, &RouteUI::open_comment_editor))); diff --git a/gtk2_ardour/trigger_ui.cc b/gtk2_ardour/trigger_ui.cc index 9838d811c0..4dbd6f21f4 100644 --- a/gtk2_ardour/trigger_ui.cc +++ b/gtk2_ardour/trigger_ui.cc @@ -145,6 +145,7 @@ TriggerUI::trigger_swap (uint32_t n) void TriggerUI::choose_color () { + // TODO use StripableColorDialog and see note there regarding eyedropper.. if (!_color_dialog) { _color_dialog = new Gtk::ColorSelectionDialog; } diff --git a/gtk2_ardour/vca_master_strip.cc b/gtk2_ardour/vca_master_strip.cc index 0fed879533..4a041f0505 100644 --- a/gtk2_ardour/vca_master_strip.cc +++ b/gtk2_ardour/vca_master_strip.cc @@ -585,7 +585,7 @@ VCAMasterStrip::state_id () const void VCAMasterStrip::start_color_edit () { - _color_picker.popup (_vca); + _color_picker.popup (_vca, dynamic_cast (get_toplevel())); } bool diff --git a/gtk2_ardour/vca_time_axis.cc b/gtk2_ardour/vca_time_axis.cc index b29286acf1..f425d9848f 100644 --- a/gtk2_ardour/vca_time_axis.cc +++ b/gtk2_ardour/vca_time_axis.cc @@ -561,5 +561,5 @@ VCATimeAxisView::drop_all_slaves () void VCATimeAxisView::choose_color () { - _color_picker.popup (_vca); + _color_picker.popup (_vca, PublicEditor::instance ().current_toplevel()); }