Hi,
Just re-posting my old patches, re-based against the current tree.
As some of you might be interested in testing them.
Nathaniel, can you take a look and see if at least some of those can be
merged sooner rather than later. I think: move-common-parts is ok-ish.
"ignore-sendclientmessage" I think you said that was not used?
"conditional-pyrex" is no good (just useful for building without cygwin)
keyboard and clipboard patches are not for merging, we need to think of
a better way of abstracting this, and ideally support both on win32.
Patches may need to be applied them in this order:
patch -p1 < ../patch-queue/mswindows-move-common-parts.patch
patch -p1 < ../patch-queue/mswindows-conditional-pyrex.patch
patch -p1 < ../patch-queue/mswindows-ignore-sendclientmessage.patch
patch -p1 < ../patch-queue/mswindows-keyboard-not-impl.patch
patch -p1 < ../patch-queue/mswindows-cant-clipboard-asis.patch
Cheers
Antoine
--- parti-all-0.0.7-pre-vanilla/xpra/client.py 2009-04-03 08:29:09.000000000 +0200
+++ parti-all-0.0.7-pre/xpra/client.py 2009-05-04 21:46:45.430683756 +0200
@@ -8,6 +8,7 @@
import cairo
import os
import os.path
+import sys
from wimpiggy.util import (one_arg_signal,
gtk_main_quit_really,
@@ -19,7 +20,6 @@
from xpra.protocol import Protocol
from xpra.keys import mask_to_names
-from xpra.clipboard import ClipboardProtocolHelper
import xpra
default_capabilities = {"__prerelease_version": xpra.__version__}
@@ -284,7 +285,11 @@
self._keymap.connect("keys-changed", self._keys_changed)
self._keys_changed()
- self._clipboard_helper = ClipboardProtocolHelper(self.send)
+ if not sys.platform.startswith("win"):
+ from xpra.clipboard import ClipboardProtocolHelper
+ self._clipboard_helper = ClipboardProtocolHelper(self.send)
+ else:
+ self._clipboard_helper = None
self._focused = None
@@ -322,7 +327,8 @@
if capabilities.get("__prerelease_version") != xpra.__version__:
log.error("sorry, I only know how to talk to v%s servers",
xpra.__version__)
- self._clipboard_helper.send_all_tokens()
+ if self._clipboard_helper:
+ self._clipboard_helper.send_all_tokens()
def _process_new_common(self, packet, override_redirect):
(_, id, x, y, w, h, metadata) = packet
@@ -381,7 +387,8 @@
packet_type = packet[0]
if (isinstance(packet_type, str)
and packet_type.startswith("clipboard-")):
- self._clipboard_helper.process_clipboard_packet(packet)
+ if self._clipboard_helper:
+ self._clipboard_helper.process_clipboard_packet(packet)
else:
self._packet_handlers[packet_type](self, packet)
--- parti-all-0.0.6-as-sent/setup.py 2009-03-22 16:34:43.000000000 +0700
+++ parti-all-0.0.6-dev/setup.py 2009-03-22 22:33:47.000000000 +0700
@@ -15,8 +15,7 @@
from distutils.core import setup
from distutils.extension import Extension
-from Pyrex.Distutils import build_ext
-import commands, os
+import commands, os, sys
# Tweaked from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/502261
def pkgconfig(*packages, **kw):
@@ -53,6 +52,25 @@
xpra:
%s""" % (wimpiggy_desc, parti_desc, xpra_desc)
+if not sys.platform.startswith("win"):
+ from Pyrex.Distutils import build_ext
+ ext_modules=[
+ Extension("wimpiggy.lowlevel.bindings",
+ ["wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx"],
+ **pkgconfig("pygobject-2.0", "gdk-x11-2.0", "gtk+-x11-2.0",
+ "xtst", "xfixes", "xcomposite", "xdamage")
+ ),
+ Extension("xpra.wait_for_x_server",
+ ["xpra/xpra.wait_for_x_server.pyx"],
+ **pkgconfig("x11")
+ ),
+ ]
+ # Turn on Pyrex-sensitivity:
+ cmdclass = {'build_ext': build_ext}
+else:
+ ext_modules=None
+ cmdclass={}
+
setup(
name="parti-all",
author="Nathaniel Smith",
@@ -70,17 +88,6 @@
"scripts/xpra",
],
data_files = [("share/man/man1", ["xpra.1"])],
- ext_modules=[
- Extension("wimpiggy.lowlevel.bindings",
- ["wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx"],
- **pkgconfig("pygobject-2.0", "gdk-x11-2.0", "gtk+-x11-2.0",
- "xtst", "xfixes", "xcomposite", "xdamage")
- ),
- Extension("xpra.wait_for_x_server",
- ["xpra/xpra.wait_for_x_server.pyx"],
- **pkgconfig("x11")
- ),
- ],
- # Turn on Pyrex-sensitivity:
- cmdclass = {'build_ext': build_ext}
+ ext_modules=ext_modules,
+ cmdclass = cmdclass
)
--- parti-all-0.0.6-as-sent/wimpiggy/lowlevel/__init__.py 2009-03-22 16:36:19.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/lowlevel/__init__.py 2009-03-22 22:47:47.000000000 +0700
@@ -3,11 +3,15 @@
# Parti is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.
-from wimpiggy.lowlevel.bindings import *
from wimpiggy.log import Logger
log = Logger()
+sendClientMessage=pass
+if not sys.platform.startswith("win"):
+ sendClientMessage = wimpiggy.lowlevel.bindings.sendClientMessage
+
+
def send_wm_take_focus(target, time):
log("sending WM_TAKE_FOCUS")
sendClientMessage(target, False, 0,
--- parti-all-0.0.7-pre-vanilla/wimpiggy/keys.py 2009-05-04 22:16:03.490674000 +0200
+++ parti-all-0.0.7-pre/wimpiggy/keys.py 2009-05-04 21:53:56.770699185 +0200
@@ -7,13 +7,14 @@
import gtk
from wimpiggy.util import one_arg_signal
from wimpiggy.error import *
-from wimpiggy.lowlevel import (get_modifier_map, grab_key, ungrab_all_keys)
-
from wimpiggy.event import add_event_receiver, remove_event_receiver
from wimpiggy.util import get_display_for
from wimpiggy.log import Logger
log = Logger()
+get_modifier_map = None
+grab_key = None
+ungrab_all_keys = None
class HotkeyManager(gobject.GObject):
__gsignals__ = {
"hotkey": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_DETAILED,
@@ -26,6 +27,13 @@
gobject.GObject.__init__(self)
self.window = window
self.hotkeys = {}
+ if not sys.platform.startswith("win"):
+ global get_modifier_map
+ global grab_key
+ global ungrab_all_keys
+ get_modifier_map = wimpiggy.lowlevel.get_modifier_map
+ grab_key = wimpiggy.lowlevel.grab_key
+ ungrab_all_keys = wimpiggy.lowlevel.ungrab_all_keys
disp = get_display_for(self.window)
self.keymap = gtk.gdk.keymap_get_for_display(disp)
@@ -61,7 +69,8 @@
gtk.gdk.x11_ungrab_server()
def _unbind_all(self):
- ungrab_all_keys(self.window)
+ if ungrab_all_keys:
+ ungrab_all_keys(self.window)
def _bind_all(self):
self.normalized_hotkeys = {}
@@ -71,8 +80,9 @@
for keycode in keycodes:
# Claim a passive grab on all the different forms of this key
for nuisance_mask in self.nuisances:
- grab_key(self.window, keycode,
- modifier_mask | nuisance_mask)
+ if grab_key:
+ grab_key(self.window, keycode,
+ modifier_mask | nuisance_mask)
# Save off the normalized form to make it easy to lookup later
# when we see the key appear
unparsed = unparse_key(modifier_mask, keycode,
@@ -134,21 +144,22 @@
}
disp = get_display_for(display_source)
- (max_keypermod, keycodes) = get_modifier_map(disp)
- assert len(keycodes) == 8 * max_keypermod
- keymap = gtk.gdk.keymap_get_for_display(disp)
- for i in range(8):
- for j in range(max_keypermod):
- keycode = keycodes[i * max_keypermod + j]
- if keycode:
- entries = keymap.get_entries_for_keycode(keycode)
- if entries is None:
- # This keycode has no entry in the keymap:
- continue
- for (keyval, _, _, _) in entries:
- keyval_name = gtk.gdk.keyval_name(keyval)
- if keyval_name in meanings:
- modifier_map[meanings[keyval_name]] |= (1 << i)
+ if get_modifier_map:
+ (max_keypermod, keycodes) = get_modifier_map(disp)
+ assert len(keycodes) == 8 * max_keypermod
+ keymap = gtk.gdk.keymap_get_for_display(disp)
+ for i in range(8):
+ for j in range(max_keypermod):
+ keycode = keycodes[i * max_keypermod + j]
+ if keycode:
+ entries = keymap.get_entries_for_keycode(keycode)
+ if entries is None:
+ # This keycode has no entry in the keymap:
+ continue
+ for (keyval, _, _, _) in entries:
+ keyval_name = gtk.gdk.keyval_name(keyval)
+ if keyval_name in meanings:
+ modifier_map[meanings[keyval_name]] |= (1 << i)
modifier_map["nuisance"] = (modifier_map["lock"]
| modifier_map["scroll"]
| modifier_map["num"])
diff -urN parti-all-0.0.6-vanilla/wimpiggy/composite.py parti-all-0.0.6-dev/wimpiggy/composite.py
--- parti-all-0.0.6-vanilla/wimpiggy/composite.py 2009-03-22 16:35:46.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/composite.py 2009-03-22 20:03:35.000000000 +0700
@@ -12,9 +12,9 @@
xcomposite_name_window_pixmap,
xdamage_start, xdamage_stop,
xdamage_acknowledge,
- add_event_receiver, remove_event_receiver,
get_parent, addXSelectInput, const,
geometry_with_border)
+from wimpiggy.event import add_event_receiver, remove_event_receiver
from wimpiggy.log import Logger
log = Logger()
diff -urN parti-all-0.0.6-vanilla/wimpiggy/event.py parti-all-0.0.6-dev/wimpiggy/event.py
--- parti-all-0.0.6-vanilla/wimpiggy/event.py 1970-01-01 07:00:00.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/event.py 2009-03-22 19:47:27.000000000 +0700
@@ -0,0 +1,45 @@
+# This file is part of Parti.
+# Copyright (C) 2008, 2009 Nathaniel Smith <[email protected]>
+# Parti is released under the terms of the GNU GPL v2, or, at your option, any
+# later version. See the file COPYING for details.
+
+import types
+import gobject
+from wimpiggy.log import Logger
+log = Logger()
+
+_ev_receiver_key = "wimpiggy-route-events-to"
+def add_event_receiver(window, receiver):
+ receivers = window.get_data(_ev_receiver_key)
+ if receivers is None:
+ receivers = set()
+ if receiver not in receivers:
+ receivers.add(receiver)
+ window.set_data(_ev_receiver_key, receivers)
+
+def remove_event_receiver(window, receiver):
+ receivers = window.get_data(_ev_receiver_key)
+ if receivers is None:
+ return
+ receivers.discard(receiver)
+ if not receivers:
+ receivers = None
+ window.set_data(_ev_receiver_key, receivers)
+
+def _maybe_send_event(window, signal, event):
+ handlers = window.get_data(_ev_receiver_key)
+ if handlers is not None:
+ # Copy the 'handlers' list, because signal handlers might cause items
+ # to be added or removed from it while we are iterating:
+ for handler in list(handlers):
+ if signal in gobject.signal_list_names(handler):
+ log(" forwarding event to a %s handler's %s signal",
+ type(handler).__name__, signal)
+ handler.emit(signal, event)
+ log(" forwarded")
+ else:
+ log(" not forwarding to %s handler, it has no %s signal",
+ type(handler).__name__, signal)
+ else:
+ log(" no handler registered for this window, ignoring event")
+
diff -urN parti-all-0.0.6-vanilla/wimpiggy/keys.py parti-all-0.0.6-dev/wimpiggy/keys.py
--- parti-all-0.0.6-vanilla/wimpiggy/keys.py 2009-03-22 16:35:58.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/keys.py 2009-03-22 19:57:37.000000000 +0700
@@ -7,10 +7,10 @@
import gtk
from wimpiggy.util import one_arg_signal
from wimpiggy.error import *
-from wimpiggy.lowlevel import (get_display_for,
- get_modifier_map, grab_key, ungrab_all_keys,
- add_event_receiver, remove_event_receiver)
+from wimpiggy.lowlevel import (get_modifier_map, grab_key, ungrab_all_keys)
+from wimpiggy.event import add_event_receiver, remove_event_receiver
+from wimpiggy.util import get_display_for
from wimpiggy.log import Logger
log = Logger()
diff -urN parti-all-0.0.6-vanilla/wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx parti-all-0.0.6-dev/wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx
--- parti-all-0.0.6-vanilla/wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx 2009-03-22 16:36:25.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx 2009-03-22 20:02:49.000000000 +0700
@@ -14,7 +14,8 @@
import gtk
import gtk.gdk
-from wimpiggy.util import dump_exc, LameStruct, gtk_main_quit_really
+from wimpiggy.util import dump_exc, LameStruct, gtk_main_quit_really, get_display_for
+from wimpiggy.event import _maybe_send_event
from wimpiggy.error import trap, XError
from wimpiggy.log import Logger
@@ -336,16 +337,6 @@
raise XError, BadWindow
return win
-def get_display_for(obj):
- if isinstance(obj, gtk.gdk.Display):
- return obj
- elif isinstance(obj, (gtk.gdk.Drawable,
- gtk.Widget,
- gtk.Clipboard)):
- return obj.get_display()
- else:
- raise TypeError, "Don't know how to get a display from %r" % (obj,)
-
cdef cGdkDisplay * get_raw_display_for(obj) except? NULL:
return <cGdkDisplay*> unwrap(get_display_for(obj), gtk.gdk.Display)
@@ -1125,41 +1116,6 @@
# client that owns the window they are sent to, otherwise they go to any
# clients that are selecting for that mask they are sent with.
-_ev_receiver_key = "wimpiggy-route-events-to"
-def add_event_receiver(window, receiver):
- receivers = window.get_data(_ev_receiver_key)
- if receivers is None:
- receivers = set()
- if receiver not in receivers:
- receivers.add(receiver)
- window.set_data(_ev_receiver_key, receivers)
-
-def remove_event_receiver(window, receiver):
- receivers = window.get_data(_ev_receiver_key)
- if receivers is None:
- return
- receivers.discard(receiver)
- if not receivers:
- receivers = None
- window.set_data(_ev_receiver_key, receivers)
-
-def _maybe_send_event(window, signal, event):
- handlers = window.get_data(_ev_receiver_key)
- if handlers is not None:
- # Copy the 'handlers' list, because signal handlers might cause items
- # to be added or removed from it while we are iterating:
- for handler in list(handlers):
- if signal in gobject.signal_list_names(handler):
- log(" forwarding event to a %s handler's %s signal",
- type(handler).__name__, signal)
- handler.emit(signal, event)
- log(" forwarded")
- else:
- log(" not forwarding to %s handler, it has no %s signal",
- type(handler).__name__, signal)
- else:
- log(" no handler registered for this window, ignoring event")
-
def _route_event(event, signal, parent_signal):
# Sometimes we get GDK events with event.window == None, because they are
# for windows we have never created a GdkWindow object for, and GDK
diff -urN parti-all-0.0.6-vanilla/wimpiggy/prop.py parti-all-0.0.6-dev/wimpiggy/prop.py
--- parti-all-0.0.6-vanilla/wimpiggy/prop.py 2009-03-22 16:36:30.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/prop.py 2009-03-22 19:53:12.000000000 +0700
@@ -16,7 +16,7 @@
from wimpiggy.lowlevel import \
XGetWindowProperty, XChangeProperty, PropertyError, \
get_xatom, get_pyatom, get_xwindow, get_pywindow, const, \
- get_display_for, premultiply_argb_in_place
+ premultiply_argb_in_place
from wimpiggy.error import trap, XError
from wimpiggy.log import Logger
log = Logger()
diff -urN parti-all-0.0.6-vanilla/wimpiggy/selection.py parti-all-0.0.6-dev/wimpiggy/selection.py
--- parti-all-0.0.6-vanilla/wimpiggy/selection.py 2009-03-22 16:36:36.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/selection.py 2009-03-22 19:59:57.000000000 +0700
@@ -15,8 +15,8 @@
from wimpiggy.util import no_arg_signal, one_arg_signal
from wimpiggy.lowlevel import (get_xatom, get_pywindow, sendClientMessage,
- myGetSelectionOwner, const,
- add_event_receiver, remove_event_receiver)
+ myGetSelectionOwner, const)
+from wimpiggy.event import add_event_receiver, remove_event_receiver
from wimpiggy.error import *
from wimpiggy.log import Logger
diff -urN parti-all-0.0.6-vanilla/wimpiggy/test_selection.py parti-all-0.0.6-dev/wimpiggy/test_selection.py
--- parti-all-0.0.6-vanilla/wimpiggy/test_selection.py 2009-03-22 16:36:56.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/test_selection.py 2009-03-22 20:00:28.000000000 +0700
@@ -6,6 +6,7 @@
from wimpiggy.test import *
from wimpiggy.selection import ManagerSelection, AlreadyOwned
import wimpiggy.lowlevel
+from wimpiggy.event import add_event_receiver
import struct
@@ -46,7 +47,7 @@
d2 = self.clone_display()
root2 = d2.get_default_screen().get_root_window()
root2.set_events(gtk.gdk.STRUCTURE_MASK)
- wimpiggy.lowlevel.add_event_receiver(root2, self)
+ add_event_receiver(root2, self)
d2.flush()
self.event = None
diff -urN parti-all-0.0.6-vanilla/wimpiggy/util.py parti-all-0.0.6-dev/wimpiggy/util.py
--- parti-all-0.0.6-as-sent/wimpiggy/util.py 2009-03-22 20:07:53.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/util.py 2009-03-22 21:35:48.000000000 +0700
@@ -7,6 +7,7 @@
import sys
import types
import gobject
+import gtk
class AutoPropGObjectMixin(object):
"""Mixin for automagic property support in GObjects.
--- parti-all-0.0.6-vanilla/wimpiggy/util.py 2009-03-22 16:37:05.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/util.py 2009-03-22 19:48:09.000000000 +0700
@@ -60,6 +60,16 @@
one_arg_signal = n_arg_signal(1)
+def get_display_for(obj):
+ if isinstance(obj, gtk.gdk.Display):
+ return obj
+ elif isinstance(obj, (gtk.gdk.Drawable,
+ gtk.Widget,
+ gtk.Clipboard)):
+ return obj.get_display()
+ else:
+ raise TypeError, "Don't know how to get a display from %r" % (obj,)
+
# Collects the results from signal handlers for a given signal into a list,
# ignoring all handlers that return None. (This filtering is useful because
# the intended use of this method is to "poll" all connected objects, so it's
diff -urN parti-all-0.0.6-vanilla/wimpiggy/window.py parti-all-0.0.6-dev/wimpiggy/window.py
--- parti-all-0.0.6-vanilla/wimpiggy/window.py 2009-03-22 16:37:10.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/window.py 2009-03-22 19:59:27.000000000 +0700
@@ -20,6 +20,8 @@
from wimpiggy.util import (AutoPropGObjectMixin,
one_arg_signal, n_arg_signal,
non_none_list_accumulator)
+from wimpiggy.event import add_event_receiver, remove_event_receiver
+from wimpiggy.util import get_display_for
from wimpiggy.error import *
from wimpiggy.prop import prop_get, prop_set
from wimpiggy.composite import CompositeHelper
@@ -214,7 +216,7 @@
self.client_window = client_window
self._internal_set_property("client-window", client_window)
- wimpiggy.lowlevel.add_event_receiver(client_window, self)
+ add_event_receiver(client_window, self)
def setup():
# Keith Packard says that composite state is undefined following a
@@ -256,7 +258,7 @@
self.emit("unmanaged", exiting)
def do_unmanaged(self, wm_exiting):
- wimpiggy.lowlevel.remove_event_receiver(self.client_window, self)
+ remove_event_receiver(self.client_window, self)
self._composite.disconnect(self._damage_forward_handle)
self._composite.destroy()
@@ -419,7 +421,7 @@
wclass=gtk.gdk.INPUT_OUTPUT,
event_mask=gtk.gdk.PROPERTY_CHANGE_MASK)
wimpiggy.lowlevel.substructureRedirect(self.corral_window)
- wimpiggy.lowlevel.add_event_receiver(self.corral_window, self)
+ add_event_receiver(self.corral_window, self)
log("created corral window 0x%x", self.corral_window.xid)
# The WM_HINTS input field
@@ -686,7 +688,7 @@
# actually display-clean. Oh well.
pixmap = gtk.gdk.Pixmap(None,
surf.get_width(), surf.get_height(), 32)
- screen = wimpiggy.lowlevel.get_display_for(pixmap).get_default_screen()
+ screen = get_display_for(pixmap).get_default_screen()
pixmap.set_colormap(screen.get_rgba_colormap())
cr = pixmap.cairo_create()
cr.set_source_surface(surf)
diff -urN parti-all-0.0.6-vanilla/wimpiggy/wm.py parti-all-0.0.6-dev/wimpiggy/wm.py
--- parti-all-0.0.6-vanilla/wimpiggy/wm.py 2009-03-22 16:37:13.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/wm.py 2009-03-22 19:58:18.000000000 +0700
@@ -14,6 +14,7 @@
import wimpiggy.lowlevel
from wimpiggy.prop import prop_set
from wimpiggy.util import no_arg_signal, one_arg_signal
+from wimpiggy.event import add_event_receiver
from wimpiggy.window import WindowModel, Unmanageable
@@ -177,7 +178,7 @@
# Okay, ready to select for SubstructureRedirect and then load in all
# the existing clients.
- wimpiggy.lowlevel.add_event_receiver(self._root, self)
+ add_event_receiver(self._root, self)
wimpiggy.lowlevel.substructureRedirect(self._root)
for w in wimpiggy.lowlevel.get_children(self._root):
diff -urN parti-all-0.0.6-vanilla/xpra/server.py parti-all-0.0.6-dev/xpra/server.py
--- parti-all-0.0.6-vanilla/xpra/server.py 2009-03-22 16:44:21.000000000 +0700
+++ parti-all-0.0.6-dev/xpra/server.py 2009-03-22 20:04:19.000000000 +0700
@@ -25,8 +25,8 @@
xtest_fake_key,
xtest_fake_button,
is_override_redirect, is_mapped,
- add_event_receiver,
get_children)
+from wimpiggy.event import add_event_receiver
from wimpiggy.window import OverrideRedirectWindowModel, Unmanageable
from wimpiggy.keys import grok_modifier_map
from wimpiggy.error import XError, trap
_______________________________________________
Parti-discuss mailing list
[email protected]
http://lists.partiwm.org/cgi-bin/mailman/listinfo/parti-discuss