Linux Guia da Plataforma
O backend Linux usa GTK3 (C) para todos os widgets nativos, com Cairo para desenho customizado. Ele e escrito em C puro e compilado com GCC, proporcionando uma experiencia Linux nativa que se integra com GNOME, XFCE, KDE e outros ambientes de escritorio compativeis com GTK.
| Linguagem | C |
|---|---|
| Linhas de codigo | ~7.300 |
| Funcoes HB_FUNC | ~132 |
| API Nativa | GTK3 (GtkWidget, GtkFixed) |
| Desenho | Cairo / Pango |
| Scintilla | 5.6.1 (biblioteca compartilhada) |
| Distros Suportadas | Ubuntu, Debian, Fedora, openSUSE, Arch, etc. |
Visao Geral da Arquitetura
preprocessador #xcommand"] B --> C["TForm, TControl
classes OOP Harbour"] C --> D["Bridge HB_FUNC
~132 funcoes"] D --> E["Backend GTK3
C / GtkWidget"] E --> F["Widgets GTK
GtkButton, GtkEntry, etc."] E --> G["Cairo / Pango
Desenho customizado"] E --> H["Scintilla 5.6.1
Biblioteca compartilhada"] style A fill:#58a6ff,stroke:#388bfd,color:#0d1117 style B fill:#8b5cf6,stroke:#7c3aed,color:#fff style C fill:#f59e0b,stroke:#d97706,color:#0d1117 style D fill:#f59e0b,stroke:#d97706,color:#0d1117 style E fill:#e95420,stroke:#c34113,color:#fff style F fill:#e95420,stroke:#c34113,color:#fff style G fill:#e95420,stroke:#c34113,color:#fff style H fill:#555,stroke:#333,color:#fff
Criacao de Janelas Nativas
Cada formulario HarbourBuilder e um GtkWindow com um container GtkFixed para
controles filhos com posicionamento absoluto. O backend cria widgets GTK e armazena seus ponteiros
em uma tabela de handles:
// gtk3_backend.c - Criando uma janela de formulario HB_FUNC( UI_FORMNEW ) { const char * cTitle = hb_parc( 1 ); gint nWidth = hb_parni( 2 ); gint nHeight = hb_parni( 3 ); GtkWidget * window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); gtk_window_set_title( GTK_WINDOW( window ), cTitle ); gtk_window_set_default_size( GTK_WINDOW( window ), nWidth, nHeight ); gtk_window_set_position( GTK_WINDOW( window ), GTK_WIN_POS_NONE ); // Usar GtkFixed para posicionamento absoluto de controles filhos GtkWidget * fixed = gtk_fixed_new(); gtk_container_add( GTK_CONTAINER( window ), fixed ); // Armazenar handle na tabela de objetos do lado Harbour hb_retnint( (gintptr) window ); }
Controles mapeiam para widgets GTK3:
| Controle HarbourBuilder | Widget GTK3 |
|---|---|
| Button | gtk_button_new_with_label() |
| Label | gtk_label_new() |
| Edit | gtk_entry_new() |
| Memo | gtk_text_view_new() (em GtkScrolledWindow) |
| CheckBox | gtk_check_button_new_with_label() |
| Radio | gtk_radio_button_new_with_label() |
| ComboBox | gtk_combo_box_text_new() |
| ListBox | gtk_list_box_new() (em GtkScrolledWindow) |
| GroupBox | gtk_frame_new() |
| ProgressBar | gtk_progress_bar_new() |
| Slider/TrackBar | gtk_scale_new_with_range() |
| Image | gtk_image_new_from_file() |
| TabControl | gtk_notebook_new() |
| TreeView | gtk_tree_view_new() (em GtkScrolledWindow) |
| Timer | g_timeout_add() |
| StatusBar | gtk_statusbar_new() |
| ToolBar | gtk_toolbar_new() |
Tratamento de Eventos (g_signal)
O backend GTK3 usa o sistema de sinais do GObject (g_signal_connect()) para conectar
eventos nativos de widgets aos manipuladores de eventos Harbour:
// gtk3_backend.c - Vinculacao de eventos baseada em sinais HB_FUNC( UI_ONEVENT ) { gint nHandle = hb_parnint( 1 ); gint nEventId = hb_parnint( 2 ); PHB_ITEM pBlock = hb_param( 3, HB_IT_BLOCK ); GtkWidget * widget = GTK_WIDGET( GetHandlePtr( nHandle ) ); // Armazenar o bloco de codigo Harbour StoreEventBlock( nHandle, nEventId, pBlock ); // Conectar o sinal GTK a nossa funcao de despacho switch( nEventId ) { case EVENT_CLICK: g_signal_connect( widget, "clicked", G_CALLBACK( on_clicked_signal ), GINT_TO_POINTER( nHandle ) ); break; case EVENT_CHANGE: g_signal_connect( widget, "changed", G_CALLBACK( on_changed_signal ), GINT_TO_POINTER( nHandle ) ); break; case EVENT_KEYDOWN: g_signal_connect( widget, "key-press-event", G_CALLBACK( on_key_signal ), GINT_TO_POINTER( nHandle ) ); break; // ... conexoes adicionais de sinais } } // Callback de sinal despacha para Harbour static void on_clicked_signal( GtkWidget * widget, gpointer user_data ) { gint nHandle = GPOINTER_TO_INT( user_data ); FireEvent( nHandle, EVENT_CLICK ); }
Modo Escuro
O modo escuro GTK3 e controlado via configuracoes GTK:
gtk-application-prefer-dark-theme— O backend define esta propriedade GTK comoTRUEquando o sistema esta em modo escuro. Temas GTK3 (como Adwaita-dark) respondem fornecendo esquemas de cores escuras para todos os widgets.- Daemon de configuracoes GTK — Em ambientes de escritorio que suportam (GNOME, XFCE), o GTK3 le a preferencia de tema do sistema do daemon de configuracoes automaticamente.
- Substituicao manual — Usuarios podem forcar o modo escuro definindo a variavel de ambiente:
export GTK_THEME=Adwaita:dark
- Estilizacao CSS — Para controle detalhado, o backend pode carregar uma folha de estilo CSS GTK que substitui as cores dos widgets para o tema escuro.
// gtk3_backend.c - Configuracao do tema escuro void SetupDarkTheme( void ) { GtkSettings * settings = gtk_settings_get_default(); // Verificar preferencia de tema do sistema gboolean prefer_dark = IsSystemDarkMode(); g_object_set( settings, "gtk-application-prefer-dark-theme", prefer_dark, NULL ); }
No GNOME, o tema do sistema e lido de org.gnome.desktop.interface gtk-theme via
gsettings. O backend verifica isso na inicializacao e define
gtk-application-prefer-dark-theme conforme necessario. Em outros ambientes de escritorio, o
daemon de configuracoes GTK fornece a mesma informacao atraves da API padrao de configuracoes GTK.
Integracao Scintilla
No Linux, Scintilla 5.6.1 e compilado como biblioteca compartilhada:
| Arquivo | Tipo | Proposito |
|---|---|---|
libscintilla.so | Biblioteca compartilhada | Componente principal de edicao Scintilla |
liblexilla.so | Biblioteca compartilhada | Biblioteca de lexer |
O Scintilla e carregado com dlopen() e dlsym() em tempo de execucao. O widget
GTK Scintilla (ScintillaObject) e incorporado na aba do editor de codigo:
// Carregando Scintilla no Linux void * hSci = dlopen( "libscintilla.so", RTLD_LAZY ); if( !hSci ) { fprintf( stderr, "Falha ao carregar Scintilla: %s\n", dlerror() ); return; } // Criando o widget Scintilla GTK ScintillaObject * sci = scintilla_new(); gtk_container_add( GTK_CONTAINER( editor_scrolled ), GTK_WIDGET( sci ) ); scintilla_send_message( sci, SCI_SETLEXER, SCLEX_CPP, 0 );
Processo de Build
Pre-requisitos
- Compilador GCC:
sudo apt install gcc g++
- Bibliotecas de desenvolvimento GTK3:
sudo apt install libgtk-3-dev
- Harbour 3.2+ — Instale pelo gerenciador de pacotes da sua distro ou compile do fonte:
sudo apt install harbour
Ou clone de github.com/harbour/core.
Script de Build (build_linux.sh)
O script executa estas etapas:
- Verificar pre-requisitos — Verifica se GCC e headers GTK3 estao disponiveis.
- Build do Scintilla — Compila as bibliotecas compartilhadas Scintilla e Lexilla a partir do fonte.
- Compilar fonte Harbour — Executa o compilador Harbour nos arquivos fonte do IDE.
- Compilar o backend — Compila
gtk3_backend.ccom GCC. - Linkagem — Linka tudo junto com GTK3, Cairo, Pango e o runtime Harbour.
# build_linux.sh - Sessao de build tipica no Ubuntu/Debian # Instalar dependencias sudo apt update sudo apt install libgtk-3-dev gcc g++ harbour # Build cd HarbourBuilder/samples ./build_linux.sh # Executar ../bin/hbbuilder_linux
No Fedora: sudo dnf install gtk3-devel gcc harbour
No Arch: sudo pacman -S gtk3 harbour harbour-contrib
No openSUSE: sudo zypper install gtk3-devel harbour
Detalhes de Compilacao
# Compilacao manual (o que build_linux.sh faz internamente) # 1. Compilar fonte Harbour para C harbour hbbuilder.prg -n -q -gc1 # 2. Compilar backend C gcc -O2 -c gtk3_backend.c \ $(pkg-config --cflags gtk+-3.0) \ -I$HBDIR/include \ -I./include # 3. Compilar codigo C gerado pelo Harbour gcc -O2 -c hbbuilder.c \ -I$HBDIR/include # 4. Linkar gcc -o hbbuilder_linux hbbuilder.o gtk3_backend.o \ $(pkg-config --libs gtk+-3.0) \ -lcairo -lpango-1.0 \ -lscintilla -llexilla \ -L$HBDIR/lib -lharbour \ -ldl -lm
Recursos Especificos da Plataforma
| Recurso | Implementacao Linux |
|---|---|
| Dialogos de arquivo | gtk_file_chooser_dialog_new() com GtkFileChooserNative |
| Dialogo de fonte | GtkFontChooserDialog |
| Dialogo de cor | GtkColorChooserDialog |
| Dialogos de mensagem | GtkMessageDialog |
| Area de transferencia | gtk_clipboard_get() / gtk_clipboard_set_text() |
| Arrastar e soltar | API de arrastar-e-soltar GTK (gtk_drag_dest_set()) |
| Bandeja do sistema | GtkStatusIcon / AppIndicator (dependendo do DE) |
| Modo escuro | Configuracao GTK gtk-application-prefer-dark-theme |
| Integracao com desktop | Arquivo .desktop, tipos MIME, temas de icones |
| Impressao | GtkPrintOperation |
Limitacoes Conhecidas
- Variancia de ambiente de escritorio — Widgets GTK3 tem aparencia diferente no GNOME, XFCE, KDE, etc. O backend tem como alvo o tema Adwaita padrao. Outros temas podem produzir aparencias ligeiramente diferentes.
- Layout GtkFixed — O backend usa
GtkFixedpara posicionamento absoluto (correspondendo ao modelo Windows/macOS). Isso significa que os controles nao redimensionam ou refluem automaticamente quando o tamanho da janela muda. Use o eventoOnResizepara layout dinamico. - Biblioteca compartilhada Scintilla — O
libscintilla.sodeve estar no caminho de busca de bibliotecas (LD_LIBRARY_PATHou/usr/local/lib). Executesudo ldconfigapos a instalacao. - Wayland — GTK3 suporta Wayland, mas alguns recursos (bandeja do sistema, menus globais) podem nao funcionar em sessoes Wayland puras. X11 e totalmente suportado.
Dependencias
| Pacote/Biblioteca | Proposito |
|---|---|
libgtk-3-dev | Headers e bibliotecas GTK3 (widgets, janelas, eventos) |
libcairo2-dev | Biblioteca de graficos 2D Cairo (desenho customizado) |
libpango1.0-dev | Layout e renderizacao de texto Pango |
libglib2.0-dev | Funcoes utilitarias GLib (timers, sinais, memoria) |
libgdk-pixbuf2.0-dev | Carregamento e manipulacao de imagens |
libscintilla.so | Componente de edicao de codigo (biblioteca compartilhada) |
liblexilla.so | Componente de lexer (biblioteca compartilhada) |
libharbour | Runtime Harbour |
-ldl | Carregamento dinamico (dlopen/dlsym para Scintilla) |
-lm | Biblioteca matematica |