Index: greetd/src/session/worker.rs
--- greetd/src/session/worker.rs.orig
+++ greetd/src/session/worker.rs
@@ -1,5 +1,13 @@
 use std::{env, ffi::CString, os::unix::net::UnixDatagram};
 
+use libc::{ c_int, c_char, uid_t, gid_t };
+#[link(name = "util")]
+extern "C" {
+    fn login_fbtab(tty: *const c_char, uid: uid_t, gid: gid_t) -> c_int;
+}
+
+use std::os::unix::fs;
+
 use nix::{
     sys::wait::waitpid,
     unistd::{execve, fork, initgroups, setgid, setsid, setuid, ForkResult},
@@ -163,6 +171,18 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
 
     let user = nix::unistd::User::from_name(&pam_username)?.ok_or("unable to get user info")?;
 
+//    let rc = unsafe { login_fbtab("ttyC0", user.uid.into(), user.gid.into()); };
+//    if rc != 0 {
+//        return Err("login_fbtab failed".into());
+//    }
+
+    const DEVICES: [&'static str;5] = ["/dev/wskbd0", "/dev/wsmouse0", "/dev/wsmouse1", "/dev/dri/card0", "/dev/dri/renderD128"];
+
+    for (i, device) in DEVICES.iter().enumerate() {
+        fs::chown(device, Some(user.uid.into()), Some(user.gid.into()))
+            .map_err(|e| format!("unable to chown {} to {}:{}", device, user.uid, user.gid))?;
+    }
+
     // Make this process a session leader.
     setsid().map_err(|e| format!("unable to become session leader: {}", e))?;
 
@@ -170,7 +190,7 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
         TerminalMode::Stdin => (),
         TerminalMode::Terminal { path, vt, switch } => {
             // Tell PAM what TTY we're targetting, which is used by logind.
-            pam.set_item(PamItemType::TTY, &format!("tty{}", vt))?;
+            pam.set_item(PamItemType::TTY, &format!("ttyC{}", vt))?;
             pam.putenv(&format!("XDG_VTNR={}", vt))?;
 
             // Opening our target terminal.
@@ -204,6 +224,8 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
     // and set all environment variables later.
     let prepared_env = [
         "XDG_SEAT=seat0".to_string(),
+        "WLR_DRM_DEVICES=/dev/dri/card0".to_string(),
+        "QT_QPA_PLATFORM=wayland".to_string(),
         format!("XDG_SESSION_CLASS={}", class.as_str()),
         format!("USER={}", user.name),
         format!("LOGNAME={}", user.name),
@@ -216,6 +238,13 @@ fn worker(sock: &UnixDatagram) -> Result<(), Error> {
     ];
     for e in env.iter().chain(prepared_env.iter()) {
         pam.putenv(e)?;
+    }
+
+//    if user.uid.into() == 0 as uid_t && user.gid.into() == 0 as gid_t {
+    if user.name == "root" {
+        pam.putenv("XDG_RUNTIME_DIR=/var/run/greetd")?;
+    } else {
+        pam.putenv(&format!("XDG_RUNTIME_DIR={}/.local/run", user.dir.to_string_lossy()))?;
     }
 
     // Session time!
