Commits

Anonymous committed f59ed85

*should* fix #17 issue with steam, actually got new options working properly, fixed GUI

Comments (0)

Files changed (8)

+
+      _____ ____   ____
+     |  ___/ ___| / ___| __ _ _ __ ___   ___ _ __
+     | |_  \___ \| |  _ / _` | '_ ` _ \ / _ \ '__|
+     |  _|  ___) | |_| | (_| | | | | | |  __/ |
+     |_|   |____/ \____|\__,_|_| |_| |_|\___|_|
+
 
 FSGamer
 ---
 slowing everything down to be happy, and lets you easily switch in or out of
 fullscreen games which grab too many keystrokes.
 
-Grab the latest stable package from:
+Grab the latest stable package from [michaelb.org/fsgamer](http://michaelb.org/fsgamer/).
 
-http://michaelb.org/fsgamer/
 
-
-Everything sucks
+Running
 -----
 
-This project is hacked together using Canonical's `quickly`. It is very clumsy
-and poorly written, I was more concerned with getting it to work than getting
-it done right. Be warned!
+To run the fsgamer GUI:
 
-I'm not sure if there's an easy way to test run it without `quickly`, for
-non-Ubuntu folks out there.
+    bin/fsgamer
 
 
+To see what CLI options are available:
+
+    bin/fsgamer --help
+
+
+Config
+-----
+
+FSGamer stores normal XDG `.desktop` files in `~/.config/fsgamer`. These files
+are the same you would use to launch the game in FSGamer. Configuration options
+are stored as mere CLI arguments in the `Exec=` field.
+
+When you check the box to show the game in the menu it will copy that
+`.desktop` `~/.local/share/applications/`, which will make it show up in your
+menu.
+
+Hacking
+-----
+
+This project is hacked together using Canonical's `quickly`. So if you want to
+contribute you might consider using that!
+
+Please note: It is very clumsy and poorly written, I was more concerned with
+getting it to work than getting it done right. Be warned!
+
+

data/ui/AboutFsgamerDialog.ui

 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
+  <!-- interface-requires about_fsgamer_dialog 1.0 -->
   <!-- interface-requires gtk+ 3.0 -->
-  <!-- interface-requires about_fsgamer_dialog 1.0 -->
   <object class="AboutFsgamerDialog" id="about_fsgamer_dialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
     <property name="skip_taskbar_hint">True</property>
     <property name="skip_pager_hint">True</property>
     <property name="program_name">FS Gamer</property>
-    <property name="version">version 0.2</property>
+    <property name="version">version 0.1.1</property>
     <property name="copyright" translatable="yes">© Copyleft Michael Bethencourt, Some Rights Deserved</property>
     <property name="website">http://michaelb.org/fsgamer/</property>
     <property name="website_label" translatable="yes">michaelb.org/fsgamer</property>
             <property name="position">0</property>
           </packing>
         </child>
-        <child>
-          <placeholder/>
-        </child>
       </object>
     </child>
   </object>

data/ui/FsgamerWindow.ui

                       <object class="GtkLabel" id="game_options_label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="xalign">0.0099999997764825821</property>
+                        <property name="margin_left">10</property>
+                        <property name="xalign">0</property>
                         <property name="yalign">0</property>
-                        <property name="xpad">11</property>
-                        <property name="ypad">1</property>
                         <property name="label" translatable="yes">Configure this game</property>
                         <attributes>
                           <attribute name="font-desc" value="Sans Bold 12"/>
                     <property name="height_request">60</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <property name="margin_left">10</property>
+                    <property name="margin_top">15</property>
                     <child>
                       <object class="GtkBox" id="box3">
                         <property name="visible">True</property>
                                 <property name="xalign">1</property>
                                 <property name="yalign">0</property>
                                 <property name="xpad">10</property>
-                                <property name="label" translatable="yes">Use alternate xorg conf file:</property>
+                                <property name="label" translatable="yes">Use alternative xorg.conf:</property>
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkEntry" id="option_xorg_conf">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="invisible_char">•</property>
-                                <signal name="changed" handler="on_options_changed" swapped="no"/>
-                              </object>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="top_attach">0</property>
-                                <property name="width">1</property>
-                                <property name="height">1</property>
-                              </packing>
-                            </child>
-                            <child>
                               <object class="GtkEntry" id="option_before_script">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="invisible_char">•</property>
                                 <property name="invisible_char_set">True</property>
+                                <signal name="changed" handler="on_options_change" swapped="no"/>
                               </object>
                               <packing>
                                 <property name="left_attach">1</property>
                                 <property name="can_focus">True</property>
                                 <property name="invisible_char">•</property>
                                 <property name="invisible_char_set">True</property>
+                                <signal name="changed" handler="on_options_change" swapped="no"/>
                               </object>
                               <packing>
                                 <property name="left_attach">1</property>
                                 <property name="can_focus">True</property>
                                 <property name="invisible_char">•</property>
                                 <property name="invisible_char_set">True</property>
+                                <signal name="changed" handler="on_options_change" swapped="no"/>
                               </object>
                               <packing>
                                 <property name="left_attach">1</property>
                                 <property name="height">1</property>
                               </packing>
                             </child>
+                            <child>
+                              <object class="GtkBox" id="box6">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkLabel" id="label4">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">0</property>
+                                    <property name="label" translatable="yes">/etc/X11/</property>
+                                    <property name="justify">right</property>
+                                    <property name="ellipsize">start</property>
+                                    <attributes>
+                                      <attribute name="font-desc" value="Monospace 10"/>
+                                    </attributes>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkEntry" id="option_xorg_conf">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="invisible_char">•</property>
+                                    <property name="invisible_char_set">True</property>
+                                    <signal name="changed" handler="on_options_change" swapped="no"/>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="top_attach">0</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
                         </child>
                         <child>
                           <object class="GtkExpander" id="options_preview_expander">
+                            <property name="height_request">25</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="margin_left">20</property>
                             <property name="margin_right">20</property>
                             <child>
                               <object class="GtkBox" id="box4">
+                                <property name="height_request">90</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
                                 <child>
                                   <object class="GtkFrame" id="frame1">
+                                    <property name="height_request">80</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="hexpand">True</property>
                                     <property name="vexpand">True</property>
                                     <property name="label_xalign">0</property>
+                                    <property name="shadow_type">none</property>
                                     <child>
                                       <object class="GtkAlignment" id="alignment1">
                                         <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="halign">start</property>
                                     <property name="label_xalign">0</property>
+                                    <property name="shadow_type">none</property>
                                     <child>
                                       <object class="GtkAlignment" id="alignment2">
                                         <property name="visible">True</property>
                                         <child>
                                           <object class="GtkScrolledWindow" id="scrolledwindow5">
                                             <property name="width_request">240</property>
-                                            <property name="height_request">100</property>
                                             <property name="visible">True</property>
                                             <property name="can_focus">True</property>
                                             <property name="shadow_type">in</property>

fsgamer/FsgamerWindow.py

 """
 
 APP_INSTRUCTIONS = """
-Application is now configured to run fullscreen with FS Gamer. Start it by
-clicking the ludicrously large button to the right.
+Start your game by clicking the ludicrously large button to the right.
 
 Ctrl+Alt+F7  will take you back to your desktop from the game.
 """.replace("y\n", "y ").strip()
 
 
     def on_options_change(self, widget, data=None):
-        print "Changing options!"
         if not self.current_app:
             return
 
             elif isinstance(default_val, basestring):
                 w = get_buffer_for_widget(widget)
                 val = w.get_text().strip()
-            print "key , val", key, val
 
             if val != default_val:
                 self.current_app.opts[key] = val
                 if key in self.current_app.opts:
                     del self.current_app.opts[key]
 
-            self.refresh_script_previews()
+        self.refresh_script_previews()
 
         self.current_app.write_menu_icon()
         self.current_app.write_desktop()
 
     def refresh_script_previews(self):
-        xinit_script = self.current_app.get_xinit_fsgwm()
+        xinit_script = self.current_app.get_xinit_fsgwm(fake_shell=True)
         xserver_script = self.current_app.get_exec_opts()
         self.ui.preview_options_xinit.set_text(xinit_script)
         self.ui.preview_options_xserver.set_text(xserver_script)

fsgamer/fsgamer_app.py

     Icon=%(icon)s
 """.replace("    ", "").strip()
 
+
 def _load_de(fn):
     try:
         new_entry = d.DesktopEntry(filename=fn)
         print("Uh oh, could not load ", fn)
     return new_entry
 
+
 def get_xdg_applications():
     lst = []
 
         desktop_entries.append(new_entry)
     return desktop_entries
 
+
 class DesktopEntryList(list):
     def __init__(self, initial=None):
         entries = initial or get_xdg_applications()
         os.makedirs(path)
     return os.path.abspath(path)
 
+
 def _local_share_applications_path():
     p = os.path.join(utils.HOMEDIR, ".local", "share", "applications")
     if not os.path.exists(p):
         os.makedirs(p)
     return os.path.abspath(p)
 
+
 class ApplicationList(list):
     def __init__(self, path=None):
         # Defaults to home directory
 
 TITLE_TRANS = ''.join(chr(c) if chr(c).isupper() or chr(c).islower() else '_' for c in range(256))
 
+
 def _to_filename(s):
     return s.translate(TITLE_TRANS).strip('_')
 
 
         if self.desktop:
             e = self.desktop.getExec().strip()
-            if e.startswith(utils.BINPATH):
+            if e.startswith(utils.BINPATH) or 'fsgamer' in e:
                 # Strip away our options for its internal representation
                 options, args = utils.parse_options(e)
                 self.desktop.set('Exec', options.exe)
         a.opts.update(opts)
         return a
 
-
     def get_name(self):
         if self.command:
             # figure out
         then run_inner on another xsession)
         """
         e = self.build_exec()
+        print "THIS IS E", e
 
         # Run outer:
         self.process = utils.shell_run(e, replace=True)
             e = self.command
         else:
             e = self.desktop.getExec()
-        if self.opts.get('xserer_script', '').strip():
-            return "%s &\n%s" % (e, self.opts['xserver_script'].strip())
-        else:
-            return e
 
-    def get_xinit_fsgwm(self):
-        if self.command:
-            e = self.command
-        else:
-            e = self.desktop.getExec()
+        inner_script = ''
+        if self.opts.get('xserver_script', '').strip():
+            inner_script += "%s &\n" % self.opts['xserver_script'].strip()
+        inner_script += "exec %s" % e
+        return inner_script
 
-        if self.opts.get('xserver_script', '').strip():
-            inner_script = "%s &\n%s" % (e, self.opts['xserver_script'].strip())
+    def get_xinit_fsgwm(self, fake_shell=False):
+        script = ''
 
-            inner_script_sh = utils.shell_run.sh_from_script(inner_script)
-            script = utils.shellbuilder.xinit_fsgwm(inner_script_sh, self.opts)
-        else:
-            script = utils.shellbuilder.xinit_fsgwm(e, self.opts)
+        if self.opts.get('before_script', '').strip():
+            script += "%s &\n" % self.opts['before_script'].strip()
+
+        inner_script_sh = utils.shell_run.sh_from_script(self.get_exec_opts(), fake_shell)
+        script += utils.shellbuilder.xinit_fsgwm(inner_script_sh, self.opts)
 
         return script
 
         # This is the key function that actually runs this command in a
         # separate xsession
         self.process = utils.shell_run(script)
+        print "---------------> MY PROCESS ", self.process
 
     def kill(self):
         """

fsgamer/openbox.py

 TEMPLATE = '%s --sm-disable --config-file %s --startup %s'
 def main(exe, opts):
     data = open(CONF_PATH).read()
-    data = data.replace("<!--[[END]]-->", make_conf(exe))
+    extra_conf = make_conf(exe) + 
+    data = data.replace("<!--[[END]]-->", extra_conf)
 
     path = utils.write_tmp_file("openbox_conf.xml", data)
 
 
 class DependencyError(Exception): pass
 
-BINPATH = os.environ.get("FSGAMER_BIN", sys.argv[0])
+#BINPATH = os.environ.get("FSGAMER_BIN", sys.argv[0])
+
+BINPATH = os.path.abspath(sys.argv[0])
 
 # Quick hack for during development using quickly
-QUICKLY_RUN_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(
-                                os.path.realpath(__file__)))), "quicklyrun.sh")
-if os.path.exists(QUICKLY_RUN_PATH):
-    BINPATH = QUICKLY_RUN_PATH
+
+#QUICKLY_RUN_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(
+#                                os.path.realpath(__file__)))), "quicklyrun.sh")
+#if os.path.exists(QUICKLY_RUN_PATH):
+#    BINPATH = QUICKLY_RUN_PATH
 
 
 HOMEDIR = os.path.expanduser("~")
             # If we have TTS notifications enabled, then add that to the script
             script.append(unparse_options({'tts': None}) + " &")
 
-        if not opts.get('keep_going'):
-            # Run kill-pact process to kill everything if the child process
-            # fails to start
-            d = {'killpact': None, 'exec': cmd}
-            script.append(unparse_options(d) + " &")
+        #if not opts.get('keep_going'):
+        #    # Run kill-pact process to kill everything if the child process
+        #    # fails to start
+        #    d = {'killpact': None, 'exec': cmd}
+        #    script.append(unparse_options(d) + " &")
 
         script.append(
                 shellbuilder.xinit(shellbuilder.fsgwm(cmd, opts), opts)
         #return subprocess.Popen(script_args, shell=True, bufsize=-1)
 
 
-TMP_DIR = "/tmp/%i/fsgamer/"
+TMP_DIR = "/tmp/fsgamer_%i/"
 def tmp_file_path(path):
     return os.path.join(TMP_DIR%os.getuid(), path)
 
 
 
 class ShellRun:
-    TMP_DIR = "/tmp/%i/fsgamer/shell_run/"
+    TMP_DIR = "/tmp/fsgamer_%i/run/"
     def __init__(self):
         self.processes = []
         self.defunct = []
             return
         self(script, replace=True)
 
-    def sh_from_script(self, script):
+    def sh_from_script(self, script, fake_shell=False):
         tmp_dir = self.TMP_DIR % os.getuid()
         script_text = "#!/bin/bash\n%s" % script
-        fn = "fsgamer_%i" % len(script)
+        fn = "%i.sh" % len(script)
         path = os.path.join(tmp_dir, fn)
+
+        # If we are just getting a name, and not actually writing it out
+        if fake_shell:
+            return path
+
         try:
             os.makedirs(tmp_dir)
             os.chmod(tmp_dir, 0777)
                                     shell=True,
                                     bufsize=-1)
             self.processes.append(process)
+            print "THESE ARE MY PROCESSES", self.processes
             return process
         else:
+            print "----------------------------------------------"
+            print path
+            print "=============================================="
+            print script
+            print "----------------------------------------------"
             os.execv(path, [path])
         #script_args = shlex.split(script)
         #return subprocess.Popen(script_args, shell=True, bufsize=-1)
 
     def which(self, cmd):
-        path = subprocess.check_output("which %s"%cmd, shell=True)
+        try:
+            path = subprocess.check_output("which %s"%cmd, shell=True)
+        except subprocess.CalledProcessError:
+            path = None
+
         if not path:
-            raise DependencyError("%s was not found" % cmd)
+            return path
         return path.strip()
 
     def get_processes(self):
 
 DistUtilsExtra.auto.setup(
     name='fsgamer',
-    version='0.1',
+    version='0.1.1',
     license='GPL-3',
     author='Michael Bethencourt',
     author_email='michaelpb@gmail.com',
-    description='Run games in separate X session',
+    description='Run games in separate X server',
     url='https://michaelb.org/fsgamer',
     cmdclass={'install': InstallAndUpdateDataDirectory}
     )