wayland: keyboard: unlink keymap file after creation

The SHM pools in the buffer code can be removed immediately after
creation. This allows the filesystem to be clean after the application
closes. After files are unlinked, they are not deleted until all open
file descriptors are closed, such as the handle passed to Wayland.
Unlink the keymap file after it is created from the filesystem.
This commit is contained in:
Richard Acayan 2024-10-21 18:25:36 -04:00
parent bffe08cbed
commit 1e2c3d2ef4
No known key found for this signature in database
GPG key ID: 0346F4894879DB73

View file

@ -13,8 +13,7 @@ use crate::wayland::virtual_keyboard_unstable_v1::zwp_virtual_keyboard_manager_v
use crate::wayland::virtual_keyboard_unstable_v1::zwp_virtual_keyboard_v1::ZwpVirtualKeyboardV1; use crate::wayland::virtual_keyboard_unstable_v1::zwp_virtual_keyboard_v1::ZwpVirtualKeyboardV1;
use reis::ei; use reis::ei;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs;
use std::fs::OpenOptions;
use std::io::Seek; use std::io::Seek;
use std::io::Write; use std::io::Write;
use std::os::fd::AsFd; use std::os::fd::AsFd;
@ -106,7 +105,6 @@ const STATIC_KEYCODES: [(Keysym, u8); 76] = [
pub struct VirtualKeyboard { pub struct VirtualKeyboard {
vk: Option<ZwpVirtualKeyboardV1>, vk: Option<ZwpVirtualKeyboardV1>,
keymap: File,
keymap_id: u8, keymap_id: u8,
im: Option<ZwpInputMethodV2>, im: Option<ZwpInputMethodV2>,
@ -132,12 +130,8 @@ impl VirtualKeyboard {
let vk = vk_man.as_ref().map(|m| m.create_virtual_keyboard(seat, queue, ())); let vk = vk_man.as_ref().map(|m| m.create_virtual_keyboard(seat, queue, ()));
let im = im_man.as_ref().map(|m| m.get_input_method(seat, queue, ())); let im = im_man.as_ref().map(|m| m.get_input_method(seat, queue, ()));
let path = format!("/tmp/ufkbd-keymap-pid{}-1", process::id());
let keymap = File::create(path).unwrap();
VirtualKeyboard { VirtualKeyboard {
vk, vk,
keymap,
keymap_id: 1, keymap_id: 1,
im, im,
@ -152,25 +146,25 @@ impl VirtualKeyboard {
} }
} }
fn write_key(&mut self, part: &Part, keycode: u8) fn write_key(keymap: &mut fs::File, part: &Part, keycode: u8)
{ {
let sym = part.sym(); let sym = part.sym();
let lower = &sym.name().unwrap()[3..]; let lower = &sym.name().unwrap()[3..];
let upper = &Part::modify_shift(sym).name().unwrap()[3..]; let upper = &Part::modify_shift(sym).name().unwrap()[3..];
writeln!(self.keymap, " key <I{:03}> {{ [ {}, {} ] }};", writeln!(keymap, " key <I{:03}> {{ [ {}, {} ] }};",
keycode, lower, upper).unwrap(); keycode, lower, upper).unwrap();
if sym == Keysym::Shift_L { if sym == Keysym::Shift_L {
writeln!(self.keymap, writeln!(keymap,
" modifier_map Shift {{ <I{:03}> }};", " modifier_map Shift {{ <I{:03}> }};",
keycode).unwrap(); keycode).unwrap();
} else if sym == Keysym::Control_L { } else if sym == Keysym::Control_L {
writeln!(self.keymap, writeln!(keymap,
" modifier_map Control {{ <I{:03}> }};", " modifier_map Control {{ <I{:03}> }};",
keycode).unwrap(); keycode).unwrap();
} else if sym == Keysym::Alt_L { } else if sym == Keysym::Alt_L {
writeln!(self.keymap, writeln!(keymap,
" modifier_map Mod1 {{ <I{:03}> }};", " modifier_map Mod1 {{ <I{:03}> }};",
keycode).unwrap(); keycode).unwrap();
} }
@ -314,13 +308,11 @@ impl Keyboard for VirtualKeyboard {
let path = format!("/tmp/ufkbd-keymap-pid{}-{}", let path = format!("/tmp/ufkbd-keymap-pid{}-{}",
process::id(), self.keymap_id); process::id(), self.keymap_id);
self.keymap = OpenOptions::new() let mut keymap = fs::File::create_new(path.clone()).unwrap();
.read(true).write(true) let _ = fs::remove_file(path);
.create(true).truncate(true)
.open(path).unwrap();
self.keymap.write_all(b"xkb_keymap {\n").unwrap(); keymap.write_all(b"xkb_keymap {\n").unwrap();
self.keymap.write_all(b" xkb_symbols \"ufkbd\" {\n").unwrap(); keymap.write_all(b" xkb_symbols \"ufkbd\" {\n").unwrap();
self.keycodes.clear(); self.keycodes.clear();
for row in layout.rows() { for row in layout.rows() {
@ -333,7 +325,7 @@ impl Keyboard for VirtualKeyboard {
if let Ok(idx) = STATIC_KEYCODES.binary_search_by_key(&part.sym(), |(s, _)| *s) { if let Ok(idx) = STATIC_KEYCODES.binary_search_by_key(&part.sym(), |(s, _)| *s) {
let (sym, code) = STATIC_KEYCODES[idx]; let (sym, code) = STATIC_KEYCODES[idx];
self.keycodes.insert(sym, code - 8); self.keycodes.insert(sym, code - 8);
self.write_key(part, code); Self::write_key(&mut keymap, part, code);
used_codes[code as usize - 8] = true; used_codes[code as usize - 8] = true;
} }
} }
@ -356,43 +348,43 @@ impl Keyboard for VirtualKeyboard {
} }
self.keycodes.insert(part.sym(), keycode - 8); self.keycodes.insert(part.sym(), keycode - 8);
self.write_key(part, keycode); Self::write_key(&mut keymap, part, keycode);
keycode += 1; keycode += 1;
} }
} }
} }
self.keymap.write_all(b" };\n").unwrap(); keymap.write_all(b" };\n").unwrap();
self.keymap.write_all(b"\n").unwrap(); keymap.write_all(b"\n").unwrap();
self.keymap.write_all(b" xkb_keycodes \"ufkbd\" {\n").unwrap(); keymap.write_all(b" xkb_keycodes \"ufkbd\" {\n").unwrap();
self.keymap.write_all(b" minimum = 8;\n").unwrap(); keymap.write_all(b" minimum = 8;\n").unwrap();
self.keymap.write_all(b" maximum = 255;\n").unwrap(); keymap.write_all(b" maximum = 255;\n").unwrap();
for i in 8..keycode { for i in 8..keycode {
writeln!(self.keymap, " <I{:03}> = {};", i, i).unwrap(); writeln!(keymap, " <I{:03}> = {};", i, i).unwrap();
} }
for i in keycode..255 { for i in keycode..255 {
if used_codes[i as usize - 8] { if used_codes[i as usize - 8] {
writeln!(self.keymap, " <I{:03}> = {};", i, i).unwrap(); writeln!(keymap, " <I{:03}> = {};", i, i).unwrap();
} }
} }
self.keymap.write_all(b" indicator 1 = \"Caps Lock\";\n").unwrap(); keymap.write_all(b" indicator 1 = \"Caps Lock\";\n").unwrap();
self.keymap.write_all(b" };\n").unwrap(); keymap.write_all(b" };\n").unwrap();
self.keymap.write_all(b"\n").unwrap(); keymap.write_all(b"\n").unwrap();
self.keymap.write_all(b" xkb_types \"ufkbd\" {\n").unwrap(); keymap.write_all(b" xkb_types \"ufkbd\" {\n").unwrap();
self.keymap.write_all(b" type \"TWO_LEVEL\" {\n").unwrap(); keymap.write_all(b" type \"TWO_LEVEL\" {\n").unwrap();
self.keymap.write_all(b" modifiers = Shift;\n").unwrap(); keymap.write_all(b" modifiers = Shift;\n").unwrap();
self.keymap.write_all(b" map[Shift] = Level2;\n").unwrap(); keymap.write_all(b" map[Shift] = Level2;\n").unwrap();
self.keymap.write_all(b" level_name[Level1] = \"Base\";\n").unwrap(); keymap.write_all(b" level_name[Level1] = \"Base\";\n").unwrap();
self.keymap.write_all(b" level_name[Level2] = \"Shift\";\n").unwrap(); keymap.write_all(b" level_name[Level2] = \"Shift\";\n").unwrap();
self.keymap.write_all(b" };\n").unwrap(); keymap.write_all(b" };\n").unwrap();
self.keymap.write_all(b" };\n").unwrap(); keymap.write_all(b" };\n").unwrap();
self.keymap.write_all(b"\n").unwrap(); keymap.write_all(b"\n").unwrap();
self.keymap.write_all(b" xkb_compatibility \"ufkbd\" {\n").unwrap(); keymap.write_all(b" xkb_compatibility \"ufkbd\" {\n").unwrap();
self.keymap.write_all(b" };\n").unwrap(); keymap.write_all(b" };\n").unwrap();
self.keymap.write_all(b"};\n").unwrap(); keymap.write_all(b"};\n").unwrap();
if let Some(vk) = self.vk.as_ref() { if let Some(vk) = self.vk.as_ref() {
if self.mod_state != 0 { if self.mod_state != 0 {
@ -405,8 +397,8 @@ impl Keyboard for VirtualKeyboard {
} }
} }
let len = self.keymap.stream_position().unwrap() as u32; let len = keymap.stream_position().unwrap() as u32;
vk.keymap(KeymapFormat::XkbV1 as u32, self.keymap.as_fd(), len); vk.keymap(KeymapFormat::XkbV1 as u32, keymap.as_fd(), len);
if self.mod_state != 0 { if self.mod_state != 0 {
vk.modifiers(self.mod_state, 0, 0, 0); vk.modifiers(self.mod_state, 0, 0, 0);