diff --git a/common/widgets/lib_tree.cpp b/common/widgets/lib_tree.cpp
index b51d7a2d27..761d8bbbb7 100644
--- a/common/widgets/lib_tree.cpp
+++ b/common/widgets/lib_tree.cpp
@@ -176,6 +176,11 @@ void LIB_TREE::Unselect()
     m_tree_ctrl->UnselectAll();
 }
 
+void LIB_TREE::ExpandLibId( const LIB_ID& aLibId )
+{
+    expandIfValid( m_adapter->FindItem( aLibId ) );
+}
+
 
 void LIB_TREE::Regenerate()
 {
@@ -235,6 +240,12 @@ void LIB_TREE::centerIfValid( const wxDataViewItem& aTreeId )
 }
 
 
+void LIB_TREE::expandIfValid( const wxDataViewItem& aTreeId )
+{
+    if( aTreeId.IsOk() && !m_tree_ctrl->IsExpanded( aTreeId ) )
+        m_tree_ctrl->Expand( aTreeId );
+}
+
 
 void LIB_TREE::postPreselectEvent()
 {
diff --git a/common/widgets/lib_tree.h b/common/widgets/lib_tree.h
index 0e7679935b..822e8cbf4f 100644
--- a/common/widgets/lib_tree.h
+++ b/common/widgets/lib_tree.h
@@ -84,6 +84,11 @@ public:
      */
     void Unselect();
 
+    /**
+     * Expand and item i the tree widget.
+     */
+    void ExpandLibId( const LIB_ID& aLibId );
+
     /**
      * Associates a right click context menu for a specific node type.
      * @param aType is the node type to have a menu associated.
@@ -123,6 +128,8 @@ protected:
 
     void centerIfValid( const wxDataViewItem& aTreeId );
 
+    void expandIfValid( const wxDataViewItem& aTreeId );
+
     /**
      * Post a wxEVT_DATAVIEW_SELECTION_CHANGED to notify the selection handler
      * that a new part has been preselected.
diff --git a/eeschema/lib_edit_frame.cpp b/eeschema/lib_edit_frame.cpp
index 82a9eb246a..42bd511dad 100644
--- a/eeschema/lib_edit_frame.cpp
+++ b/eeschema/lib_edit_frame.cpp
@@ -31,6 +31,7 @@
 #include <fctsys.h>
 #include <pgm_base.h>
 #include <kiface_i.h>
+#include <kiway_express.h>
 #include <class_drawpanel.h>
 #include <base_screen.h>
 #include <confirm.h>
@@ -1658,3 +1659,52 @@ void LIB_EDIT_FRAME::ShowChangedLanguage()
     UpdateMsgPanel();
 }
 
+
+void LIB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
+{
+    const std::string& payload = mail.GetPayload();
+
+    switch( mail.Command() )
+    {
+    case MAIL_LIB_EDIT:
+        if( !payload.empty() )
+        {
+            wxString libFileName( payload );
+            wxString libNickname;
+            wxString msg;
+
+            SYMBOL_LIB_TABLE*    libTable = Prj().SchSymbolLibTable();
+            const LIB_TABLE_ROW* libTableRow = libTable->FindRowByURI( libFileName );
+
+            if( !libTableRow )
+            {
+                msg.Printf( _( "The current configuration does not include the symbol library\n"
+                               "\"%s\".\nUse Manage Symbol Libraries to edit the configuration." ),
+                            libFileName );
+                DisplayErrorMessage( this, _( "Library not found in symbol library table." ), msg );
+                break;
+            }
+
+            libNickname = libTableRow->GetNickName();
+
+            if( !libTable->HasLibrary( libNickname, true ) )
+            {
+                msg.Printf( _( "The library with the nickname \"%s\" is not enabled\n"
+                               "in the current configuration.  Use Manage Symbol Libraries to\n"
+                               "edit the configuration." ), libNickname );
+                DisplayErrorMessage( this, _( "Symbol library not enabled." ), msg );
+                break;
+            }
+
+            SetCurLib( libNickname );
+
+            if( m_treePane )
+                m_treePane->GetLibTree()->ExpandLibId( LIB_ID( libNickname, wxEmptyString ) );
+        }
+
+        break;
+
+    default:
+        ;
+    }
+}
diff --git a/eeschema/lib_edit_frame.h b/eeschema/lib_edit_frame.h
index b23cd0fac0..242b9c02b5 100644
--- a/eeschema/lib_edit_frame.h
+++ b/eeschema/lib_edit_frame.h
@@ -703,6 +703,8 @@ public:
 
     void ShowChangedLanguage() override;
 
+    void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
+
 private:
     ///> Helper screen used when no part is loaded
     SCH_SCREEN* m_dummyScreen;
diff --git a/include/mail_type.h b/include/mail_type.h
index 93b3dca934..ebb81d5f30 100644
--- a/include/mail_type.h
+++ b/include/mail_type.h
@@ -48,6 +48,9 @@ enum MAIL_T
     MAIL_SCH_PCB_UPDATE_REQUEST,
     MAIL_SCH_REFRESH,               ///< The the schematic editor to refresh the display.
 
+    MAIL_LIB_EDIT,
+    MAIL_FP_EDIT,
+
     ///< General-puspose messages
     MAIL_STATUS
 };
diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp
index d5960a6670..ee73254679 100644
--- a/kicad/mainframe.cpp
+++ b/kicad/mainframe.cpp
@@ -283,32 +283,20 @@ void KICAD_MANAGER_FRAME::Execute( wxWindow* frame, const wxString& execFile,
 
 void KICAD_MANAGER_FRAME::RunEeschema( const wxString& aProjectSchematicFileName )
 {
-    KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, false );
+    KIWAY_PLAYER* frame;
 
-    // Please: note: DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::initBuffers() calls
-    // Kiway.Player( FRAME_SCH, true )
-    // therefore, the schematic editor is sometimes running, but the schematic project
-    // is not loaded, if the library editor was called, and the dialog field editor was used.
-    // On linux, it happens the first time the schematic editor is launched, if
-    // library editor was running, and the dialog field editor was open
-    // On Windows, it happens always after the library editor was called,
-    // and the dialog field editor was used
-    if( !frame )
+    try
     {
-        try
-        {
-            frame = Kiway().Player( FRAME_SCH, true );
-        }
-        catch( const IO_ERROR& err )
-        {
-            wxMessageBox( _( "Eeschema failed to load:\n" ) + err.What(),
-                          _( "KiCad Error" ), wxOK | wxICON_ERROR, this );
-            return;
-        }
+        frame = Kiway().Player( FRAME_SCH, true );
+    }
+    catch( const IO_ERROR& err )
+    {
+        wxMessageBox( _( "Eeschema failed to load:\n" ) + err.What(),
+                      _( "KiCad Error" ), wxOK | wxICON_ERROR, this );
+        return;
     }
 
-    if( !frame->IsShown() ) // the frame exists, (created by the dialog field editor)
-                            // but no project loaded.
+    if( !frame->IsShown() ) // A hidden frame might not have the project loaded.
     {
         frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectSchematicFileName ) );
         frame->Show( true );
@@ -338,23 +326,21 @@ void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event )
 
 void KICAD_MANAGER_FRAME::OnRunSchLibEditor( wxCommandEvent& event )
 {
-    KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_LIB_EDITOR, false );
+    KIWAY_PLAYER* frame;
 
-    if( !frame )
+    try
     {
-        try
-        {
-            frame = Kiway().Player( FRAME_SCH_LIB_EDITOR, true );
-        }
-        catch( const IO_ERROR& err )
-        {
-            wxMessageBox( _( "Component library editor failed to load:\n" ) + err.What(),
-                          _( "KiCad Error" ), wxOK | wxICON_ERROR, this );
-            return;
-        }
-
-        frame->Show( true );
+        frame = Kiway().Player( FRAME_SCH_LIB_EDITOR, true );
     }
+    catch( const IO_ERROR& err )
+    {
+        wxMessageBox( _( "Component library editor failed to load:\n" ) + err.What(),
+                      _( "KiCad Error" ), wxOK | wxICON_ERROR, this );
+        return;
+    }
+
+    if( !frame->IsShown() )
+        frame->Show( true );
 
     // On Windows, Raise() does not bring the window on screen, when iconized
     if( frame->IsIconized() )
@@ -379,10 +365,7 @@ void KICAD_MANAGER_FRAME::RunPcbNew( const wxString& aProjectBoardFileName )
         return;
     }
 
-    // a pcb frame can be already existing, but not yet used.
-    // this is the case when running the footprint editor, or the footprint viewer first
-    // if the frame is not visible, the board is not yet loaded
-    if( !frame->IsVisible() )
+    if( !frame->IsVisible() )   // A hidden frame might not have the board loaded.
     {
         frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectBoardFileName ) );
         frame->Show( true );
@@ -410,23 +393,21 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event )
 
 void KICAD_MANAGER_FRAME::OnRunPcbFpEditor( wxCommandEvent& event )
 {
-    KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_EDITOR, false );
+    KIWAY_PLAYER* frame;
 
-    if( !frame )
+    try
     {
-        try
-        {
-            frame = Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
-        }
-        catch( const IO_ERROR& err )
-        {
-            wxMessageBox( _( "Footprint library editor failed to load:\n" ) + err.What(),
-                          _( "KiCad Error" ), wxOK | wxICON_ERROR, this );
-            return;
-        }
-
-        frame->Show( true );
+        frame = Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
     }
+    catch( const IO_ERROR& err )
+    {
+        wxMessageBox( _( "Footprint library editor failed to load:\n" ) + err.What(),
+                      _( "KiCad Error" ), wxOK | wxICON_ERROR, this );
+        return;
+    }
+
+    if( !frame->IsShown() )
+        frame->Show( true );
 
     // On Windows, Raise() does not bring the window on screen, when iconized
     if( frame->IsIconized() )
diff --git a/kicad/treeproject_item.cpp b/kicad/treeproject_item.cpp
index 0b9bbeb150..30d6263060 100644
--- a/kicad/treeproject_item.cpp
+++ b/kicad/treeproject_item.cpp
@@ -33,7 +33,7 @@
 
 #include <gestfich.h>
 #include <executable_names.h>
-
+#include <kiway.h>
 #include "treeprojectfiles.h"
 #include "pgm_kicad.h"
 #include "tree_project_frame.h"
@@ -235,10 +235,9 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* aTreePrjFrame )
         break;
 
     case TREE_NET:
-        // Nothing to do ( can be read only by Pcbnew, or by a text editor)
-        break;
-
+    case TREE_DRILL:
     case TREE_TXT:
+    case TREE_REPORT:
         {
             wxString editorname = Pgm().GetEditorName();
 
@@ -251,6 +250,22 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* aTreePrjFrame )
         frame->Execute( m_parent, PL_EDITOR_EXE, fullFileName );
         break;
 
+    case TREE_FOOTPRINT_FILE:
+        {
+            wxCommandEvent dummy;
+            frame->OnRunPcbFpEditor( dummy );
+            frame->Kiway().ExpressMail( FRAME_PCB_MODULE_EDITOR, MAIL_FP_EDIT, fullFileName );
+        }
+        break;
+
+    case TREE_SCHEMATIC_LIBFILE:
+        {
+            wxCommandEvent dummy;
+            frame->OnRunSchLibEditor( dummy );
+            frame->Kiway().ExpressMail( FRAME_SCH_LIB_EDITOR, MAIL_LIB_EDIT, fullFileName );
+        }
+        break;
+
     default:
         AddDelimiterString( fullFileName );
         OpenFile( fullFileName );
diff --git a/pcbnew/footprint_edit_frame.h b/pcbnew/footprint_edit_frame.h
index a719882200..e51206e572 100644
--- a/pcbnew/footprint_edit_frame.h
+++ b/pcbnew/footprint_edit_frame.h
@@ -507,6 +507,7 @@ public:
      */
     void UpdateMsgPanel() override;
 
+    void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
 
     DECLARE_EVENT_TABLE()
 
diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp
index 6f7134f7bf..31f5dc52a6 100644
--- a/pcbnew/footprint_editor_utils.cpp
+++ b/pcbnew/footprint_editor_utils.cpp
@@ -29,6 +29,7 @@
 #include <fctsys.h>
 #include <kiface_i.h>
 #include <kiway.h>
+#include <kiway_express.h>
 #include <class_drawpanel.h>
 #include <pcb_draw_panel_gal.h>
 #include <confirm.h>
@@ -1105,3 +1106,57 @@ bool FOOTPRINT_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileS
 
     return true;
 }
+
+
+void FOOTPRINT_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
+{
+    const std::string& payload = mail.GetPayload();
+
+    switch( mail.Command() )
+    {
+    case MAIL_FP_EDIT:
+        if( !payload.empty() )
+        {
+            wxFileName fpFileName( payload );
+            wxString libNickname;
+            wxString msg;
+
+            FP_LIB_TABLE*        libTable = Prj().PcbFootprintLibs();
+            const LIB_TABLE_ROW* libTableRow = libTable->FindRowByURI( fpFileName.GetPath() );
+
+            if( !libTableRow )
+            {
+                msg.Printf( _( "The current configuration does not include the footprint library\n"
+                               "\"%s\".\nUse Manage Footprint Libraries to edit the configuration." ),
+                            fpFileName.GetPath() );
+                DisplayErrorMessage( this, _( "Library not found in footprint library table." ), msg );
+                break;
+            }
+
+            libNickname = libTableRow->GetNickName();
+
+            if( !libTable->HasLibrary( libNickname, true ) )
+            {
+                msg.Printf( _( "The library with the nickname \"%s\" is not enabled\n"
+                               "in the current configuration.  Use Manage Footprint Libraries to\n"
+                               "edit the configuration." ), libNickname );
+                DisplayErrorMessage( this, _( "Footprint library not enabled." ), msg );
+                break;
+            }
+
+            LIB_ID  fpId( libNickname, fpFileName.GetName() );
+
+            if( m_treePane )
+            {
+                m_treePane->GetLibTree()->SelectLibId( fpId );
+                wxCommandEvent event( COMPONENT_SELECTED );
+                wxPostEvent( m_treePane, event );
+            }
+        }
+
+        break;
+
+    default:
+        ;
+    }
+}