[master] 0f335ab - Improve kdialog-based native file chooser.

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 0f335ab - Improve kdialog-based native file chooser. "ManoloFLTK" 03:47 Jan 16 top right image
 
commit 0f335ab4409943ff59dd0c542e9a3c9947c911d7
Author:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Sun Jan 16 12:33:26 2022 +0100
Commit:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Sun Jan 16 12:33:26 2022 +0100

    Improve kdialog-based native file chooser.
    
    Processing of all FLTK events as well as window resizing while the file chooser runs is suspended,
    Normal event processing and resizing is restored when chooser closes.

 src/Fl_Native_File_Chooser_Kdialog.H   |  7 ++-
 src/Fl_Native_File_Chooser_Kdialog.cxx | 82 ++++++++++++++++++++++++++++------
 2 files changed, 74 insertions(+), 15 deletions(-)

diff --git src/Fl_Native_File_Chooser_Kdialog.H src/Fl_Native_File_Chooser_Kdialog.H
index 730b25e..f73242c 100644
--- src/Fl_Native_File_Chooser_Kdialog.H
+++ src/Fl_Native_File_Chooser_Kdialog.H
@@ -1,7 +1,7 @@
 //
 // FLTK native file chooser widget : KDE version
 //
-// Copyright 2021 by Bill Spitzak and others.
+// Copyright 2021-2022 by Bill Spitzak and others.
 //
 // This library is free software. Distribution and use rights are outlined in
 // the file "COPYING" which should have been included with this file.  If this
@@ -21,6 +21,11 @@
 
 class FL_EXPORT Fl_Kdialog_Native_File_Chooser_Driver : public Fl_Native_File_Chooser_FLTK_Driver {
   friend class Fl_Native_File_Chooser;
+  struct fnfc_pipe_struct {
+    char *all_files;
+    int fd;
+  };
+  static void fnfc_fd_cb(int fd, fnfc_pipe_struct *data);
   char **_pathnames;
   int _tpathnames;
   char *_directory;
diff --git src/Fl_Native_File_Chooser_Kdialog.cxx src/Fl_Native_File_Chooser_Kdialog.cxx
index 6f2298b..368a2b6 100644
--- src/Fl_Native_File_Chooser_Kdialog.cxx
+++ src/Fl_Native_File_Chooser_Kdialog.cxx
@@ -1,7 +1,7 @@
 //
 // FLTK native file chooser widget : KDE version
 //
-// Copyright 2021 by Bill Spitzak and others.
+// Copyright 2021-2022 by Bill Spitzak and others.
 //
 // This library is free software. Distribution and use rights are outlined in
 // the file "COPYING" which should have been included with this file.  If this
@@ -17,10 +17,11 @@
 #include <config.h>
 #include <FL/Fl_Native_File_Chooser.H>
 #include "Fl_Native_File_Chooser_Kdialog.H"
-
+#include "Fl_Window_Driver.H"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 
 /* Fl_Kdialog_Native_File_Chooser_Driver : file chooser based on the "kdialog" command */
@@ -47,8 +48,25 @@ Fl_Kdialog_Native_File_Chooser_Driver::~Fl_Kdialog_Native_File_Chooser_Driver()
 }
 
 
+void Fl_Kdialog_Native_File_Chooser_Driver::fnfc_fd_cb(int fd,
+                      Fl_Kdialog_Native_File_Chooser_Driver::fnfc_pipe_struct *data) {
+  char tmp[FL_PATH_MAX];
+  int l = read(fd, tmp, sizeof(tmp)-1);
+  if (l > 0) {
+    tmp[l] = 0;
+    data->all_files = Fl_Native_File_Chooser_Driver::strapp(data->all_files, tmp);
+  } else {
+    data->fd = -1;
+  }
+}
+
+
+static int fnfc_dispatch(int /*event*/, Fl_Window* /*win*/) {
+  return 0;
+}
+
+
 int Fl_Kdialog_Native_File_Chooser_Driver::show() {
-  Fl::flush(); // to close menus if necessary
   const char *option;
   switch (_btype) {
     case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY: {
@@ -103,25 +121,61 @@ int Fl_Kdialog_Native_File_Chooser_Driver::show() {
   strcat(command, "2> /dev/null"); // get rid of stderr output
 //puts(command);
   FILE *pipe = popen(command, "r");
-  char *all_files = NULL;
+  fnfc_pipe_struct data;
+  data.all_files = NULL;
   if (pipe) {
-    char *p, tmp[FL_PATH_MAX];
-    do {
-      p = fgets(tmp, sizeof(tmp), pipe);
-      if (p) all_files = strapp(all_files, p);
+    data.fd = fileno(pipe);
+    Fl::add_fd(data.fd, FL_READ, (Fl_FD_Handler)fnfc_fd_cb, &data);
+    Fl_Event_Dispatch old_dispatch = Fl::event_dispatch();
+    // prevent FLTK from processing any event
+    Fl::event_dispatch(fnfc_dispatch);
+    struct win_dims {
+      Fl_Window *win;
+      int minw,minh,maxw,maxh;
+      struct win_dims *next;
+    } *first_dim = NULL;
+    // consider all bordered, top-level FLTK windows
+    Fl_Window *win = Fl::first_window();
+    while (win) {
+      if (!win->parent() && win->border()) {
+        Fl_Window_Driver *dr = Fl_Window_Driver::driver(win);
+        win_dims *dim = new win_dims;
+        dim->win = win;
+        dim->minw = dr->minw();
+        dim->minh = dr->minh();
+        dim->maxw = dr->maxw();
+        dim->maxh = dr->maxh();
+        //make win un-resizable
+        win->size_range(win->w(), win->h(), win->w(), win->h());
+        dim->next = first_dim;
+        first_dim = dim;
+      }
+      win = Fl::next_window(win);
     }
-    while (p);
+    // run event loop until pipe finishes
+    while (data.fd >= 0) Fl::wait();
+    Fl::remove_fd(fileno(pipe));
     pclose(pipe);
-    if (all_files) {
-      if (all_files[strlen(all_files)-1] == '\n') all_files[strlen(all_files)-1] = 0;
+    // return to previous event processing by FLTK
+    Fl::event_dispatch(old_dispatch);
+    while (first_dim) {
+      win_dims *dim = first_dim;
+      //give back win its resizing parameters
+      dim->win->size_range(dim->minw, dim->minh, dim->maxw, dim->maxh);
+      first_dim = dim->next;
+      delete dim;
+    }
+    if (data.all_files) {
+      // process text received from pipe
+      if (data.all_files[strlen(data.all_files)-1] == '\n') data.all_files[strlen(data.all_files)-1] = 0;
       for (int i = 0; i < _tpathnames; i++) delete[] _pathnames[i];
       delete[] _pathnames;
-      p = all_files;
+      char *p = data.all_files;
       int count = 1;
       while ((p = strchr(p+1, ' '))) count++;
       _pathnames = new char*[count];
       _tpathnames = 0;
-      char *q = strtok(all_files, " ");
+      char *q = strtok(data.all_files, " ");
       while (q) {
         _pathnames[_tpathnames] = new char[strlen(q)+1];
         strcpy(_pathnames[_tpathnames], q);
@@ -133,7 +187,7 @@ int Fl_Kdialog_Native_File_Chooser_Driver::show() {
   delete[] command;
   if (_title) { free(_title); _title = NULL; }
   if (!pipe) return -1;
-  return (all_files == NULL ? 1 : 0);
+  return (data.all_files == NULL ? 1 : 0);
 }
 
 
Direct Link to Message ]
 
bottom left image   bottom right image
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2022 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.