WindowSensor.st
changeset 8335 922ba14b4680
parent 8332 a5540d67cf81
child 8338 f1a44724b64b
equal deleted inserted replaced
8334:c982775d0f33 8335:922ba14b4680
       
     1 "{ Encoding: utf8 }"
       
     2 
     1 "
     3 "
     2  COPYRIGHT (c) 1993 by Claus Gittinger
     4  COPYRIGHT (c) 1993 by Claus Gittinger
     3               All Rights Reserved
     5               All Rights Reserved
     4 
     6 
     5  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
    99 
   101 
   100     NOTICE: in previous releases, only one listener was allowed, which was notified
   102     NOTICE: in previous releases, only one listener was allowed, which was notified
   101     via #buttonPress/#buttonRelease ... invocations.
   103     via #buttonPress/#buttonRelease ... invocations.
   102     We have changed this to allow multiple handlers, and also to pass the event to a single
   104     We have changed this to allow multiple handlers, and also to pass the event to a single
   103     #handleEvent method.
   105     #handleEvent method.
   104     The old mechanism is kept for a while for backward compatibility, but will eventually
       
   105     vanish.
       
   106 
   106 
   107     [instance variables:]
   107     [instance variables:]
   108         eventSemaphore          <Semaphore>     the semaphore to be signalled when an event
   108         eventSemaphore          <Semaphore>     the semaphore to be signalled when an event
   109                                                 (or damage) arrives
   109                                                 (or damage) arrives
   110 
   110 
   141 
   141 
   142         translateKeyboardEvents <Boolean>       if true, keyboard events are translated via
   142         translateKeyboardEvents <Boolean>       if true, keyboard events are translated via
   143                                                 the devices leyboardMap; if false, they
   143                                                 the devices leyboardMap; if false, they
   144                                                 are reported as raw-keys. Default is true.
   144                                                 are reported as raw-keys. Default is true.
   145 
   145 
   146         eventListener           <Object>        if non nil, this one will get all pointer
       
   147         OBSOLETE - will vanish                  and keyboard events for this sensors views first.
       
   148                                                 If it returns true, the event is supposed to
       
   149                                                 be already handled by the listener and not sent to
       
   150                                                 the view. If false, the event is handled as usual.
       
   151                                                 This allows applications to catch events for any of
       
   152                                                 its views.
       
   153 
       
   154         keyboardListener        <Object>        if non nil, this one will get all keyboard events 
       
   155         OBSOLETE - will vanish                  for this sensors views first (but after the eventListener,
       
   156                                                 if any).
       
   157                                                 If it returns true, the event is supposed to
       
   158                                                 be already handled by the listener and not sent to
       
   159                                                 the view. If false, the event is handled as usual.
       
   160                                                 This allows applications to catch events for any of
       
   161                                                 its views.
       
   162                                                 ApplicationModels can catch keyboard input with:
       
   163                                                     postOpenWith:aBuilder
       
   164                                                         aBuilder window sensor keyboardListener:self
       
   165 
   146 
   166         eventListeners          <Collection>    Collection of new event listeners.
   147         eventListeners          <Collection>    Collection of new event listeners.
   167                                                 Each will be sent a #handleEvent: message.
       
   168                                                 The event will not be enqueued, if any returns
       
   169                                                 true.
       
   170 
       
   171         keyboardListeners       <Collection>    Collection of new event listeners.
       
   172                                                 Each will be sent a #handleEvent: message.
   148                                                 Each will be sent a #handleEvent: message.
   173                                                 The event will not be enqueued, if any returns
   149                                                 The event will not be enqueued, if any returns
   174                                                 true.
   150                                                 true.
   175 
   151 
   176         accessLock              <Semaphore>     controls access to the event queues
   152         accessLock              <Semaphore>     controls access to the event queues
   194                                                 (such as a long fileRead in the fileBrowser)
   170                                                 (such as a long fileRead in the fileBrowser)
   195                                                 without entering the debugger.
   171                                                 without entering the debugger.
   196                                                 (actually, Control-Y is wrong here; the actual
   172                                                 (actually, Control-Y is wrong here; the actual
   197                                                  key is #UserAbort, which may be mapped onto
   173                                                  key is #UserAbort, which may be mapped onto
   198                                                  any key)
   174                                                  any key)
   199 
       
   200         EventListener           <Object>        if non nil, this one will get all pointer
       
   201         OBSOLETE - will vanish                  and keyboard events for ALL views first.
       
   202                                                 If it returns true, the event is supposed to
       
   203                                                 be already handled by the listener and not enqueued. 
       
   204                                                 If false, the event is handled as usual.
       
   205                                                 This allows overall event catchers to be
       
   206                                                 installed for example to implement event
       
   207                                                 recorders, active help managers etc.
       
   208 
   175 
   209         EventListeners          <Collection>    Collection of new event listeners.
   176         EventListeners          <Collection>    Collection of new event listeners.
   210                                                 Each will be sent a #handleEvent: message.
   177                                                 Each will be sent a #handleEvent: message.
   211                                                 The event will not be enqueued, if any returns
   178                                                 The event will not be enqueued, if any returns
   212                                                 true.
   179                                                 true.
   685      changed. (For example, recorder/playback applications may
   652      changed. (For example, recorder/playback applications may
   686      want to make certain that the playback view is at the same
   653      want to make certain that the playback view is at the same
   687      position - or record any origin changes to translate later
   654      position - or record any origin changes to translate later
   688      synthetic events)."
   655      synthetic events)."
   689 
   656 
   690     | ev|
   657     |ev|
   691 
   658 
   692 "/    "/ backward compatibility ... will vanish
   659     EventListeners notEmptyOrNil ifTrue:[
   693 "/    EventListener notNil ifTrue:[
       
   694 "/        EventListener postCreateView:aView.
       
   695 "/    ].
       
   696 "/
       
   697     "/ new protocol
       
   698     EventListeners size > 0 ifTrue:[
       
   699         ev := WindowEvent postViewCreateNotification:aView.
   660         ev := WindowEvent postViewCreateNotification:aView.
   700         EventListeners copy do:[:aListener |
   661         EventListeners copy do:[:aListener |
   701             aListener processEvent:ev
   662             aListener processEvent:ev
   702         ]
   663         ]
   703     ].
   664     ].
   704 
   665 
   705     "Modified: / 29-06-2011 / 18:56:05 / cg"
   666     "Modified: / 29-06-2011 / 18:56:05 / cg"
       
   667     "Modified (format): / 13-04-2018 / 14:46:22 / stefan"
   706 !
   668 !
   707 
   669 
   708 preViewCreateNotification:aView
   670 preViewCreateNotification:aView
   709     "invoked right before a new view is created.
   671     "invoked right before a new view is created.
   710      Notify listeners and allow for the origin/extent to be
   672      Notify listeners and allow for the origin/extent to be
   711      changed. (For example, recorder/playback applications may
   673      changed. (For example, recorder/playback applications may
   712      want to make certain that the playback view is at the same
   674      want to make certain that the playback view is at the same
   713      position - or record any origin changes to translate later
   675      position - or record any origin changes to translate later
   714      synthetic events)."
   676      synthetic events)."
   715 
   677 
   716     |ret ev|
   678     |ev|
   717 
   679 
   718 "/    "/ backward compatibility ... will vanish
   680     EventListeners notEmptyOrNil ifTrue:[
   719 "/    EventListener notNil ifTrue:[
       
   720 "/        ret := EventListener preCreateView:aView origin:aView origin.
       
   721 "/        ret isPoint ifTrue:[
       
   722 "/            aView setOrigin:ret
       
   723 "/        ]
       
   724 "/    ].
       
   725 "/
       
   726     "/ new protocol
       
   727     EventListeners size > 0 ifTrue:[
       
   728         ev := WindowEvent preViewCreateNotification:aView.
   681         ev := WindowEvent preViewCreateNotification:aView.
   729         EventListeners copy do:[:aListener |
   682         EventListeners copy do:[:aListener |
   730             aListener processEvent:ev
   683             aListener processEvent:ev
   731         ]
   684         ]
   732     ].
   685     ].
   733 
   686 
   734     "Modified: / 29-06-2011 / 18:54:57 / cg"
   687     "Modified: / 29-06-2011 / 18:54:57 / cg"
       
   688     "Modified: / 13-04-2018 / 14:46:17 / stefan"
   735 ! !
   689 ! !
   736 
   690 
   737 !WindowSensor class methodsFor:'queries'!
   691 !WindowSensor class methodsFor:'queries'!
   738 
   692 
   739 cursorPoint
   693 cursorPoint
   862 removeEventListener:aListener
   816 removeEventListener:aListener
   863     "remove a local eventListener (with new protocol - #processEvent:)
   817     "remove a local eventListener (with new protocol - #processEvent:)
   864      - see documentation for what this can be used for"
   818      - see documentation for what this can be used for"
   865 
   819 
   866     eventListeners notNil ifTrue:[
   820     eventListeners notNil ifTrue:[
   867         eventListeners removeIdentical:aListener ifAbsent:nil
   821         eventListeners removeIdentical:aListener ifAbsent:nil.
   868     ].
   822         eventListeners isEmpty ifTrue:[
   869 
   823             eventListeners := nil.
   870 
   824         ].
       
   825     ].
       
   826 
       
   827     "Modified: / 13-04-2018 / 14:41:05 / stefan"
   871 ! !
   828 ! !
   872 
   829 
   873 !WindowSensor methodsFor:'accessing-private'!
   830 !WindowSensor methodsFor:'accessing-private'!
   874 
   831 
   875 criticalDamageEventQueueAccess:aBlock
   832 criticalDamageEventQueueAccess:aBlock
   876     "perform some action which needs synchronized (exclusive)
   833     "perform some action which needs synchronized (exclusive)
   877      access to the damage event queue. 
   834      access to the damage event queue. 
   878      (i.e. protected by a critical region)"
   835      (i.e. protected by a critical region)"
   879 
   836 
   880     self criticalEventQueueAccess:damageEventAccessLock do:aBlock.
   837     ^ self criticalEventQueueAccess:damageEventAccessLock do:aBlock.
       
   838 
       
   839     "Modified: / 13-04-2018 / 15:25:12 / stefan"
   881 !
   840 !
   882 
   841 
   883 criticalEventQueueAccess:whichLock do:aBlock
   842 criticalEventQueueAccess:whichLock do:aBlock
   884     "perform some action which needs synchronized (exclusive)
   843     "perform some action which needs synchronized (exclusive)
   885      access to one of the event queues. 
   844      access to one of the event queues. 
   888     |wasBlocked p|
   847     |wasBlocked p|
   889 
   848 
   890     p := Processor activeProcess.
   849     p := Processor activeProcess.
   891     wasBlocked := p blockInterrupts.
   850     wasBlocked := p blockInterrupts.
   892 
   851 
   893     [
   852     ^ [
   894         whichLock critical:aBlock
   853         whichLock critical:aBlock
   895     ] on:Error do:[:ex|
   854     ] on:Error do:[:ex|
   896         ('WindowSensor [Warning]: Error in eventQ handling ignored: ' , ex description) errorPrintCR.
   855         ('WindowSensor [Warning]: Error in eventQ handling ignored: ' , ex description) errorPrintCR.
   897         "/ thisContext fullPrintAll.
   856         "/ thisContext fullPrintAll.
   898         "/ whichLock printCR.
   857         "/ whichLock printCR.
   903         ]
   862         ]
   904     ]
   863     ]
   905 
   864 
   906     "Created: / 06-06-1998 / 21:04:02 / cg"
   865     "Created: / 06-06-1998 / 21:04:02 / cg"
   907     "Modified: / 14-10-1998 / 17:17:05 / cg"
   866     "Modified: / 14-10-1998 / 17:17:05 / cg"
   908     "Modified: / 31-01-2017 / 16:53:08 / stefan"
   867     "Modified: / 13-04-2018 / 15:25:02 / stefan"
   909 !
   868 !
   910 
   869 
   911 criticalUserEventQueueAccess:aBlock
   870 criticalUserEventQueueAccess:aBlock
   912     "perform some action which needs synchronized (exclusive)
   871     "perform some action which needs synchronized (exclusive)
   913      access to the user event queue. 
   872      access to the user event queue. 
   914      (i.e. protected by a critical region)"
   873      (i.e. protected by a critical region)"
   915 
   874 
   916     self criticalEventQueueAccess:userEventAccessLock do:aBlock.
   875     ^ self criticalEventQueueAccess:userEventAccessLock do:aBlock.
       
   876 
       
   877     "Modified: / 13-04-2018 / 15:24:42 / stefan"
   917 !
   878 !
   918 
   879 
   919 damageEventAccessLock
   880 damageEventAccessLock
   920     "return the semaphore which controls access to the damage event queue.
   881     "return the semaphore which controls access to the damage event queue.
   921      This should probably not be exposed to the public,
   882      This should probably not be exposed to the public,
   997      A helper for the various flush entries.
   958      A helper for the various flush entries.
   998      Returns the last flushed event or nil."
   959      Returns the last flushed event or nil."
   999 
   960 
  1000     |lastFlushed whichLock|
   961     |lastFlushed whichLock|
  1001 
   962 
  1002     anEventQueue isNil ifTrue:[^ nil].
   963     anEventQueue isEmptyOrNil ifTrue:[
       
   964         ^ nil
       
   965     ].
  1003 
   966 
  1004     whichLock := (anEventQueue == damage) ifTrue:[damageEventAccessLock] ifFalse:[userEventAccessLock].
   967     whichLock := (anEventQueue == damage) ifTrue:[damageEventAccessLock] ifFalse:[userEventAccessLock].
  1005     self 
   968     self 
  1006         criticalEventQueueAccess:whichLock 
   969         criticalEventQueueAccess:whichLock 
  1007         do:[
   970         do:[
  1024                 ]
   987                 ]
  1025             ].
   988             ].
  1026         ].
   989         ].
  1027     ^ lastFlushed
   990     ^ lastFlushed
  1028 
   991 
  1029     "Modified: / 6.6.1998 / 21:10:22 / cg"
   992     "Created: / 06-06-1998 / 21:17:54 / cg"
  1030     "Created: / 6.6.1998 / 21:17:54 / cg"
   993     "Modified (format): / 13-04-2018 / 12:21:26 / stefan"
  1031 !
   994 !
  1032 
   995 
  1033 flushEventsFor:aViewOrNil where:aBlock
   996 flushEventsFor:aViewOrNil where:aBlock
  1034     "throw away all events for aView, for which aBlock evaluates to true 
   997     "throw away all events for aView, for which aBlock evaluates to true 
  1035      or any view, if the argument is nil."
   998      or any view, if the argument is nil."
  1218 
  1181 
  1219     ev := WindowEvent buttonMotion:buttonState x:x y:y view:aView.
  1182     ev := WindowEvent buttonMotion:buttonState x:x y:y view:aView.
  1220     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1183     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1221        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1184        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1222 
  1185 
  1223     "/ any eventListener
       
  1224     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1225     self pushEvent:ev.
  1186     self pushEvent:ev.
  1226 
  1187 
  1227     "Modified: / 29-06-2011 / 18:45:59 / cg"
  1188     "Modified: / 29-06-2011 / 18:45:59 / cg"
       
  1189     "Modified (comment): / 13-04-2018 / 15:35:11 / stefan"
  1228 !
  1190 !
  1229 
  1191 
  1230 buttonMultiPress:button x:x y:y view:aView
  1192 buttonMultiPress:button x:x y:y view:aView
  1231     "mouse button was pressed - this is sent from the device (Display)"
  1193     "mouse button was pressed - this is sent from the device (Display)"
  1232 
  1194 
  1240 
  1202 
  1241     ev := WindowEvent buttonMultiPress:button x:x y:y view:aView.
  1203     ev := WindowEvent buttonMultiPress:button x:x y:y view:aView.
  1242     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1204     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1243        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1205        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1244 
  1206 
  1245     "/ any eventListener
       
  1246     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1247     self pushEvent:ev.
  1207     self pushEvent:ev.
  1248 
  1208 
  1249     "Modified: / 29-06-2011 / 18:46:03 / cg"
  1209     "Modified: / 29-06-2011 / 18:46:03 / cg"
       
  1210     "Modified (comment): / 13-04-2018 / 15:35:26 / stefan"
  1250 !
  1211 !
  1251 
  1212 
  1252 buttonPress:button x:x y:y view:aView
  1213 buttonPress:button x:x y:y view:aView
  1253     "mouse button was pressed - this is sent from the device (Display)"
  1214     "mouse button was pressed - this is sent from the device (Display)"
  1254 
  1215 
  1262 
  1223 
  1263     ev := WindowEvent buttonPress:button x:x y:y view:aView.
  1224     ev := WindowEvent buttonPress:button x:x y:y view:aView.
  1264     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1225     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1265        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1226        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1266 
  1227 
  1267     "/ any eventListener
       
  1268     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1269     self pushEvent:ev.
  1228     self pushEvent:ev.
  1270 
  1229 
  1271     "Modified: / 29-06-2011 / 18:46:07 / cg"
  1230     "Modified: / 29-06-2011 / 18:46:07 / cg"
       
  1231     "Modified (comment): / 13-04-2018 / 15:35:33 / stefan"
  1272 !
  1232 !
  1273 
  1233 
  1274 buttonRelease:button x:x y:y view:aView
  1234 buttonRelease:button x:x y:y view:aView
  1275     "mouse button was released- this is sent from the device (Display)"
  1235     "mouse button was released- this is sent from the device (Display)"
  1276 
  1236 
  1284 
  1244 
  1285     ev := WindowEvent buttonRelease:button x:x y:y view:aView.
  1245     ev := WindowEvent buttonRelease:button x:x y:y view:aView.
  1286     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1246     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1287        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1247        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1288 
  1248 
  1289     "/ any eventListener
       
  1290     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1291     self pushEvent:ev.
  1249     self pushEvent:ev.
  1292 
  1250 
  1293     "Modified: / 29-06-2011 / 18:46:11 / cg"
  1251     "Modified: / 29-06-2011 / 18:46:11 / cg"
       
  1252     "Modified (comment): / 13-04-2018 / 15:35:53 / stefan"
  1294 !
  1253 !
  1295 
  1254 
  1296 clientMessage:type format:format eventData:data view:aView
  1255 clientMessage:type format:format eventData:data view:aView
  1297     "some other process has sent data to a view.
  1256     "some other process has sent data to a view.
  1298      This is an X-specific event. (see copyDataEvent for win32 variant)"
  1257      This is an X-specific event. (see copyDataEvent for win32 variant)"
  1327     ].
  1286     ].
  1328 
  1287 
  1329     "/
  1288     "/
  1330     "/ remove any old configure event (WIN32 speedup)
  1289     "/ remove any old configure event (WIN32 speedup)
  1331     "/
  1290     "/
  1332     damage size ~~ 0 ifTrue:[
  1291     damage notEmpty ifTrue:[
  1333         damage keysAndValuesDo:[:idx :aDamage |
  1292         damage keysAndValuesDo:[:idx :aDamage |
  1334             (aDamage notNil 
  1293             (aDamage notNil 
  1335             and:[aDamage type == #configureX:y:width:height:
  1294             and:[aDamage type == #configureX:y:width:height:
  1336             and:[aDamage view == aView]]) ifTrue:[
  1295             and:[aDamage view == aView]]) ifTrue:[
  1337                 damage at:idx put:nil.
  1296                 damage at:idx put:nil.
  1341 
  1300 
  1342     self pushDamageEvent:(WindowEvent configureX:x y:y width:w height:h view:aView).
  1301     self pushDamageEvent:(WindowEvent configureX:x y:y width:w height:h view:aView).
  1343 
  1302 
  1344     "Modified: / 29-04-1999 / 10:06:47 / cg"
  1303     "Modified: / 29-04-1999 / 10:06:47 / cg"
  1345     "Modified (comment): / 31-08-2017 / 20:18:59 / cg"
  1304     "Modified (comment): / 31-08-2017 / 20:18:59 / cg"
       
  1305     "Modified: / 13-04-2018 / 11:29:12 / stefan"
  1346 !
  1306 !
  1347 
  1307 
  1348 copyDataEvent:parameter eventData:data view:aView
  1308 copyDataEvent:parameter eventData:data view:aView
  1349     "some other process has sent data to a view.
  1309     "some other process has sent data to a view.
  1350      This is a Win32-specific event. (see clientMessage for x-windows variant)"
  1310      This is a Win32-specific event. (see clientMessage for x-windows variant)"
  1588             rawKey:keyWithModifier
  1548             rawKey:keyWithModifier
  1589             hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1549             hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1590             button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown
  1550             button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown
  1591             x:x y:y view:aView.
  1551             x:x y:y view:aView.
  1592 
  1552 
  1593     "/ any eventListener
       
  1594     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1595     self pushEvent:ev.
  1553     self pushEvent:ev.
  1596 
  1554 
  1597     "Modified: / 10-02-2017 / 21:42:25 / cg"
  1555     "Modified: / 10-02-2017 / 21:42:25 / cg"
       
  1556     "Modified (comment): / 13-04-2018 / 15:36:20 / stefan"
  1598 !
  1557 !
  1599 
  1558 
  1600 keyRelease:key x:x y:y view:aView
  1559 keyRelease:key x:x y:y view:aView
  1601     "key was released - this is sent from the device (Display)."
  1560     "key was released - this is sent from the device (Display)."
  1602 
  1561 
  1619             rawKey:key
  1578             rawKey:key
  1620             hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1579             hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1621             button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown
  1580             button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown
  1622             x:x y:y view:aView.
  1581             x:x y:y view:aView.
  1623 
  1582 
  1624     "/ any eventListener
       
  1625     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1626     self pushEvent:ev.
  1583     self pushEvent:ev.
  1627 
  1584 
  1628     "Modified: / 29-06-2011 / 18:46:46 / cg"
  1585     "Modified: / 29-06-2011 / 18:46:46 / cg"
       
  1586     "Modified (comment): / 13-04-2018 / 15:36:28 / stefan"
  1629 !
  1587 !
  1630 
  1588 
  1631 mappedView:aView
  1589 mappedView:aView
  1632     "view was mapped (from window manager) - this is sent from the device (Display)"
  1590     "view was mapped (from window manager) - this is sent from the device (Display)"
  1633 
  1591 
  1636 !
  1594 !
  1637 
  1595 
  1638 mouseWheelMotion:state x:x y:y amount:amount deltaTime:dTime view:aView
  1596 mouseWheelMotion:state x:x y:y amount:amount deltaTime:dTime view:aView
  1639     "mouse-wheel was turned - this is sent from the device (Display)"
  1597     "mouse-wheel was turned - this is sent from the device (Display)"
  1640 
  1598 
  1641     |ev affectedView windowGroup|
  1599     |ev affectedView|
  1642 
  1600 
  1643     "/ update my idea of button and modifier state information
  1601     "/ update my idea of button and modifier state information
  1644     self updateModifierStateFrom:state device:(aView graphicsDevice).
  1602     self updateModifierStateFrom:state device:(aView graphicsDevice).
  1645 
  1603 
  1646     ignoreUserInput == true ifTrue:[
  1604     ignoreUserInput == true ifTrue:[
  1662 
  1620 
  1663     ev := WindowEvent mouseWheelMotion:state x:x y:y amount:amount deltaTime:dTime view:affectedView.
  1621     ev := WindowEvent mouseWheelMotion:state x:x y:y amount:amount deltaTime:dTime view:affectedView.
  1664     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1622     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1665        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1623        button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1666 
  1624 
  1667     "/ any eventListener
       
  1668     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1669     self pushEvent:ev.
  1625     self pushEvent:ev.
  1670 
  1626 
  1671     "Created: / 21-05-1999 / 13:05:18 / cg"
  1627     "Created: / 21-05-1999 / 13:05:18 / cg"
  1672     "Modified: / 29-06-2011 / 18:46:54 / cg"
  1628     "Modified: / 29-06-2011 / 18:46:54 / cg"
       
  1629     "Modified (comment): / 13-04-2018 / 15:36:42 / stefan"
  1673 !
  1630 !
  1674 
  1631 
  1675 nativeWidgetCommand:command arguments:argVector view:aView
  1632 nativeWidgetCommand:command arguments:argVector view:aView
  1676     "native widget action - this is sent from the device (Display).
  1633     "native widget action - this is sent from the device (Display).
  1677      These are only delivered if native widgets are enabled under win32"
  1634      These are only delivered if native widgets are enabled under win32"
  1715 
  1672 
  1716     ev := WindowEvent pointerEnter:state x:x y:y view:aView.
  1673     ev := WindowEvent pointerEnter:state x:x y:y view:aView.
  1717     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1674     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1718                           button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1675                           button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1719 
  1676 
  1720     "/ any eventListener
       
  1721     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1722     self pushEvent:ev.
  1677     self pushEvent:ev.
  1723 
  1678 
  1724     "Modified: / 29-06-2011 / 18:47:05 / cg"
  1679     "Modified: / 29-06-2011 / 18:47:05 / cg"
  1725     "Modified (format): / 10-02-2017 / 21:36:45 / cg"
  1680     "Modified (format): / 10-02-2017 / 21:36:45 / cg"
       
  1681     "Modified (comment): / 13-04-2018 / 15:36:57 / stefan"
  1726 !
  1682 !
  1727 
  1683 
  1728 pointerLeave:state view:aView
  1684 pointerLeave:state view:aView
  1729     "mouse cursor was moved out of the view - this is sent from the device (Display)"
  1685     "mouse cursor was moved out of the view - this is sent from the device (Display)"
  1730 
  1686 
  1734     self updateModifierStateFrom:state device:(aView graphicsDevice).
  1690     self updateModifierStateFrom:state device:(aView graphicsDevice).
  1735 
  1691 
  1736     ev := WindowEvent pointerLeave:state view:aView.
  1692     ev := WindowEvent pointerLeave:state view:aView.
  1737     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1693     ev hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
  1738                           button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1694                           button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown.
  1739     "/ any eventListener
       
  1740     "/ (self notifyEventListenersAbout:ev) ifTrue:[^ self].
       
  1741     self pushEvent:ev.
  1695     self pushEvent:ev.
  1742 
  1696 
  1743     "Modified: / 29-06-2011 / 18:47:09 / cg"
  1697     "Modified: / 29-06-2011 / 18:47:09 / cg"
  1744     "Modified (format): / 10-02-2017 / 21:36:50 / cg"
  1698     "Modified (format): / 10-02-2017 / 21:36:50 / cg"
       
  1699     "Modified (comment): / 13-04-2018 / 15:46:15 / stefan"
  1745 !
  1700 !
  1746 
  1701 
  1747 preViewCreateNotification:aView
  1702 preViewCreateNotification:aView
  1748     "invoked right before a new view is created.
  1703     "invoked right before a new view is created.
  1749      Notify listeners and allow for the origin/extent to be
  1704      Notify listeners and allow for the origin/extent to be
  1812 !
  1767 !
  1813 
  1768 
  1814 trayAction:command arguments:argVector view:aView
  1769 trayAction:command arguments:argVector view:aView
  1815     "native widget action - this is sent from the device (Display)"
  1770     "native widget action - this is sent from the device (Display)"
  1816 
  1771 
  1817     |ev|
  1772     self pushEvent:(WindowEvent trayAction:command arguments:argVector view:aView).
  1818 
       
  1819     ev := WindowEvent trayAction:command arguments:argVector view:aView.
       
  1820     self pushEvent:ev.
       
  1821 
  1773 
  1822     "Created: / 31-10-2007 / 01:22:08 / cg"
  1774     "Created: / 31-10-2007 / 01:22:08 / cg"
       
  1775     "Modified: / 13-04-2018 / 15:46:58 / stefan"
  1823 !
  1776 !
  1824 
  1777 
  1825 unmappedView:aView
  1778 unmappedView:aView
  1826     "view was unmapped (from window manager) - this is sent from the device (Display)"
  1779     "view was unmapped (from window manager) - this is sent from the device (Display)"
  1827 
  1780 
  2149 
  2102 
  2150 basicAddDamage:newRectangle view:aView
  2103 basicAddDamage:newRectangle view:aView
  2151     "{ Pragma: +optSpeed }"
  2104     "{ Pragma: +optSpeed }"
  2152 
  2105 
  2153     "Add newRectangle to the view's update region.
  2106     "Add newRectangle to the view's update region.
       
  2107      Answer true, if there are new damaged pixels, false otherwise.
       
  2108 
  2154      Must be careful, if the damage queue contains an event pattern such as:
  2109      Must be careful, if the damage queue contains an event pattern such as:
  2155         damage  map
  2110         damage  map
  2156      in this case, a new damage event is required to be added AFTER the map event,
  2111      in this case, a new damage event is required to be added AFTER the map event,
  2157      otherwise, the newRectangle will be processed in a state where the map has not yet been
  2112      otherwise, the newRectangle will be processed in a state where the map has not yet been
  2158      processed and the view thinks it can be ignored.
  2113      processed and the view thinks it can be ignored.
  2159      In this case, the damage event is re-added at the end of the queue.
  2114      In this case, the damage event is re-added at the end of the queue.
  2160      Attention: this method MUST be called in a critical region, controlling the damage queue access"
  2115      Attention: this method MUST be called in a critical region, controlling the damage queue access"
  2161 
  2116 
  2162     |sz  "{ Class: SmallInteger }" 
  2117     |sz  "{ Class: SmallInteger }" 
  2163      aDamageEvent oldDamageEvent oldDamageEventIndex anyOtherEventPending lastNilIndex
  2118      aDamageEvent oldDamageEvent oldDamageEventIndex anyOtherEventPending lastNilIndex|
  2164      ev "badGuy"|
       
  2165 
  2119 
  2166     "/ NEWDAMAGE handling - experimental;
  2120     "/ NEWDAMAGE handling - experimental;
  2167     "/ comment these lines if you encounter trouble.
  2121     "/ comment these lines if you encounter trouble.
  2168     sz := damage size.
  2122     sz := damage size.
  2169     (sz > 100) ifTrue:[
  2123     (sz > 100) ifTrue:[
  2170         damage := damage select:[:d | d notNil].
  2124         damage removeAllSuchThat:[:each | each isNil].
  2171         sz := damage size.
  2125         sz := damage size.
  2172     ].
  2126     ].
  2173 
  2127 
  2174     "/ find any other damage for this view,
  2128     "/ find any other damage for this view,
  2175     "/ and as a side effect, find the index of the last empty damage queue slot (nil index)
  2129     "/ and as a side effect, find the index of the last empty damage queue slot (nil index)
  2176     oldDamageEventIndex := nil.
       
  2177     anyOtherEventPending := false.
  2130     anyOtherEventPending := false.
  2178     1 to:sz do:[:idx |
  2131     1 to:sz do:[:idx |
  2179         aDamageEvent := damage at:idx.
  2132         aDamageEvent := damage at:idx.
  2180         aDamageEvent notNil ifTrue:[
  2133         aDamageEvent notNil ifTrue:[
  2181             (aDamageEvent isDamageForView:aView) ifTrue:[
  2134             (aDamageEvent isDamageForView:aView) ifTrue:[
  2187         ] ifFalse:[
  2140         ] ifFalse:[
  2188             lastNilIndex := idx
  2141             lastNilIndex := idx
  2189         ].
  2142         ].
  2190     ].
  2143     ].
  2191 
  2144 
  2192     oldDamageEventIndex notNil ifTrue:[
  2145     oldDamageEvent notNil ifTrue:[
  2193         "/ there is already a damage for this view in the queue
  2146         "/ there is already a damage for this view in the queue
  2194         "/ (which will wake up the WG, if currently sleeping).
  2147         "/ (which will wake up the WG, if currently sleeping).
  2195         "/ so all we have to do is to add the reactangle to the view's updateRegion.
  2148         "/ so all we have to do is to add the reactangle to the view's updateRegion.
  2196         "/ However, if the view was unmapped, and there is
  2149         "/ However, if the view was unmapped, and there is
  2197         "/ a mapped event AFTER the expose, we MUST perform the expose
  2150         "/ a mapped event AFTER the expose, we MUST perform the expose
  2204         anyOtherEventPending ifFalse:[
  2157         anyOtherEventPending ifFalse:[
  2205             ^ aView addUpdateRectangle:newRectangle.
  2158             ^ aView addUpdateRectangle:newRectangle.
  2206         ].
  2159         ].
  2207 
  2160 
  2208         (oldDamageEventIndex > (sz-30)) ifTrue:[
  2161         (oldDamageEventIndex > (sz-30)) ifTrue:[
       
  2162             "can remove oldDamage, copy will be fast"
  2209             damage removeIndex:oldDamageEventIndex.
  2163             damage removeIndex:oldDamageEventIndex.
  2210         ] ifFalse:[
  2164         ] ifFalse:[
       
  2165             "copy would take too long, just nil oldDamage"
  2211             damage at:oldDamageEventIndex put:nil.
  2166             damage at:oldDamageEventIndex put:nil.
  2212             (lastNilIndex notNil and:[lastNilIndex > (sz-30)]) ifTrue:[
  2167             (lastNilIndex notNil and:[lastNilIndex > (sz-30)]) ifTrue:[
  2213                 damage removeIndex:lastNilIndex.
  2168                 damage removeIndex:lastNilIndex.
  2214             ].
  2169             ].
  2215         ].
  2170         ].
  2216         damage add:oldDamageEvent.
  2171     ] ifFalse:[
  2217         aView addUpdateRectangle:newRectangle.
  2172         (lastNilIndex notNil and:[lastNilIndex > (sz-30)]) ifTrue:[
  2218         ^ true
  2173             damage removeIndex:lastNilIndex.
  2219     ].
  2174         ].
  2220 
  2175         oldDamageEvent := WindowEvent newDamageFor:aView.
  2221     (lastNilIndex notNil and:[lastNilIndex > (sz-30)]) ifTrue:[
  2176     ].
  2222         damage removeIndex:lastNilIndex.
       
  2223     ].
       
  2224 
       
  2225     aView addUpdateRectangle:newRectangle.
  2177     aView addUpdateRectangle:newRectangle.
  2226     ev := WindowEvent newDamageFor:aView.
  2178     damage add:oldDamageEvent.
  2227     damage add:ev.
       
  2228     ^ true.
  2179     ^ true.
  2229 
  2180 
  2230 "/    |newEvent r fullRedraw aDamageEvent 
  2181 "/    |newEvent r fullRedraw aDamageEvent 
  2231 "/     nDamagesForView bounds areaOfIndividualRects thisRectangle
  2182 "/     nDamagesForView bounds areaOfIndividualRects thisRectangle
  2232 "/     mergedLeft mergedRight mergedTop mergedBottom
  2183 "/     mergedLeft mergedRight mergedTop mergedBottom
  2343 "/
  2294 "/
  2344 "/    ^ true.
  2295 "/    ^ true.
  2345 
  2296 
  2346     "Modified: / 20-01-2011 / 22:41:50 / cg"
  2297     "Modified: / 20-01-2011 / 22:41:50 / cg"
  2347     "Modified (comment): / 29-01-2018 / 14:53:16 / mawalch"
  2298     "Modified (comment): / 29-01-2018 / 14:53:16 / mawalch"
       
  2299     "Modified: / 13-04-2018 / 14:30:13 / stefan"
  2348 !
  2300 !
  2349 
  2301 
  2350 basicPushEvent:anEvent
  2302 basicPushEvent:anEvent
  2351     "internal basic event queueing"
  2303     "internal basic event queueing"
  2352 
  2304 
  2395      Return if there are no damage events.
  2347      Return if there are no damage events.
  2396      Remove it from the queue."
  2348      Remove it from the queue."
  2397 
  2349 
  2398     |theEvent|
  2350     |theEvent|
  2399 
  2351 
  2400     damage size == 0 ifTrue:[^ nil].
  2352     damage isEmpty ifTrue:[
       
  2353         ^ nil
       
  2354     ].
  2401 
  2355 
  2402     "
  2356     "
  2403      be careful: events are inserted at higher prio ...
  2357      be careful: events are inserted at higher prio ...
  2404     "
  2358     "
  2405     self criticalDamageEventQueueAccess:[
  2359     self criticalDamageEventQueueAccess:[
  2412             anEvent notNil ifTrue:[
  2366             anEvent notNil ifTrue:[
  2413                 firstNonNilIndex isNil ifTrue:[
  2367                 firstNonNilIndex isNil ifTrue:[
  2414                     firstNonNilIndex := idx
  2368                     firstNonNilIndex := idx
  2415                 ].
  2369                 ].
  2416                 (aViewOrNil isNil or:[anEvent view == aViewOrNil]) ifTrue:[
  2370                 (aViewOrNil isNil or:[anEvent view == aViewOrNil]) ifTrue:[
       
  2371                     theEvent := anEvent.
  2417                     damage at:idx put:nil.
  2372                     damage at:idx put:nil.
  2418                     theEvent := anEvent.
  2373                     idx := damageSize.      "/ leave loop
  2419                     idx := damageSize.
       
  2420                 ].
  2374                 ].
  2421             ].
  2375             ].
  2422             idx := idx + 1.
  2376             idx := idx + 1.
  2423         ].
  2377         ].
  2424         firstNonNilIndex isNil ifTrue:[
  2378         firstNonNilIndex isNil ifTrue:[
  2425             damage removeAll
  2379             damage removeAll
  2426         ] ifFalse:[
  2380         ] ifFalse:[
  2427             firstNonNilIndex ~~ 1 ifTrue:[
  2381             firstNonNilIndex ~~ 1 ifTrue:[
  2428                 damage removeFromIndex:1 toIndex:(firstNonNilIndex-1)
  2382                 damage removeFromIndex:1 toIndex:(firstNonNilIndex-1)
  2429             ]
  2383             ]
  2430         ]
  2384         ].
  2431     ].
  2385     ].
  2432 
  2386 
  2433     ^ theEvent
  2387     ^ theEvent
  2434 
  2388 
  2435     "Created: / 3.12.1998 / 13:41:49 / cg"
  2389     "Created: / 03-12-1998 / 13:41:49 / cg"
  2436     "Modified: / 5.2.1999 / 20:58:20 / cg"
  2390     "Modified: / 05-02-1999 / 20:58:20 / cg"
       
  2391     "Modified (comment): / 13-04-2018 / 12:44:18 / stefan"
  2437 !
  2392 !
  2438 
  2393 
  2439 nextEvent
  2394 nextEvent
  2440     "retrieve the next event or nil, if there is none.
  2395     "retrieve the next event or nil, if there is none.
  2441      Remove it from the queue."
  2396      Remove it from the queue."
  2471      Return nil if there are no expose events.
  2426      Return nil if there are no expose events.
  2472      Remove it from the queue."
  2427      Remove it from the queue."
  2473 
  2428 
  2474     |theEvent|
  2429     |theEvent|
  2475 
  2430 
  2476     damage size == 0 ifTrue:[^ nil].
  2431     damage isEmpty ifTrue:[
       
  2432         ^ nil
       
  2433     ].
  2477 
  2434 
  2478     "
  2435     "
  2479      be careful: events are inserted at higher prio ...
  2436      be careful: events are inserted at higher prio ...
  2480     "
  2437     "
  2481     self criticalDamageEventQueueAccess:[
  2438     self criticalDamageEventQueueAccess:[
  2498 
  2455 
  2499                 anEvent isDamage ifTrue:[
  2456                 anEvent isDamage ifTrue:[
  2500                     (aViewOrNil isNil or:[anEvent view == aViewOrNil]) ifTrue:[
  2457                     (aViewOrNil isNil or:[anEvent view == aViewOrNil]) ifTrue:[
  2501                         theEvent := anEvent.
  2458                         theEvent := anEvent.
  2502                         damage at:idx put:nil.
  2459                         damage at:idx put:nil.
  2503                         idx := damageSize.
  2460                         idx := damageSize.      "/ leave loop
  2504                     ]
  2461                     ]
  2505                 ].
  2462                 ].
  2506             ].
  2463             ].
  2507             idx := idx + 1.
  2464             idx := idx + 1.
  2508         ].
  2465         ].
  2518 
  2475 
  2519     ^ theEvent
  2476     ^ theEvent
  2520 
  2477 
  2521     "Created: / 21-05-1996 / 17:20:54 / cg"
  2478     "Created: / 21-05-1996 / 17:20:54 / cg"
  2522     "Modified: / 05-02-1999 / 20:58:28 / cg"
  2479     "Modified: / 05-02-1999 / 20:58:28 / cg"
  2523     "Modified (comment): / 11-04-2018 / 11:45:54 / stefan"
  2480     "Modified: / 13-04-2018 / 11:04:13 / stefan"
       
  2481     "Modified (comment): / 13-04-2018 / 12:44:30 / stefan"
  2524 !
  2482 !
  2525 
  2483 
  2526 pendingEvent
  2484 pendingEvent
  2527     "retrieve the next pending user (i.e. non-damage) event.
  2485     "retrieve the next pending user (i.e. non-damage) event.
  2528      Return nil, if there is none pending.
  2486      Return nil, if there is none pending.
  2529      Do not remove it from the queue."
  2487      Do not remove it from the queue."
  2530 
  2488 
  2531     |e|
  2489     mouseAndKeyboard isEmpty ifTrue:[
  2532 
  2490         ^ nil
  2533     mouseAndKeyboard size == 0 ifTrue:[^ nil].
  2491     ].
  2534 
  2492 
  2535     "
  2493     "
  2536      be careful: events are inserted at higher prio ...
  2494      be careful: events are inserted at higher prio ...
  2537     "
  2495     "
  2538     self criticalUserEventQueueAccess:[
  2496     ^ self criticalUserEventQueueAccess:[
  2539         [e isNil] whileTrue:[
  2497         |event|
  2540             mouseAndKeyboard size == 0 ifTrue:[^ nil].
  2498 
  2541 
  2499         [
  2542             e := mouseAndKeyboard first.
  2500             mouseAndKeyboard isEmpty ifTrue:[
  2543             e isNil ifTrue:[
  2501                 ^ nil
       
  2502             ].
       
  2503 
       
  2504             event := mouseAndKeyboard first.
       
  2505             event isNil ifTrue:[
  2544                 mouseAndKeyboard removeFirst
  2506                 mouseAndKeyboard removeFirst
  2545             ].
  2507             ].
  2546         ]
  2508             event isNil.
  2547     ].
  2509         ] whileTrue.
  2548     ^ e
  2510         event
  2549 
  2511     ].
  2550     "Modified: / 6.6.1998 / 21:10:51 / cg"
  2512 
       
  2513     "Modified: / 06-06-1998 / 21:10:51 / cg"
       
  2514     "Modified: / 13-04-2018 / 15:28:31 / stefan"
  2551 !
  2515 !
  2552 
  2516 
  2553 pushDamageEvent:anEvent
  2517 pushDamageEvent:anEvent
  2554     "put an event into the damage queue
  2518     "put an event into the damage queue
  2555      - this is not meant for public use"
  2519      - this is not meant for public use"
  2719 !
  2683 !
  2720 
  2684 
  2721 initializeState
  2685 initializeState
  2722     "initialize the event queues to empty"
  2686     "initialize the event queues to empty"
  2723 
  2687 
  2724     damageEventAccessLock := RecursionLock new.
  2688     damageEventAccessLock := RecursionLock name:'WSensor ev-q damageEventAccessLock'.
  2725     damageEventAccessLock name:'WSensor ev-q damageEventAccessLock'.
  2689     userEventAccessLock := RecursionLock name:'WSensor ev-q userEventAccessLock'.
  2726     userEventAccessLock := RecursionLock new.
       
  2727     userEventAccessLock name:'WSensor ev-q userEventAccessLock'.
       
  2728 
  2690 
  2729     damage := OrderedCollection new.
  2691     damage := OrderedCollection new.
  2730     mouseAndKeyboard := OrderedCollection new.
  2692     mouseAndKeyboard := OrderedCollection new.
  2731 
  2693 
  2732     gotExpose := IdentitySet new.
  2694     gotExpose := IdentitySet new.
  2736     shiftDown := ctrlDown := altDown := metaDown := modeSwitchDown := false.
  2698     shiftDown := ctrlDown := altDown := metaDown := modeSwitchDown := false.
  2737     leftButtonDown := middleButtonDown := rightButtonDown := false.
  2699     leftButtonDown := middleButtonDown := rightButtonDown := false.
  2738     collectedMouseWheelMotion := 0.
  2700     collectedMouseWheelMotion := 0.
  2739 
  2701 
  2740     "Modified: / 10-02-2017 / 22:33:44 / cg"
  2702     "Modified: / 10-02-2017 / 22:33:44 / cg"
       
  2703     "Modified: / 13-04-2018 / 11:02:36 / stefan"
  2741 !
  2704 !
  2742 
  2705 
  2743 reinitialize
  2706 reinitialize
  2744     "called when an image is restarted;
  2707     "called when an image is restarted;
  2745      reinitialize the event queues to empty; leave other setup as-is"
  2708      reinitialize the event queues to empty; leave other setup as-is"
  2746 
  2709 
  2747     self initializeState.
  2710     self initializeState.
  2748 ! !
  2711 ! !
  2749 
  2712 
  2750 !WindowSensor methodsFor:'queries-event queue'!
  2713 !WindowSensor methodsFor:'queries-event queue'!
  2751 
       
  2752 damageCount 
       
  2753     "return the number of pending damage events (i.e. expose or resize)"
       
  2754 
       
  2755     ^ damage size
       
  2756 
       
  2757     "Modified: / 2.4.1997 / 14:14:01 / cg"
       
  2758     "Created: / 5.4.1998 / 11:35:04 / cg"
       
  2759 !
       
  2760 
       
  2761 eventPending
       
  2762     "return true, if either damage or events are pending"
       
  2763 
       
  2764     mouseAndKeyboard size ~~ 0 ifTrue:[^ true].
       
  2765     ^ damage size ~~ 0
       
  2766 !
       
  2767 
  2714 
  2768 hasButtonEventFor:aView 
  2715 hasButtonEventFor:aView 
  2769     "return true, if any button events are pending.
  2716     "return true, if any button events are pending.
  2770      If the argument, aView is nil, the information is regarding any
  2717      If the argument, aView is nil, the information is regarding any
  2771      view (i.e. is there a button event for any of my views);
  2718      view (i.e. is there a button event for any of my views);
  2772      otherwise, the information is regarding that specific view."
  2719      otherwise, the information is regarding that specific view."
  2773 
  2720 
  2774     (self hasButtonMotionEventFor:aView) ifTrue:[^ true].
  2721     ^ (self hasButtonMotionEventFor:aView) 
  2775     (self hasButtonPressEventFor:aView) ifTrue:[^ true].
  2722         or:[(self hasButtonPressEventFor:aView)  
  2776     ^ (self hasButtonReleaseEventFor:aView)
  2723         or:[self hasButtonReleaseEventFor:aView]].
  2777 
  2724 
  2778     "Created: 1.11.1996 / 17:02:23 / cg"
  2725     "Created: / 01-11-1996 / 17:02:23 / cg"
  2779     "Modified: 1.11.1996 / 17:12:03 / cg"
  2726     "Modified: / 13-04-2018 / 15:13:55 / stefan"
  2780 !
  2727 !
  2781 
  2728 
  2782 hasButtonMotionEventFor:aView 
  2729 hasButtonMotionEventFor:aView 
  2783     "return true, if any buttonMotion events are pending.
  2730     "return true, if any buttonMotion events are pending.
  2784      If the argument, aView is nil, the information is regarding any
  2731      If the argument, aView is nil, the information is regarding any
  2824 
  2771 
  2825     "Modified: 1.11.1996 / 17:11:27 / cg"
  2772     "Modified: 1.11.1996 / 17:11:27 / cg"
  2826 !
  2773 !
  2827 
  2774 
  2828 hasDamage 
  2775 hasDamage 
  2829     "return true, if any damage events (i.e. expose or resize) are pending.
  2776     "return true, if any damage events (i.e. expose or resize) might be pending.
  2830      Since this is often invoked by ST-80 classes to poll the sensor,
  2777      Since this is often invoked by ST-80 classes to poll the sensor,
  2831      a yield is done here to avoid a busy wait blocking other processes."
  2778      a yield is done here to avoid a busy wait blocking other processes."
  2832 
  2779 
  2833     Processor yield.
  2780     Processor yield.
  2834     ^ damage size ~~ 0
  2781     ^ damage notEmpty
  2835 
  2782 
  2836     "Modified: 2.4.1997 / 14:14:01 / cg"
  2783     "Modified: / 02-04-1997 / 14:14:01 / cg"
       
  2784     "Modified: / 13-04-2018 / 11:25:57 / stefan"
       
  2785     "Modified (comment): / 13-04-2018 / 12:47:15 / stefan"
  2837 !
  2786 !
  2838 
  2787 
  2839 hasDamageFor:aViewOrNil 
  2788 hasDamageFor:aViewOrNil 
  2840     "return true, if any damage events (i.e. expose or resize)
  2789     "return true, if any damage events (i.e. expose or resize)
  2841      are pending for aViewOrNil. If nil, returns true if any damage is 
  2790      are pending for aViewOrNil. If nil, returns true if any damage is 
  2842      pending for this windowGroup."
  2791      pending for this windowGroup."
  2843 
  2792 
  2844     damage size ~~ 0 ifTrue:[
  2793     damage isEmpty ifTrue:[
  2845         damage do:[:aDamage |
  2794         ^ false.
  2846             aDamage notNil ifTrue:[
  2795     ].
  2847                 (aViewOrNil isNil or:[aDamage view == aViewOrNil]) ifTrue:[^ true]
  2796     damage do:[:aDamage |
  2848             ].
  2797         aDamage notNil ifTrue:[
  2849         ]
  2798             (aViewOrNil isNil or:[aDamage view == aViewOrNil]) ifTrue:[
       
  2799                 ^ true
       
  2800             ]
       
  2801         ].
  2850     ].
  2802     ].
  2851     ^ false
  2803     ^ false
  2852 
  2804 
  2853     "Modified: 21.5.1996 / 17:15:09 / cg"
  2805     "Modified: / 21-05-1996 / 17:15:09 / cg"
       
  2806     "Modified: / 13-04-2018 / 12:22:10 / stefan"
  2854 !
  2807 !
  2855 
  2808 
  2856 hasEvent:type for:aReceiverOrNil
  2809 hasEvent:type for:aReceiverOrNil
  2857     "return true, if a specific event is pending in my queues.
  2810     "return true, if a specific event is pending in my queues.
  2858      Type is the type of event, dType the corresponding device event.
  2811      Type is the type of event, dType the corresponding device event.
  2859      If the argument, aReceiverOrNil is nil, the information is regarding any
  2812      If the argument, aReceiverOrNil is nil, the information is regarding any
  2860      view (i.e. is there an event for any of my views);
  2813      view (i.e. is there an event for any of my views);
  2861      otherwise, the information is regarding to that specific view."
  2814      otherwise, the information is regarding to that specific view."
  2862 
  2815 
  2863     mouseAndKeyboard size ~~ 0 ifTrue:[
  2816     mouseAndKeyboard notEmpty ifTrue:[
  2864         (self hasUserEvent:type for:aReceiverOrNil) ifTrue:[^ true].
  2817         (self hasUserEvent:type for:aReceiverOrNil) ifTrue:[
  2865     ].
  2818             ^ true
  2866     damage size ~~ 0 ifTrue:[
  2819         ].
  2867         damage do:[:anEvent |
  2820     ].
  2868             anEvent notNil ifTrue:[
  2821     damage isEmpty ifTrue:[
  2869                 (aReceiverOrNil isNil or:[anEvent receiver == aReceiverOrNil]) ifTrue:[
  2822         ^ false.
  2870                     (type isNil or:[anEvent type == type]) ifTrue:[^ true].
  2823     ].
  2871                 ]
  2824     damage do:[:anEvent |
  2872             ].
  2825         anEvent notNil ifTrue:[
  2873         ]
  2826             (aReceiverOrNil isNil or:[anEvent receiver == aReceiverOrNil]) ifTrue:[
       
  2827                 (type isNil or:[anEvent type == type]) ifTrue:[
       
  2828                     ^ true
       
  2829                 ].
       
  2830             ]
       
  2831         ].
  2874     ].
  2832     ].
  2875     ^ false
  2833     ^ false
  2876 
  2834 
  2877     "Created: / 10.6.1998 / 17:33:46 / cg"
  2835     "Created: / 10-06-1998 / 17:33:46 / cg"
  2878     "Modified: / 18.6.1998 / 09:29:18 / cg"
  2836     "Modified: / 18-06-1998 / 09:29:18 / cg"
       
  2837     "Modified: / 13-04-2018 / 12:22:46 / stefan"
  2879 !
  2838 !
  2880 
  2839 
  2881 hasEvent:type for:aView withArguments:argsOrNil 
  2840 hasEvent:type for:aView withArguments:argsOrNil 
  2882     "return true, if a specific event is pending in my queues.
  2841     "return true, if a specific event is pending in my queues.
  2883      Type is the type of event, args are the arguments.
  2842      Type is the type of event, args are the arguments.
  2902      view (i.e. is there an event for any of my views);
  2861      view (i.e. is there an event for any of my views);
  2903      otherwise, the information is regarding to that specific view.
  2862      otherwise, the information is regarding to that specific view.
  2904      If the type-argument is nil, any event matches, otherwise only events with
  2863      If the type-argument is nil, any event matches, otherwise only events with
  2905      that type are matched."
  2864      that type are matched."
  2906 
  2865 
  2907     mouseAndKeyboard size ~~ 0 ifTrue:[
  2866     |doBlock|
  2908         mouseAndKeyboard do:[:anEvent |
  2867 
  2909             anEvent notNil ifTrue:[
  2868     doBlock := [:eachEvent |
  2910                 (aReceiverOrNil isNil or:[anEvent receiver == aReceiverOrNil]) ifTrue:[
  2869             eachEvent notNil ifTrue:[
  2911                     (type isNil or:[anEvent type == type]) ifTrue:[
  2870                 (aReceiverOrNil isNil or:[eachEvent receiver == aReceiverOrNil]) ifTrue:[
  2912                         (argMatchBlock value:anEvent arguments) ifTrue:[
  2871                     (type isNil or:[eachEvent type == type]) ifTrue:[
       
  2872                         (argMatchBlock value:eachEvent arguments) ifTrue:[
  2913                             ^ true
  2873                             ^ true
  2914                         ].
  2874                         ].
  2915                     ]
  2875                     ]
  2916                 ]
  2876                 ]
  2917             ].
  2877             ].
  2918         ]
  2878         ].
  2919     ].
  2879 
  2920     damage size ~~ 0 ifTrue:[
  2880     mouseAndKeyboard notEmpty ifTrue:[
  2921         damage do:[:anEvent |
  2881         mouseAndKeyboard do:doBlock.
  2922             anEvent notNil ifTrue:[
  2882     ].
  2923                 (aReceiverOrNil isNil or:[anEvent receiver == aReceiverOrNil]) ifTrue:[
  2883     damage notEmpty ifTrue:[
  2924                     (type isNil or:[anEvent type == type]) ifTrue:[
  2884         damage do:doBlock.
  2925                         (argMatchBlock value:anEvent arguments) ifTrue:[
  2885     ].
  2926                             ^ true
  2886 
  2927                         ]
       
  2928                     ].
       
  2929                 ]
       
  2930             ].
       
  2931         ]
       
  2932     ].
       
  2933     ^ false
  2887     ^ false
  2934 
  2888 
  2935     "Modified: 1.11.1996 / 17:11:47 / cg"
  2889     "Modified: / 01-11-1996 / 17:11:47 / cg"
  2936     "Created: 4.1.1997 / 14:00:29 / cg"
  2890     "Created: / 04-01-1997 / 14:00:29 / cg"
       
  2891     "Modified: / 13-04-2018 / 12:23:56 / stefan"
  2937 !
  2892 !
  2938 
  2893 
  2939 hasEvent:type orPendingDeviceEvent:dType for:aView
  2894 hasEvent:type orPendingDeviceEvent:dType for:aView
  2940     "return true, if a specific event is pending in a queue
  2895     "return true, if a specific event is pending in a queue
  2941      or in the devices event queue.
  2896      or in the devices event queue.
  2959 
  2914 
  2960     "Modified: / 10.6.1998 / 17:34:51 / cg"
  2915     "Modified: / 10.6.1998 / 17:34:51 / cg"
  2961 !
  2916 !
  2962 
  2917 
  2963 hasEvents 
  2918 hasEvents 
  2964     "return true, if any mouse/keyboard events are pending"
  2919     "return true, if any mouse/keyboard events might be pending"
  2965 
  2920 
  2966     mouseAndKeyboard size ~~ 0 ifTrue:[^ true].
  2921     ^ mouseAndKeyboard notEmpty or:[damage notEmpty].
  2967     ^ damage size ~~ 0
  2922 
  2968 
  2923     "Modified: / 05-02-1999 / 22:30:23 / cg"
  2969     "Modified: / 5.2.1999 / 22:30:23 / cg"
  2924     "Modified: / 13-04-2018 / 11:05:20 / stefan"
       
  2925     "Modified (comment): / 13-04-2018 / 12:47:37 / stefan"
  2970 !
  2926 !
  2971 
  2927 
  2972 hasExposeEventFor:aViewOrNil 
  2928 hasExposeEventFor:aViewOrNil 
  2973     "return true, if any exposure events are pending for aView.
  2929     "return true, if any exposure events are pending for aView.
  2974      If aViewOrNil is nil, return true if any exposure event for any view
  2930      If aViewOrNil is nil, return true if any exposure event for any view
  2975      in my windowGroup is pending"
  2931      in my windowGroup is pending"
  2976 
  2932 
  2977     damage size ~~ 0 ifTrue:[
  2933     damage isEmpty ifTrue:[
  2978         damage do:[:aDamage |
  2934         ^ false.
  2979             aDamage notNil ifTrue:[
  2935     ].
  2980                 aDamage isDamage ifTrue:[
  2936     damage do:[:eachDamage |
  2981                     (aViewOrNil isNil or:[aDamage view == aViewOrNil]) ifTrue:[^ true].
  2937         (eachDamage notNil and:[eachDamage isDamage]) ifTrue:[
  2982                 ]
  2938             (aViewOrNil isNil or:[eachDamage view == aViewOrNil]) ifTrue:[
       
  2939                 ^ true
  2983             ].
  2940             ].
  2984         ]
  2941         ].
  2985     ].
  2942     ].
  2986     ^ false
  2943     ^ false
  2987 
  2944 
  2988     "Modified: 21.5.1996 / 17:13:09 / cg"
  2945     "Modified: / 21-05-1996 / 17:13:09 / cg"
  2989     "Created: 1.11.1996 / 17:05:41 / cg"
  2946     "Created: / 01-11-1996 / 17:05:41 / cg"
       
  2947     "Modified: / 13-04-2018 / 12:22:14 / stefan"
  2990 !
  2948 !
  2991 
  2949 
  2992 hasKeyEventFor:aViewOrNil 
  2950 hasKeyEventFor:aViewOrNil 
  2993     "return true, if any key (press or release) events are pending.
  2951     "return true, if any key (press or release) events are pending.
  2994      If the argument, aView is nil, the information is regarding any
  2952      If the argument, aView is nil, the information is regarding any
  2995      view (i.e. is there a key event for any of my views);
  2953      view (i.e. is there a key event for any of my views);
  2996      otherwise, the information is regarding that specific view."
  2954      otherwise, the information is regarding that specific view."
  2997 
  2955 
  2998     (self hasKeyPressEventFor:aViewOrNil) ifTrue:[^ true].
  2956     ^ (self hasKeyPressEventFor:aViewOrNil) or:[self hasKeyReleaseEventFor:aViewOrNil]
  2999     ^ self hasKeyReleaseEventFor:aViewOrNil
  2957 
  3000 
  2958     "Created: / 01-11-1996 / 17:08:03 / cg"
  3001     "Created: 1.11.1996 / 17:08:03 / cg"
  2959     "Modified: / 13-04-2018 / 15:11:30 / stefan"
  3002     "Modified: 1.11.1996 / 17:11:55 / cg"
       
  3003 !
  2960 !
  3004 
  2961 
  3005 hasKeyPressEventFor:aViewOrNil 
  2962 hasKeyPressEventFor:aViewOrNil 
  3006     "return true, if any keyPress events are pending.
  2963     "return true, if any keyPress events are pending.
  3007      If the argument, aView is nil, the information is regarding any
  2964      If the argument, aView is nil, the information is regarding any
  3031      Type is the type of event, dType the corresponding device event.
  2988      Type is the type of event, dType the corresponding device event.
  3032      If the argument, aReceiverOrNil is nil, the information is regarding any
  2989      If the argument, aReceiverOrNil is nil, the information is regarding any
  3033      view (i.e. is there an event for any of my views);
  2990      view (i.e. is there an event for any of my views);
  3034      otherwise, the information is regarding to that specific view."
  2991      otherwise, the information is regarding to that specific view."
  3035 
  2992 
  3036     mouseAndKeyboard size ~~ 0 ifTrue:[
  2993     mouseAndKeyboard notEmpty ifTrue:[
  3037         mouseAndKeyboard do:[:anEvent |
  2994         mouseAndKeyboard do:[:anEvent |
  3038             anEvent notNil ifTrue:[
  2995             anEvent notNil ifTrue:[
  3039                 (aReceiverOrNil isNil or:[anEvent receiver == aReceiverOrNil]) ifTrue:[
  2996                 (aReceiverOrNil isNil or:[anEvent receiver == aReceiverOrNil]) ifTrue:[
  3040                     (type isNil or:[anEvent type == type]) ifTrue:[^ true].
  2997                     (type isNil or:[anEvent type == type]) ifTrue:[^ true].
  3041                 ]
  2998                 ]
  3042             ].
  2999             ].
  3043         ]
  3000         ]
  3044     ].
  3001     ].
  3045     ^ false
  3002     ^ false
  3046 
  3003 
  3047     "Created: / 17.6.1998 / 12:55:54 / cg"
  3004     "Created: / 17-06-1998 / 12:55:54 / cg"
  3048     "Modified: / 18.6.1998 / 08:57:00 / cg"
  3005     "Modified: / 18-06-1998 / 08:57:00 / cg"
       
  3006     "Modified: / 13-04-2018 / 15:11:49 / stefan"
  3049 !
  3007 !
  3050 
  3008 
  3051 hasUserEvent:type for:aView withArguments:argsOrNil 
  3009 hasUserEvent:type for:aView withArguments:argsOrNil 
  3052     "return true, if a specific user event (non damage) is pending in my queues.
  3010     "return true, if a specific user event (non damage) is pending in my queues.
  3053      Type is the type of event, args are the arguments.
  3011      Type is the type of event, args are the arguments.
  3069      Type is the type of event, dType the corresponding device event.
  3027      Type is the type of event, dType the corresponding device event.
  3070      If the argument, aReceiverOrNil is nil, the information is regarding any
  3028      If the argument, aReceiverOrNil is nil, the information is regarding any
  3071      view (i.e. is there an event for any of my views);
  3029      view (i.e. is there an event for any of my views);
  3072      otherwise, the information is regarding to that specific view."
  3030      otherwise, the information is regarding to that specific view."
  3073 
  3031 
  3074     mouseAndKeyboard size ~~ 0 ifTrue:[
  3032     mouseAndKeyboard notEmpty ifTrue:[
  3075         mouseAndKeyboard do:[:anEvent |
  3033         mouseAndKeyboard do:[:anEvent |
  3076             anEvent notNil ifTrue:[
  3034             anEvent notNil ifTrue:[
  3077                 (aReceiverOrNil isNil or:[anEvent receiver == aReceiverOrNil]) ifTrue:[
  3035                 (aReceiverOrNil isNil or:[anEvent receiver == aReceiverOrNil]) ifTrue:[
  3078                     (type isNil or:[anEvent type == type]) ifTrue:[
  3036                     (type isNil or:[anEvent type == type]) ifTrue:[
  3079                         (argMatchBlock value:anEvent arguments) ifTrue:[
  3037                         (argMatchBlock value:anEvent arguments) ifTrue:[
  3084             ].
  3042             ].
  3085         ]
  3043         ]
  3086     ].
  3044     ].
  3087     ^ false
  3045     ^ false
  3088 
  3046 
  3089     "Created: / 17.6.1998 / 12:55:54 / cg"
  3047     "Created: / 17-06-1998 / 12:55:54 / cg"
  3090     "Modified: / 18.6.1998 / 08:57:00 / cg"
  3048     "Modified: / 18-06-1998 / 08:57:00 / cg"
       
  3049     "Modified: / 13-04-2018 / 15:12:07 / stefan"
  3091 !
  3050 !
  3092 
  3051 
  3093 hasUserEventFor:aView 
  3052 hasUserEventFor:aView 
  3094     "return true, if any user event (i.e. key or button events) are pending.
  3053     "return true, if any user event (i.e. key or button events) are pending.
  3095      If the argument, aView is nil, the information is regarding any
  3054      If the argument, aView is nil, the information is regarding any
  3096      view (i.e. is there a user event for any of my views);
  3055      view (i.e. is there a user event for any of my views);
  3097      otherwise, the information is regarding that specific view."
  3056      otherwise, the information is regarding that specific view."
  3098 
  3057 
  3099     (self hasKeyEventFor:aView) ifTrue:[^ true].
  3058     ^ (self hasKeyEventFor:aView) or:[self hasButtonEventFor:aView].
  3100     ^ (self hasButtonEventFor:aView)
  3059 
  3101 
  3060     "Created: / 01-11-1996 / 17:08:50 / cg"
  3102     "Created: 1.11.1996 / 17:08:50 / cg"
  3061     "Modified: / 13-04-2018 / 15:12:32 / stefan"
  3103     "Modified: 1.11.1996 / 17:12:21 / cg"
       
  3104 !
  3062 !
  3105 
  3063 
  3106 hasUserEvents 
  3064 hasUserEvents 
  3107     "return true, if any mouse/keyboard events are pending"
  3065     "return true, if any mouse/keyboard events might be pending"
  3108 
  3066 
  3109     ^ mouseAndKeyboard size ~~ 0
  3067     ^ mouseAndKeyboard notEmpty
  3110 
  3068 
  3111     "Created: / 5.2.1999 / 22:29:11 / cg"
  3069     "Created: / 05-02-1999 / 22:29:11 / cg"
       
  3070     "Modified: / 13-04-2018 / 12:48:01 / stefan"
  3112 !
  3071 !
  3113 
  3072 
  3114 motionEventPending 
  3073 motionEventPending 
  3115     "return true, if any buttonMotion events are pending."
  3074     "return true, if any buttonMotion events are pending."
  3116 
  3075