commit dd0280a1e5c66a5bee20aea8c8e4331bb506cbad Author: modeco80 Date: Thu Feb 1 04:06:07 2024 -0500 init diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..336112f --- /dev/null +++ b/.clang-format @@ -0,0 +1,43 @@ +BasedOnStyle: Google + +# force T* or T& +DerivePointerAlignment: false +PointerAlignment: Left + +TabWidth: 4 +IndentWidth: 4 +UseTab: Always +IndentPPDirectives: BeforeHash + +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true + +BinPackArguments: true +BinPackParameters: true +BreakConstructorInitializers: BeforeColon +BreakStringLiterals: false + +CompactNamespaces: false + +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ContinuationIndentWidth: 0 + +# turning this on causes major issues with initializer lists +Cpp11BracedListStyle: false +SpaceBeforeCpp11BracedList: true + +FixNamespaceComments: true + +NamespaceIndentation: All +ReflowComments: true + +SortIncludes: CaseInsensitive +SortUsingDeclarations: true + +SpacesInSquareBrackets: false +SpaceBeforeParens: Never +SpacesBeforeTrailingComments: 1 diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0b53eb8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +indent_style = tab +indent_size = 4 + +# specifically for YAML +[{yml, yaml}] +indent_style = space diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2313355 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build/ +cmake-build-*/ +/.idea +.cache/ +/compile_commands.json diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..56bedde --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2024 Lily Tsuru , The NanoSM authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0c9ce43 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# nanosm + +A nano-sized not-really-a session manager intended to replace less-than-robust Bash/etc scripts. + +Written in C++20. + +# Why write this? + +Because `app &` then `exec wm` is impressively awful. What if your WM crashes, or your panel? Guess you lose them! + +And if your WM crashes? Your whole xorg server goes with it, meaning so does everything else. + +A more robust solution that's still small and easy to setup is clearly a better idea. + +# Installation + +TODO + +# Configuration + +- Copy `/usr/share/doc/nanosm/nanosm.toml` to `~/.config/nanosm/` and edit it to your liking. +- Add `exec nanosm` to the end of your `.xinitrc`. diff --git a/doc/nanosm.toml b/doc/nanosm.toml new file mode 100644 index 0000000..a85ea12 --- /dev/null +++ b/doc/nanosm.toml @@ -0,0 +1,18 @@ +# The nanosm(1) configuration file. + +[nanosm] +# The window manager you want to use. This is the first application +# launched, and this will always be true +window-manager="/path/to/wm/binary --any-additional-args-here" + +# Enable verbose debug logging. Only useful for debugging issues. +verbose=false + +# Restart delay in seconds. +restart-delay=1 + +# Any applications besides your window manager you want to run at startup. +# Note that applications are executed in the order they are declared. +[nanosm.apps] +lxpanel = { command = "lxpanel" } +pcmanfm-desktop = { command = "pcmanfm --desktop" } diff --git a/src/EventLoop.hpp b/src/EventLoop.hpp new file mode 100644 index 0000000..4f2a1fd --- /dev/null +++ b/src/EventLoop.hpp @@ -0,0 +1,34 @@ +#include +#include + +namespace nanosm { + + /// The nanosm event loop. Pretty barren. + struct EventLoop { + + /// A pollable object. + struct Pollable { + virtual ~Pollable() = default; + + /// Returns the FD. May return nullopt if there is no active file descriptor + /// for this polled object (this simply means you won't get events until there is one) + virtual std::optional GetFD() const = 0; + + /// Called when the object is ready (do any i/o or handling here) + virtual void OnReady() = 0; + }; + + EventLoop(); + ~EventLoop(); + + /// Add an object to the epoll event loop. + void AddObject(int fd, std::shared_ptr obj); + + /// Runs the main loop. + void Run(); + + private: + int epollFd{}; + }; + +} diff --git a/src/design-noodling.txt b/src/design-noodling.txt new file mode 100644 index 0000000..089a9a2 --- /dev/null +++ b/src/design-noodling.txt @@ -0,0 +1,39 @@ +general + + +timer: + +nanosm::Timer : nanosm::EventLoop::Pollable + bool Set(... duration, ... callback); + // OnReady() will just call the timer callback + + +proesses: + +nanosm::Process : nanosm::EventLoop::Pollable + void Kill(); + bool Spawn(... exitCallback); + + static std::shared_ptr SpawnCmdLine(); + +nanosm::RestartingProcess final : Process + // spawn is shadowed by a version that exits callback to set timerfd-backed timer which on expiry/callback will be cancelled + // then spawn the process again (which will make it have a valid pidfd again etc etc + + std::shared_ptr timer; + +program mainn flow: + +main() + parse config (fail if it's bad) + create state (nanosm::NanoSm), from parsed config + create event loop + post callback into event loop to run state + run event loop + +nanosm::NanoSm::Run() + spawn wm (if this fails give up and exit early) + for each app (in toml order): + spawn app + + return (the event loop wil persist and keep everything alive until it needs to shutdown) diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..970d628 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,8 @@ +#include "EventLoop.hpp" + +int main(int argc, char** argv) { + nanosm::EventLoop ev; + + ev.Run(); + return 0; +}