# HG changeset patch
# User Torsten Lilge <ttl-octave@mailbox.org>
# Date 1590267052 -7200
#      Sat May 23 22:50:52 2020 +0200
# Branch stable
# Node ID baf65d046506696d6f2a7d31aaa951fb29e17d8a
# Parent  2a4c4c7dfc88bca15aece672da617c56097da026
fix focus issues in editor due to qt bug with focus proxy chains (bug #57635)

* file-editor-tab.cc (file_editor_tab): initialize flag for actuve lists,
  do not set a focus proxy;
  (show_auto_completion): set flag for active list;
  (handle_cursor_moved): test for active list and emit signal if a
  list was closed

* file-editor-tab.h: new flag m_atuoc_active and new signal
  autoc_closed

* file-editor.cc (activate): do not emit signal for focussing current
  editor tab but call new method reset_focus where the signal is emitted;
  (handle_editor_state_changed): do not set a focus proxy;
  (construct): set tab widget as focus proxy;
  (handle_autoc_cancelled): slot for signal when auto-completion list
  is cancelled, complete the list for really closing it;
  (reset_focus): new method for resetting focus to the editor tab
  (make_file_editor_tab): connect signals for cancelled, completed and
  closed auto-completion list to related new slots
  (foucsInEvent): reimplemented event for setting the foucs to
  the edit tab and its edit area

* file-editor.h: new slots handle_autoc_cancelled and reset_focus,
  reimplemented focusInEvent

diff -r 2a4c4c7dfc88 -r baf65d046506 libgui/src/m-editor/file-editor-tab.cc
--- a/libgui/src/m-editor/file-editor-tab.cc	Fri May 22 18:47:16 2020 -0400
+++ b/libgui/src/m-editor/file-editor-tab.cc	Sat May 23 22:50:52 2020 +0200
@@ -106,6 +106,7 @@ namespace octave
     m_lexer_apis = nullptr;
     m_is_octave_file = true;
     m_lines_changed = false;
+    m_autoc_active = false;
 
     m_ced = directory_arg;
 
@@ -263,8 +264,6 @@ namespace octave
     if (settings)
       notice_settings (settings, true);
 
-    setFocusProxy (m_edit_area);
-
     // encoding, not updated with the settings
     QString locale_enc_name =
       QString ("SYSTEM (") +
@@ -1447,6 +1446,8 @@ namespace octave
     if (ID != this)
       return;
 
+    m_autoc_active = true;
+
     QsciScintilla::AutoCompletionSource s = m_edit_area->autoCompletionSource ();
     switch (s)
       {
@@ -3022,9 +3023,19 @@ namespace octave
 
   void file_editor_tab::handle_cursor_moved (int line, int col)
   {
+    // Cursor has moved, first check wether an autocompletion list
+    // is active or if it was closed. Scintilla provides signals for
+    // completed or cancelled lists, but not for list that where hidden
+    // due to a new character not matching anymore with the list entries
     if (m_edit_area->SendScintilla (QsciScintillaBase::SCI_AUTOCACTIVE))
-      show_auto_completion (this);
-
+      m_autoc_active = true;
+    else if (m_autoc_active)
+      {
+        m_autoc_active = false;
+        emit autoc_closed (); // Tell editor about closed list
+      }
+
+    // Lines changed? Take care of indentation
     if (m_lines_changed)  // cursor moved and lines have changed
       {
         m_lines_changed = false;
@@ -3037,9 +3048,9 @@ namespace octave
           }
       }
 
+    // Update line and column indicator in the status bar
     m_line = line;
     m_col  = col;
-
     m_row_indicator->setNum (line+1);
     m_col_indicator->setNum (col+1);
   }
diff -r 2a4c4c7dfc88 -r baf65d046506 libgui/src/m-editor/file-editor-tab.h
--- a/libgui/src/m-editor/file-editor-tab.h	Fri May 22 18:47:16 2020 -0400
+++ b/libgui/src/m-editor/file-editor-tab.h	Sat May 23 22:50:52 2020 +0200
@@ -86,6 +86,8 @@ namespace octave
     void edit_mfile_request (const QString&, const QString&,
                              const QString&, int);
 
+    void autoc_closed (void);
+
     void update_breakpoints_signal (const octave_value_list& args);
 
     void remove_breakpoint_via_debugger_linenr (int debugger_linenr);
@@ -314,6 +316,7 @@ namespace octave
     QString m_new_encoding;
     QDateTime m_last_modified;
 
+    bool m_autoc_active;
     bool m_long_title;
     bool m_copy_available;
     bool m_is_octave_file;
diff -r 2a4c4c7dfc88 -r baf65d046506 libgui/src/m-editor/file-editor.cc
--- a/libgui/src/m-editor/file-editor.cc	Fri May 22 18:47:16 2020 -0400
+++ b/libgui/src/m-editor/file-editor.cc	Sat May 23 22:50:52 2020 +0200
@@ -94,6 +94,7 @@ namespace octave
     return retval;
   }
 
+
   // File editor
 
   file_editor::file_editor (QWidget *p, base_qobject& oct_qobj)
@@ -122,6 +123,7 @@ namespace octave
 
     setVisible (false);
     setAcceptDrops (true);
+    setFocusPolicy (Qt::StrongFocus);
   }
 
   file_editor::~file_editor (void)
@@ -129,6 +131,18 @@ namespace octave
     delete m_mru_file_menu;
   }
 
+  void file_editor::focusInEvent (QFocusEvent *e)
+  {
+    // The focus is transferred to the active tab and its edit
+    // area in this focus in event handler. This is to avoid
+    // using focus proxies with conflicts in the proxy change
+    // presumably introduced by bug
+    // https://bugreports.qt.io/browse/QTBUG-61092
+    reset_focus (); // Make sure editor tab with edit area get focus
+
+    QDockWidget::focusInEvent (e);
+  }
+
   // insert global actions, that should also be displayed in the editor window,
   // into the editor's menu and/or toolbar
   void file_editor::insert_global_actions (QList<QAction*> shared_actions)
@@ -340,9 +354,7 @@ namespace octave
     octave_dock_widget::activate ();
 
     // set focus to current tab
-    QWidget *fileEditorTab = m_tab_widget->currentWidget ();
-    if (fileEditorTab)
-      emit fetab_set_focus (fileEditorTab);
+    reset_focus ();
   }
 
   void file_editor::set_focus (QWidget *fet)
@@ -965,8 +977,6 @@ namespace octave
         m_cut_action->setEnabled (copy_available);
         m_run_selection_action->setEnabled (copy_available);
         m_run_action->setEnabled (is_octave_file);
-
-        setFocusProxy (m_tab_widget->currentWidget ());
       }
 
     m_copy_action_enabled = m_copy_action->isEnabled ();
@@ -2296,6 +2306,40 @@ namespace octave
     check_actions ();
   }
 
+  // Slot when autocompletion list was cancelled
+  void file_editor::handle_autoc_cancelled (void)
+  {
+    // List was cancelled but somehow still active and blocking the
+    // edit area from accepting shortcuts. Only after another keypress
+    // shortcuts and lists are working againnas expected. This is
+    // probably caused by qt bug https://bugreports.qt.io/browse/QTBUG-83720
+    // Hack: Accept the list, which is hidden but still active
+    //       and undo the text insertion, if any
+
+    file_editor_tab *f = reset_focus ();
+    octave_qscintilla *qsci = f->qsci_edit_area ();
+
+    int line, col;
+    qsci->getCursorPosition (&line, &col);
+    int l1 = qsci->lineLength (line); // Current line length
+
+    // Accept autocompletion
+    qsci->SendScintilla (QsciScintillaBase::SCI_AUTOCCOMPLETE);
+
+    // Was text inserted? If yes, undo
+    if (qsci->text (line).length () - l1)
+      qsci->undo ();
+  }
+
+  file_editor_tab* file_editor::reset_focus (void)
+  {
+    // Reset the focus of the tab and the related edit area
+    file_editor_tab *f
+       = static_cast<file_editor_tab *> (m_tab_widget->currentWidget ());
+     emit fetab_set_focus (f);
+     return f;
+  }
+
   file_editor_tab *
   file_editor::make_file_editor_tab (const QString& directory)
   {
@@ -2319,7 +2363,17 @@ namespace octave
              SIGNAL (focus_console_after_command_signal (void)),
              main_win (), SLOT (focus_console_after_command (void)));
 
+    connect (f->qsci_edit_area (),
+             SIGNAL (SCN_AUTOCCOMPLETED (const char*, int, int, int)),
+             this, SLOT (reset_focus (void)));
+
+    connect (f->qsci_edit_area (), SIGNAL (SCN_AUTOCCANCELLED (void)),
+             this, SLOT (handle_autoc_cancelled (void)));
+
     // Signals from the file editor_tab
+    connect (f, SIGNAL (autoc_closed (void)),
+             this, SLOT (reset_focus (void)));
+
     connect (f, SIGNAL (file_name_changed (const QString&, const QString&, bool)),
              this, SLOT (handle_file_name_changed (const QString&,
                                                    const QString&, bool)));
diff -r 2a4c4c7dfc88 -r baf65d046506 libgui/src/m-editor/file-editor.h
--- a/libgui/src/m-editor/file-editor.h	Fri May 22 18:47:16 2020 -0400
+++ b/libgui/src/m-editor/file-editor.h	Sat May 23 22:50:52 2020 +0200
@@ -274,6 +274,10 @@ namespace octave
 
     void toplevel_change (bool toplevel);
 
+    void handle_autoc_cancelled (void);
+
+    file_editor_tab* reset_focus (void);
+
   protected slots:
 
     void copyClipboard (void);
@@ -311,6 +315,7 @@ namespace octave
     void closeEvent (QCloseEvent *event);
     void dragEnterEvent (QDragEnterEvent *event);
     void dropEvent (QDropEvent *event);
+    void focusInEvent (QFocusEvent *e);
 
   private:
 
