Advertisement
Guest User

cpufreq@konkor Gnome-shell 42

a guest
Apr 8th, 2022
592
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * This is a part of CPUFreq Manager
  3.  * Copyright (C) 2016-2019 konkor <konkor.github.io>
  4.  *
  5.  * Free Software Foundation, either version 3 of the License, or
  6.  * (at your option) any later version.
  7.  * You should have received a copy of the GNU General Public License along
  8.  * with this program. If not, see <http://www.gnu.org/licenses/>.
  9.  */
  10.  
  11. const Lang      = imports.lang;
  12. const GLib      = imports.gi.GLib;
  13. const GObject   = imports.gi.GObject;
  14. const Gio       = imports.gi.Gio;
  15. const St        = imports.gi.St;
  16. const Main      = imports.ui.main;
  17. const PanelMenu = imports.ui.panelMenu;
  18.  
  19. const ExtensionUtils = imports.misc.extensionUtils;
  20.  
  21. const Me = ExtensionUtils.getCurrentExtension ();
  22. const Logger       = Me.imports.common.Logger;
  23. const Convenience  = Me.imports.convenience;
  24. const EXTENSIONDIR = Me.dir.get_path ();
  25. const APP_PATH     = EXTENSIONDIR + "/cpufreq-application";
  26.  
  27. const SAVE_SETTINGS_KEY = 'save-settings';
  28. const EXTENSION_MODE_KEY= 'extension-mode';
  29. const SHOW_SPLASH_KEY   = 'show-splash';
  30. const PROFILE_ID_KEY    = 'profile-id';
  31. const MONITOR_KEY       = 'monitor';
  32. const EPROFILES_KEY     = 'event-profiles';
  33. const LABEL_KEY         = 'label'
  34. const LABEL_SHOW_KEY    = 'label-show';
  35. const UNITS_SHOW_KEY    = 'units-show';
  36. const FREQ_SHOW_KEY     = 'frequency-show';
  37. const GOVS_SHOW_KEY     = 'governors-show';
  38. const LOAD_SHOW_KEY     = 'load-show';
  39.  
  40. const COLOR_SHOW_KEY = 'color-show';
  41. const COLOR_SHOW_CUSTOM_KEY = 'color-show-custom';
  42. const COLOR_SHOW_CUSTOM_NORMAL_KEY = 'color-show-custom-normal';
  43. const COLOR_SHOW_CUSTOM_WARNING_KEY = 'color-show-custom-warning';
  44. const COLOR_SHOW_CUSTOM_CRITICAL_KEY = 'color-show-custom-critical';
  45.  
  46. let color_show = false;
  47. let color_show_custom = false;
  48. let color_show_default_normal = ''; //'#33d552';
  49. let color_show_default_warning = 'orange';
  50. let color_show_default_critical = 'red';
  51. let color_show_custom_normal = '#ebebeb';
  52. let color_show_custom_warning = '#ebebeb';
  53. let color_show_custom_critical = '#ff0000';
  54.  
  55. //const SETTINGS_ID = 'org.gnome.shell.extensions.cpufreq';
  56.  
  57. let event = 0;
  58. let event_style = 0;
  59. let monitor_event = 0;
  60. let settingsID, powerID, scheduleID;
  61.  
  62. let save = false;
  63. let extmode = true;
  64. let splash = true;
  65. let label_text = "";
  66. let label_show = false;
  67. let units_show = true;
  68. let frequency_show = true;
  69. let governor_show = false;
  70. let load_show = false;
  71. let title_text = "\u26A0";
  72. let title_style = "";
  73. let monitor_timeout = 500;
  74. let eprofiles = [
  75.   {percent:0, event:0, guid:""},
  76.   {percent:100, event:1, guid:""}
  77. ];
  78. let first_boot = true;
  79. let guid_battery = "";
  80.  
  81. const UP_BUS_NAME = 'org.freedesktop.UPower';
  82. const UP_OBJECT_PATH = '/org/freedesktop/UPower/devices/DisplayDevice';
  83. const DisplayDeviceInterface = '<node> \
  84. <interface name="org.freedesktop.UPower.Device"> \
  85.  <property name="Type" type="u" access="read"/> \
  86.  <property name="State" type="u" access="read"/> \
  87.  <property name="Percentage" type="d" access="read"/> \
  88.  <property name="TimeToEmpty" type="x" access="read"/> \
  89.  <property name="TimeToFull" type="x" access="read"/> \
  90.  <property name="IsPresent" type="b" access="read"/> \
  91.  <property name="IconName" type="s" access="read"/> \
  92. </interface> \
  93. </node>';
  94. const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(DisplayDeviceInterface);
  95.  
  96. const BUS_NAME = 'org.konkor.cpufreq.service';
  97. const OBJECT_PATH = '/org/konkor/cpufreq/service';
  98. const CpufreqServiceIface = '<node> \
  99. <interface name="org.konkor.cpufreq.service"> \
  100. <property name="Frequency" type="t" access="read"/> \
  101. <signal name="MonitorEvent"> \
  102.  <arg name="metrics" type="s"/> \
  103. </signal> \
  104. <signal name="LoadingEvent"> \
  105.  <arg name="loading" type="t"/> \
  106. </signal> \
  107. <signal name="StyleChanged"> \
  108.  <arg name="style" type="s"/> \
  109. </signal> \
  110. </interface> \
  111. </node>';
  112. const CpufreqServiceProxy = Gio.DBusProxy.makeProxyWrapper (CpufreqServiceIface);
  113.  
  114. const FrequencyIndicator = GObject.registerClass(
  115. class CpuFreq extends PanelMenu.Button
  116. {
  117.   _init () {
  118.     super._init(0.0, "CPU Frequency Indicator", false);
  119.     this.settings = Convenience.getSettings();
  120.     this.on_settings (null, null);
  121.  
  122.     this.statusLabel = new St.Label ({
  123.       text: title_text, y_expand: true, y_align: 2, style_class:'cpufreq-text'
  124.     });
  125.     this.statusLabel.style = title_style;
  126.     let _box = new St.BoxLayout();
  127.     _box.add_actor (this.statusLabel);
  128.     this.actor.add_actor (_box);
  129.     this.actor.connect ('button-press-event', () => {
  130.       var args = extmode ? "--extension" : "";
  131.       if (splash)
  132.         if (!this.app_running) this.show_splash ();
  133.       if (!guid_battery || (guid_battery == this.guid)) this.launch_app (args);
  134.       else this.launch_app (args + " --no-save");
  135.     });
  136.     if (!monitor_timeout) this.statusLabel.set_text (this.get_title ());
  137.  
  138.     this.add_event ();
  139.  
  140.     //TODO: Workaround updating title
  141.     this.settings.set_boolean (SAVE_SETTINGS_KEY, !save);
  142.     this.settings.set_boolean (SAVE_SETTINGS_KEY, save);
  143.  
  144.     if (settingsID) this.settings.disconnect (settingsID);
  145.     settingsID = this.settings.connect ("changed", this.on_settings.bind (this));
  146.  
  147.     this.power = new PowerManagerProxy (Gio.DBus.system, UP_BUS_NAME, UP_OBJECT_PATH, (proxy, e) => {
  148.       if (e) {
  149.         error (e.message);
  150.         return;
  151.       }
  152.       this.on_power_state (proxy.State, proxy.Percentage);
  153.       if (save && first_boot && !guid_battery) this.launch_app ("-p user");
  154.       first_boot = false;
  155.       GLib.timeout_add (0, 8000, () => {
  156.         powerID = this.power.connect ('g-properties-changed', (o,a) => {
  157.           //a = a{sv}
  158.           this.on_power_state (this.power.State, this.power.Percentage);
  159.         });
  160.       });
  161.     });
  162.   }
  163.  
  164.   on_settings (o, key) {
  165.     let s;
  166.     o = o || this.settings;
  167.  
  168.     if (!key) {
  169.       this.guid =  o.get_string (PROFILE_ID_KEY);
  170.       monitor_timeout =  o.get_int (MONITOR_KEY);
  171.       save = o.get_boolean (SAVE_SETTINGS_KEY);
  172.       extmode = o.get_boolean (EXTENSION_MODE_KEY);
  173.       splash = o.get_boolean (SHOW_SPLASH_KEY);
  174.       label_text = o.get_string (LABEL_KEY);
  175.       label_show = o.get_boolean (LABEL_SHOW_KEY);
  176.       units_show = o.get_boolean (UNITS_SHOW_KEY);
  177.       frequency_show = o.get_boolean (FREQ_SHOW_KEY);
  178.       governor_show = o.get_boolean (GOVS_SHOW_KEY);
  179.       load_show = o.get_boolean (LOAD_SHOW_KEY);
  180.       color_show = o.get_boolean (COLOR_SHOW_KEY);
  181.       color_show_custom = o.get_boolean (COLOR_SHOW_CUSTOM_KEY);
  182.       color_show_custom_normal = o.get_string (COLOR_SHOW_CUSTOM_NORMAL_KEY);
  183.       color_show_custom_warning = o.get_string (COLOR_SHOW_CUSTOM_WARNING_KEY);
  184.       color_show_custom_critical = o.get_string (COLOR_SHOW_CUSTOM_CRITICAL_KEY);
  185.       s = o.get_string (EPROFILES_KEY);
  186.       if (s) eprofiles = JSON.parse (s);
  187.     }
  188.  
  189.     if (key == MONITOR_KEY) {
  190.       monitor_timeout =  o.get_int (MONITOR_KEY);
  191.       if (monitor_event) {
  192.         GLib.source_remove (monitor_event);
  193.         monitor_event = 0;
  194.       }
  195.       monitor_event = GLib.timeout_add (100, 1000, this.add_event.bind (this));
  196.     } else if (key == PROFILE_ID_KEY) {
  197.       this.guid =  o.get_string (PROFILE_ID_KEY);
  198.     } else if (key == EPROFILES_KEY) {
  199.       s = o.get_string (EPROFILES_KEY);
  200.       if (s) eprofiles = JSON.parse (s);
  201.     } else if (key == EXTENSION_MODE_KEY) {
  202.       extmode = o.get_boolean (EXTENSION_MODE_KEY);
  203.     } else if (key == SHOW_SPLASH_KEY) {
  204.       splash = o.get_boolean (SHOW_SPLASH_KEY);
  205.     } else if (key == LABEL_KEY) {
  206.       label_text = o.get_string (LABEL_KEY);
  207.     } else if (key == LABEL_SHOW_KEY) {
  208.       label_show = o.get_boolean (LABEL_SHOW_KEY);
  209.     } else if (key == UNITS_SHOW_KEY) {
  210.       units_show = o.get_boolean (UNITS_SHOW_KEY);
  211.     } else if (key == FREQ_SHOW_KEY) {
  212.       frequency_show = o.get_boolean (FREQ_SHOW_KEY);
  213.     } else if (key == GOVS_SHOW_KEY) {
  214.       governor_show = o.get_boolean (GOVS_SHOW_KEY);
  215.     } else if (key == LOAD_SHOW_KEY) {
  216.       load_show = o.get_boolean (LOAD_SHOW_KEY);
  217.     }else if (key == COLOR_SHOW_KEY) {
  218.       color_show = o.get_boolean (COLOR_SHOW_KEY);
  219.     } else if (key == COLOR_SHOW_CUSTOM_KEY) {
  220.       color_show_custom = o.get_boolean (COLOR_SHOW_CUSTOM_KEY);
  221.     } else if (key == COLOR_SHOW_CUSTOM_NORMAL_KEY) {
  222.       color_show_custom_normal = o.get_string (COLOR_SHOW_CUSTOM_NORMAL_KEY);
  223.     } else if (key == COLOR_SHOW_CUSTOM_WARNING_KEY) {
  224.       color_show_custom_warning = o.get_string (COLOR_SHOW_CUSTOM_WARNING_KEY);
  225.     } else if (key == COLOR_SHOW_CUSTOM_CRITICAL_KEY) {
  226.       color_show_custom_critical = o.get_string (COLOR_SHOW_CUSTOM_CRITICAL_KEY);
  227.     }
  228.  
  229.     //TODO: statusLabel
  230.     if ((key == LABEL_KEY) && !monitor_timeout) this.statusLabel.set_text (this.get_title ());
  231.  
  232.     /*if ((key == "power-state") || (key == "power-percentage")) {
  233.       debug ("power-state changed...");
  234.       this.on_power_state (o.get_uint ("power-state"), o.get_double ("power-percentage"));
  235.     }*/
  236.   }
  237.  
  238.   on_power_state (state, percentage) {
  239.     let id = eprofiles[1].guid;
  240.     //debug ("on_power_state: %s %s%%".format (this.power.State, this.power.Percentage));
  241.     debug ("on_power_state: %s %s%%".format (state, percentage));
  242.     if (!id) return;
  243.     if (state == 2) {
  244.       //on battery
  245.       if (id == guid_battery) return;
  246.       if (percentage < eprofiles[1].percent) {
  247.         this.schedule_profile ('--no-save -p ' + id);
  248.         guid_battery = id;
  249.       }
  250.     } else {
  251.       //restoring prev state
  252.       if (guid_battery == this.guid) return;
  253.       this.schedule_profile ('-p user');
  254.       guid_battery = this.guid;
  255.     }
  256.   }
  257.  
  258.   unschedule_profile () {
  259.     GLib.source_remove (scheduleID);
  260.     scheduleID = 0;
  261.   }
  262.  
  263.   schedule_profile (options) {
  264.     if (scheduleID) this.unschedule_profile ();
  265.     scheduleID = GLib.timeout_add (0, 5000, () => {
  266.       this.launch_app (options);
  267.       scheduleID = 0;
  268.     });
  269.   }
  270.  
  271.   launch_app (options) {
  272.     let extra = "";
  273.     /*if (Logger.debug_lvl == 2) extra = " --debug";
  274.     else if (Logger.debug_lvl == 1) extra = " --verbose";*/
  275.     options = options || "";
  276.     info ("launch_app " + options + extra);
  277.     GLib.spawn_command_line_async ("%s %s".format (APP_PATH, options + extra));
  278.   }
  279.  
  280.   get app_running () {
  281.     let res = GLib.spawn_command_line_sync ("ps -A");
  282.     let o, n;
  283.     if (res[0]) o = Convenience.byteArrayToString (res[1]).toString().split("\n");
  284.     for (let i = 0; i < o.length; i++) {
  285.       if (o[i].indexOf ("cpufreq-app") > -1) {
  286.         n = parseInt (o[i].trim().split(" ")[0]);
  287.         if (Number.isInteger(n) && n > 0) return n;
  288.       }
  289.     }
  290.     return 0;
  291.   }
  292.  
  293.   get_title (text) {
  294.     if (!text) return title_text;
  295.     let metrics = JSON.parse (text), s = "", f = 0, units;
  296.     if (frequency_show) {
  297.       f = metrics.frequency_maximum;
  298.       if (f) if (f < 1000000) {
  299.         units = " \u3392";
  300.         s = (f / 1000).toFixed(0).toString ();
  301.       } else {
  302.         units = "\u3393";
  303.         s = (f / 1000000).toFixed(2).toString ();
  304.       }
  305.       if (units_show) s += units;
  306.     }
  307.     if (governor_show && metrics.governor) {
  308.       s += " " + this.get_governor_symbolyc (metrics.governor);
  309.     }
  310.     if (load_show && Number.isInteger (metrics.state))
  311.       s += ' ' + this.get_state_symbolyc (metrics.state);
  312.     if (label_show) s += ' ' + label_text;
  313.     if (s) title_text = s.trim ();
  314.     else title_text = label_text;
  315.  
  316.     if (color_show && Number.isInteger (metrics.state)) {
  317.       s = this.get_stylestring (metrics.state);
  318.     } else title_style = "";
  319.     if (s != title_style) {
  320.       title_style = s;
  321.       this.statusLabel.style = title_style;
  322.     }
  323.     return title_text;
  324.   }
  325.  
  326.   get_governor_symbolyc (name) {
  327.     let g = name;
  328.     if (g == "mixed") g = "\u25cd";
  329.     else if (g == "powersave") g = "\uf06c";
  330.     else if (g == "performance") g = "\uf197";
  331.     else if (g == "ondemand") g = "\uf0e7";
  332.     else if (g == "conservative") g = "\ue976";
  333.     else if (g == "schedutil") g = "\ue953";
  334.     else if (g == "userspace") g = "\uf007";
  335.     else g = "\uf0e7";
  336.     return g;
  337.   }
  338.  
  339.   get_state_symbolyc (state) {
  340.     let g = "☺";
  341.     if (state == 1) g = "";
  342.     else if (state == 2) g = "☹";
  343.     return g;
  344.   }
  345.  
  346.   get_stylestring (state) {
  347.     let s;
  348.     if (color_show_custom) state += 3;
  349.     switch (state) {
  350.       case 0:
  351.         s = "color:" + color_show_default_normal + ";";
  352.         break;
  353.       case 1:
  354.         s = "color:" + color_show_default_warning + ";";
  355.         break;
  356.       case 2:
  357.         s = "color:" + color_show_default_critical + ";";
  358.         break;
  359.       case 3:
  360.         s = "color:" + color_show_custom_normal + ";";
  361.         break;
  362.       case 4:
  363.         s = "color:" + color_show_custom_warning + ";";
  364.         break;
  365.       case 5:
  366.         s = "color:" + color_show_custom_critical + ";";
  367.         break;
  368.       default:
  369.         s = "";
  370.     }
  371.     return s;
  372.   }
  373.  
  374.   add_event () {
  375.     this.remove_proxy ();
  376.     if (monitor_timeout > 0) {
  377.       if (!GLib.spawn_command_line_async (EXTENSIONDIR + "/cpufreq-service")) {
  378.         //error ("Unable to start cpufreq service...");
  379.         return;
  380.       }
  381.       this.proxy = new CpufreqServiceProxy (Gio.DBus.session, BUS_NAME, OBJECT_PATH, (proxy, e) => {
  382.         if (e) {
  383.           error (e.message);
  384.           return;
  385.         }
  386.         event = this.proxy.connectSignal ('MonitorEvent', (o, s, metrics) => {
  387.           if (metrics) this.statusLabel.set_text (this.get_title (metrics.toString ()));
  388.         });
  389.         event_style = this.proxy.connectSignal ('StyleChanged', (o, s, style) => {
  390.           if (style) {
  391.             title_style = style.toString ();
  392.             this.statusLabel.style = title_style;
  393.           }
  394.         });
  395.       });
  396.     }
  397.     monitor_event = 0;
  398.     // cpufreq-service should stop auto on disabled monitors
  399.     //else GLib.spawn_command_line_async ("killall cpufreq-service");
  400.   }
  401.  
  402.   remove_proxy () {
  403.     if (this.proxy) {
  404.       if (event) this.proxy.disconnectSignal (event);
  405.       if (event_style) this.proxy.disconnectSignal (event_style);
  406.       delete this.proxy;
  407.     }
  408.     this.proxy = null;
  409.     event = 0;
  410.     event_style = 0;
  411.   }
  412.  
  413.   remove_events () {
  414.     this.remove_proxy ();
  415.     if (settingsID) this.settings.disconnect (settingsID);
  416.     if (powerID) this.power.disconnect (powerID);
  417.     if (monitor_event) GLib.source_remove (monitor_event);
  418.     event = 0; monitor_event = 0;
  419.     settingsID = 0; powerID = 0;
  420.     //GLib.spawn_command_line_async ("killall cpufreq-service");
  421.   }
  422.  
  423.   show_splash () {
  424.     let monitor = Main.layoutManager.focusMonitor;
  425.     let height = monitor.height < monitor.width ? monitor.height : monitor.width;
  426.     let width = 512 * height / 1200;
  427.     if (!this.splash)
  428.       this.splash = Gio.icon_new_for_string (EXTENSIONDIR + "/data/splash.svg");
  429.     let splash = new St.Icon ({gicon: this.splash, icon_size: width});
  430.     Main.uiGroup.add_actor (splash);
  431.  
  432.     splash.set_position (Math.floor (monitor.width / 2 - splash.width / 2),
  433.       Math.floor (monitor.height / 2 - splash.height / 2));
  434.  
  435.     if (splash.ease) splash.ease ({
  436.       opacity: 20, mode: 8, duration: 1200,
  437.       onComplete: () => { remove_actor (splash)}
  438.     }); else GLib.timeout_add (0, 1200, () => { return remove_actor (splash)});
  439.   }
  440. });
  441.  
  442. function remove_actor (o) {
  443.   Main.uiGroup.remove_actor (o);
  444.   o.destroy ();
  445.   return false;
  446. }
  447.  
  448. function show_notify (message, style) {
  449.   //var text = new St.Label ({text: message, style_class: style?style:'cpufreq-notify'});
  450.   var text = new St.Label ({text: message, style_class: "modal-dialog audio-selection-content restart-message"});
  451.   text.opacity = 255;
  452.   Main.uiGroup.add_actor (text);
  453.  
  454.   text.set_position (Math.floor (Main.layoutManager.primaryMonitor.width / 2 - text.width / 2),
  455.     Math.floor (Main.layoutManager.primaryMonitor.height / 2 - text.height / 2));
  456.  
  457.   GLib.timeout_add (0, 1200, () => { return remove_actor (text)});
  458. }
  459.  
  460. function show_warn (message) {
  461.     show_notify (message, "warn-label");
  462. }
  463.  
  464. let monitor;
  465. Logger.init (Logger.LEVEL.ERROR, true);
  466.  
  467. function info (msg) {
  468.   Logger.info ("extension", msg);
  469. }
  470.  
  471. function debug (msg) {
  472.   Logger.debug ("extension", msg);
  473. }
  474.  
  475. function error (msg) {
  476.   Logger.error ("extension", msg);
  477. }
  478.  
  479. function init () {
  480. }
  481.  
  482. function enable () {
  483.   monitor = new FrequencyIndicator;
  484.   Main.panel.addToStatusArea ('cpufreq-indicator', monitor);
  485. }
  486.  
  487. function disable () {
  488.   monitor.remove_events ();
  489.   monitor.destroy ();
  490.   monitor = null;
  491. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement