Commits

Anonymous committed 5f74e5e

fixes #1 -- Also adds advanced options

  • Participants
  • Parent commits 28dabf5

Comments (0)

Files changed (6)

File data/ui/AboutFsgamerDialog.ui

 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
+  <!-- interface-requires gtk+ 3.0 -->
   <!-- interface-requires about_fsgamer_dialog 1.0 -->
-  <!-- interface-requires gtk+ 3.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.1</property>
+    <property name="version">version 0.2</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>

File data/ui/FsgamerWindow.ui

   <!-- interface-requires fsgamer_window 1.0 -->
   <!-- interface-local-resource-path ../media -->
   <object class="GtkAction" id="action1"/>
+  <object class="GtkAction" id="action2"/>
   <object class="FsgamerWindow" id="fsgamer_window">
     <property name="can_focus">False</property>
     <property name="title" translatable="yes">Fsgamer</property>
-    <property name="resizable">False</property>
     <property name="icon">../media/fsgamer.svg</property>
     <child>
       <object class="GtkVBox" id="vbox1">
         </child>
         <child>
           <object class="GtkPaned" id="paned1">
-            <property name="width_request">751</property>
+            <property name="width_request">780</property>
             <property name="height_request">408</property>
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="margin_right">10</property>
             <property name="margin_top">10</property>
             <property name="margin_bottom">10</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <property name="position">240</property>
             <child>
               <object class="GtkBox" id="box1">
                 <property name="visible">True</property>
                 <property name="orientation">vertical</property>
                 <child>
                   <object class="GtkScrolledWindow" id="scrolledwindow1">
-                    <property name="height_request">360</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
                     <property name="shadow_type">in</property>
                     <child>
                       <object class="GtkIconView" id="iconview">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="border_width">5</property>
+                        <property name="hscroll_policy">natural</property>
+                        <property name="item_orientation">horizontal</property>
                         <property name="columns">1</property>
+                        <property name="column_spacing">1</property>
                         <signal name="selection-changed" handler="on_selection_changed" swapped="no"/>
                       </object>
                     </child>
                                 <property name="can_focus">False</property>
                                 <property name="xpad">20</property>
                                 <property name="ypad">20</property>
-                                <property name="pixbuf">playbutton_triangle.png</property>
+                                <property name="pixbuf">playbutton2.png</property>
                                 <property name="icon-size">6</property>
                               </object>
                             </child>
                         <property name="xalign">0</property>
                         <property name="yalign">0</property>
                         <property name="xpad">20</property>
-                        <property name="ypad">20</property>
+                        <property name="ypad">15</property>
                         <property name="label" translatable="yes">Application is now configured to run fullscreen with FS Gamer. Start it by clicking the ludicrously large button to the right.</property>
                         <property name="justify">fill</property>
                         <property name="wrap">True</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <child>
-                      <object class="GtkGrid" id="grid1">
+                      <object class="GtkBox" id="box3">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkLabel" id="label1">
+                          <object class="GtkGrid" id="grid1">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="xalign">0</property>
-                            <property name="yalign">0</property>
-                            <property name="xpad">15</property>
-                            <property name="label" translatable="yes">Use alternate xorg conf file:</property>
+                            <property name="hexpand">True</property>
+                            <property name="vexpand">True</property>
+                            <property name="row_spacing">3</property>
+                            <property name="column_homogeneous">True</property>
+                            <child>
+                              <object class="GtkLabel" id="label1">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</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>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">0</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label_0">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">1</property>
+                                <property name="xpad">10</property>
+                                <property name="label" translatable="yes">Script to run before xinit:</property>
+                                <property name="justify">right</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">1</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label_1">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0.99000000953674316</property>
+                                <property name="xpad">10</property>
+                                <property name="label" translatable="yes">Script to run in new X server:</property>
+                                <property name="justify">right</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">2</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label3">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">1</property>
+                                <property name="yalign">0</property>
+                                <property name="xpad">10</property>
+                                <property name="label" translatable="yes">Extra OpenBox configuration:</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">3</property>
+                                <property name="width">1</property>
+                                <property name="height">1</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>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="top_attach">1</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkEntry" id="option_xserver_script">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="invisible_char">•</property>
+                                <property name="invisible_char_set">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="top_attach">2</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkEntry" id="option_openbox_config">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="invisible_char">•</property>
+                                <property name="invisible_char_set">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="top_attach">3</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
-                            <property name="left_attach">0</property>
-                            <property name="top_attach">0</property>
-                            <property name="width">1</property>
-                            <property name="height">1</property>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="option_xorg_conf">
+                          <object class="GtkExpander" id="options_preview_expander">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
-                            <property name="invisible_char">•</property>
-                            <signal name="changed" handler="on_options_change" swapped="no"/>
+                            <property name="margin_left">20</property>
+                            <property name="margin_right">20</property>
+                            <child>
+                              <object class="GtkBox" id="box4">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkFrame" id="frame1">
+                                    <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>
+                                    <child>
+                                      <object class="GtkAlignment" id="alignment1">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="left_padding">12</property>
+                                        <child>
+                                          <object class="GtkScrolledWindow" id="scrolledwindow4">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="shadow_type">in</property>
+                                            <child>
+                                              <object class="GtkViewport" id="viewport1">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <child>
+                                                  <object class="GtkLabel" id="preview_options_xinit">
+                                                    <property name="visible">True</property>
+                                                    <property name="can_focus">False</property>
+                                                    <property name="xalign">0</property>
+                                                    <property name="yalign">0</property>
+                                                    <property name="xpad">10</property>
+                                                    <property name="ypad">10</property>
+                                                    <property name="label" translatable="yes">label</property>
+                                                    <attributes>
+                                                      <attribute name="font-desc" value="Monospace 8"/>
+                                                    </attributes>
+                                                  </object>
+                                                </child>
+                                              </object>
+                                            </child>
+                                          </object>
+                                        </child>
+                                      </object>
+                                    </child>
+                                    <child type="label">
+                                      <object class="GtkLabel" id="label2">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="label" translatable="yes">Script to launch the X server:</property>
+                                        <property name="use_markup">True</property>
+                                        <attributes>
+                                          <attribute name="weight" value="bold"/>
+                                        </attributes>
+                                      </object>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">True</property>
+                                    <property name="fill">True</property>
+                                    <property name="padding">5</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkFrame" id="frame2">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="halign">start</property>
+                                    <property name="label_xalign">0</property>
+                                    <child>
+                                      <object class="GtkAlignment" id="alignment2">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="left_padding">12</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>
+                                            <child>
+                                              <object class="GtkViewport" id="viewport2">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <child>
+                                                  <object class="GtkLabel" id="preview_options_xserver">
+                                                    <property name="visible">True</property>
+                                                    <property name="can_focus">False</property>
+                                                    <property name="xalign">0</property>
+                                                    <property name="yalign">0</property>
+                                                    <property name="xpad">10</property>
+                                                    <property name="ypad">10</property>
+                                                    <property name="label" translatable="yes">label</property>
+                                                    <attributes>
+                                                      <attribute name="font-desc" value="Monospace 8"/>
+                                                    </attributes>
+                                                  </object>
+                                                </child>
+                                              </object>
+                                            </child>
+                                          </object>
+                                        </child>
+                                      </object>
+                                    </child>
+                                    <child type="label">
+                                      <object class="GtkLabel" id="label5">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="label" translatable="yes">Script run in new X server:</property>
+                                        <property name="use_markup">True</property>
+                                        <attributes>
+                                          <attribute name="weight" value="bold"/>
+                                        </attributes>
+                                      </object>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="padding">5</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                            </child>
+                            <child type="label">
+                              <object class="GtkLabel" id="expander_10">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">Preview scripts</property>
+                              </object>
+                            </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>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="padding">14</property>
+                            <property name="position">2</property>
                           </packing>
                         </child>
                       </object>

File data/ui/playbutton2.png

Added
New image

File fsgamer/FsgamerWindow.py

 OPTION_DEFAULTS = {
     'notifications_tts': False,
     'xorg_conf': '',
+    'before_script': '',
+    'xserver_script': '',
+    'openbox_config': '',
 }
 
 NO_APP_INSTRUCTIONS = """
 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 ")
+""".replace("y\n", "y ").strip()
 
 
+def get_buffer_for_widget(widget):
+    if hasattr(widget, 'get_text'):
+        return widget
+    else:
+        return widget.get_buffer()
+
 
 # See fsgamer_lib.Window.py for more details about how this class works
 class FsgamerWindow(Window):
     __gtype_name__ = "FsgamerWindow"
-    
+
     def finish_initializing(self, builder): # pylint: disable=E1002
         """Set up the main window"""
         super(FsgamerWindow, self).finish_initializing(builder)
             name = "option_" + key
             widget = getattr(self.ui, name)
 
-            widget.handler_block_by_func(self.on_options_change)
+            try:
+                widget.handler_block_by_func(self.on_options_change)
+            except TypeError as e:
+                pass
 
             if isinstance(default_val, bool):
                 widget.set_active(val)
             elif isinstance(default_val, basestring):
-                widget.set_text(val)
+                w = get_buffer_for_widget(widget)
+                w.set_text(val)
 
-            widget.handler_unblock_by_func(self.on_options_change)
+            try:
+                widget.handler_unblock_by_func(self.on_options_change)
+            except TypeError as e:
+                pass
+
+            self.refresh_script_previews()
 
 
     def on_options_change(self, widget, data=None):
             if isinstance(default_val, bool):
                 val = widget.get_active()
             elif isinstance(default_val, basestring):
-                val = widget.get_text().strip()
+                w = get_buffer_for_widget(widget)
+                val = w.get_text().strip()
             print "key , val", key, val
 
             if val != default_val:
                 if key in self.current_app.opts:
                     del self.current_app.opts[key]
 
+            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()
+        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)
 
     def on_check_show_menu_icon_toggled(self, widget, data=None):
         if self.current_app:

File fsgamer/fsgamer_app.py

         # Run outer:
         self.process = utils.shell_run(e, replace=True)
 
+    def get_exec_opts(self):
+        if self.command:
+            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()
+
+        if self.opts.get('xserver_script', '').strip():
+            inner_script = "%s &\n%s" % (e, self.opts['xserver_script'].strip())
+
+            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)
+
+        return script
+
+
     def run(self):
         """
         Runs application on the other desktop (without GUI)
         if self.process:
             return
 
-        if self.command:
-            e = self.command
-        else:
-            e = self.desktop.getExec()
+        script = self.get_xinit_fsgwm()
 
         # This is the key function that actually runs this command in a
         # separate xsession
-        self.process = utils.shell_run.xinit_fsgwm(e, self.opts)
+        self.process = utils.shell_run(script)
 
     def kill(self):
         """

File fsgamer/utils.py

             'xinit': xinit,
             'display': 1,
             'cmd': cmd.strip(),
+            'extra': '',
         }
 
         if opts.get('xorg_conf'):
-            if not os.path.exists(opts['xorg_conf']):
-                print "ERROR: Xorg conf specified does not exist: ", opts['xorg_conf']
-                sys.exit(1)
+            #if not os.path.exists(opts['xorg_conf']):
+            #    print "ERROR: Xorg conf specified does not exist: ", opts['xorg_conf']
+            #    sys.exit(1)
             d['extra'] = '-xf86config %s' % quote(opts['xorg_conf'])
 
         # Wrap script
 
         return unparse_options(d)
 
+    @staticmethod
+    def xinit_fsgwm(cmd, opts):
+        """
+        This is the main function where all the magic is:
 
-TMP_DIR = "/tmp/fsgamer/"
+        It runs (blocking) a command using the FSGamer windows manager in a new
+        xinit buffer wrapped around ck-launch-session, passing to the windows
+        manager (via JSON) the dictionary of opts
+        """
+        script = []
+
+        if opts.get('notifications_tts'):
+            # 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) + " &")
+
+        script.append(
+                shellbuilder.xinit(shellbuilder.fsgwm(cmd, opts), opts)
+            )
+
+        return "\n".join(script)
+        #return self("\n".join(script))
+        #return subprocess.Popen(script_args, shell=True, bufsize=-1)
+
+
+TMP_DIR = "/tmp/%i/fsgamer/"
 def tmp_file_path(path):
-    return os.path.join(TMP_DIR, path)
+    return os.path.join(TMP_DIR%os.getuid(), path)
 
 def write_tmp_file(path, data):
-    path = os.path.join(TMP_DIR, path)
+    path = os.path.join(TMP_DIR%os.getuid(), path)
     dirpath = os.path.dirname(path)
     try:
         os.makedirs(dirpath)
+        os.chmod(dirpath, 0777)
     except OSError:
         pass
 
 
 
 class ShellRun:
-    TMP_DIR = "/tmp/fsgamer/shell_run/"
+    TMP_DIR = "/tmp/%i/fsgamer/shell_run/"
     def __init__(self):
         self.processes = []
         self.defunct = []
         self(script, replace=True)
 
     def sh_from_script(self, script):
+        tmp_dir = self.TMP_DIR % os.getuid()
         script_text = "#!/bin/bash\n%s" % script
         fn = "fsgamer_%i" % len(script)
-        path = os.path.join(self.TMP_DIR, fn)
+        path = os.path.join(tmp_dir, fn)
         try:
-            os.makedirs(self.TMP_DIR)
+            os.makedirs(tmp_dir)
+            os.chmod(tmp_dir, 0777)
         except OSError:
             pass
 
                 return
             time.sleep(3)
 
-    def xinit_fsgwm(self, cmd, opts):
-        """
-        This is the main function where all the magic is:
-
-        It runs (blocking) a command using the FSGamer windows manager in a new
-        xinit buffer wrapped around ck-launch-session, passing to the windows
-        manager (via JSON) the dictionary of opts
-        """
-        script = []
-
-        if opts.get('notifications_tts'):
-            # 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) + " &")
-
-        script.append(
-                shellbuilder.xinit(shellbuilder.fsgwm(cmd, opts), opts)
-            )
-
-        return self("\n".join(script))
-        #return subprocess.Popen(script_args, shell=True, bufsize=-1)
-
 shell_run = ShellRun()
 
 def unparse_options(dct, command=None, use_equals=True):