Skip to content

The taskbar icon of Spec application windows cannot be set #1546

@koendehondt

Description

@koendehondt

Context: Pharo 12.

Problem

When finishing the chapter "Managing windows" of the Spec book, I investigated why the code in the section "Setting the icon" does not work.

After careful inspection of the code, I conclude that setting the taskbar icon for a window is not implemented correctly. It seems that the code is a mix of old and new ways to set the icon of a window in the taskbar.

Root cause

Look at SpPresenter>>#initializeWindow::

initializeWindow: aWindowPresenter
	"override this to set window values before opening. 
	 You may want to add a menu, a toolbar or a statusbar"

	"IMPORTANT: Please ovirride this method and set yourself the informations you want in your window.
	The content of this method is here to help the transition between Spec 1 and 2.
	In the next Spec version the content of this method will be removed and it will do nothing by default because the goal is to remove the management of all of those informations from Composable to put them in WindowPresenter."

	aWindowPresenter
		title: self title;
		initialExtent: self initialExtent;
		windowIcon: self windowIcon

Sending windowIcon: self windowIcon does not have an effect. The analysis below describes why.

SystemWindow>>#taskbarTask does this:

taskbarTask
	"Answer a taskbar task for the receiver.
	Answer nil if not required."

	(self valueOfProperty: #noTaskbarTask ifAbsent: [false]) ifTrue: [^nil].
	taskbarTask := TaskbarTask
		morph: self
		state: self taskbarState
		icon: (self iconNamed: self taskbarIconName)
		label: self taskbarLabel.
	^taskbarTask

and SystemWindow>>#taskbarIconName does this:

taskbarIconName
	"Answer the icon for the receiver in a task bar."

	self model ifNotNil: [
		self model taskbarIconName
			ifNotNil: [ :aName | ^aName ] ].

	^ super taskbarIconName

Which means that the model of a window should respond to taskbarIconName. In Spec applications, the model is a SpWindowPresenter. That class does not implement taskbarIconName. It inherits it from Object:

Object>>#taskbarIconName
	"Answer the icon for the receiver in a task bar
	or nil for the default."

	^self class taskbarIconName

and Object class implements:

taskbarIconName
	"Answer the icon for an instance of the receiver in a task bar"

	^#smallWindow

Due to this implementation, all Spec windows in the task bar are shown with the #smallWindow icon. And there is no way to change it!

Here is an example that does not work as expected. StPlaygroundPresenter has this method to specify the taskbar icon:

windowIcon
	
	^ self application iconNamed: #workspace

but that method is never invoked, and therefore playground windows show up like this in the taskbar:

Screenshot 2024-05-23 at 12 24 04

This icon should be shown according to the intentions of the StPlaygroundPresenter class:

Screenshot 2024-05-23 at 12 31 12

Suggested solution

Suppose one creates a subclass of SpPresenter. Then it would be nice to configure the associated SpWindowPresenter as follows:

initializeWindow: aWindowPresenter

	aWindowPresenter
		taskbarIconName: #thumbsUp;
		title: 'Test'

So that the taskbars shows:

Screenshot 2024-05-25 at 16 33 49

instead of

Screenshot 2024-05-25 at 16 35 25

This does not require many changes. First, SpWindowPresenter requires a new slot:

#taskbarIconName => ObservableSlot

and accessors:

taskbarIconName

	^ taskbarIconName ifNil: [ super taskbarIconName ]

taskbarIconName: anIconNameSymbol

	taskbarIconName := anIconNameSymbol

@estebanlm Please tell me whether this is the way to go. If so, I will create a PR. If not, let's discuss here and/or at the Pharo Sprint on May 31, 2024.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions