Qt does not position forms lazarus / 32-Linux ---------------------------------------------------------------------- systemgvp · 2026-05-10 13:47 Situation:  - kubuntu 26.04  - lazarus 4.6  - wayland Using gtk3, qt5 or qt6, if I set a form position, it isn't executed. Using gtk2, it is. Example: 1. I create a new empty application 2. I set position=poDesigned 3. I add a button and associate Form1.Left:=0; 4. I compile If I click on button1, the form doesn't move, but stays in the center of the screen. What's missing? Why does it only work with GTK2? On Kubuntu 25.10, Lazarus doesn't cause any problems, even on Windows. ---------------------------------------------------------------------- Alexx2000 · 2026-05-10 13:52 Wayland does not support changing window position. GTK2 executes using Xwayland that's why it works. ---------------------------------------------------------------------- Thaddy · 2026-05-10 16:35 Basically it should NOT work, because Xwayland <> Wayland and by now everybody knows that the cause is not Lazarus or has been sleeping under a rock. Everybody else also knows that Wayland has by now an extended API that allows for Windowing management a bit better, but no one has implemented it yet (that includes Lazarus, but also the rest of the world except for tests). It is rather pointless to discuss this any further. Just automatically refer to the Wayland developers. Btw: Qt6 is a lot better than GTK2. And you @Alexx2000 already know all that. Don't even mention GTK2 is a Qt thread. ---------------------------------------------------------------------- systemgvp · 2026-05-10 19:44 Yes, Qt6 is a lot better than GTK2, but unfortunately, I need to set the shape's position in my application. Are you aware of any Wayland scams? ---------------------------------------------------------------------- valdir.marcos · 2026-05-10 20:35 Quote from: systemgvp on May 10, 2026, 09:44:10 pmYes, Qt6 is a lot better than GTK2, but unfortunately, I need to set the shape's position in my application. Are you aware of any Wayland scams? There is no immediate solution for Wayland. The alternative, if possible in your case, would be to switch to XLibre: Ubuntu Repository for XLibre https://github.com/xlibre-debian/ubuntu About XLibre: https://github.com/X11Libre/xserver ---------------------------------------------------------------------- zeljko · 2026-05-11 05:27 Quote from: systemgvp on May 10, 2026, 09:44:10 pmYes, Qt6 is a lot better than GTK2, but unfortunately, I need to set the shape's position in my application. Are you aware of any Wayland scams? You can use Qt6 on same system where gtk2 is used, QT_QPA_PLATFORM=xcb ./yourapp should work. ---------------------------------------------------------------------- systemgvp · 2026-05-11 06:46 where should I put this string? ---------------------------------------------------------------------- zeljko · 2026-05-11 07:05 Put it as env variable just like I shown you for test. If that works you can start your app via script. Adding it globally into your $HOME/.bashrc isn't clever idea if you're on KDE Plasma wayland because then everything will be x11/xcb... ---------------------------------------------------------------------- systemgvp · 2026-05-11 12:47 Sorry, but I don't understand where to insert the variable. Where is this test? ---------------------------------------------------------------------- zeljko · 2026-05-11 13:00 In linux terminal: QT_QPA_PLATFORM=xcb ./yourapp , or if you run app via lazrus debugger, Run -> Run parameters -> click second tab "Environment", click Add button below, write env variable name QT_QPA_PLATFORM, for value set xcb, now run your qt6 app. ---------------------------------------------------------------------- systemgvp · 2026-05-11 22:08 Thanks, both solutions work with QT6. I hope they are only a temporary solution. ---------------------------------------------------------------------- dbannon · 2026-05-12 13:19 You can also add a command line parameter if thats more intuitive - Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i $> my-app -platform xcb Note its only one dash (should be two) and no '=' but the parameter is filtered out by Qt before it gets to your app, so does not cause problems with your command line parsing. Davo ---------------------------------------------------------------------- Fred vS · 2026-05-12 15:32 Gemini propose this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program YourAppName; {$mode objfpc}{$H+} uses  {$IFDEF LINUX}  Unix, // Required for fpGetEnv and fpSetEnv  {$ENDIF}  Interfaces, // Initializes the Lazarus widgetset  Forms,   Unit1; {$IFDEF LINUX}procedure CheckAndForceXCB;var  SessionType: String;begin  // Retrieve the current desktop session type  SessionType := LowerCase(fpGetEnv('XDG_SESSION_TYPE'));    // If running on Wayland, force Qt to fallback to XCB (via XWayland)  if SessionType = 'wayland' then  begin    fpSetEnv('QT_QPA_PLATFORM', 'xcb', 1);  end;end;{$ENDIF} begin  {$IFDEF LINUX}  // This must execute before the Interfaces unit initializes Qt  CheckAndForceXCB;  {$ENDIF}   Application.Initialize;  Application.CreateForm(TForm1, Form1);  Application.Run;end. ---------------------------------------------------------------------- systemgvp · 2026-05-12 17:25 The problem is that I would like this solution to be already included in the application, and not have to start the app manually every time Quote from: zeljko on May 11, 2026, 03:00:17 pmIn linux terminal: QT_QPA_PLATFORM=xcb ./yourapp , or if you run app via lazrus debugger, Run -> Run parameters -> click second tab "Environment", click Add button below, write env variable name QT_QPA_PLATFORM, for value set xcb, now run your qt6 app. ---------------------------------------------------------------------- systemgvp · 2026-05-12 17:35 As always when using AI things don't work, in fact lazarus doesn't recognize the fpGetEnv() and fpSetEnv() functions Quote from: Fred vS on May 12, 2026, 05:32:55 pmGemini propose this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program YourAppName; {$mode objfpc}{$H+} uses  {$IFDEF LINUX}  Unix, // Required for fpGetEnv and fpSetEnv  {$ENDIF}  Interfaces, // Initializes the Lazarus widgetset  Forms,   Unit1; {$IFDEF LINUX}procedure CheckAndForceXCB;var  SessionType: String;begin  // Retrieve the current desktop session type  SessionType := LowerCase(fpGetEnv('XDG_SESSION_TYPE'));    // If running on Wayland, force Qt to fallback to XCB (via XWayland)  if SessionType = 'wayland' then  begin    fpSetEnv('QT_QPA_PLATFORM', 'xcb', 1);  end;end;{$ENDIF} begin  {$IFDEF LINUX}  // This must execute before the Interfaces unit initializes Qt  CheckAndForceXCB;  {$ENDIF}   Application.Initialize;  Application.CreateForm(TForm1, Form1);  Application.Run;end. ---------------------------------------------------------------------- Alexx2000 · 2026-05-12 18:06 Add this unit to uses before Interfaces unit: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit uQtWorkaround; {$mode objfpc}{$H+} interface implementation uses  InitC, BaseUnix; function setenv(const name, value: pchar; overwrite: cint): cint; cdecl; external clib; initialization  setenv('QT_QPA_PLATFORM', 'xcb', 1); end. ---------------------------------------------------------------------- Fred vS · 2026-05-12 18:07 Quote from: systemgvp on May 12, 2026, 07:35:53 pmAs always when using AI things don't work, in fact lazarus doesn't recognize the fpGetEnv() and fpSetEnv() functions Quote from: Fred vS on May 12, 2026, 05:32:55 pmGemini propose this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program YourAppName; {$mode objfpc}{$H+} uses  {$IFDEF LINUX}  Unix, // Required for fpGetEnv and fpSetEnv  {$ENDIF}  Interfaces, // Initializes the Lazarus widgetset  Forms,   Unit1; {$IFDEF LINUX}procedure CheckAndForceXCB;var  SessionType: String;begin  // Retrieve the current desktop session type  SessionType := LowerCase(fpGetEnv('XDG_SESSION_TYPE'));    // If running on Wayland, force Qt to fallback to XCB (via XWayland)  if SessionType = 'wayland' then  begin    fpSetEnv('QT_QPA_PLATFORM', 'xcb', 1);  end;end;{$ENDIF} begin  {$IFDEF LINUX}  // This must execute before the Interfaces unit initializes Qt  CheckAndForceXCB;  {$ENDIF}   Application.Initialize;  Application.CreateForm(TForm1, Form1);  Application.Run;end.  Indeed, it should write: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  {$IFDEF LINUX}  BaseUnix, // Required for fpGetEnv and fpSetEnv  {$ENDIF} Bad gemini. ---------------------------------------------------------------------- systemgvp · 2026-05-12 18:31 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$IFDEF LINUX}  SysUtils, InitC, BaseUnix, // Required for fpGetEnv and fpSetEnv  {$ENDIF} {$IFDEF LINUX}//function setenv(name, value: PChar; overwrite: Integer): Integer; cdecl; external 'libc.so.6';function setenv(const name, value: pchar; overwrite: cint): cint; cdecl; external clib; var SessionType: String;{$ENDIF}  {$IFDEF LINUX}  //per risolvere il problema dei QT6 su wayland  SessionType := LowerCase(GetEnvironmentVariable('XDG_SESSION_TYPE'));  //if SessionType = 'wayland' then setenv('QT_QPA_PLATFORM', 'xcb', 1);   setenv('QT_QPA_PLATFORM', 'xcb', 1);  {$ENDIF}  Code: [Select]ShowMessage(GetEnvironmentVariable('XDG_SESSION_TYPE')+' --- '+GetEnvironmentVariable('QT_QPA_PLATFORM')); if I compile and run I get "wayland --- ", it doesn't matter with both functions. ---------------------------------------------------------------------- Alexx2000 · 2026-05-12 19:41 Yes, of course. Because GetEnvironmentVariable returns Free Pascal environment. While we change C  environment which used by Qt. You can check which session really used by Qt using IsWayland function from QtInt unit. ---------------------------------------------------------------------- systemgvp · 2026-05-12 19:43 Unfortunately I'm an amateur programmer ---------------------------------------------------------------------- systemgvp · 2026-05-12 19:56 I'm using this solution which actually sets the variable QT_QPA_PLATFORM=xcb Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$IFDEF LINUX}function setenv(const name, value: pchar; overwrite: cint): cint; cdecl; external clib;var SessionType: String;  EnvP: PPChar; external name 'environ';function SetEnvironmentVariable(const Name, Value: string): Boolean;begin  if setenv(PChar(Name), PChar(Value), 1) <> 0 then  begin    Result := False;    Exit;  end;  // Forza FPC a rileggere l'ambiente dalla libc  // Punta il puntatore interno di FPC all'environ della libc  System.envp := EnvP;  Result := True;end;{$ENDIF}  {$IFDEF LINUX}    //per risolvere il problema dei QT6 su wayland    SessionType := LowerCase(GetEnvironmentVariable('XDG_SESSION_TYPE'));    if SessionType = 'wayland' then SetEnvironmentVariable('QT_QPA_PLATFORM','xcb');  {$ENDIF But I always get the same result. If I start the application from lazarus (run), where the variable is preset, the form position is displayed correctly. If I start the application outside of lazarus, the application sets the variable correctly but doesn't move the form. ---------------------------------------------------------------------- dbannon · 2026-05-14 06:49 Well, I tried Alexx2000's method and found it worked perfectly, both in Lazarus and in a stand alone app running on a Ubuntu26.04 VM. However, we must remember that libxcb is just an interface to X as is xlib. The nasty people who want to get rid of X will obviously remove libxcb when they finally have their way. I tested my app on that U26.04 box, patched and it works fine, windows appear where they should be etc. So I then hid libxcb and my patched app crashed because it cannot find libxcb, I'd hoped it would fall back to xlib or even wayland. So I tried an unpatched version, with libxcb hidden, it too crashed !  That means, even apps force to go via wayland have a dependency on libxcb ??  So, I read that as saying we are safe having a hard dependency on libxcb for the time being ! Better code might first test if libxcb is available before setting that env var, only a few more lines of code ... IMHO. Davo ---------------------------------------------------------------------- zeljko · 2026-05-14 07:08 all qts in lazarus (qtint.pas) includes xlib unit and that's why it crashes when there's no any x11 lib on system afair. Probably I'll create an small unit with dynamic loading of libxcb (only needed stuff) to get x11 part work (qtx11.inc), but to avoid crash on pure wayland system without any x11 lib. ---------------------------------------------------------------------- dbannon · 2026-05-14 07:42 Well, I have not seen a system yet that does not have X at all. U26.04 does not let you switch Gnome to X but all the expected X libs are still there. But for how long I ask ? Mind you, looking at the size of the U26.04 install image, they clearly don't care about disk space .... As usual zeljko, thanks for what you do ! Davo