2023-08-01 18:06:35 +02:00
// SPDX-License-Identifier: GPL-3.0-or-later
2023-06-22 01:58:49 +02:00
//! A very, VERY WIP Smithay-based Wayland compositor.
//!
//! Pinnacle is heavily inspired by the [Awesome Window Manager](https://awesomewm.org),
//! and this is an attempt to make something akin to it for Wayland.
//!
2023-06-22 02:08:29 +02:00
//! While Pinnacle is not a library, this documentation serves to guide those who want to
2023-06-22 01:58:49 +02:00
//! contribute or learn how building something like this works.
2024-01-22 06:42:48 +01:00
// #![deny(unused_imports)] // this has remained commented out for months lol
2023-06-30 00:41:08 +02:00
#![ warn(clippy::unwrap_used) ]
2023-06-29 19:29:00 +02:00
2023-09-08 07:21:09 +02:00
use clap ::Parser ;
2023-12-19 12:09:36 +01:00
use nix ::unistd ::Uid ;
2023-09-14 08:34:20 +02:00
use tracing_appender ::rolling ::Rotation ;
2023-09-11 09:48:33 +02:00
use tracing_subscriber ::{ fmt ::writer ::MakeWriterExt , EnvFilter } ;
use xdg ::BaseDirectories ;
2023-09-08 07:21:09 +02:00
2023-12-15 05:00:04 +01:00
mod api ;
2023-06-12 00:56:34 +02:00
mod backend ;
2023-09-20 22:27:51 +02:00
mod config ;
2023-06-12 00:56:34 +02:00
mod cursor ;
2023-06-18 04:02:58 +02:00
mod focus ;
2023-06-12 00:56:34 +02:00
mod grab ;
mod handlers ;
mod input ;
mod layout ;
2023-06-26 03:26:52 +02:00
mod output ;
2023-06-12 00:56:34 +02:00
mod render ;
mod state ;
2023-07-01 04:34:07 +02:00
mod tag ;
2023-06-12 00:56:34 +02:00
mod window ;
2023-09-11 09:48:33 +02:00
lazy_static ::lazy_static! {
pub static ref XDG_BASE_DIRS : BaseDirectories =
BaseDirectories ::with_prefix ( " pinnacle " ) . expect ( " couldn't create xdg BaseDirectories " ) ;
}
2023-09-08 07:21:09 +02:00
#[ derive(clap::Args, Debug) ]
2023-09-09 03:20:00 +02:00
#[ group(id = " backend " , required = false, multiple = false) ]
2023-09-08 07:21:09 +02:00
struct Backends {
#[ arg(long, group = " backend " ) ]
/// Run Pinnacle in a window in your graphical environment
winit : bool ,
#[ arg(long, group = " backend " ) ]
/// Run Pinnacle from a tty
udev : bool ,
}
#[ derive(clap::Parser, Debug) ]
#[ command(author, version, about, long_about = None) ]
struct Args {
#[ command(flatten) ]
backend : Backends ,
#[ arg(long) ]
/// Allow running Pinnacle as root (this is NOT recommended)
allow_root : bool ,
#[ arg(long, requires = " backend " ) ]
/// Force Pinnacle to run with the provided backend
force : bool ,
}
2024-01-08 20:43:38 +01:00
#[ tokio::main ]
2024-01-08 19:51:04 +01:00
async fn main ( ) -> anyhow ::Result < ( ) > {
2023-09-11 09:48:33 +02:00
let xdg_state_dir = XDG_BASE_DIRS . get_state_home ( ) ;
2023-09-14 08:34:20 +02:00
let appender = tracing_appender ::rolling ::Builder ::new ( )
. rotation ( Rotation ::HOURLY )
. filename_suffix ( " pinnacle.log " )
. max_log_files ( 8 )
. build ( xdg_state_dir )
. expect ( " failed to build file logger " ) ;
2023-09-11 09:48:33 +02:00
let ( appender , _guard ) = tracing_appender ::non_blocking ( appender ) ;
let writer = appender . and ( std ::io ::stdout ) ;
let env_filter = EnvFilter ::try_from_default_env ( ) . unwrap_or ( EnvFilter ::new ( " debug " ) ) ;
tracing_subscriber ::fmt ( )
. compact ( )
. with_env_filter ( env_filter )
. with_writer ( writer )
. init ( ) ;
2023-06-15 19:42:34 +02:00
2023-09-08 07:21:09 +02:00
let args = Args ::parse ( ) ;
2023-12-19 12:08:52 +01:00
if Uid ::effective ( ) . is_root ( ) & & ! args . allow_root {
2023-09-08 07:21:09 +02:00
println! ( " You are trying to run Pinnacle as root. \n This is NOT recommended. \n To run Pinnacle as root, pass in the --allow-root flag. Again, this is NOT recommended. " ) ;
return Ok ( ( ) ) ;
}
2023-08-08 20:25:47 +02:00
let in_graphical_env =
std ::env ::var ( " WAYLAND_DISPLAY " ) . is_ok ( ) | | std ::env ::var ( " DISPLAY " ) . is_ok ( ) ;
2023-09-08 07:21:09 +02:00
match ( args . backend . winit , args . backend . udev , args . force ) {
( false , false , _ ) = > {
if in_graphical_env {
tracing ::info! ( " Starting winit backend " ) ;
crate ::backend ::winit ::run_winit ( ) ? ;
} else {
tracing ::info! ( " Starting udev backend " ) ;
crate ::backend ::udev ::run_udev ( ) ? ;
}
}
( true , false , force ) = > {
2023-08-08 20:25:47 +02:00
if ! in_graphical_env {
2023-09-08 07:21:09 +02:00
if force {
tracing ::warn! ( " Starting winit backend with no detected graphical environment " ) ;
2023-08-08 20:25:47 +02:00
crate ::backend ::winit ::run_winit ( ) ? ;
} else {
2023-09-08 07:21:09 +02:00
println! ( " Both WAYLAND_DISPLAY and DISPLAY are not set. " ) ;
2023-08-08 20:25:47 +02:00
println! ( " If you are trying to run the winit backend in a tty, it won't work. " ) ;
println! ( " If you really want to, additionally pass in the --force flag. " ) ;
}
} else {
tracing ::info! ( " Starting winit backend " ) ;
crate ::backend ::winit ::run_winit ( ) ? ;
}
2023-06-19 20:27:54 +02:00
}
2023-09-08 07:21:09 +02:00
( false , true , force ) = > {
2023-08-08 20:25:47 +02:00
if in_graphical_env {
2023-09-08 07:21:09 +02:00
if force {
tracing ::warn! ( " Starting udev backend with a detected graphical environment " ) ;
2023-08-08 20:25:47 +02:00
crate ::backend ::udev ::run_udev ( ) ? ;
} else {
2023-09-08 07:21:09 +02:00
println! ( " WAYLAND_DISPLAY and/or DISPLAY are set. " ) ;
2023-08-08 20:25:47 +02:00
println! (
" If you are trying to run the udev backend in a graphical environment, "
) ;
println! ( " it won't work and may mess some things up. " ) ;
println! ( " If you really want to, additionally pass in the --force flag. " ) ;
}
} else {
tracing ::info! ( " Starting udev backend " ) ;
crate ::backend ::udev ::run_udev ( ) ? ;
}
2023-06-19 20:27:54 +02:00
}
2023-09-08 07:21:09 +02:00
_ = > unreachable! ( ) ,
2023-06-19 19:42:49 +02:00
}
2023-06-12 00:56:34 +02:00
Ok ( ( ) )
}