示例#1
0
        public void hide_others(Client client)
        {
            for (int i=0;i<clients.Count; i++) {
              Client c = (Client) clients[i];

              if (c.state == InternalState.NORMAL && c != client) hide (c);
            }
        }
示例#2
0
        public void maximize(Client client, bool full_screen)
        {
            if (full_screen)
              client.move_resize (0, 0, display.default_screen.width (),
            display.default_screen.height ());

            else
              client.move_resize (space);
        }
示例#3
0
 public void give_up_focus(Client client)
 {
     if (client == focus)
       set_focus (next_client_normal (client, true), false);
 }
示例#4
0
        public bool grant_preference(Client client)
        {
            if (client.class_hint == null) return false;

            String id = client.class_hint.res + ":";

            // no focus
            if (pref.no_focus (id)) client.state = InternalState.NO_FOCUS;

            // register
            int keysym = '0' + pref.register (id);
            if (keysym >= '0') {
              int keycode = display.input.keysym_to_keycode (keysym);
              client.register = keycode - display.input.min_keycode;
              registers [client.register] = client;
            }

            int max_width = display.default_screen.width ();
            int max_height = display.default_screen.height ();

            // position
            Rectangle r = pref.position (id);
            if (r != null) {
              // similar to geometry parameter processing in X toolkit
              r.x = (r.x + max_width) % max_width;
              r.y = (r.y + max_height) % max_height;
              client.move_resize (r);
              return true;		// user-specified position
            }

            return false;
        }
示例#5
0
        //throws NotFoundException
        public Puppet(String [] args)
            : base(args)
        {
            Preference.staticInit();

            print_event = option.booleann ("print-event",
              "dump all events for debug", false);

            space = option.rectangle ("space",
              "workspace for normal windows", pref.space ());

            about ("0.1", "puppet window manager",
              "Stephen Tse <*****@*****.**>",
              "http://escher.sourceforge.net/",
              "\nFor bindings, check http://escher.sourceforge.net/"
              + "current/doc/gnu/app/puppet/Puppet.html.");

            if (help_option) return;

            /**
             * addShutdownHook in IBM JDK 1.3 does not seem to work for processing
             * Control-C. It simply ignores TERM signal instead of calling shutdown
             * hooks and then exiting.
             */
            //     Runtime.getRuntime ().addShutdownHook (new Thread () {
            //       public void run () { System.err.println ("shutting down..."); }});

            root = display.default_root;
            Window.NONE.display = display; // for move pointer
            xtest = new XTest (display); // for press button
            registers = new Client [display.input.max_keycode
              - display.input.min_keycode];

            _mit_priority_colors = (Atom) Atom.intern (display, "_MIT_PRIORITY_COLORS");
            wm_change_state = (Atom) Atom.intern (display, "WM_CHANGE_STATE");
            wm_state = (Atom) Atom.intern (display, "WM_STATE");
            wm_colormap_windows = (Atom) Atom.intern (display, "WM_COLORMAP_WINDOWS");
            wm_protocols = (Atom) Atom.intern (display, "WM_PROTOCOLS");
            wm_take_focus = (Atom) Atom.intern (display, "WM_TAKE_FOCUS");
            wm_save_yourself = (Atom) Atom.intern (display, "WM_SAVE_YOURSELF");
            wm_delete_window = (Atom) Atom.intern (display, "WM_DELETE_WINDOW");
            sm_client_id = (Atom) Atom.intern (display, "SM_CLIENT_ID");
            wm_client_leader = (Atom) Atom.intern (display, "WM_CLIENT_LEADER");
            wm_window_role = (Atom) Atom.intern (display, "WM_WINDOW_ROLE");

            control_root_window ();
            scan_children ();

            focus = (Client) Client.intern (root.pointer ().child ());
            focus.set_input_focus ();

            grab_keybut ();
            Console.WriteLine ("Initialization completed.");

            while (!exit_now) read_and_dispatch_event ();
        }
示例#6
0
 public void deny_focus(Client client)
 {
     client.state = InternalState.NO_FOCUS;
     give_up_focus (client);
 }
示例#7
0
        /**
           * @see #next_client(Client, bool)
           */
        public Client next_client_same_class(Client from, bool reverse)
        {
            Client next = next_client_normal (from, reverse);
            if (next == null) return null; // prevent looping

            if (focus_base.class_hint != null
              && next.class_hint != null
              && focus_base.class_hint.class_Equals (next.class_hint))

              return next;

            return next_client_same_class (next, reverse); // recursive
        }
示例#8
0
        public void when_button_press(ButtonPress evt)
        {
            /* Because we are doing grabbing on root window, we should not check
             * <code>event.window()</code> since it always Equals to
             * {@link #root}. Instead, check <code>event.child()</code>.
             */
            bool control_down = (evt.state () & gnu.x11.Input.CONTROL_MASK) != 0;
            bool meta_down = (evt.state () & gnu.x11.Input.META_MASK) != 0;
            bool on_root = evt.child_id () == 0;

            if (meta_down && on_root) { // `lanuch-on-root'

            Process.Start (pref.launch_on_root ());

              return;
            }

            if (!meta_down && on_root) { // `pointer-root-focus'
              root.set_input_focus ();
              return;
            }

            Client client = (Client) Client.intern (display, evt.child_id ());
            if (client.early_unmapped || client.early_destroyed) return;
            if (!control_down) return;
            int button = evt.detail ();

            switch (button) {
            case gnu.x11.Input.BUTTON1:
              if (meta_down)            // `delete-window'
            client.delete ();

              else {                    // `focus-with-raise'
            // same as set_focus ()
            client.raise ();
            focus = client;
            focus.set_input_focus ();
            update_client_order (focus);
              }
              break;

            case gnu.x11.Input.BUTTON2:         // `focus-without-raise'
              focus = client;
              focus.set_input_focus ();
              update_client_order (focus);
              break;

            case gnu.x11.Input.BUTTON3:
              if (meta_down) client.kill (); // `kill-window'

              else {                    // `lower-behind'
            // give focus to some other window (under pointer)
            client.lower ();
            focus = (Client) Client.intern (root.pointer ().child ());
            focus.set_input_focus ();
            update_client_order (focus); // != client
              }
              break;
            }
        }
示例#9
0
        /**
           * @see #next_client(Client, bool)
           */
        public Client next_client_first_char(Client from, bool reverse,
    char c, bool all)
        {
            Client next = next_client (from, reverse);
            if (next == null) return null; // prevent looping

            bool state = all ?
              // no UNMAPPED
              next.state == InternalState.NORMAL | next.state == InternalState.HIDDEN | next.state == InternalState.NO_FOCUS
              : next.state == InternalState.NORMAL;

            if (next.class_hint != null) {
              String c1 = next.class_hint.res.Substring (0, 1);
              String c2 = new String(new char[]{c});

              if (state && next.class_hint.res.Length > 0
            && String.Compare(c1,c2,true)==0)

            return next;
            }

            return next_client_first_char (next, reverse, c, all); // recursive
        }
示例#10
0
 /**
    * @see #next_client(Client, bool)
    */
 public Client next_client_normal(Client from, bool reverse)
 {
     Client next = next_client (from, reverse);
     if (next == null) return null; // prevent looping
     if (next.state == InternalState.NORMAL) return next;
     return next_client_normal (next, reverse); // recursive
 }
示例#11
0
        /**
           * @see #next_client(Client, bool)
           */
        public Client next_client_different_class(Client from, 
    bool reverse)
        {
            Client next = next_client_normal (from, reverse);
            if (next == null) return null; // prevent looping

            /* Check if WM-CLASS of next window is different from all we have
             * processed so far since first pressing SUPER-TAB.
             *
             * Respect null res_class.
             */
            String res_class = "";
            if (next.class_hint != null) res_class = next.class_hint.res_class ();
            if (!focus_so_far.Contains (res_class)) {
              focus_so_far.Add (res_class);
              return next;
            }

            return next_client_different_class (next, reverse);	// recursive
        }
示例#12
0
        public Client next_client(Client from, bool reverse)
        {
            int index = clients.IndexOf (from);
            int n = clients.Count;

            // + n for no negative value
            // % n for cycle
            index = (reverse ? index-1+n : index+1+n) % n;

            Client next = (Client) clients[index];

            /* Detect looping.
             *
             * Case !focus_key_pressed: focus is always at the top of
             * clients, i.e., the end of the ArrayList. next == focus means we
             * are searching in a loop. We return null to signal it. Callers should
             * quit recursive searching, and return null to set_focus, which does
             * nothing (as search fails).
             *
             * Case focus_key_pressed: focus_base is the last active window.
             * Note orders of windows in clients stays constants during
             * focus_key_pressed, and thus focus cannot be used to detect
             * looping. next == focus_base means we are searching in a loop.
             * We return null to signal it. Callers should quit recursive
             * searching, and return null to set_focus, which, however, sets focus
             * to focus_base, to allow circular tabbing.
             *
             * Note that returning null (instead of focus_base) is critical in
             * next_* () methods as, say, next_client_normal () will be called by,
             * say, next_client_first_char (), returning null in next_client_normal
             * () prevents looping in next_client_first_char ().
             */
            if (focus_key_pressed && next == focus_base) return null;
            if (!focus_key_pressed && next == focus) return null;

            if (next.early_unmapped || next.early_destroyed)
              return next_client (next, reverse);
            else
              return next;
        }
示例#13
0
        public void minimize(Client client)
        {
            client.width = client.size_hints == null ||
              client.size_hints.min_width () == 0 ?
              client.width/2 : client.size_hints.min_width ();

            client.height = client.size_hints == null ||
              client.size_hints.min_height () == 0 ?
              client.height/2 : client.size_hints.min_height ();

            client.resize ();
            relocate (client);
        }
示例#14
0
        public void unhide(Client client)
        {
            if (client.state != InternalState.HIDDEN) return;

            /* Do not set client.state here. Do it right in
             * {@link #when_map_notify(MapNotify)}.
             */
            client.map ();
        }
示例#15
0
        // find another client of same res_name and res_class
        public void register_fall_back(Client client)
        {
            if (client.register == -1) return;
            Client fall_back = null;

            if (client.class_hint != null)
              for (int i=0;i<clients.Count;i++) {
            Client c = (Client) clients[i];

            if (c != client           // another!
              && c.class_hint.Equals (client.class_hint)
              && !c.early_unmapped && !c.early_destroyed) {

              fall_back = c;
              break;
            }
              }

            registers [client.register] = fall_back;
            client.register = -1;
        }
示例#16
0
 public void update_client_order(Client client)
 {
     clients.Remove (client);
     clients.Add (client);
 }
示例#17
0
        public void relocate(Client client)
        {
            int x_range = space.width - client.width;
            int y_range = space.height - client.height;

            if (x_range < 0) x_range = 0;
            if (y_range < 0) y_range = 0;

            client.x = x_range == 0 ? 0 : random.Next (x_range);
            client.y = y_range == 0 ? 0 : random.Next (y_range);

            // origin of space
            client.x += space.x;
            client.y += space.y;

            client.move ();
        }
示例#18
0
        public void when_key_press(KeyPress evt)
        {
            keycode = evt.detail ();
            int keystate = evt.state ();
            keysym = display.input.keycode_to_keysym (keycode, keystate);

            shift_down = (keystate & gnu.x11.Input.SHIFT_MASK) != 0;
            control_down = (keystate & gnu.x11.Input.CONTROL_MASK) != 0;
            meta_down = (keystate & gnu.x11.Input.META_MASK) != 0;
            alt_down = (keystate & gnu.x11.Input.ALT_MASK) != 0;
            base_down = (keystate & gnu.x11.Input.SUPER_MASK) != 0;

            if (!system_key_pressed && !focus_key_pressed) {
              int status = root.grab_keyboard (false, Window.ASYNCHRONOUS,
            Window.ASYNCHRONOUS, Display.CURRENT_TIME);
              if (status != Window.SUCCESS)
            throw new Exception ("Failed to grab keyboard");

              focus_key_pressed = keysym == Misc.TAB;
              system_key_pressed = !focus_key_pressed;
              if (system_key_pressed) return;

              // if tab (see #next_client)
              focus_base = focus;
              focus_so_far.Clear ();
              if (focus_base.class_hint != null)
            focus_so_far.Add (focus.class_hint.res_class ());
            }

            if (focus_key_pressed) {
              if (keysym == Misc.ESCAPE) { // abort-switch-focus
            focus_key_pressed = false;
            set_focus (focus_base, true);

              } else if (keysym ==  Misc.TAB)
            key_switch_focus ();

              return;
            }

            if (key_process ()) {       // done
              display.input.ungrab_keyboard ();
              system_key_pressed = false;
              prefix0 = prefix1 = 0;

              argument = 0;
              argument_negative = false;
              argument_present = false;
            }
        }
示例#19
0
 public void restore_size(Client client)
 {
     client.resize (client.saved_width, client.saved_height);
 }
示例#20
0
        public void client_to_register(Client client, int keycode)
        {
            int index = client.register = keycode - display.input.min_keycode;
            Client old = registers [index];

            if (old != null) old.register = -1;
            registers [index] = client;
        }
示例#21
0
 public void save_size(Client client)
 {
     client.saved_width = client.width;
     client.saved_height = client.height;
 }
示例#22
0
        public void focus_client_first_char(Client client, bool reverse,
    char c, bool all)
        {
            // support only alphabetic window class
            if (c < 'A' || c > 'z') return;

            Client next = next_client_first_char (client, reverse, c, all);
            if (next == null) alert_user ("Client not found: " + c);

            // possibly hidden and no-focus, as we search all windows
            // BUT do not grant focus, leave it as before
            if (all && next != null) unhide (next);

            set_focus (next, true);
        }
示例#23
0
        public void scale_size(Client client, double factor)
        {
            client.width = (int)(client.width*factor);
            client.height = (int)(client.height*factor);

            client.width = Math.Min (client.width, space.width);
            client.height = Math.Min (client.height, space.height);

            client.resize ();
            relocate (client);
        }
示例#24
0
 public void grant_focus(Client client)
 {
     if (client.state == InternalState.NO_FOCUS) client.state = InternalState.NORMAL;
 }
示例#25
0
        public void set_focus(Client client, bool warp_pointer)
        {
            /* Process return value from next_client_* () to prevent looping.
             *
             * Case 1 = !focus_key_pressed && client == null. next_client_* fails
             * to find a matching client. Operation aborts and this method simply
             * returns.
             *
             * Case 2 = focus_key_pressed && client == null. next_client_* detects
             * a cycle (start pressing TAB on client A, navigate all matching
             * clients, and come back to client A). Cycling operation restarts and
             * this method continues with client = focus_base.
             *
             * @see #next_client(Client, bool)
             * @see #focus_so_far
             */
            if (!focus_key_pressed && client == null) return;

            if (focus_key_pressed && client == null) {
              client = focus_base;
              focus_so_far.Clear ();
              if (focus_base.class_hint != null)
            focus_so_far.Add (focus_base.class_hint.res_class ());
            }

            client.raise ();		// we choose to do it
            focus = client;

            /* At this point, and only at this point, we are 100% sure that the
             * window is mapped and hence can be assigned focus to. Otherwise, an
             * {@link Error#BAD_WINDOW} will result.
             */
            focus.set_input_focus ();

            // give hint
            if (warp_pointer) client.warp_pointer (10, 10);

            /* For changing focus in focus_key_pressed mode, do not update client order
             * until the user decides which window to stay with and releases focus
             * key modifier.
             *
             * @see #when_key_release(KeyRelease)
             */
            if (!focus_key_pressed) update_client_order (focus);
        }
示例#26
0
        public void hide(Client client)
        {
            if (client.state == InternalState.HIDDEN) return;

            /* Set this state to give hint to {@link
             * #when_unmap_notify(UnmapNotify)}.
             *
             * <p>Do it before <code>client.unmap ()</code>.
             */
            client.state = InternalState.HIDDEN;
            client.set_wm_state (Window.WMState.ICONIC);

            client.unmap ();
            last_hide = client;
        }
示例#27
0
 public void toggle_focus(Client client)
 {
     if (client.state == InternalState.NORMAL)
       deny_focus (client);
     else if (client.state == InternalState.NO_FOCUS)
       grant_focus (client);
 }
示例#28
0
        public void hide_same_class(Client client)
        {
            for (int i=0;i<clients.Count; i++) {
              Client c = (Client) clients[i];

              if (c.state == InternalState.NORMAL
            && c.class_hint != null
            && c.class_hint.class_Equals (client.class_hint))

            hide (c);
            }
        }
示例#29
0
        public void manage(Client client)
        {
            if (!clients.Contains (client)) clients.Add (client);

            // ready for move and resize
            client.geometry ();

            // ready for next focus and preference
            client.class_hint = client.wm_class_hint ();

            // ready for minimize
            client.size_hints = client.wm_normal_hints ();

            // ready for info
            client.name = client.wm_name ();

            client.change_save_set (false);

            if (!grant_preference (client))
              // no position preference, do bounding box
              client.move_resize (client.rectangle ().within (space));
        }