Log In  


Welcome to my first post!
I present to you the

Popup Notifications!

Cart #popup_demo-1 | 2024-06-02 | Embed ▽ | License: CC4-BY-NC-SA
2

But as you can probably see, it sadly does not work out-of-the-box.
The problem is such Picotron (AFAIK) doesn't have any way to draw a window which would be visible on all workspaces.
So I had to slightly edit original Window Manager and add such an option.

Furthermore - changes made to /system folder are only temporary by default, so I had to bypass it as well.
I don't know if this is a well known thing, but you can just copy the /system folder to a different location (cp /system /tmp), delete original /system and rename previously copied directory to /system. Then it will be a real folder, not stored in RAM.

For anyone wondering here is my edited wm.lua file.


Installation

I've made an installer (yes, really) to automate a whole process.
It is stored inside of a cartridge. Just go inside of /ram/cart and run install_popup.p64
(Actually there are a separate installers for popup and permament /system, so you can just take it out of the cartridge and use anywhere else :) )

JUST MAKE A BACKUP OF A WHOLE DRIVE JUST IN CASE.
Nothing should go wrong, but you know...
Then you will have everything installed. You just have to reboot to load a new wm.lua


Popup Daemon

Inside /appdata/popup is a daemon (already automatically launched) and a library to communicate with the daemon.
Just include it in your scripts and you are good to go. You can check how to use it by seeing how Popup Demo works.


Library Reference

The best solution is to just copy the library located in /appdata/popup/lib/ to your cart and use it from here, so it would always be available. When daemon is not found on a system the library will use notify() as a fallback.

I've tried to make it as customizable as possible, so there are some nasty quirks that we have to speak about.

Popup is defined by a table with 4 functions:

  • init
  • draw
  • get_height
  • to_delete

(I will speak about separately them later)
But these functions have to be passed AS STRING. In fact, everything inside of the popup table must be a string.
It is because a communication using send_message prohibits sending functions (it erases them).

But in the daemon they are converted to their non-string form:

  • "123" would be a number 123
  • "true" would be a boolean true
  • "function() end" would be a function
  • "\"Hello!\"" would be a string "Hello!"

The next thing is, you can't pass references. So the only possible communication with your script would be by using send_message etc.

Example popup (that won't crash the daemon :>) would look like this

{
  init = "function() end",
  draw = "function() end",
  get_height = "function() return 0 end",
  to_delete = "function() return false end",
  some_passed_value = "10",
  another_value = "false"
}

There is also a mechanism to help popups to not cover each other.
Each popup must declare it's height (may be 0) and receives next available height on the screen where it can be drawn.

Functions

init

init(self, starting_y)
Runs right after sending the popup to the daemon.

  • starting_y - height where popup can be drawn, so it wouldn't cover any other popup.

draw

draw(self)
Runs every frame.
You can just use any drawing function inside on a 480x270 window and it will work.

get_height

get_height(self)
Runs right after init.
Must return a number indicating it's own height, so other popups would know where to start to draw.

to_delete

to_delete(self)
Runs every frame, after draw.
Must return a boolean.
When the return value is true, the popup will be destroyed.
WARNING! - The popup MUST NOT BE VISIBLE while being destroyed, because it will be stuck on a screen.

Simpler creating of a popup

There is a popup.new({}) function that will generate a very simple (and ugly) popup. The argument to this function can be used to override any option inside of a popup.

Behavior of a default popup:

  • The height is always 16
  • text stores a text to show
  • duration says after how many frames the popup should start to disappear
  • terget_dx is a width of a popup
  • background_color says which color should be used as a background of a popup

Example use of a default popup:

popup.new({
text = "\"You have a new message!\"",
target_dx = "200"
})

But you can edit every function as well as you like.

Demo contains a simple, default popup (no changes), slightly changed default popup (to show how to do it), 100% custom popup with custom graphics, animations etc. AND FIREWORKS WOOHOOO (also as popups cuz why not).


But why?

Idk, for funsies. I think it would be nice to have such popup notifications inside of a picotron but installation process is a bit too much.

2


If anything that I wrote here is beyond understanding just let me know and I will try to write it better or something


Version 1.1

  • increased stability
    Badly-written popups shouldn't crash the daemon now.

  • added fallback
    When there is no daemon running on a system, the library fallbacks to using notify().
    Text is taken from a text property of a popup.

Looks cool, but it crashes if I press x :(


can the notifications follow the current desktop theme? 🤩

could you add border and rounded corners like main windows have?


@cheesemug
Like I said, you have to install my daemon for it to work. The installer is available inside of a cartridge.

It changes wm.lua inside of /system/wm and adds a line to the /appdata/system/startup.lua so the daemon would run every time you boot up.

I think it's more of a "proof of concept" than real solution because you shouldn't really change what the OS is doing unless you know what exactly what is going on (when multiple programs need to edit some files in OS then both changes can be hard to merge properly)

@merwok
Yes they can.
The notifications are just normal "separate" programs that run in background. You can write in them whatever you want.

Just keep in mind that every notification runs inside of a daemon (maybe I should put them all on separate processes?) so be careful with using functions with lasting effects (like camera() or pal())

I don't know by heart how colors work in Picotron and what pallette window manager uses but iirc it already has current desktop theme loaded?


the cart labels have notifications using black, red, blue, not the theme colours we can see in the rest of the screenshot :)



[Please log in to post a comment]