diff libgui/src/m-editor/file-editor.cc @ 28382:2b52e473b6ef stable

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
author Torsten Lilge <ttl-octave@mailbox.org>
date Tue, 26 May 2020 06:59:45 +0200
parents ec769a7ab9fb
children f3200b8cff19 d0a64e67749e
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor.cc	Mon May 25 14:53:54 2020 -0700
+++ b/libgui/src/m-editor/file-editor.cc	Tue May 26 06:59:45 2020 +0200
@@ -94,6 +94,7 @@
     return retval;
   }
 
+
   // File editor
 
   file_editor::file_editor (QWidget *p, base_qobject& oct_qobj)
@@ -122,6 +123,7 @@
 
     setVisible (false);
     setAcceptDrops (true);
+    setFocusPolicy (Qt::StrongFocus);
   }
 
   file_editor::~file_editor (void)
@@ -129,6 +131,18 @@
     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 @@
     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 @@
         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 @@
     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 @@
              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)));