|
Class: WindowGroup
Object
|
+--WindowGroup
- Package:
- stx:libview
- Category:
- Interface-Support-UI
- Version:
- rev:
1.413
date: 2024/03/26 13:08:48
- user: cg
- file: WindowGroup.st directory: libview
- module: stx stc-classLibrary: libview
In Smalltalk/X, the known (ST-80) concept of a controller has been
extended (split) into a WindowGroup which handles process related stuff,
and the Controller, which only handles events for a view and defines the user interaction.
The controller functionality might be (actually: often is) included in the view components.
All interaction is via event queues - there is no polling in controllers (not even conceptionally).
WindowGroups are responsible to wait for and forward events for a group of
windows. All views in a windowGroup share a single windowSensor which holds the
event queue (therefore subviews all share the same input event queue).
Actually, there are two separate event queues - one for damage and view-visibility-related events,
another one for user interaction (such as mouse, keyboard etc.)
The event queues are filled with incoming events as arriving from the physical display.
This is done by a separate process (so called event-dispatcher) which runs at a higher
priority. The event dispatcher determines the queue into which an event has to be placed,
by asking the view for which the event is destined (via the view's sensor).
There may be multiple event dispatchers running (to support multiple displays simultaneously),
there may also be multiple input device readers running
(to suppert tablet/pen input, or other input devices).
See the documentation/examples in DeviceWorkstation/XWorkstation on how this is done.
Except for modal boxes, a separate process is created for each windowGroup
which waits for events to arrive and processes them, by sending corresponding
event messages to the view's controller or the view (*).
The controller is determined by asking the view (for which the event is destined);
if the returned controller is nil, the event is sent directly to the view.
This allows for simple views to work without a controller.
(all of this is actually done in a WindowEvent method)
Therefore, multiple applications run pseudo parallel.
Even if some window performs a long time computation, events are still received
and entered into the corresponding event queues (because the event dispatcher process
runs at a higher priority). However, the actual processing of the event is only
possibly if no other process is busy at the same or a higher priority (unless timeslicing is enabled).
If timeslicing is off, it is possible to change a windowProcesses priority in order to give
other windows a chance to execute (some views do this while performing longtime actions).
Modal boxes create an extra window group for the components of the modal
box, but execute the event-processing loop for this new group in the original process -
therefore, the original windowgroup is blocked for the duration of the modal
interaction.
However, the modal-event processing loop peeks into the original groups event queue
from time to time, and handles expose events. Thus, even while blocked for user input,
the original group continues to get update/redraw events.
Normally, one windowgroup is associated to each topview (StandardSystemView)
and all of its subviews. However, this is not strictly required;
it is possible to create extra windowgroups for subviews, which will let them
run in parallel
(for example, the FileBrowsers kill-Button is created that
way, to allow a kill of an executing unix command, while the browser
itself reads the pipeStream for incoming text.
Even if the fileBrowser is busy reading the pipe, the killButton is still
working and allows terminating the pipe-read action).
On the other hand, multiple topviews can be placed into the same windowGroup;
which allows for multiview applications, of which only one communicates with
the user at a time (for example: the GUI painters canvas and gallery are in the same group).
Multiple topviews within a windowGroup can be configured to behave like one
unit with respect to iconification, deiconification and termination.
This is done by creating multiple topViews in one group, and setting up a master/slave
or partner relation among them (see TopView>>beSlave and TopView>>bePartner).
WindowGroups also support a focus window: this is the one that gets the
keyboard input - even if the cursor is located in another subview.
The sequence is defined by the topView or its model (typically an applicationModel).
It should return an orderedCollection of subviews when asked via #focusSequence.
For debugging or special event manipulations, windowGroups allow for hooks to be installed
around the processing of events - preEventHook is sent a #procesEvent: message before an event is processed,
postEventHook is informed after the event has been processed.
The preEventHook should return a boolean - if it returns true, the event is considered
being already processed by the hook and ignored.
This allows for event-tracing, timing or even filtering (if preEventHook returns true).
(notice: there is also an eventHook facility available in the sensor class.)
Finally, windowgroups are the perfect place for things like defining a
cursor for all associated views, flushing all input, waiting for expose events etc.
Late News:
a busyHook and busyHookTimeout has been added; this hook-(block) gets invoked, whenever
the process was busy handling an event for some time. This can be used to automatically install
a busy cursor (hour-glass) in an application, if some processing takes some time
(without a need for #withCursorDo: all over the place in the application)
Don't get confused:
You don't have to care for all those details in the normal case;
a windowgroup is created for you automatically, when a view is opened.
All of the internals are not required to be known for most applications.
[instance variables:]
views collection of views of this group
topViews collection of topviews of this group
myProcess the process executing the events
mySensor my input sensor
isModal true if this is for a modal box; i.e. running a separate
modal event loop on top of another window group.
Those modal groups execute in the same process as the underlying group
inModalLoop true if this group's event processing is currently suspended
because I have opened a modal window (with its own 'isModal'
group) which handles events for a while.
modalGroup non-nil windowGroup which is my modal windowGroup, if I am
in a modal loop. I.e. the group which has been started by me and
which has taken control.
previousGroup if modal, the group that started this one (might be another modal one)
isDebugged true if a debugger sits on top of me
focusView the one that has the keyboard focus (or nil)
focusByTab if focus came via tabbing
(as opposed to an implicit focus change)
focusSequence defines the focus sequence
preEventHook if non-nil, that one gets notified of incoming
events BEFORE an event is dispatched.
May eat events (i.e. suppress dispatch)
(hook for event filters or recorders)
postEventHook if non-nil, that one gets notified
AFTER an event was dispatched.
isForModalSubView
groupHasFocus true, if this windowGroup has the focus
[class variables:]
LeaveSignal if raised, a modal box leaves (closes)
WindowGroupQuerySignal to ask for the current windowGroup,
anywhere in the program, simply raise this
signal. The raise returns nil, for processes,
which are not under control of a windowGroup.
(i.e. wg := WindowGroup windowGroupQuerySignal raise)
LastEventQuerySignal to ask for the event which was responsible
for being where you are (whereever that is).
The raise returns nil, if you did not arrive
there due to an event.
(i.e. ev := WindowGroup lastEventQuerySignal raise)
The event can be asked for the view, the type
of event, x/y position etc.
(*)
due to historic reasons, many views have the controller functionality
integrated, and handle events themself. The windowSensor takes care
of this, by checking if a view has a controller, and, if so, forwarding
the events to it. Otherwise, events are sent directly to the view.
In the future, all views will be rewritten to actually use a controller.
Currently (being in the middle of this migration), only some views
(buttons, toggles and subclasses) do so.
For more information, read 'introduction to view programming' in the
doc/online directory.
copyrightCOPYRIGHT (c) 1993 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
Signal constants
-
lastEventQuerySignal
-
return the signal which is used to query for the last event
-
leaveSignal
-
return the signal which is used to exit a modal loop.
This private signal, is always caught while a modalbox is active.
Raising it will exit the modal loop and return from the view's #openModal
method.
-
windowGroupQuerySignal
-
return the signal which is used to query for the windowGroup
accessing
-
activeApplication
-
return the currently active application.
Notice: this may be a modal dialogs application - i.e. it is not
always the main application.
Usage example(s):
WindowGroup activeApplication
|
-
activeGroup
-
return the currently active windowGroup.
The returned value may not be fully correct, in case the current process
handles multiple windowGroups simultaneously. In this case,
(usually) the first group is returned (prefering a modal if there is one).
(maybe we should return a collection of windowGroups here).
This method is required to simulate the historic ST-80 single display
behavior for Cursor>>show / Cursor>>showWhile and some others (raising the
activeGroups topView when modalBoxes appear) on multiple display screens.
These methods should change the cursor for the currently
active windowGroup ONLY, instead of globally affecting the display or
all views
(since, depending on the priority, other views could be unaffacted by this
and an overall cursor change does not make sense.)
Usage example(s):
-
activeMainApplication
-
return the currently active main application.
Notice:
if invoked by a modal application, this returns the main (non-modal)
application.
Usage example(s):
WindowGroup activeMainApplication
|
-
allTopViews
-
-
flushCachedActiveGroup
-
-
lastEvent
-
notice: this returns the thread-specific (i.e. windowGroup-specific)
last event, by issuing a query signal.
Every windowGroup-process will have its own last event returned here
-
scheduledWindowGroups
-
return a collection of all windowGroups
(possibly for different display devices) which are scheduled
(i.e. which have a process running, handling events).
Usage example(s):
WindowGroup scheduledWindowGroups
|
-
setActiveGroup: aGroup
-
set the currently active windowGroup.
Temporary; do not use this interface, it will vanish.
focus control support
-
takeFocusFromDevice: aDevice
-
initialization
-
initialize
-
ms
Usage example(s):
instance creation
-
new
-
create and return a new WindowGroup object
others
-
sendKeyboardFocusEventTo: aView withArgument: arg
-
Modified (format): / 11-04-2018 / 14:27:50 / stefan
accessing
-
creatingProcess
-
return the process which created this group or nil.
Only returns non-nil for modal groups.
-
device
-
return the device, we receive our events from
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
doNotCloseOnAbortSignal: aBoolean
-
normally, an abortSignal closes a modal dialog, which is different from a non-modal
one, where only the current action (event handling) is aborted.
This can be disabled, if you want to avoid closing a modal application,
but instead have the same non-modal behavior for modal app vies
-
graphicsDevice
-
return the device, we receive our events from
-
isDebugged
-
return true, if the receiver has a debugger sitting on top of me,
so I do not have control
-
isDebugged: aBoolean
-
only set by the debugger to mark the currently active group as being debugged
-
isInModalLoop
-
return true, if the receiver has given up control to some other modal windowGroup
(i.e. if it has popped up a modal dialog or a popUpMenu)
-
isModal
-
return true, if the receiver is for a modal view
(i.e. it is for a modal box, dialog or popUpMenu).
The suspended windowgroup would return true to the isInModalLoop query if this is the case.
-
mainGroup
-
return the main windowgroup (for modal groups only)
that is the top one, which is not modal.
NonModal groups return themSelf.
There is one exception to this: the debugger (which is sort of modal)
returns itself as mainGroup (not its debuggee).
-
mainGroup: aWindowGroup
-
set the main windowgroup (for modal/autonomous groups only)
Exposeevents for that windowGroup will be handled by this group
as well.
-
modalGroup
-
if the receiver has given up control to some other modal windowGroup
(i.e. if it has popped up a modal dialog or a popUpMenu), this is the modalGroup
-
previousGroup
-
return the windowgroup that started this group. (for modal groups only).
This may be another modalGroup (for boxes opened by boxes).
NonModal groups return nil.
-
process
-
return the windowGroup's process
-
processPriority
-
-
processPriority: anInteger
-
-
sensor
-
return the windowGroup's sensor.
All events for any of the group's views is handled by that sensor.
-
sensor: aSensor
-
set the windowGroup's sensor
accessing-hooks
-
addPostEventHook: anEventProcessor
-
add another postEventHook
-
addPreEventHook: anEventProcessor
-
add a preEventHook.
This can be a block or an object which understands #processEvent:
and will be called BEFORE an event is dispatched.
If it returns true, the event is assumed to be already eaten and not
dispatched.
(similar to eventListeners, but invoked asynchronously,
in the target's windowGroup process)
-
busyHook
-
return the busyHook if any
-
busyHook: anObject
-
set the busyHook - this one will be invoked when the event-handling action
takes some time.
-
busyHookTimeout
-
return the busyHook's timeout if any.
The busyHook (if non-nil) will be called whenever an event's
processing time takes longer.
-
busyHookTimeout: anObject
-
set the busyHook's timeout.
The busyHook will be invoked when the event-handling action
takes longer than this time.
-
haltInterruptHandler: aHandlerBlock
-
can be used to intercept control interrupts
(breakpoints and halts) on a per windowGroup base.
If set, it gets called like an exception handler
(i.e. with optional ex argument, which can be rejected, resumed, etc.)
-
postEventHooks
-
return the postEventHooks if any
-
preEventHooks
-
return the preEventHooks if any
-
removePostEventHook: anEventProcessor
-
remove a postEventHook
-
removePreEventHook: anEventProcessor
-
remove a preEventHook
-
showWaitCursorWhenBusyForMillis: millis
-
setup a busyHook, which automatically shows a waitCursor,
whenever some action takes longer than millis
accessing-views
-
addTopView: aView
-
add a topview to the group
-
addView: aView
-
add aView to the windowGroup
-
application
-
-
mainView
-
return the mainview. That's the first topView by default
-
removeView: aView
-
remove aView from the windowGroup;
if this was the last view in this group,
also shut down the corresponding process
(actually, only wake it up here - it will terminate itself
when finding out that all views are gone)
-
topViews
-
return the topviews associated to this windowGroup
-
views
-
return the views associated to this windowGroup
activation & deactivation
-
closeDownViews
-
destroy all views associated to this window group
-
hideTopViews
-
unmap all topViews associated to this windowGroup.
-
modalDialogFinished
-
invoked, when a modal dialog is closed
-
modalDialogStarts: aModalGroup
-
invoked, when a modal dialog is opened
-
realizeTopViews
-
realize all topViews associated to this windowGroup.
-
restart
-
restart after a snapin.
This re-creates the windowGroup process and informs
my views.
-
restartTopViews
-
inform all topViews associated to this windowGroup.
about the restart.
-
shutDown
-
shutdown the window group; close all views and
terminate the process
-
shutDownProcess
-
shutdown the window group process
-
startupModal: checkBlock
-
startup the window-group in a modal loop
(i.e. under the currently running process);
checkBlock is evaluated and the modal loop is left,
whenever false is returned.
-
startupModal: checkBlock forGroup: mainGroup
-
startup the window-group in a modal loop
(i.e. under the currently running process - NOT creating a new process);
checkBlock is evaluated and loop is left, when false is returned.
The mainGroup info is required to allow peeking into its
event queue in order for its expose/redraws to be handled.
-
startupWith: startupAction
-
startup the window-group;
this creates a new window group process, which does the event processing.
The startupAction arg is evaluated by the windowGroup process,
before the eventLoop is entered, and is used to realize any views.
[this is done to have the new process realize its views, instead of
the caller - which may make a difference in case of errors and/or
blocking operations ...]
-
unhideTopViews
-
map all topViews associated to this windowGroup.
enumerating
-
allNonTopViewsDo: aBlock
-
evaluate aBlock for all nonTopviews (i.e. subviews) in this group.
This enumerates a copy of the view collection, to allow for
destroy and other collection changing operations to be performed in the loop.
-
allTopViewsDo: aBlock
-
evaluate aBlock for all topviews in this group.
This enumerates a copy of the view collection, to allow for
destroy and other collection changing operations to be performed in the loop.
-
allTopViewsExcept: aView do: aBlock
-
evaluate aBlock for all topviews except aView in this group.
This enumerates a copy of the view collection, to allow for
destroy and other collection changing operations to be performed in the loop.
-
allViewsDo: aBlock
-
evaluate aBlock for all views & topviews in this group.
This enumerates a copy of the view collection, to allow for
destroy and other collection changing operations to be performed in the loop.
-
partnersDo: aBlock
-
evaluate aBlock for all partnerViews.
This enumerates a copy of the view collection, to allow for
destroy and other collection changing operations to be performed in the loop.
-
slavesDo: aBlock
-
evaluate aBlock for all slaveViews.
This enumerates a copy of the view collection, to allow for
destroy and other collection changing operations to be performed in the loop.
event debugging
-
traceEvents
-
return the event tracing flag
-
traceEvents: trueOrFalse
-
turn event tracing on/off
event handling
-
eventLoop
-
loop executed by windowGroup process;
wait-for and process events forever
-
eventLoopWhile: aBlock onLeave: cleanupActions
-
this is the main event loop in which application sits:
wait-for and process events.
Stay in this loop while there are still any views to dispatch for,
and aBlock evaluates to true.
Some signals are caught & handled:
LeaveSignal forces an exit from the eventLoop;
AbortOperationRequest brings us back into the loop, processing the next event;
ActivityNotifications send a #showActivity: if nonModal,
otherwise they are ignored.
-
executePostEventHooksFor: anEvent
-
-
executePreEventHooksFor: anEvent
-
return true, if the event was eaten
-
lastEvent
-
-
leaveEventLoop
-
immediately leave the event loop, returning way back.
This can be used to leave (and closedown) a modal group.
(for normal views, this does not make sense)
-
leaveModalLoop
-
if the receiver has a modal window open (i.e. is in a modalLoop),
force him to leave it and proceed as usual.
Be warned: this is not a regular (i.e. OK/ESCAPE) the modal box closing.
-
processEvents
-
process all pending events from either the damage- or user input queues.
Abort is assumed to be handled elsewhere.
-
processEventsWithModalGroup: aModalGroup
-
process all pending events from either the damage- or user input queues.
Abort is assumed to be handled elsewhere.
If modalGroup is non-nil, this is actually called from a modal-group's eventloop,
in order for the underlying mainGroup (me) to handle its redraw events.
In this case, ignore any user input events.
-
processExposeEvents
-
process only pending expose events from the damage queue.
This also handles resize, mapped and unmap events.
-
processExposeEventsFor: aViewOrNil
-
process only pending expose events from the damage queue.
This also handles resize, mapped and unmap events.
-
processRealExposeEvents
-
process only pending expose events from the damage queue
(for any of my views).
This only handles true expose events - leaving map, unmap etc. in the queue.
This is required before/after a scroll operation,
to wait for either a noExpose or a real expose.
-
processRealExposeEventsFor: someViewOrNil
-
process only pending expose events from the damage queue
(for any of my views if the arg is nil).
This only handles true expose events - leaving map, unmap etc. in the queue.
This is required before/after a scroll operation,
to wait for either a noExpose or a real expose.
-
repairDamage
-
repair all damaged areas for any of my views right now.
-
waitForExposeFor: aView
-
wait for an expose or noExpose event for aView, then process all exposes.
To be used after a scroll.
This is very X-specific and not needed with other systems
(i.e. a synthetic noExpose may be generated there).
focus control
-
defaultKeyboardConsumer
-
-
explicitFocusView
-
return the view which currently has the explicit (i.e. tabbed) focus
-
focusBackToPreviousFocusView
-
give focus to the view who had it before
-
focusCameByTab
-
-
focusMomentaryRelease
-
release and reacquire focus.
Use this to allow input fields with accept on lost focus
to accept when a button or menu item is pressed
-
focusNext
-
give focus to next view in the focusSequence from focusView or topView
-
focusNextFrom: aView
-
give focus to the view after aView in the focusSequence
-
focusPrevious
-
give focus to previous view in the focusSequence from focusView or topView
-
focusPreviousFrom: aView
-
give focus to the view before aView in the focusSequence
-
focusRequestFrom: aView
-
aView requests focus. I will grant it, if I have no explicit
focusView (i.e. not tabbed)
-
focusSequence: aSequenceableCollection
-
define the focus sequence for focusNext/focusPrevious.
Focus is stepped in the order in which subviews occur in
the sequence.
-
focusToView: aViewOrNil
-
give focus to aViewOrNil
-
focusView
-
return the view which currently has the focus
-
focusView: aViewOrNil
-
give focus to aViewOrNil
Usage example(s):
|top v1 v2|
top := StandardSystemView new.
v1 := EditTextView origin:0.0@0.0 corner:1.0@0.5 in:top.
v2 := EditTextView origin:0.0@0.5 corner:1.0@1.0 in:top.
top open.
top windowGroup focusView:v1.
|
-
focusView: aViewOrNil byTab: focusCameViaTabOrNil
-
give focus to aViewOrNil.
The focusCameViaTabOrNil argument specifies if the focus came via
tabbing or by pointer-movement/automatic or (if nil) by reassigning the topView focus
to the windowGroup which had it before.
If it came via tabbing, the view is notified differently, to allow
for special highlighting (i.e. drawing a focus-border around itself).
Also, if tabbed in, the focusFollowsMouse behavior is disabled (as we assume,
that the user has explicitely tabbed into the view to force focus to it)
Usage example(s):
|top v1 v2|
top := StandardSystemView new.
v1 := EditTextView origin:0.0@0.0 corner:1.0@0.5 in:top.
v2 := EditTextView origin:0.0@0.5 corner:1.0@1.0 in:top.
top open.
top windowGroup focusView:v1.
|
-
focusViewUnmapped
-
the view which currently had the focus was unmapped
-
pointerView
-
return the view which currently has the pointer
-
setFocusView: aViewOrNil
-
initialization
-
beSynchronous
-
-
initialize
-
setup the windowgroup, by creating a new sensor
and an event semaphore
-
reinitialize
-
reinitialize the windowgroup after an image restart
-
setProcessNameWithRedirectIndicator: redirectString
-
give the windowGroup process a user friendly name.
This name shows up in the ProcessMonitor.
redirectString is nonEmpty, for remote display views
keyboard control
-
processMnemonic: aKeyEvent
-
a mnemonicKey event as forwarded from the keyboardProcessor - if there
is the mnemonic-key defined for a subView, true is returned and the view
becomes the focusView. Otherwise return false.
-
processShortcut: aKeyEvent
-
a shortcut key event as forwarded from the keyboardProcessor - if there is the
shortcut key defined, process the shortcut and return true - otherwise false.
printing & storing
-
printOn: aStream
-
return a printed representation;
just for more user friendlyness: add name of process.
queries
-
anyViewHasFocus
-
-
isPopUp
-
return true, if the receiver is for a popUp view
special
-
migrateTo: anotherDisplay
-
migrate all of my views to some other display device
Usage example(s):
|anotherDisplay v host|
v := StandardSystemView new.
v extent:100@100.
v addSubView:(Button label:'foo').
v openAndWaitUntilVisible.
host := Dialog request:'display:' initialAnswer:'dawn:0'.
host isNil ifTrue:[^ self].
anotherDisplay := XWorkstation newDispatchingFor:host.
anotherDisplay isNil ifTrue:[
self warn:'Could not connect to remote display'.
^ self
].
Smalltalk at:#Display2 put:anotherDisplay.
v windowGroup migrateTo:anotherDisplay
|
Usage example(s):
|anotherDisplay app host|
app := NewSystemBrowser open.
app window waitUntilVisible.
host := Dialog request:'display:' initialAnswer:'dawn:0'.
host isNil ifTrue:[^ self].
anotherDisplay := XWorkstation newDispatchingFor:host.
anotherDisplay isNil ifTrue:[
self warn:'Could not connect to remote display'.
^ self
].
Smalltalk at:#Display2 put:anotherDisplay.
app windowGroup migrateTo:anotherDisplay
|
Usage example(s):
|host anotherDisplay|
host := Dialog request:'display:' initialAnswer:'dawn:0'.
host isNil ifTrue:[^ self].
anotherDisplay := XWorkstation newDispatchingFor:host.
anotherDisplay isNil ifTrue:[
self warn:'Could not connect to remote display'.
^ self
].
Smalltalk at:#Display2 put:anotherDisplay.
Transcript topView windowGroup migrateTo:anotherDisplay
|
Usage example(s):
Transcript topView windowGroup migrateTo:Display
|
special-accessing
-
isForModalSubview
-
special for windowgroup with modal subviews.
These must be flagged specially to avoid the views being reassigned
to the maingroup.
This is a private interface to the SimpleView class
-
isForModalSubview: aBoolean
-
special for windowgroups with modal subviews.
These must be flagged specially to avoid the views being reassigned
to the maingroup.
This is a private interface to the SimpleView class
-
setModal: aBoolean
-
special entry for debugger: set the modal flag.
Not for public use
-
setPreviousGroup: aGroup
-
special entry for debugger:
set the windowgroup that started this group (for modal groups only).
This is not a public interface.
-
setProcess: aProcess
-
special entry for debugger: set the windowGroup's process.
Not for public use.
special-user interaction
-
restoreCursors
-
restore the original cursors in all of my views
-
showActivity: someMessage
-
some activityNotification shalt be communicated to
the user;
forward it to my first topView if there is one
(that one should know how to deal with it)
-
showCursor: aCursor
-
change the cursor to aCursor in all of my views
(This sets the cursor directly, without changing the state of the cursor instance variable;
the reason is to allow for #restoreCursors to be able to undo this).
-
withCursor: aCursor do: aBlock
-
evaluate aBlock while showing aCursor in all
my views (used to show wait-cursor while doing something).
Return the result as returned by aBlock.
-
withExecuteCursorDo: aBlock
-
evaluate aBlock while showing a busyCursor in all
my views (used to show busy-cursor while doing something time consuming).
Return the result as returned by aBlock.
-
withReadCursorDo: aBlock
-
evaluate aBlock while showing a readCursor in all
my views (used to show read-cursor while reading a file).
Return the result as returned by aBlock.
-
withWaitCursorDo: aBlock
-
evaluate aBlock while showing a waitCursor in all
my views (used to show wait-cursor while doing something time consuming).
Return the result as returned by aBlock.
-
withWriteCursorDo: aBlock
-
evaluate aBlock while showing a writeCursor in all
my views (used to show read-cursor while writing a file).
Return the result as returned by aBlock.
LastEventQuery
WindowGroupQuery
|