'Flutter PDF Viewer for Linux desktop

I developing some kind of chat application with PDF viewing functions on Flutter for Android and Linux desktop platforms.

So i want to embed PDF viewer in flutter application using some kind of PDF reader or WebBrowser. There is no problems with PDF's on Android - more than 100 plugins on pub.dev for PDF's and WebViews, but none of them supported Linux desktop.

I have tried to add Linux desktop support for Android and IOS plugins, but look's like all of them using PlatformView and webview_flutter classes, which not supported on Linux desktop yet: webview_flutter PlatformView. They have P4 priority and no milestone assigned. I can't wait undefinitely long time, i should end this project in 2 months. So what should i do?

I have read that Flutter uses GTK+ to display on Linux desktop, and i know that there is GTK+ components to display PDF. So is it possible to inject somehow this component in flutter ui? Is there any example?

Or maybe better will be to convert PDF in jpeg and show images instead? (But i don't want lost zoom and document navigation)

Opening PDF into external program with File.Open() is not solution for me, because in this case user's should constantly switch between flutter app (where we have list of PDF files) and PDF reader windows.

I am new to both Flutter and Linux, so any help would be appreciated.



Solution 1:[1]

So just to clarify how we can achive this using webkit, as example:

CMakeLists.txt:

#add webkit package reference
pkg_check_modules(WEBKIT2 REQUIRED IMPORTED_TARGET webkit2gtk-4.0)
...
#remove -Werror flag to allow compilation with warnings
target_compile_options(${TARGET} PRIVATE -Wall)
...
#link webkit libraries
target_link_libraries(${BINARY_NAME} PUBLIC PkgConfig::WEBKIT2) 
#somehow this line causes 'flutter run' to crash on "Linking CXX executable" step.
#Looks like it compiles, but fails to link. 
#I think there is should be other question opened for this issue. 

my_application.cc:

#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#include <webkit2/webkit2.h>
#include "flutter/generated_plugin_registrant.h"

static void my_application_activate(GApplication* application) {

  GtkWidget *vbox1 = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox1);

  // we can insert any gtk controls in this window outside of FlView
  GtkWidget *label = gtk_label_new ("Hello GNOME!");
  gtk_box_pack_start (GTK_BOX (vbox1), label, TRUE, TRUE, 2);
  gtk_widget_show (label);

  // webkit/poppler/evince should work perfect because they gtk+
  WebKitWebView *pWebKitView = WEBKIT_WEB_VIEW(webkit_web_view_new());
  gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET(pWebKitView), TRUE, TRUE, 2);
  gtk_widget_show(GTK_WIDGET(pWebKitView));

  // finally add FlView
  g_autoptr(FlDartProject) project = fl_dart_project_new();
  FlView *view = fl_view_new(project);
  gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET(view), TRUE, TRUE, 2);
  gtk_widget_show (GTK_WIDGET (view));

  GtkWindow* window =
  GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
  gtk_container_add (GTK_CONTAINER (window), vbox1);

  fl_register_plugins(FL_PLUGIN_REGISTRY(view));
  gtk_widget_grab_focus(GTK_WIDGET(view));

  GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
  gtk_widget_show(GTK_WIDGET(header_bar));
  gtk_header_bar_set_title(header_bar, "client");
  gtk_header_bar_set_show_close_button(header_bar, TRUE);
  gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
  gtk_window_set_default_size(window, 1280, 720);

  gtk_widget_show(GTK_WIDGET(window));
}

Solution 2:[2]

So is it possible to inject somehow this component in flutter ui?

That is exactly what PlatformView is, so that's equivalent to the question of whether PlatformView is supported on Linux.

Two options that could work without PlatformView support:

  • Swap the window between displaying the Flutter view and a PDF view (if you want the PDF to fill the window while displayed).
  • Place the Flutter view and the PDF view side by side in the window (if you want both Flutter content—like your list of files—and PDF content visible at the same time).

Both would require the work to be done in the native code, so you would need to either write a plugin, or implement it directly in your runner, and use a method channel to coordinate between Dart and native code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 DotNetAdept
Solution 2 smorgan