Skip to content

Commit

Permalink
Linux support now stable
Browse files Browse the repository at this point in the history
  • Loading branch information
bitsdojo committed Jun 9, 2021
1 parent f2d8dfa commit e79b2c7
Show file tree
Hide file tree
Showing 33 changed files with 1,271 additions and 174 deletions.
29 changes: 29 additions & 0 deletions bitsdojo_window/example/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
4 changes: 0 additions & 4 deletions bitsdojo_window/example/linux/flutter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid)
pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma)

set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")

Expand Down Expand Up @@ -67,8 +65,6 @@ target_link_libraries(flutter INTERFACE
PkgConfig::GTK
PkgConfig::GLIB
PkgConfig::GIO
PkgConfig::BLKID
PkgConfig::LZMA
)
add_dependencies(flutter flutter_assemble)

Expand Down
29 changes: 14 additions & 15 deletions bitsdojo_window/example/linux/my_application.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
#include "my_application.h"

#include <flutter_linux/flutter_linux.h>
Expand Down Expand Up @@ -27,31 +28,29 @@ static void my_application_activate(GApplication* application) {
// in case the window manager does more exotic layout, e.g. tiling.
// If running on Wayland assume the header bar will work (may need changing
// if future cases occur).
gboolean use_header_bar = FALSE;
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
GdkScreen *screen = gtk_window_get_screen(window);
GdkScreen* screen = gtk_window_get_screen(window);
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
}
#endif
if (use_header_bar) {
GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "example");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
}
else {
// Use an empty header bar so that gtk doesn't show the title bar but still retains window resize controls
GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else {
gtk_window_set_title(window, "example");
}

gtk_window_set_default_size(window, 1280, 720);
auto bdw = bitsdojo_window_from(window);
bdw->setCustomFrame(true);
//gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));

g_autoptr(FlDartProject) project = fl_dart_project_new();
Expand All @@ -67,7 +66,7 @@ static void my_application_activate(GApplication* application) {
}

// Implements GApplication::local_command_line.
static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) {
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
MyApplication* self = MY_APPLICATION(application);
// Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
Expand All @@ -86,7 +85,7 @@ static gboolean my_application_local_command_line(GApplication* application, gch
}

// Implements GObject::dispose.
static void my_application_dispose(GObject *object) {
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Generated file. Do not edit.
//

// clang-format off

import FlutterMacOS
import Foundation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Generated file. Do not edit.
//

// clang-format off

#include "generated_plugin_registrant.h"

#include <bitsdojo_window_windows/bitsdojo_window_plugin.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Generated file. Do not edit.
//

// clang-format off

#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_

Expand Down
4 changes: 2 additions & 2 deletions bitsdojo_window/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ dependencies:
#path: ../bitsdojo_window_windows
bitsdojo_window_macos: ^0.1.0
#path: ../bitsdojo_window_macos
bitsdojo_window_linux: ^0.1.0+1
#path: ../bitsdojo_window_linux
bitsdojo_window_linux: #^0.1.0
path: ../bitsdojo_window_linux
2 changes: 2 additions & 0 deletions bitsdojo_window_linux/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## 0.1.1
- Linux support now stable
## 0.1.0+1
- Fix gtk library name
## 0.1.0
Expand Down
10 changes: 2 additions & 8 deletions bitsdojo_window_linux/lib/src/app_window.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
library bitsdojo_window_linux;

import './native_api.dart';
import './native_api.dart' as native;
import './window.dart';

const notInitializedMessage = """
Expand All @@ -13,13 +13,7 @@ class BitsDojoNotInitializedException implements Exception {

class GtkAppWindow extends GtkWindow {
GtkAppWindow._() {
super.handle = getFlutterWindow();
//TODO - implement this check
/*final isLoaded = isBitsdojoWindowLoaded();
if (!isLoaded) {
print(notInitializedMessage);
throw BitsDojoNotInitializedException;
}*/
super.handle = native.getAppWindowHandle();
assert(handle != null, "Could not get Flutter window");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ library bitsdojo_window_linux;

import 'dart:ui';
import 'package:bitsdojo_window_platform_interface/bitsdojo_window_platform_interface.dart';

import './window.dart';
import './app_window.dart';
import 'package:flutter/widgets.dart';

Expand All @@ -12,7 +12,9 @@ class BitsdojoWindowLinux extends BitsdojoWindowPlatform {
@override
void doWhenWindowReady(VoidCallback callback) {
WidgetsBinding.instance!.waitUntilFirstFrameRasterized.then((value) {
isInsideDoWhenWindowReady = true;
callback();
isInsideDoWhenWindowReady = false;
});
}

Expand Down
124 changes: 112 additions & 12 deletions bitsdojo_window_linux/lib/src/native_api.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,121 @@
library bitsdojo_window_linux;

import 'dart:ffi';
import 'package:ffi/ffi.dart';

final DynamicLibrary _appExecutable = DynamicLibrary.executable();

final getFlutterWindow =
_appExecutable.lookupFunction<IntPtr Function(), int Function()>(
"bitsdojo_window_getFlutterWindow");
// getAppWindowHandle
typedef IntPtr TGetAppWindowHandle();
typedef DGetAppWindowHandle = int Function();
final DGetAppWindowHandle getAppWindowHandle =
_theAPI.ref.getAppWindowHandle.asFunction();

final getFlutterGdkWindow =
_appExecutable.lookupFunction<IntPtr Function(), int Function()>(
"bitsdojo_window_getFlutterGdkWindow");
// getScreenRect
typedef Void TGetScreenRect(IntPtr window, Pointer<Int32> x, Pointer<Int32> y,
Pointer<Int32> width, Pointer<Int32> height);
typedef DGetScreenRect = void Function(int window, Pointer<Int32> x,
Pointer<Int32> y, Pointer<Int32> width, Pointer<Int32> height);
final DGetScreenRect getScreenRect = _theAPI.ref.getScreenRect.asFunction();

final setMinSize = _appExecutable.lookupFunction<
Void Function(Int32 width, Int32 height),
void Function(int width, int height)>("bitsdojo_window_setMinSize");
// getScaleFactor
typedef Void TGetScaleFactor(IntPtr window, Pointer<Int32> scaleFactor);
typedef DGetScaleFactor = void Function(int window, Pointer<Int32> scaleFactor);
final DGetScaleFactor getScaleFactor = _theAPI.ref.getScaleFactor.asFunction();

final setMaxSize = _appExecutable.lookupFunction<
Void Function(Int32 width, Int32 height),
void Function(int width, int height)>("bitsdojo_window_setMaxSize");
// getPosition
typedef Void TGetPosition(IntPtr window, Pointer<Int32> x, Pointer<Int32> y);
typedef DGetPosition = void Function(
int window, Pointer<Int32> x, Pointer<Int32> y);
final DGetPosition getPosition = _theAPI.ref.getPosition.asFunction();

// setPosition
typedef Void TSetPosition(IntPtr window, Int32 x, Int32 y);
typedef DSetPosition = void Function(int window, int x, int y);
final DSetPosition setPosition = _theAPI.ref.setPosition.asFunction();

// getSize
typedef Void TGetSize(
IntPtr window, Pointer<Int32> width, Pointer<Int32> height);
typedef DGetSize = void Function(
int window, Pointer<Int32> width, Pointer<Int32> height);
final DGetSize getSize = _theAPI.ref.getSize.asFunction();

// setSize
typedef Void TSetSize(IntPtr window, Int32 width, Int32 height);
typedef DSetSize = void Function(int window, int width, int height);
final DSetSize setSize = _theAPI.ref.setSize.asFunction();
// setRect
typedef Void TSetRect(
IntPtr window, Int32 x, Int32 y, Int32 width, Int32 height);
typedef DSetRect = void Function(
int window, int x, int y, int width, int height);
final DSetRect setRect = _theAPI.ref.setRect.asFunction();

// setMinSize
typedef Void TSetMinSize(IntPtr window, Int32 width, Int32 height);
typedef DSetMinSize = void Function(int window, int width, int height);
final DSetMinSize setMinSize = _theAPI.ref.setMinSize.asFunction();

// setMaxSize
typedef Void TSetMaxSize(IntPtr window, Int32 width, Int32 height);
typedef DSetMaxSize = void Function(int window, int width, int height);
final DSetMinSize setMaxSize = _theAPI.ref.setMaxSize.asFunction();

// showWindow
typedef Void TShowWindow(IntPtr window);
typedef DShowWindow = void Function(int window);
final DShowWindow showWindow = _theAPI.ref.showWindow.asFunction();

// hideWindow
typedef Void THideWindow(IntPtr window);
typedef DHideWindow = void Function(int window);
final DHideWindow hideWindow = _theAPI.ref.hideWindow.asFunction();

// maximizeWindow
typedef Void TMinimizeWindow(IntPtr window);
typedef DMinimizeWindow = void Function(int window);
final DMinimizeWindow minimizeWindow = _theAPI.ref.minimizeWindow.asFunction();

// maximizeWindow
typedef Void TMaximizeWindow(IntPtr window);
typedef DMaximizeWindow = void Function(int window);
final DMaximizeWindow maximizeWindow = _theAPI.ref.maximizeWindow.asFunction();

// unmaximizeWindow
typedef Void TUnmaximizeWindow(IntPtr window);
typedef DUnmaximizeWindow = void Function(int window);
final DMaximizeWindow unmaximizeWindow =
_theAPI.ref.unmaximizeWindow.asFunction();

// setWindowTitle
typedef Void TSetWindowTitle(IntPtr window, Pointer<Utf8> title);
typedef DSetWindowTitle = void Function(int window, Pointer<Utf8> title);
final DSetWindowTitle setWindowTitle = _theAPI.ref.setWindowTitle.asFunction();

class BDWAPI extends Struct {
external Pointer<NativeFunction<TGetAppWindowHandle>> getAppWindowHandle;
external Pointer<NativeFunction<TGetScreenRect>> getScreenRect;
external Pointer<NativeFunction<TGetScaleFactor>> getScaleFactor;
external Pointer<NativeFunction<TGetPosition>> getPosition;
external Pointer<NativeFunction<TSetPosition>> setPosition;
external Pointer<NativeFunction<TGetSize>> getSize;
external Pointer<NativeFunction<TSetSize>> setSize;
external Pointer<NativeFunction<TSetRect>> setRect;
external Pointer<NativeFunction<TSetMinSize>> setMinSize;
external Pointer<NativeFunction<TSetMaxSize>> setMaxSize;
external Pointer<NativeFunction<TShowWindow>> showWindow;
external Pointer<NativeFunction<THideWindow>> hideWindow;
external Pointer<NativeFunction<TMinimizeWindow>> minimizeWindow;
external Pointer<NativeFunction<TMaximizeWindow>> maximizeWindow;
external Pointer<NativeFunction<TUnmaximizeWindow>> unmaximizeWindow;
external Pointer<NativeFunction<TSetWindowTitle>> setWindowTitle;
}

typedef Pointer<BDWAPI> TBitsdojoWindowAPI();

final TBitsdojoWindowAPI bitsdojoWindowAPI = _appExecutable
.lookup<NativeFunction<TBitsdojoWindowAPI>>("bitsdojo_window_api")
.asFunction();

final Pointer<BDWAPI> _theAPI = bitsdojoWindowAPI();
5 changes: 0 additions & 5 deletions bitsdojo_window_linux/lib/src/plugin_channel.dart

This file was deleted.

Loading

0 comments on commit e79b2c7

Please sign in to comment.