--- a/XWorkstation.st Wed Sep 03 10:39:40 2008 +0200
+++ b/XWorkstation.st Fri Sep 12 20:42:11 2008 +0200
@@ -2808,125 +2808,128 @@
(msgType := self atomIDOf:#DndProtocol) notNil ifTrue:[
- "/ DND can drop files, file, dir, links, dirLink and text
- "/ check for this.
-
- dropObjects isCollection ifFalse:[
- dropColl := Array with:dropObjects
- ] ifTrue:[
- dropColl := dropObjects
- ].
- anyFile := anyDir := anyText := anyOther := false.
- dropColl do:[:aDropObject |
- aDropObject isFileObject ifTrue:[
- aDropObject theObject isDirectory ifTrue:[
- anyDir := true
- ] ifFalse:[
- anyFile := true
- ]
- ] ifFalse:[
- aDropObject isTextObject ifTrue:[
- anyText := true
- ] ifFalse:[
- anyOther := true
- ]
- ]
- ].
-
- anyOther ifTrue:[
- "/ DND does not support this ...
- 'XWorkstation [info]: DND can only drop files or text' infoPrintCR.
- ^ false
- ].
- anyText ifTrue:[
- (anyFile or:[anyDir]) ifTrue:[
- "/ DND does not support mixed types
- 'XWorkstation [info]: DND cannot drop both files and text' infoPrintCR.
- ^ false
- ]
- ].
-
- dropCollSize := dropColl size.
- anyFile ifTrue:[
- dropType := #DndFiles.
- dropCollSize == 1 ifTrue:[
- dropType := #DndFile
- ]
- ] ifFalse:[
- anyDir ifTrue:[
- dropType := #DndFiles.
- dropCollSize == 1 ifTrue:[
- dropType := #DndDir
- ]
- ] ifFalse:[
- anyText ifTrue:[
- dropCollSize == 1 ifTrue:[
- dropType := #DndText
- ] ifFalse:[
- "/ can only drop a single text object
- 'XWorkstation [info]: DND can only drop a single text' infoPrintCR.
- ^ false
- ]
- ] ifFalse:[
- "/ mhmh ...
- 'XWorkstation [info]: DND cannot drop this' infoPrintCR.
- ^ false
- ]
- ]
- ].
-
- dropTypeCode := self dndDropTypes indexOf:dropType.
- dropTypeCode == 0 ifTrue:[
- 'XWorkstation [info]: DND cannot drop this' infoPrintCR.
- ^ false
- ].
- dropTypeCode := dropTypeCode - 1.
-
-
- "/ place the selection inTo the DndSelection property
- "/ of the rootView ...
- "/ ... need a single string, with 0-terminated parts.
-
- strings := OrderedCollection new.
- sz := 0.
- dropColl do:[:anObject |
- |s o|
-
- o := anObject theObject.
- anObject isFileObject ifTrue:[
- o := o pathName
- ].
- s := o asString.
- strings add:s.
- sz := sz + (s size) + 1.
- ].
- val := String new:sz.
- idx := 1.
- strings do:[:aString |
- |sz|
-
- sz := aString size.
- val replaceFrom:idx to:(idx + sz - 1) with:aString startingAt:1.
- idx := idx + sz.
- val at:idx put:(Character value:0).
- idx := idx + 1
- ].
-
- self
- setProperty:(self atomIDOf:#DndSelection)
- type:(self atomIDOf:#STRING)
- value:val
- for:rootId.
-
- ^ self
- sendClientEvent:msgType
- format:32
- to:destinationId
- data1:dropTypeCode
- data2:0
- data3:destinationId
- data4:nil
- data5:nil.
+ "/ DND can drop files, file, dir, links, dirLink and text
+ "/ check for this.
+
+ dropObjects isCollection ifFalse:[
+ dropColl := Array with:dropObjects
+ ] ifTrue:[
+ dropColl := dropObjects
+ ].
+ anyFile := anyDir := anyText := anyOther := false.
+ dropColl do:[:aDropObject |
+ aDropObject isFileObject ifTrue:[
+ aDropObject theObject isDirectory ifTrue:[
+ anyDir := true
+ ] ifFalse:[
+ anyFile := true
+ ]
+ ] ifFalse:[
+ aDropObject isTextObject ifTrue:[
+ anyText := true
+ ] ifFalse:[
+ anyOther := true
+ ]
+ ]
+ ].
+
+ anyOther ifTrue:[
+ "/ DND does not support this ...
+ 'XWorkstation [info]: DND can only drop files or text' infoPrintCR.
+ ^ false
+ ].
+ anyText ifTrue:[
+ (anyFile or:[anyDir]) ifTrue:[
+ "/ DND does not support mixed types
+ 'XWorkstation [info]: DND cannot drop both files and text' infoPrintCR.
+ ^ false
+ ]
+ ].
+
+ dropCollSize := dropColl size.
+ anyFile ifTrue:[
+ dropType := #DndFiles.
+ dropCollSize == 1 ifTrue:[
+ dropType := #DndFile
+ ]
+ ] ifFalse:[
+ anyDir ifTrue:[
+ dropType := #DndFiles.
+ dropCollSize == 1 ifTrue:[
+ dropType := #DndDir
+ ]
+ ] ifFalse:[
+ anyText ifTrue:[
+ dropCollSize == 1 ifTrue:[
+ dropType := #DndText
+ ] ifFalse:[
+ "/ can only drop a single text object
+ 'XWorkstation [info]: DND can only drop a single text' infoPrintCR.
+ ^ false
+ ]
+ ] ifFalse:[
+ "/ mhmh ...
+ 'XWorkstation [info]: DND cannot drop this' infoPrintCR.
+ ^ false
+ ]
+ ]
+ ].
+
+ dropTypeCode := self dndDropTypes indexOf:dropType.
+ dropTypeCode == 0 ifTrue:[
+ 'XWorkstation [info]: DND cannot drop this' infoPrintCR.
+ ^ false
+ ].
+ dropTypeCode := dropTypeCode - 1.
+
+
+ "/ place the selection inTo the DndSelection property
+ "/ of the rootView ...
+ "/ ... need a single string, with 0-terminated parts.
+
+ strings := OrderedCollection new.
+ sz := 0.
+ dropColl do:[:anObject |
+ |s o|
+
+ o := anObject theObject.
+ anObject isFileObject ifTrue:[
+ o := o pathName
+ ].
+ s := o asString.
+ strings add:s.
+ sz := sz + (s size) + 1.
+ ].
+ val := String new:sz.
+ idx := 1.
+ strings do:[:aString |
+ |sz|
+
+ sz := aString size.
+ val replaceFrom:idx to:(idx + sz - 1) with:aString startingAt:1.
+ idx := idx + sz.
+ val at:idx put:(Character value:0).
+ idx := idx + 1
+ ].
+
+ self
+ setProperty:(self atomIDOf:#DndSelection)
+ type:(self atomIDOf:#STRING)
+ value:val
+ for:rootId.
+
+ ^ self
+ sendClientEvent:msgType
+ format:32
+ to:destinationId
+ propagate:true
+ eventMask:nil
+ window:destinationId
+ data1:dropTypeCode
+ data2:0
+ data3:destinationId
+ data4:nil
+ data5:nil.
].
^ false
@@ -5021,6 +5024,8 @@
else if (anEventSymbol == @symbol(resizeRedirect)) m = ResizeRedirectMask;
else if (anEventSymbol == @symbol(propertyChange)) m = PropertyChangeMask;
else if (anEventSymbol == @symbol(colormapChange)) m = ColormapChangeMask;
+ else if (anEventSymbol == @symbol(substructureNotify)) m = SubstructureNotifyMask;
+ else if (anEventSymbol == @symbol(substructureRedirect)) m = SubstructureRedirectMask;
RETURN (__MKSMALLINT(m));
%}
!
@@ -5752,7 +5757,7 @@
!XWorkstation methodsFor:'event sending'!
-sendClientEvent:msgType format:msgFormat to:targetWindowID data1:d1 data2:d2 data3:d3 data4:d4 data5:d5
+sendClientEvent:msgType format:msgFormat to:targetWindowID propagate:propagate eventMask:eventMask window:windowID data1:d1 data2:d2 data3:d3 data4:d4 data5:d5
"send a ClientMessage to some other (possibly: non-ST/X) view.
The client message gets message_type and msgFormat as specified by
the arguments. The additional data arguments specify up to
@@ -5764,94 +5769,110 @@
"/ Event.xclient.display = dpy;
"/ Event.xclient.message_type = msgType;
"/ Event.xclient.format = msgFormat;
- "/ Event.xclient.window = targetWindowID;
+ "/ Event.xclient.window = windowID;
"/ Event.xclient.data.l[0] = d1
"/ Event.xclient.data.l[1] = d2
"/ Event.xclient.data.l[2] = d3
"/ Event.xclient.data.l[3] = d4
"/ Event.xclient.data.l[4] = d5
"/
- "/ XSendEvent(dpy,DispatchWindow,True,NoEventMask,&Event);
+ "/ XSendEvent(dpy, targetWindowID, propagate, eventMask, &Event);
<context: #return>
%{
int type;
int state;
+ int __eventMask;
if (ISCONNECTED
&& __isInteger(msgType)
&& __isInteger(msgFormat)
+ && (eventMask == nil || __isInteger(eventMask))
+ && (__isExternalAddress(windowID) || __isInteger(windowID))
&& (__isExternalAddress(targetWindowID) || __isInteger(targetWindowID))) {
- Display *dpy = myDpy;
- XEvent ev;
- Status result;
-
- if (__isInteger(d1)) {
- ev.xclient.data.l[0] = __longIntVal(d1);
- } else {
- if (__isExternalAddress(d1)) {
- ev.xclient.data.l[0] = (INT)__externalAddressVal(d1);
- } else {
- ev.xclient.data.l[0] = 0;
- }
- }
- if (__isInteger(d2)) {
- ev.xclient.data.l[1] = __longIntVal(d2);
- } else {
- if (__isExternalAddress(d2)) {
- ev.xclient.data.l[1] = (INT)__externalAddressVal(d2);
- } else {
- ev.xclient.data.l[1] = 0;
- }
- }
- if (__isInteger(d3)) {
- ev.xclient.data.l[2] = __longIntVal(d3);
- } else {
- if (__isExternalAddress(d3)) {
- ev.xclient.data.l[2] = (INT)__externalAddressVal(d3);
- } else {
- ev.xclient.data.l[2] = 0;
- }
- }
- if (__isInteger(d4)) {
- ev.xclient.data.l[3] = __longIntVal(d4);
- } else {
- if (__isExternalAddress(d4)) {
- ev.xclient.data.l[3] = (INT)__externalAddressVal(d4);
- } else {
- ev.xclient.data.l[3] = 0;
- }
- }
- if (__isInteger(d5)) {
- ev.xclient.data.l[4] = __longIntVal(d5);
- } else {
- if (__isExternalAddress(d5)) {
- ev.xclient.data.l[4] = (INT)__externalAddressVal(d5);
- } else {
- ev.xclient.data.l[4] = 0;
- }
- }
-
- if (__isExternalAddress(targetWindowID)) {
- ev.xclient.window = __WindowVal(targetWindowID);
- } else {
- ev.xclient.window = (Window)__longIntVal(targetWindowID);
- }
-
- ev.xclient.type = ClientMessage;
- ev.xclient.display = dpy;
- ev.xclient.message_type = __longIntVal(msgType);
- ev.xclient.format = __longIntVal(msgFormat);
-
- ENTER_XLIB();
- result = XSendEvent(dpy, ev.xclient.window, True, NoEventMask , &ev);
- LEAVE_XLIB();
-
- if ((result == BadValue) || (result == BadWindow)) {
- DPRINTF(("bad status in sendClientEvent\n"));
- RETURN ( false )
- }
- RETURN (true)
+ Display *dpy = myDpy;
+ XEvent ev;
+ Status result;
+ Window targetWindow;
+
+ if (__isInteger(d1)) {
+ ev.xclient.data.l[0] = __longIntVal(d1);
+ } else {
+ if (__isExternalAddress(d1)) {
+ ev.xclient.data.l[0] = (INT)__externalAddressVal(d1);
+ } else {
+ ev.xclient.data.l[0] = 0;
+ }
+ }
+ if (__isInteger(d2)) {
+ ev.xclient.data.l[1] = __longIntVal(d2);
+ } else {
+ if (__isExternalAddress(d2)) {
+ ev.xclient.data.l[1] = (INT)__externalAddressVal(d2);
+ } else {
+ ev.xclient.data.l[1] = 0;
+ }
+ }
+ if (__isInteger(d3)) {
+ ev.xclient.data.l[2] = __longIntVal(d3);
+ } else {
+ if (__isExternalAddress(d3)) {
+ ev.xclient.data.l[2] = (INT)__externalAddressVal(d3);
+ } else {
+ ev.xclient.data.l[2] = 0;
+ }
+ }
+ if (__isInteger(d4)) {
+ ev.xclient.data.l[3] = __longIntVal(d4);
+ } else {
+ if (__isExternalAddress(d4)) {
+ ev.xclient.data.l[3] = (INT)__externalAddressVal(d4);
+ } else {
+ ev.xclient.data.l[3] = 0;
+ }
+ }
+ if (__isInteger(d5)) {
+ ev.xclient.data.l[4] = __longIntVal(d5);
+ } else {
+ if (__isExternalAddress(d5)) {
+ ev.xclient.data.l[4] = (INT)__externalAddressVal(d5);
+ } else {
+ ev.xclient.data.l[4] = 0;
+ }
+ }
+
+ if (__isExternalAddress(windowID)) {
+ ev.xclient.window = __WindowVal(windowID);
+ } else {
+ ev.xclient.window = (Window)__longIntVal(windowID);
+ }
+
+ if (__isExternalAddress(targetWindowID)) {
+ targetWindow = __WindowVal(targetWindowID);
+ } else {
+ targetWindow = (Window)__longIntVal(targetWindowID);
+ }
+
+ ev.xclient.type = ClientMessage;
+ ev.xclient.display = dpy;
+ ev.xclient.message_type = __longIntVal(msgType);
+ ev.xclient.format = __longIntVal(msgFormat);
+
+ if (eventMask == nil) {
+ __eventMask = NoEventMask;
+ } else {
+ __eventMask = __longIntVal(eventMask);
+ }
+
+ ENTER_XLIB();
+ result = XSendEvent(dpy, targetWindow, (propagate == true ? True : False), __eventMask , &ev);
+ LEAVE_XLIB();
+
+ if ((result == BadValue) || (result == BadWindow)) {
+ DPRINTF(("bad status in sendClientEvent\n"));
+ RETURN ( false )
+ }
+ RETURN (true)
}
%}.
self primitiveFailedOrClosedConnection.
@@ -9534,7 +9555,7 @@
!XWorkstation methodsFor:'resources'!
atomIDOf:aStringOrSymbol
- "return an X11 atoms ID; dont create if not already present.
+ "return an X11 atoms ID.
This is highly X specific and only for local use (with selections).
The default is to create the atom, if it does not exist, in order to
speed up future lookups"
@@ -11196,6 +11217,31 @@
self primitiveFailedOrClosedConnection
!
+setForegroundWindow:aWindowId
+ "bring a window to front.
+ Send a specific message to the WindowManager"
+
+ |activeWindowAtom|
+
+ self raiseWindow:aWindowId.
+
+ activeWindowAtom := self atomIDOf:#'_NET_ACTIVE_WINDOW'.
+ activeWindowAtom notNil ifTrue:[
+ self
+ sendClientEvent:activeWindowAtom
+ format:32
+ to:(self rootWindowId)
+ propagate:false
+ eventMask:((self eventMaskFor:#substructureNotify) bitOr:(self eventMaskFor:#substructureRedirect))
+ window:aWindowId
+ data1:2 "activate request from pager. This is a trick: kwm ignores requests from applications (1)"
+ data2:nil
+ data3:nil
+ data4:nil
+ data5:nil.
+ ].
+!
+
setIconName:aString in:aWindowId
"define a windows iconname"
@@ -11927,7 +11973,7 @@
!XWorkstation class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.496 2008-03-15 17:17:21 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.497 2008-09-12 18:42:11 stefan Exp $'
! !
XWorkstation initialize!