Page 1 of 3

Simple Clock

Posted: Mon Jun 13, 2022 6:48 pm
by masinick

I have a short Bash script that produces a simple clock in the top left corner of a bash shell window.
I've copied the text of the script below.

I'd like to create a very simple Yad script that displays the date and time like this:
Jun 13, 2022 02:42:01 PM

in a small Yad clock. I've seen a Yad alarm clock called yalarm that was created a few years ago.
I have been able to modify the clock time in that script using the simple "%r" string instead of the "%H:%M:%S" string, but when I attempt to pull out the alarm clock function I have been unable to do that successfully and still display the time or the date and time.

Here is my bash script code:

Code: Select all

loop=1
while (( loop )); do
  clear
  date +"%b %d, %Y  %r"
  sleep 0.5s
done

Does anyone know what I can add to this simple script to display it in a small yad window instead of the terminal window?

Thanks for any guidance.


Re: Simple Clock

Posted: Mon Jun 13, 2022 7:56 pm
by fredx181

Hi masinick,
The following should do it basically, but tell me if you want the display similar as in yalarm with the colors and the special font and I'll look into that.

Code: Select all

while :
do
  date +"%b %d, %Y  %r"
  sleep 0.5
done 2>&1 | yad --title=clock --width=220 --form --cycle-read --field=": " --no-buttons --undecorated  &
2022-06-13_21-55-43.gif
2022-06-13_21-55-43.gif (20.61 KiB) Viewed 2673 times

EDIT: Could look like this with colors and special font (not transparent borders in this image but should be possible to make transparent by using "gtkdesklet"):

2022-06-13_22-43-06.gif
2022-06-13_22-43-06.gif (50.14 KiB) Viewed 2663 times

Re: Simple Clock

Posted: Mon Jun 13, 2022 8:53 pm
by mikewalsh

@fredx181 :-

"--cycle-read", huh? New one on me. Where d'ya find that one? I don't see any mention of this anywhere in the man pages...

Mike. ;)


Re: Simple Clock

Posted: Mon Jun 13, 2022 9:07 pm
by fredx181
mikewalsh wrote: Mon Jun 13, 2022 8:53 pm

@fredx181 :-

"--cycle-read", huh? New one on me. Where d'ya find that one? I don't see any mention of this anywhere in the man pages...

Mike. ;)

It's a real option (I didn't just dream it :) ) see here for example; https://www.mankier.com/1/yad

--cycle-read

Cycled reading of stdin data. Sending FormFeed character clears the form. This symbol may be sent as echo -e '\f'.

EDIT: Not sure btw from which yad version on this is supported, I use yad v0.40


Re: Simple Clock

Posted: Mon Jun 13, 2022 9:15 pm
by masinick

Thanks!

I also added --posx and --posy coordinates to move the box close to the top; experimenting to see what values are best for my current setup.

I really appreciate your help!


Re: Simple Clock

Posted: Mon Jun 13, 2022 9:27 pm
by mikewalsh

Hmm... Interesting.

Can I pick your brains, Fred?

That wee script works a treat. I've modified it slightly, to go in a specific place on the desktop:-

Code: Select all

#!/bin/sh
#
# YAD clock... (cheers, Fred!)
#
while :
do
  date +"%a %d %b %H:%M %S"
  sleep 0.5
done 2>&1 | yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated  &

Now, of course, it's running with the preset global font & fontsize, yes? (I had to modify the window size a bit, anyway, 'cos I run with a slightly larger global font; the old peepers aren't as good as they once were!) Lifting this from Smokey's YAD guide, I'd like to change things a bit with

Code: Select all

--fontname="Exo 2 Bold Italic 24"

....but I can't for the life of me figure out where you insert this to change the font? I can see you perform your calculation first, then pipe the output into an undecorated YAD window. Fair enough, I understand that. The bit I haven't yet got my head round is that I've often found certain commands must go in very specific locations in the "chain".....and some of them don't even work unless others are present, yes?

I guess I just haven't used it enough, I suspect. (Things aren't yet "second nature", y'know? :roll:) And Grant's example doesn't make it that clear..... (*sigh*)

Mike. ;)


Re: Simple Clock

Posted: Mon Jun 13, 2022 9:43 pm
by fredx181
mikewalsh wrote:

Can I pick your brains, Fred?

That wee script works a treat. I've modified it slightly, to go in a specific place on the desktop:-
....

Hey Mike, I'll come back to that later, don't know atm, bit late already here, not sure if --fontname works with the --form option of yad, my guess is not.

@masinick You're welcome and.. :welcome: to the forum !


Re: Simple Clock

Posted: Mon Jun 13, 2022 9:49 pm
by mikewalsh
fredx181 wrote: Mon Jun 13, 2022 9:43 pm
mikewalsh wrote:

Can I pick your brains, Fred?

That wee script works a treat. I've modified it slightly, to go in a specific place on the desktop:-
....

Hey Mike, I'll come back to that later, don't know atm, bit late already here, not sure if --fontname works with the --form option of yad, my guess is not.

No worries, mate. As & when, as & when.....more curiosity than anything else at present. In your own time....

Mike. ;)


Re: Simple Clock

Posted: Mon Jun 13, 2022 11:43 pm
by williams2

I use this in my Firefox start script.

Code: Select all

yaf-splash -close never -fontsize 26 -bg cyan4 -text 'Firefox starting ...' -timeout 5 &>/dev/null & disown

Re: Simple Clock

Posted: Tue Jun 14, 2022 9:21 am
by fredx181

Hey Mike, I'll come back to that later, don't know atm, bit late already here, not sure if --fontname works with the --form option of yad, my guess is not.

Seems that --fontname doesn't combine with --form --field, only way to set font and colors in this case AFAIK is with a gtkrc config file (only for gtk2, so won't work with yad compiled with gtk3)

Code: Select all

# Set font and colors, comment, uncomment or modify as preferred
FONTNAME="Ticking Timebomb BB 30"
#FONTNAME="Exo 2 Bold Italic 24"
#FONTNAME="Sans Bold 20"
FCOL=yellow
BCOL=grey30
#FCOL=blue
#BCOL=yellow

# create gtkrc
echo "style \"y_clock\" { font_name=\"$FONTNAME\"
base[NORMAL]=\"$BCOL\" 
text[NORMAL]=\"$FCOL\" }
widget \"*\" style \"y_clock\"
" > /tmp/gtkrc_yclock

while :
do
  date +"%a %d %b %H:%M %S"
  sleep 0.5
done 2>&1 | GTK2_RC_FILES=/tmp/gtkrc_yclock yad --title=clock --geometry=330x0+420+16 --form --cycle-read --field=": " --no-buttons --undecorated --gtk-module=gtk2desklet &
2022-06-14_11-09-14.gif
2022-06-14_11-09-14.gif (63.27 KiB) Viewed 2573 times

If gtk2desklet is installed, the borders will become transparent, remove --gtk-module=gtk2desklet from the code if not desired.
Here's the Ticking Timebomb font attached (remove fake .gz and place in ~/.local/share/fonts (if not exist, create it) or in /usr/share/fonts .

TickingTimebombBB.ttf.gz
Remove fake .gz
(30.51 KiB) Downloaded 68 times

Re: Simple Clock

Posted: Tue Jun 14, 2022 11:51 am
by mikewalsh

@fredx181 :-

Yah, that works nicely. Now; here's a poser....

How do you kill the process manually? I've saved all the above as a script named "time.sh", OK? Trying all the usual suspects - killall, kill, pkill, xkill, etc - on the script, nothing works.

Under the 'Processes' tab of Mate-System-Monitor - this is what I normally use to kill reluctant processes - it simply shows up as a running YAD process. Highlighting the process, then clicking the 'End Process' button, it quits beautifully. BUT; the actual process doesn't appear to show up anywhere..?

I know it probably wouldn't bother most folks, who would want it showing all the time.....but when it comes to desktop widgets, although I'm happy for them to auto-start and run till shutdown, I still like to have a manual 'override'. This is what I've done with all the wee GIFs I have running on the desktop - 3, at present - and 'killall' works nicely to shut these down. But the same process doesn't work with this......and I can't actually find the running process anywhere in the file-system. Not even in /tmp.

Any suggestions? Ideas?

(EDIT:- I thought the following might work, but.....no dice...

Code: Select all

killall 'yad --title=clock --geometry=330x0+420+16 --form --cycle-read --field=": "  --no-buttons --undecorated --gtk-module=gtk2desklet &'

What d'you reckon? I'm probably approaching this from the wrong angle...)

Mike. :?


Re: Simple Clock

Posted: Tue Jun 14, 2022 12:14 pm
by stemsee
clock.png
clock.png (14.17 KiB) Viewed 2255 times

Here's an idea which will let you add background colours and fonts and text colours, still using yad. yad --text-info lets you specify font size and color and background colour too.

UPDATED to use yad --text-info with pango markup available.

Code: Select all

#!/bin/sh

#!/bin/sh

mkfifo /tmp/clock
exec 8<> /tmp/clock
yad --text-info --fontname="Sans Bold Italic 20" --no-buttons --back=black --fore=red --skip-tray --width=200 --height=72 --undecorated --no-headers --listen <& 8 &
while sleep 1
do
TIME="$(date +%X)"

echo -e '\f' >/tmp/clock
printf "%s\n" "$TIME" >/tmp/clock
done

Re: Simple Clock

Posted: Tue Jun 14, 2022 12:56 pm
by fredx181

@mikewalsh
Yeah Mike, you are right, difficult to kill, I'm not sure, but I think that the time.sh process is already gone after running it and the while loop process stays .
I found that this should work to kill the yad process, but perhaps there's a better solution.
pidyclock="$(pgrep -lf "yad --title=clock" | awk '{ print $1 }')"; kill $pidyclock
EDIT: Or simply: kill $(pgrep -lf "yad --title=clock" | awk '{ print $1 }')


Re: Simple Clock

Posted: Tue Jun 14, 2022 2:29 pm
by wiak

I think you could also run your clock script in a backgrounded shell job kind of construct like this:

Code: Select all

{ ./yourclock; } &

and probably:

Code: Select all

kill %1

kills the whole job off?

or you can pick up the pid after running it (using $!); no that doesn't work - you can kill the job off though


Re: Simple Clock

Posted: Tue Jun 14, 2022 5:26 pm
by mikewalsh
fredx181 wrote: Tue Jun 14, 2022 12:56 pm

@mikewalsh
Yeah Mike, you are right, difficult to kill, I'm not sure, but I think that the time.sh process is already gone after running it and the while loop process stays .
I found that this should work to kill the yad process, but perhaps there's a better solution.
pidyclock="$(pgrep -lf "yad --title=clock" | awk '{ print $1 }')"; kill $pidyclock
EDIT: Or simply: kill $(pgrep -lf "yad --title=clock" | awk '{ print $1 }')

Well, either works for me, Fred. So that gives me time.sh to start it.......and time-stop.sh to make it quit.

That'll do! :thumbup:

I have "hidden" manual controls for all my desktop GIFS/widgets...

[Click to enlarge:-]

Image

Mike. :D


Re: Simple Clock

Posted: Wed Jun 15, 2022 1:38 am
by misko_2083
fredx181 wrote: Tue Jun 14, 2022 12:56 pm

difficult to kill

You guys... :lol:

Just made this:

Code: Select all

#include <stdio.h>
#include <time.h>
#include <gtk/gtk.h>

static gboolean
on_timeout (gpointer user_data)
{
  GtkLabel *label = GTK_LABEL (user_data);
  time_t timer;
  char buff[28];
  struct tm* tm_info;

  time (&timer);
  tm_info = localtime(&timer);

  strftime(buff, 28, "%a %b %d/%m/%Y %H:%M:%S", tm_info);

  gchar *markup = g_strdup_printf ("<b><span font='Sans Bold 20' foreground='red'>%s</span></b>", buff); 
  gtk_label_set_markup (GTK_LABEL (label), markup);

  g_free (markup);

  return G_SOURCE_CONTINUE;
}

void destroy_handler (GtkApplication* app, gpointer data)
{
    g_application_quit(G_APPLICATION (data));
}

static gboolean
key_handler (GtkWidget *w, GdkEventKey *ev, gpointer data)
{
  GtkApplication *app = GTK_APPLICATION (data);
  switch (ev->keyval)
    {
    case GDK_KEY_Escape:
        destroy_handler(NULL, app);
        return TRUE;
    }
  return FALSE;
}

static gboolean
button_handler (GtkWidget *w, GdkEventButton *ev, gpointer data)
{
  if (ev->button == 1)
    {
      gtk_window_begin_move_drag(GTK_WINDOW(w),
          ev->button,
          ev->x_root,
          ev->y_root,
          ev->time);
      return TRUE;
    }
  if (ev->button == 3)
    {
      GtkApplication *app = GTK_APPLICATION (data);
      GtkWidget *item, *popup_menu;

      popup_menu = gtk_menu_new ();
      gtk_menu_set_reserve_toggle_size (GTK_MENU (popup_menu), FALSE);
      item = gtk_menu_item_new_with_label ("Exit");
      gtk_widget_show (item);
      gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
      g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (destroy_handler), app);
      gtk_menu_popup_at_pointer (GTK_MENU (popup_menu), NULL);
      return TRUE;
    }
  return FALSE;
}

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget           *window;
  GtkWidget           *grid;
  GtkWidget           *label;
  GtkStyleProvider    *style_provider;
  char                *css_text;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Simple Clock");
  gtk_window_set_default_size (GTK_WINDOW (window), 400, 60);
  gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
  gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);

  grid = gtk_grid_new ();
  gtk_grid_set_column_homogeneous (GTK_GRID (grid),
                                TRUE);
  gtk_grid_set_row_homogeneous (GTK_GRID (grid),
                                FALSE);
  gtk_grid_set_row_spacing (GTK_GRID (grid), 10);

  label = gtk_label_new(NULL);
  g_timeout_add (1000, on_timeout, label);

  gtk_widget_set_halign (label, GTK_ALIGN_CENTER);

  gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);

  gtk_container_add (GTK_CONTAINER (window), grid);
  gtk_container_set_border_width (GTK_CONTAINER(window),10);

  style_provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
  gtk_style_context_add_provider (gtk_widget_get_style_context (window),
                                  style_provider,
                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

  css_text = g_strdup_printf ("window,\n"
                              "window\n"
                              "{\n"
                              "  background: black;\n"
                              "}\n");

  gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (style_provider),
                                   css_text, -1, NULL);
  g_free (css_text);

  g_signal_connect (G_OBJECT(window), "destroy",
                    G_CALLBACK (destroy_handler), app);
  g_signal_connect (G_OBJECT (window), "key-press-event",
                    G_CALLBACK (key_handler), app);
  g_signal_connect (G_OBJECT (window), "button-press-event",
                    G_CALLBACK (button_handler), app);
  gtk_widget_show_all (window);
}

int
main (int argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.simple_time",
                             G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

Save as sclock.c
Fred you install libgtk-3-dev since you run debian.
Compile with:

Code: Select all

gcc sclock.c -o sclock $(pkg-config --cflags --libs gtk+-3.0)

run

Code: Select all

./sclock

I made it look the same as yad above red/black.
Plus left click can drag a window, right click opens a menu to exit.
Also Escape key when the window is in focus is used to exit app.

@mikewalsh Almost forgot, I set the skip_pager_hint so it doesn't show in a window list on alt+tab.

P.S. Used an app named peek to record this animated gif
Image

Oh I just noticed I used this date format dd/mm/YYYY.
I don't know about you guys, it comes naturally for me to read day first, then month.


Re: Simple Clock

Posted: Wed Jun 15, 2022 3:25 am
by MochiMoppel
masinick wrote: Mon Jun 13, 2022 6:48 pm

I have a short Bash script that produces a simple clock in the top left corner of a bash shell window.

I changed the script to prettify the display and bring it closer to the following yad adaptations. Important is to get rid of the clear command because it creates flicker.

Code: Select all

#!/bin/sh
urxvt -title ConsoleClock -font 9x15B +scrollBar -bg yellow -underlineColor yellow -geometry 25x1 -e bash -c '
while : ; do
  echo -en $(date +"%b %d, %Y  %r")" \r"
  sleep 1
done'
consoleclock.png
consoleclock.png (1.67 KiB) Viewed 2116 times

However if I understand your post correctly, a simple clock is not your objective. This is what you already have and can produce with your modification of yalarm. What you really want is to use/fix/change the alarm function of that script, right? If so it would be nice if you could post the yalarm script and clarify what functionality the "simple clock" eventually should have.

mikewalsh wrote: Tue Jun 14, 2022 11:51 am

How do you kill the process manually? I've saved all the above as a script named "time.sh", OK? Trying all the usual suspects - killall, kill, pkill, xkill, etc - on the script, nothing works.

Click on the window and then press Esc key or Alt+F4
or close the "clock" tab in the tray.

But that solves only part of the problem.

fredx181 wrote: Tue Jun 14, 2022 12:56 pm

I found that this should work to kill the yad process, but perhaps there's a better solution.
pidyclock="$(pgrep -lf "yad --title=clock" | awk '{ print $1 }')"; kill $pidyclock
EDIT: Or simply: kill $(pgrep -lf "yad --title=clock" | awk '{ print $1 }')

Or simpler (they all do the same thing):
kill $(pgrep -f "yad --title=clock")
pkill -f "yad --title=clock"
pkill -f title=clock <= not exactly the same but should be sufficient

Now here is the problem: This kills yad and its window, but it doesn't kill time.sh
After three times of starting time.sh and killing yad, 6 processes of the script are still running:

Code: Select all

# pgrep -f time.sh    
17639
17640
17752
17753
17893
17894

Killing all processes when closing the window (via Alt+F4 or tray) is tricky. The most convenient way I can think of is using the trap command (I took the liberty to remove the counterproductive 2>&1 redirection and changed sleep to 1 sec)

Code: Select all

#!/bin/sh
while :
do
  date +"%a %d %b %H:%M %S"
  sleep 1
done  | { trap "pkill -f $0" EXIT ; yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated  ;}

[EDIT]: No, doesn't need trap, can be done after yad closed or killed:

Code: Select all

done  | { yad --title="clock" --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated ; pkill -f "$0"  ;}

Re: Simple Clock

Posted: Wed Jun 15, 2022 5:59 pm
by misko_2083

On the other hand there is no need for background. The window is now transparent.
Added some options to set the color of the text, date format, font.

Code: Select all

Usage:
  sclock [OPTION?]

Help Options:
  -h, --help        Show help options

Application Options:
  --color=COLOR     Specify color to use
  --date=STRING     Specify display time, not 'now
  --font=FONT       Specify font to use

Also set GdkWindowHints to prevent resizing.
It resized and maximized window if dragged to the screen edge on Xfwm4, probably with other window managers too.
If wrong options are set it defaults to

Code: Select all

    color = "red";
    date = "%a %b %d/%m/%Y %H:%M:%S";
    font = "Sans Bold 20";

Compiles with the same command:

Code: Select all

gcc sclock.c -o sclock $(pkg-config --cflags --libs gtk+-3.0)

sclock.c

Code: Select all

#include <stdio.h>
#include <time.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <pango/pango.h>

static gchar *date = NULL;
static gchar *font = NULL;
static gchar *color = NULL;

static gboolean
on_timeout (gpointer user_data)
{
  GtkLabel *label = GTK_LABEL (user_data);
  GError *error = NULL;
  char *out = NULL;

  time_t timer;
  char buff[28];
  struct tm* tm_info;

  time (&timer);
  tm_info = localtime(&timer);
  strftime(buff, 28, date, tm_info);

  gchar *markup = g_strdup_printf ("<b><span font='%s' foreground='%s'>%s</span></b>",
                                   font, color, buff);

  if (pango_parse_markup (markup,
                         -1,
                          0,
                          NULL,
                          &out,
                          NULL,
                          &error) == FALSE)
  {
    fprintf (stderr, "%s\n", error->message);
    color = "red";
    date = "%a %b %d/%m/%Y %H:%M:%S";
    font = "Sans Bold 20";

    gchar *markup = g_strdup_printf ("<b><span font='%s' foreground='%s'>%s</span></b>",
                                     font, color, buff);

    if (out)
       free (out);
    g_error_free (error);
  }
  
  gtk_label_set_markup (GTK_LABEL (label), markup);

  g_free (markup);

  return G_SOURCE_CONTINUE;
}

void destroy_handler (GtkApplication* app, gpointer data)
{
    g_application_quit(G_APPLICATION (data));
}

static gboolean
key_handler (GtkWidget *w, GdkEventKey *ev, gpointer data)
{
  GtkApplication *app = GTK_APPLICATION (data);
  switch (ev->keyval)
    {
    case GDK_KEY_Escape:
        destroy_handler(NULL, app);
        return TRUE;
    }
  return FALSE;
}

static gboolean
button_handler (GtkWidget *w, GdkEventButton *ev, gpointer data)
{
  if (ev->button == 1)
    {
      gtk_window_begin_move_drag(GTK_WINDOW(w),
          ev->button,
          ev->x_root,
          ev->y_root,
          ev->time);
      return TRUE;
    }
  if (ev->button == 3)
    {
      GtkApplication *app = GTK_APPLICATION (data);
      GtkWidget *item, *popup_menu;

      popup_menu = gtk_menu_new ();
      gtk_menu_set_reserve_toggle_size (GTK_MENU (popup_menu), FALSE);
      item = gtk_menu_item_new_with_label ("Exit");
      gtk_widget_show (item);
      gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
      g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (destroy_handler), app);
      gtk_menu_popup_at_pointer (GTK_MENU (popup_menu), NULL);
      return TRUE;
    }
  return FALSE;
}

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget           *window;
  GtkWidget           *grid;
  GtkWidget           *label;
  GdkScreen           *screen;
  GdkVisual           *visual;
  GdkGeometry         hints;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Simple Clock");
  gtk_window_set_default_size (GTK_WINDOW (window), 10, 10);
  gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
  gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);

  gtk_widget_set_app_paintable (window, TRUE);
  screen = gdk_screen_get_default();
  visual = gdk_screen_get_rgba_visual(screen);

  if (visual != NULL && gdk_screen_is_composited(screen)) {
    gtk_widget_set_visual(window, visual);
  }

  grid = gtk_grid_new ();
  gtk_grid_set_column_homogeneous (GTK_GRID (grid),
                                TRUE);
  gtk_grid_set_row_homogeneous (GTK_GRID (grid),
                                FALSE);
  gtk_grid_set_row_spacing (GTK_GRID (grid), 10);

  label = gtk_label_new(NULL);
  g_timeout_add (1000, on_timeout, label);

  gtk_widget_set_halign (label, GTK_ALIGN_CENTER);

  gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);

  gtk_container_add (GTK_CONTAINER (window), grid);
  gtk_container_set_border_width (GTK_CONTAINER(window), 10);

  g_signal_connect (G_OBJECT(window), "destroy",
                    G_CALLBACK (destroy_handler), app);
  g_signal_connect (G_OBJECT (window), "key-press-event",
                    G_CALLBACK (key_handler), app);
  g_signal_connect (G_OBJECT (window), "button-press-event",
                    G_CALLBACK (button_handler), app);
  gtk_widget_show_all (window);

  hints.min_width = 0;
  hints.max_width = gtk_widget_get_allocated_width (window);
  hints.min_height = 0;
  hints.max_height = gtk_widget_get_allocated_height (window);

  gtk_window_set_geometry_hints(
        GTK_WINDOW(window),
        window,
        &hints,
        (GdkWindowHints)(GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE));
}

static int
get_options (int argc,
             char *argv[])
{
  static
    GOptionEntry option_entries[] = {
    { "color",        0, 0, G_OPTION_ARG_STRING,   &color,
       "Specify color to use", "COLOR" },
    { "date",        0, 0, G_OPTION_ARG_STRING,   &date,
       "Specify display time, not 'now", "STRING" },
    { "font",        0, 0, G_OPTION_ARG_STRING,   &font,
       "Specify font to use", "FONT" },
    { NULL }
  };
              
  GOptionContext *option_context;

  GError *error = NULL;

#if (!GLIB_CHECK_VERSION (2, 36, 0))
  g_type_init ();
#endif

  option_context = g_option_context_new (NULL);
  g_option_context_add_main_entries (option_context,
                                     option_entries,
                                     NULL);
  if (g_option_context_parse (option_context,
                              &argc,
                              &argv,
                              &error) == FALSE) {
    fprintf (stderr, "%s\n", error->message);
    return 1;
  }

  if (color == NULL)
      color = "red";
  if (date == NULL)
      date = "%a %b %d/%m/%Y %H:%M:%S";
  if (font == NULL)
      font = "Sans Bold 20";

  g_option_context_free (option_context);

  return 0;
}

int
main (int argc,
      char **argv)
{
  int status;
  GtkApplication *app;
  gboolean opts;

  opts = get_options (argc, argv);
  if (opts == 1)
     return 1;

  app = gtk_application_new ("org.gtk.simple_clock",
                             G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

Animated gif made with peek app:
Image
Options used for the gif: --color="#fcfcfc" --font="Noto Sans 30" --date="Year %Y: %H:%M:%S"


Re: Simple Clock

Posted: Wed Jun 15, 2022 6:07 pm
by misko_2083
MochiMoppel wrote: Wed Jun 15, 2022 3:25 am

Killing all processes when closing the window (via Alt+F4 or tray) is tricky. The most convenient way I can think of is using the trap command (I took the liberty to remove the counterproductive 2>&1 redirection and changed sleep to 1 sec)

Code: Select all

#!/bin/sh
while :
do
  date +"%a %d %b %H:%M %S"
  sleep 1
done  | { trap "pkill -f $0" EXIT ; yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated  ;}

[EDIT]: No, doesn't need trap, can be done after yad closed or killed:

Code: Select all

done  | { yad --title="clock" --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated ; pkill -f "$0"  ;}

Not sure but I think that was an old bug in yad version 0.40.1.
But Gustavo hasn't packaged any new versions for Debian since then. https://bugs.debian.org/cgi-bin/bugrepo ... bug=919785
And everyone is stuck with that. I know @step prefers Gtk2.
Yad was ported long ago to Gtk3 and right now at version 12.


Re: Simple Clock

Posted: Wed Jun 15, 2022 9:49 pm
by williams2

i sometimes use xclock

xclock.png
xclock.png (13.26 KiB) Viewed 2056 times

Re: Simple Clock

Posted: Thu Jun 16, 2022 1:38 am
by MochiMoppel
misko_2083 wrote: Wed Jun 15, 2022 6:07 pm

Not sure but I think that was an old bug in yad version 0.40.1.

I'm using version 0.36.2 and I wasn't sure if it's a bug at all or a general problem when using such pipe constructs (see here), but then I built a similar construct with Xdialog. Unlike yad this would not leave any processes hanging around when the clock window is closed. So yes, may be a yad bug (and no, using the yad option --kill-parent SIGTERM would not solve the problem. Would terminate the parent but would not stop the while..done subprocess)

Code: Select all

#!/bin/sh
while : ; do 
	echo  XXX 
	date +"%a %d %b %H:%M %S" 
	echo XXX 
	sleep 1 
done | Xdialog --no-buttons -infobox "" 250x30 0

Re: Simple Clock

Posted: Thu Jun 16, 2022 9:17 am
by misko_2083
MochiMoppel wrote: Thu Jun 16, 2022 1:38 am
misko_2083 wrote: Wed Jun 15, 2022 6:07 pm

Not sure but I think that was an old bug in yad version 0.40.1.

I'm using version 0.36.2 and I wasn't sure if it's a bug at all or a general problem when using such pipe constructs (see here), but then I built a similar construct with Xdialog. Unlike yad this would not leave any processes hanging around when the clock window is closed. So yes, may be a yad bug (and no, using the yad option --kill-parent SIGTERM would not solve the problem. Would terminate the parent but would not stop the while..done subprocess)

Date is the problem.
This works.

Code: Select all

    while : ; do
        date="$(date +"%a %d %b %H:%M %S")"
        echo "$date"
        sleep 1
    done | yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated

Re: Simple Clock

Posted: Fri Jun 17, 2022 2:08 am
by MochiMoppel
misko_2083 wrote: Thu Jun 16, 2022 9:17 am

Date is the problem.

Because date is an external command. All external commands piping to yad will cause this problem while Bash builtin commands like echo or printf are OK. Therefore this would also work (in bash 4.2 or newer) and would be more efficient:

Code: Select all

#!/bin/sh
while : ; do
	printf '%(%a %d %b %H:%M %S)T\n'
	sleep 1
done | yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated &

Re: Simple Clock

Posted: Fri Jun 17, 2022 10:10 am
by misko_2083
MochiMoppel wrote: Fri Jun 17, 2022 2:08 am
misko_2083 wrote: Thu Jun 16, 2022 9:17 am

Date is the problem.

Because date is an external command

Interesting, I'll have a look at the source code later.

MochiMoppel wrote: Fri Jun 17, 2022 2:08 am

would be more efficient:

Code: Select all

#!/bin/sh
while : ; do
	printf '%(%a %d %b %H:%M %S)T\n'
	sleep 1
done | yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated &

Indeed.


Re: Simple Clock

Posted: Mon Jun 20, 2022 4:41 pm
by masinick

I love all of these suggestions.
I found a solution and I have also been experimenting with simple clocks in several scripting languages and tools, including Bash, yad, TCL/Tk, pythons and Conky.

At this point I have several solutions and the comments are correct; there are many clocks available; this is for retirement coding practice so all comments are appreciated; thank you all!


Re: Simple Clock

Posted: Tue Jun 21, 2022 3:14 pm
by masinick

I hacked the C code, citing our talented coder misco_2083, and I offer back my modified hacks here for anyone interested:

Code: Select all

/* sclock.c */
/* Provided on https://forum.puppylinux.com/viewtopic.php?p=59787#p59787 */
/* by misco_2083 */
/* requires libgtk-3-dev on Debian, pulls in a lot of extra packages */
/* if you use it on antiX */
/* commented and adapted by Brian Masinick */

#include <stdio.h>
#include <time.h>
#include <gtk/gtk.h>

static gboolean
on_timeout (gpointer user_data)
{
  GtkLabel *label = GTK_LABEL (user_data);
  time_t timer;
  char buff[12];
  struct tm* tm_info;

  time (&timer);
  tm_info = localtime(&timer);

  strftime(buff, 12, "%r", tm_info);

  gchar *markup = g_strdup_printf ("<b><span font='Sans Bold 16' foreground='green'>%s</span></b>", buff); 
  gtk_label_set_markup (GTK_LABEL (label), markup);

  g_free (markup);

  return G_SOURCE_CONTINUE;
}

void destroy_handler (GtkApplication* app, gpointer data)
{
    g_application_quit(G_APPLICATION (data));
}

static gboolean
key_handler (GtkWidget *w, GdkEventKey *ev, gpointer data)
{
  GtkApplication *app = GTK_APPLICATION (data);
  switch (ev->keyval)
    {
    case GDK_KEY_Escape:
        destroy_handler(NULL, app);
        return TRUE;
    }
  return FALSE;
}

static gboolean
button_handler (GtkWidget *w, GdkEventButton *ev, gpointer data)
{
  if (ev->button == 1)
    {
      gtk_window_begin_move_drag(GTK_WINDOW(w),
          ev->button,
          ev->x_root,
          ev->y_root,
          ev->time);
      return TRUE;
    }
  if (ev->button == 3)
    {
      GtkApplication *app = GTK_APPLICATION (data);
      GtkWidget *item, *popup_menu;

      popup_menu = gtk_menu_new ();
      gtk_menu_set_reserve_toggle_size (GTK_MENU (popup_menu), FALSE);
      item = gtk_menu_item_new_with_label ("Exit");
      gtk_widget_show (item);
      gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
      g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (destroy_handler), app);
      gtk_menu_popup_at_pointer (GTK_MENU (popup_menu), NULL);
      return TRUE;
    }
  return FALSE;
}

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget           *window;
  GtkWidget           *grid;
  GtkWidget           *label;
  GtkStyleProvider    *style_provider;
  char                *css_text;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Digital Clock");
  gtk_window_set_default_size (GTK_WINDOW (window), 220, 20);
  gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
  gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);

  grid = gtk_grid_new ();
  gtk_grid_set_column_homogeneous (GTK_GRID (grid),
                                TRUE);
  gtk_grid_set_row_homogeneous (GTK_GRID (grid),
                                FALSE);
  gtk_grid_set_row_spacing (GTK_GRID (grid), 10);

  label = gtk_label_new(NULL);
  g_timeout_add (1000, on_timeout, label);

  gtk_widget_set_halign (label, GTK_ALIGN_CENTER);

  gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);

  gtk_container_add (GTK_CONTAINER (window), grid);
  gtk_container_set_border_width (GTK_CONTAINER(window),5);

  style_provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
  gtk_style_context_add_provider (gtk_widget_get_style_context (window),
                                  style_provider,
                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

  css_text = g_strdup_printf ("window,\n"
                              "window\n"
                              "{\n"
                              "  background: black;\n"
                              "}\n");

  gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (style_provider),
                                   css_text, -1, NULL);
  g_free (css_text);

  g_signal_connect (G_OBJECT(window), "destroy",
                    G_CALLBACK (destroy_handler), app);
  g_signal_connect (G_OBJECT (window), "key-press-event",
                    G_CALLBACK (key_handler), app);
  g_signal_connect (G_OBJECT (window), "button-press-event",
                    G_CALLBACK (button_handler), app);
  gtk_widget_show_all (window);
}

int
main (int argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.simple_time",
                             G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

 

Re: Simple Clock

Posted: Tue Jun 21, 2022 7:56 pm
by rockedge

@masinick Wow! That works great and really fits the look of this desktop

Screenshot(15).jpg
Screenshot(15).jpg (41.45 KiB) Viewed 2270 times

Re: Simple Clock

Posted: Tue Jun 21, 2022 9:22 pm
by masinick

Glad you like it! Without the coding expertise and helpful notes from misco_2083 that never would have happened.

We have several other really nice, simple examples too. Thanks to everyone who responded. This has been an educational and fun exercise!


Re: Simple Clock

Posted: Thu Jun 23, 2022 9:38 am
by misko_2083
masinick wrote: Tue Jun 21, 2022 9:22 pm

misco_2083

That guy has a similar username. :D

I've added a some options.
Bacground and border is drawn with cairo. see in help ($ ./sclock --help)
Colors can be in various formats x11 like, black, white, lime, then rgb(r,g,b), rgba(r,g,b,a), #FFFFFF .
--opacity between 0 and 100
--lock prevents moving on left click drag.
Although it's still possible to use Alt_L+L_click drag.
There is a right click menu item to lock/unlock.
--posx --posy and --center to set the initial position
--keep-above to place it on top of window stack, default is to place it bellow all the windows now.
Keep above t may be useful for displaying the clock with timeout.

Code: Select all

timeout 5 ./sclock --keep-above

Code: Select all

#include <time.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <glib.h>
#include <pango/pango.h>
#include <cairo/cairo.h>

GdkRGBA color_bg;
GdkRGBA color_border;
static gchar *bgcolor = NULL;
static gchar *border_color = NULL;
static gchar *color = NULL;
static gchar *date = NULL;
static gchar *font = NULL;
static gboolean above = FALSE;
static gint border;
static gboolean center = FALSE;
static gboolean lock = FALSE;
static gint opacity;
static gint  posx = 0;
static gint  posy = 0;

static gboolean
on_timeout (gpointer user_data)
{
  GtkLabel *label = GTK_LABEL (user_data);
  GError *error = NULL;
  char *out = NULL;

  time_t timer;
  char buff[64];
  struct tm* tm_info;

  time (&timer);
  tm_info = localtime (&timer);
  strftime (buff, 64, date, tm_info);

  gchar *markup = g_strdup_printf ("<b><span font='%s' foreground='%s'>%s</span></b>",
                                   font, color, buff);
  if (pango_parse_markup (markup,
                         -1,
                          0,
                          NULL,
                          &out,
                          NULL,
                          &error) == FALSE)
  {
    g_printerr ("%s\nSwitching to default values\n", error->message);
    color = "red";
    date = "%r";
    font = "Sans Bold 20";

    gchar *markup = g_strdup_printf ("<span font='%s' foreground='%s'>%s</span>",
                                     font, color, buff);

    if (out)
       free (out);
    g_error_free (error);
  }
  
  gtk_label_set_markup (GTK_LABEL (label), markup);

  g_free (markup);

  return G_SOURCE_CONTINUE;
}

void destroy_handler (GtkApplication* app, gpointer data)
{
  g_application_quit(G_APPLICATION (data));
}

static void
toggle_lock_position (GtkWidget *menu_item, gpointer user_data)
{
  if (lock == TRUE)
      lock = FALSE;
  else
      lock = TRUE;
}

static gboolean
key_handler (GtkWidget *w, GdkEventKey *ev, gpointer data)
{
  GtkApplication *app = GTK_APPLICATION (data);
  switch (ev->keyval)
    {
    case GDK_KEY_Escape:
        destroy_handler(NULL, app);
        return TRUE;
    }
  return FALSE;
}

static gboolean
button_handler (GtkWidget *window, GdkEventButton *ev, gpointer data)
{
  if ((ev->button == 1) && (lock == FALSE))
    {
      gtk_window_begin_move_drag (GTK_WINDOW(window),
          ev->button,
          ev->x_root,
          ev->y_root,
          ev->time);
      return TRUE;
    }
  if (ev->button == 3)
    {
      GtkApplication *app = GTK_APPLICATION (data);
      GtkWidget *toggle_lock, *exit, *popup_menu;

      popup_menu = gtk_menu_new ();
      gtk_menu_set_reserve_toggle_size (GTK_MENU (popup_menu), FALSE);
      if (lock == TRUE)
          toggle_lock = gtk_menu_item_new_with_label ("Unlock");
      else
          toggle_lock = gtk_menu_item_new_with_label ("Lock");
      gtk_widget_show (toggle_lock);
      exit = gtk_menu_item_new_with_label ("Exit");
      gtk_widget_show (exit);
      gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), toggle_lock);
      gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), exit);
      g_signal_connect (G_OBJECT (toggle_lock), "activate", G_CALLBACK (toggle_lock_position), NULL);
      g_signal_connect (G_OBJECT (exit), "activate", G_CALLBACK (destroy_handler), app);
      gtk_menu_popup_at_pointer (GTK_MENU (popup_menu), NULL);
      return TRUE;
    }
  return FALSE;
}

static void
geometry_hints (GtkWidget *widget,
                    gpointer data)
{
  GdkGeometry         hints;

  hints.min_width = 0;
  hints.max_width = gtk_widget_get_allocated_width (widget);
  hints.min_height = 0;
  hints.max_height = gtk_widget_get_allocated_height (widget);

  gtk_window_set_geometry_hints(
        GTK_WINDOW (widget),
        widget,
        &hints,
        (GdkWindowHints)(GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE));
}

static void
draw_handler (GtkWidget *widget,
              cairo_t *cr,
              gpointer user_data)
{
  float alpha;
  float alpha_border;
  if (opacity) {
      alpha = alpha_border = (float) opacity / 100;
  }
  else {
      alpha = color_bg.alpha;
      alpha_border = color_border.alpha;
  }
  
  cairo_set_source_rgba (cr, color_bg.red, color_bg.green, color_bg.blue,  alpha);
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); 
  cairo_paint(cr);

  if (border) {
     if (border_color == NULL) {
         cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.7);
     }
     else {
         cairo_set_source_rgba (cr, color_border.red, color_border.green, color_border.blue,  alpha_border);
      }
      cairo_rectangle(cr, border / 2, border / 2, gtk_widget_get_allocated_width (widget) - border,
                                                gtk_widget_get_allocated_height (widget) - border);
      cairo_set_line_width(cr, border);
      cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); 
      cairo_stroke(cr); 
  }
}

static void
composited_changed (
  GtkWidget *widget,
  gpointer user_data)
{
  GdkScreen           *screen;
  GdkVisual           *visual;

  screen = gdk_screen_get_default();
  visual = gdk_screen_get_rgba_visual(screen);
  if (visual != NULL && gdk_screen_is_composited(screen))
      gtk_widget_set_visual(widget, visual);
}

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget           *window;
  GtkWidget           *grid;
  GtkWidget           *label;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Simple Clock");
  gtk_window_set_default_size (GTK_WINDOW (window), 10, 10);
  gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
  gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
  gtk_widget_set_app_paintable (window, TRUE);
  composited_changed (window, NULL);
  if (center == TRUE)
      gtk_window_set_position(GTK_WINDOW(window),
                              GTK_WIN_POS_CENTER_ALWAYS);
  if (above == TRUE) {
      gtk_window_set_keep_above (GTK_WINDOW(window), TRUE);
  }
  else {
      gtk_window_set_keep_below (GTK_WINDOW(window), TRUE);
  }

  grid = gtk_grid_new ();
  gtk_grid_set_column_homogeneous (GTK_GRID (grid),
                                TRUE);
  gtk_grid_set_row_homogeneous (GTK_GRID (grid),
                                FALSE);
  gtk_grid_set_row_spacing (GTK_GRID (grid), 10);

  label = gtk_label_new (NULL);
  g_timeout_add (1000, on_timeout, label);
  gtk_widget_set_halign (label, GTK_ALIGN_CENTER);

  gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
  gtk_container_add (GTK_CONTAINER (window), grid);
  gtk_container_set_border_width (GTK_CONTAINER (window), 8);

  g_signal_connect (G_OBJECT(window), "destroy",
                    G_CALLBACK (destroy_handler), app);
  g_signal_connect (G_OBJECT (window), "key-press-event",
                    G_CALLBACK (key_handler), app);
  g_signal_connect (G_OBJECT (window), "button-press-event",
                    G_CALLBACK (button_handler), app);
  g_signal_connect (G_OBJECT (window), "size-allocate",
                    G_CALLBACK (geometry_hints), NULL);
  g_signal_connect (G_OBJECT (window), "draw",
                    G_CALLBACK (draw_handler), NULL);
  g_signal_connect (G_OBJECT (window), "draw",
                    G_CALLBACK (draw_handler), NULL);
  g_signal_connect (G_OBJECT (window), "composited-changed",
                    G_CALLBACK (composited_changed), NULL);
  gtk_widget_show_all (window);

  if ((posx != 0) || (posy != 0))
     gtk_window_move (GTK_WINDOW (window), posx, posy);
}

static int
get_options (int argc,
             char *argv[])
{
  static
    GOptionEntry option_entries[] = {
    { "bgcolor",       0, 0, G_OPTION_ARG_STRING,  &bgcolor,
       "Specify window background color, black, #000, rgb(r,g,b), rgba(r,g,b,a)", "COLOR" },
    { "border",  0, 0, G_OPTION_ARG_INT,   &border,
       "Draw window border, same as bgcolor", "COLOR" },
    { "border-color",  0, 0, G_OPTION_ARG_STRING,   &border_color,
       "Set border color", "COLOR" },
    { "center",  0, 0, G_OPTION_ARG_NONE,   &center,
       "Place window at the center of the screen", NULL },
    { "color",       0, 0, G_OPTION_ARG_STRING,  &color,
       "Specify color of the label, white, #FFFFFF", "COLOR" },
    { "date",        0, 0, G_OPTION_ARG_STRING,  &date,
       "Specify display time, e.g. %a %b %d/%m/%Y %H:%M:%S but not 'now", "STRING" },
    { "font",        0, 0, G_OPTION_ARG_STRING,  &font,
       "Specify font to use", "FONT" },
    { "keep-above",  0, 0, G_OPTION_ARG_NONE,   &above,
       "Keep window above, default is to keep window below", NULL },
    { "lock",  0, 0, G_OPTION_ARG_NONE,   &lock,
       "Lock position", NULL },
    { "opacity",  0, 0, G_OPTION_ARG_INT,   &opacity,
       "Set window opacity, compositing must be enabled first", NULL },
    { "posx",        0, 0, G_OPTION_ARG_INT,    &posx,
       "Specify X position to use", "INT" },
    { "posy",        0, 0, G_OPTION_ARG_INT,   &posy,
       "Specify Y position to use", "INT" },
    { NULL }
  };
              
  GOptionContext *option_context;
  GError *error = NULL;

#if (!GLIB_CHECK_VERSION (2, 36, 0))
  g_type_init ();
#endif

  option_context = g_option_context_new (NULL);
  g_option_context_add_main_entries (option_context,
                                     option_entries,
                                     NULL);
  if (g_option_context_parse (option_context,
                              &argc,
                              &argv,
                              &error) == FALSE) {
    g_printerr ("%s\n", error->message);
    g_error_free (error);
    return 1;
  }
  if (bgcolor != NULL) {
     if (gdk_rgba_parse (&color_bg, bgcolor) == FALSE) {
         g_printerr ("Unknown color: %s\n", bgcolor);
         return 1;
     }
  }
  if (border_color != NULL) {
      if (gdk_rgba_parse (&color_border, border_color) == FALSE) {
          g_printerr ("Unknown color: %s\n", border_color);
          return 1;
      }
  }
  if (opacity < 0 || opacity > 100) {
      g_printerr ("Opacity must be between 0 and 100: %d\n", opacity);
      return 1;
  }
  if (color == NULL)
      color = "red";
  if (date == NULL)
      date = "%r";
  if (font == NULL)
      font = "Sans Bold 20";
  g_option_context_free (option_context);

  return 0;
}

int
main (int argc,
      char **argv)
{
  int status;
  GtkApplication *app;
  gboolean opts;

  opts = get_options (argc, argv);

  if (opts == 1)
     return 1;

  app = gtk_application_new ("org.gtk.simple_clock",
                             G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

If we resize the buffer it would be possible to use several colors and font sizes with pango markup.

Code: Select all

# in terminal
_date="%a, %b %d, %Y
<span color='#cfcfcf'>%r</span>"
./sclock--keep-above --date="${_date}" --border=2 --border-color=blue --bgcolor=grey

Which currently gives

sclock.png
sclock.png (6.01 KiB) Viewed 2252 times

EDIT:
Just had an idea to place it next to the xfce4-panel.
xdotool helps to find the position (Y and Y).


Re: Simple Clock

Posted: Thu Jun 23, 2022 7:21 pm
by rockedge

can I include sclock in KLV's? Include it as feature.

Compiled in KLV-Airedale (install gtk+-devel)
Started with : sclock --color=orange in a .desktop file
Could use a shell script to set options and start or modify the .desktop file itself.
Should probably just make a sclock-config GUI for fun

Screenshot_2022-06-23_15-13-37.jpg
Screenshot_2022-06-23_15-13-37.jpg (56.95 KiB) Viewed 2189 times
Screenshot_2022-06-23_15-29-42.jpg
Screenshot_2022-06-23_15-29-42.jpg (64.33 KiB) Viewed 2188 times