2013-02-13 11 views
6

voglio creare un'applicazione in cui attingo su una finestra, sia in finestra o pieno schermo, dove ho il mouse afferrato ma senza intercettare eventuali scorciatoie da tastiera WM, come Alt + Tab, e ho anche bisogno di essere notificate ogni volta che l'utente entra/esce dallo stato attivo.Come creare programmi compatibili a schermo intero Alt + Tab (come i giochi) in Linux?

Le applicazioni comuni come Google Chrome, Firefox o gnome-terminal possono gestirlo correttamente (andando a schermo intero con F11, ma hanno ancora Alt + Tab), ma non afferrano il mouse.

SDL ha una notoria cattiva gestione di questo caso d'uso: SDL_WM_GrabInput cattura il mouse ma intercetta anche le scorciatoie WM; e SDL_FULLSCREEN sembra avere una sorta di automatico automatico da solo (non chiedermi il motivo).

Una soluzione potrebbe essere scrivere codice per Alt + Tab, ma questo fa schifo (e non aiuta per altre scorciatoie WM, come cambiare in un altro spazio di lavoro).

Un'altra soluzione è quella di non chiamare SDL_WM_GrabInput, ma invece finto una gru a benna: basta nascondere il puntatore del mouse (con SDL_ShowCursor) e spostare di nuovo al centro ogni volta che l'utente si muove. Il che è brutto, ma in pratica funziona - tranne ovviamente per SDL_FULLSCREEN, perché cattura automaticamente (a differenza di implementazioni sensate). Una soluzione SDL fullscreen-capable è questa, ma non è ancora quello che voglio. Non voglio avere hack per abilitare e disabilitare Grab, voglio afferrare il mouse ma non afferrare la tastiera.

Quindi sono arrabbiato con SDL e voglio vedere le alternative. I vorrebbe per utilizzare SDL ma questo non è necessario.

This question sembra indicare che ciò che SDL fa effettivamente è utilizzare XGrabKeyboard. Leggendo la pagina man non mi è immediatamente chiaro se puoi afferrare il mouse senza afferrare la tastiera (non ho mai usato Xlib da solo).

So come creare "falsi schermo intero" con GTK (ovvero, della varietà gnome-terminal Alt + Tab friendly). Immagino che fare questo, accoppiato con il mouse che si nasconde e spostarlo di nuovo al centro ("falso afferrare") potrebbe fare fare il trucco, ma questo sembra troppo nastro adesivo. Ci deve essere un modo più semplice. (Inoltre, non voglio aggiungere GTK come dipendenza, ma non sono nemmeno sicuro che effettuare chiamate Xlib non elaborate sia una buona idea).

Qual è una buona soluzione per questo?

Ho bisogno di una soluzione Linux/X11 ma sarebbe bello che fosse multipiattaforma - so che questo può essere risolto senza problemi su Windows, quindi forse c'è una libreria che fa esattamente questo. (Anche, io rendo con OpenGL, ma questo è irrilevante)

PS: Forse sto avendo una cattiva comprensione di questo problema e non sto chiedendo il diritto domanda, quindi sentitevi liberi di segnalare approcci Mi rifugio' t considerato.

+0

La [domanda che ho citato] (http://stackoverflow.com/questions/10916997/alt-tab-from-fullscreen-sdl), a mio parere, non è proprio un duplicato, dal momento che non sto guardando specificamente per una soluzione SDL. SDL è semplicemente la libreria che sto usando * adesso *. – darque

+0

Ho appena visto su Xlib API la funzione [XGrabPointer] (http://tronche.com/gui/x/xlib/input/XGrabPointer.html). Quindi, a quanto pare, Xlib ha abbastanza funzionalità per afferrare * solo * il mouse, senza dover afferrare la tastiera. – darque

risposta

4

Attualmente utilizzo Gtk e GtkGLExt per giocare su Linux in questi giorni (ad esempio, le mie voci di Ludum Dare). Qui (gtk.c Gist) è il mio codice, l'ho rilasciato sotto la licenza di FreeBSD. Puoi vedere il codice che ho commentato per il debug delle modifiche allo stato della finestra. Dovrei dire che questo fa parte di un framework molto più ampio che uso per cose come Ludum Dare, e preferisco l'SDL proprio per le stesse ragioni che hai menzionato: le applicazioni risultanti si conformano più strettamente alle aspettative degli utenti per le applicazioni native su le loro piattaforme (Linux, OS X, Windows). Inutile dire che percorrere questa strada richiede molto lavoro.

La programmazione X11 raw, tuttavia, è un vero casino. Stimo che ci vorrebbero un paio di settimane di programmazione solida e documenti di lettura per convertire il mio codice Gtk in codice X11; non ne vale la pena, ma potresti decidere diversamente. (Molte ore solo per eliminare una dipendenza che tutti hanno installato comunque!) La dipendenza Gtk non è in realtà così scandalosa, probabilmente è già già caricata in memoria, e l'ABI per 2.x è molto stabile, quindi non danneggerà la compatibilità binaria .

Un grosso problema con la programmazione X11 per i giochi è che la gestione degli eventi è un disastro totale. Non è possibile eseguire facilmente il polling per gli eventi. L'interfaccia Xlib sta bloccando, quindi devi usare una sequenza arcana di chiamate di funzione per leggere i dati, controllare che ci siano eventi in sospeso e quindi leggere solo gli eventi dalla coda, se esistono (altrimenti l'applicazione bloccherà fino a quando gli eventi non compaiono). La libreria xcb è alternativa a Xlib, che è molto meglio tutt'intorno e supporta un'interfaccia non bloccante, ma non funziona bene con OpenGL. Quindi potresti provare a mescolare i due, oppure potresti semplicemente usare Gtk.

Lasciate che vi faccia un frammento del codice Gtk per fullscreen:

static void toggle_fullscreen() 
{ 
    if (sg_gtk_status & SG_STATUS_VISIBLE) { 
     if (sg_gtk_status & SG_STATUS_FULLSCREEN) 
      gtk_window_unfullscreen(sg_window); 
     else 
      gtk_window_fullscreen(sg_window); 
    } 
} 

Provate a immaginare quanto lavoro questo sarebbe con l'interfaccia X11: capire le dimensioni dello schermo (ci potrebbe essere più di uno!), ridimensiona la finestra, modifica l'ordine in modo che sia in cima a tutto il resto, modifica la decorazione e quindi rispondi in modo intelligente quando l'utente cambia i desktop virtuali. Blah! (In realtà, questo descrive come funziona il mio codice su OS X, ma le API sono molto più belle.)

Inoltre, se stai usando X11, dovrai imparare come reagire all'utente nel modo atteso. X11 è degli anni '80. Gtk, al confronto, fornisce alla tua applicazione una serie di impostazioni predefinite appropriate dai progettisti dell'interfaccia utente di Gtk. La progettazione dell'interfaccia utente è lavoro. E ricorda: puoi mescolare X11 con Gtk bene.

Il sommario: La programmazione X11 è per programmatori con molto tempo libero.

Note: Il GtkGLExt aggiunge un fastidioso flag del linker, -Wl,--export-dynamic. I miei script di compilazione rimuovono il flag dall'output di pkg-config.

X11 esperienze: Penso di aver trascorso circa una settimana cercando di far funzionare tutto in X11, e ho finito per seguire molti vicoli ciechi nel processo. Impara dai miei fallimenti.

+0

Ehi, un grande grazie! Darò un'occhiata al tuo codice. Concordo sul fatto che i vantaggi di semplificare la programmazione superino rapidamente gli svantaggi dell'aggiunta di una dipendenza da grassi come GTK. Preferirei una piccola biblioteca che faccia la stessa cosa comunque. (o, ad essere onesti, preferirei che SDL lo facesse ..) – darque

+0

@darque: Vorrei anche che SDL lo facesse, ma penso che la sfortunata realtà sia che il design di SDL 1.2 è una reliquia di un'epoca precedente. Forse SDL 1.3 è migliore. E SDL è abbastanza buono per la maggior parte delle persone. C'è sicuramente spazio per una sostituzione moderna di SDL, ma dal 2013 dovrebbe funzionare bene su Android e iOS, il che rende l'impresa molto più complicata. –

+0

SDL 1.3? Hmm ho sentito che SDL 2.0 avrebbe migliorato questo aspetto, ma non riesco a trovarlo su Google (eccetto [questa roadmap] (http://wiki.libsdl.org/moin.cgi/Roadmap # Mouse_Input) che cita miglioramenti sul grab del mouse senza elaborazione). – darque

Problemi correlati