From 5f4ce7f6559382ab1c2c8af10e2d875864a5ee86 Mon Sep 17 00:00:00 2001 From: hanez Date: Wed, 15 Jul 2026 23:18:48 +0200 Subject: [PATCH] A lot of modernizing. --- CMakeLists.txt | 6 -- Makefile | 12 ---- requirements.txt | 1 - setup.py | 0 spacetray.c | 85 +++++++++++++++++++----- spacetray.py | 47 ------------- spacetray2.c | 168 ----------------------------------------------- themes/lock.h | 4 +- 8 files changed, 69 insertions(+), 254 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 requirements.txt delete mode 100644 setup.py delete mode 100755 spacetray.py delete mode 100644 spacetray2.c diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 22a20a1..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 3.26) -project(spacetray C) - -set(CMAKE_C_STANDARD 11) - -add_executable(spacetray spacetray.c) diff --git a/Makefile b/Makefile index 4afc205..ef923a6 100644 --- a/Makefile +++ b/Makefile @@ -9,15 +9,3 @@ clean: run: ./bin/spacetray - -all2: - $(CC) -Wall -g `pkg-config --cflags --libs gtk+-2.0 --libs appindicator-0.1 --libs libcurl --libs json-c --libs libnotify` -DLIBNOTIFY -o bin/spacetray2 spacetray2.c - -nonotify2: - $(CC) -Wall -g `pkg-config --cflags --libs gtk+-2.0 --libs appindicator-0.1 --libs libcurl --libs json-c` -o bin/spacetray2 spacetray2.c - -clean2: - rm -f ./bin/spacetray2 - -run2: - ./bin/spacetray2 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index d78b713..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pygobject==3.46.0 \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index e69de29..0000000 diff --git a/spacetray.c b/spacetray.c index f2681b6..f68e86c 100644 --- a/spacetray.c +++ b/spacetray.c @@ -3,7 +3,6 @@ * * Author: hanez * Website: https://hanez.org/project/spacetray/ - * Contributors: atari, beh, eisbaer and Haeger * * License (MIT License): * @@ -13,9 +12,19 @@ */ #include +#define GLIB_DISABLE_DEPRECATION_WARNINGS +#define GDK_PIXBUF_ENABLE_BACKWARDS_COMPATIBILITY #include #include #include + +#ifdef G_GNUC_BEGIN_IGNORE_DEPRECATIONS +#define IGNORE_DEPRECATIONS_START G_GNUC_BEGIN_IGNORE_DEPRECATIONS +#define IGNORE_DEPRECATIONS_END G_GNUC_END_IGNORE_DEPRECATIONS +#else +#define IGNORE_DEPRECATIONS_START +#define IGNORE_DEPRECATIONS_END +#endif #if LIBNOTIFY #include #endif @@ -23,6 +32,8 @@ #include #include #include +#include +#include #include "themes/lock.h" @@ -32,7 +43,7 @@ struct string { }; static char *name = "SpaceAPI widget for UNIX"; -static char *statusurl = "https://www.hamburg.ccc.de/dooris/status.json"; +static char *statusurl = NULL; static char *agent = "Spacetray/0.42"; // The delay for polling the dooris service. Adjust this before compiling @@ -40,10 +51,24 @@ static int delay = 1000; // ms. aka 15 minutes bool door_open = false; bool old_door_open = false; +int door_last_change = 0; void do_it(); void invoke_notification(); +gboolean do_it_wrapper(gpointer data) { + do_it(); + return FALSE; +} + +void *status_update_thread(void *arg) { + while (1) { + sleep(delay); + g_idle_add(do_it_wrapper, NULL); + } + return NULL; +} + GtkStatusIcon *tray_icon; void init_string(struct string *s) { @@ -79,8 +104,6 @@ void get_bouncer_data() { struct json_object *leaf_json_object; bool door_status; - int door_last_change; - struct string s; printf("Called get_bouncer_data()\n"); @@ -123,14 +146,8 @@ void get_bouncer_data() { leaf_json_object = json_object_object_get(door_json_object, "lastchange"); door_last_change = json_object_get_int(leaf_json_object); - // free door object - json_object_put(door_json_object); - - // free leaf object - //json_object_put(leaf_json_object); - // free response object - // json_object_put(response_json_object); + json_object_put(response_json_object); printf("Door status: = %d\n", door_status); printf("Door last change: = %d\n", door_last_change); @@ -143,12 +160,17 @@ void get_bouncer_data() { } void invoke_notification() { - char door[20]; + char door[128]; + char date_str[64]; + time_t last_change_time = (time_t)door_last_change; + struct tm *tm_info = localtime(&last_change_time); + + strftime(date_str, sizeof(date_str), "%Y-%m-%d %H:%M:%S", tm_info); if (door_open == true) { - snprintf(door, 20, "Door open..."); + snprintf(door, sizeof(door), "Door open since %s", date_str); } else { - snprintf(door, 20, "Door closed..."); + snprintf(door, sizeof(door), "Door closed since %s", date_str); } gtk_status_icon_set_tooltip(tray_icon, door); @@ -156,20 +178,23 @@ void invoke_notification() { #if LIBNOTIFY NotifyNotification *n; - notify_init(name); n = notify_notification_new(name, door, NULL); //notify_notification_set_timeout(n, 10000); if (door_open == true) { + IGNORE_DEPRECATIONS_START notify_notification_set_icon_from_pixbuf(n, gdk_pixbuf_from_pixdata( - &icon_closed_pixbuf, + &icon_open_pixbuf, true, NULL)); + IGNORE_DEPRECATIONS_END } else { + IGNORE_DEPRECATIONS_START notify_notification_set_icon_from_pixbuf(n, gdk_pixbuf_from_pixdata( &icon_closed_pixbuf, true, NULL)); + IGNORE_DEPRECATIONS_END } notify_notification_show(n, NULL); g_object_unref(G_OBJECT(n)); @@ -179,31 +204,50 @@ void invoke_notification() { void set_status() { if (door_open == true) { printf("Set to status: open\n"); + IGNORE_DEPRECATIONS_START gtk_status_icon_set_from_pixbuf(tray_icon, gdk_pixbuf_from_pixdata(&icon_open_pixbuf, true, NULL)); + IGNORE_DEPRECATIONS_END } else { printf("Set to status: closed\n"); + IGNORE_DEPRECATIONS_START gtk_status_icon_set_from_pixbuf(tray_icon, gdk_pixbuf_from_pixdata(&icon_closed_pixbuf, true, NULL)); + IGNORE_DEPRECATIONS_END } } void do_it() { + static bool first_run = true; get_bouncer_data(); set_status(); - if (door_open != old_door_open) { + if (!first_run && door_open != old_door_open) { invoke_notification(); } + first_run = false; } int main(int argc, char **argv) { + pthread_t thread_id; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + statusurl = argv[1]; + gtk_init(&argc, &argv); +#if LIBNOTIFY + notify_init(name); +#endif + tray_icon = gtk_status_icon_new(); g_signal_connect(G_OBJECT(tray_icon), "activate", G_CALLBACK(do_it), NULL); @@ -220,7 +264,12 @@ int main(int argc, char **argv) { //invoke_notification(); //gtk_timeout_add(delay, (GtkFunction)do_it, (gpointer)NULL); - guint xxx = g_timeout_add_seconds(1000, (GSourceFunc)do_it, (gpointer)NULL); + // guint xxx = g_timeout_add_seconds(1000, (GSourceFunc)do_it, (gpointer)NULL); + + if (pthread_create(&thread_id, NULL, status_update_thread, NULL) != 0) { + fprintf(stderr, "Error creating thread\n"); + return 1; + } gtk_main(); diff --git a/spacetray.py b/spacetray.py deleted file mode 100755 index 3d26fb3..0000000 --- a/spacetray.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2023 Johannes Findeisen . -# -import gi -import sys -gi.require_version('Gtk', '3.0') -from gi.repository import Gtk -gi.require_version('AppIndicator3', '0.1') -from gi.repository import AppIndicator3 as AppIndicator - -__VERSION__ = "0.0.3" - - -def menuitem_response(w, label): - print(label) - - -def exit_app(): - sys.exit() - - -if __name__ == "__main__": - ind = AppIndicator.Indicator.new("example-simple-client", - "indicator-messages", - AppIndicator.IndicatorCategory.APPLICATION_STATUS) - ind.set_status(AppIndicator.IndicatorStatus.ACTIVE) - ind.set_attention_icon("indicator-messages-new") - - # create a menu - menu = Gtk.Menu() - - # create some sub menus - for i in range(3): - label = "Test-sub-menu - %d" % i - menu_items = Gtk.MenuItem(label=label) - menu.append(menu_items) - - # this is where you would connect your menu item up with a function: - menu_items.connect("activate", menuitem_response, label) - - # show the items - menu_items.show() - - ind.set_menu(menu) - - Gtk.main() diff --git a/spacetray2.c b/spacetray2.c deleted file mode 100644 index 3266d77..0000000 --- a/spacetray2.c +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include - -static void activate_action (GtkAction *action); - -static GtkActionEntry entries[] = { - { "FileMenu", NULL, "_File" }, - { "New", "document-new", "_New", "N", - "Create a new file", G_CALLBACK (activate_action) }, - { "Open", "document-open", "_Open", "O", - "Open a file", G_CALLBACK (activate_action) }, - { "Save", "document-save", "_Save", "S", - "Save file", G_CALLBACK (activate_action) }, - { "Quit", "application-exit", "_Quit", "Q", - "Exit the application", G_CALLBACK (gtk_main_quit) }, -}; -static guint n_entries = G_N_ELEMENTS (entries); - -static const gchar *ui_info = -"" -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -""; - -static void -activate_action (GtkAction *action) -{ - const gchar *name = gtk_action_get_name (action); - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, - "You activated action: \"%s\"", - name); - - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - - gtk_widget_show (dialog); -} - -int main (int argc, char **argv) -{ - GtkWidget *window; - GtkWidget *menubar; - GtkWidget *table; - GtkWidget *sw; - GtkWidget *contents; - GtkWidget *statusbar; - GtkWidget *indicator_menu; - GtkActionGroup *action_group; - GtkUIManager *uim; - AppIndicator *indicator; - GError *error = NULL; - - gtk_init (&argc, &argv); - - /* main window */ - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "Indicator Demo"); - gtk_window_set_icon_name (GTK_WINDOW (window), "indicator-messages-new"); - g_signal_connect (G_OBJECT (window), - "destroy", - G_CALLBACK (gtk_main_quit), - NULL); - - table = gtk_table_new (1, 5, FALSE); - gtk_container_add (GTK_CONTAINER (window), table); - - /* Menus */ - action_group = gtk_action_group_new ("AppActions"); - gtk_action_group_add_actions (action_group, - entries, n_entries, - window); - - uim = gtk_ui_manager_new (); - g_object_set_data_full (G_OBJECT (window), - "ui-manager", uim, - g_object_unref); - gtk_ui_manager_insert_action_group (uim, action_group, 0); - gtk_window_add_accel_group (GTK_WINDOW (window), - gtk_ui_manager_get_accel_group (uim)); - - if (!gtk_ui_manager_add_ui_from_string (uim, ui_info, -1, &error)) - { - g_message ("Failed to build menus: %s\n", error->message); - g_error_free (error); - error = NULL; - } - - menubar = gtk_ui_manager_get_widget (uim, "/ui/MenuBar"); - gtk_widget_show (menubar); - gtk_table_attach (GTK_TABLE (table), - menubar, - 0, 1, 0, 1, - GTK_EXPAND | GTK_FILL, 0, - 0, 0); - - /* Document */ - sw = gtk_scrolled_window_new (NULL, NULL); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), - GTK_SHADOW_IN); - - gtk_table_attach (GTK_TABLE (table), - sw, - /* X direction */ /* Y direction */ - 0, 1, 3, 4, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, - 0, 0); - - gtk_window_set_default_size (GTK_WINDOW (window), - 200, 200); - - contents = gtk_text_view_new (); - gtk_widget_grab_focus (contents); - - gtk_container_add (GTK_CONTAINER (sw), - contents); - - - /* Create statusbar */ - statusbar = gtk_statusbar_new (); - gtk_table_attach (GTK_TABLE (table), - statusbar, - /* X direction */ /* Y direction */ - 0, 1, 4, 5, - GTK_EXPAND | GTK_FILL, 0, - 0, 0); - - /* Show the window */ - gtk_widget_show_all (window); - - /* Indicator */ - indicator = app_indicator_new ("example-simple-client", - "indicator-messages", - APP_INDICATOR_CATEGORY_APPLICATION_STATUS); - - indicator_menu = gtk_ui_manager_get_widget (uim, "/ui/IndicatorPopup"); - - app_indicator_set_status (indicator, APP_INDICATOR_STATUS_ACTIVE); - app_indicator_set_attention_icon (indicator, "indicator-messages-new"); - - app_indicator_set_menu (indicator, GTK_MENU (indicator_menu)); - - gtk_main (); - - return 0; -} diff --git a/themes/lock.h b/themes/lock.h index 05fa722..7d92b12 100644 --- a/themes/lock.h +++ b/themes/lock.h @@ -6,7 +6,7 @@ static const GdkPixdata icon_open_pixbuf = { 52, /* width */ 48, /* height */ /* pixel_data: */ - "\202\0\0\0\0\4\200\0\0\6\200\0\0\221\200\0\0\337\200\0\0\362\251\200" + (guint8 *)"\202\0\0\0\0\4\200\0\0\6\200\0\0\221\200\0\0\337\200\0\0\362\251\200" "\0\0\365\3\201\0\0\354\200\0\0\316\177\0\0L\203\0\0\0\0\5\177\0\0(\200" "\0\0\362\200\0\0\377\201\1\1\376\203\4\4\376\227\202\4\4\377\222\202" "\5\5\377\11\203\4\4\376\200\0\0\377\177\0\0\377\201\1\1\270\0\0\0\0\0" @@ -320,7 +320,7 @@ static const GdkPixdata icon_closed_pixbuf = { 52, /* width */ 48, /* height */ /* pixel_data: */ - "\202\0\0\0\0\3/M\30+.P\25\263.Q\25\332\251-P\26\343\3-P\27\337-P\26\310" + (guint8 *)"\202\0\0\0\0\3/M\30+.P\25\263.Q\25\332\251-P\26\343\3-P\27\337-P\26\310" ".O\26j\204\0\0\0\0\1.Q\25\233\202-P\26\377\1-P\26\376\236.Q\30\376\213" "/Q\30\376\12.Q\30\376-Q\27\377-P\26\377-Q\26\3441U\30\25\0\0\0\0-Q\25" "x-P\26\3770R\31\377Ih6\377\214Rn@\377\1Sn@\377\202SnA\377\202SoB\377"