@@ -59,69 +59,130 @@ void WfMenuCategoryButton::on_click()
5959 menu->set_category (category);
6060}
6161
62- WfMenuMenuItem::WfMenuMenuItem (WayfireMenu *_menu, Glib::RefPtr<Gio::DesktopAppInfo> app) :
63- Gtk::FlowBoxChild(), menu(_menu), m_app_info (app)
62+ WfMenuItem::WfMenuItem (WayfireMenu *_menu, Glib::RefPtr<Gio::DesktopAppInfo> app) :
63+ Gtk::FlowBoxChild(), menu(_menu), app_info (app)
6464{
65- m_image.set ((const Glib::RefPtr<const Gio::Icon>&)app->get_icon ());
66- m_image.set_pixel_size (48 );
67- m_label.set_text (app->get_name ());
68- m_label.set_xalign (0.0 );
69- m_label.set_hexpand (true );
70- m_has_actions = app->list_actions ().size () > 0 ;
71- m_button_box.append (m_image);
72- m_button_box.append (m_label);
73-
74- m_button.set_child (m_button_box);
75- signals.push_back (m_button.signal_clicked ().connect (
76- [this ] ()
65+ image.set ((const Glib::RefPtr<const Gio::Icon>&)app->get_icon ());
66+
67+ label.set_text (app->get_name ());
68+ label.set_ellipsize (Pango::EllipsizeMode::END );
69+
70+ extra_actions_button.add_css_class (" flat" );
71+ extra_actions_button.add_css_class (" app-button-extras" );
72+ extra_actions_button.set_direction (Gtk::ArrowType::RIGHT );
73+ extra_actions_button.set_has_frame (false );
74+
75+ box.set_expand (false );
76+ box.add_css_class (" flat" );
77+ box.add_css_class (" widget-icon" );
78+ box.add_css_class (" app-button" );
79+
80+ auto left_click_g = Gtk::GestureClick::create ();
81+ auto right_click_g = Gtk::GestureClick::create ();
82+ auto long_press_g = Gtk::GestureLongPress::create ();
83+ left_click_g->set_button (1 );
84+ right_click_g->set_button (3 );
85+ long_press_g->set_touch_only (true );
86+
87+ signals.push_back (left_click_g->signal_pressed ().connect (
88+ [=] (int c, double x, double y)
7789 {
78- this ->on_click ();
90+ on_click ();
91+ left_click_g->set_state (Gtk::EventSequenceState::CLAIMED );
92+ }));
93+ signals.push_back (right_click_g->signal_pressed ().connect (
94+ [=] (int c, double x, double y)
95+ {
96+ extra_actions_button.activate ();
97+ right_click_g->set_state (Gtk::EventSequenceState::CLAIMED );
98+ }));
99+ signals.push_back (long_press_g->signal_pressed ().connect (
100+ [=] (double x, double y)
101+ {
102+ extra_actions_button.activate ();
103+ long_press_g->set_state (Gtk::EventSequenceState::CLAIMED );
104+ left_click_g->set_state (Gtk::EventSequenceState::DENIED );
79105 }));
80- m_padding_box.append (m_button);
81- m_label.set_ellipsize (Pango::EllipsizeMode::END );
82- m_label.set_max_width_chars (5 );
83- m_button.add_css_class (" flat" );
84- m_extra_actions_button.add_css_class (" flat" );
85- m_extra_actions_button.add_css_class (" app-button-extras" );
86- m_extra_actions_button.set_halign (Gtk::Align::END );
87- m_extra_actions_button.set_direction (Gtk::ArrowType::RIGHT );
88- m_extra_actions_button.set_has_frame (false );
89- m_extra_actions_button.set_icon_name (" arrow-right" );
90- m_menu = Gio::Menu::create ();
91- m_actions = Gio::SimpleActionGroup::create ();
92- m_extra_actions_button.hide ();
93106
94107 if (menu->menu_list )
95108 {
96- m_padding_box.append (m_extra_actions_button);
97- this ->set_size_request (menu->menu_min_content_width , 48 );
98- for (auto action : app->list_actions ())
109+ label.set_hexpand (true );
110+ label.set_halign (Gtk::Align::FILL );
111+ label.set_halign (Gtk::Align::START );
112+ label.set_xalign (0.0 );
113+ list_item.set_hexpand (true );
114+ box.set_hexpand (true );
115+ set_hexpand (true );
116+ box.set_orientation (Gtk::Orientation::HORIZONTAL );
117+ extra_actions_button.set_halign (Gtk::Align::END );
118+ extra_actions_button.set_icon_name (" arrow-right" );
119+ button.add_css_class (" flat" );
120+
121+ list_item.append (image);
122+ list_item.append (label);
123+ button.set_child (list_item);
124+
125+ list_item.add_controller (left_click_g);
126+ list_item.add_controller (right_click_g);
127+ list_item.add_controller (long_press_g);
128+
129+ box.append (button);
130+ box.append (extra_actions_button);
131+
132+ set_child (box);
133+ } else
134+ {
135+ label.set_max_width_chars (0 );
136+ box.set_orientation (Gtk::Orientation::VERTICAL );
137+ box.append (image);
138+ if (app->list_actions ().size () == 0 )
99139 {
100- std::stringstream ss;
101- ss << " app." << action;
102- std::string full_action = ss.str ();
140+ button.set_child (box);
141+ button.add_css_class (" flat" );
142+ set_child (button);
143+ } else
144+ {
145+ extra_actions_button.set_child (box);
146+ extra_actions_button.add_css_class (" flat" );
147+ set_child (extra_actions_button);
148+ }
103149
104- auto menu_item = Gio::MenuItem::create (m_app_info->get_action_name (action), full_action);
150+ box.add_controller (left_click_g);
151+ box.add_controller (right_click_g);
152+ box.add_controller (long_press_g);
105153
106- auto action_obj = Gio::SimpleAction::create (action);
107- signals.push_back (action_obj->signal_activate ().connect (
108- [this , action] (Glib::VariantBase vb)
109- {
110- auto ctx = Gdk::Display::get_default ()->get_app_launch_context ();
111- m_app_info->launch_action (action, ctx);
112- menu->hide_menu ();
113- }));
114- m_menu->append_item (menu_item);
115- m_actions->add_action (action_obj);
116-
117- m_extra_actions_button.show ();
118- }
154+ box.append (label);
155+ }
119156
120- m_extra_actions_button.set_menu_model (m_menu);
157+ m_menu = Gio::Menu::create ();
158+ actions = Gio::SimpleActionGroup::create ();
159+ extra_actions_button.hide ();
160+
161+ for (auto action : app->list_actions ())
162+ {
163+ std::stringstream ss;
164+ ss << " app." << action;
165+ std::string full_action = ss.str ();
166+
167+ auto menu_item = Gio::MenuItem::create (app_info->get_action_name (action), full_action);
168+
169+ auto action_obj = Gio::SimpleAction::create (action);
170+ signals.push_back (action_obj->signal_activate ().connect (
171+ [this , action] (Glib::VariantBase vb)
172+ {
173+ auto ctx = Gdk::Display::get_default ()->get_app_launch_context ();
174+ app_info->launch_action (action, ctx);
175+ menu->hide_menu ();
176+ }));
177+ m_menu->append_item (menu_item);
178+ actions->add_action (action_obj);
179+
180+ extra_actions_button.show ();
121181 }
122182
123- set_child (m_padding_box);
124- add_css_class (" app-button" );
183+ extra_actions_button.set_menu_model (m_menu);
184+ extra_actions_button.insert_action_group (" app" , actions);
185+
125186 set_has_tooltip ();
126187 signals.push_back (signal_query_tooltip ().connect ([=] (int x, int y, bool key_mode,
127188 const std::shared_ptr<Gtk::Tooltip>& tooltip) ->
@@ -130,54 +191,31 @@ WfMenuMenuItem::WfMenuMenuItem(WayfireMenu *_menu, Glib::RefPtr<Gio::DesktopAppI
130191 tooltip->set_text (app->get_name ());
131192 return true ;
132193 }, false ));
133- m_extra_actions_button.insert_action_group (" app" , m_actions);
134-
135- auto click_gesture = Gtk::GestureClick::create ();
136- auto long_press = Gtk::GestureLongPress::create ();
137- long_press->set_touch_only (true );
138- long_press->signal_pressed ().connect (
139- [=] (double x, double y)
140- {
141- m_extra_actions_button.activate ();
142- long_press->set_state (Gtk::EventSequenceState::CLAIMED );
143- click_gesture->set_state (Gtk::EventSequenceState::DENIED );
144- });
145- click_gesture->set_button (3 );
146- signals.push_back (click_gesture->signal_pressed ().connect ([=] (int count, double x, double y)
147- {
148- click_gesture->set_state (Gtk::EventSequenceState::CLAIMED );
149- }));
150- signals.push_back (click_gesture->signal_released ().connect ([=] (int count, double x, double y)
151- {
152- m_extra_actions_button.activate ();
153- }));
154- m_button.add_controller (long_press);
155- m_button.add_controller (click_gesture);
156194}
157195
158- WfMenuMenuItem ::~WfMenuMenuItem ()
196+ WfMenuItem ::~WfMenuItem ()
159197{
160198 for (auto signal : signals)
161199 {
162200 signal.disconnect ();
163201 }
164202}
165203
166- void WfMenuMenuItem ::on_click ()
204+ void WfMenuItem ::on_click ()
167205{
168206 auto ctx = Gdk::Display::get_default ()->get_app_launch_context ();
169- m_app_info ->launch (std::vector<Glib::RefPtr<Gio::File>>(), ctx);
207+ app_info ->launch (std::vector<Glib::RefPtr<Gio::File>>(), ctx);
170208 menu->hide_menu ();
171209}
172210
173- void WfMenuMenuItem ::set_search_value (uint32_t value)
211+ void WfMenuItem ::set_search_value (uint32_t value)
174212{
175- m_search_value = value;
213+ search_value = value;
176214}
177215
178- uint32_t WfMenuMenuItem ::get_search_value ()
216+ uint32_t WfMenuItem ::get_search_value ()
179217{
180- return m_search_value ;
218+ return search_value ;
181219}
182220
183221/* Fuzzy search for pattern in text. We use a greedy algorithm as follows:
@@ -209,12 +247,12 @@ static bool fuzzy_match(Glib::ustring text, Glib::ustring pattern)
209247 return i == pattern.length ();
210248}
211249
212- uint32_t WfMenuMenuItem ::fuzzy_match (Glib::ustring pattern)
250+ uint32_t WfMenuItem ::fuzzy_match (Glib::ustring pattern)
213251{
214252 uint32_t match_score = 0 ;
215- Glib::ustring name = m_app_info ->get_name ();
216- Glib::ustring long_name = m_app_info ->get_display_name ();
217- Glib::ustring progr = m_app_info ->get_executable ();
253+ Glib::ustring name = app_info ->get_name ();
254+ Glib::ustring long_name = app_info ->get_display_name ();
255+ Glib::ustring progr = app_info ->get_executable ();
218256
219257 auto name_lower = name.lowercase ();
220258 auto long_name_lower = long_name.lowercase ();
@@ -239,13 +277,13 @@ uint32_t WfMenuMenuItem::fuzzy_match(Glib::ustring pattern)
239277 return match_score;
240278}
241279
242- uint32_t WfMenuMenuItem ::matches (Glib::ustring pattern)
280+ uint32_t WfMenuItem ::matches (Glib::ustring pattern)
243281{
244282 uint32_t match_score = 0 ;
245- Glib::ustring long_name = m_app_info ->get_display_name ();
246- Glib::ustring name = m_app_info ->get_name ();
247- Glib::ustring progr = m_app_info ->get_executable ();
248- Glib::ustring descr = m_app_info ->get_description ();
283+ Glib::ustring long_name = app_info ->get_display_name ();
284+ Glib::ustring name = app_info ->get_name ();
285+ Glib::ustring progr = app_info ->get_executable ();
286+ Glib::ustring descr = app_info ->get_description ();
249287
250288 auto name_lower = name.lowercase ();
251289 auto long_name_lower = long_name.lowercase ();
@@ -280,10 +318,10 @@ uint32_t WfMenuMenuItem::matches(Glib::ustring pattern)
280318 return match_score;
281319}
282320
283- bool WfMenuMenuItem ::operator <(const WfMenuMenuItem & other)
321+ bool WfMenuItem ::operator <(const WfMenuItem & other)
284322{
285- return Glib::ustring (m_app_info ->get_name ()).lowercase () <
286- Glib::ustring (other.m_app_info ->get_name ()).lowercase ();
323+ return Glib::ustring (app_info ->get_name ()).lowercase () <
324+ Glib::ustring (other.app_info ->get_name ()).lowercase ();
287325}
288326
289327void WayfireMenu::load_menu_item (AppInfo app_info)
@@ -384,7 +422,7 @@ void WayfireMenu::populate_menu_items(std::string category)
384422
385423 for (auto app_info : category_list[category]->items )
386424 {
387- auto app = new WfMenuMenuItem (this , app_info);
425+ auto app = new WfMenuItem (this , app_info);
388426 flowbox.append (*app);
389427 }
390428}
@@ -478,7 +516,7 @@ void WayfireMenu::on_search_changed()
478516
479517bool WayfireMenu::on_filter (Gtk::FlowBoxChild *child)
480518{
481- auto button = dynamic_cast <WfMenuMenuItem *>(child);
519+ auto button = dynamic_cast <WfMenuItem *>(child);
482520 assert (button);
483521
484522 auto text = search_entry.get_text ();
@@ -497,8 +535,8 @@ bool WayfireMenu::on_filter(Gtk::FlowBoxChild *child)
497535
498536bool WayfireMenu::on_sort (Gtk::FlowBoxChild *a, Gtk::FlowBoxChild *b)
499537{
500- auto b1 = dynamic_cast <WfMenuMenuItem *>(a);
501- auto b2 = dynamic_cast <WfMenuMenuItem *>(b);
538+ auto b1 = dynamic_cast <WfMenuItem *>(a);
539+ auto b2 = dynamic_cast <WfMenuItem *>(b);
502540 assert (b1 && b2);
503541
504542 if (m_sort_names)
@@ -606,7 +644,7 @@ void WayfireMenu::setup_popover_layout()
606644 auto children = flowbox.get_selected_children ();
607645 if (children.size () == 1 )
608646 {
609- auto child = dynamic_cast <WfMenuMenuItem *>(children[0 ]);
647+ auto child = dynamic_cast <WfMenuItem *>(children[0 ]);
610648 child->on_click ();
611649 }
612650
@@ -706,6 +744,14 @@ void WayfireMenu::update_popover_layout()
706744 popover_layout_box.remove (box_bottom);
707745 }
708746
747+ if (menu_list)
748+ {
749+ flowbox.set_max_children_per_line (1 );
750+ } else
751+ {
752+ flowbox.set_max_children_per_line (-1 );
753+ }
754+
709755 if ((std::string)panel_position == WF_WINDOW_POSITION_TOP )
710756 {
711757 popover_layout_box.append (search_entry);
@@ -933,6 +979,11 @@ void WayfireMenu::init(Gtk::Box *container)
933979
934980 // configuration reloading callbacks
935981 menu_icon.set_callback ([=] () { update_icon (); });
982+ flowbox_spacing.set_callback ([=] ()
983+ {
984+ flowbox.set_column_spacing (flowbox_spacing.value ());
985+ flowbox.set_column_spacing (flowbox_spacing.value ());
986+ });
936987 menu_min_category_width.set_callback ([=] () { update_category_width (); });
937988 menu_min_content_height.set_callback ([=] () { update_content_height (); });
938989 menu_min_content_width.set_callback ([=] () { update_content_width (); });
@@ -1080,7 +1131,7 @@ void WayfireMenu::select_first_flowbox_item()
10801131 auto child = flowbox.get_child_at_index (0 );
10811132 if (child)
10821133 {
1083- auto cast_child = dynamic_cast <WfMenuMenuItem *>(child);
1134+ auto cast_child = dynamic_cast <WfMenuItem *>(child);
10841135 if (cast_child)
10851136 {
10861137 flowbox.select_child (*cast_child);
0 commit comments