WindowGroup.st
changeset 2440 a0002dc34d0a
parent 2438 618503d1c7f6
child 2444 6b4c26e1949c
equal deleted inserted replaced
2439:358644786358 2440:a0002dc34d0a
   916     "wait-for and process events.
   916     "wait-for and process events.
   917      Stay in this loop while there are still any views to dispatch for,
   917      Stay in this loop while there are still any views to dispatch for,
   918      and aBlock evaluates to true.
   918      and aBlock evaluates to true.
   919 
   919 
   920      Some signals are caught & handled: 
   920      Some signals are caught & handled: 
   921 	LeaveSignal forces an exit from the eventLoop;
   921         LeaveSignal forces an exit from the eventLoop;
   922 	AbortSignal brings us back into the loop, processing the next event;
   922         AbortSignal brings us back into the loop, processing the next event;
   923 	ActivityNotifications send a #showActivity: if nonModal, 
   923         ActivityNotifications send a #showActivity: if nonModal, 
   924 	otherwise they are ignored."
   924         otherwise they are ignored."
   925 
   925 
   926     |thisProcess sigs mainSema prevSema|
   926     |thisProcess sigs mainSema prevSema|
   927 
   927 
   928     thisProcess := Processor activeProcess.
   928     thisProcess := Processor activeProcess.
   929 
   929 
   930     sigs := SignalSet 
   930     sigs := SignalSet 
   931 		with:AbortSignal 
   931                 with:AbortSignal 
   932 		with:LeaveSignal 
   932                 with:LeaveSignal 
   933 		with:(self class activityNotificationSignal).
   933                 with:(self class activityNotificationSignal).
   934 
   934 
   935     [
   935     [
   936 	|p g s mainGroup mySema waitSema groupForSema|
   936         |p g s mainGroup mySema waitSema groupForSema|
   937 
   937 
   938 	waitSema := mySema := mySensor eventSemaphore.
   938         waitSema := mySema := mySensor eventSemaphore.
   939 
   939 
   940 	isModal ifTrue:[
   940         isModal ifTrue:[
   941 	    mainGroup := self mainGroup.
   941             mainGroup := self mainGroup.
   942 	    mainGroup == self ifTrue:[
   942             mainGroup == self ifTrue:[
   943 		mainGroup := nil
   943                 mainGroup := nil
   944 	    ].
   944             ].
   945 	] ifFalse:[
   945         ] ifFalse:[
   946 	    mainGroup := previousGroup
   946             mainGroup := previousGroup
   947 	].
   947         ].
   948         
   948         
   949 	mainGroup notNil ifTrue:[
   949         mainGroup notNil ifTrue:[
   950 	    mainSema := mainGroup sensor eventSemaphore.
   950             mainSema := mainGroup sensor eventSemaphore.
   951 	    waitSema := SemaphoreSet with:mySema with:mainSema.
   951             waitSema := SemaphoreSet with:mySema with:mainSema.
   952 
   952 
   953 	    "/ must also care for all other groups in between
   953             "/ must also care for all other groups in between
   954 	    "/ (in case its a modal dialog opened from a modal dialog)
   954             "/ (in case its a modal dialog opened from a modal dialog)
   955         
   955         
   956 	    g := previousGroup.
   956             g := previousGroup.
   957 	    g ~~ mainGroup ifTrue:[
   957             g ~~ mainGroup ifTrue:[
   958 		groupForSema := IdentityDictionary new.
   958                 groupForSema := IdentityDictionary new.
   959 		[g ~~ mainGroup] whileTrue:[
   959                 [g ~~ mainGroup] whileTrue:[
   960 		    s := g sensor eventSemaphore.
   960                     s := g sensor eventSemaphore.
   961 		    waitSema add:s.
   961                     waitSema add:s.
   962 		    groupForSema at:s put:g.
   962                     groupForSema at:s put:g.
   963 		    g := g previousGroup.
   963                     g := g previousGroup.
   964 		]
   964                 ]
   965 	    ].
   965             ].
   966 	].
   966         ].
   967 
   967 
   968 	[aBlock value] whileTrue:[ 
   968         [aBlock value] whileTrue:[ 
   969 	    LastActiveGroup := self.
   969             LastActiveGroup := self.
   970 	    LastActiveProcess := thisProcess.
   970             LastActiveProcess := thisProcess.
   971 
   971 
   972 	    (views isNil and:[topViews isNil]) ifTrue:[
   972             (views isNil and:[topViews isNil]) ifTrue:[
   973 		myProcess notNil ifTrue:[
   973                 myProcess notNil ifTrue:[
   974 		    p := myProcess.
   974                     p := myProcess.
   975 		    myProcess := nil.
   975                     myProcess := nil.
   976 		    p terminate.
   976                     p terminate.
   977 		    "not reached - there is no life after death"
   977                     "not reached - there is no life after death"
   978 		].
   978                 ].
   979 		"
   979                 "
   980 		 this is the end of a modal loop
   980                  this is the end of a modal loop
   981 		 (not having a private process ...)
   981                  (not having a private process ...)
   982 		"
   982                 "
   983 		^ self
   983                 ^ self
   984 	    ].
   984             ].
   985 
   985 
   986 	    sigs handle:[:ex |
   986             sigs handle:[:ex |
   987 		|theSig|
   987                 |theSig|
   988 
   988 
   989 		(theSig := ex signal) == AbortSignal ifTrue:[
   989                 (theSig := ex signal) == AbortSignal ifTrue:[
   990 		    "/
   990                     "/
   991 		    "/ on abort, stay in loop
   991                     "/ on abort, stay in loop
   992 		    "/
   992                     "/
   993 		    ex return
   993                     ex return
   994 		].
   994                 ].
   995 		theSig == LeaveSignal ifTrue:[
   995                 theSig == LeaveSignal ifTrue:[
   996 		    "/
   996                     "/
   997 		    "/ on leave, exit the event loop
   997                     "/ on leave, exit the event loop
   998 		    "/
   998                     "/
   999 		    ^ self
   999                     ^ self
  1000 		].
  1000                 ].
  1001 
  1001 
  1002 		"/ ActivityNotification
  1002                 "/ ActivityNotification
  1003 		"/
  1003                 "/
  1004 		"/ if I am a modal-group, let it be handled
  1004                 "/ if I am a modal-group, let it be handled
  1005 		"/ by the outer main-groups handler
  1005                 "/ by the outer main-groups handler
  1006 		"/ otherwise show the activityMessage and continue.
  1006                 "/ otherwise show the activityMessage and continue.
  1007 		"/
  1007                 "/
  1008 		isModal ifTrue:[
  1008                 isModal ifTrue:[
  1009 		    ex reject
  1009                     ex reject
  1010 		    "never reached"
  1010                     "never reached"
  1011 		].
  1011                 ].
  1012 		self showActivity:(ex errorString).
  1012                 self showActivity:(ex errorString).
  1013 		ex proceed.
  1013                 ex proceed.
  1014 	    ] do:[
  1014             ] do:[
  1015 		|dev gotSema mainView|
  1015                 |dev gotSema mainView|
  1016 
  1016 
  1017 		"/ Flush device output before going to sleep. 
  1017                 "/ Flush device output before going to sleep. 
  1018 		"/ This may produce more events to arrive.
  1018                 "/ This may produce more events to arrive.
  1019 		"/ Q: is this still needed (see suspendAction) ?
  1019                 "/ Q: is this still needed (see suspendAction) ?
  1020 
  1020 
  1021 "/                dev := self graphicsDevice.
  1021 "/                dev := self graphicsDevice.
  1022 "/                dev notNil ifTrue:[dev flush].
  1022 "/                dev notNil ifTrue:[dev flush].
  1023 
  1023 
  1024 		"/ now, wait for an event to arrive
  1024                 (mainGroup notNil or:[mySensor hasEvents not]) ifTrue:[
  1025 		thisProcess setStateTo:#eventWait if:#active.
  1025                     "/ now, wait for an event to arrive
  1026 		waitSema isNil ifTrue:[
  1026                     thisProcess setStateTo:#eventWait if:#active.
  1027 		    "/ oops - how can this happen ....
  1027                     waitSema isNil ifTrue:[
  1028 		    ^ self.
  1028                         "/ oops - how can this happen ....
  1029 		].
  1029                         ^ self.
  1030 		gotSema := waitSema wait.
  1030                     ].
  1031 		LastActiveGroup := self.
  1031                     gotSema := waitSema wait.
  1032 		LastActiveProcess := thisProcess.
  1032                 ] ifFalse:[
  1033 
  1033                     gotSema := mySema
  1034 		"/ some bad guy ;-) could have closed all down
  1034                 ].
  1035 		"/ in the meanwhile ...
  1035                 LastActiveGroup := self.
  1036 
  1036                 LastActiveProcess := thisProcess.
  1037 		mySensor notNil ifTrue:[
  1037 
  1038 		    gotSema == mySema ifTrue:[
  1038                 "/ some bad guy ;-) could have closed all down
  1039 			"/
  1039                 "/ in the meanwhile ...
  1040 			"/ an event for me 
  1040 
  1041 			"/
  1041                 mySensor notNil ifTrue:[
  1042 			self processEventsWithModalGroup:nil
  1042                     gotSema == mySema ifTrue:[
  1043 		    ] ifFalse:[
  1043                         "/
  1044 			groupForSema notNil ifTrue:[
  1044                         "/ an event for me 
  1045 			    g := groupForSema at:gotSema ifAbsent:nil.
  1045                         "/
  1046 			    g := g ? mainGroup.
  1046                         self processEventsWithModalGroup:nil
  1047 			] ifFalse:[
  1047                     ] ifFalse:[
  1048 			    g := mainGroup
  1048                         groupForSema notNil ifTrue:[
  1049 			].
  1049                             g := groupForSema at:gotSema ifAbsent:nil.
  1050 
  1050                             g := g ? mainGroup.
  1051 			"/
  1051                         ] ifFalse:[
  1052 			"/ an event for my mainGroup 
  1052                             g := mainGroup
  1053 			"/
  1053                         ].
  1054 			g topViews notNil ifTrue:[
  1054 
  1055 			    mainView := g topViews first
  1055                         "/
  1056 			].
  1056                         "/ an event for my mainGroup 
  1057 			mainView notNil ifTrue:[
  1057                         "/
  1058 			    "/
  1058                         g topViews notNil ifTrue:[
  1059 			    "/ if anything happened to the mainGroup
  1059                             mainView := g topViews first
  1060 			    "/ bring my own topView back to the front
  1060                         ].
  1061 			    "/ This keeps modalBoxes visible
  1061                         mainView notNil ifTrue:[
  1062 			    "/
  1062                             "/
  1063 			    (g sensor hasConfigureEventFor:mainView) ifTrue:[
  1063                             "/ if anything happened to the mainGroup
  1064 				topViews size > 0 ifTrue:[
  1064                             "/ bring my own topView back to the front
  1065 				    topViews first raiseDeiconified
  1065                             "/ This keeps modalBoxes visible
  1066 				]
  1066                             "/
  1067 			    ]
  1067                             (g sensor hasConfigureEventFor:mainView) ifTrue:[
  1068 			].
  1068                                 topViews size > 0 ifTrue:[
  1069 			"
  1069                                     topViews first raiseDeiconified
  1070 			 if modal, also check for redraw events in my maingroup
  1070                                 ]
  1071 			 (we arrive here after we woke up on maingroup sensor eventSemaphore)
  1071                             ]
  1072 			"
  1072                         ].
  1073 			g processEventsWithModalGroup:self.
  1073                         "
  1074 		    ]
  1074                          if modal, also check for redraw events in my maingroup
  1075 		]
  1075                          (we arrive here after we woke up on maingroup sensor eventSemaphore)
  1076 	    ].
  1076                         "
  1077 	].
  1077                         g processEventsWithModalGroup:self.
       
  1078                     ]
       
  1079                 ]
       
  1080             ].
       
  1081         ].
  1078     ] valueNowOrOnUnwindDo:[
  1082     ] valueNowOrOnUnwindDo:[
  1079 	"/
  1083         "/
  1080 	"/ perform any cleanupActions
  1084         "/ perform any cleanupActions
  1081 	"/
  1085         "/
  1082 	cleanupActions notNil ifTrue:[cleanupActions value]
  1086         cleanupActions notNil ifTrue:[cleanupActions value]
  1083     ]
  1087     ]
  1084 
  1088 
  1085     "Modified: / 14.12.1995 / 11:12:24 / stefan"
  1089     "Modified: / 14.12.1995 / 11:12:24 / stefan"
  1086     "Modified: / 4.8.1998 / 18:17:59 / cg"
  1090     "Modified: / 5.2.1999 / 22:32:07 / cg"
  1087 !
  1091 !
  1088 
  1092 
  1089 leaveEventLoop
  1093 leaveEventLoop
  1090     "immediately leave the event loop, returning way back.
  1094     "immediately leave the event loop, returning way back.
  1091      This can be used to leave (and closedown) a modal group.
  1095      This can be used to leave (and closedown) a modal group.
  1280                     LastEventQuerySignal handle:[:ex |
  1284                     LastEventQuerySignal handle:[:ex |
  1281                         ex proceedWith:event
  1285                         ex proceedWith:event
  1282                     ] do:[
  1286                     ] do:[
  1283                         (preEventHook notNil 
  1287                         (preEventHook notNil 
  1284                         and:[preEventHook processEvent:event]) ifFalse:[
  1288                         and:[preEventHook processEvent:event]) ifFalse:[
  1285                             event isDamage ifTrue:[
  1289                             "/
  1286                                 "/
  1290                             "/ if the view is no longer shown (iconified or closed),
  1287                                 "/ if the view is no longer shown (iconified or closed),
  1291                             "/ this is a leftover event and ignored.
  1288                                 "/ this is a leftover event and ignored.
  1292                             "/
  1289                                 "/
  1293                             "/ could this ever be a non-damage ?
  1290                                 view shown ifTrue:[
  1294                             "/
  1291                                     LastActiveGroup := self.
  1295                             (view shown or:[event isDamage not]) ifTrue:[
  1292                                     LastActiveProcess := thisProcess.
       
  1293 
       
  1294                                     view
       
  1295                                         dispatchEvent:(event type) 
       
  1296                                         arguments:(event arguments) 
       
  1297                                         withFocusOn:nil 
       
  1298                                         delegate:true
       
  1299 
       
  1300     "/                            ] ifFalse:[
       
  1301     "/                                ('WGROUP: damage for ' , view displayString , ' ignored') infoPrintCR.
       
  1302                                 ]
       
  1303                             ] ifFalse:[
       
  1304                                 "
       
  1305                                  mhmh - could we possibly arrive here ?
       
  1306                                 "
       
  1307                                 LastActiveGroup := self.
  1296                                 LastActiveGroup := self.
  1308                                 LastActiveProcess := thisProcess.
  1297                                 LastActiveProcess := thisProcess.
  1309                                 "/ event sendEventWithFocusOn:nil.
  1298 
  1310                                 view
  1299                                 view
  1311                                     dispatchEvent:(event type) 
  1300                                     dispatchEvent:(event type) 
  1312                                     arguments:(event arguments) 
  1301                                     arguments:(event arguments) 
  1313                                     withFocusOn:nil 
  1302                                     withFocusOn:nil 
  1314                                     delegate:true
  1303                                     delegate:true
  1315                             ]
  1304                             ].
  1316                         ]
  1305                         ]
  1317                     ].
  1306                     ].
  1318                     postEventHook notNil ifTrue:[
  1307                     postEventHook notNil ifTrue:[
  1319                         postEventHook processEvent:event
  1308                         postEventHook processEvent:event
  1320                     ]
  1309                     ]
  1322             ]
  1311             ]
  1323         ]
  1312         ]
  1324     ]
  1313     ]
  1325 
  1314 
  1326     "Created: / 3.12.1998 / 14:01:39 / cg"
  1315     "Created: / 3.12.1998 / 14:01:39 / cg"
  1327     "Modified: / 3.12.1998 / 13:42:10 / cg"
  1316     "Modified: / 5.2.1999 / 22:26:44 / cg"
  1328 !
  1317 !
  1329 
  1318 
  1330 processRealExposeEvents
  1319 processRealExposeEvents
  1331     "process only expose events from the damage queue
  1320     "process only expose events from the damage queue
  1332      (for any of my views).
  1321      (for any of my views).
  1860 ! !
  1849 ! !
  1861 
  1850 
  1862 !WindowGroup class methodsFor:'documentation'!
  1851 !WindowGroup class methodsFor:'documentation'!
  1863 
  1852 
  1864 version
  1853 version
  1865     ^ '$Header: /cvs/stx/stx/libview/WindowGroup.st,v 1.148 1999-02-04 23:14:52 cg Exp $'
  1854     ^ '$Header: /cvs/stx/stx/libview/WindowGroup.st,v 1.149 1999-02-08 14:24:11 cg Exp $'
  1866 ! !
  1855 ! !
  1867 WindowGroup initialize!
  1856 WindowGroup initialize!