mirror of
https://github.com/an-anime-team/sleepy-launcher.git
synced 2025-03-15 06:28:27 +03:00
feat(ui): added gamescope settings support
Added gamescope settings support. As well made gamemode and gamescope switches non-sensitive if needed packages aren't installed
This commit is contained in:
parent
ec30411ef8
commit
84683ded86
16 changed files with 357 additions and 7 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -74,7 +74,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anime-launcher-sdk"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"anime-game-core",
|
||||
"anyhow",
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e662699b992108c50602944647cded05df6beba9
|
||||
Subproject commit f1f8eb6a2cc2d61dc8a2fa02051bd5ab2c400338
|
|
@ -24,6 +24,9 @@ performance = Leistung
|
|||
gamemode = Gamemode
|
||||
gamemode-description = Dem Spiel den Vorrang vor den übrigen Prozessen geben
|
||||
|
||||
gamescope = Gamescope
|
||||
gamescope-description = Gamescope is a tool from Valve that allows for games to run in an isolated Xwayland instance and supports AMD, Intel, and Nvidia GPUs
|
||||
|
||||
fps-unlocker = FPS Freischalter
|
||||
|
||||
enabled = Aktiviert
|
||||
|
@ -36,6 +39,7 @@ monitor = Monitor
|
|||
monitor-description = Nummer des Monitors, auf dem das Spiel laufen soll
|
||||
|
||||
window-mode = Fenster Modus
|
||||
borderless = Borderless
|
||||
popup = Popup
|
||||
fullscreen = Vollbild
|
||||
|
||||
|
|
6
assets/locales/de/gamescope.ftl
Normal file
6
assets/locales/de/gamescope.ftl
Normal file
|
@ -0,0 +1,6 @@
|
|||
game-resolution = Game resolution
|
||||
gamescope-resolution = Gamescope resolution
|
||||
other-settings = Other settings
|
||||
framerate-limit = Framerate limit
|
||||
unfocused-framerate-limit = Unfocused framerate limit
|
||||
integer-scaling = Integer scaling
|
|
@ -3,6 +3,9 @@ none = Kein
|
|||
default = Standard
|
||||
details = Einzelheiten
|
||||
|
||||
width = Width
|
||||
height = Height
|
||||
|
||||
# Menu items
|
||||
|
||||
launcher-folder = Launcher-Ordner
|
||||
|
|
|
@ -24,6 +24,9 @@ performance = Performance
|
|||
gamemode = Gamemode
|
||||
gamemode-description = Prioritize the game over the rest of the processes
|
||||
|
||||
gamescope = Gamescope
|
||||
gamescope-description = Gamescope is a tool from Valve that allows for games to run in an isolated Xwayland instance and supports AMD, Intel, and Nvidia GPUs
|
||||
|
||||
fps-unlocker = FPS Unlocker
|
||||
|
||||
enabled = Enabled
|
||||
|
@ -36,6 +39,7 @@ monitor = Monitor
|
|||
monitor-description = Number of monitor you want to run the game on
|
||||
|
||||
window-mode = Window Mode
|
||||
borderless = Borderless
|
||||
popup = Popup
|
||||
fullscreen = Fullscreen
|
||||
|
||||
|
|
6
assets/locales/en/gamescope.ftl
Normal file
6
assets/locales/en/gamescope.ftl
Normal file
|
@ -0,0 +1,6 @@
|
|||
game-resolution = Game resolution
|
||||
gamescope-resolution = Gamescope resolution
|
||||
other-settings = Other settings
|
||||
framerate-limit = Framerate limit
|
||||
unfocused-framerate-limit = Unfocused framerate limit
|
||||
integer-scaling = Integer scaling
|
|
@ -3,6 +3,9 @@ none = None
|
|||
default = Default
|
||||
details = Details
|
||||
|
||||
width = Width
|
||||
height = Height
|
||||
|
||||
# Menu items
|
||||
|
||||
launcher-folder = Launcher folder
|
||||
|
|
|
@ -24,6 +24,9 @@ performance = Скорость
|
|||
gamemode = Gamemode
|
||||
gamemode-description = Выделять игре приоритет перед остальными процессами
|
||||
|
||||
gamescope = Gamescope
|
||||
gamescope-description = Программа от Valve, позволяющая запускать игры в изолированном окружении Xwayland и поддерживает видеокарты от AMD, Intel, и Nvidia
|
||||
|
||||
fps-unlocker = FPS Unlocker
|
||||
|
||||
enabled = Включен
|
||||
|
@ -36,6 +39,7 @@ monitor = Монитор
|
|||
monitor-description = Номер монитора, на котором стоит запустить игру
|
||||
|
||||
window-mode = Режим окна
|
||||
borderless = Безрамочный
|
||||
popup = Всплывающий
|
||||
fullscreen = Полноэкранный
|
||||
|
||||
|
|
6
assets/locales/ru/gamescope.ftl
Normal file
6
assets/locales/ru/gamescope.ftl
Normal file
|
@ -0,0 +1,6 @@
|
|||
game-resolution = Разрешение игры
|
||||
gamescope-resolution = Разрешение Gamescope
|
||||
other-settings = Другие настройки
|
||||
framerate-limit = Лимит числа кадров
|
||||
unfocused-framerate-limit = Лимит числа кадров вне фокуса
|
||||
integer-scaling = Целочисленное масштабирование
|
|
@ -3,6 +3,9 @@ none = Нет
|
|||
default = По умолчанию
|
||||
details = Подробнее
|
||||
|
||||
width = Ширина
|
||||
height = Высота
|
||||
|
||||
# Menu items
|
||||
|
||||
launcher-folder = Папка лаунчера
|
||||
|
|
|
@ -2,6 +2,7 @@ use relm4::prelude::*;
|
|||
|
||||
use gtk::prelude::*;
|
||||
|
||||
use anime_launcher_sdk::VERSION as SDK_VERSION;
|
||||
use anime_launcher_sdk::anime_game_core::{VERSION as CORE_VERSION, curl_sys};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
|
@ -65,7 +66,9 @@ impl SimpleComponent for AboutDialog {
|
|||
].join("\n"),
|
||||
|
||||
set_debug_info: &[
|
||||
format!("Anime Game core: {CORE_VERSION}"),
|
||||
format!("Anime Launcher SDK: {SDK_VERSION}"),
|
||||
format!("Anime Game Core: {CORE_VERSION}"),
|
||||
String::new(),
|
||||
format!("curl: {}", CURL_INFO.version()),
|
||||
format!("SSL: {}", CURL_INFO.ssl_version().unwrap_or("?")),
|
||||
String::new(),
|
||||
|
|
|
@ -5,16 +5,27 @@ use adw::prelude::*;
|
|||
|
||||
use anime_launcher_sdk::config;
|
||||
use anime_launcher_sdk::config::prelude::*;
|
||||
use anime_launcher_sdk::is_available;
|
||||
|
||||
use crate::i18n::tr;
|
||||
use crate::*;
|
||||
|
||||
pub struct EnhancementsApp;
|
||||
use super::gamescope::*;
|
||||
|
||||
pub struct EnhancementsApp {
|
||||
gamescope: AsyncController<GamescopeApp>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EnhancementsAppMsg {
|
||||
SetGamescopeParent(adw::PreferencesWindow),
|
||||
OpenGamescope
|
||||
}
|
||||
|
||||
#[relm4::component(async, pub)]
|
||||
impl SimpleAsyncComponent for EnhancementsApp {
|
||||
type Init = ();
|
||||
type Input = ();
|
||||
type Input = EnhancementsAppMsg;
|
||||
type Output = ();
|
||||
|
||||
view! {
|
||||
|
@ -227,6 +238,8 @@ impl SimpleAsyncComponent for EnhancementsApp {
|
|||
set_title: &tr("gamemode"),
|
||||
set_subtitle: &tr("gamemode-description"),
|
||||
|
||||
set_sensitive: is_available("gamemoderun"),
|
||||
|
||||
add_suffix = >k::Switch {
|
||||
set_valign: gtk::Align::Center,
|
||||
|
||||
|
@ -237,6 +250,38 @@ impl SimpleAsyncComponent for EnhancementsApp {
|
|||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamemode = switch.state();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: &tr("gamescope"),
|
||||
set_subtitle: &tr("gamescope-description"),
|
||||
|
||||
set_sensitive: is_available("gamescope"),
|
||||
|
||||
add_suffix = >k::Button {
|
||||
set_icon_name: "emblem-system-symbolic",
|
||||
add_css_class: "flat",
|
||||
|
||||
set_valign: gtk::Align::Center,
|
||||
|
||||
connect_clicked => EnhancementsAppMsg::OpenGamescope
|
||||
},
|
||||
|
||||
add_suffix = >k::Switch {
|
||||
set_valign: gtk::Align::Center,
|
||||
|
||||
set_state: CONFIG.game.enhancements.gamescope.enabled,
|
||||
|
||||
connect_state_notify => move |switch| {
|
||||
if is_ready() {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.enabled = switch.state();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
|
@ -402,13 +447,30 @@ impl SimpleAsyncComponent for EnhancementsApp {
|
|||
async fn init(
|
||||
_init: Self::Init,
|
||||
root: Self::Root,
|
||||
_sender: AsyncComponentSender<Self>,
|
||||
sender: AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
tracing::info!("Initializing enhancements settings");
|
||||
|
||||
let model = Self;
|
||||
let model = Self {
|
||||
gamescope: GamescopeApp::builder()
|
||||
.launch(())
|
||||
.detach()
|
||||
};
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
AsyncComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
async fn update(&mut self, msg: Self::Input, _sender: AsyncComponentSender<Self>) {
|
||||
match msg {
|
||||
EnhancementsAppMsg::SetGamescopeParent(parent) => {
|
||||
self.gamescope.widget().set_transient_for(Some(&parent));
|
||||
}
|
||||
|
||||
EnhancementsAppMsg::OpenGamescope => {
|
||||
self.gamescope.widget().show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
243
src/ui/preferences/gamescope.rs
Normal file
243
src/ui/preferences/gamescope.rs
Normal file
|
@ -0,0 +1,243 @@
|
|||
use relm4::prelude::*;
|
||||
use relm4::component::*;
|
||||
|
||||
use adw::prelude::*;
|
||||
|
||||
use anime_launcher_sdk::config;
|
||||
use anime_launcher_sdk::config::prelude::*;
|
||||
|
||||
use crate::i18n::tr;
|
||||
use crate::*;
|
||||
|
||||
pub struct GamescopeApp;
|
||||
|
||||
#[relm4::component(async, pub)]
|
||||
impl SimpleAsyncComponent for GamescopeApp {
|
||||
type Init = ();
|
||||
type Input = ();
|
||||
type Output = ();
|
||||
|
||||
view! {
|
||||
adw::PreferencesWindow {
|
||||
set_title: Some(&tr("gamescope")),
|
||||
|
||||
set_modal: true,
|
||||
set_hide_on_close: true,
|
||||
set_search_enabled: false,
|
||||
|
||||
add = &adw::PreferencesPage {
|
||||
add = &adw::PreferencesGroup {
|
||||
set_title: &tr("game-resolution"),
|
||||
|
||||
adw::EntryRow {
|
||||
set_title: &tr("width"),
|
||||
set_input_purpose: gtk::InputPurpose::Digits,
|
||||
|
||||
set_text: &if CONFIG.game.enhancements.gamescope.game.width > 0 {
|
||||
CONFIG.game.enhancements.gamescope.game.width.to_string()
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
|
||||
connect_changed => |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.game.width = row.text().parse().unwrap_or_default();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adw::EntryRow {
|
||||
set_title: &tr("height"),
|
||||
set_input_purpose: gtk::InputPurpose::Digits,
|
||||
|
||||
set_text: &if CONFIG.game.enhancements.gamescope.game.height > 0 {
|
||||
CONFIG.game.enhancements.gamescope.game.height.to_string()
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
|
||||
connect_changed => |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.game.height = row.text().parse().unwrap_or_default();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_title: &tr("gamescope-resolution"),
|
||||
|
||||
adw::EntryRow {
|
||||
set_title: &tr("width"),
|
||||
set_input_purpose: gtk::InputPurpose::Digits,
|
||||
|
||||
set_text: &if CONFIG.game.enhancements.gamescope.gamescope.width > 0 {
|
||||
CONFIG.game.enhancements.gamescope.gamescope.width.to_string()
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
|
||||
connect_changed => |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.gamescope.width = row.text().parse().unwrap_or_default();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adw::EntryRow {
|
||||
set_title: &tr("height"),
|
||||
set_input_purpose: gtk::InputPurpose::Digits,
|
||||
|
||||
set_text: &if CONFIG.game.enhancements.gamescope.gamescope.height > 0 {
|
||||
CONFIG.game.enhancements.gamescope.gamescope.height.to_string()
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
|
||||
connect_changed => |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.gamescope.height = row.text().parse().unwrap_or_default();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
add = &adw::PreferencesGroup {
|
||||
set_title: &tr("other-settings"),
|
||||
|
||||
// TODO: maybe use Fps enum like in fps unlocker settings
|
||||
|
||||
adw::EntryRow {
|
||||
set_title: &tr("framerate-limit"),
|
||||
set_input_purpose: gtk::InputPurpose::Digits,
|
||||
|
||||
set_text: &if CONFIG.game.enhancements.gamescope.framerate.focused > 0 {
|
||||
CONFIG.game.enhancements.gamescope.framerate.focused.to_string()
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
|
||||
connect_changed => |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.framerate.focused = row.text().parse().unwrap_or_default();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adw::EntryRow {
|
||||
set_title: &tr("unfocused-framerate-limit"),
|
||||
set_input_purpose: gtk::InputPurpose::Digits,
|
||||
|
||||
set_text: &if CONFIG.game.enhancements.gamescope.framerate.unfocused > 0 {
|
||||
CONFIG.game.enhancements.gamescope.framerate.unfocused.to_string()
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
|
||||
connect_changed => |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.framerate.unfocused = row.text().parse().unwrap_or_default();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: &tr("integer-scaling"),
|
||||
|
||||
add_suffix = >k::Switch {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_state: CONFIG.game.enhancements.gamescope.integer_scaling,
|
||||
|
||||
connect_state_notify => |switch| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.integer_scaling = switch.state();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: "FSR",
|
||||
|
||||
add_suffix = >k::Switch {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_state: CONFIG.game.enhancements.gamescope.fsr,
|
||||
|
||||
connect_state_notify => |switch| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.fsr = switch.state();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: "Nvidia Image Scaling",
|
||||
|
||||
add_suffix = >k::Switch {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_state: CONFIG.game.enhancements.gamescope.nis,
|
||||
|
||||
connect_state_notify => |switch| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.nis = switch.state();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adw::ComboRow {
|
||||
set_title: &tr("window-mode"),
|
||||
|
||||
#[wrap(Some)]
|
||||
set_model = >k::StringList::new(&[
|
||||
&tr("borderless"),
|
||||
&tr("fullscreen")
|
||||
]),
|
||||
|
||||
set_selected: CONFIG.game.enhancements.gamescope.window_type.ordinal() as u32,
|
||||
|
||||
connect_selected_notify => |row| unsafe {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamescope.window_type = WindowType::from_ordinal_unsafe(row.selected() as i8);
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn init(
|
||||
_init: Self::Init,
|
||||
root: Self::Root,
|
||||
_sender: AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
tracing::info!("Initializing gamescope settings");
|
||||
|
||||
let model = Self;
|
||||
let widgets = view_output!();
|
||||
|
||||
AsyncComponentParts { model, widgets }
|
||||
}
|
||||
}
|
|
@ -105,6 +105,8 @@ impl SimpleAsyncComponent for PreferencesApp {
|
|||
}
|
||||
|
||||
#[allow(unused_must_use)] {
|
||||
model.enhancements.sender().send(EnhancementsAppMsg::SetGamescopeParent(widgets.preferences_window.clone()));
|
||||
|
||||
model.general.sender().send(GeneralAppMsg::UpdateDownloadedWine);
|
||||
model.general.sender().send(GeneralAppMsg::UpdateDownloadedDxvk);
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@ pub mod main;
|
|||
pub mod general;
|
||||
pub mod enhancements;
|
||||
pub mod environment;
|
||||
pub mod gamescope;
|
||||
|
|
Loading…
Add table
Reference in a new issue