const { Gio, GLib, GObject, Gtk } = imports.gi; const Debug = imports.src.debug; const FileOps = imports.src.fileOps; const Misc = imports.src.misc; const Actions = imports.src.actions; const { debug } = Debug; const { settings } = Misc; var AppBase = GObject.registerClass( class ClapperAppBase extends Gtk.Application { _init() { super._init({ application_id: Misc.appId, }); this.doneFirstActivate = false; this.isFileAppend = false; } vfunc_startup() { super.vfunc_startup(); const window = new Gtk.ApplicationWindow({ application: this, title: Misc.appName, }); if(Gtk.MINOR_VERSION > 0 || Gtk.MICRO_VERSION > 1) window.add_css_class('gtk402'); if(!settings.get_boolean('render-shadows')) window.add_css_class('gpufriendly'); window.add_css_class('gpufriendlyfs'); } vfunc_activate() { super.vfunc_activate(); if(!this.doneFirstActivate) this._onFirstActivate(); this.active_window.present_with_time( Math.floor(GLib.get_monotonic_time() / 1000) ); } async _openFilesAsync(files) { const urisArr = []; for(let file of files) { const uri = file.get_uri(); if(!uri.startsWith('file:')) { urisArr.push(uri); continue; } /* If file is not a dir its URI will be returned in an array */ const uris = await FileOps.getDirFilesUrisPromise(file).catch(debug); if(uris && uris.length) urisArr.push(...uris); } const [playlist, subs] = Misc.parsePlaylistFiles(urisArr); const { player } = this.active_window.get_child(); const action = (this.isFileAppend) ? 'append' : 'set'; if(playlist && playlist.length) player[`${action}_playlist`](playlist); if(subs) player.set_subtitles(subs); /* Restore default behavior */ this.isFileAppend = false; } _onFirstActivate() { for(let name in Actions.actions) { const simpleAction = new Gio.SimpleAction({ name }); simpleAction.connect('activate', (action) => Actions.handleAction(action, this.active_window) ); this.add_action(simpleAction); const accels = Actions.actions[name]; if(accels) this.set_accels_for_action(`app.${name}`, accels); } const gtkSettings = Gtk.Settings.get_default(); settings.bind( 'dark-theme', gtkSettings, 'gtk-application-prefer-dark-theme', Gio.SettingsBindFlags.GET ); this._onThemeChanged(gtkSettings); this._onIconThemeChanged(gtkSettings); gtkSettings.connect('notify::gtk-theme-name', this._onThemeChanged.bind(this)); gtkSettings.connect('notify::gtk-icon-theme-name', this._onIconThemeChanged.bind(this)); this.doneFirstActivate = true; } _onThemeChanged(gtkSettings) { const theme = gtkSettings.gtk_theme_name; const window = this.active_window; const hasAdwThemeDark = window.has_css_class('adwthemedark'); debug(`user selected theme: ${theme}`); /* FIXME: AFAIK there is no way to detect theme rounded corners. Having 2/4 corners rounded in floating mode is not good. */ if(!window.has_css_class('adwrounded')) window.add_css_class('adwrounded'); if(theme.startsWith('Adwaita') || theme.startsWith('Default')) { const isDarkTheme = settings.get_boolean('dark-theme'); if(isDarkTheme && !hasAdwThemeDark) window.add_css_class('adwthemedark'); else if(!isDarkTheme && hasAdwThemeDark) window.remove_css_class('adwthemedark'); } else if(hasAdwThemeDark) window.remove_css_class('adwthemedark'); if(!theme.endsWith('-dark')) return; /* We need to request a default theme with optional dark variant to make the "gtk_application_prefer_dark_theme" setting work */ const parsedTheme = theme.substring(0, theme.lastIndexOf('-')); gtkSettings.gtk_theme_name = parsedTheme; debug(`set theme: ${parsedTheme}`); } _onIconThemeChanged(gtkSettings) { const iconTheme = gtkSettings.gtk_icon_theme_name; const window = this.active_window; const hasAdwIcons = window.has_css_class('adwicons'); if(iconTheme === 'Adwaita' || iconTheme === 'Default') { if(!hasAdwIcons) window.add_css_class('adwicons'); } else if(hasAdwIcons) window.remove_css_class('adwicons'); } });