@@ -134,7 +134,7 @@ class VisibleChildIterator {
134134 * no-recent "No recent documents" button
135135 * none Default type
136136 * place PlaceButton
137- * favorite PathButton
137+ * favorite FavoriteDocumentButton
138138 * recent PathButton
139139 * recent-clear "Clear recent documents" button
140140 * search-provider SearchProviderResultButton
@@ -330,11 +330,11 @@ class SimpleMenuItem {
330330 }
331331}
332332
333- class ApplicationContextMenuItem extends PopupMenu . PopupBaseMenuItem {
334- constructor ( appButton , label , action , iconName ) {
333+ class ContextMenuItem extends PopupMenu . PopupBaseMenuItem {
334+ constructor ( button , label , action , iconName ) {
335335 super ( { focusOnHover : false } ) ;
336336
337- this . _appButton = appButton ;
337+ this . _button = button ;
338338 this . _action = action ;
339339 this . label = new St . Label ( { text : label } ) ;
340340
@@ -350,6 +350,12 @@ class ApplicationContextMenuItem extends PopupMenu.PopupBaseMenuItem {
350350
351351 this . addActor ( this . label ) ;
352352 }
353+ }
354+
355+ class ApplicationContextMenuItem extends ContextMenuItem {
356+ constructor ( appButton , label , action , iconName ) {
357+ super ( appButton , label , action , iconName ) ;
358+ }
353359
354360 activate ( event ) {
355361 let closeMenu = true ;
@@ -370,13 +376,13 @@ class ApplicationContextMenuItem extends PopupMenu.PopupBaseMenuItem {
370376 let launcherApplet = Main . AppletManager . get_role_provider ( Main . AppletManager . Roles . PANEL_LAUNCHER ) ;
371377 if ( ! launcherApplet )
372378 return true ;
373- launcherApplet . acceptNewLauncher ( this . _appButton . app . get_id ( ) ) ;
379+ launcherApplet . acceptNewLauncher ( this . _button . app . get_id ( ) ) ;
374380 }
375381 return false ;
376382 } ) ;
377383 break ;
378384 case "add_to_desktop" :
379- let file = Gio . file_new_for_path ( this . _appButton . app . get_app_info ( ) . get_filename ( ) ) ;
385+ let file = Gio . file_new_for_path ( this . _button . app . get_app_info ( ) . get_filename ( ) ) ;
380386 let destFile = Gio . file_new_for_path ( USER_DESKTOP_PATH + "/" + file . get_basename ( ) ) ;
381387 try {
382388 file . copy ( destFile , 0 , null , function ( ) { } ) ;
@@ -386,41 +392,41 @@ class ApplicationContextMenuItem extends PopupMenu.PopupBaseMenuItem {
386392 }
387393 break ;
388394 case "add_to_favorites" :
389- AppFavorites . getAppFavorites ( ) . addFavorite ( this . _appButton . app . get_id ( ) ) ;
395+ AppFavorites . getAppFavorites ( ) . addFavorite ( this . _button . app . get_id ( ) ) ;
390396 this . label . set_text ( _ ( "Remove from favorites" ) ) ;
391397 this . icon . icon_name = "xsi-starred" ;
392398 this . _action = "remove_from_favorites" ;
393399 closeMenu = false ;
394400 break ;
395401 case "remove_from_favorites" :
396- AppFavorites . getAppFavorites ( ) . removeFavorite ( this . _appButton . app . get_id ( ) ) ;
402+ AppFavorites . getAppFavorites ( ) . removeFavorite ( this . _button . app . get_id ( ) ) ;
397403 this . label . set_text ( _ ( "Add to favorites" ) ) ;
398404 this . icon . icon_name = "xsi-non-starred" ;
399405 this . _action = "add_to_favorites" ;
400406 closeMenu = false ;
401407 break ;
402408 case "app_properties" :
403- Util . spawnCommandLine ( "cinnamon-desktop-editor -mlauncher -o" + GLib . shell_quote ( this . _appButton . app . get_app_info ( ) . get_filename ( ) ) ) ;
409+ Util . spawnCommandLine ( "cinnamon-desktop-editor -mlauncher -o" + GLib . shell_quote ( this . _button . app . get_app_info ( ) . get_filename ( ) ) ) ;
404410 break ;
405411 case "uninstall" :
406- Util . spawnCommandLine ( "/usr/bin/cinnamon-remove-application '" + this . _appButton . app . get_app_info ( ) . get_filename ( ) + "'" ) ;
412+ Util . spawnCommandLine ( "/usr/bin/cinnamon-remove-application '" + this . _button . app . get_app_info ( ) . get_filename ( ) + "'" ) ;
407413 break ;
408414 case "offload_launch" :
409415 try {
410- this . _appButton . app . launch_offloaded ( 0 , [ ] , - 1 ) ;
416+ this . _button . app . launch_offloaded ( 0 , [ ] , - 1 ) ;
411417 } catch ( e ) {
412418 logError ( e , "Could not launch app with dedicated gpu: " ) ;
413419 }
414420 break ;
415421 default :
416422 if ( this . _action . startsWith ( "action_" ) ) {
417423 let action = this . _action . substring ( 7 ) ;
418- this . _appButton . app . get_app_info ( ) . launch_action ( action , global . create_app_launch_context ( ) ) ;
424+ this . _button . app . get_app_info ( ) . launch_action ( action , global . create_app_launch_context ( ) ) ;
419425 } else return true ;
420426 }
421427 if ( closeMenu ) {
422- this . _appButton . applet . toggleContextMenu ( this . _appButton ) ;
423- this . _appButton . applet . menu . close ( ) ;
428+ this . _button . applet . toggleContextMenu ( this . _button ) ;
429+ this . _button . applet . menu . close ( ) ;
424430 }
425431 return false ;
426432 }
@@ -756,14 +762,52 @@ class RecentButton extends SimpleMenuItem {
756762 }
757763}
758764
765+ class PathContextMenuItem extends ContextMenuItem {
766+ constructor ( pathButton , label , action , iconName ) {
767+ super ( pathButton , label , action , iconName ) ;
768+ }
769+
770+ activate ( event ) {
771+ switch ( this . _action ) {
772+ case "open_containing_folder" :
773+ this . _openContainingFolder ( ) ;
774+ this . _button . applet . toggleContextMenu ( this . _button ) ;
775+ this . _button . applet . menu . close ( ) ;
776+ return false ;
777+ }
778+ return true ;
779+ }
780+
781+ _openContainingFolder ( ) {
782+ try {
783+ Gio . DBus . session . call_sync (
784+ "org.freedesktop.FileManager1" ,
785+ "/org/freedesktop/FileManager1" ,
786+ "org.freedesktop.FileManager1" ,
787+ "ShowItems" ,
788+ new GLib . Variant ( "(ass)" , [
789+ [ this . _button . uri ] ,
790+ global . get_pid ( ) . toString ( )
791+ ] ) ,
792+ null ,
793+ Gio . DBusCallFlags . NONE ,
794+ 1000 ,
795+ null
796+ ) ;
797+ } catch ( e ) {
798+ global . logError ( `Could not open containing folder: ${ e } ` ) ;
799+ }
800+ }
801+ }
802+
759803class PathButton extends SimpleMenuItem {
760804 constructor ( applet , type , name , uri , icon ) {
761805 super ( applet , {
762806 name : name ,
763807 description : shorten_path ( uri , name ) ,
764808 type : type ,
765809 styleClass : 'appmenu-application-button' ,
766- withMenu : false ,
810+ withMenu : true ,
767811 uri : uri ,
768812 } ) ;
769813
@@ -795,6 +839,49 @@ class PathButton extends SimpleMenuItem {
795839 source . notify ( notification ) ;
796840 }
797841 }
842+
843+ populateMenu ( menu ) {
844+ let menuItem = new PathContextMenuItem ( this , _ ( "Open containing folder" ) , "open_containing_folder" , "xsi-go-jump-symbolic" ) ;
845+ menu . addMenuItem ( menuItem ) ;
846+ }
847+ }
848+
849+ class FavoriteDocumentContextMenuItem extends ContextMenuItem {
850+ constructor ( favDocButton , label , action , iconName ) {
851+ super ( favDocButton , label , action , iconName ) ;
852+ }
853+
854+ activate ( event ) {
855+ switch ( this . _action ) {
856+ case "remove_from_favorite_documents" :
857+ this . _button . _unfavorited = true ;
858+ this . _button . applet . _unfavoritedUris . push ( this . _button . uri ) ;
859+ this . _button . applet . toggleContextMenu ( this . _button ) ;
860+ this . _button . actor . hide ( ) ;
861+ return false ;
862+ }
863+ return true ;
864+ }
865+ }
866+
867+ class FavoriteDocumentButton extends PathButton {
868+ constructor ( applet , type , name , uri , icon ) {
869+ super ( applet , type , name , uri , icon ) ;
870+
871+ this . _unfavorited = false ;
872+ this . _signals . connect ( this . actor , "show" , ( ) => {
873+ if ( this . _unfavorited )
874+ this . actor . hide ( ) ;
875+ return Clutter . EVENT_PROPAGATE ;
876+ } ) ;
877+ }
878+
879+ populateMenu ( menu ) {
880+ let menuItem = new FavoriteDocumentContextMenuItem ( this , _ ( "Remove from favorites" ) , "remove_from_favorite_documents" , "xsi-unfavorite-symbolic" ) ;
881+ menu . addMenuItem ( menuItem ) ;
882+
883+ super . populateMenu ( menu ) ;
884+ }
798885}
799886
800887class CategoryButton extends SimpleMenuItem {
@@ -1182,6 +1269,7 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
11821269 this . _recentButtons = [ ] ;
11831270 this . favoriteDocsButton = null ;
11841271 this . _favoriteDocButtons = [ ] ;
1272+ this . _unfavoritedUris = [ ] ;
11851273 this . _categoryButtons = [ ] ;
11861274 this . _searchProviderButtons = [ ] ;
11871275 this . hoveredApp = null ;
@@ -1411,6 +1499,7 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
14111499 if ( this . searchActive ) {
14121500 this . resetSearch ( ) ;
14131501 }
1502+ this . _removeUnfavoritedUris ( ) ;
14141503
14151504 this . hoveredCategory = null ;
14161505 this . hoveredApp = null ;
@@ -2239,7 +2328,7 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
22392328 gicon : Gio . content_type_get_icon ( info . cached_mimetype ) ,
22402329 icon_size : this . applicationIconSize
22412330 } ) ;
2242- let button = new PathButton ( this , 'favorite' , info . display_name , info . uri , icon ) ;
2331+ let button = new FavoriteDocumentButton ( this , 'favorite' , info . display_name , info . uri , icon ) ;
22432332 this . _favoriteDocButtons . push ( button ) ;
22442333 this . applicationsBox . add_actor ( button . actor ) ;
22452334 button . actor . visible = this . menu . isOpen && this . lastSelectedCategory === "favorite" ;
@@ -2957,6 +3046,15 @@ class CinnamonMenuApplet extends Applet.TextIconApplet {
29573046
29583047 return false ;
29593048 }
3049+
3050+ _removeUnfavoritedUris ( ) {
3051+ if ( this . _unfavoritedUris . length !== 0 ) {
3052+ let favorites = XApp . Favorites . get_default ( ) ;
3053+ for ( let uri of this . _unfavoritedUris )
3054+ favorites . remove ( uri ) ;
3055+ this . _unfavoritedUris = [ ] ;
3056+ }
3057+ }
29603058} ;
29613059
29623060function main ( metadata , orientation , panel_height , instance_id ) {
0 commit comments