From 7ac866fac3ded22c565936d0fdc4966ca0a234b7 Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 14 Jul 2017 18:36:59 +0200 Subject: [PATCH] Moved JNA to Utility module for use by other applications --- .../systemTray/jna/linux/AppIndicator.java | 198 ------- .../systemTray/jna/linux/FuncCallback.java | 29 - .../systemTray/jna/linux/GCallback.java | 30 - .../systemTray/jna/linux/GEventCallback.java | 28 - src/dorkbox/systemTray/jna/linux/Glib.java | 72 --- src/dorkbox/systemTray/jna/linux/Gobject.java | 75 --- src/dorkbox/systemTray/jna/linux/Gtk.java | 380 ------------- src/dorkbox/systemTray/jna/linux/Gtk2.java | 197 ------- src/dorkbox/systemTray/jna/linux/Gtk3.java | 257 --------- .../jna/linux/GtkEventDispatch.java | 352 ------------ .../systemTray/jna/linux/GtkLoader.java | 210 ------- .../systemTray/jna/linux/GtkState.java | 23 - .../systemTray/jna/linux/GtkTheme.java | 527 ------------------ .../structs/AppIndicatorInstanceStruct.java | 37 -- .../jna/linux/structs/GObjectStruct.java | 46 -- .../linux/structs/GTypeInstanceStruct.java | 44 -- .../jna/linux/structs/GdkColor.java | 88 --- .../jna/linux/structs/GdkEventButton.java | 47 -- .../jna/linux/structs/GtkRequisition.java | 37 -- .../jna/linux/structs/GtkStyle.java | 116 ---- .../jna/linux/structs/PangoRectangle.java | 39 -- 21 files changed, 2832 deletions(-) delete mode 100644 src/dorkbox/systemTray/jna/linux/AppIndicator.java delete mode 100644 src/dorkbox/systemTray/jna/linux/FuncCallback.java delete mode 100644 src/dorkbox/systemTray/jna/linux/GCallback.java delete mode 100644 src/dorkbox/systemTray/jna/linux/GEventCallback.java delete mode 100644 src/dorkbox/systemTray/jna/linux/Glib.java delete mode 100644 src/dorkbox/systemTray/jna/linux/Gobject.java delete mode 100644 src/dorkbox/systemTray/jna/linux/Gtk.java delete mode 100644 src/dorkbox/systemTray/jna/linux/Gtk2.java delete mode 100644 src/dorkbox/systemTray/jna/linux/Gtk3.java delete mode 100644 src/dorkbox/systemTray/jna/linux/GtkEventDispatch.java delete mode 100644 src/dorkbox/systemTray/jna/linux/GtkLoader.java delete mode 100644 src/dorkbox/systemTray/jna/linux/GtkState.java delete mode 100644 src/dorkbox/systemTray/jna/linux/GtkTheme.java delete mode 100644 src/dorkbox/systemTray/jna/linux/structs/AppIndicatorInstanceStruct.java delete mode 100644 src/dorkbox/systemTray/jna/linux/structs/GObjectStruct.java delete mode 100644 src/dorkbox/systemTray/jna/linux/structs/GTypeInstanceStruct.java delete mode 100644 src/dorkbox/systemTray/jna/linux/structs/GdkColor.java delete mode 100644 src/dorkbox/systemTray/jna/linux/structs/GdkEventButton.java delete mode 100644 src/dorkbox/systemTray/jna/linux/structs/GtkRequisition.java delete mode 100644 src/dorkbox/systemTray/jna/linux/structs/GtkStyle.java delete mode 100644 src/dorkbox/systemTray/jna/linux/structs/PangoRectangle.java diff --git a/src/dorkbox/systemTray/jna/linux/AppIndicator.java b/src/dorkbox/systemTray/jna/linux/AppIndicator.java deleted file mode 100644 index 90ebf65..0000000 --- a/src/dorkbox/systemTray/jna/linux/AppIndicator.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import static dorkbox.systemTray.SystemTray.logger; - -import com.sun.jna.NativeLibrary; -import com.sun.jna.Pointer; - -import dorkbox.systemTray.SystemTray; -import dorkbox.systemTray.jna.linux.structs.AppIndicatorInstanceStruct; -import dorkbox.util.OS; -import dorkbox.util.jna.JnaHelper; - -/** - * bindings for libappindicator - * - * Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md - */ -@SuppressWarnings({"Duplicates", "SameParameterValue", "DanglingJavadoc"}) -public -class AppIndicator { - public static final boolean isVersion3; - public static final boolean isLoaded; - - /** - * Loader for AppIndicator, because it is absolutely mindboggling how those whom maintain the standard, can't agree to what that - * standard library naming convention or features/API set is. We just try until we find one that works, and are able to map the - * symbols we need. There are bash commands that will tell us the linked library name, however - I'd rather not run bash commands - * to determine this. - * - * This is so hacky it makes me sick. - */ - static { - boolean _isVersion3 = false; - boolean _isLoaded = false; - - boolean shouldLoadAppIndicator = !(OS.isWindows() || OS.isMacOsX()); - if (!shouldLoadAppIndicator) { - _isLoaded = true; - } - - // objdump -T /usr/lib/x86_64-linux-gnu/libappindicator.so.1 | grep foo - // objdump -T /usr/lib/x86_64-linux-gnu/libappindicator3.so.1 | grep foo - - // NOTE: - // ALSO WHAT VERSION OF GTK to use? appindiactor1 -> GTK2, appindicator3 -> GTK3. - // appindiactor1 is GKT2 only (can't use GTK3 bindings with it) - // appindicator3 doesn't support menu icons via GTK2!! - - if (!_isLoaded && SystemTray.FORCE_TRAY_TYPE == SystemTray.TrayType.GtkStatusIcon) { - // if we force GTK type system tray, don't attempt to load AppIndicator libs - if (SystemTray.DEBUG) { - logger.debug("Forced GtkStatusIcon tray type, not using AppIndicator"); - } - _isLoaded = true; - } - - if (!_isLoaded && SystemTray.FORCE_GTK2) { - // if specified, try loading appindicator1 first, maybe it's there? - // note: we can have GTK2 + appindicator3, but NOT ALWAYS. - try { - // deliberately without the "1" at the end. - final NativeLibrary library = JnaHelper.register("appindicator", AppIndicator.class); - if (library != null) { - _isLoaded = true; - } - } catch (Throwable e) { - if (SystemTray.DEBUG) { - logger.debug("Error loading GTK2 explicit appindicator. {}", e.getMessage()); - } - } - } - - String nameToCheck1; - String nameToCheck2; - - if (Gtk.isGtk2) { - nameToCheck1 = "appindicator"; // deliberately without the "1" at the end. - } - else { - nameToCheck1 = "appindicator3"; - } - - // start with base version using whatever the OS specifies as the proper symbolic link - if (!_isLoaded) { - try { - final NativeLibrary library = JnaHelper.register(nameToCheck1, AppIndicator.class); - String s = library.getFile().getName(); - - if (SystemTray.DEBUG) { - logger.debug("Loading library (first attempt): '{}'", s); - } - - if (s.contains("appindicator3")) { - _isVersion3 = true; - } - - _isLoaded = true; - } catch (Throwable e) { - if (SystemTray.DEBUG) { - logger.debug("Error loading library: '{}'. \n{}", nameToCheck1, e.getMessage()); - } - } - } - - // maybe it's really GTK2 version? who knows... - if (!_isLoaded) { - try { - JnaHelper.register("appindicator", AppIndicator.class); - _isLoaded = true; - } catch (Throwable e) { - if (SystemTray.DEBUG) { - logger.debug("Error loading library: '{}'. \n{}", "appindicator", e.getMessage()); - } - } - } - - // If we are GTK2, change the order we check and load libraries - - if (Gtk.isGtk2) { - nameToCheck1 = "appindicator-gtk"; - nameToCheck2 = "appindicator-gtk3"; - } - else { - nameToCheck1 = "appindicator-gtk3"; - nameToCheck2 = "appindicator-gtk"; - } - - // another type. who knows... - if (!_isLoaded) { - try { - JnaHelper.register(nameToCheck1, AppIndicator.class); - _isLoaded = true; - } catch (Throwable e) { - if (SystemTray.DEBUG) { - logger.debug("Error loading library: '{}'. \n{}", nameToCheck1, e.getMessage()); - } - } - } - - // this is HORRID. such a PITA - if (!_isLoaded) { - try { - JnaHelper.register(nameToCheck2, AppIndicator.class); - _isLoaded = true; - } catch (Throwable e) { - if (SystemTray.DEBUG) { - logger.debug("Error loading library: '{}'. \n{}", nameToCheck2, e.getMessage()); - } - } - } - - // We fall back to GtkStatusIndicator or Swing if this cannot load - if (shouldLoadAppIndicator && _isLoaded) { - isLoaded = true; - isVersion3 = _isVersion3; - } else { - isLoaded = false; - isVersion3 = false; - } - } - - // Note: AppIndicators DO NOT support tooltips, as per mark shuttleworth. Rather stupid IMHO. - // See: https://bugs.launchpad.net/indicator-application/+bug/527458/comments/12 - - public static final int CATEGORY_APPLICATION_STATUS = 0; -// public static final int CATEGORY_COMMUNICATIONS = 1; -// public static final int CATEGORY_SYSTEM_SERVICES = 2; -// public static final int CATEGORY_HARDWARE = 3; -// public static final int CATEGORY_OTHER = 4; - - public static final int STATUS_PASSIVE = 0; - public static final int STATUS_ACTIVE = 1; -// public static final int STATUS_ATTENTION = 2; - - - public static native - AppIndicatorInstanceStruct app_indicator_new(String id, String icon_name, int category); - - public static native void app_indicator_set_title(AppIndicatorInstanceStruct self, String title); - public static native void app_indicator_set_status(AppIndicatorInstanceStruct self, int status); - public static native void app_indicator_set_menu(AppIndicatorInstanceStruct self, Pointer menu); - public static native void app_indicator_set_icon(AppIndicatorInstanceStruct self, String icon_name); -} diff --git a/src/dorkbox/systemTray/jna/linux/FuncCallback.java b/src/dorkbox/systemTray/jna/linux/FuncCallback.java deleted file mode 100644 index fb177c1..0000000 --- a/src/dorkbox/systemTray/jna/linux/FuncCallback.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import com.sun.jna.Callback; -import com.sun.jna.Pointer; - -import dorkbox.util.Keep; - -@Keep -interface FuncCallback extends Callback { - /** - * @return Gtk.FALSE if it will be automatically removed from the stack once it's handled - */ - int callback(Pointer data); -} diff --git a/src/dorkbox/systemTray/jna/linux/GCallback.java b/src/dorkbox/systemTray/jna/linux/GCallback.java deleted file mode 100644 index 53344e0..0000000 --- a/src/dorkbox/systemTray/jna/linux/GCallback.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import com.sun.jna.Callback; -import com.sun.jna.Pointer; - -import dorkbox.util.Keep; - -@Keep -public -interface GCallback extends Callback { - /** - * @return Gtk.TRUE if we handled this event - */ - int callback(Pointer instance, Pointer data); -} diff --git a/src/dorkbox/systemTray/jna/linux/GEventCallback.java b/src/dorkbox/systemTray/jna/linux/GEventCallback.java deleted file mode 100644 index 32e2686..0000000 --- a/src/dorkbox/systemTray/jna/linux/GEventCallback.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import com.sun.jna.Callback; -import com.sun.jna.Pointer; - -import dorkbox.systemTray.jna.linux.structs.GdkEventButton; -import dorkbox.util.Keep; - -@Keep -public -interface GEventCallback extends Callback { - void callback(Pointer instance, GdkEventButton event); -} diff --git a/src/dorkbox/systemTray/jna/linux/Glib.java b/src/dorkbox/systemTray/jna/linux/Glib.java deleted file mode 100644 index adb17b2..0000000 --- a/src/dorkbox/systemTray/jna/linux/Glib.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import com.sun.jna.Callback; -import com.sun.jna.NativeLibrary; -import com.sun.jna.Pointer; - -import dorkbox.systemTray.SystemTray; -import dorkbox.util.jna.JnaHelper; - -/** - * bindings for glib-2.0 - * - * Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md - */ -public -class Glib { - static { - try { - NativeLibrary library = JnaHelper.register("glib-2.0", Glib.class); - if (library == null) { - SystemTray.logger.error("Error loading Glib library, it failed to load."); - } - } catch (Throwable e) { - SystemTray.logger.error("Error loading Glib library, it failed to load {}", e.getMessage()); - } - } - - public interface GLogLevelFlags { - public static final int RECURSION = 1 << 0; - public static final int FATAL = 1 << 1; - /* GLib log levels */ - public static final int ERROR = 1 << 2; /* always fatal */ - public static final int CRITICAL = 1 << 3; - public static final int WARNING = 1 << 4; - public static final int MESSAGE = 1 << 5; - public static final int INFO = 1 << 6; - public static final int DEBUG = 1 << 7; - public static final int MASK = ~(RECURSION | FATAL); - } - - public interface GLogFunc extends Callback { - void callback (String log_domain, int log_level, String message, Pointer data); - } - - public static final Glib.GLogFunc nullLogFunc = new Glib.GLogFunc() { - @Override - public - void callback(final String log_domain, final int log_level, final String message, final Pointer data) { - // do nothing - } - }; - - public static native int g_log_set_handler(String log_domain, int levels, GLogFunc handler, Pointer user_data); - public static native void g_log_default_handler (String log_domain, int log_level, String message, Pointer unused_data); - public static native GLogFunc g_log_set_default_handler(GLogFunc log_func, Pointer user_data); - public static native void g_log_remove_handler (String log_domain, int handler_id); -} diff --git a/src/dorkbox/systemTray/jna/linux/Gobject.java b/src/dorkbox/systemTray/jna/linux/Gobject.java deleted file mode 100644 index d4236af..0000000 --- a/src/dorkbox/systemTray/jna/linux/Gobject.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import com.sun.jna.Callback; -import com.sun.jna.NativeLibrary; -import com.sun.jna.Pointer; - -import dorkbox.systemTray.SystemTray; -import dorkbox.util.jna.JnaHelper; - -/** - * bindings for libgobject-2.0 - * - * Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md - */ -public -class Gobject { - - static { - try { - NativeLibrary library = JnaHelper.register("gobject-2.0", Gobject.class); - if (library == null) { - SystemTray.logger.error("Error loading GObject library, it failed to load."); - } - } catch (Throwable e) { - SystemTray.logger.error("Error loading GObject library, it failed to load {}", e.getMessage()); - } - } - - // objdump -T /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 | grep block - - public static native void g_object_unref(Pointer object); - - public static native void g_object_force_floating(Pointer object); - public static native void g_object_ref_sink(Pointer object); - - // note: the return type here MUST be long to avoid issues on freeBSD. NativeLong (previously used) worked on everything except BSD. - public static native long g_signal_connect_object(Pointer instance, String detailed_signal, Callback c_handler, Pointer object, int connect_flags); - - public static native void g_signal_handler_block(Pointer instance, long handlerId); - public static native void g_signal_handler_unblock(Pointer instance, long handlerId); - - public static native void g_object_get(Pointer instance, String property_name, Pointer value, Pointer terminator); - - - - // Types are here https://developer.gnome.org/gobject/stable/gobject-Type-Information.html - public static native void g_value_init(Pointer gvalue, double type); - - /** - * Clears the current value in value (if any) and "unsets" the type, this releases all resources associated with this GValue. - * An unset value is the same as an uninitialized (zero-filled) GValue structure. - */ - public static native void g_value_unset(Pointer gvalue); - - public static native String g_value_get_string(Pointer gvalue); - public static native int g_value_get_int(Pointer gvalue); - - public static native Pointer g_type_class_ref(Pointer widgetType); - public static native void g_type_class_unref(Pointer widgetClass); -} diff --git a/src/dorkbox/systemTray/jna/linux/Gtk.java b/src/dorkbox/systemTray/jna/linux/Gtk.java deleted file mode 100644 index 03cbbf0..0000000 --- a/src/dorkbox/systemTray/jna/linux/Gtk.java +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import com.sun.jna.Function; -import com.sun.jna.Pointer; - -import dorkbox.systemTray.jna.linux.structs.GtkStyle; - -/** - * Bindings for GTK+ 2. Bindings that are exclusively for GTK+ 3 are in that respective class - *

- * Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md - */ -@SuppressWarnings({"Duplicates", "SameParameterValue", "DeprecatedIsStillUsed", "WeakerAccess"}) -public -interface Gtk { - // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 | grep gtk - // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk - // objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk - - // For funsies to look at, SyncThing did a LOT of work on compatibility in python (unfortunate for us, but interesting). - // https://github.com/syncthing/syncthing-gtk/blob/b7a3bc00e3bb6d62365ae62b5395370f3dcc7f55/syncthing_gtk/statusicon.py - - - // make specific note of GTK2 vs GTK3 APIs - Gtk Gtk2 = GtkLoader.isGtk2 ? new Gtk2() : new Gtk3(); - Gtk3 Gtk3 = GtkLoader.isGtk2 ? null : (Gtk3) Gtk2; - - boolean isGtk2 = GtkLoader.isGtk2; - boolean isGtk3 = GtkLoader.isGtk3; - boolean isLoaded = GtkLoader.isLoaded; - - Function gtk_status_icon_position_menu = GtkLoader.gtk_status_icon_position_menu; - - int FALSE = 0; - int TRUE = 1; - - int MAJOR = GtkLoader.MAJOR; - int MINOR = GtkLoader.MINOR; - int MICRO = GtkLoader.MICRO; - - /** - * Adds a function to be called whenever there are no higher priority events pending. If the function returns FALSE it is automatically - * removed from the list of event sources and will not be called again. - *

- * This variant of g_idle_add_full() calls function with the GDK lock held. It can be thought of a MT-safe version for GTK+ widgets - * for the following use case, where you have to worry about idle_callback() running in thread A and accessing self after it has - * been finalized in thread B. - */ - int gdk_threads_add_idle_full(int priority, FuncCallback function, Pointer data, Pointer notify); - - /** - * This would NORMALLY have a 2nd argument that is a String[] -- however JNA direct-mapping DOES NOT support this. We are lucky - * enough that we just pass 'null' as the second argument, therefore, we don't have to define that parameter here. - */ - boolean gtk_init_check(int argc); - - /** - * Runs the main loop until gtk_main_quit() is called. You can nest calls to gtk_main(). In that case gtk_main_quit() will make the - * innermost invocation of the main loop return. - */ - void gtk_main(); - - /** - * aks for the current nesting level of the main loop. Useful to determine (at startup) if GTK is already running - */ - int gtk_main_level(); - - /** - * Makes the innermost invocation of the main loop return when it regains control. ONLY CALL FROM THE GtkSupport class, UNLESS you know - * what you're doing! - */ - void gtk_main_quit(); - - - - /** - * Creates a new GtkMenu - */ - Pointer gtk_menu_new(); - - /** - * Sets or replaces the menu item’s submenu, or removes it when a NULL submenu is passed. - */ - void gtk_menu_item_set_submenu(Pointer menuEntry, Pointer menu); - - /** - * Creates a new GtkSeparatorMenuItem. - */ - Pointer gtk_separator_menu_item_new(); - - /** - * Creates a new GtkImage displaying the file filename . If the file isn’t found or can’t be loaded, the resulting GtkImage will - * display a “broken image” icon. This function never returns NULL, it always returns a valid GtkImage widget. - *

- * If the file contains an animation, the image will contain an animation. - */ - Pointer gtk_image_new_from_file(String iconPath); - - /** - * Sets the active state of the menu item’s check box. - */ - void gtk_check_menu_item_set_active(Pointer check_menu_item, boolean isChecked); - - /** - * Creates a new GtkImageMenuItem containing a label. The label will be created using gtk_label_new_with_mnemonic(), so underscores - * in label indicate the mnemonic for the menu item. - *

- * uses '_' to define which key is the mnemonic - *

- * gtk_image_menu_item_new_with_mnemonic has been deprecated since version 3.10 and should not be used in newly-written code. - * NOTE: Use gtk_menu_item_new_with_mnemonic() instead. - */ - Pointer gtk_image_menu_item_new_with_mnemonic(String label); - - Pointer gtk_check_menu_item_new_with_mnemonic(String label); - - /** - * Sets the image of image_menu_item to the given widget. Note that it depends on the show-menu-images setting whether the image - * will be displayed or not. - *

- * gtk_image_menu_item_set_image has been deprecated since version 3.10 and should not be used in newly-written code. - */ - void gtk_image_menu_item_set_image(Pointer image_menu_item, Pointer image); - - /** - * If TRUE, the menu item will ignore the “gtk-menu-images” setting and always show the image, if available. - * Use this property if the menuitem would be useless or hard to use without the image - *

- * gtk_image_menu_item_set_always_show_image has been deprecated since version 3.10 and should not be used in newly-written code. - */ - void gtk_image_menu_item_set_always_show_image(Pointer menu_item, boolean forceShow); - - /** - * Creates an empty status icon object. - *

- * gtk_status_icon_new has been deprecated since version 3.14 and should not be used in newly-written code. - * Use notifications - */ - Pointer gtk_status_icon_new(); - - /** - * Obtains the root window (parent all other windows are inside) for the default display and screen. - * - * @return the default root window - */ - Pointer gdk_get_default_root_window(); - - /** - * Gets the default screen for the default display. (See gdk_display_get_default()). - * - * @return a GdkScreen, or NULL if there is no default display. - * - * @since 2.2 - */ - Pointer gdk_screen_get_default(); - - /** - * Gets the resolution for font handling on the screen; see gdk_screen_set_resolution() for full details. - * - * IE: - * - * The resolution for font handling on the screen. This is a scale factor between points specified in a PangoFontDescription and - * cairo units. The default value is 96, meaning that a 10 point font will be 13 units high. (10 * 96. / 72. = 13.3). - * - * @return the current resolution, or -1 if no resolution has been set. - * - * @since Since: 2.10 - */ - double gdk_screen_get_resolution(Pointer screen); - - /** - * Makes status_icon display the file filename . See gtk_status_icon_new_from_file() for details. - *

- * gtk_status_icon_set_from_file has been deprecated since version 3.14 and should not be used in newly-written code. - * Use notifications - */ - void gtk_status_icon_set_from_file(Pointer widget, String label); - - /** - * Shows or hides a status icon. - *

- * gtk_status_icon_set_visible has been deprecated since version 3.14 and should not be used in newly-written code. - * Use notifications - */ - void gtk_status_icon_set_visible(Pointer widget, boolean visible); - - - /** - * Sets text as the contents of the tooltip. - * This function will take care of setting “has-tooltip” to TRUE and of the default handler for the “query-tooltip” signal. - * - * app indicators don't support this - * - * gtk_status_icon_set_tooltip_text has been deprecated since version 3.14 and should not be used in newly-written code. - * Use notifications - */ - void gtk_status_icon_set_tooltip_text(Pointer widget, String tooltipText); - - /** - * Sets the title of this tray icon. This should be a short, human-readable, localized string describing the tray icon. It may be used - * by tools like screen readers to render the tray icon. - *

- * gtk_status_icon_set_title has been deprecated since version 3.14 and should not be used in newly-written code. - * Use notifications - */ - void gtk_status_icon_set_title(Pointer widget, String titleText); - - /** - * Sets the name of this tray icon. This should be a string identifying this icon. It is may be used for sorting the icons in the - * tray and will not be shown to the user. - *

- * gtk_status_icon_set_name has been deprecated since version 3.14 and should not be used in newly-written code. - * Use notifications - */ - void gtk_status_icon_set_name(Pointer widget, String name); - - /** - * Displays a menu and makes it available for selection. - *

- * gtk_menu_popup has been deprecated since version 3.22 and should not be used in newly-written code. - * NOTE: Please use gtk_menu_popup_at_widget(), gtk_menu_popup_at_pointer(). or gtk_menu_popup_at_rect() instead - */ - void gtk_menu_popup(Pointer menu, Pointer widget, Pointer bla, Function func, Pointer data, int button, int time); - - /** - * Sets text on the menu_item label - */ - void gtk_menu_item_set_label(Pointer menu_item, String label); - - /** - * Adds a new GtkMenuItem to the end of the menu shell's item list. - */ - void gtk_menu_shell_append(Pointer menu_shell, Pointer child); - - /** - * Sets the sensitivity of a widget. A widget is sensitive if the user can interact with it. Insensitive widgets are “grayed out” - * and the user can’t interact with them. Insensitive widgets are known as “inactive”, “disabled”, or “ghosted” in some other toolkits. - */ - void gtk_widget_set_sensitive(Pointer widget, boolean sensitive); - - /** - * Recursively shows a widget, and any child widgets (if the widget is a container) - */ - void gtk_widget_show_all(Pointer widget); - - /** - * Removes widget from container . widget must be inside container . Note that container will own a reference to widget , and that - * this may be the last reference held; so removing a widget from its container can destroy that widget. - *

- * If you want to use widget again, you need to add a reference to it before removing it from a container, using g_object_ref(). - * If you don’t want to use widget again it’s usually more efficient to simply destroy it directly using gtk_widget_destroy() - * since this will remove it from the container and help break any circular reference count cycles. - */ - void gtk_container_remove(Pointer parentWidget, Pointer widget); - - /** - * Destroys a widget. - * When a widget is destroyed all references it holds on other objects will be released: - * - if the widget is inside a container, it will be removed from its parent - * - if the widget is a container, all its children will be destroyed, recursively - * - if the widget is a top level, it will be removed from the list of top level widgets that GTK+ maintains internally - *

- * It's expected that all references held on the widget will also be released; you should connect to the “destroy” signal if you - * hold a reference to widget and you wish to remove it when this function is called. It is not necessary to do so if you are - * implementing a GtkContainer, as you'll be able to use the GtkContainerClass.remove() virtual function for that. - *

- * It's important to notice that gtk_widget_destroy() will only cause the widget to be finalized if no additional references, - * acquired using g_object_ref(), are held on it. In case additional references are in place, the widget will be in an "inert" state - * after calling this function; widget will still point to valid memory, allowing you to release the references you hold, but you - * may not query the widget's own state. - *

- * NOTE You should typically call this function on top level widgets, and rarely on child widgets. - */ - void gtk_widget_destroy(Pointer widget); - - /** - * Gets the GtkSettings object for screen , creating it if necessary. - * - * @since 2.2 - */ - Pointer gtk_settings_get_for_screen(Pointer screen); - - /** - * Finds all matching RC styles for a given widget, composites them together, and then creates a GtkStyle representing the composite - * appearance. (GTK+ actually keeps a cache of previously created styles, so a new style may not be created.) - */ - GtkStyle gtk_rc_get_style(Pointer widget); - - /** - * Adds widget to container . Typically used for simple containers such as GtkWindow, GtkFrame, or GtkButton; for more complicated - * layout containers such as GtkBox or GtkTable, this function will pick default packing parameters that may not be correct. So - * consider functions such as gtk_box_pack_start() and gtk_table_attach() as an alternative to gtk_container_add() in those cases. - * A widget may be added to only one container at a time; you can't place the same widget inside two different containers. - */ - void gtk_container_add(Pointer offscreen, Pointer widget); - - /** - * Get's the child from a GTK Bin object - */ - Pointer gtk_bin_get_child(Pointer bin); - - /** - * Gets the PangoLayout used to display the label. The layout is useful to e.g. convert text positions to pixel positions, in - * combination with gtk_label_get_layout_offsets(). The returned layout is owned by the label so need not be freed by the caller. - * - * The label is free to recreate its layout at any time, so it should be considered read-only. - */ - Pointer gtk_label_get_layout(Pointer label); - - /** - * Computes the logical and ink extents of layout in device units. This function just calls pango_layout_get_extents() followed - * by two pango_extents_to_pixels() calls, rounding ink_rect and logical_rect such that the rounded rectangles fully contain the - * unrounded one (that is, passes them as first argument to pango_extents_to_pixels()). - * - * @param layout a PangoLayout - * @param ink_rect rectangle used to store the extents of the layout as drawn or NULL to indicate that the result is not needed. - * @param logical_rect rectangle used to store the logical extents of the layout or NULL to indicate that the result is not needed. - */ - void pango_layout_get_pixel_extents(Pointer layout, Pointer ink_rect, Pointer logical_rect); - - /** - * Creates the GDK (windowing system) resources associated with a widget. For example, widget->window will be created when a widget - * is realized. Normally realization happens implicitly; if you show a widget and all its parent containers, then the widget will - * be realized and mapped automatically. - * - * Realizing a widget requires all the widget’s parent widgets to be realized; calling gtk_widget_realize() realizes the widget’s - * parents in addition to widget itself. If a widget is not yet inside a toplevel window when you realize it, bad things will happen. - * - * This function is primarily used in widget implementations, and isn’t very useful otherwise. Many times when you think you might - * need it, a better approach is to connect to a signal that will be called after the widget is realized automatically, such as - * “draw”. Or simply g_signal_connect() to the “realize” signal. - */ - void gtk_widget_realize(Pointer widget); - - /** - * Creates a toplevel container widget that is used to retrieve snapshots of widgets without showing them on the screen. - * - * @since 2.20 - */ - Pointer gtk_offscreen_window_new(); - - /** - * This function is typically used when implementing a GtkContainer subclass. Obtains the preferred size of a widget. The - * container uses this information to arrange its child widgets and decide what size allocations to give them with - * gtk_widget_size_allocate(). - * - * You can also call this function from an application, with some caveats. Most notably, getting a size request requires the - * widget to be associated with a screen, because font information may be needed. Multihead-aware applications should keep this in mind. - * - * Also remember that the size request is not necessarily the size a widget will actually be allocated. - */ - void gtk_widget_size_request(final Pointer widget, final Pointer requisition); - - /** - * Creates a new GtkImageMenuItem containing the image and text from a stock item. Some stock ids have preprocessor macros - * like GTK_STOCK_OK and GTK_STOCK_APPLY. - * - * @param stock_id the name of the stock item. - * @param accel_group the GtkAccelGroup to add the menu items accelerator to, or NULL. - * - * @return a new GtkImageMenuItem. - */ - Pointer gtk_image_menu_item_new_from_stock(String stock_id, Pointer accel_group); -} - diff --git a/src/dorkbox/systemTray/jna/linux/Gtk2.java b/src/dorkbox/systemTray/jna/linux/Gtk2.java deleted file mode 100644 index 8c623a2..0000000 --- a/src/dorkbox/systemTray/jna/linux/Gtk2.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import com.sun.jna.Function; -import com.sun.jna.Pointer; - -import dorkbox.systemTray.jna.linux.structs.GtkStyle; - -/** - * Bindings for GTK+ 2. Bindings that are exclusively for GTK+ 3 are in that respective class - *

- * Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md - */ -public -class Gtk2 implements Gtk { - // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 | grep gtk - - @Override - public native - int gdk_threads_add_idle_full(final int priority, final FuncCallback function, final Pointer data, final Pointer notify); - - @Override - public native - boolean gtk_init_check(final int argc); - - @Override - public native - void gtk_main(); - - @Override - public native - int gtk_main_level(); - - @Override - public native - void gtk_main_quit(); - - @Override - public native - Pointer gtk_menu_new(); - - @Override - public native - void gtk_menu_item_set_submenu(final Pointer menuEntry, final Pointer menu); - - @Override - public native - Pointer gtk_separator_menu_item_new(); - - @Override - public native - Pointer gtk_image_new_from_file(final String iconPath); - - @Override - public native - void gtk_check_menu_item_set_active(final Pointer check_menu_item, final boolean isChecked); - - @Override - public native - Pointer gtk_image_menu_item_new_with_mnemonic(final String label); - - @Override - public native - Pointer gtk_check_menu_item_new_with_mnemonic(final String label); - - @Override - public native - void gtk_image_menu_item_set_image(final Pointer image_menu_item, final Pointer image); - - @Override - public native - void gtk_image_menu_item_set_always_show_image(final Pointer menu_item, final boolean forceShow); - - @Override - public native - Pointer gtk_status_icon_new(); - - @Override - public native - Pointer gdk_get_default_root_window(); - - @Override - public native - Pointer gdk_screen_get_default(); - - @Override - public native - double gdk_screen_get_resolution(final Pointer screen); - - @Override - public native - void gtk_status_icon_set_from_file(final Pointer widget, final String label); - - @Override - public native - void gtk_status_icon_set_visible(final Pointer widget, final boolean visible); - - @Override - public native - void gtk_status_icon_set_tooltip_text(final Pointer widget, final String tooltipText); - - @Override - public native - void gtk_status_icon_set_title(final Pointer widget, final String titleText); - - @Override - public native - void gtk_status_icon_set_name(final Pointer widget, final String name); - - @Override - public native - void gtk_menu_popup(final Pointer menu, - final Pointer widget, - final Pointer bla, - final Function func, - final Pointer data, - final int button, - final int time); - - @Override - public native - void gtk_menu_item_set_label(final Pointer menu_item, final String label); - - @Override - public native - void gtk_menu_shell_append(final Pointer menu_shell, final Pointer child); - - @Override - public native - void gtk_widget_set_sensitive(final Pointer widget, final boolean sensitive); - - @Override - public native - void gtk_widget_show_all(final Pointer widget); - - @Override - public native - void gtk_container_remove(final Pointer parentWidget, final Pointer widget); - - @Override - public native - void gtk_widget_destroy(final Pointer widget); - - @Override - public native - Pointer gtk_settings_get_for_screen(final Pointer screen); - - @Override - public native - GtkStyle gtk_rc_get_style(final Pointer widget); - - @Override - public native - void gtk_container_add(final Pointer offscreen, final Pointer widget); - - @Override - public native - Pointer gtk_bin_get_child(final Pointer bin); - - @Override - public native - Pointer gtk_label_get_layout(final Pointer label); - - @Override - public native - void pango_layout_get_pixel_extents(final Pointer layout, final Pointer ink_rect, final Pointer logical_rect); - - @Override - public native - void gtk_widget_realize(final Pointer widget); - - @Override - public native - Pointer gtk_offscreen_window_new(); - - @Override - public native - void gtk_widget_size_request(final Pointer widget, final Pointer requisition); - - @Override - public native - Pointer gtk_image_menu_item_new_from_stock(final String stock_id, final Pointer accel_group); -} diff --git a/src/dorkbox/systemTray/jna/linux/Gtk3.java b/src/dorkbox/systemTray/jna/linux/Gtk3.java deleted file mode 100644 index d59c4f6..0000000 --- a/src/dorkbox/systemTray/jna/linux/Gtk3.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import com.sun.jna.Function; -import com.sun.jna.Pointer; - -import dorkbox.systemTray.jna.linux.structs.GtkStyle; - -/** - * bindings for GTK+ 3. - *

- * Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md - */ -public -class Gtk3 implements Gtk { - // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk - // objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk - - /** - * This function is typically used when implementing a GtkContainer subclass. Obtains the preferred size of a widget. The - * container uses this information to arrange its child widgets and decide what size allocations to give them with - * gtk_widget_size_allocate(). - * - * You can also call this function from an application, with some caveats. Most notably, getting a size request requires the - * widget to be associated with a screen, because font information may be needed. Multihead-aware applications should keep this in mind. - * - * Also remember that the size request is not necessarily the size a widget will actually be allocated. - */ - @Override - public - void gtk_widget_size_request(final Pointer widget, final Pointer requisition) { - this.gtk_widget_get_preferred_size(widget, requisition, null); - } - - /** - * Retrieves the minimum and natural size of a widget, taking into account the widget’s preference for height-for-width management. - *

- * This is used to retrieve a suitable size by container widgets which do not impose any restrictions on the child placement. - * It can be used to deduce toplevel window and menu sizes as well as child widgets in free-form containers such as GtkLayout. - *

- * Handle with care. Note that the natural height of a height-for-width widget will generally be a smaller size than the minimum - * height, since the required height for the natural width is generally smaller than the required height for the minimum width. - *

- * Use gtk_widget_get_preferred_height_and_baseline_for_width() if you want to support baseline alignment. - * - * @param widget a GtkWidget instance - * @param minimum_size location for storing the minimum size, or NULL. - * @param natural_size location for storing the natural size, or NULL. - */ - public native - void gtk_widget_get_preferred_size(final Pointer widget, final Pointer minimum_size, final Pointer natural_size); - - public native - int gtk_get_major_version(); - - public native - int gtk_get_minor_version(); - - public native - int gtk_get_micro_version(); - - /** - * Returns the internal scale factor that maps from window coordinates to the actual device pixels. On traditional systems this is 1, - * but on very high density outputs this can be a higher value (often 2). - *

- * A higher value means that drawing is automatically scaled up to a higher resolution, so any code doing drawing will automatically - * look nicer. However, if you are supplying pixel-based data the scale value can be used to determine whether to use a pixel - * resource with higher resolution data. - *

- * The scale of a window may change during runtime, if this happens a configure event will be sent to the toplevel window. - * - * @return the scale factor - * - * @since 3.10 - */ - public native - int gdk_window_get_scale_factor(Pointer window); - - - - - @Override - public native - int gdk_threads_add_idle_full(final int priority, final FuncCallback function, final Pointer data, final Pointer notify); - - @Override - public native - boolean gtk_init_check(final int argc); - - @Override - public native - void gtk_main(); - - @Override - public native - int gtk_main_level(); - - @Override - public native - void gtk_main_quit(); - - @Override - public native - Pointer gtk_menu_new(); - - @Override - public native - void gtk_menu_item_set_submenu(final Pointer menuEntry, final Pointer menu); - - @Override - public native - Pointer gtk_separator_menu_item_new(); - - @Override - public native - Pointer gtk_image_new_from_file(final String iconPath); - - @Override - public native - void gtk_check_menu_item_set_active(final Pointer check_menu_item, final boolean isChecked); - - @Override - public native - Pointer gtk_image_menu_item_new_with_mnemonic(final String label); - - @Override - public native - Pointer gtk_check_menu_item_new_with_mnemonic(final String label); - - @Override - public native - void gtk_image_menu_item_set_image(final Pointer image_menu_item, final Pointer image); - - @Override - public native - void gtk_image_menu_item_set_always_show_image(final Pointer menu_item, final boolean forceShow); - - @Override - public native - Pointer gtk_status_icon_new(); - - @Override - public native - Pointer gdk_get_default_root_window(); - - @Override - public native - Pointer gdk_screen_get_default(); - - @Override - public native - double gdk_screen_get_resolution(final Pointer screen); - - @Override - public native - void gtk_status_icon_set_from_file(final Pointer widget, final String label); - - @Override - public native - void gtk_status_icon_set_visible(final Pointer widget, final boolean visible); - - @Override - public native - void gtk_status_icon_set_tooltip_text(final Pointer widget, final String tooltipText); - - @Override - public native - void gtk_status_icon_set_title(final Pointer widget, final String titleText); - - @Override - public native - void gtk_status_icon_set_name(final Pointer widget, final String name); - - @Override - public native - void gtk_menu_popup(final Pointer menu, - final Pointer widget, - final Pointer bla, - final Function func, - final Pointer data, - final int button, - final int time); - - @Override - public native - void gtk_menu_item_set_label(final Pointer menu_item, final String label); - - @Override - public native - void gtk_menu_shell_append(final Pointer menu_shell, final Pointer child); - - @Override - public native - void gtk_widget_set_sensitive(final Pointer widget, final boolean sensitive); - - @Override - public native - void gtk_widget_show_all(final Pointer widget); - - @Override - public native - void gtk_container_remove(final Pointer parentWidget, final Pointer widget); - - @Override - public native - void gtk_widget_destroy(final Pointer widget); - - @Override - public native - Pointer gtk_settings_get_for_screen(final Pointer screen); - - @Override - public native - GtkStyle gtk_rc_get_style(final Pointer widget); - - @Override - public native - void gtk_container_add(final Pointer offscreen, final Pointer widget); - - @Override - public native - Pointer gtk_bin_get_child(final Pointer bin); - - @Override - public native - Pointer gtk_label_get_layout(final Pointer label); - - @Override - public native - void pango_layout_get_pixel_extents(final Pointer layout, final Pointer ink_rect, final Pointer logical_rect); - - @Override - public native - void gtk_widget_realize(final Pointer widget); - - @Override - public native - Pointer gtk_offscreen_window_new(); - - @Override - public native - Pointer gtk_image_menu_item_new_from_stock(final String stock_id, final Pointer accel_group); -} diff --git a/src/dorkbox/systemTray/jna/linux/GtkEventDispatch.java b/src/dorkbox/systemTray/jna/linux/GtkEventDispatch.java deleted file mode 100644 index fd1de0d..0000000 --- a/src/dorkbox/systemTray/jna/linux/GtkEventDispatch.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import static dorkbox.systemTray.SystemTray.logger; -import static dorkbox.systemTray.jna.linux.Gtk.Gtk2; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.LinkedList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import com.sun.jna.Pointer; - -import dorkbox.systemTray.Entry; -import dorkbox.systemTray.SystemTray; -import dorkbox.systemTray.util.JavaFX; -import dorkbox.systemTray.util.Swt; - -public -class GtkEventDispatch { - // have to save these in a field to prevent GC on the objects (since they go out-of-scope from java) - private static final LinkedList gtkCallbacks = new LinkedList(); - - // This is required because the EDT needs to have it's own value for this boolean, that is a different value than the main thread - private static ThreadLocal isDispatch = new ThreadLocal() { - @Override - protected - Boolean initialValue() { - return false; - } - }; - - private static volatile boolean started = false; - - @SuppressWarnings("FieldCanBeLocal") - private static Thread gtkUpdateThread = null; - - // when debugging the EDT, we need a longer timeout. - private static final boolean debugEDT = true; - - // timeout is in seconds - private static final int TIMEOUT = debugEDT ? 10000000 : 2; - - - public static - void startGui() { - // only permit one startup per JVM instance - if (!started) { - started = true; - - // startup the GTK GUI event loop. There can be multiple/nested loops. - - - if (!GtkLoader.alreadyRunningGTK) { - // If JavaFX/SWT is used, this is UNNECESSARY (we can detect if the GTK main_loop is running) - - gtkUpdateThread = new Thread() { - @Override - public - void run() { - Glib.GLogFunc orig = null; - if (SystemTray.DEBUG) { - logger.debug("Running GTK Native Event Loop"); - } else { - // NOTE: This can output warnings, so we suppress them - orig = Glib.g_log_set_default_handler(Glib.nullLogFunc, null); - } - - - // prep for the event loop. - // GThread.g_thread_init(null); would be needed for g_idle_add() - - if (!Gtk2.gtk_init_check(0)) { - if (SystemTray.DEBUG) { - logger.error("Error starting GTK"); - } - return; - } - - // gdk_threads_enter(); would be needed for g_idle_add() - - if (orig != null) { - Glib.g_log_set_default_handler(orig, null); - } - - // blocks unit quit - Gtk2.gtk_main(); - - // clean up threads - // gdk_threads_leave(); would be needed for g_idle_add() - } - }; - gtkUpdateThread.setDaemon(false); // explicitly NOT daemon so that this will hold the JVM open as necessary - gtkUpdateThread.setName("GTK Native Event Loop"); - gtkUpdateThread.start(); - } - } - } - - /** - * Waits for the all posted events to GTK to finish loading - */ - @SuppressWarnings("Duplicates") - public static - void waitForEventsToComplete() { - final CountDownLatch blockUntilStarted = new CountDownLatch(1); - - dispatch(new Runnable() { - @Override - public - void run() { - blockUntilStarted.countDown(); - } - }); - - if (SystemTray.isJavaFxLoaded) { - if (!JavaFX.isEventThread()) { - try { - if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) { - if (SystemTray.DEBUG) { - SystemTray.logger.error("Something is very wrong. The waitForEventsToComplete took longer than expected.", - new Exception("")); - } - } - - // we have to WAIT until all events are done processing, OTHERWISE we have initialization issues - while (true) { - Thread.sleep(100); - - synchronized (gtkCallbacks) { - if (gtkCallbacks.isEmpty()) { - break; - } - } - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - else if (SystemTray.isSwtLoaded) { - if (!Swt.isEventThread()) { - // we have to WAIT until all events are done processing, OTHERWISE we have initialization issues - try { - if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) { - if (SystemTray.DEBUG) { - SystemTray.logger.error("Something is very wrong. The waitForEventsToComplete took longer than expected.", - new Exception("")); - } - } - - while (true) { - Thread.sleep(100); - - synchronized (gtkCallbacks) { - if (gtkCallbacks.isEmpty()) { - break; - } - } - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - else { - try { - if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) { - if (SystemTray.DEBUG) { - SystemTray.logger.error("Something is very wrong. The waitForEventsToComplete took longer than expected.", - new Exception("")); - } - } - - // we have to WAIT until all events are done processing, OTHERWISE we have initialization issues - while (true) { - Thread.sleep(100); - - synchronized (gtkCallbacks) { - if (gtkCallbacks.isEmpty()) { - break; - } - } - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - - /** - * Best practices for GTK, is to call EVERYTHING for it on the GTK THREAD. This accomplishes that. - */ - public static - void dispatch(final Runnable runnable) { - if (GtkLoader.alreadyRunningGTK) { - if (SystemTray.isJavaFxLoaded) { - // JavaFX only - if (JavaFX.isEventThread()) { - // Run directly on the JavaFX event thread - runnable.run(); - } - else { - JavaFX.dispatch(runnable); - } - - return; - } - - if (SystemTray.isSwtLoaded) { - if (Swt.isEventThread()) { - // Run directly on the SWT event thread. If it's not on the dispatch thread, we can use raw GTK to put it there - runnable.run(); - - return; - } - } - } - - // not javafx - // gtk/swt are **mostly** the same in how events are dispatched, so we can use "raw" gtk methods for SWT - if (isDispatch.get()) { - // Run directly on the dispatch thread - runnable.run(); - } - else { - final FuncCallback callback = new FuncCallback() { - @Override - public - int callback(final Pointer data) { - synchronized (gtkCallbacks) { - gtkCallbacks.removeFirst(); // now that we've 'handled' it, we can remove it from our callback list - } - - isDispatch.set(true); - - try { - runnable.run(); - } finally { - isDispatch.set(false); - } - - return Gtk2.FALSE; // don't want to call this again - } - }; - - synchronized (gtkCallbacks) { - gtkCallbacks.offer(callback); // prevent GC from collecting this object before it can be called - } - - // the correct way to do it. Add with a slightly higher value - Gtk2.gdk_threads_add_idle_full(100, callback, null, null); - } - } - - public static - void shutdownGui() { - dispatchAndWait(new Runnable() { - @Override - public - void run() { - // If JavaFX/SWT is used, this is UNNECESSARY (and will break SWT/JavaFX shutdown) - if (!GtkLoader.alreadyRunningGTK) { - Gtk2.gtk_main_quit(); - } - - started = false; - } - }); - } - - public static - void dispatchAndWait(final Runnable runnable) { - if (isDispatch.get()) { - // Run directly on the dispatch thread (should not "redispatch" this again) - runnable.run(); - } - else { - final CountDownLatch countDownLatch = new CountDownLatch(1); - - dispatch(new Runnable() { - @Override - public - void run() { - try { - runnable.run(); - } catch (Exception e) { - SystemTray.logger.error("Error during GTK run loop: ", e); - } finally { - countDownLatch.countDown(); - } - } - }); - - // this is slightly different than how swing does it. We have a timeout here so that we can make sure that updates on the GUI - // thread occur in REASONABLE time-frames, and alert the user if not. - try { - if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) { - if (SystemTray.DEBUG) { - SystemTray.logger.error( - "Something is very wrong. The Event Dispatch Queue took longer than " + TIMEOUT + " seconds " + - "to complete.", new Exception("")); - } - else { - throw new RuntimeException("Something is very wrong. The Event Dispatch Queue took longer than " + TIMEOUT + - " seconds " + "to complete."); - } - } - } catch (InterruptedException e) { - SystemTray.logger.error("Error waiting for dispatch to complete.", new Exception("")); - } - } - } - - /** - * required to properly setup the dispatch flag when using native menus - * - * @param callback will never be null. - */ - public static - void proxyClick(final Entry menuEntry, final ActionListener callback) { - isDispatch.set(true); - - try { - if (menuEntry != null) { - callback.actionPerformed(new ActionEvent(menuEntry, ActionEvent.ACTION_PERFORMED, "")); - } - else { - // checkbox entries will not pass the menuEntry in, because they redispatch the click event so that the checkbox state is - // toggled - callback.actionPerformed(null); - } - } finally { - isDispatch.set(false); - } - } -} diff --git a/src/dorkbox/systemTray/jna/linux/GtkLoader.java b/src/dorkbox/systemTray/jna/linux/GtkLoader.java deleted file mode 100644 index b1b8b69..0000000 --- a/src/dorkbox/systemTray/jna/linux/GtkLoader.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import static dorkbox.systemTray.SystemTray.logger; -import static dorkbox.systemTray.jna.linux.Gtk.Gtk2; - -import com.sun.jna.Function; -import com.sun.jna.NativeLibrary; - -import dorkbox.systemTray.SystemTray; -import dorkbox.util.OS; -import dorkbox.util.jna.JnaHelper; - -/** - * Bindings for GTK+ 2. Bindings that are exclusively for GTK+ 3 are in that respective class - *

- * Direct-mapping, See: https://github.com/java-native-access/jna/blob/master/www/DirectMapping.md - */ -@SuppressWarnings({"Duplicates", "SameParameterValue", "DeprecatedIsStillUsed", "WeakerAccess"}) -class GtkLoader { - // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 | grep gtk - // objdump -T /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 | grep gtk - // objdump -T /usr/local/lib/libgtk-3.so.0 | grep gtk - - // For funsies to look at, SyncThing did a LOT of work on compatibility in python (unfortunate for us, but interesting). - // https://github.com/syncthing/syncthing-gtk/blob/b7a3bc00e3bb6d62365ae62b5395370f3dcc7f55/syncthing_gtk/statusicon.py - - // NOTE: AppIndicator uses this info to figure out WHAT VERSION OF appindicator to use: GTK2 -> appindicator1, GTK3 -> appindicator3 - static final boolean isGtk2; - static final boolean isGtk3; - static final boolean isLoaded; - - - static final boolean alreadyRunningGTK; - - static Function gtk_status_icon_position_menu = null; - - static final int MAJOR; - static final int MINOR; - static final int MICRO; - - /* - * We can have GTK v3 or v2. - * - * Observations: - * JavaFX uses GTK2, and we can't load GTK3 if GTK2 symbols are loaded - * SWT uses GTK2 or GTK3. We do not work with the GTK3 version of SWT. - */ - static { - boolean shouldUseGtk2 = SystemTray.FORCE_GTK2; - boolean _isGtk2 = false; - boolean _isLoaded = false; - boolean _alreadyRunningGTK = false; - int major = 0; - int minor = 0; - int micro = 0; - - boolean shouldLoadGtk = !(OS.isWindows() || OS.isMacOsX()); - if (!shouldLoadGtk) { - _isLoaded = true; - } - - // we can force the system to use the swing indicator, which WORKS, but doesn't support transparency in the icon. However, there - // are certain GTK functions we might want to use (even if we are Swing or AWT), so we load GTK anyways... - - // in some cases, we ALWAYS want to try GTK2 first - String gtk2LibName = "gtk-x11-2.0"; - String gtk3LibName = "libgtk-3.so.0"; - - - if (!_isLoaded && shouldUseGtk2) { - try { - NativeLibrary library = JnaHelper.register(gtk2LibName, Gtk2.class); - gtk_status_icon_position_menu = Function.getFunction(gtk2LibName, "gtk_status_icon_position_menu"); - _isGtk2 = true; - Gtk gtk = new Gtk2(); - - // when running inside of JavaFX, this will be '1'. All other times this should be '0' - // when it's '1', it means that someone else has started GTK -- so we DO NOT NEED TO. - _alreadyRunningGTK = gtk.gtk_main_level() != 0; - _isLoaded = true; - - major = library.getGlobalVariableAddress("gtk_major_version").getInt(0); - minor = library.getGlobalVariableAddress("gtk_minor_version").getInt(0); - micro = library.getGlobalVariableAddress("gtk_micro_version").getInt(0); - - if (SystemTray.DEBUG) { - logger.debug("GTK: {}", gtk2LibName); - } - } catch (Throwable e) { - if (SystemTray.DEBUG) { - logger.error("Error loading library", e); - } - } - } - - // now for the defaults... - - // start with version 3 - if (!_isLoaded) { - try { - // ALSO map Gtk2.java to GTK3 library. - JnaHelper.register(gtk3LibName, Gtk3.class); - gtk_status_icon_position_menu = Function.getFunction(gtk3LibName, "gtk_status_icon_position_menu"); - Gtk3 gtk = new Gtk3(); - - // when running inside of JavaFX, this will be '1'. All other times this should be '0' - // when it's '1', it means that someone else has started GTK -- so we DO NOT NEED TO. - _alreadyRunningGTK = gtk.gtk_main_level() != 0; - _isLoaded = true; - - major = gtk.gtk_get_major_version(); - minor = gtk.gtk_get_minor_version(); - micro = gtk.gtk_get_micro_version(); - - if (SystemTray.DEBUG) { - logger.debug("GTK: {}", gtk3LibName); - } - } catch (Throwable e) { - if (SystemTray.DEBUG) { - logger.error("Error loading library", e); - } - } - } - - // now version 2 - if (!_isLoaded) { - try { - NativeLibrary library = JnaHelper.register(gtk2LibName, Gtk2.class); - gtk_status_icon_position_menu = Function.getFunction(gtk2LibName, "gtk_status_icon_position_menu"); - _isGtk2 = true; - - // when running inside of JavaFX, this will be '1'. All other times this should be '0' - // when it's '1', it means that someone else has started GTK -- so we DO NOT NEED TO. - _alreadyRunningGTK = Gtk2.gtk_main_level() != 0; - _isLoaded = true; - - major = library.getGlobalVariableAddress("gtk_major_version").getInt(0); - minor = library.getGlobalVariableAddress("gtk_minor_version").getInt(0); - micro = library.getGlobalVariableAddress("gtk_micro_version").getInt(0); - - if (SystemTray.DEBUG) { - logger.debug("GTK: {}", gtk2LibName); - } - } catch (Throwable e) { - if (SystemTray.DEBUG) { - logger.error("Error loading library", e); - } - } - } - - if (shouldLoadGtk && _isLoaded) { - isLoaded = true; - - // depending on how the system is initialized, SWT may, or may not, have the gtk_main loop running. It will EVENTUALLY run, so we - // do not want to run our own GTK event loop. - _alreadyRunningGTK |= SystemTray.isSwtLoaded; - - if (SystemTray.DEBUG) { - logger.debug("Is the system already running GTK? {}", _alreadyRunningGTK); - } - - alreadyRunningGTK = _alreadyRunningGTK; - isGtk2 = _isGtk2; - isGtk3 = !_isGtk2; - - MAJOR = major; - MINOR = minor; - MICRO = micro; - } - else { - isLoaded = false; - - alreadyRunningGTK = false; - isGtk2 = false; - isGtk3 = false; - - MAJOR = 0; - MINOR = 0; - MICRO = 0; - } - - if (shouldLoadGtk) { - // now we output what version of GTK we have loaded. - if (SystemTray.DEBUG) { - SystemTray.logger.debug("GTK Version: " + MAJOR + "." + MINOR + "." + MICRO); - } - - if (!_isLoaded) { - throw new RuntimeException("We apologize for this, but we are unable to determine the GTK library is in use, " + - "or even if it is in use... Please create an issue for this and include your OS type and configuration."); - } - } - } -} - diff --git a/src/dorkbox/systemTray/jna/linux/GtkState.java b/src/dorkbox/systemTray/jna/linux/GtkState.java deleted file mode 100644 index 49a39af..0000000 --- a/src/dorkbox/systemTray/jna/linux/GtkState.java +++ /dev/null @@ -1,23 +0,0 @@ -package dorkbox.systemTray.jna.linux; - -/** - * - */ -@SuppressWarnings({"unused", "PointlessBitwiseExpression"}) -public -class GtkState { - public static final int NORMAL = 0x0; // normal state. - public static final int ACTIVE = 0x1; // pressed-in or activated; e.g. buttons while the mouse button is held down. - public static final int PRELIGHT = 0x2; // color when the mouse is over an activatable widget. - public static final int SELECTED = 0x3; // color when something is selected, e.g. when selecting some text to cut/copy. - public static final int INSENSITIVE = 0x4; // color when the mouse is over an activatable widget. - - public static final int FLAG_NORMAL = 0; - public static final int FLAG_ACTIVE = 1 << 0; - public static final int FLAG_PRELIGHT = 1 << 1; - public static final int FLAG_SELECTED = 1 << 2; - public static final int FLAG_INSENSITIVE = 1 << 3; - public static final int FLAG_INCONSISTENT = 1 << 4; - public static final int FLAG_FOCUSED = 1 << 5; - public static final int FLAG_BACKDROP = 1 << 6; -} diff --git a/src/dorkbox/systemTray/jna/linux/GtkTheme.java b/src/dorkbox/systemTray/jna/linux/GtkTheme.java deleted file mode 100644 index 5e085fe..0000000 --- a/src/dorkbox/systemTray/jna/linux/GtkTheme.java +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux; - -import static dorkbox.systemTray.jna.linux.Gtk.Gtk2; -import static dorkbox.systemTray.jna.linux.Gtk.Gtk3; - -import java.awt.Color; -import java.awt.Rectangle; -import java.awt.Toolkit; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.PrintStream; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import com.sun.jna.Pointer; -import com.sun.jna.ptr.PointerByReference; - -import dorkbox.systemTray.SystemTray; -import dorkbox.systemTray.jna.linux.structs.GtkRequisition; -import dorkbox.systemTray.jna.linux.structs.GtkStyle; -import dorkbox.systemTray.jna.linux.structs.PangoRectangle; -import dorkbox.util.FileUtil; -import dorkbox.util.MathUtil; -import dorkbox.util.OS; -import dorkbox.util.OSUtil; -import dorkbox.util.process.ShellProcessBuilder; - -/** - * Class to contain all of the various methods needed to get information set by a GTK theme. - */ -@SuppressWarnings({"deprecation", "WeakerAccess"}) -public -class GtkTheme { - private static final boolean DEBUG = false; - - public static - Rectangle getPixelTextHeight(String text) { - // the following method requires an offscreen widget to get the size of text (for the checkmark size) via pango - // don't forget to destroy everything! - Pointer menu = null; - Pointer item = null; - - try { - menu = Gtk2.gtk_menu_new(); - item = Gtk2.gtk_image_menu_item_new_with_mnemonic(text); - - Gtk2.gtk_container_add(menu, item); - - Gtk2.gtk_widget_realize(menu); - Gtk2.gtk_widget_realize(item); - Gtk2.gtk_widget_show_all(menu); - - // get the text widget (GtkAccelLabel/GtkLabel) from inside the GtkMenuItem - Pointer textLabel = Gtk2.gtk_bin_get_child(item); - Pointer pangoLayout = Gtk2.gtk_label_get_layout(textLabel); - - // ink pixel size is how much exact space it takes on the screen - PangoRectangle ink = new PangoRectangle(); - - Gtk2.pango_layout_get_pixel_extents(pangoLayout, ink.getPointer(), null); - ink.read(); - - return new Rectangle(ink.width, ink.height); - } finally { - Gtk2.gtk_widget_destroy(item); - Gtk2.gtk_widget_destroy(menu); - } - } - - /** - * @return the size of the GTK menu entry's IMAGE, as best as we can tell, for determining how large of icons to use for the menu entry - */ - public static - int getMenuEntryImageSize() { - final AtomicReference imageHeight = new AtomicReference(); - - GtkEventDispatch.dispatchAndWait(new Runnable() { - @Override - public - void run() { - Pointer offscreen = Gtk2.gtk_offscreen_window_new(); - - // get the default icon size for the "paste" icon. - Pointer item = Gtk2.gtk_image_menu_item_new_from_stock("gtk-paste", null); - - Gtk2.gtk_container_add(offscreen, item); - - PointerByReference r = new PointerByReference(); - Gobject.g_object_get(item, "image", r.getPointer(), null); - - Pointer imageWidget = r.getValue(); - GtkRequisition gtkRequisition = new GtkRequisition(); - Gtk2.gtk_widget_size_request(imageWidget, gtkRequisition.getPointer()); - gtkRequisition.read(); - - imageHeight.set(gtkRequisition.height); - } - }); - - int height = imageHeight.get(); - if (height > 0) { - return height; - } - else { - return 16; // who knows? - } - } - - /** - * Gets the system tray indicator size. - * - AppIndicator: will properly scale the image if it's not the correct size - * - GtkStatusIndicator: ?? - */ - public static - int getIndicatorSize() { - // Linux is similar enough, that it just uses this method - // https://wiki.archlinux.org/index.php/HiDPI - - // 96 DPI is the default - final double defaultDPI = 96.0; - - final AtomicReference screenScale = new AtomicReference(); - final AtomicInteger screenDPI = new AtomicInteger(); - screenScale.set(0D); - screenDPI.set(0); - - GtkEventDispatch.dispatchAndWait(new Runnable() { - @Override - public - void run() { - // screen DPI - Pointer screen = Gtk2.gdk_screen_get_default(); - if (screen != null) { - // this call makes NO SENSE, but reading the documentation shows it is the CORRECT call. - screenDPI.set((int) Gtk2.gdk_screen_get_resolution(screen)); - } - - if (Gtk2.isGtk3) { - Pointer window = Gtk2.gdk_get_default_root_window(); - if (window != null) { - double scale = Gtk3.gdk_window_get_scale_factor(window); - screenScale.set(scale); - } - } - } - }); - - // fallback - if (screenDPI.get() == 0) { - // GET THE DPI IN LINUX - // https://wiki.archlinux.org/index.php/Talk:GNOME - Object detectedValue = Toolkit.getDefaultToolkit().getDesktopProperty("gnome.Xft/DPI"); - if (detectedValue instanceof Integer) { - int dpi = ((Integer) detectedValue) / 1024; - if (dpi == -1) { - screenDPI.set((int) defaultDPI); - } - if (dpi < 50) { - // 50 dpi is the minimum value gnome allows - screenDPI.set(50); - } - } - } - - - // check system ENV variables. - if (screenScale.get() == 0) { - String envVar = System.getenv("QT_AUTO_SCREEN_SCALE_FACTOR"); - if (envVar != null) { - try { - screenScale.set(Double.parseDouble(envVar)); - } catch (Exception ignored) { - } - } - } - - // check system ENV variables. - if (screenScale.get() == 0) { - String envVar = System.getenv("QT_SCALE_FACTOR"); - if (envVar != null) { - try { - screenScale.set(Double.parseDouble(envVar)); - } catch (Exception ignored) { - } - } - } - - // check system ENV variables. - if (screenScale.get() == 0) { - String envVar = System.getenv("GDK_SCALE"); - if (envVar != null) { - try { - screenScale.set(Double.parseDouble(envVar)); - } catch (Exception ignored) { - } - } - } - - // check system ENV variables. - if (screenScale.get() == 0) { - String envVar = System.getenv("ELM_SCALE"); - if (envVar != null) { - try { - screenScale.set(Double.parseDouble(envVar)); - } catch (Exception ignored) { - } - } - } - - - - OSUtil.DesktopEnv.Env env = OSUtil.DesktopEnv.get(); - // sometimes the scaling-factor is set. If we have gsettings, great! otherwise try KDE - try { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8196); - PrintStream outputStream = new PrintStream(byteArrayOutputStream); - - // gsettings get org.gnome.desktop.interface scaling-factor - final ShellProcessBuilder shellVersion = new ShellProcessBuilder(outputStream); - shellVersion.setExecutable("gsettings"); - shellVersion.addArgument("get"); - shellVersion.addArgument("org.gnome.desktop.interface"); - shellVersion.addArgument("scaling-factor"); - shellVersion.start(); - - String output = ShellProcessBuilder.getOutput(byteArrayOutputStream); - - if (!output.isEmpty()) { - // DEFAULT icon size is 16. HiDpi changes this scale, so we should use it as well. - // should be: uint32 0 or something - if (output.contains("uint32")) { - String value = output.substring(output.indexOf("uint") + 7, output.length()); - - // 0 is disabled (no scaling) - // 1 is enabled (default scale) - // 2 is 2x scale - // 3 is 3x scale - // etc - - double scalingFactor = Double.parseDouble(value); - if (scalingFactor >= 1) { - screenScale.set(scalingFactor); - } - - // A setting of 2, 3, etc, which is all you can do with scaling-factor - // To enable HiDPI, use gsettings: - // gsettings set org.gnome.desktop.interface scaling-factor 2 - } - } - } catch (Throwable ignore) { - } - - if (OSUtil.DesktopEnv.isKDE()) { - // check the custom KDE override file - try { - File customSettings = new File("/usr/bin/startkde-custom"); - if (customSettings.canRead()) { - List lines = FileUtil.readLines(customSettings); - for (String line : lines) { - String str = "export GDK_SCALE="; - int i = line.indexOf(str); - if (i > -1) { - String scale = line.substring(i + str.length()); - double scalingFactor = Double.parseDouble(scale); - if (scalingFactor >= 1) { - screenScale.set(scalingFactor); - break; - } - } - } - } - } catch (Exception ignored) { - } - } - -// System.err.println("screen scale: " + screenScale.get()); -// System.err.println("screen DPI: " + screenDPI.get()); - - if (OSUtil.DesktopEnv.isKDE()) { - /* - * - * Looking in plasma-framework/src/declarativeimports/core/units.cpp: - // Scale the icon sizes up using the devicePixelRatio - // This function returns the next stepping icon size - // and multiplies the global settings with the dpi ratio. - const qreal ratio = devicePixelRatio(); - - if (ratio < 1.5) { - return size; - } else if (ratio < 2.0) { - return size * 1.5; - } else if (ratio < 2.5) { - return size * 2.0; - } else if (ratio < 3.0) { - return size * 2.5; - } else if (ratio < 3.5) { - return size * 3.0; - } else { - return size * ratio; - } -My ratio is 1.47674, that means I have no scaling at all when there is a 1.5 factor existing. Is it reasonable? Wouldn't it make more sense to use the factor the closest to the ratio rather than what is done here? - - */ - - File mainFile = new File("/usr/share/plasma/plasmoids/org.kde.plasma.private.systemtray/contents/config/main.xml"); - if (mainFile.canRead()) { - List lines = FileUtil.readLines(mainFile); - boolean found = false; - int index; - for (final String line : lines) { - if (line.contains("")) { - found = true; - // have to get the "default" line value - } - - String str = ""; - if (found && (index = line.indexOf(str)) > -1) { - // this is our line. now get the value. - String substring = line.substring(index + str.length(), line.indexOf("", index)); - - if (MathUtil.isInteger(substring)) { - // Default icon size for the systray icons, it's an enum which values mean, - // Small, SmallMedium, Medium, Large, Huge, Enormous respectively. - // On low DPI systems they correspond to : - // 16, 22, 32, 48, 64, 128 pixels. - // On high DPI systems those values would be scaled up, depending on the DPI. - int imageSize = 0; - int imageSizeEnum = Integer.parseInt(substring); - switch (imageSizeEnum) { - case 0: - imageSize = 16; - break; - case 1: - imageSize = 22; - break; - case 2: - imageSize = 32; - break; - case 3: - imageSize = 48; - break; - case 4: - imageSize = 64; - break; - case 5: - imageSize = 128; - break; - } - - if (imageSize > 0) { - double scaleRatio = screenDPI.get() / defaultDPI; - - return (int) (scaleRatio * imageSize); - } - } - } - } - } - } - else { - if (OSUtil.Linux.isUbuntu() && env == OSUtil.DesktopEnv.Env.Unity || env == OSUtil.DesktopEnv.Env.Unity7) { - // if we measure on ubuntu unity using a screen shot (using swing, so....) , the max size was 24, HOWEVER this goes from - // the top->bottom of the indicator bar -- and since it was swing, it uses a different rendering method and it (honestly) - // looks weird, because there is no padding for the icon. The official AppIndicator size is hardcoded... - // http://bazaar.launchpad.net/~indicator-applet-developers/libindicator/trunk.16.10/view/head:/libindicator/indicator-image-helper.c - - return 22; - } - else { - // xfce is easy, because it's not a GTK setting for the size (xfce notification area maximum icon size) - if (env == OSUtil.DesktopEnv.Env.XFCE) { - String properties = OSUtil.DesktopEnv.queryXfce("xfce4-panel", null); - List propertiesAsList = Arrays.asList(properties.split(OS.LINE_SEPARATOR)); - for (String prop : propertiesAsList) { - if (prop.startsWith("/plugins/") && prop.endsWith("/size-max")) { - // this is the property we are looking for (we just don't know which panel it's on) - - String size = OSUtil.DesktopEnv.queryXfce("xfce4-panel", prop); - try { - return Integer.parseInt(size); - } catch (Exception e) { - SystemTray.logger.error("Unable to get XFCE notification panel size for channel '{}', property '{}'", - "xfce4-panel", prop, e); - } - } - } - - // default... - return 22; - } - - - // try to use GTK to get the tray icon size - final AtomicInteger traySize = new AtomicInteger(); - - GtkEventDispatch.dispatchAndWait(new Runnable() { - @Override - public - void run() { - Pointer screen = Gtk2.gdk_screen_get_default(); - Pointer settings = null; - - if (screen != null) { - settings = Gtk2.gtk_settings_get_for_screen(screen); - } - - if (settings != null) { - PointerByReference pointer = new PointerByReference(); - - // https://wiki.archlinux.org/index.php/GTK%2B - // To use smaller icons, use a line like this: - // gtk-icon-sizes = "panel-menu=16,16:panel=16,16:gtk-menu=16,16:gtk-large-toolbar=16,16:gtk-small-toolbar=16,16:gtk-button=16,16" - - // this gets icon sizes. On XFCE, ubuntu, it returns "panel-menu-bar=24,24" - // NOTE: gtk-icon-sizes is deprecated and ignored since GTK+ 3.10. - - // A list of icon sizes. The list is separated by colons, and item has the form: size-name = width , height - Gobject.g_object_get(settings, "gtk-icon-sizes", pointer.getPointer(), null); - - Pointer value = pointer.getValue(); - if (value != null) { - String iconSizes = value.getString(0); - String[] strings = new String[] {"panel-menu-bar=", "panel=", "gtk-large-toolbar=", "gtk-small-toolbar="}; - for (String var : strings) { - int i = iconSizes.indexOf(var); - if (i >= 0) { - String size = iconSizes.substring(i + var.length(), iconSizes.indexOf(",", i)); - - if (MathUtil.isInteger(size)) { - traySize.set(Integer.parseInt(size)); - return; - } - } - } - } - } - } - }); - - int i = traySize.get(); - if (i != 0) { - return i; - } - } - } - - // sane default - return 22; - } - - /** - * @return the widget color of text for the current theme, or black. It is important that this is called AFTER GTK has been initialized. - */ - public static - Color getTextColor() { - final AtomicReference color = new AtomicReference(null); - GtkEventDispatch.dispatchAndWait(new Runnable() { - @SuppressWarnings("UnusedAssignment") - @Override - public - void run() { - Color c = null; - - // the following method requires an offscreen widget to get the style information from. - // don't forget to destroy everything! - Pointer menu = null; - Pointer item = null; - - try { - menu = Gtk2.gtk_menu_new(); - item = Gtk2.gtk_image_menu_item_new_with_mnemonic("a"); - - Gtk2.gtk_container_add(menu, item); - - Gtk2.gtk_widget_realize(menu); - Gtk2.gtk_widget_realize(item); - Gtk2.gtk_widget_show_all(menu); - - GtkStyle style = Gtk2.gtk_rc_get_style(item); - style.read(); - - // this is the same color chromium uses (fg) - // https://chromium.googlesource.com/chromium/src/+/b3ca230ddd7d1238ee96ed26ea23e369f10dd655/chrome/browser/ui/libgtk2ui/gtk2_ui.cc#873 - c = style.fg[GtkState.NORMAL].getColor(); - - color.set(c); - } finally { - Gtk2.gtk_widget_destroy(item); - Gtk2.gtk_widget_destroy(menu); - } - } - }); - - - Color c = color.get(); - if (c != null) { - if (DEBUG) { - System.err.println("COLOR FOUND: " + c); - } - return c; - } - - SystemTray.logger.error("Unable to determine the text color in use by your system. Please create an issue and include your " + - "full OS configuration and desktop environment, including theme details, such as the theme name, color " + - "variant, and custom theme options (if any)."); - - // who knows WHAT the color is supposed to be. This is just a "best guess" default value. - return Color.BLACK; - } -} diff --git a/src/dorkbox/systemTray/jna/linux/structs/AppIndicatorInstanceStruct.java b/src/dorkbox/systemTray/jna/linux/structs/AppIndicatorInstanceStruct.java deleted file mode 100644 index 4d97eb1..0000000 --- a/src/dorkbox/systemTray/jna/linux/structs/AppIndicatorInstanceStruct.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux.structs; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; - -import dorkbox.util.Keep; - -@Keep -public -class AppIndicatorInstanceStruct extends Structure { - public GObjectStruct parent; - public Pointer priv; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("parent", "priv"); - } -} diff --git a/src/dorkbox/systemTray/jna/linux/structs/GObjectStruct.java b/src/dorkbox/systemTray/jna/linux/structs/GObjectStruct.java deleted file mode 100644 index 14d74d5..0000000 --- a/src/dorkbox/systemTray/jna/linux/structs/GObjectStruct.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux.structs; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; - -import dorkbox.util.Keep; - -@Keep -public -class GObjectStruct extends Structure { - public - class ByValue extends GObjectStruct implements Structure.ByValue {} - - - public - class ByReference extends GObjectStruct implements Structure.ByReference {} - - - public GTypeInstanceStruct g_type_instance; - public int ref_count; - public Pointer qdata; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("g_type_instance", "ref_count", "qdata"); - } -} diff --git a/src/dorkbox/systemTray/jna/linux/structs/GTypeInstanceStruct.java b/src/dorkbox/systemTray/jna/linux/structs/GTypeInstanceStruct.java deleted file mode 100644 index 6f27fbb..0000000 --- a/src/dorkbox/systemTray/jna/linux/structs/GTypeInstanceStruct.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux.structs; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; - -import dorkbox.util.Keep; - -@Keep -public -class GTypeInstanceStruct extends Structure { - public - class ByValue extends GTypeInstanceStruct implements Structure.ByValue {} - - - public - class ByReference extends GTypeInstanceStruct implements Structure.ByReference {} - - - public Pointer g_class; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("g_class"); - } -} diff --git a/src/dorkbox/systemTray/jna/linux/structs/GdkColor.java b/src/dorkbox/systemTray/jna/linux/structs/GdkColor.java deleted file mode 100644 index 000e356..0000000 --- a/src/dorkbox/systemTray/jna/linux/structs/GdkColor.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux.structs; - -import java.awt.Color; -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Structure; - -/** - * https://developer.gnome.org/gdk3/stable/gdk3-Colors.html - * - * GdkColor has been deprecated since version 3.14 and should not be used in newly-written code. - */ -public -class GdkColor extends Structure { - - /* The color type. - * A color consists of red, green and blue values in the - * range 0-65535 and a pixel value. The pixel value is highly - * dependent on the depth and colormap which this color will - * be used to draw into. Therefore, sharing colors between - * colormaps is a bad idea. - */ - public int pixel; - public short red; - public short green; - public short blue; - - /** - * Convert from positive int (value between 0 and 65535, these are 16 bits per pixel) to values from 0-255 - */ - private static int convert(int inputColor) { - return (inputColor & 0x0000FFFF >> 8) & 0xFF; - } - - public int red() { - return convert(red); - } - - public int green() { - return convert(green); - } - - public int blue() { - return convert(blue); - } - - public - Color getColor() { - read(); // have to read the struct members first! - return new Color(red(), green(), blue()); - } - - @Override - public - String toString() { - return "[r=" + red() + ",g=" + green() + ",b=" + blue() + "]"; - } - - @Override - protected - List getFieldOrder() { - return Arrays.asList("pixel", "red", "green", "blue"); - } - - - public - class ByValue extends GdkColor implements Structure.ByValue {} - - - public static - class ByReference extends GdkColor implements Structure.ByReference {} -} diff --git a/src/dorkbox/systemTray/jna/linux/structs/GdkEventButton.java b/src/dorkbox/systemTray/jna/linux/structs/GdkEventButton.java deleted file mode 100644 index e74510d..0000000 --- a/src/dorkbox/systemTray/jna/linux/structs/GdkEventButton.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2015 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux.structs; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; - -import dorkbox.util.Keep; - -@Keep -public -class GdkEventButton extends Structure { - public int type; - public Pointer window; - public int send_event; - public int time; - public double x; - public double y; - public Pointer axes; - public int state; - public int button; - public Pointer device; - public double x_root; - public double y_root; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("type", "window", "send_event", "time", "x", "y", "axes", "state", "button", "device", "x_root", "y_root"); - } -} diff --git a/src/dorkbox/systemTray/jna/linux/structs/GtkRequisition.java b/src/dorkbox/systemTray/jna/linux/structs/GtkRequisition.java deleted file mode 100644 index faac052..0000000 --- a/src/dorkbox/systemTray/jna/linux/structs/GtkRequisition.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux.structs; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Structure; - -/** - * https://developer.gimp.org/api/2.0/gtk/GtkWidget.html#GtkRequisition - */ -public -class GtkRequisition extends Structure { - - public int width; - public int height; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("width", "height"); - } -} diff --git a/src/dorkbox/systemTray/jna/linux/structs/GtkStyle.java b/src/dorkbox/systemTray/jna/linux/structs/GtkStyle.java deleted file mode 100644 index 70e8420..0000000 --- a/src/dorkbox/systemTray/jna/linux/structs/GtkStyle.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux.structs; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; - -import dorkbox.util.Keep; - -@Keep -public -class GtkStyle extends Structure { - /* - * There are several 'directives' to change the attributes of a widget. - * fg - Sets the foreground color of a widget. - * bg - Sets the background color of a widget. - * text - Sets the foreground color for widgets that have editable text. - * base - Sets the background color for widgets that have editable text. - * bg_pixmap - Sets the background of a widget to a tiled pixmap. - * font_name - Sets the font to be used with the given widget. - * xthickness - Sets the left and right border width. This is not what you might think; it sets the borders of children(?) - * ythickness - similar to above but for the top and bottom. - * - * There are several states a widget can be in, and you can set different colors, pixmaps and fonts for each state. These states are: - * NORMAL - The normal state of a widget. Ie the mouse is not over it, and it is not being pressed, etc. - * PRELIGHT - When the mouse is over top of the widget, colors defined using this state will be in effect. - * ACTIVE - When the widget is pressed or clicked it will be active, and the attributes assigned by this tag will be in effect. - * INSENSITIVE - This is the state when a widget is 'greyed out'. It is not active, and cannot be clicked on. - * SELECTED - When an object is selected, it takes these attributes. - */ - - public static - class ByReference extends GtkStyle implements Structure.ByReference { - } - - public - class ByValue extends GtkStyle implements Structure.ByValue { - } - - // required, even though it's "private" in the corresponding C code. OTHERWISE the memory offsets are INCORRECT. - public GObjectStruct parent_instance; - - /** fg: foreground for drawing GtkLabel */ - public GdkColor fg[] = new GdkColor[5]; - - /** bg: the usual background color, gray by default */ - public GdkColor bg[] = new GdkColor[5]; - - public GdkColor light[] = new GdkColor[5]; - public GdkColor dark[] = new GdkColor[5]; - public GdkColor mid[] = new GdkColor[5]; - - /** - * text: text for entries and text widgets (although in GTK 1.2 sometimes fg gets used, this is more or less a bug and fixed in GTK 2.0). - */ - public GdkColor text[] = new GdkColor[5]; - - /** base: background when using text, colored white in the default theme. */ - public GdkColor base[] = new GdkColor[5]; - - /** Halfway between text/base */ - public GdkColor text_aa[] = new GdkColor[5]; - - public GdkColor black; - public GdkColor white; - public Pointer /*PangoFontDescription*/ font_desc; - public int xthickness; - public int ythickness; - public Pointer /*cairo_pattern_t*/ background[] = new Pointer[5]; - - public - void debug(final int gtkState) { - System.err.println("base " + base[gtkState].getColor()); - System.err.println("text " + text[gtkState].getColor()); - System.err.println("text_aa " + text_aa[gtkState].getColor()); - System.err.println("bg " + bg[gtkState].getColor()); - System.err.println("fg " + fg[gtkState].getColor()); - } - - - @Override - protected - List getFieldOrder() { - return Arrays.asList("parent_instance", - "fg", - "bg", - "light", - "dark", - "mid", - "text", - "base", - "text_aa", - "black", - "white", - "font_desc", - "xthickness", - "ythickness", - "background"); - } -} diff --git a/src/dorkbox/systemTray/jna/linux/structs/PangoRectangle.java b/src/dorkbox/systemTray/jna/linux/structs/PangoRectangle.java deleted file mode 100644 index 1f58343..0000000 --- a/src/dorkbox/systemTray/jna/linux/structs/PangoRectangle.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2017 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.systemTray.jna.linux.structs; - -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Structure; - -/** - * https://developer.gnome.org/pango/stable/pango-Glyph-Storage.html#PangoRectangle - */ -public -class PangoRectangle extends Structure { - - public int x; - public int y; - public int width; - public int height; - - @Override - protected - List getFieldOrder() { - return Arrays.asList("x", "y", "width", "height"); - } -}