Paola Magillo, Univestita' di Genova, Corso di Interfacce Utente per Informatica, a.a. 2007-2008.

FINESTRE, EVENTI E LORO GESTIONE

Precisazione su che cosa e' una finestra

Per finestra qui intendiamo un'area rettangolare sullo schermo, su cui e' possibile visualizzare testo / grafica, catturare eventi. Non sono solo le finestre top-level!
Funziona come unita' autonoma di I/O.

Una finestra e' identificata dal server in modo univoco.
Client puo' agire su una finestra facendo richieste al server tramite l'identificatore (link) della finestra.

Non e' necessario che un client indirizzi solamente le finestre da esso create. Puo' anche agire su altre finestre purche' ne conosca l'identificatore (es: window manager e' un client che gestisce posizione e dimensione di tutte le finestre di uno schermo - ved. piu' avanti).

Gerarchia delle finestre

Le finestre sono organizzate secondo una struttura ad albero (albero delle finestre) che rispecchia la relazione di contenimento o annidamento.
Contenimento = Una finestra e' ritagliata dentro un'altra finestra.

Una sottofinestra e' vincolata a rispettare l'annidamento. Se spostata fuori dall'area della finestra da cui discende, la parte esterna non e' visibile.

Una finestra puo' esistere ma non essere visibile (es. non mappata, iconificata o ricoperta da altre finestre). Una finestra e' visibile solo se le finestre da cui discende sono visibili.

Finestre a top-level

Ogni finestra top-level appartiene ad un'applicazione. Le sue sotto-finestre appartengono alla stessa applicazione.

Una finestra top-level ha:

Stack delle finestre (top-level)

Consideriamo solo finestre top-level.

Diverse finestre di diverse applicazioni possono coesistere su una stessa porzione di schermo sovrapponendosi parzialmente o totalmente.

Il sistema tiene un ordinamento (pila o stack) delle finestre. La posizione nello stack (sopra/sotto) decide quale finestra va a coprire l'altra in caso di coesistenza della stessa area dello schermo.

Nota: a differenza di quanto avviene nell'albero delle finestre, qui la sovrapposizione fra due finestre e' accidentale e transitoria.


Stack in generale vale per un insieme di finestre sorelle (sotto-finestre della stessa finestra a stesso livello nella gerarchia di contenimento).
Il caso piu' significativo e' lo stack tra finestre top-level (figlie della root window, cioe' finestre disegnate direttamente sullo sfondo del desktop).

Su richiesta delle applicazioni o in conseguenza di azioni dell'utente e' possibile cambiare l'ordine nella pila.

E' possibile modificare la posizione nella pila di una finestra rispetto alle finestre che stanno al suo stesso livello nella gerarchia ad albero. In genere si agisce sulle top-level.

Una sottofinestra segue la finestra da cui discende in ogni suo spostamento nella pila.

Mapping di finestre

Creazione di una finestra da parte del server consiste nell'allocazione ed inizializzazione della corrispondente struttura dati.

Una finestra creata non e' necessariamente visualizzata sullo schermo.

Client puo' richiedere la visualizzazione di una finestra attraverso mapping.

Una finestra mappata e' visibile purche':

Per rendere non piu' visualizzata una finestra: operazione di unmapping. Unmapping di una finestra provoca automaticamente unmapping delle sue discendenti.

Esempio: iconificazione di una finestra = unmapping della finestra e contemporaneo mapping dell'icona.

Sistemi di coordinate

Ogni finestra ha un sistema di riferimento a coordinate intere. Ogni pixel una unita'.

Una finestra e' caratterizzata da:

La posizione cambia in corrispondenza di azioni di spostamento.
Il sistema di coordinate cambia in corrispondenza di azioni di ridimensionamento.

Eventi nelle finestre (non solo top-level)

Evento: messaggio inviato da server a client per notificare che qualcosa e' successo o qualche condizione e' cambiata.

Un evento accade sempre in una finestra (source window = finestra sorgente): la finestra dove e' avvenuta l'azione dell'utente oppure la finestra che ha cambiato stato.

Per essere abilitato a ricevere eventi, il client deve fare una richiesta esplicita al server in cui indica:

Quando accade una potenziale causa di evento, il server:

La finestra sulla quale un evento viene intercettato e notificato (che e' o la source window o una sua antenata nella gerarchia) e' chiamata event window.

Il client ha una coda FIFO in cui raccoglie gli eventi che gli vengono mandati dal server (sono solo gli eventi che lo riguardano) nell'ordine in cui sono stati generati.

Informazioni associate a un evento

Un evento porta con se' un pacchetto di informazioni:

Eventi da mouse

Il mouse permette essenzialmente di:

Associato al mouse c'e' un cursore (eco) descritto da una bitmap che viene mantenuta dal server e viene visualizzata come immagine digitale sullo schermo.

Cursore e' caratterizzato da un suo punto interno (hotspot). Questo punto rappresenta la posizione del mouse e viene monitorato dal server.

Il client puo' chiedere al server di notificare eventi quando:

Eventi da mouse hanno coordinate (x,y) della posizione del mouse nella finestra e stato dei bottoni.
Eventi relativi a pressione di bottoni sono caratterizzati da un "time stamp" per discriminare fra pressioni singole e sequenze tipo doppio click o triplo click.
Sono distinti pressione e rilascio (utile per per menu' pop-up, operazioni di drag).

Eventi di spostamento sono onerosi da gestire. Client puo' chiedere al server di generare un evento all'inizio e uno alla fine del movimento.

Eventi di entrata ed uscita sono utili per evitare che le applicazioni debbano monitorare continuamente la posizione del mouse (es. mentre l'utente scorre tra le opzioni di un menu' pull-down).

Eventi da tastiera

Server genera un evento ogni volta che un tasto viene premuto o rilasciato.

Evento e' caratterizzato dal codice del tasto piu' dalla presenza di modificatori dovuti alla pressione contemporanea di piu' tasti (es. control, alt...).

La finestra a cui si riferisce un evento di tastiera si chiama focus window.

Sono possibili varie convenzioni per stabilire la focus window:

Mantenimento del contenuto delle finestre

Il contenuto (grafico, testuale) di una finestra e' il risultato delle operazioni eseguite (mediante richieste al server) dal client sulla finestra.

Quando una finestra viene oscurata o resa invisibile e poi torna visibile, e' necessario ripristinare il suo contenuto. Di questo puo' incaricarsi:

  1. Il server, che deve avere tenuto copia locale del contenuto della finestra (backing store), eseguendo tutti gli aggiornamenti anche sulla copia.
    Non richiede intervento del client, e' molto oneroso per il server.
  2. Il client, inviando al server le richieste necessarie a riprodurre il contenuto della finestra: E' piu' laborioso per programmatore e client.

La strategia 1 ha uso molto limitato e per finestre transitorie (es. menu' pop-up): server salva copia solo del contenuto dell'area della finestra che cade sotto ad una particolare finestra che viene mappata temporaneamente sopra di essa.

Ordinariamente e' usata la strategia 2.

Window manager (WM)

Window manager: un'applicazione particolare che ha il compito di gestire l'assetto delle finestre top-level nell'ambito del desktop o workspace.
Essendo applicazione, e' client. Ma gira sulla macchina server.

Compiti principali del WM:

WM dialoga con il server attraverso richieste ed eventi (come tutti i client).

Tutte le finestre top-level (e solo quelle) di ogni applicazione sono gestite dal window manager.
L'applicazione non ha il controllo della posizione e dimensione di queste, ne' del fatto che siano mappate o no. Puo' dare hint (suggerimenti) al window manager, ma non e' detto chi siano rispettati; e comunque l'utente puo' intervenire a cambiare la situazione.
Invece, l'applicazione ha il pieno controllo delle sottofinestre.

Il server ridirige al WM le richieste provenienti da altre applicazioni (altri client) e riguardanti la struttura di una finestra top-level.

Decorazioni del WM

WM mappa (rende visibili) finestre top-level arricchendo la finestra con una cornice (bordo, barra del titolo, detti anche decorazioni della finestra aggiunte dal WM).

La cornice contiene dispositivi con i quali utente puo' agire sulla finestra stessa per iconificare, cambiare dimensione, chiudere ecc.
Queste azioni sulla finestra non sono gestite dal programma applicativo, il programma applicativo gestisce solo le azioni avvenute all'interno della finestra (comprese le sottofinestre).

WM crea una finestra piu' grande di quella richiesta dal client e ritaglia la finestra del client come sottofinestra.

Finestre e icone

Il WM gestisce anche le icone, che rappresentano la versione "a riposo" di una finestra:

Posizionamento di finestre

Al momento di aprire una finestra top-level, cioe' mapparla per la prima volta, il WM e' incaricato dal sistema di posizionarla. Sullo schemo ci sono altre finestre. WM puo' adottare varie politiche per collocare la nuova finestra.

La nuova finestra viene messa in cima allo stack.

Toolkit per lo sviluppo di interfacce

Nelle interfacce di applicazioni si notano elementi ricorrenti che assolvono funzioni specifiche, caratterizzati da aspetto e comportamento particolari, esempi:

Toolkit sono pacchetti sw implementati sopra la API del sistema a finestre che forniscono un insieme di widget o componenti o dispositivi di interfaccia, cioe' tipi di elementi di interfaccia prefabbricati, che il programmatore puo' configurare (entro i limiti previsti) ed assemblare per costruire un'interfaccia.
Esempi di configurazione:

A seconda del tipo, un widget e' realizzato con una o piu' finestre, widget = window object.

Il toolkit implementa i widget usando la API del sistema a finestre, in modo trasparente all'applicazione.

Un esempio: il sistema X-Window

Sistema a finestre (window management system) indipendente da hw e sistema operativo, con architettura client-server.

Permette di realizzare applicazioni portabili su macchine diverse sotto sistemi operativi diversi (tutti della famiglia UNIX).

Progettato per sistemi distribuiti, permette a piu' applicazioni di cooperare attraverso una rete (es. l'interfaccia grafica gira su una macchina diversa da quella dove gira il programma). Anche con architetture e/o sistema operativi diversi. Tutto avviene in maniera completamente trasparente all'applicazione.

Facciamo una prova

Supponiamo di avere due macchine in rete: questa.educ.disi.unige.it e unaltra.educ.disi.unige.it. Stando sullo stesso dominio, e' possibile usare solo i nomi questa e unaltra senza il resto dell'indirizzo di rete.

Noi sediamo davanti a questa (il nostro server). Vogliamo far girare un'applicazione su unaltra (il nostro client) e vedere la sua interfaccia su questa.

  1. Dobbiamo avere avviato X.
  2. Apriamo una finestra di comandi
  3. Digitando il comando xhost + unaltra autorizziamo unaltra ad accedere come host (cioe' client) al sistema X che gira su questa
  4. Colleghiamoci in remoto con unaltra tramite il comando ssh unaltra (chiede login e password)
  5. Tutti i comandi che diamo ora sono eseguiti dalla CPU di unaltra.
  6. Dichiariamo che vogliamo usare lo schermo di questa con il comando setenv DISPLAY=questa:0.0
  7. Lanciamo qualsiasi programma con interfaccia (es. un text editor, la calcolatrice...) e vedremo su questa la sua interfaccia

Utile in casi in cui: